Esempio n. 1
0
        /// <summary>
        /// KillEdge( eDel ) destroys an edge (the half-edges eDel and eDel->Sym),
        /// and removes from the global edge list.
        /// </summary>
        public static void KillEdge(IPool pool, Edge eDel)
        {
            // Half-edges are allocated in pairs, see EdgePair above
            Edge.EnsureFirst(ref eDel);

            // delete from circular doubly-linked list
            var eNext = eDel._next;
            var ePrev = eDel._Sym._next;

            eNext._Sym._next = ePrev;
            ePrev._Sym._next = eNext;

            pool.Return(eDel._Sym);
            pool.Return(eDel);
        }
Esempio n. 2
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);
        }
Esempio n. 3
0
        public void Tessellate(WindingRule windingRule, ElementType elementType, int polySize, CombineCallback combineCallback, Vec3 normal)
        {
            _normal   = normal;
            _vertices = null;
            _elements = null;

            _windingRule     = windingRule;
            _combineCallback = combineCallback;

            if (_mesh == null)
            {
                return;
            }

            // Determine the polygon normal and project vertices onto the plane
            // of the polygon.
            ProjectPolygon();

            // ComputeInterior computes the planar arrangement specified
            // by the given contours, and further subdivides this arrangement
            // into regions.  Each region is marked "inside" if it belongs
            // to the polygon, according to the rule given by windingRule.
            // Each interior region is guaranteed be monotone.
            ComputeInterior();

            // If the user wants only the boundary contours, we throw away all edges
            // except those which separate the interior from the exterior.
            // Otherwise we tessellate all the regions marked "inside".
            if (elementType == ElementType.BoundaryContours)
            {
                SetWindingNumber(1, true);
            }
            else
            {
                TessellateInterior();
            }

            _mesh.Check();

            if (elementType == ElementType.BoundaryContours)
            {
                OutputContours();
            }
            else
            {
                OutputPolymesh(elementType, polySize);
            }

            _pool.Return(_mesh);
            _mesh = null;
        }
Esempio n. 4
0
        public void Reset(IPool pool)
        {
            for (MeshUtils.Face f = _fHead, fNext = _fHead; f._next != null; f = fNext)
            {
                fNext = f._next;
                pool.Return(f);
            }
            for (MeshUtils.Vertex v = _vHead, vNext = _vHead; v._next != null; v = vNext)
            {
                vNext = v._next;
                pool.Return(v);
            }
            for (MeshUtils.Edge e = _eHead, eNext = _eHead; e._next != null; e = eNext)
            {
                eNext = e._next;
                pool.Return(e._Sym);
                pool.Return(e);
            }

            _vHead = null;
            _fHead = null;
            _eHead = _eHeadSym = null;
        }
Esempio n. 5
0
        /// <summary>
        /// KillFace( fDel ) destroys a face and removes it from the global face
        /// list. It updates the face loop to point to a given new face.
        /// </summary>
        public static void KillFace(IPool pool, Face fDel, Face newLFace)
        {
            var eStart = fDel._anEdge;

            // change the left face of all affected edges
            var e = eStart;

            do
            {
                e._Lface = newLFace;
                e        = e._Lnext;
            } while (e != eStart);

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

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

            pool.Return(fDel);
        }
Esempio n. 6
0
        /// <summary>
        /// KillVertex( vDel ) destroys a vertex and removes it from the global
        /// vertex list. It updates the vertex loop to point to a given new vertex.
        /// </summary>
        public static void KillVertex(IPool pool, Vertex vDel, Vertex newOrg)
        {
            var eStart = vDel._anEdge;

            // change the origin of all affected edges
            var e = eStart;

            do
            {
                e._Org = newOrg;
                e      = e._Onext;
            } while (e != eStart);

            // delete from circular doubly-linked list
            var vPrev = vDel._prev;
            var vNext = vDel._next;

            vNext._prev = vPrev;
            vPrev._next = vNext;

            pool.Return(vDel);
        }