示例#1
0
        public Mesh Build(MeshSmoothingMethod method, int times = 5, float alpha = 0.2f, float beta = 0.5f)
        {
            var mesh = triangulation.Build(
                (Vertex2D v) => {
                float z = 0f;
                if (heightTable.ContainsKey(v))
                {
                    z = heightTable[v];
                }
                return(new Vector3(v.Coordinate.x, v.Coordinate.y, -z));
            }
                );

            mesh = Symmetrize(mesh);

            switch (method)
            {
            case MeshSmoothingMethod.Laplacian:
                mesh = MeshSmoothing.LaplacianFilter(mesh, times);
                break;

            case MeshSmoothingMethod.HC:
                mesh = MeshSmoothing.HCFilter(mesh, times, alpha, beta);
                break;
            }

            network = VertexConnection.BuildNetwork(mesh.triangles);
            return(mesh);
        }
    public static VertexConnection[] FindAllOverLappingVert(Mesh mesh)
    {
        Vector3[]          vertices    = mesh.vertices;
        VertexConnection[] connections = new VertexConnection[vertices.Length];

        for (int i = 0; i < vertices.Length; i++)
        {
            var P1  = vertices[i];
            var VC1 = connections[i];
            for (int n = i + 1; n < vertices.Length; n++)
            {
                if (P1 == vertices[n])
                {
                    var VC2 = connections[n];
                    if (VC2 == null)
                    {
                        VC2 = connections[n] = new VertexConnection();
                    }
                    if (VC1 == null)
                    {
                        VC1 = connections[i] = new VertexConnection();
                    }
                    VC1.connections.Add(n);
                    VC2.connections.Add(i);
                }
            }
        }
        return(connections);
    }
示例#3
0
        public static VertexConnection[] GetSharedVertices(Vector3[] vertices)
        {
            VertexConnection[] connections = new VertexConnection[vertices.Length];

            for (int i = 0; i < vertices.Length; i++)
            {
                var P1  = vertices[i];
                var VC1 = connections[i];
                for (int n = i + 1; n < vertices.Length; n++)
                {
                    if (P1 == vertices[n])
                    {
                        var VC2 = connections[n];
                        if (VC2 == null)
                        {
                            VC2 = connections[n] = new VertexConnection();
                        }
                        if (VC1 == null)
                        {
                            VC1 = connections[i] = new VertexConnection();
                        }
                        VC1.connections.Add(n);
                        VC2.connections.Add(i);
                    }
                }
            }

            return(connections);
        }
示例#4
0
    // Use this for initialization
    void Start()
    {
        hmul = 1F / hardness;
        mf = GetComponent<MeshFilter> ();
        mc = GetComponent<MeshCollider> ();
        verts = mf.mesh.vertices;
        tris = mf.mesh.triangles;
        //mf.mesh.SetIndices (tris, MeshTopology.LineStrip, 0);

        connections = new VertexConnection[verts.Length];
        for (int i = 0; i < verts.Length; i++) {
            Vector3 P1 = verts [i];
            VertexConnection VC1 = connections [i];
            for (int n = i+1; n < verts.Length; n++) {
                if (P1 == verts [n]) {
                    var VC2 = connections [n];
                    if (VC2 == null)
                        VC2 = connections [n] = new VertexConnection ();
                    if (VC1 == null)
                        VC1 = connections [i] = new VertexConnection ();
                    VC1.connections.Add (n);
                    VC2.connections.Add (i);
                }
            }
        }
    }
示例#5
0
    public static Vector3[] LaplacianFilter(Vector3[] vertices, int[] triangles, int times)
    {
        var network = VertexConnection.BuildNetwork(triangles);

        for (int i = 0; i < times; i++)
        {
            vertices = LaplacianFilter(network, vertices, triangles);
        }
        return(vertices);
    }
示例#6
0
    static Vector3[] HCFilter(Vector3[] vertices, int[] triangles, int times, float alpha, float beta)
    {
        alpha = Mathf.Clamp01(alpha);
        beta  = Mathf.Clamp01(beta);

        var network = VertexConnection.BuildNetwork(triangles);

        Vector3[] origin = new Vector3[vertices.Length];
        Array.Copy(vertices, origin, vertices.Length);
        for (int i = 0; i < times; i++)
        {
            vertices = HCFilter(network, origin, vertices, triangles, alpha, beta);
        }
        return(vertices);
    }
示例#7
0
    static Vector3[] HCFilter(Vector3[] vertices, List <int> limitedTriangles, int times, float alpha, float beta)
    {
        alpha = Mathf.Clamp01(alpha);
        beta  = Mathf.Clamp01(beta);

        var limitedTrianglesArray = limitedTriangles.ToArray();

        var network            = VertexConnection.BuildNetwork(limitedTrianglesArray);
        var limitedVertexCount = limitedTriangles.Max();

        Vector3[] origin = new Vector3[limitedVertexCount];
        Array.Copy(vertices, origin, limitedVertexCount);
        for (int i = 0; i < times; i++)
        {
            vertices = HCFilter(network, origin, vertices, limitedTrianglesArray, alpha, beta);
        }
        return(vertices);
    }
示例#8
0
    public static Vector3[] LaplacianFilter(Vector3[] sourceVertices, int[] sourceTriangles, int times, JobHandle initialJobHandlerDependency)
    {
        var filterJobHandlers = new List <JobHandle>();
        int batchSize         = 250;

        Network        = VertexConnection.BuildNetwork(sourceTriangles);
        LatestVertices = sourceVertices;

        for (int i = 0; i < times; i++)
        {
            var vertexArray    = new NativeArray <Vector3>(LatestVertices, Allocator.TempJob);
            var trianglesArray = new NativeArray <int>(sourceTriangles, Allocator.TempJob);

            var job = new LaplactianFilterJob
            {
                vertices  = vertexArray,
                triangles = trianglesArray
            };

            if (i == 0)
            {
                filterJobHandlers.Add(job.Schedule(vertexArray.Length, batchSize, initialJobHandlerDependency));
            }
            else
            {
                filterJobHandlers.Add(job.Schedule(vertexArray.Length, batchSize, filterJobHandlers[i - 1]));
            }

            filterJobHandlers.Last().Complete();

            // set vertices
            LatestVertices = new Vector3[vertexArray.Length];
            vertexArray.CopyTo(LatestVertices);

            vertexArray.Dispose();
            trianglesArray.Dispose();
        }

        return(LatestVertices);
    }
示例#9
0
    void Start()
    {
        vertexConnection = GetComponent <VertexConnection>();
        meshSmoothing    = GetComponent <MeshSmoothing>();
        meshSmoothing.SetVertexConnection(vertexConnection);

        //mesh = meshFilter.sharedMesh;

        mesh = meshFilter.mesh;
        mesh = ApplyNormalNoise(mesh);

        switch (type)
        {
        case FilterType.Laplacian:
            mesh = meshSmoothing.LaplacianFilter(mesh, times);
            break;

        case FilterType.HC:
            mesh = meshSmoothing.HCFilter(mesh, times, hcAlpha, hcBeta);
            break;
        }
    }
示例#10
0
//		private class AdjacentNeightboursHelper{
//			// Does the vertex v exist in the list of vertices
//			public static bool isVertexExist(List<Vector3>adjacentV, Vector3 v)
//			{
//				bool marker = false;
//				foreach (Vector3 vec in adjacentV)
//					if (Mathf.Approximately(vec.x,v.x) && Mathf.Approximately(vec.y,v.y) && Mathf.Approximately(vec.z,v.z))
//					{
//						marker = true;
//						break;
//					}
//
//				return marker;
//			}
//		}

        //Finds adjacent neighbours of the supplied vertex.
        //sharedPositions can be filled by Helper.GetSharedVertices() if the mesh has seams/gaps
        public static List <Vector3> FindAdjacentVertexNeighbours(Vector3[] vertices, int[] triangles, Vector3 vertex, VertexConnection[] sharedPositions = null)
        {
            List <Vector3> adjacentV  = new List <Vector3>();
            HashSet <int>  facemarker = new HashSet <int>();
            int            facecount  = 0;

            if (sharedPositions == null)
            {
                sharedPositions = new VertexConnection[vertices.Length];
            }

            //caches
            int              v1 = 0;
            int              v2 = 0;
            bool             marker = false;
            int              tk, tk1, tk2;
            VertexConnection sharedPosition;

            // Find matching vertices
            for (int i = 0; i < vertices.Length; ++i)
            {
                if (Mathf.Approximately(Vector3.Distance(vertex, vertices[i]), 0))
                {
//					v1 = 0;
//					v2 = 0;
//					marker = false;

                    // Find vertex indices from the triangle array
                    for (int k = 0; k < triangles.Length; k = k + 3)
                    {
                        if (facemarker.Contains(k) == false)
                        {
                            v1     = 0;
                            v2     = 0;
                            marker = false;

                            tk  = triangles[k];
                            tk1 = triangles[k + 1];
                            tk2 = triangles[k + 2];

                            if (i == tk)
                            {
                                v1     = tk1;
                                v2     = tk2;
                                marker = true;
                            }

                            if (i == tk1)
                            {
                                v1     = tk;
                                v2     = tk2;
                                marker = true;
                            }

                            if (i == tk2)
                            {
                                v1     = tk;
                                v2     = tk1;
                                marker = true;
                            }

                            facecount++;
                            if (marker)
                            {
                                // Once face has been used mark it so it does not get used again
                                facemarker.Add(k);

                                //						// Add non duplicate vertices to the list
                                //						if (AdjacentNeightboursHelper.isVertexExist(adjacentV, v[v1]) == false )
                                //						{
                                //							adjacentV.Add(v[v1]);
                                //							//Debug.Log("Adjacent vertex index = " + v1);
                                //						}
                                //
                                //						if ( AdjacentNeightboursHelper.isVertexExist(adjacentV, v[v2]) == false )
                                //						{
                                //							adjacentV.Add(v[v2]);
                                //							//Debug.Log("Adjacent vertex index = " + v2);
                                //						}

                                // Add non duplicate vertices to the list
                                // This is faster than the above code
                                sharedPosition = sharedPositions[v1];
                                if (sharedPosition == null)
                                {
                                    adjacentV.Add(vertices[v1]);
                                }
                                else
                                {
                                    for (int sv = 0; sv < sharedPosition.connections.Count; ++sv)
                                    {
                                        adjacentV.Add(vertices[sharedPosition.connections[sv]]);
                                    }
                                }
                                sharedPosition = sharedPositions[v2];
                                if (sharedPosition == null)
                                {
                                    adjacentV.Add(vertices[v2]);
                                }
                                else
                                {
                                    for (int sv = 0; sv < sharedPosition.connections.Count; ++sv)
                                    {
                                        adjacentV.Add(vertices[sharedPosition.connections[sv]]);
                                    }
                                }

                                marker = false;
                            }
                        }
                    }
                }
            }

            //Debug.Log("Faces Found = " + facecount);

            return(adjacentV);
        }
示例#11
0
        /**
         *	Splits face per vertex.
         *	Todo - Could implement more sanity checks - namely testing for edges before sending to Split_Internal.  However,
         *	the split method is smart enough to fail on those cases, so ignore for now.
         */
        public static bool ConnectVertices(this pb_Object pb, List <VertexConnection> vertexConnectionsUnfiltered, out pb_Face[] faces)
        {
            List <VertexConnection> vertexConnections = new List <VertexConnection>();
            List <int> inds = new List <int>();

            int i = 0;

            for (i = 0; i < vertexConnectionsUnfiltered.Count; i++)
            {
                VertexConnection vc = vertexConnectionsUnfiltered[i];
                vc.indices = vc.indices.Distinct().ToList();

                if (vc.isValid)
                {
                    inds.AddRange(vc.indices);
                    vertexConnections.Add(vc);
                }
            }

            if (vertexConnections.Count < 1)
            {
                faces = null;
                return(false);
            }

            int              len = vertexConnections.Count;
            List <pb_Face>   successfullySplitFaces = new List <pb_Face>();
            List <pb_Face>   all_splitFaces         = new List <pb_Face>();
            List <Vector3[]> all_splitVertices      = new List <Vector3[]>();
            List <int[]>     all_splitSharedIndices = new List <int[]>();

            bool[] success = new bool[len];

            pb_IntArray[] sharedIndices = pb.sharedIndices;

            i = 0;
            foreach (VertexConnection vc in vertexConnections)
            {
                pb_Face[]   splitFaces         = null;
                Vector3[][] splitVertices      = null;
                int[][]     splitSharedIndices = null;

                if (vc.indices.Count < 3)
                {
                    int indA = vc.face.indices.IndexOf(vc.indices[0], sharedIndices);
                    int indB = vc.face.indices.IndexOf(vc.indices[1], sharedIndices);

                    if (indA < 0 || indB < 0)
                    {
                        success[i] = false;
                        continue;
                    }

                    indA = vc.face.indices[indA];
                    indB = vc.face.indices[indB];

                    success[i] = SplitFace_Internal(new SplitSelection(pb, vc.face, pb.vertices[indA], pb.vertices[indB], true, true, indA, indB),
                                                    out splitFaces,
                                                    out splitVertices,
                                                    out splitSharedIndices);

                    if (success[i])
                    {
                        successfullySplitFaces.Add(vc.face);
                    }
                }
                else
                {
                    success[i] = PokeFace_Internal(pb, vc.face, vc.indices.ToArray(),
                                                   out splitFaces,
                                                   out splitVertices,
                                                   out splitSharedIndices);

                    if (success[i])
                    {
                        successfullySplitFaces.Add(vc.face);
                    }
                }

                if (success[i])
                {
                    int texGroup = pb.UnusedTextureGroup(i + 1);

                    for (int j = 0; j < splitFaces.Length; j++)
                    {
                        splitFaces[j].textureGroup = texGroup;
                        all_splitFaces.Add(splitFaces[j]);
                        all_splitVertices.Add(splitVertices[j]);
                        all_splitSharedIndices.Add(splitSharedIndices[j]);
                    }
                }

                i++;
            }

            if (all_splitFaces.Count < 1)
            {
                faces = null;
                return(false);
            }

            pb_Face[] appendedFaces = pb.AppendFaces(all_splitVertices.ToArray(), all_splitFaces.ToArray(), all_splitSharedIndices.ToArray());
            inds.AddRange(pb_Face.AllTriangles(appendedFaces));

            pb.WeldVertices(inds.ToArray(), Mathf.Epsilon);

            pb.DeleteFaces(successfullySplitFaces.ToArray());

            faces = appendedFaces;
            return(true);
        }
示例#12
0
 public void SetVertexConnection(VertexConnection vC)
 {
     vertexConnection = vC;
 }