/// <summary> /// MakeFace( eOrig, fNext ) attaches a new face and makes it the left /// face of all edges in the face loop to which eOrig belongs. "fNext" gives /// a place to insert the new face in the global face list. We insert /// the new face *before* fNext so that algorithms which walk the face /// list will not see the newly created faces. /// </summary> public static void MakeFace(IPool pool, Edge eOrig, Face fNext) { var fNew = pool.Get <MeshUtils.Face>(); // insert in circular doubly-linked list before fNext var fPrev = fNext._prev; fNew._prev = fPrev; fPrev._next = fNew; fNew._next = fNext; fNext._prev = fNew; fNew._anEdge = eOrig; fNew._trail = null; fNew._marked = false; // The new face is marked "inside" if the old one was. This is a // convenience for the common case where a face has been split in two. fNew._inside = fNext._inside; // fix other edges on this face loop var e = eOrig; do { e._Lface = fNew; e = e._Lnext; } while (e != eOrig); }
public void Init(IPool pool) { var v = _vHead = pool.Get <MeshUtils.Vertex>(); var f = _fHead = pool.Get <MeshUtils.Face>(); var pair = MeshUtils.EdgePair.Create(pool); var e = _eHead = pair._e; var eSym = _eHeadSym = pair._eSym; v._next = v._prev = v; v._anEdge = null; f._next = f._prev = f; f._anEdge = null; f._trail = null; f._marked = false; f._inside = false; e._next = e; e._Sym = eSym; e._Onext = null; e._Lnext = null; e._Org = null; e._Lface = null; e._winding = 0; e._activeRegion = null; eSym._next = eSym; eSym._Sym = e; eSym._Onext = null; eSym._Lnext = null; eSym._Org = null; eSym._Lface = null; eSym._winding = 0; eSym._activeRegion = null; }
private void AddContourInternal(IList <ContourVertex> vertices, ContourOrientation forceOrientation) { if (_mesh == null) { _mesh = _pool.Get <Mesh>(); } bool reverse = false; if (forceOrientation != ContourOrientation.Original) { var area = SignedArea(vertices); reverse = (forceOrientation == ContourOrientation.Clockwise && area < new DeterministicFloat(0)) || (forceOrientation == ContourOrientation.CounterClockwise && area > new DeterministicFloat(0)); } MeshUtils.Edge e = null; for (int i = 0; i < vertices.Count; ++i) { if (e == null) { e = _mesh.MakeEdge(_pool); _mesh.Splice(_pool, e, e._Sym); } else { // Create a new vertex and edge which immediately follow e // in the ordering around the left face. _mesh.SplitEdge(_pool, e); e = e._Lnext; } int index = reverse ? vertices.Count - 1 - i : i; // The new vertex is now e._Org. e._Org._coords = vertices[index].Position; e._Org._data = vertices[index].Data; // The winding of an edge says how the winding number changes as we // cross from the edge's right face to its left face. We add the // vertices in such an order that a CCW contour will add +1 to // the winding number of the region inside the contour. e._winding = 1; e._Sym._winding = -1; } }
/// <summary> /// MakeVertex( eOrig, vNext ) attaches a new vertex and makes it the /// origin of all edges in the vertex loop to which eOrig belongs. "vNext" gives /// a place to insert the new vertex in the global vertex list. We insert /// the new vertex *before* vNext so that algorithms which walk the vertex /// list will not see the newly created vertices. /// </summary> public static void MakeVertex(IPool pool, Edge eOrig, Vertex vNext) { var vNew = pool.Get <MeshUtils.Vertex>(); // insert in circular doubly-linked list before vNext var vPrev = vNext._prev; vNew._prev = vPrev; vPrev._next = vNew; vNew._next = vNext; vNext._prev = vNew; vNew._anEdge = eOrig; // leave coords, s, t undefined // fix other edges on this vertex loop var e = eOrig; do { e._Org = vNew; e = e._Onext; } while (e != eOrig); }