TESShalfEdge *stackPop( EdgeStack *stack ) { TESShalfEdge *e = NULL; EdgeStackNode *node = stack->top; if (node) { stack->top = node->next; e = node->edge; bucketFree( stack->nodeBucket, node ); } return e; }
static void DeleteRegion( TESStesselator *tess, ActiveRegion *reg ) { if( reg->fixUpperEdge ) { /* It was created with zero winding number, so it better be * deleted with zero winding number (ie. it better not get merged * with a real edge). */ assert( reg->eUp->winding == 0 ); } reg->eUp->activeRegion = NULL; dictDelete( tess->dict, reg->nodeUp ); bucketFree( tess->regionPool, reg ); }
/* tessMeshMakeEdge creates one edge, two vertices, and a loop (face). * The loop consists of the two new half-edges. */ TESShalfEdge *tessMeshMakeEdge( TESSmesh *mesh ) { TESSvertex *newVertex1 = (TESSvertex*)bucketAlloc(mesh->vertexBucket); TESSvertex *newVertex2 = (TESSvertex*)bucketAlloc(mesh->vertexBucket); TESSface *newFace = (TESSface*)bucketAlloc(mesh->faceBucket); TESShalfEdge *e; /* if any one is null then all get freed */ if (newVertex1 == NULL || newVertex2 == NULL || newFace == NULL) { if (newVertex1 != NULL) bucketFree( mesh->vertexBucket, newVertex1 ); if (newVertex2 != NULL) bucketFree( mesh->vertexBucket, newVertex2 ); if (newFace != NULL) bucketFree( mesh->faceBucket, newFace ); return NULL; } e = MakeEdge( mesh, &mesh->eHead ); if (e == NULL) return NULL; MakeVertex( newVertex1, e, &mesh->vHead ); MakeVertex( newVertex2, e->Sym, &mesh->vHead ); MakeFace( newFace, e, &mesh->fHead ); return e; }
/* KillEdge( eDel ) destroys an edge (the half-edges eDel and eDel->Sym), * and removes from the global edge list. */ static void KillEdge( TESSmesh *mesh, TESShalfEdge *eDel ) { TESShalfEdge *ePrev, *eNext; /* Half-edges are allocated in pairs, see EdgePair above */ if( eDel->Sym < eDel ) { eDel = eDel->Sym; } /* delete from circular doubly-linked list */ eNext = eDel->next; ePrev = eDel->Sym->next; eNext->Sym->next = ePrev; ePrev->Sym->next = eNext; bucketFree( mesh->edgeBucket, eDel ); }
/* tessMeshZapFace( fZap ) 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! */ void tessMeshZapFace( TESSmesh *mesh, TESSface *fZap ) { TESShalfEdge *eStart = fZap->anEdge; TESShalfEdge *e, *eNext, *eSym; TESSface *fPrev, *fNext; /* walk around face, deleting edges whose right face is also NULL */ eNext = eStart->Lnext; do { e = eNext; eNext = e->Lnext; e->Lface = NULL; if( e->Rface == NULL ) { /* delete the edge -- see TESSmeshDelete above */ if( e->Onext == e ) { KillVertex( mesh, e->Org, NULL ); } else { /* Make sure that e->Org points to a valid half-edge */ e->Org->anEdge = e->Onext; Splice( e, e->Oprev ); } eSym = e->Sym; if( eSym->Onext == eSym ) { KillVertex( mesh, eSym->Org, NULL ); } else { /* Make sure that eSym->Org points to a valid half-edge */ eSym->Org->anEdge = eSym->Onext; Splice( eSym, eSym->Oprev ); } KillEdge( mesh, e ); } } while( e != eStart ); /* delete from circular doubly-linked list */ fPrev = fZap->prev; fNext = fZap->next; fNext->prev = fPrev; fPrev->next = fNext; bucketFree( mesh->faceBucket, fZap ); }
/* 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. */ static void KillFace( TESSmesh *mesh, TESSface *fDel, TESSface *newLface ) { TESShalfEdge *e, *eStart = fDel->anEdge; TESSface *fPrev, *fNext; /* change the left face of all affected edges */ e = eStart; do { e->Lface = newLface; e = e->Lnext; } while( e != eStart ); /* delete from circular doubly-linked list */ fPrev = fDel->prev; fNext = fDel->next; fNext->prev = fPrev; fPrev->next = fNext; bucketFree( mesh->faceBucket, fDel ); }
/* 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. */ static void KillVertex( TESSmesh *mesh, TESSvertex *vDel, TESSvertex *newOrg ) { TESShalfEdge *e, *eStart = vDel->anEdge; TESSvertex *vPrev, *vNext; /* change the origin of all affected edges */ e = eStart; do { e->Org = newOrg; e = e->Onext; } while( e != eStart ); /* delete from circular doubly-linked list */ vPrev = vDel->prev; vNext = vDel->next; vNext->prev = vPrev; vPrev->next = vNext; bucketFree( mesh->vertexBucket, vDel ); }
/* really tessDictListDelete */ void dictDelete( Dict *dict, DictNode *node ) /*ARGSUSED*/ { node->next->prev = node->prev; node->prev->next = node->next; bucketFree( dict->nodePool, node ); }