コード例 #1
0
ファイル: tess.c プロジェクト: OpenCPN/OpenCPN
//	Starting with a valid triangulation, uses the Edge Flip algorithm to
//	refine the triangulation into a Constrained Delaunay Triangulation.
void tessMeshRefineDelaunay( TESSmesh *mesh, TESSalloc *alloc )
{
	// At this point, we have a valid, but not optimal, triangulation.
	// We refine the triangulation using the Edge Flip algorithm
	//
	//  1) Find all internal edges
	//	2) Mark all dual edges
	//	3) insert all dual edges into a queue

	TESSface *f;
	EdgeStack stack;
	TESShalfEdge *e;
	int maxFaces = 0, maxIter = 0, iter = 0;

	stackInit(&stack, alloc);

	for( f = mesh->fHead.next; f != &mesh->fHead; f = f->next ) {
		if ( f->inside) {
			e = f->anEdge;
			do {
				e->mark = EdgeIsInternal(e); // Mark internal edges
				if (e->mark && !e->Sym->mark) stackPush(&stack, e); // Insert into queue
				e = e->Lnext;
			} while (e != f->anEdge);
			maxFaces++;
		}
	}

	// The algorithm should converge on O(n^2), since the predicate is not robust,
	// we'll save guard against infinite loop.
	maxIter = maxFaces * maxFaces;

	// Pop stack until we find a reversed edge
	// Flip the reversed edge, and insert any of the four opposite edges
	// which are internal and not already in the stack (!marked)
	while (!stackEmpty(&stack) && iter < maxIter) {
		e = stackPop(&stack);
		e->mark = e->Sym->mark = 0;
		if (!tesedgeIsLocallyDelaunay(e)) {
			TESShalfEdge *edges[4];
			int i;
			tessMeshFlipEdge(mesh, e);
			// for each opposite edge
			edges[0] = e->Lnext;
			edges[1] = e->Lprev;
			edges[2] = e->Sym->Lnext;
			edges[3] = e->Sym->Lprev;
			for (i = 0; i < 4; i++) {
				if (!edges[i]->mark && EdgeIsInternal(edges[i])) {
					edges[i]->mark = edges[i]->Sym->mark = 1;
					stackPush(&stack, edges[i]);
				}
			}
		}
		iter++;
	}

	stackDelete(&stack);
}
コード例 #2
0
ファイル: tess.c プロジェクト: Aidoru/openscad
/*
	Starting with a valid triangulation, uses the Edge Flip algorithm to
	refine the triangulation into a Constrained Delaunay Triangulation.
*/
int tessMeshRefineDelaunay( TESSmesh *mesh, TESSalloc *alloc )
{
	/* At this point, we have a valid, but not optimal, triangulation.
		 We refine the triangulation using the Edge Flip algorithm */

/*
	 1) Find all internal edges
	 2) Mark all dual edges
	 3) insert all dual edges into a queue
*/
	TESSface *f;
	EdgeStack stack;
	TESShalfEdge *e;
	TESShalfEdge *edges[4];
	stackInit(&stack, alloc);
	for( f = mesh->fHead.next; f != &mesh->fHead; f = f->next ) {
		if ( f->inside) {
			e = f->anEdge;
			do {
				e->mark = EdgeIsInternal(e); /* Mark internal edges */
				if (e->mark && !e->Sym->mark) stackPush(&stack, e); /* Insert into queue */
				e = e->Lnext;
			} while (e != f->anEdge);
		}
	}
	
	// Pop stack until we find a reversed edge
	// Flip the reversed edge, and insert any of the four opposite edges
	// which are internal and not already in the stack (!marked)
	while (!stackEmpty(&stack)) {
		e = stackPop(&stack);
		e->mark = e->Sym->mark = 0;
		if (!tesedgeIsLocallyDelaunay(e)) {
			int i;
			tessMeshFlipEdge(mesh, e);
			// for each opposite edge
			edges[0] = e->Lnext;
			edges[1] = e->Lprev;
			edges[2] = e->Sym->Lnext;
			edges[3] = e->Sym->Lprev;
			for (i=0;i<3;i++) {
				if (!edges[i]->mark && EdgeIsInternal(edges[i])) {
					edges[i]->mark = edges[i]->Sym->mark = 1;
					stackPush(&stack, edges[i]);
				}
			}
		}
	}
	
	stackDelete(&stack);

	return 1;
}
コード例 #3
0
ファイル: mesh.c プロジェクト: DINKIN/omim
void tessMeshFlipEdge( TESSmesh *mesh, TESShalfEdge *edge )
{
	TESShalfEdge *a0 = edge;
	TESShalfEdge *a1 = a0->Lnext;
	TESShalfEdge *a2 = a1->Lnext;
	TESShalfEdge *b0 = edge->Sym;
	TESShalfEdge *b1 = b0->Lnext;
	TESShalfEdge *b2 = b1->Lnext;

	TESSvertex *aOrg = a0->Org;
	TESSvertex *aOpp = a2->Org;
	TESSvertex *bOrg = b0->Org;
	TESSvertex *bOpp = b2->Org;

	TESSface *fa = a0->Lface;
	TESSface *fb = b0->Lface;

	assert(EdgeIsInternal(edge));
	assert(a2->Lnext == a0);
	assert(b2->Lnext == b0);

	a0->Org = bOpp;
	a0->Onext = b1->Sym;
	b0->Org = aOpp;
	b0->Onext = a1->Sym;
	a2->Onext = b0;
	b2->Onext = a0;
	b1->Onext = a2->Sym;
	a1->Onext = b2->Sym;

	a0->Lnext = a2;
	a2->Lnext = b1;
	b1->Lnext = a0;

	b0->Lnext = b2;
	b2->Lnext = a1;
	a1->Lnext = b0;

	a1->Lface = fb;
	b1->Lface = fa;

	fa->anEdge = a0;
	fb->anEdge = b0;

	if (aOrg->anEdge == a0) aOrg->anEdge = b1;
	if (bOrg->anEdge == b0) bOrg->anEdge = a1;

	assert( a0->Lnext->Onext->Sym == a0 );
	assert( a0->Onext->Sym->Lnext == a0 );
	assert( a0->Org->anEdge->Org == a0->Org );


	assert( a1->Lnext->Onext->Sym == a1 );
	assert( a1->Onext->Sym->Lnext == a1 );
	assert( a1->Org->anEdge->Org == a1->Org );

	assert( a2->Lnext->Onext->Sym == a2 );
	assert( a2->Onext->Sym->Lnext == a2 );
	assert( a2->Org->anEdge->Org == a2->Org );

	assert( b0->Lnext->Onext->Sym == b0 );
	assert( b0->Onext->Sym->Lnext == b0 );
	assert( b0->Org->anEdge->Org == b0->Org );

	assert( b1->Lnext->Onext->Sym == b1 );
	assert( b1->Onext->Sym->Lnext == b1 );
	assert( b1->Org->anEdge->Org == b1->Org );

	assert( b2->Lnext->Onext->Sym == b2 );
	assert( b2->Onext->Sym->Lnext == b2 );
	assert( b2->Org->anEdge->Org == b2->Org );

	assert(aOrg->anEdge->Org == aOrg);
	assert(bOrg->anEdge->Org == bOrg);

	assert(a0->Oprev->Onext->Org == a0->Org);
}