示例#1
0
        /// <summary>
        /// Create a simple shallow copy of these mesh faces
        /// </summary>
        /// <returns></returns>
        public MeshFaceCollection FastDuplicate()
        {
            var result = new MeshFaceCollection();

            foreach (MeshFace face in this)
            {
                result.Add(new MeshFace(face));
            }
            return(result);
        }
示例#2
0
 /// <summary>
 /// Initialise a mesh with the specified vertices and faces.
 /// The vertices used should not already form part of any other geometry definition.
 /// </summary>
 /// <param name="verts"></param>
 /// <param name="faces"></param>
 public Mesh(VertexCollection verts, MeshFaceCollection faces) : this()
 {
     foreach (Vertex v in verts)
     {
         Vertices.Add(v);
     }
     foreach (MeshFace f in faces)
     {
         Faces.Add(f);
     }
 }
示例#3
0
        /// <summary>
        /// Get all mesh faces in this collection that contain any vertices
        /// shared with the specified vertex collection
        /// </summary>
        /// <param name="vertices"></param>
        /// <returns></returns>
        public MeshFaceCollection AllWithVertices(VertexCollection vertices)
        {
            var result = new MeshFaceCollection();

            foreach (MeshFace face in this)
            {
                if (face.ContainsAnyVertex(vertices))
                {
                    result.Add(face);
                }
            }
            return(result);
        }
示例#4
0
        /// <summary>
        /// Refine and subdivide the faces in this collection to
        /// reduce the maximum edge length below the specified
        /// </summary>
        /// <param name="maxEdgeLength"></param>
        /// <returns></returns>
        public MeshFaceCollection Refine(double maxEdgeLength)
        {
            MeshFaceCollection result = new MeshFaceCollection();

            ExtractVertices().AssignVertexIndices(1);
            var edges = new MeshDivisionEdgeCollection(this);

            edges.SubDivideAll(maxEdgeLength);
            foreach (var face in this)
            {
                var faceEdges = edges.GetEdgesForFace(face);
                face.Refine(faceEdges, result);
            }
            return(result);
        }
示例#5
0
        /// <summary>
        /// Trim this collection of faces to only those which fit within the specified boundary polygon
        /// on the XY plane
        /// </summary>
        /// <param name="boundary"></param>
        /// <param name="vertices">Optional.  The collection of vertices to which new vertices created during
        /// this process should be added.</param>
        /// <returns></returns>
        public MeshFaceCollection TrimToPolygonXY(IList <Vertex> boundary, IList <Vertex> vertices = null)
        {
            MeshFaceCollection result = new MeshFaceCollection();

            foreach (MeshFace face in this)
            {
                IList <MeshFace> splitFaces = Intersect.PolygonOverlapXY <MeshFace>(face, boundary, vertices);
                if (splitFaces != null)
                {
                    foreach (MeshFace sFace in splitFaces)
                    {
                        result.Add(sFace);
                    }
                }
            }
            return(result);
        }
示例#6
0
        /// <summary>
        /// Convert a set of mesh faces generated via delaunay triangulation into its dual -
        /// the voronoi diagram of the vertices.
        /// </summary>
        /// <param name="triangles"></param>
        /// <returns></returns>
        public static Dictionary <Vertex, MeshFace> VoronoiFromDelaunay(VertexCollection vertices, MeshFaceCollection faces, bool weighted = false)
        {
            var cells = new Dictionary <Vertex, MeshFace>(); //The generated voronoi cells

            foreach (Vertex v in vertices)
            {
                cells.Add(v, new MeshFace()); //Create empty cells
            }

            foreach (MeshFace face in faces)
            {
                Vertex newVert;
                if (weighted)
                {
                    face.WeightedVoronoiPoints(cells);
                }
                else
                {
                    newVert = new Vertex(face.XYCircumcentre);

                    foreach (Vertex v in face)
                    {
                        if (cells.ContainsKey(v))
                        {
                            MeshFace cell = cells[v];
                            cell.Add(newVert);
                        }
                    }
                }
            }

            //TODO: Deal with cells on the edge

            //Sort cell vertices anticlockwise around vertex
            foreach (KeyValuePair <Vertex, MeshFace> kvp in cells)
            {
                kvp.Value.SortVerticesAntiClockwise(kvp.Key.Position);
            }

            return(cells);
        }
示例#7
0
        /// <summary>
        /// Generate a set of mesh faces that represent a delaunay triangulation in the XY plane of the
        /// specified set of vertices.
        /// Based on the algorithm described here: http://paulbourke.net/papers/triangulate/
        /// </summary>
        /// <param name="vertices">The vertices to mesh between</param>
        /// <param name="faces">Optional.  The face collection to which to add the triangles.
        /// If null or ommitted, a new MeshFaceCollection will be created.</param>
        /// <param name="bounds">The bounding box that contains the triangulation.  Should encompass all vertices
        /// and, for later voronoi generation, any bounding geometry.  If null, the bounding box of the vertices
        /// themselves will be used.</param>
        /// <param name="clean">Clean up construction Super Triangle.  If true, any remaining fragments of the
        /// initial generating supertriangle will be removed from the output face list.  Set this to false
        /// if planning on using this mesh for subsequent voronoi generation so that the edge cells can be extended.</param>
        /// <param name="outerVerts">Optional.  If input and non-null, this collection will be populated with the exterior vertices - those connected
        /// to the original supertriangle.  If 'clean' is false, this will instead return the supertriangle vertices.</param>
        public static MeshFaceCollection DelaunayTriangulationXY(VertexCollection vertices,
                                                                 MeshFaceCollection faces = null, BoundingBox bounds = null, bool clean = true, VertexCollection outerVerts = null)
        {
            List <Vertex> vertexList = vertices.ToList();

            vertexList.Sort();

            if (faces == null)
            {
                faces = new MeshFaceCollection();
            }

            if (bounds == null)
            {
                bounds = new BoundingBox(vertexList);
            }
            else
            {
                bounds = new BoundingBox(bounds);
            }

            bounds.Scale(5); //Provide a little wriggle room!

            // Meshing starts with one 'super triangle' that encloses all vertices.
            // This will be removed at the end
            MeshFace superTriangle = DelaunayTriangle.GenerateSuperTriangleXY(bounds);

            faces.Add(superTriangle);



            // Include each vertex in the meshing one at a time
            foreach (Vertex v in vertexList)
            {
                //for (int k = 0; k < 8; k++)
                //{
                //    Vertex v = vertexList[k];
                //    if (k == 7)
                //    {
                //        bool bum = true;
                //    }

                IList <MeshEdge> edges = new List <MeshEdge>(); //The edges of replaced triangles

                for (int i = faces.Count - 1; i >= 0; i--)
                {
                    MeshFace face = faces[i];

                    if (face.XYCircumcircleContainmentQuickCheck(v)) //The vertex lies within the circumcircle of this face
                    {
                        //The edges of the triangle are added to the current edge set...
                        for (int j = 0; j < face.Count; j++)
                        {
                            edges.Add(face.GetEdge(j));
                        }
                        //...and the triangle is removed.
                        faces.RemoveAt(i);
                    }
                }

                //Remove duplicate edges to retain only the convex hull of edges.
                //edges.RemoveDuplicates();

                //Replaced with bespoke version
                for (int i = edges.Count - 2; i >= 0; i--)
                {
                    MeshEdge itemA = edges[i];
                    for (int j = edges.Count - 1; j > i; j--)
                    {
                        if (itemA.Equals(edges[j]))
                        {
                            edges.RemoveAt(j);
                            edges.RemoveAt(i);
                            j--;
                            continue;
                        }
                    }
                }

                // Add triangle fan between all remaining edges and the new vertex
                foreach (MeshEdge edge in edges)
                {
                    faces.Add(new DelaunayTriangle(edge, v));
                }
            }

            // Extract outer vertices
            if (outerVerts != null)
            {
                if (clean)
                {
                    var outerFaces = faces.AllWithVertices(new VertexCollection(superTriangle));
                    foreach (Vertex v in outerFaces.ExtractVertices())
                    {
                        outerVerts.Add(v);
                    }
                }
                else
                {
                    foreach (Vertex v in superTriangle)
                    {
                        outerVerts.Add(v);
                    }
                }
            }

            // Remove the super triangle and any triangles still attached to it
            if (clean)
            {
                faces.RemoveAllWithVertices(new VertexCollection(superTriangle));
            }

            return(faces);
        }