示例#1
0
 public void Splice(MeshUtils.Edge eOrg, MeshUtils.Edge eDst)
 {
     if (eOrg != eDst)
     {
         bool flag = false;
         if (eDst._Org != eOrg._Org)
         {
             flag = true;
             MeshUtils.KillVertex(eDst._Org, eOrg._Org);
         }
         bool flag2 = false;
         if (eDst._Lface != eOrg._Lface)
         {
             flag2 = true;
             MeshUtils.KillFace(eDst._Lface, eOrg._Lface);
         }
         MeshUtils.Splice(eDst, eOrg);
         if (!flag)
         {
             MeshUtils.MakeVertex(eDst, eOrg._Org);
             eOrg._Org._anEdge = eOrg;
         }
         if (!flag2)
         {
             MeshUtils.MakeFace(eDst, eOrg._Lface);
             eOrg._Lface._anEdge = eOrg;
         }
     }
 }
示例#2
0
        /// <summary>
        /// Removes the edge eDel. There are several cases:
        /// if (eDel->Lface != eDel->Rface), we join two loops into one; the loop
        /// eDel->Lface is deleted. Otherwise, we are splitting one loop into two;
        /// the newly created loop will contain eDel->Dst. If the deletion of eDel
        /// would create isolated vertices, those are deleted as well.
        /// </summary>
        public void Delete(MeshUtils.Edge eDel)
        {
            var eDelSym = eDel._Sym;

            // First step: disconnect the origin vertex eDel->Org.  We make all
            // changes to get a consistent mesh in this "intermediate" state.

            bool joiningLoops = false;

            if (eDel._Lface != eDel._Rface)
            {
                // We are joining two loops into one -- remove the left face
                joiningLoops = true;
                MeshUtils.KillFace(eDel._Lface, eDel._Rface);
            }

            if (eDel._Onext == eDel)
            {
                MeshUtils.KillVertex(eDel._Org, null);
            }
            else
            {
                // Make sure that eDel->Org and eDel->Rface point to valid half-edges
                eDel._Rface._anEdge = eDel._Oprev;
                eDel._Org._anEdge   = eDel._Onext;

                MeshUtils.Splice(eDel, eDel._Oprev);

                if (!joiningLoops)
                {
                    // We are splitting one loop into two -- create a new loop for eDel.
                    MeshUtils.MakeFace(MeshUtils.Face.Create(), eDel, eDel._Lface);
                }
            }

            // Claim: the mesh is now in a consistent state, except that eDel->Org
            // may have been deleted.  Now we disconnect eDel->Dst.

            if (eDelSym._Onext == eDelSym)
            {
                MeshUtils.KillVertex(eDelSym._Org, null);
                MeshUtils.KillFace(eDelSym._Lface, null);
            }
            else
            {
                // Make sure that eDel->Dst and eDel->Lface point to valid half-edges
                eDel._Lface._anEdge  = eDelSym._Oprev;
                eDelSym._Org._anEdge = eDelSym._Onext;
                MeshUtils.Splice(eDelSym, eDelSym._Oprev);
            }

            // Any isolated vertices or faces have already been freed.
            MeshUtils.KillEdge(eDel);
        }
示例#3
0
        /// <summary>
        /// Destroys a face and removes it from the global face list. All edges of
        /// fZap will have a NULL pointer as their left face. Any edges which
        /// also have a NULL pointer as their right face are deleted entirely
        /// (along with any isolated vertices this produces).
        /// An entire mesh can be deleted by zapping its faces, one at a time,
        /// in any order. Zapped faces cannot be used in further mesh operations!
        /// </summary>
        public void ZapFace(IPool pool, MeshUtils.Face fZap)
        {
            var eStart = fZap._anEdge;

            // walk around face, deleting edges whose right face is also NULL
            var eNext = eStart._Lnext;

            MeshUtils.Edge e, eSym;
            do
            {
                e     = eNext;
                eNext = e._Lnext;

                e._Lface = null;
                if (e._Rface == null)
                {
                    // delete the edge -- see TESSmeshDelete above

                    if (e._Onext == e)
                    {
                        MeshUtils.KillVertex(pool, e._Org, null);
                    }
                    else
                    {
                        // Make sure that e._Org points to a valid half-edge
                        e._Org._anEdge = e._Onext;
                        MeshUtils.Splice(e, e._Oprev);
                    }
                    eSym = e._Sym;
                    if (eSym._Onext == eSym)
                    {
                        MeshUtils.KillVertex(pool, eSym._Org, null);
                    }
                    else
                    {
                        // Make sure that eSym._Org points to a valid half-edge
                        eSym._Org._anEdge = eSym._Onext;
                        MeshUtils.Splice(eSym, eSym._Oprev);
                    }
                    MeshUtils.KillEdge(pool, e);
                }
            } while (e != eStart);

            /* delete from circular doubly-linked list */
            var fPrev = fZap._prev;
            var fNext = fZap._next;

            fNext._prev = fPrev;
            fPrev._next = fNext;

            pool.Return(fZap);
        }
示例#4
0
        /// <summary>
        /// Splice is the basic operation for changing the
        /// mesh connectivity and topology.  It changes the mesh so that
        ///     eOrg->Onext = OLD( eDst->Onext )
        ///     eDst->Onext = OLD( eOrg->Onext )
        /// where OLD(...) means the value before the meshSplice operation.
        ///
        /// This can have two effects on the vertex structure:
        ///  - if eOrg->Org != eDst->Org, the two vertices are merged together
        ///  - if eOrg->Org == eDst->Org, the origin is split into two vertices
        /// In both cases, eDst->Org is changed and eOrg->Org is untouched.
        ///
        /// Similarly (and independently) for the face structure,
        ///  - if eOrg->Lface == eDst->Lface, one loop is split into two
        ///  - if eOrg->Lface != eDst->Lface, two distinct loops are joined into one
        /// In both cases, eDst->Lface is changed and eOrg->Lface is unaffected.
        ///
        /// Some special cases:
        /// If eDst == eOrg, the operation has no effect.
        /// If eDst == eOrg->Lnext, the new face will have a single edge.
        /// If eDst == eOrg->Lprev, the old face will have a single edge.
        /// If eDst == eOrg->Onext, the new vertex will have a single edge.
        /// If eDst == eOrg->Oprev, the old vertex will have a single edge.
        /// </summary>
        public void Splice(MeshUtils.Edge eOrg, MeshUtils.Edge eDst)
        {
            if (eOrg == eDst)
            {
                return;
            }

            bool joiningVertices = false;

            if (eDst._Org != eOrg._Org)
            {
                // We are merging two disjoint vertices -- destroy eDst->Org
                joiningVertices = true;
                MeshUtils.KillVertex(eDst._Org, eOrg._Org);
            }
            bool joiningLoops = false;

            if (eDst._Lface != eOrg._Lface)
            {
                // We are connecting two disjoint loops -- destroy eDst->Lface
                joiningLoops = true;
                MeshUtils.KillFace(eDst._Lface, eOrg._Lface);
            }

            // Change the edge structure
            MeshUtils.Splice(eDst, eOrg);

            if (!joiningVertices)
            {
                // We split one vertex into two -- the new vertex is eDst->Org.
                // Make sure the old vertex points to a valid half-edge.
                MeshUtils.MakeVertex(MeshUtils.Vertex.Create(), eDst, eOrg._Org);
                eOrg._Org._anEdge = eOrg;
            }
            if (!joiningLoops)
            {
                // We split one loop into two -- the new loop is eDst->Lface.
                // Make sure the old face points to a valid half-edge.
                MeshUtils.MakeFace(MeshUtils.Face.Create(), eDst, eOrg._Lface);
                eOrg._Lface._anEdge = eOrg;
            }
        }
示例#5
0
 public void ZapFace(MeshUtils.Face fZap)
 {
     MeshUtils.Edge anEdge = fZap._anEdge;
     MeshUtils.Edge lnext  = anEdge._Lnext;
     MeshUtils.Edge edge;
     do
     {
         edge        = lnext;
         lnext       = edge._Lnext;
         edge._Lface = null;
         if (edge._Rface == null)
         {
             if (edge._Onext == edge)
             {
                 MeshUtils.KillVertex(edge._Org, null);
             }
             else
             {
                 edge._Org._anEdge = edge._Onext;
                 MeshUtils.Edge edge2 = edge;
                 MeshUtils.Splice(edge2, edge2._Oprev);
             }
             MeshUtils.Edge sym = edge._Sym;
             if (sym._Onext == sym)
             {
                 MeshUtils.KillVertex(sym._Org, null);
             }
             else
             {
                 sym._Org._anEdge = sym._Onext;
                 MeshUtils.Edge edge3 = sym;
                 MeshUtils.Splice(edge3, edge3._Oprev);
             }
             MeshUtils.KillEdge(edge);
         }
     }while (edge != anEdge);
     MeshUtils.Face prev = fZap._prev;
     MeshUtils.Face next = fZap._next;
     next._prev = prev;
     prev._next = next;
     fZap.Free();
 }
示例#6
0
        public void Delete(MeshUtils.Edge eDel)
        {
            MeshUtils.Edge sym  = eDel._Sym;
            bool           flag = false;

            if (eDel._Lface != eDel._Rface)
            {
                flag = true;
                MeshUtils.KillFace(eDel._Lface, eDel._Rface);
            }
            if (eDel._Onext == eDel)
            {
                MeshUtils.KillVertex(eDel._Org, null);
            }
            else
            {
                eDel._Rface._anEdge = eDel._Oprev;
                eDel._Org._anEdge   = eDel._Onext;
                MeshUtils.Splice(eDel, eDel._Oprev);
                if (!flag)
                {
                    MeshUtils.MakeFace(eDel, eDel._Lface);
                }
            }
            if (sym._Onext == sym)
            {
                MeshUtils.KillVertex(sym._Org, null);
                MeshUtils.KillFace(sym._Lface, null);
            }
            else
            {
                eDel._Lface._anEdge = sym._Oprev;
                sym._Org._anEdge    = sym._Onext;
                MeshUtils.Edge edge = sym;
                MeshUtils.Splice(edge, edge._Oprev);
            }
            MeshUtils.KillEdge(eDel);
        }