Example #1
0
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;
}
Example #2
0
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 );
}
Example #8
0
/* really tessDictListDelete */
void dictDelete( Dict *dict, DictNode *node ) /*ARGSUSED*/
{
	node->next->prev = node->prev;
	node->prev->next = node->next;
	bucketFree( dict->nodePool, node );
}