Example #1
0
        private void SubdivideAllFacesWithInternalFace()
        {
            var edges       = new HashSet <HalfEdge>(HalfEdges.Where(a => a.Primary));
            var newVertices = new HashSet <Vertex>();

            foreach (var edge in edges)
            {
                newVertices.Add(edge.Split(GetVertex(edge.End.Position * 0.5f + edge.Twin.End.Position * 0.5f)).End);
            }

            WalkFaces((f, m) =>
            {
                var verts = f.Vertices.ToArray();
                f.Delete();

                GetFace(verts.Where(a => newVertices.Contains(a)));

                for (int i = 0; i < verts.Length; i++)
                {
                    if (newVertices.Contains(verts[i]))
                    {
                        GetFace(
                            verts[i],
                            verts[(i + 1) % verts.Length],
                            verts[(i + 2) % verts.Length]
                            );
                    }
                }
            });
        }
Example #2
0
        ////////////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>   Makes a deep copy of this object. </summary>
        ///
        /// <remarks>   Darrell Plank, 12/31/2017. </remarks>
        ///
        /// <returns>   A copy of this object. </returns>
        ////////////////////////////////////////////////////////////////////////////////////////////////////
        public Mesh Clone()
        {
            var newMesh = Factory.CreateMesh();

            var oldToNewVertex   = new Dictionary <Vertex, Vertex>();
            var oldToNewHalfEdge = new Dictionary <HalfEdge, HalfEdge>();
            var oldToNewFace     = new Dictionary <Face, Face>();
            var newVertices      = new List <Vertex>();
            var newHalfEdges     = new List <HalfEdge>();
            var newFaces         = new List <Face>();

            foreach (var vertex in Vertices.Where(v => v.IsAlive))
            {
                var newVertex = Factory.CreateVertex(newMesh, vertex.Position.Clone());
                Factory.CloneVertex(newVertex, vertex);
                newVertices.Add(newVertex);
                oldToNewVertex[vertex] = newVertex;
            }

            foreach (var halfEdge in HalfEdges.Where(he => he.IsAlive))
            {
                var newHalfEdge = Factory.CreateHalfEdge(oldToNewVertex[halfEdge.InitVertex],
                                                         null, null, null);
                Factory.CloneHalfEdge(newHalfEdge, halfEdge, oldToNewVertex);
                newHalfEdges.Add(newHalfEdge);
                oldToNewHalfEdge[halfEdge] = newHalfEdge;
            }

            foreach (var face in Faces.Where(f => f.IsAlive))
            {
                var newFace = Factory.CreateFace();
                newFace.HalfEdge = oldToNewHalfEdge[face.HalfEdge];
                Factory.CloneFace(newFace, face, oldToNewHalfEdge, oldToNewVertex);
                newFaces.Add(newFace);
                oldToNewFace[face] = newFace;
            }

            newMesh.VerticesInternal  = newVertices;
            newMesh.HalfEdgesInternal = newHalfEdges;
            newMesh.FacesInternal     = newFaces;

            newMesh.PatchClone(
                this,
                oldToNewVertex,
                oldToNewHalfEdge,
                oldToNewFace);
#if DEBUG
            newMesh.Validate();
#endif
            return(newMesh);
        }
Example #3
0
        ////////////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>   Validates this mesh. </summary>
        ///
        /// <remarks>   TODO: Think about this
        ///             How much do we really want to do at this top level?  Without making certain assumptions
        ///             it's really difficult to do anything useful but we want to be as flexible as possible.
        ///             Since we currently only create elements by adding faces, it's pretty safe, I think, to
        ///             insist that all faces have at least three edges.
        ///
        ///             Darrell Plank, 12/8/2017. </remarks>
        ///
        /// <returns>   True if it succeeds, false if it fails. </returns>
        ////////////////////////////////////////////////////////////////////////////////////////////////////
        public virtual bool Validate()
        {
            if (VerticesInternal.Count == 0)
            {
                if (HalfEdgesInternal.Count != 0 && FacesInternal.Count != 0)
                {
                    throw new MeshNavException("No vertices but we have other elements");
                }
            }

            if (Faces.Any(face => face.Edges().Take(3).Count() != 3 && !face.IsBoundary))
            {
                throw new MeshNavException("Faces with less than three sides not allowed");
            }

            if (Faces.Where(f => f.IsAlive).Any(f => !f.HalfEdge.IsAlive))
            {
                throw new MeshNavException("Live faces point to dead halfedges");
            }

            if (Vertices.Where(v => v.IsAlive).Any(v => v.Mesh != this || !v.Edge.IsAlive))
            {
                throw new MeshNavException("Live vertices point at dead half edges or don't belong to this mesh");
            }

            if (HalfEdges.Where(he => he.IsAlive).Any(he => !he.InitVertex.IsAlive || he.Face != null && !he.Face.IsAlive))
            {
                throw new MeshNavException("Live halfedge points at dead component");
            }

            if (HalfEdges.Where(he => he.IsAlive).Any(he => he.InitVertex == he.Opposite.InitVertex))
            {
                throw new MeshNavException("Edge and opposite oriented identically");
            }
            return(true);
        }