Example #1
0
/*Added by J.Callut*/
void pqInsertIfSpaceOrGreaterThanMin(ElementType X, PriorityQueue H){

	ElementType min;

	if( ! pqIsFull( H ) )
		pqInsert( X, H );
	else{
		min = pqFindMin(H);
		if(H->compareElementType(&(X),&(min)) > 0){
			pqDeleteMin(H);
			pqInsert( X, H );
		}
	}
}
Example #2
0
static int InitPriorityQ( TESStesselator *tess )
/*
* Insert all vertices into the priority queue which determines the
* order in which vertices cross the sweep line.
*/
{
	PriorityQ *pq;
	TESSvertex *v, *vHead;
	int vertexCount = 0;
	
	vHead = &tess->mesh->vHead;
	for( v = vHead->next; v != vHead; v = v->next ) {
		vertexCount++;
	}
	/* Make sure there is enough space for sentinels. */
	vertexCount += MAX( 8, tess->alloc.extraVertices );
	
	pq = tess->pq = pqNewPriorityQ( &tess->alloc, vertexCount, (int (*)(PQkey, PQkey)) tesvertLeq );
	if (pq == NULL) return 0;

	vHead = &tess->mesh->vHead;
	for( v = vHead->next; v != vHead; v = v->next ) {
		v->pqHandle = pqInsert( &tess->alloc, pq, v );
		if (v->pqHandle == INV_HANDLE)
			break;
	}
	if (v != vHead || !pqInit( &tess->alloc, pq ) ) {
		pqDeletePriorityQ( &tess->alloc, tess->pq );
		tess->pq = NULL;
		return 0;
	}

	return 1;
}
Example #3
0
static int InitPriorityQ( GLUtesselator *tess )
/*
 * Insert all vertices into the priority queue which determines the
 * order in which vertices cross the sweep line.
 */
{
  PriorityQ *pq;
  GLUvertex *v, *vHead;

  /* __gl_pqSortNewPriorityQ */
  pq = tess->pq = pqNewPriorityQ( (int (*)(PQkey, PQkey)) __gl_vertLeq );
  if (pq == NULL) return 0;

  vHead = &tess->mesh->vHead;
  for( v = vHead->next; v != vHead; v = v->next ) {
    v->pqHandle = pqInsert( pq, v ); /* __gl_pqSortInsert */
    if (v->pqHandle == LONG_MAX) break;
  }
  if (v != vHead || !pqInit( pq ) ) { /* __gl_pqSortInit */
    pqDeletePriorityQ(tess->pq);	/* __gl_pqSortDeletePriorityQ */
    tess->pq = NULL;
    return 0;
  }

  return 1;
}
Example #4
0
static int CheckForIntersect( TESStesselator *tess, ActiveRegion *regUp )
/*
* Check the upper and lower edges of the given region to see if
* they intersect.  If so, create the intersection and add it
* to the data structures.
*
* Returns TRUE if adding the new intersection resulted in a recursive
* call to AddRightEdges(); in this case all "dirty" regions have been
* checked for intersections, and possibly regUp has been deleted.
*/
{
	ActiveRegion *regLo = RegionBelow(regUp);
	TESShalfEdge *eUp = regUp->eUp;
	TESShalfEdge *eLo = regLo->eUp;
	TESSvertex *orgUp = eUp->Org;
	TESSvertex *orgLo = eLo->Org;
	TESSvertex *dstUp = eUp->Dst;
	TESSvertex *dstLo = eLo->Dst;
	TESSreal tMinUp, tMaxLo;
	TESSvertex isect, *orgMin;
	TESShalfEdge *e;

	assert( ! VertEq( dstLo, dstUp ));
	assert( EdgeSign( dstUp, tess->event, orgUp ) <= 0 );
	assert( EdgeSign( dstLo, tess->event, orgLo ) >= 0 );
	assert( orgUp != tess->event && orgLo != tess->event );
	assert( ! regUp->fixUpperEdge && ! regLo->fixUpperEdge );

	if( orgUp == orgLo ) return FALSE;	/* right endpoints are the same */

	tMinUp = MIN( orgUp->t, dstUp->t );
	tMaxLo = MAX( orgLo->t, dstLo->t );
	if( tMinUp > tMaxLo ) return FALSE;	/* t ranges do not overlap */

	if( VertLeq( orgUp, orgLo )) {
		if( EdgeSign( dstLo, orgUp, orgLo ) > 0 ) return FALSE;
	} else {
		if( EdgeSign( dstUp, orgLo, orgUp ) < 0 ) return FALSE;
	}

	/* At this point the edges intersect, at least marginally */
	DebugEvent( tess );

	tesedgeIntersect( dstUp, orgUp, dstLo, orgLo, &isect );
	/* The following properties are guaranteed: */
	assert( MIN( orgUp->t, dstUp->t ) <= isect.t );
	assert( isect.t <= MAX( orgLo->t, dstLo->t ));
	assert( MIN( dstLo->s, dstUp->s ) <= isect.s );
	assert( isect.s <= MAX( orgLo->s, orgUp->s ));

	if( VertLeq( &isect, tess->event )) {
		/* The intersection point lies slightly to the left of the sweep line,
		* so move it until it''s slightly to the right of the sweep line.
		* (If we had perfect numerical precision, this would never happen
		* in the first place).  The easiest and safest thing to do is
		* replace the intersection by tess->event.
		*/
		isect.s = tess->event->s;
		isect.t = tess->event->t;
	}
	/* Similarly, if the computed intersection lies to the right of the
	* rightmost origin (which should rarely happen), it can cause
	* unbelievable inefficiency on sufficiently degenerate inputs.
	* (If you have the test program, try running test54.d with the
	* "X zoom" option turned on).
	*/
	orgMin = VertLeq( orgUp, orgLo ) ? orgUp : orgLo;
	if( VertLeq( orgMin, &isect )) {
		isect.s = orgMin->s;
		isect.t = orgMin->t;
	}

	if( VertEq( &isect, orgUp ) || VertEq( &isect, orgLo )) {
		/* Easy case -- intersection at one of the right endpoints */
		(void) CheckForRightSplice( tess, regUp );
		return FALSE;
	}

	if(    (! VertEq( dstUp, tess->event )
		&& EdgeSign( dstUp, tess->event, &isect ) >= 0)
		|| (! VertEq( dstLo, tess->event )
		&& EdgeSign( dstLo, tess->event, &isect ) <= 0 ))
	{
		/* Very unusual -- the new upper or lower edge would pass on the
		* wrong side of the sweep event, or through it.  This can happen
		* due to very small numerical errors in the intersection calculation.
		*/
		if( dstLo == tess->event ) {
			/* Splice dstLo into eUp, and process the new region(s) */
			if (tessMeshSplitEdge( tess->mesh, eUp->Sym ) == NULL) longjmp(tess->env,1);
			if ( !tessMeshSplice( tess->mesh, eLo->Sym, eUp ) ) longjmp(tess->env,1);
			regUp = TopLeftRegion( tess, regUp );
			if (regUp == NULL) longjmp(tess->env,1);
			eUp = RegionBelow(regUp)->eUp;
			FinishLeftRegions( tess, RegionBelow(regUp), regLo );
			AddRightEdges( tess, regUp, eUp->Oprev, eUp, eUp, TRUE );
			return TRUE;
		}
		if( dstUp == tess->event ) {
			/* Splice dstUp into eLo, and process the new region(s) */
			if (tessMeshSplitEdge( tess->mesh, eLo->Sym ) == NULL) longjmp(tess->env,1);
			if ( !tessMeshSplice( tess->mesh, eUp->Lnext, eLo->Oprev ) ) longjmp(tess->env,1); 
			regLo = regUp;
			regUp = TopRightRegion( regUp );
			e = RegionBelow(regUp)->eUp->Rprev;
			regLo->eUp = eLo->Oprev;
			eLo = FinishLeftRegions( tess, regLo, NULL );
			AddRightEdges( tess, regUp, eLo->Onext, eUp->Rprev, e, TRUE );
			return TRUE;
		}
		/* Special case: called from ConnectRightVertex.  If either
		* edge passes on the wrong side of tess->event, split it
		* (and wait for ConnectRightVertex to splice it appropriately).
		*/
		if( EdgeSign( dstUp, tess->event, &isect ) >= 0 ) {
			RegionAbove(regUp)->dirty = regUp->dirty = TRUE;
			if (tessMeshSplitEdge( tess->mesh, eUp->Sym ) == NULL) longjmp(tess->env,1);
			eUp->Org->s = tess->event->s;
			eUp->Org->t = tess->event->t;
		}
		if( EdgeSign( dstLo, tess->event, &isect ) <= 0 ) {
			regUp->dirty = regLo->dirty = TRUE;
			if (tessMeshSplitEdge( tess->mesh, eLo->Sym ) == NULL) longjmp(tess->env,1);
			eLo->Org->s = tess->event->s;
			eLo->Org->t = tess->event->t;
		}
		/* leave the rest for ConnectRightVertex */
		return FALSE;
	}

	/* General case -- split both edges, splice into new vertex.
	* When we do the splice operation, the order of the arguments is
	* arbitrary as far as correctness goes.  However, when the operation
	* creates a new face, the work done is proportional to the size of
	* the new face.  We expect the faces in the processed part of
	* the mesh (ie. eUp->Lface) to be smaller than the faces in the
	* unprocessed original contours (which will be eLo->Oprev->Lface).
	*/
	if (tessMeshSplitEdge( tess->mesh, eUp->Sym ) == NULL) longjmp(tess->env,1);
	if (tessMeshSplitEdge( tess->mesh, eLo->Sym ) == NULL) longjmp(tess->env,1);
	if ( !tessMeshSplice( tess->mesh, eLo->Oprev, eUp ) ) longjmp(tess->env,1);
	eUp->Org->s = isect.s;
	eUp->Org->t = isect.t;
	eUp->Org->pqHandle = pqInsert( &tess->alloc, tess->pq, eUp->Org );
	if (eUp->Org->pqHandle == INV_HANDLE) {
		pqDeletePriorityQ( &tess->alloc, tess->pq );
		tess->pq = NULL;
		longjmp(tess->env,1);
	}
	GetIntersectData( tess, eUp->Org, orgUp, dstUp, orgLo, dstLo );
	RegionAbove(regUp)->dirty = regUp->dirty = regLo->dirty = TRUE;
	return FALSE;
}
Example #5
0
int main()
{
	struct pq_t *p1=NULL, *p2=NULL;
	char cmd[10240];
	size_t cap, keySize, objSize;
	int ret;
	void *data1, *data2;
	int opChoice, pqChoice = 1;
    struct pq_t *now_pq;
    now_pq = p1;
	int keyType, objType;
    int (*cmp)(const void *, const void*);
	data1=malloc(sizeof(double)*10);
	data2=malloc(sizeof(double)*10);
	for(;;)
	{
		if(now_pq==NULL)
		{
			printf("The pq%d needs to be initialized.\n", pqChoice);
            if(pqChoice == 1){
                printf("Init step 1. key type: d for double, others for short:\n");
                scanf("%s",cmd);
                keyType=(cmd[0]=='d')?__DS__DOUBLE__:__DS__SHORT__;
                printf("Init step 2. object type: d for double, others for short:\n");
                scanf("%s",cmd);
                objType=(cmd[0]=='d')?__DS__DOUBLE__:__DS__SHORT__;
            }
            else
                printf("pq2 has same key/object size and cmp as pq1\n");

			printf("Init step 3. Capacity: ");
			scanf("%zu",&cap);
            if(pqChoice == 1)
                now_pq = p1 = pqAlloc();
            else
                now_pq = p2 = pqAlloc();

			if(keyType == __DS__DOUBLE__){
                keySize = sizeof(double);
                cmp = doubleGT; 
            }
            else{
                keySize = sizeof(short);
                cmp = shortGT;
            }
			if(objType == __DS__DOUBLE__)
                objSize = sizeof(double);
            else
                objSize = sizeof(short);

            ret=pqInit(now_pq, keySize, objSize, cap, cmp);
			if(ret)
			{
				puts("Not enough memory.");
				pqFree(now_pq);
				now_pq=NULL;
                if(pqChoice == 1)
                    p1 = NULL;
                else{
                    p2 = NULL;
                    now_pq = p1;
                    pqChoice = 1;
                }
			}
			else
				puts("Initialization done.");
		}
		else
		{
            // printf("now_pq:%x, pq1:%x, pq2:%x\n", now_pq, p1, p2);
			printf("size/capacity: %zu/%zu\n", pqSize(now_pq), pqCap(now_pq));
			printf("now is in Priority Queue %d:\n", pqChoice);
			size_t keySize=pqKeySize(now_pq);
			size_t objSize=pqObjSize(now_pq);
			printf("Valid operations: 1)insert, 2)extract max, 3)max, 4)union, 5)empty,\n");
            printf("                  6)switch to another pq, 7)free 2 pqs, 8)quit\n");
			for(opChoice=0;opChoice<=0||opChoice>8;sscanf(cmd,"%d",&opChoice))
				scanf("%s",cmd);
			if(opChoice==1)
			{
				printf("Input a %s value for key: ",keySize==sizeof(double)?"double":"short");
				getData(keyType,data1);
				printf("Input a %s value for obj: ",objSize==sizeof(double)?"double":"short");
				getData(objType,data2);
				ret=pqInsert(now_pq, data1, data2);
				if(ret == __DS__PQ__FULL__) printf("The pq%d is full!\n", pqChoice);
				else if(ret == __DS__PQ__OBJ_EXIST__){ 
                    printf("The object ");
                    printData(objType, data2);
                    printf(" is in the pq%d now!\n", pqChoice);
                }
			}
			else if(opChoice>=2 && opChoice<=3)
			{
                if(opChoice == 2) ret=pqExtractMax(now_pq, data1, data2);
                else if(opChoice == 3) ret=pqMax(now_pq, data1, data2);
                
                // printf("pq op!\n");
				if(!ret)
				{
					printf("The result is <");
					printData(keyType, data1);
                    printf(", ");
					printData(objType, data2);
					puts(">.");
				}
				else
					printf("The pq%d is empty!\n", pqChoice);
			}
            else if(opChoice==4){
                if(p2 == NULL){
                    printf("pq2 is empty. you can't union it.\n");
                }
                else{
                    printf("Choose you want to union(p1, p2) or union(p2, p1).\n");
                    printf("Input 1 for former, else for latter.\n");
                    char cmd2[1024] = {0};
                    int choice;
                    scanf("%s", cmd2);
                    choice = (cmd2[0]=='1')?1:2;
                    if(choice == 1){
                        ret = pqUnion(p1, p2);
                    }
                    else{
                        ret = pqUnion(p2, p1);
                        if(ret == __DS__PQ__NORMAL__){
                            p1 = p2;
                        }
                    }
                    if(ret == __DS__PQ__NORMAL__){
                        p2 = NULL;
                        pqChoice = 1;
                        now_pq = p1;
                    }
                    else if(ret == __DS__PQ__FULL__)
                        printf("pq1 doesn't have enough place to merge pq2.\n");
                    else if(ret == __DS__PQ__DIFF_SIZE__)
                        printf("You can union two different type priority queues.\n");
                }
            }
			else if(opChoice==5)
			{
				if(pqEmpty(now_pq)) printf("The pq%d is empty.\n", pqChoice);
				else printf("The pq%d is not empty.\n", pqChoice);
			}
            else if(opChoice==6){
                pqChoice = (pqChoice==1)?2:1;
                now_pq = (pqChoice==1)?p1:p2;
            }
			else if(opChoice==7)
			{
                if(p2 != NULL)
                    pqFree(p2);
                if(p1 != NULL)
                    pqFree(p1);
				p1 = p2 = NULL;
                pqChoice = 1;
                now_pq = p1;
			}
			else
				break;
		}
	}
    free(data1);
    free(data2);
	return 0;
}