812 lines
21 KiB
C
812 lines
21 KiB
C
|
/********************************************************************/
|
||
|
/* STRIPE: converting a polygonal model to triangle strips
|
||
|
Francine Evans, 1996.
|
||
|
SUNY @ Stony Brook
|
||
|
Advisors: Steven Skiena and Amitabh Varshney
|
||
|
*/
|
||
|
/********************************************************************/
|
||
|
|
||
|
/*---------------------------------------------------------------------*/
|
||
|
/* STRIPE: common.c
|
||
|
This file contains common code used in both the local and global algorithm
|
||
|
*/
|
||
|
/*---------------------------------------------------------------------*/
|
||
|
|
||
|
|
||
|
#include <stdlib.h>
|
||
|
#include "polverts.h"
|
||
|
#include "extend.h"
|
||
|
#include "output.h"
|
||
|
#include "triangulate.h"
|
||
|
#include "util.h"
|
||
|
#include "add.h"
|
||
|
|
||
|
int Old_Adj(int face_id)
|
||
|
{
|
||
|
/* Find the bucket that the face_id is currently in,
|
||
|
because maybe we will be deleting it.
|
||
|
*/
|
||
|
PF_FACES temp = NULL;
|
||
|
ListHead *pListHead;
|
||
|
int size,y;
|
||
|
|
||
|
pListHead = PolFaces[face_id];
|
||
|
temp = ( PF_FACES ) PeekList( pListHead, LISTHEAD, 0 );
|
||
|
if ( temp == NULL )
|
||
|
{
|
||
|
printf("The face was already deleted, there is an error\n");
|
||
|
exit(0);
|
||
|
}
|
||
|
|
||
|
size = temp->nPolSize;
|
||
|
if (Done(face_id,size,&y) == NULL)
|
||
|
{
|
||
|
printf("There is an error in finding the face\n");
|
||
|
exit(0);
|
||
|
}
|
||
|
return y;
|
||
|
}
|
||
|
|
||
|
int Number_Adj(int id1, int id2, int curr_id)
|
||
|
{
|
||
|
/* Given edge whose endpoints are specified by id1 and id2,
|
||
|
determine how many polygons share this edge and return that
|
||
|
number minus one (since we do not want to include the polygon
|
||
|
that the caller has already).
|
||
|
*/
|
||
|
|
||
|
int size,y,count=0;
|
||
|
PF_EDGES temp = NULL;
|
||
|
PF_FACES temp2 = NULL;
|
||
|
ListHead *pListHead;
|
||
|
BOOL there= FALSE;
|
||
|
|
||
|
/* Always want smaller id first */
|
||
|
switch_lower(&id1,&id2);
|
||
|
|
||
|
pListHead = PolEdges[id1];
|
||
|
temp = (PF_EDGES) PeekList(pListHead,LISTHEAD,count);
|
||
|
if (temp == NULL)
|
||
|
/* new edge that was created might not be here */
|
||
|
return 0;
|
||
|
while (temp->edge[0] != id2)
|
||
|
{
|
||
|
count++;
|
||
|
temp = (PF_EDGES) PeekList(pListHead,LISTHEAD,count);
|
||
|
if (temp == NULL)
|
||
|
/* This edge was not there in the original, which
|
||
|
mean that we created it in the partial triangulation.
|
||
|
So it is adjacent to nothing.
|
||
|
*/
|
||
|
return 0;
|
||
|
}
|
||
|
/* Was not adjacent to anything else except itself */
|
||
|
if (temp->edge[2] == -1)
|
||
|
return 0;
|
||
|
else
|
||
|
{
|
||
|
/* It was adjacent to another polygon, but maybe we did this
|
||
|
polygon already, and it was done partially so that this edge
|
||
|
could have been done
|
||
|
*/
|
||
|
if (curr_id != temp->edge[1])
|
||
|
{
|
||
|
/* Did we use this polygon already?and it was deleted
|
||
|
completely from the structure
|
||
|
*/
|
||
|
pListHead = PolFaces[temp->edge[1]];
|
||
|
temp2 = ( PF_FACES ) PeekList( pListHead, LISTHEAD, 0 );
|
||
|
if (Done(temp->edge[1],temp2->nPolSize,&size) == NULL)
|
||
|
return 0;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
pListHead = PolFaces[temp->edge[2]];
|
||
|
temp2 = ( PF_FACES ) PeekList( pListHead, LISTHEAD, 0 );
|
||
|
if (Done(temp->edge[2],temp2->nPolSize,&size)== NULL)
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
/* Now we have to check whether it was partially done, before
|
||
|
we can say definitely if it is adjacent.
|
||
|
Check each edge of the face and tally the number of adjacent
|
||
|
polygons to this face.
|
||
|
*/
|
||
|
if ( temp2 != NULL )
|
||
|
{
|
||
|
/* Size of the polygon */
|
||
|
size = temp2->nPolSize;
|
||
|
for (y = 0; y< size; y++)
|
||
|
{
|
||
|
/* If we are doing partial triangulation, we must check
|
||
|
to see whether the edge is still there in the polygon,
|
||
|
since we might have done a portion of the polygon
|
||
|
and saved the rest for later.
|
||
|
*/
|
||
|
if (y != (size-1))
|
||
|
{
|
||
|
if( ((id1 == *(temp2->pPolygon+y)) && (id2 ==*(temp2->pPolygon+y+1)))
|
||
|
|| ((id2 == *(temp2->pPolygon+y)) && (id1 ==*(temp2->pPolygon+y+1))))
|
||
|
/* edge is still there we are ok */
|
||
|
there = TRUE;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if( ((id1 == *(temp2->pPolygon)) && (id2 == *(temp2->pPolygon+size-1)))
|
||
|
|| ((id2 == *(temp2->pPolygon)) && (id1 ==*(temp2->pPolygon+size-1))))
|
||
|
/* edge is still there we are ok */
|
||
|
there = TRUE;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (there )
|
||
|
return 1;
|
||
|
return 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
int Min_Adj(int id)
|
||
|
{
|
||
|
/* Used for the lookahead to break ties. It will
|
||
|
return the minimum adjacency found at this face.
|
||
|
*/
|
||
|
int y,numverts,t,x=60;
|
||
|
PF_FACES temp=NULL;
|
||
|
ListHead *pListHead;
|
||
|
|
||
|
/* If polygon was used then we can't use this face */
|
||
|
if (Done(id,59,&y) == NULL)
|
||
|
return 60;
|
||
|
|
||
|
/* It was not used already */
|
||
|
pListHead = PolFaces[id];
|
||
|
temp = ( PF_FACES ) PeekList( pListHead, LISTHEAD, 0 );
|
||
|
if ( temp != NULL )
|
||
|
{
|
||
|
numverts = temp->nPolSize;
|
||
|
for (y = 0; y< numverts; y++)
|
||
|
{
|
||
|
if (y != (numverts-1))
|
||
|
t = Number_Adj(*(temp->pPolygon+y),*(temp->pPolygon+y+1),id);
|
||
|
else
|
||
|
t = Number_Adj(*(temp->pPolygon),*(temp->pPolygon+(numverts-1)),id);
|
||
|
if (t < x)
|
||
|
x = t;
|
||
|
}
|
||
|
}
|
||
|
if (x == -1)
|
||
|
{
|
||
|
printf("Error in the look\n");
|
||
|
exit(0);
|
||
|
}
|
||
|
return x;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
void Edge_Least(int *index,int *new1,int *new2,int face_id,int size)
|
||
|
{
|
||
|
/* We had a polygon without an input edge and now we re going to pick one
|
||
|
of the edges with the least number of adjacencies to be the input
|
||
|
edge
|
||
|
*/
|
||
|
register int x,value,smallest=60;
|
||
|
|
||
|
for (x = 0; x<size; x++)
|
||
|
{
|
||
|
if (x != (size -1) )
|
||
|
value = Number_Adj(*(index+x),*(index+x+1),face_id);
|
||
|
else
|
||
|
value = Number_Adj(*(index),*(index+size-1),face_id);
|
||
|
if (value < smallest)
|
||
|
{
|
||
|
smallest = value;
|
||
|
if (x != (size -1))
|
||
|
{
|
||
|
*new1 = *(index+x);
|
||
|
*new2 = *(index+x+1);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
*new1 = *(index);
|
||
|
*new2 = *(index+size-1);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if ((smallest == 60) || (smallest < 0))
|
||
|
{
|
||
|
printf("There is an error in getting the least edge\n");
|
||
|
exit(0);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
void Check_In_Polygon(int face_id, int *min, int size)
|
||
|
{
|
||
|
/* Check to see the adjacencies by going into a polygon that has
|
||
|
greater than 4 sides.
|
||
|
*/
|
||
|
|
||
|
ListHead *pListHead;
|
||
|
PF_FACES temp;
|
||
|
int y,id1,id2,id3,x=0,z=0;
|
||
|
int saved[2];
|
||
|
int big_saved[60];
|
||
|
|
||
|
pListHead = PolFaces[face_id];
|
||
|
temp = ( PF_FACES ) PeekList( pListHead, LISTHEAD, 0 );
|
||
|
|
||
|
/* Get the input edge that we came in on */
|
||
|
Last_Edge(&id1,&id2,&id3,0);
|
||
|
|
||
|
/* Find the number of adjacencies to the edges that are adjacent
|
||
|
to the input edge.
|
||
|
*/
|
||
|
for (y=0; y< size; y++)
|
||
|
{
|
||
|
if (y != (size-1))
|
||
|
{
|
||
|
if (((*(temp->pPolygon+y) == id2) && (*(temp->pPolygon+y+1) != id3))
|
||
|
|| ((*(temp->pPolygon+y) == id3) && (*(temp->pPolygon+y+1) != id2)))
|
||
|
{
|
||
|
saved[x++] = Number_Adj(*(temp->pPolygon+y),*(temp->pPolygon+y+1),face_id);
|
||
|
big_saved[z++] = saved[x-1];
|
||
|
}
|
||
|
else
|
||
|
big_saved[z++] = Number_Adj(*(temp->pPolygon+y),*(temp->pPolygon+y+1),face_id);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (((*(temp->pPolygon) == id2) && (*(temp->pPolygon+size-1) != id3))
|
||
|
|| ((*(temp->pPolygon) == id3) && (*(temp->pPolygon+size-1) != id2)))
|
||
|
{
|
||
|
saved[x++] = Number_Adj(*(temp->pPolygon),*(temp->pPolygon+size-1),face_id);
|
||
|
big_saved[z++] = saved[x-1];
|
||
|
}
|
||
|
else
|
||
|
big_saved[z++] = Number_Adj(*(temp->pPolygon),*(temp->pPolygon+size-1),face_id);
|
||
|
}
|
||
|
}
|
||
|
/* There was an input edge */
|
||
|
if (x == 2)
|
||
|
{
|
||
|
if (saved[0] < saved[1])
|
||
|
/* Count the polygon that we will be cutting as another adjacency*/
|
||
|
*min = saved[0] + 1;
|
||
|
else
|
||
|
*min = saved[1] + 1;
|
||
|
}
|
||
|
/* There was not an input edge */
|
||
|
else
|
||
|
{
|
||
|
if (z != size)
|
||
|
{
|
||
|
printf("There is an error with the z %d %d\n",size,z);
|
||
|
exit(0);
|
||
|
}
|
||
|
*min = 60;
|
||
|
for (x = 0; x < size; x++)
|
||
|
{
|
||
|
if (*min > big_saved[x])
|
||
|
*min = big_saved[x];
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
void New_Face (int face_id, int v1, int v2, int v3)
|
||
|
{
|
||
|
/* We want to change the face that was face_id, we will
|
||
|
change it to a triangle, since the rest of the polygon
|
||
|
was already outputtted
|
||
|
*/
|
||
|
ListHead *pListHead;
|
||
|
PF_FACES temp = NULL;
|
||
|
|
||
|
pListHead = PolFaces[face_id];
|
||
|
temp = ( PF_FACES ) PeekList( pListHead, LISTHEAD, 0);
|
||
|
/* Check each edge of the face and tally the number of adjacent
|
||
|
polygons to this face.
|
||
|
*/
|
||
|
if ( temp != NULL )
|
||
|
{
|
||
|
/* Size of the polygon */
|
||
|
if (temp->nPolSize != 4)
|
||
|
{
|
||
|
printf("There is a miscalculation in the partial\n");
|
||
|
exit (0);
|
||
|
}
|
||
|
temp->nPolSize = 3;
|
||
|
*(temp->pPolygon) = v1;
|
||
|
*(temp->pPolygon+1) = v2;
|
||
|
*(temp->pPolygon+2) = v3;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void New_Size_Face (int face_id)
|
||
|
{
|
||
|
/* We want to change the face that was face_id, we will
|
||
|
change it to a triangle, since the rest of the polygon
|
||
|
was already outputtted
|
||
|
*/
|
||
|
ListHead *pListHead;
|
||
|
PF_FACES temp = NULL;
|
||
|
|
||
|
pListHead = PolFaces[face_id];
|
||
|
temp = ( PF_FACES ) PeekList( pListHead, LISTHEAD, 0 );
|
||
|
/* Check each edge of the face and tally the number of adjacent
|
||
|
polygons to this face.
|
||
|
*/
|
||
|
if ( temp != NULL )
|
||
|
(temp->nPolSize)--;
|
||
|
else
|
||
|
printf("There is an error in updating the size\n");
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
void Check_In_Quad(int face_id,int *min)
|
||
|
{
|
||
|
/* Check to see what the adjacencies are for the polygons that
|
||
|
are inside the quad, ie the 2 triangles that we can form.
|
||
|
*/
|
||
|
ListHead *pListHead;
|
||
|
int y,id1,id2,id3,x=0;
|
||
|
int saved[4];
|
||
|
PF_FACES temp;
|
||
|
register int size = 4;
|
||
|
|
||
|
pListHead = PolFaces[face_id];
|
||
|
temp = ( PF_FACES ) PeekList( pListHead, LISTHEAD, 0 );
|
||
|
|
||
|
/* Get the input edge that we came in on */
|
||
|
Last_Edge(&id1,&id2,&id3,0);
|
||
|
|
||
|
/* Now find the adjacencies for the inside triangles */
|
||
|
for (y = 0; y< size; y++)
|
||
|
{
|
||
|
/* Will not do this if the edge is the input edge */
|
||
|
if (y != (size-1))
|
||
|
{
|
||
|
if ((((*(temp->pPolygon+y) == id2) && (*(temp->pPolygon+y+1) == id3))) ||
|
||
|
(((*(temp->pPolygon+y) == id3) && (*(temp->pPolygon+y+1) == id2))))
|
||
|
saved[x++] = -1;
|
||
|
else
|
||
|
{
|
||
|
if (x == 4)
|
||
|
{
|
||
|
printf("There is an error in the check in quad \n");
|
||
|
exit(0);
|
||
|
}
|
||
|
/* Save the number of Adjacent Polygons to this edge */
|
||
|
saved[x++] = Number_Adj(*(temp->pPolygon+y),*(temp->pPolygon+y+1),face_id);
|
||
|
}
|
||
|
}
|
||
|
else if ((((*(temp->pPolygon) == id2) && (*(temp->pPolygon+size-1) == id3))) ||
|
||
|
(((*(temp->pPolygon) == id3) && (*(temp->pPolygon+size-1) == id2))) )
|
||
|
saved[x++] = -1;
|
||
|
else
|
||
|
{
|
||
|
if (x == 4)
|
||
|
{
|
||
|
printf("There is an error in the check in quad \n");
|
||
|
exit(0);
|
||
|
}
|
||
|
/* Save the number of Adjacent Polygons to this edge */
|
||
|
saved[x++] = Number_Adj(*(temp->pPolygon),*(temp->pPolygon+size-1),face_id);
|
||
|
|
||
|
}
|
||
|
}
|
||
|
if (x != 4)
|
||
|
{
|
||
|
printf("Did not enter all the values %d \n",x);
|
||
|
exit(0);
|
||
|
}
|
||
|
|
||
|
*min = 10;
|
||
|
for (x=0; x<4; x++)
|
||
|
{
|
||
|
if (x!= 3)
|
||
|
{
|
||
|
if ((saved[x] != -1) && (saved[x+1] != -1) &&
|
||
|
((saved[x] + saved[x+1]) < *min))
|
||
|
*min = saved[x] + saved[x+1];
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if ((saved[0] != -1) && (saved[x] != -1) &&
|
||
|
((saved[x] + saved[0]) < *min))
|
||
|
*min = saved[0] + saved[x];
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
int Get_Output_Edge(int face_id, int size, int *index,int id2,int id3)
|
||
|
{
|
||
|
/* Return the vertex adjacent to either input1 or input2 that
|
||
|
is adjacent to the least number of polygons on the edge that
|
||
|
is shared with either input1 or input2.
|
||
|
*/
|
||
|
register int x=0,y;
|
||
|
int saved[2];
|
||
|
int edges[2][1];
|
||
|
|
||
|
for (y = 0; y < size; y++)
|
||
|
{
|
||
|
if (y != (size-1))
|
||
|
{
|
||
|
if (((*(index+y) == id2) && (*(index+y+1) != id3))
|
||
|
|| ((*(index+y) == id3) && (*(index+y+1) != id2)))
|
||
|
{
|
||
|
saved[x++] = Number_Adj(*(index+y),*(index+y+1),face_id);
|
||
|
edges[x-1][0] = *(index+y+1);
|
||
|
}
|
||
|
else if (y != 0)
|
||
|
{
|
||
|
if (( (*(index+y) == id2) && (*(index+y-1) != id3) ) ||
|
||
|
( (*(index+y) == id3) && (*(index+y-1) != id2)) )
|
||
|
{
|
||
|
saved[x++] = Number_Adj(*(index+y),*(index+y-1),face_id);
|
||
|
edges[x-1][0] = *(index+y-1);
|
||
|
}
|
||
|
}
|
||
|
else if (y == 0)
|
||
|
{
|
||
|
if (( (*(index) == id2) && (*(index+size-1) != id3) ) ||
|
||
|
( (*(index) == id3) && (*(index+size-1) != id2)) )
|
||
|
{
|
||
|
saved[x++] = Number_Adj(*(index),*(index+size-1),face_id);
|
||
|
edges[x-1][0] = *(index+size-1);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (((*(index+size-1) == id2) && (*(index) != id3))
|
||
|
|| ((*(index+size-1) == id3) && (*(index) != id2)))
|
||
|
{
|
||
|
saved[x++] = Number_Adj(*(index),*(index+size-1),face_id);
|
||
|
edges[x-1][0] = *(index);
|
||
|
}
|
||
|
|
||
|
if (( (*(index+size-1) == id2) && (*(index+y-1) != id3) ) ||
|
||
|
( (*(index+size-1) == id3) && (*(index+y-1) != id2)) )
|
||
|
{
|
||
|
saved[x++] = Number_Adj(*(index+size-1),*(index+y-1),face_id);
|
||
|
edges[x-1][0] = *(index+y-1);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if ((x != 2))
|
||
|
{
|
||
|
printf("There is an error in getting the input edge %d \n",x);
|
||
|
exit(0);
|
||
|
}
|
||
|
if (saved[0] < saved[1])
|
||
|
return edges[0][0];
|
||
|
else
|
||
|
return edges[1][0];
|
||
|
|
||
|
}
|
||
|
|
||
|
void Get_Input_Edge(int *index,int id1,int id2,int id3,int *new1,int *new2,int size,
|
||
|
int face_id)
|
||
|
{
|
||
|
/* We had a polygon without an input edge and now we are going to pick one
|
||
|
as the input edge. The last triangle was id1,id2,id3, we will try to
|
||
|
get an edge to have something in common with one of those vertices, otherwise
|
||
|
we will pick the edge with the least number of adjacencies.
|
||
|
*/
|
||
|
|
||
|
register int x;
|
||
|
int saved[3];
|
||
|
|
||
|
saved[0] = -1;
|
||
|
saved[1] = -1;
|
||
|
saved[2] = -1;
|
||
|
|
||
|
/* Go through the edges to see if there is one in common with one
|
||
|
of the vertices of the last triangle that we had, preferably id2 or
|
||
|
id3 since those are the last 2 things in the stack of size 2.
|
||
|
*/
|
||
|
for (x=0; x< size; x++)
|
||
|
{
|
||
|
if (*(index+x) == id1)
|
||
|
{
|
||
|
if (x != (size-1))
|
||
|
saved[0] = *(index+x+1);
|
||
|
else
|
||
|
saved[0] = *(index);
|
||
|
}
|
||
|
|
||
|
if (*(index+x) == id2)
|
||
|
{
|
||
|
if (x != (size-1))
|
||
|
saved[1] = *(index+x+1);
|
||
|
else
|
||
|
saved[1] = *(index);
|
||
|
}
|
||
|
|
||
|
if (*(index+x) == id3)
|
||
|
{
|
||
|
if (x != (size -1))
|
||
|
saved[2] = *(index+x+1);
|
||
|
else
|
||
|
saved[2] = *(index);
|
||
|
}
|
||
|
}
|
||
|
/* Now see what we saved */
|
||
|
if (saved[2] != -1)
|
||
|
{
|
||
|
*new1 = id3;
|
||
|
*new2 = saved[2];
|
||
|
return;
|
||
|
}
|
||
|
else if (saved[1] != -1)
|
||
|
{
|
||
|
*new1 = id2;
|
||
|
*new2 = saved[1];
|
||
|
return;
|
||
|
}
|
||
|
else if (saved[0] != -1)
|
||
|
{
|
||
|
*new1 = id1;
|
||
|
*new2 = saved[0];
|
||
|
return;
|
||
|
}
|
||
|
/* We did not find anything so get the edge with the least number of adjacencies */
|
||
|
Edge_Least(index,new1,new2,face_id,size);
|
||
|
|
||
|
}
|
||
|
|
||
|
int Find_Face(int current_face, int id1, int id2, int *bucket)
|
||
|
{
|
||
|
/* Find the face that is adjacent to the edge and is not the
|
||
|
current face.
|
||
|
*/
|
||
|
register int size,each_poly=0,y,tally=0,count=0;
|
||
|
PF_EDGES temp = NULL;
|
||
|
PF_FACES temp2 = NULL;
|
||
|
ListHead *pListHead;
|
||
|
int next_face;
|
||
|
BOOL there = FALSE;
|
||
|
|
||
|
|
||
|
/* Always want smaller id first */
|
||
|
switch_lower(&id1,&id2);
|
||
|
|
||
|
pListHead = PolEdges[id1];
|
||
|
temp = (PF_EDGES) PeekList(pListHead,LISTHEAD,count);
|
||
|
/* The input edge was a new edge */
|
||
|
if (temp == NULL)
|
||
|
return -1;
|
||
|
|
||
|
while (temp->edge[0] != id2)
|
||
|
{
|
||
|
count++;
|
||
|
temp = (PF_EDGES) PeekList(pListHead,LISTHEAD,count);
|
||
|
/* The input edge was a new edge */
|
||
|
if (temp == NULL)
|
||
|
return -1;
|
||
|
}
|
||
|
/* Was not adjacent to anything else except itself */
|
||
|
if (temp->edge[2] == -1)
|
||
|
return -1;
|
||
|
else
|
||
|
{
|
||
|
if (temp->edge[2] == current_face)
|
||
|
next_face = temp->edge[1];
|
||
|
else
|
||
|
next_face = temp->edge[2];
|
||
|
}
|
||
|
/* We have the other face adjacent to this edge, it is
|
||
|
next_face.
|
||
|
*/
|
||
|
pListHead = PolFaces[next_face];
|
||
|
temp2 = ( PF_FACES ) PeekList( pListHead, LISTHEAD, 0 );
|
||
|
|
||
|
/* See if the face was already deleted, and where
|
||
|
it is if it was not
|
||
|
*/
|
||
|
|
||
|
if (Done(next_face,59,bucket) == NULL)
|
||
|
return -1;
|
||
|
|
||
|
/* Make sure the edge is still in this polygon, and that it is not
|
||
|
done
|
||
|
*/
|
||
|
/* Size of the polygon */
|
||
|
size = temp2->nPolSize;
|
||
|
for (y = 0; y< size; y++)
|
||
|
{
|
||
|
/* Make sure that the edge is still in the
|
||
|
polygon and was not deleted, because if the edge was
|
||
|
deleted, then we used it already.
|
||
|
*/
|
||
|
if (y != (size-1))
|
||
|
{
|
||
|
if( ((id1 == *(temp2->pPolygon+y)) && (id2 ==*(temp2->pPolygon+y+1)))
|
||
|
|| ((id2 == *(temp2->pPolygon+y)) && (id1 ==*(temp2->pPolygon+y+1))))
|
||
|
/* edge is still there we are ok */
|
||
|
there = TRUE;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if( ((id1 == *(temp2->pPolygon)) && (id2 ==*(temp2->pPolygon+size-1)))
|
||
|
|| ((id2 == *(temp2->pPolygon)) && (id1 ==*(temp2->pPolygon+size-1))))
|
||
|
/* edge is still there we are ok */
|
||
|
there = TRUE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (!there)
|
||
|
/* Edge already used and deleted from the polygon*/
|
||
|
return -1;
|
||
|
else
|
||
|
return next_face;
|
||
|
}
|
||
|
|
||
|
BOOL Look_Up(int id1,int id2,int face_id)
|
||
|
{
|
||
|
/* See if the endpoints of the edge specified by id1 and id2
|
||
|
are adjacent to the face with face_id
|
||
|
*/
|
||
|
register int count = 0;
|
||
|
PF_EDGES temp = NULL;
|
||
|
ListHead *pListHead;
|
||
|
PF_FACES temp2 = NULL;
|
||
|
|
||
|
/* Always want smaller id first */
|
||
|
switch_lower(&id1,&id2);
|
||
|
|
||
|
pListHead = PolEdges[id1];
|
||
|
temp = (PF_EDGES) PeekList(pListHead,LISTHEAD,count);
|
||
|
if (temp == NULL)
|
||
|
/* Was a new edge that we created */
|
||
|
return 0;
|
||
|
|
||
|
while (temp->edge[0] != id2)
|
||
|
{
|
||
|
count++;
|
||
|
temp = (PF_EDGES) PeekList(pListHead,LISTHEAD,count);
|
||
|
if (temp == NULL)
|
||
|
/* Was a new edge that we created */
|
||
|
return 0;
|
||
|
}
|
||
|
/* Was not adjacent to anything else except itself */
|
||
|
if ((temp->edge[2] == face_id) || (temp->edge[1] == face_id))
|
||
|
{
|
||
|
/* Edge was adjacent to face, make sure that edge is
|
||
|
still there
|
||
|
*/
|
||
|
if (Exist(face_id,id1,id2))
|
||
|
return 1;
|
||
|
else
|
||
|
return 0;
|
||
|
}
|
||
|
else
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
void Add_Id_Strips(int id, int where)
|
||
|
{
|
||
|
/* Just save the triangle for later */
|
||
|
P_STRIPS pfNode;
|
||
|
|
||
|
pfNode = (P_STRIPS) malloc(sizeof(Strips) );
|
||
|
if ( pfNode )
|
||
|
{
|
||
|
pfNode->face_id = id;
|
||
|
if (where == 1)
|
||
|
AddTail(strips[0],(PLISTINFO) pfNode);
|
||
|
/* We are backtracking in the strip */
|
||
|
else
|
||
|
AddHead(strips[0],(PLISTINFO) pfNode);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
printf("There is not enough memory to allocate for the strips\n");
|
||
|
exit(0);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
int Num_Adj(int id1, int id2)
|
||
|
{
|
||
|
/* Given edge whose endpoints are specified by id1 and id2,
|
||
|
determine how many polygons share this edge and return that
|
||
|
number minus one (since we do not want to include the polygon
|
||
|
that the caller has already).
|
||
|
*/
|
||
|
|
||
|
PF_EDGES temp = NULL;
|
||
|
ListHead *pListHead;
|
||
|
register count=-1;
|
||
|
|
||
|
/* Always want smaller id first */
|
||
|
switch_lower(&id1,&id2);
|
||
|
|
||
|
pListHead = PolEdges[id1];
|
||
|
temp = (PF_EDGES) PeekList(pListHead,LISTHEAD,count);
|
||
|
if (temp == NULL)
|
||
|
{
|
||
|
printf("There is an error in the creation of the table \n");
|
||
|
exit(0);
|
||
|
}
|
||
|
while (temp->edge[0] != id2)
|
||
|
{
|
||
|
count++;
|
||
|
temp = (PF_EDGES) PeekList(pListHead,LISTHEAD,count);
|
||
|
if (temp == NULL)
|
||
|
{
|
||
|
printf("There is an error in the creation of the table\n");
|
||
|
exit(0);
|
||
|
}
|
||
|
}
|
||
|
/* Was not adjacent to anything else except itself */
|
||
|
if (temp->edge[2] == -1)
|
||
|
return 0;
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
|
||
|
void Add_Sgi_Adj(int bucket,int face_id)
|
||
|
{
|
||
|
/* This routine will add the face to the proper bucket,
|
||
|
depending on how many faces are adjacent to it (what the
|
||
|
value bucket should be).
|
||
|
*/
|
||
|
P_ADJACENCIES pfNode;
|
||
|
|
||
|
pfNode = (P_ADJACENCIES) malloc(sizeof(ADJACENCIES) );
|
||
|
if ( pfNode )
|
||
|
{
|
||
|
pfNode->face_id = face_id;
|
||
|
AddHead(array[bucket],(PLISTINFO) pfNode);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
printf("Out of memory for the SGI adj list!\n");
|
||
|
exit(0);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void Find_Adjacencies(int num_faces)
|
||
|
{
|
||
|
register int x,y;
|
||
|
register int numverts;
|
||
|
PF_FACES temp=NULL;
|
||
|
ListHead *pListHead;
|
||
|
|
||
|
/* Fill in the adjacencies data structure for all the faces */
|
||
|
for (x=0;x<num_faces;x++)
|
||
|
{
|
||
|
pListHead = PolFaces[x];
|
||
|
temp = ( PF_FACES ) PeekList( pListHead, LISTHEAD, 0 );
|
||
|
if ( temp != NULL )
|
||
|
{
|
||
|
numverts = temp->nPolSize;
|
||
|
if (numverts != 1)
|
||
|
{
|
||
|
for (y = 0; y< numverts; y++)
|
||
|
{
|
||
|
if (y != (numverts-1))
|
||
|
Add_AdjEdge(*(temp->pPolygon+y),*(temp->pPolygon+y+1),x,y);
|
||
|
|
||
|
else
|
||
|
Add_AdjEdge(*(temp->pPolygon),*(temp->pPolygon+(numverts-1)),x,numverts-1);
|
||
|
|
||
|
}
|
||
|
}
|
||
|
temp = NULL;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|