/// <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); }
/// <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); }
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; }
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; }
/// <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); }
/// <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); }