/********************************************************************/
/*   STRIPE: converting a polygonal model to triangle strips    
     Francine Evans, 1996.
     SUNY @ Stony Brook
     Advisors: Steven Skiena and Amitabh Varshney
*/
/********************************************************************/

/*---------------------------------------------------------------------*/
/*   STRIPE: newpolve.c
     This routine contains the bulk of the code that will find the
     patches of quads in the data model
*/
/*---------------------------------------------------------------------*/

#include <stdlib.h>
#include "polverts.h"
#include "extend.h"
#include "output.h"
#include "triangulate.h"
#include "common.h"
#include "util.h"
#include "global.h"        
#include "init.h"
#include "add.h"

ListHead **PolVerts;
ListHead **PolFaces;
ListHead **PolEdges;
int length;
BOOL resetting = FALSE;
int     ids[STRIP_MAX];
int 	added_quad = 0;
BOOL reversed = FALSE;
int patch = 0;
extern int *vn;
extern int *vt;

int Calculate_Walks(int lastvert,int y, PF_FACES temp2)
{
	/* Find the length of the walk */
	
	int previous_edge1, previous_edge2;
	register int nextvert,numverts,counter,walk=0;
	BOOL flag;
	F_EDGES *node;
     ListHead *pListHead;
     static int seen = 0;
     
	/* Find the edge that we are currently on */
	if (y != 3)
	{
		previous_edge1 = *(temp2->pPolygon +y);
		previous_edge2 = *(temp2->pPolygon + y + 1);
	}
	else
	{
		previous_edge1 = *(temp2->pPolygon +y);
		previous_edge2 = *(temp2->pPolygon);
	}

	temp2->seen = seen;
     counter = y;

     /*Find the adjacent face to this edge */
	node = *(temp2->VertandId+y);			
	if (node->edge[2] != lastvert)
        nextvert = node->edge[2];
     else
        nextvert = node->edge[1];
					
	/* Keep walking in this direction until we cannot do so */
	while ((nextvert != lastvert) && (nextvert != -1))
	{
		walk++;
		pListHead = PolFaces[nextvert];
		temp2 = (PF_FACES) PeekList(pListHead,LISTHEAD,0);
		numverts = temp2->nPolSize;
		if ((numverts != 4) || (temp2->seen == seen))
		{
			walk--;
			nextvert = -1;
		}
		else
		{
			temp2->seen = seen;
               /* Find edge that is not adjacent to the previous one */
			counter = 0;
			flag = TRUE;
			while ((counter < 3) && (flag))
			{
				if ( ((*(temp2->pPolygon+counter) == previous_edge1) ||
					(*(temp2->pPolygon+counter+1) == previous_edge2)) ||
					((*(temp2->pPolygon+counter) == previous_edge2) || 
					(*(temp2->pPolygon+counter+1) == previous_edge1)) )
					counter++;		
				else
					flag = FALSE;	
			}
	     	/* Get the IDs of the next edge */
		     if (counter < 3)
		     {
			     previous_edge1 = *(temp2->pPolygon + counter);
			     previous_edge2 = *(temp2->pPolygon + counter + 1);
		     }
		     else
		     {
                    previous_edge1 = *(temp2->pPolygon + counter);
                    previous_edge2 = *(temp2->pPolygon);
		     }
	
		     node = *(temp2->VertandId + counter);
		     if (node->edge[1] == nextvert)
			     nextvert = node->edge[2];
		     else
			     nextvert = node->edge[1];
		}
	}
     seen++;
	return walk;
}


BOOL Check_Right(int last_seen,PF_FACES temp2,int y,int face_id)
{
	/* Check when we last saw the face to the right of the current
	   one. We want to have seen it just before we started this strip
	*/

	F_EDGES *node;
	ListHead *pListHead;
	register int nextvert,oldy;
	PF_FACES t;
	
     oldy = y;
	if (y != 3)
		y = y+1;
	else
		y = 0;
	node = *(temp2->VertandId + y);
	if (face_id == node->edge[1])
		nextvert = node->edge[2];
	else
		nextvert = node->edge[1];
	
     if (nextvert == -1)
          return FALSE;
     
     pListHead = PolFaces[nextvert];
	t = (PF_FACES) PeekList(pListHead,LISTHEAD,0);
	if (t->seen != (last_seen - 1))
	{
		 /* maybe because of the numbering, we are not
		    on the right orientation, so we have to check the
		    opposite one to be sure 
           */
		if (oldy != 0)
			y = oldy-1;
		else
			y = 3;
		node = *(temp2->VertandId + y);
		if (face_id == node->edge[1])
			nextvert = node->edge[2];
		else
			nextvert = node->edge[1];
		if (nextvert == -1)
               return FALSE;
          pListHead = PolFaces[nextvert];
		t = (PF_FACES) PeekList(pListHead,LISTHEAD,0);
		if (t->seen != (last_seen - 1))
		 	return FALSE;
	}
	return TRUE;
}


int Update_and_Test(PF_FACES temp2,int y,BOOL first,int distance,int lastvert, int val)
{
	     
        static int last_seen = 17;
        int previous_edge1, previous_edge2;
        register int original_distance,nextvert,numverts,counter;
        BOOL flag;
        F_EDGES *node;
        ListHead *pListHead;
                                                        
        original_distance = distance;
        /* Find the edge that we are currently on */
        if (y != 3)
        {
                previous_edge1 = *(temp2->pPolygon +y);
                previous_edge2 = *(temp2->pPolygon + y + 1);
        }
        else
        {
                previous_edge1 = *(temp2->pPolygon +y);
                previous_edge2 = *(temp2->pPolygon);
        }

        temp2->seen = val;
        temp2->seen2 = val;
		
        node = *(temp2->VertandId+y);                   
        if (lastvert != node->edge[2])
			nextvert = node->edge[2];
	   else
			nextvert = node->edge[1];
                                        
        /* Keep walking in this direction until we cannot do so  or
		we go to distance */
        while ((distance > 0)  && (nextvert != lastvert) && (nextvert != -1))
        {
                distance--;
			           
                pListHead = PolFaces[nextvert];
                temp2 = (PF_FACES) PeekList(pListHead,LISTHEAD,0);
                temp2->seen = val;
				
                if (temp2->seen2 == val)
                {
                     last_seen++;
                     return (original_distance - distance);
                }
                
                temp2->seen2 = val;
                
                numverts = temp2->nPolSize;
                                
	     	 if (numverts != 4)
          	     nextvert = -1;
		
                else if ((!first) && (!(Check_Right(last_seen,temp2,y,nextvert))))
                {
                    last_seen++;
                    return (original_distance - distance);
                }
		      else
                {
                        /* Find edge that is not adjacent to the previous one */
                        counter = 0;
                        flag = TRUE;
                        while ((counter < 3) && (flag))
                        {
                                if ( ((*(temp2->pPolygon+counter) == previous_edge1) ||
                                        (*(temp2->pPolygon+counter+1) == previous_edge2)) ||
                                        ((*(temp2->pPolygon+counter) == previous_edge2) ||
                                        (*(temp2->pPolygon+counter+1) == previous_edge1)) )
                                        counter++;
                                else
                                        flag = FALSE;
                        }
                        /* Get the IDs of the next edge */
                        if (counter < 3)
                        {
                              previous_edge1 = *(temp2->pPolygon + counter);
                              previous_edge2 = *(temp2->pPolygon + counter + 1);
                        }
                        else
                        {
                              previous_edge1 = *(temp2->pPolygon + counter);
                              previous_edge2 = *(temp2->pPolygon);
                        }
                        if      ( ((*(temp2->walked+counter) == -1) && 
                                (*(temp2->walked+counter+2) == -1)))
                        {
                                printf("There is an error in the walks!\n");
                                printf("1Code %d %d \n",*(temp2->walked+counter),*(temp2->walked+counter+2));
                                exit(0);
                        }
                        else
                        {
                                if      ((*(temp2->walked+counter) == -1) && 
                                        (*(temp2->walked+counter-2) ==  -1))
                                {
                                        printf("There is an error in the walks!\n");
                                        printf("2Code %d %d \n",*(temp2->walked+counter),*(temp2->walked+counter-2));
                                        exit(0);
                                }
                        }
                        node = *(temp2->VertandId + counter);
                        y = counter;
		              if (node->edge[1] == nextvert)
                              nextvert = node->edge[2];
                        else
                              nextvert = node->edge[1];
             }
    }
	
    last_seen++;

    if  (distance != 0)  
    {
		if (((nextvert == -1) || (nextvert == lastvert)) && (distance != 1))
			return (original_distance - distance);
    }
    return original_distance;
}


int Test_Adj(PF_FACES temp2,int x,int north,int distance,int lastvert, int value)
{
	/* if first time, then just update the last seen field */
	if (x==1)
		return(Update_and_Test(temp2,north,TRUE,distance,lastvert,value));
	/* else we have to check if we are adjacent to the last strip */
	else
		return(Update_and_Test(temp2,north,FALSE,distance,lastvert,value));
}
  
void Get_Band_Walk(PF_FACES temp2,int face_id,int *dir1,int *dir2, 
					int orientation,int cutoff_length)
{
	int previous_edge1, previous_edge2;
	F_EDGES *node;
	ListHead *pListHead;
	register int walk = 0, nextvert,numverts,counter;
	BOOL flag;
	
	/*	Get the largest band that will include this face, starting
		from orientation. Save the values of the largest band
		(either north and south together, or east and west together)
		in the direction variables.
	*/
	/* Find the edge that we are currently on */
     if (orientation != 3)
     {
                previous_edge1 = *(temp2->pPolygon + orientation);
                previous_edge2 = *(temp2->pPolygon + orientation + 1);
     }
     else
     {
                previous_edge1 = *(temp2->pPolygon + orientation );
                previous_edge2 = *(temp2->pPolygon);
     }
		
     if (orientation == 0)
     {
			 if (*dir1 > *(temp2->walked + 1))
				*dir1 = *(temp2->walked + 1);
			 if (*dir2 > *(temp2->walked + 3))
				*dir2 = *(temp2->walked + 3);
	}
	else if (orientation == 3)
	{
			if (*dir1 > *(temp2->walked + orientation - 3))
			     *dir1 = *(temp2->walked + orientation - 3) ;
			if (*dir2 > *(temp2->walked + orientation -1 ))
				*dir2 = *(temp2->walked + orientation - 1);
	}
	else
	{
			if (*dir1 > *(temp2->walked + orientation - 1))
				*dir1 = *(temp2->walked + orientation -1) ;
			if (*dir2 > *(temp2->walked+ orientation + 1))
				*dir2 = *(temp2->walked + orientation + 1);
	}
        
     /*	if we know already that we can't extend the
        	band from this face, we do not need to do the walk
     */
     if ((*dir1 != 0) && (*dir2 != 0))
     {
		/* Find the adjacent face to this edge */
        	node = *(temp2->VertandId+orientation);                   
        	if (face_id == node->edge[1])
			nextvert = node->edge[2];
        	else 
			nextvert = node->edge[1];
	}
     else
        	nextvert = -1; /* leave w/o walking */                                
	
	/* Keep walking in this direction until we cannot do so */
     while ((nextvert != face_id) && (nextvert != -1))
     {
            walk++;
            pListHead = PolFaces[nextvert];
            temp2 = (PF_FACES) PeekList(pListHead,LISTHEAD,0);
            numverts = temp2->nPolSize;
            if ((numverts != 4)	|| (walk > cutoff_length))
                   nextvert = -1;
            else
            {
	  		  /* Find edge that is not adjacent to the previous one */
                 counter = 0;
                 flag = TRUE;
                 while ((counter < 3) && (flag))
                 {
                           if ( ((*(temp2->pPolygon+counter) == previous_edge1) ||
                                (*(temp2->pPolygon+counter+1) == previous_edge2)) ||
                                ((*(temp2->pPolygon+counter) == previous_edge2) ||
                                (*(temp2->pPolygon+counter+1) == previous_edge1)) )
                                     counter++;
                           else
                                flag = FALSE;
                 }
                 /* Get the IDs of the next edge */
                 if (counter < 3)
                 {
                        previous_edge1 = *(temp2->pPolygon + counter);
                        previous_edge2 = *(temp2->pPolygon + counter + 1);
                 }
                 else
                 {
                        previous_edge1 = *(temp2->pPolygon + counter);
                        previous_edge2 = *(temp2->pPolygon);
                 }
                
			  /* 	find out how far we can extend in the 2 directions
					along this new face in the walk
			  */
			  if (counter == 0)
			  {
					if (*dir1 > *(temp2->walked + 1))
						*dir1 = *(temp2->walked + 1);
					if (*dir2 > *(temp2->walked + 3))
						*dir2 = *(temp2->walked + 3);
			  }
			  else if (counter == 3)
			  {
					if (*dir1 > *(temp2->walked + counter - 3))
						*dir1 = *(temp2->walked + counter - 3) ;
					if (*dir2 > *(temp2->walked + counter -1 ))
						*dir2 = *(temp2->walked + counter -1);
			  }
			  else
			  {
					if (*dir1 > *(temp2->walked + counter - 1))
						*dir1 = *(temp2->walked + counter -1) ;
					if (*dir2 > *(temp2->walked + counter + 1))
						*dir2 = *(temp2->walked + counter + 1);
			  }
        
        	      /*	if we know already that we can't extend the
        	     	band from this face, we do not need to do the walk
        	      */
	        	 if ((*dir1 == 0) || (*dir2 == 0))
                	nextvert = -1;
                if (nextvert != -1)
                {
                	node = *(temp2->VertandId + counter);
                	if (node->edge[1] == nextvert)
                        nextvert = node->edge[2];
                	else
                        nextvert = node->edge[1];
                }

           }
        }
}




int Find_Max(PF_FACES temp2,int lastvert,int north,int left,
			int *lastminup,int *lastminleft)
{
	int temp,walk,counter,minup,x,band_value;
	int previous_edge1, previous_edge2;
	F_EDGES	*node;
	ListHead *pListHead;
	BOOL flag;	
	static int last_seen = 0;
	register int smallest_so_far,nextvert,max=-1;
	        
     *lastminup = MAX_BAND;
	*lastminleft = 1;

     if (left == 3)
	{
          previous_edge1 = *(temp2->pPolygon + left);
          previous_edge2 = *(temp2->pPolygon);
	}
                
	else
	{
          previous_edge1 = *(temp2->pPolygon + left + 1);
          previous_edge2 = *(temp2->pPolygon + left);
	}

	temp2->seen = last_seen;
     walk = *(temp2->walked + left);

     for (x=1;x<=(walk+1); x++)
	{
		/*   test to see if we have a true band
		     that is, are they adjacent to each other
		*/
        
         minup = *(temp2->walked + north) + 1;

	    /*	if we are at the very first face, then we do not
	    	     have to check the adjacent faces going up
	    	     and our north distance is the distance of this face's
			north direction. 
	    */
         if (x == 1) 
	    {
			*lastminup = minup;
			minup = Test_Adj(temp2,x,north,*lastminup,lastvert,last_seen);
			*lastminup = minup;
               smallest_so_far = minup;	
         }
		
	
	    /* find the largest band that we can have */
	    if (minup < (*lastminup))
	    {
			/*	see if we really can go up all the way 
				temp should by less than our equal to minup
				if it is less, then one of the faces was not
				adjacent to those next to it and the band height
				will be smaller
			*/
			temp = Test_Adj(temp2,x,north,minup,lastvert,last_seen);
			if (temp > minup)
			{
				printf("There is an error in the test adj\n");
				exit(0);
			}
			minup = temp;
			band_value = x * minup;
			if (minup < smallest_so_far)
			{
				if (band_value > max)
               	{
					smallest_so_far = minup;
					*lastminup = minup;
					*lastminleft = x;
                         max = band_value;
                    }
				else
					smallest_so_far = minup;
			}
			else
			{
				band_value = x * smallest_so_far;
     	          if (band_value > max)
                    {
                	     *lastminup = smallest_so_far;
                         *lastminleft = x;
                         max = band_value;
                    }
			}
		}
		else
		{
			if (x != 1)
               {
                    temp = Test_Adj(temp2,x,north,smallest_so_far,lastvert,last_seen);
			     if (temp > smallest_so_far)
			     {
				    printf("There is an error in the test adj\n");
				    exit(0);
			     }
			    smallest_so_far = temp;
               }
               band_value = x * smallest_so_far; 
			if (band_value > max)
			{
				*lastminup = smallest_so_far;
				*lastminleft = x;
				max = band_value;
			}
		}
		if ( x != (walk + 1))
		{
			node = *(temp2->VertandId+left);
			if (lastvert == node->edge[1])
				nextvert = node->edge[2];
			else
				nextvert = node->edge[1];

               lastvert = nextvert;
               
               if (nextvert == -1)
                    return max;
               
               pListHead = PolFaces[nextvert];
			temp2 = (PF_FACES) PeekList(pListHead, LISTHEAD, 0);
			
               /* if we have visited this face before, then there is an error */
               if (((*(temp2->walked) == -1) && (*(temp2->walked+1) == -1) &&
				(*(temp2->walked+2) == -1) && (*(temp2->walked+3) == -1))
				|| (temp2->nPolSize !=4) || (temp2->seen == last_seen))
			{

                    if (lastvert == node->edge[1])
                         nextvert = node->edge[2];
                    else
                         nextvert = node->edge[1];
                    if (nextvert == -1)
                         return max;
                    lastvert = nextvert;
                    /*   Last attempt to get the face ... */
                    pListHead = PolFaces[nextvert];
     			temp2 = (PF_FACES) PeekList(pListHead, LISTHEAD, 0);
                    if (((*(temp2->walked) == -1) && (*(temp2->walked+1) == -1) &&
				     (*(temp2->walked+2) == -1) && (*(temp2->walked+3) == -1))
				     || (temp2->nPolSize !=4) || (temp2->seen == last_seen))
                         return max;    /*   The polygon was not saved with the edge, not
                                             enough room. We will get the walk when we come
                                             to that polygon later.
                                        */
			}
			/*else
			{*/
				counter = 0;
				flag = TRUE;
				temp2->seen = last_seen;

                    while ((counter < 3) && (flag))
			     {

                         if ( ((*(temp2->pPolygon+counter) == previous_edge1) ||
                                        (*(temp2->pPolygon+counter+1) == previous_edge2)) ||
                                        ((*(temp2->pPolygon+counter) == previous_edge2) ||
                                        (*(temp2->pPolygon+counter+1) == previous_edge1)) )
                                        counter++;
				     else
                                        flag = FALSE;
                    }
               /*}*/
		
               /* Get the IDs of the next edge */
               left = counter;
		     north = left+1;
               if (left ==3)
			     north = 0;	
		     if (counter < 3)
               {
                        previous_edge1 = *(temp2->pPolygon + counter + 1);
                        previous_edge2 = *(temp2->pPolygon + counter);
               }
               else
               {
                        previous_edge1 = *(temp2->pPolygon + counter);
                        previous_edge2 = *(temp2->pPolygon);
               }

          } 

}
last_seen++;
return max;
}

void Mark_Face(PF_FACES temp2, int color1, int color2,
				int color3, FILE *output_file, BOOL end, int *edge1, int *edge2, 
                    int *face_id, int norms, int texture)
{
     static int last_quad[4];
     int x,y,z=0;
     int saved[2];
     static int output1, output2,last_id;
     BOOL cptexture = FALSE;

     /*   Are we done with the patch? If so return the last edge that
          we will come out on, and that will be the edge that we will
          start to extend upon.
     */

     if (end)
     {
          *edge1 = output1;
          *edge2 = output2;
          *face_id = last_id;
          return;
     }

     cptexture = texture;
     last_id = *face_id;
	*(temp2->walked) = -1;
	*(temp2->walked+1) = -1;
	*(temp2->walked+2) = -1;
	*(temp2->walked+3) = -1;
	added_quad++;
	temp2->nPolSize = 1;

     if (patch == 0)
     {
          /*   At the first quad in the strip -- save it */
          last_quad[0] = *(temp2->pPolygon);
          last_quad[1] = *(temp2->pPolygon+1);
          last_quad[2] = *(temp2->pPolygon+2);
          last_quad[3] = *(temp2->pPolygon+3);
          patch++;
     }
     else
     {
          /*   Now we have a triangle to output, find the edge in common */
          for (x=0; x < 4 ;x++)
          {
              for (y=0; y< 4; y++)
              {
                   if (last_quad[x] == *(temp2->pPolygon+y))
                   {
                        saved[z++] = last_quad[x];               
                        if (z > 2)
                        {
                             /*    This means that there was a non convex or
                                   an overlapping polygon
                             */
                             z--;
                             break;
                        }
                   }                             
              }
          }
          
          if (z != 2)
          {
               printf("Z is not 2 %d \n",patch);
               printf("4 %d %d %d %d %d %d %d\n",*(temp2->pPolygon),
				*(temp2->pPolygon+1),*(temp2->pPolygon+2),*(temp2->pPolygon+3),
				color1,color2,color3);
               printf("%d %d %d %d\n",last_quad[0],last_quad[1],last_quad[2],last_quad[3]);
               exit(1);
          }
          
          if (patch == 1)
          {
               /*   First one to output, there was no output edge */
               patch++;
               x = Adjacent(saved[0],saved[1],last_quad,4);
               y = Adjacent(saved[1],saved[0],last_quad,4);
               
               /*   Data might be mixed and we do not have textures for some of the vertices */
               if ((texture) && ( ((vt[x]) == 0) || ((vt[y])==0) || ((vt[saved[1]])==0)))
                    cptexture = FALSE;

               if ((!norms) && (!cptexture))
               {
                    fprintf(output_file,"\nt %d %d %d ",x+1,y+1,saved[1]+1);
                    fprintf(output_file,"%d ",saved[0]+1);
               }
               else if ((norms) && (!cptexture))
               {
                    fprintf(output_file,"\nt %d//%d %d//%d %d//%d ",x+1,vn[x] +1,
                                                                    y+1,vn[y] +1,
                                                                    saved[1]+1,vn[saved[1]]+1);
                    fprintf(output_file,"%d//%d ",saved[0]+1,vn[saved[0]]+1);
               }
               else if ((cptexture) && (!norms))
               {
                    fprintf(output_file,"\nt %d/%d %d/%d %d/%d ",x+1,vt[x] +1,
                                                                    y+1,vt[y] +1,
                                                                    saved[1]+1,vt[saved[1]]+1);
                    fprintf(output_file,"%d//%d ",saved[0]+1,vt[saved[0]]+1);
               }
               else
               {
                    fprintf(output_file,"\nt %d/%d/%d %d/%d/%d %d/%d/%d ",x+1,vt[x]+1,vn[x] +1,
                                                                    y+1,vt[y]+1,vn[y] +1,
                                                                    saved[1]+1,vt[saved[1]]+1,vn[saved[1]]+1);
                    fprintf(output_file,"%d/%d/%d ",saved[0]+1,vt[saved[0]]+1,vn[saved[0]]+1);
               }

               x = Adjacent(saved[0],saved[1],temp2->pPolygon,4);
               y = Adjacent(saved[1],saved[0],temp2->pPolygon,4);

               /*   Data might be mixed and we do not have textures for some of the vertices */
               if ((texture) && ( (vt[x] == 0) || (vt[y]==0)))
               {
                    if (cptexture)
                         fprintf(output_file,"\nq ");
                    cptexture = FALSE;
               }
               if ((!norms) && (!cptexture))
               {
                    fprintf(output_file,"%d ",x+1);
                    fprintf(output_file,"%d ",y+1);
               }
               else if ((norms) && (!cptexture))
               {
                    fprintf(output_file,"%d//%d ",x+1,vn[x]+1);
                    fprintf(output_file,"%d//%d ",y+1,vn[y]+1);
               }
               else if ((cptexture) && (!norms))
               {
                    fprintf(output_file,"%d/%d ",x+1,vt[x]+1);
                    fprintf(output_file,"%d/%d ",y+1,vt[y]+1);
               }
               else
               {
                    fprintf(output_file,"%d/%d/%d ",x+1,vt[x]+1,vn[x]+1);
                    fprintf(output_file,"%d/%d/%d ",y+1,vt[y]+1,vn[y]+1);
               }

               output1 = x;
               output2 = y;
          }
          
          else 
          {
               x = Adjacent(output2,output1,temp2->pPolygon,4);
               y = Adjacent(output1,output2,temp2->pPolygon,4);
               /*   Data might be mixed and we do not have textures for some of the vertices */
               if ((texture) && ( ((vt[x]) == 0) || ((vt[y])==0) ))
                    texture = FALSE;

               if ((!norms) && (!texture))
               {
                    fprintf(output_file,"\nq %d ",x+1);
                    fprintf(output_file,"%d ",y+1);
               }
               else if ((norms) && (!texture))
               {
                    fprintf(output_file,"\nq %d//%d ",x+1,vn[x]+1);
                    fprintf(output_file,"%d//%d ",y+1,vn[y]+1);
               }
               else if ((texture) && (!norms))
               {
                    fprintf(output_file,"\nq %d/%d ",x+1,vt[x]+1);
                    fprintf(output_file,"%d/%d ",y+1,vt[y]+1);
               }
               else
               {
                    fprintf(output_file,"\nq %d/%d/%d ",x+1,vt[x]+1,vn[x]+1);
                    fprintf(output_file,"%d/%d/%d ",y+1,vt[y]+1,vn[y]+1);
               }
               
               output1 = x;
               output2 = y;
          }
          
          last_quad[0] = *(temp2->pPolygon);
          last_quad[1] = *(temp2->pPolygon+1);
          last_quad[2] = *(temp2->pPolygon+2);
          last_quad[3] = *(temp2->pPolygon+3);
     }
}

void Fast_Reset(int x)
{
	register int y,numverts;
	register int front_walk, back_walk;
	ListHead *pListHead;
	PF_FACES temp = NULL;

     pListHead = PolFaces[x];
	temp = (PF_FACES) PeekList(pListHead,LISTHEAD,0);
	numverts = temp->nPolSize;
     
     front_walk = 0; 
     back_walk = 0;          
     resetting = TRUE;
          
     /* we are doing this only for quads */
	if (numverts == 4)
	{
			/* 	for each face not seen yet, do North and South together
				and East and West together
			*/
			for (y=0;y<2;y++)
			{
				/* Check if the opposite sides were seen already */
	     		/* Find walk for the first edge */
				front_walk = Calculate_Walks(x,y,temp);
				/* Find walk in the opposite direction */
				back_walk = Calculate_Walks(x,y+2,temp);
				/* 	Now put into the data structure the numbers that
		          	we have found
				*/
                    Assign_Walk(x,temp,front_walk,y,back_walk);
				Assign_Walk(x,temp,back_walk,y+2,front_walk);
			}
	}
     resetting = FALSE;
}


void Reset_Max(PF_FACES temp2,int face_id,int north,int last_north, int orientation,
		int last_left,FILE *output_file,int color1,int color2,int color3,
		BOOL start)
{
	int previous_edge1,previous_edge2;
	F_EDGES *node;
	ListHead *pListHead;
	int f,t,nextvert,counter;
     BOOL flag;

 
     /*   Reset walks on faces, since we just found a patch */
     if (orientation !=3)
     {
                previous_edge1 = *(temp2->pPolygon + orientation+1);
                previous_edge2 = *(temp2->pPolygon + orientation );
     }
     else
     {
                previous_edge1 = *(temp2->pPolygon + orientation );
                previous_edge2 = *(temp2->pPolygon);
     }

	/* only if we are going left, otherwise there will be -1 there */
	/*Find the adjacent face to this edge */
        
     for (t = 0; t <=3 ; t++)
     {
             node = *(temp2->VertandId+t);
              
             if (face_id == node->edge[1])
                f = node->edge[2];
             else
               f = node->edge[1];
       
             if (f != -1)
                  Fast_Reset(f);
        }

        node = *(temp2->VertandId+orientation);
        if (face_id == node->edge[1])
             nextvert = node->edge[2];
        else
             nextvert = node->edge[1];

	while ((last_left--) > 1)
	{
               
          if (start)
               Reset_Max(temp2,face_id,orientation,last_left,north,last_north,output_file,color1,color2,color3,FALSE);		
        
          face_id = nextvert;
          pListHead = PolFaces[nextvert];                
          temp2 = (PF_FACES) PeekList(pListHead,LISTHEAD,0);
          if ((temp2->nPolSize != 4) && (temp2->nPolSize != 1))
          {
             /*   There is more than 2 polygons on the edge, and we could have
                  gotten the wrong one
             */
             if (nextvert != node->edge[1])
                  nextvert = node->edge[1];
             else
                  nextvert = node->edge[2];
             pListHead = PolFaces[nextvert];          
             temp2 = (PF_FACES) PeekList(pListHead,LISTHEAD,0);
             node = *(temp2->VertandId+orientation);
          }

                
         if (!start)
         {
             for (t = 0; t <=3 ; t++)
             {
                    node = *(temp2->VertandId+t);
              
                    if (face_id == node->edge[1])
                         f = node->edge[2];
                    else
                         f = node->edge[1];
          
                    if (f != -1)
                         Fast_Reset(f);
             }
        }


        counter = 0;
	   flag = TRUE;
	   while ((counter < 3) && (flag))
        {
             if ( ((*(temp2->pPolygon+counter) == previous_edge1) ||
                   (*(temp2->pPolygon+counter+1) == previous_edge2)) ||
                  ((*(temp2->pPolygon+counter) == previous_edge2) ||
                   (*(temp2->pPolygon+counter+1) == previous_edge1)) )
                   counter++;
             else
                  flag = FALSE;
        }

        /* Get the IDs of the next edge */
        if (counter < 3)
        {
             previous_edge1 = *(temp2->pPolygon + counter+1);
             previous_edge2 = *(temp2->pPolygon + counter);
        }
        else
        {
             previous_edge1 = *(temp2->pPolygon + counter);
             previous_edge2 = *(temp2->pPolygon);
        }
        orientation = counter;

        node = *(temp2->VertandId + counter);
	   if (node->edge[1] == nextvert)
			nextvert = node->edge[2];
	   else
			nextvert = node->edge[1];

        if (!reversed)
        {
               if (counter != 3)
			     north = counter +1;
		     else
			     north = 0;
        }
        else
        {
               if (counter != 0)
                    north = counter -1;
               else
                    north = 3;
    
        }
     }
if (start)
	Reset_Max(temp2,face_id,orientation,last_left,north,last_north,output_file,color1,color2,color3,FALSE);
else if (nextvert != -1)       
     Fast_Reset(nextvert);

}


int Peel_Max(PF_FACES temp2,int face_id,int north,int last_north, int orientation,
		int last_left,FILE *output_file,int color1,int color2,int color3,
		BOOL start, int *swaps_added, int norms, int texture)
{
	int end1,end2,last_id,s=0,walk = 0;
	int previous_edge1,previous_edge2;
	static int last_seen = 1000;
	F_EDGES *node;
	ListHead *pListHead;
	int nextvert,numverts,counter,dummy,tris=0;
     BOOL flag;

     /*   Peel the patch from the model.
          We will try and extend off the end of each strip in the patch. We will return the
          number of triangles completed by this extension only, and the number of swaps
          in the extension only.
     */	
     patch = 0;
     
     if (orientation !=3)
     {
                previous_edge1 = *(temp2->pPolygon + orientation+1);
                previous_edge2 = *(temp2->pPolygon + orientation );
     }
     else
     {
                previous_edge1 = *(temp2->pPolygon + orientation );
                previous_edge2 = *(temp2->pPolygon);
     }


     walk = *(temp2->walked + orientation);
	
     /* only if we are going left, otherwise there will be -1 there */
	if ((start) && ((walk+1) < last_left))
	{
		printf("There is an error in the left %d %d\n",walk,last_left);
		exit(0);
	}
	
     /* Find the adjacent face to this edge */
     node = *(temp2->VertandId+orientation);
     if (face_id == node->edge[1])
          nextvert = node->edge[2];
     else
          nextvert = node->edge[1];
	temp2->seen = last_seen;


	while ((last_left--) > 1)
	{
 		if (start)
             tris += Peel_Max(temp2,face_id,orientation,last_left,north,last_north,output_file,
                              color1,color2,color3,FALSE,swaps_added,norms,texture);		    
          else
             Mark_Face(temp2,color1,color2,color3,output_file,FALSE,&dummy,&dummy,&face_id,norms,texture);
		

          pListHead = PolFaces[nextvert];      
          temp2 = (PF_FACES) PeekList(pListHead,LISTHEAD,0);
          numverts = temp2->nPolSize;
	
          if ((numverts != 4) || (temp2->seen == last_seen) 
			||  (nextvert == -1))
          {
  	
             /*   There is more than 2 polygons on the edge, and we could have
                  gotten the wrong one
             */
             if (nextvert != node->edge[1])
                  nextvert = node->edge[1];
             else
                  nextvert = node->edge[2];
             pListHead = PolFaces[nextvert];
             temp2 = (PF_FACES) PeekList(pListHead,LISTHEAD,0);
             numverts = temp2->nPolSize;
             if ((numverts != 4) || (temp2->seen == last_seen) )
             {
                  printf("Peel 2 %d\n",numverts);
                  exit(1);
             }
        }

        face_id = nextvert;
        temp2->seen = last_seen;
                
        counter = 0;
        flag = TRUE;
	   while ((counter < 3) && (flag))
        {
             if ( ((*(temp2->pPolygon+counter) == previous_edge1) ||
                   (*(temp2->pPolygon+counter+1) == previous_edge2)) ||
                  ((*(temp2->pPolygon+counter) == previous_edge2) ||
                   (*(temp2->pPolygon+counter+1) == previous_edge1)) )
                   counter++;
             else
                  flag = FALSE;
        }
        /* Get the IDs of the next edge */
        if (counter < 3)
        {
             previous_edge1 = *(temp2->pPolygon + counter+1);
             previous_edge2 = *(temp2->pPolygon + counter);
        }
        else
        {
             previous_edge1 = *(temp2->pPolygon + counter);
             previous_edge2 = *(temp2->pPolygon);
        }
        orientation = counter;
		              
	   node = *(temp2->VertandId + counter);
	   if (node->edge[1] == nextvert)
			nextvert = node->edge[2];
	   else
			nextvert = node->edge[1];

	   if (!reversed)
        {
               if (counter != 3)
			     north = counter +1;
		     else
			     north = 0;
        }
        else
        {
               if (counter != 0)
                    north = counter -1;
               else
                    north = 3;
        }
}

if (start)
	tris += Peel_Max(temp2,face_id,orientation,last_left,north,last_north,output_file,
                        color1,color2,color3,FALSE,swaps_added,norms,texture);	
else
     Mark_Face(temp2,color1,color2,color3,output_file,FALSE,&dummy,&dummy,&face_id,norms,texture);/* do the last face */

last_seen++;

/*    Get the edge that we came out on the last strip of the patch */
Mark_Face(NULL,0,0,0,output_file,TRUE,&end1,&end2,&last_id,norms,texture);
tris += Extend_Face(last_id,end1,end2,&s,output_file,color1,color2,color3,vn,norms,vt,texture);
*swaps_added = *swaps_added + s;
return tris;
}



void Find_Bands(int numfaces, FILE *output_file, int *swaps, int *bands, 
                int *cost, int *tri, int norms, int *vert_norms, int texture, int *vert_texture)
{

	register int x,y,max1,max2,numverts,face_id,flag,maximum = 25;
	ListHead *pListHead;
	PF_FACES temp = NULL;
	int color1 = 0, color2 = 100, color3 = 255;
	int larger,smaller;
	int north_length1,last_north,left_length1,last_left,north_length2,left_length2;
  int total_tri = 0, total_swaps = 0,last_id;
  int end1, end2,s=0;
  register int cutoff = 20;
    
  /* Code that will find the patches. "Cutoff" will be
     the cutoff of the area of the patches that we will be allowing. After
     we reach this cutoff length, then we will run the local algorithm on the
     remaining faces.
  */

	/* For each faces that is left find the largest possible band that we can
		 have with the remaining faces. Note that we will only be finding patches
     consisting of quads.
	*/

  vn = vert_norms;
  vt = vert_texture;
  y=1;
  *bands = 0;

  while ((maximum >= cutoff))
  {
	  y++;
    maximum = -1;
	  for (x=0; x<numfaces; x++)
	  { 
      /*   Used to produce the triangle strips */
 
      /* for each face, get the face */
		  pListHead = PolFaces[x];
		  temp = (PF_FACES) PeekList(pListHead,LISTHEAD,0);
		  numverts = temp->nPolSize;
		  
      /* we are doing this only for quads */
		  if (numverts == 4)
		  {
			  /* We want a face that is has not been used yet,
           since we know that that face must be part of
				   a band. Then we will find the largest band that
				   the face may be contained in
			  */
			  
        /*  Doing the north and the left */
			  if ((*(temp->walked) != -1) && (*(temp->walked+3) != -1))
				  max1 = Find_Max(temp,x,0,3,&north_length1,&left_length1);
			  if ((*(temp->walked+1) != -1) && (*(temp->walked+2) != -1))
				  max2 = Find_Max(temp,x,2,1,&north_length2,&left_length2);
			  if ((max1 != (north_length1 * left_length1)) ||
			      (max2 != (north_length2 * left_length2)))
			  {
				  printf("Max1 %d, %d %d	Max2 %d, %d %d\n",max1,north_length1,left_length1,max2,north_length2,left_length2);
				  exit(0);
			  }
                
                    
        if ((max1 > max2) && (max1 > maximum))
			  {
          maximum = max1;
          face_id = x;
          flag = 1; 
          last_north = north_length1;
          last_left = left_length1;
          /* so we know we saved max1 */
			  }
			  else if ((max2 > maximum) )
			  {
          maximum = max2;
          face_id = x;
          flag = 2; 
          last_north = north_length2;
          last_left = left_length2;
          /* so we know we saved max2 */
        }
      }
    }
    if ((maximum < cutoff) && (*bands == 0))
      return;
    pListHead = PolFaces[face_id];
    temp = (PF_FACES) PeekList(pListHead,LISTHEAD,0);	
    /*   There are no patches that we found in this pass */
    if (maximum == -1)
      break;
    printf("The maximum is  face %d area %d: lengths %d %d\n",face_id,maximum,last_north,last_left);
    if (maximum == 16)
      printf("Fran");

    if (last_north > last_left)
    {
      larger = last_north;
      smaller = last_left;
    }
    else
    {
      larger = last_left;
      smaller = last_north;
    }

    length = larger;

    if (flag == 1)
    {
	    if (last_north > last_left) /*     go north sequentially */
      {
        total_tri += Peel_Max(temp,face_id,0,last_north,3,last_left,output_file,color1,color2,color3,TRUE,&s,norms,texture);
        Reset_Max(temp,face_id,0,last_north,3,last_left,output_file,color1,color2,color3,TRUE);
        total_swaps += s;
      }
      else
      {
        reversed = TRUE;
        total_tri += Peel_Max(temp,face_id,3,last_left,0,last_north,output_file,color1,color2,color3,TRUE,&s,norms,texture);
        Reset_Max(temp,face_id,3,last_left,0,last_north,output_file,color1,color2,color3,TRUE);
        reversed = FALSE;
        total_swaps += s;
      }


      /*    Get the edge that we came out on the last strip of the patch */
      Mark_Face(NULL,0,0,0,NULL,TRUE,&end1,&end2,&last_id,norms,texture);
      total_tri += Extend_Face(last_id,end1,end2,&s,output_file,color1,color2,color3,vn,norms,vt,texture);
      total_swaps += s;

    }
    else
    {
       if (last_north > last_left)
       {
            total_tri += Peel_Max(temp,face_id,2,last_north,1,last_left,output_file,color1,color2,color3,TRUE,&s,norms,texture); 
            Reset_Max(temp,face_id,2,last_north,1,last_left,output_file,color1,color2,color3,TRUE); 
            total_swaps += s;
       }
       else
       {
            reversed = TRUE;
            total_tri += Peel_Max(temp,face_id,1,last_left,2,last_north,output_file,color1,color2,color3,TRUE,&s,norms,texture);
            Reset_Max(temp,face_id,1,last_left,2,last_north,output_file,color1,color2,color3,TRUE);
            reversed = FALSE;
            total_swaps += s;
       }

       /*    Get the edge that we came out on on the patch */
      Mark_Face(NULL,0,0,0,NULL,TRUE,&end1,&end2,&last_id,norms,texture);
      total_tri += Extend_Face(last_id,end1,end2,&s,output_file,color1,color2,color3,vn,norms,vt,texture);
      total_swaps += s;
    }

    /* Now compute the cost of transmitting this band, is equal to 
       going across the larger portion sequentially,
       and swapping 3 times per other dimension
    */

    total_tri += (maximum * 2);
    *bands = *bands + smaller;
  }

  printf("We transmitted %d triangles,using %d swaps and %d strips\n",total_tri,total_swaps, *bands);
  printf("COST %d\n",total_tri + total_swaps + *bands + *bands);

  *cost = total_tri + total_swaps + *bands + *bands;
  *tri = total_tri;
  added_quad = added_quad * 4;
  *swaps = total_swaps;
}

 
void Save_Rest(int *numfaces)
{
    /*  Put the polygons that are left into a data structure so that we can run the
        stripping code on it.
    */
    register int x,y=0,numverts;
    ListHead *pListHead;
    PF_FACES temp=NULL;

    for (x=0; x<*numfaces; x++)
    { 
			/* for each face, get the face */
			pListHead = PolFaces[x];
			temp = (PF_FACES) PeekList(pListHead,LISTHEAD,0);
			numverts = temp->nPolSize;
               /*  If we did not do the face before add it to data structure with new 
                   face id number
               */
               if (numverts != 1)
               {
                   CopyFace(temp->pPolygon,numverts,y+1,temp->pNorms);
                   y++;
               }
               /*   Used it, so remove it */
               else
                    RemoveList(pListHead,(PLISTINFO) temp);

    }
    *numfaces = y;
}

void Assign_Walk(int lastvert,PF_FACES temp2, int front_walk,int y,
				int back_walk)
{
/*      Go back and do the walk again, but this time save the lengths inside
        the data structure.
        y was the starting edge number for the front_walk length
        back_walk is the length of the walk along the opposite edge
 */
        int previous_edge1, previous_edge2;
        register int walk = 0,nextvert,numverts,counter;
        BOOL flag;
        F_EDGES *node;
        ListHead *pListHead;
        static int seen = 0;
        static BOOL first = TRUE;         
        BOOL wrap = FALSE, set = FALSE;
             
        /*     In the "Fast_Reset" resetting will be true */
        if ((resetting) && (first))
        {
             seen = 0;
             first = FALSE;
        }

        seen++;
        /*     Had a band who could be a cycle  */
        if (front_walk == back_walk)
             wrap = TRUE;
             
        /* Find the edge that we are currently on */
        if (y != 3)
        {
                previous_edge1 = *(temp2->pPolygon +y);
                previous_edge2 = *(temp2->pPolygon + y + 1);
        }
        else
        {
                previous_edge1 = *(temp2->pPolygon +y);
                previous_edge2 = *(temp2->pPolygon);
        }

        /* Assign the lengths */
	   if (y < 2) 
	   {
                *(temp2->walked+y) = front_walk--;
         		 *(temp2->walked+y+2) = back_walk++;
    	   }
	   else
	   {				
               *(temp2->walked+y) = front_walk--;
              	*(temp2->walked+y-2) = back_walk++;
  	   }

	   /*Find the adjacent face to this edge */
        node = *(temp2->VertandId+y);                   

        if (node->edge[2] != lastvert)
          nextvert = node->edge[2];
        else
          nextvert = node->edge[1];
                                       
        temp2->seen3 = seen;
        
        /* Keep walking in this direction until we cannot do so */
        while ((nextvert != lastvert) && (nextvert != -1) && (front_walk >= 0))
        {
		     walk++;
               pListHead = PolFaces[nextvert];
               
               temp2 = (PF_FACES) PeekList(pListHead,LISTHEAD,0);
               numverts = temp2->nPolSize;
               if ((numverts != 4))
               {
                    nextvert = -1;
                    /* Don't include this face in the walk */
                    walk--;
               }
               else
               {
                    /* Find edge that is not adjacent to the previous one */
                    counter = 0;
                    flag = TRUE;
                    while ((counter < 3) && (flag))
                    {
                         if ( ((*(temp2->pPolygon+counter) == previous_edge1) ||
                               (*(temp2->pPolygon+counter+1) == previous_edge2)) ||
                              ((*(temp2->pPolygon+counter) == previous_edge2) ||
                               (*(temp2->pPolygon+counter+1) == previous_edge1)) )
                              counter++;
                         else
                              flag = FALSE;
                    }
                    /* Get the IDs of the next edge */
                    if (counter < 3)
                    {
                         previous_edge1 = *(temp2->pPolygon + counter);
                         previous_edge2 = *(temp2->pPolygon + counter + 1);
                    }
                    else
                    {
                         previous_edge1 = *(temp2->pPolygon + counter);
                         previous_edge2 = *(temp2->pPolygon);
                    }
               

		          /*      Put in the walk lengths */
		          if (counter < 2)
		          {
                        if (((*(temp2->walked + counter) >= 0)
			          || (*(temp2->walked +counter + 2) >= 0)))
			          {
				          if ((resetting == FALSE) && ((temp2->seen3) != (seen-1)))
				          {
					          /*   If there are more than 2 polygons adjacent
                                        to an edge then we can be trying to assign more than
                                        once. We will save the smaller one
                                   */
                                   temp2->seen3 = seen;
                                   if ( (*(temp2->walked+counter) <= front_walk) &&
                                        (*(temp2->walked+counter+2) <= back_walk) )
                                        return;
                                   if (*(temp2->walked+counter) > front_walk)
                                       *(temp2->walked+counter) = front_walk--;
                                   else
                                        front_walk--;
                                   if (*(temp2->walked+counter+2) > back_walk)
                                       *(temp2->walked+counter+2) = back_walk++;
                                   else
                                        back_walk++;
				          }
				          else if (resetting == FALSE)
				          {
					          /* if there was a cycle then all lengths are the same */
					          walk--;
					          back_walk--;
					          front_walk++;
                                   temp2->seen3 = seen;
                                   *(temp2->walked+counter) = front_walk--;
                                   *(temp2->walked+counter+2) = back_walk++;
                              }
                              else if (((temp2->seen3 == (seen-1))
                                   && (wrap) && (walk == 1)) || (set))
                              {
					          /* if there was a cycle then all lengths are the same */
					          set = TRUE;
                                   walk--;
					          back_walk--;
					          front_walk++;
                                   temp2->seen3 = seen;
                                   *(temp2->walked+counter) = front_walk--;
                                   *(temp2->walked+counter+2) = back_walk++;
                              }
                              else
                              {
                                   temp2->seen3 = seen;
                                   *(temp2->walked+counter) = front_walk--;
                                   *(temp2->walked+counter+2) = back_walk++;
                              }
                        } /* if was > 0 */	
                        else
                        {
                             temp2->seen3 = seen;
                             *(temp2->walked+counter) = front_walk--;
                             *(temp2->walked+counter+2) = back_walk++;
                        }
                    }
		
               else
               {
                    if (((*(temp2->walked + counter) >= 0 )
                        || (*(temp2->walked +counter - 2) >= 0)) )
                    {
                         if ((temp2->seen3 != (seen-1))  && (resetting == FALSE))
                         {
                              /*   If there are more than 2 polygons adjacent
                                   to an edge then we can be trying to assign more than
                                   once. We will save the smaller one
                              */
                              temp2->seen3 = seen;
                              if ( (*(temp2->walked+counter) <= front_walk) &&
                                   (*(temp2->walked+counter-2) <= back_walk) )
                                   return;
                              if (*(temp2->walked+counter) > front_walk)
                                   *(temp2->walked+counter) = front_walk--;
                              else
                                   front_walk--;
                              if (*(temp2->walked+counter-2) > back_walk)
                                   *(temp2->walked+counter-2) = back_walk++;
                              else
                                   back_walk++;
                        	}
				     else if (resetting == FALSE)
	     			{
     					walk--;
		     			back_walk--;
			     		front_walk++;
	                         temp2->seen3 = seen;
                              *(temp2->walked+counter) = front_walk--;
                              *(temp2->walked+counter-2) = back_walk++;
                         }
                         else if (((temp2->seen3 == (seen-1)) && (walk == 1) && (wrap))
                              || (set))
                         {
					     /* if there was a cycle then all lengths are the same */
					     set = TRUE;
                              walk--;
					     back_walk--;
					     front_walk++;
                              temp2->seen3 = seen;
                              *(temp2->walked+counter) = front_walk--;
                              *(temp2->walked+counter-2) = back_walk++;
                         }
                         else
                         {
                              temp2->seen3 = seen;
                              *(temp2->walked+counter) = front_walk--;
                              *(temp2->walked+counter-2) = back_walk++;
                         }
     			}
                    else
                    {
                         temp2->seen3 = seen;
                         *(temp2->walked+counter) = front_walk--;
                         *(temp2->walked+counter-2) = back_walk++;
                    }
		                
  		     } 
		     if (nextvert != -1)
		     {
			     node = *(temp2->VertandId + counter);
                	if (node->edge[1] == nextvert)
                        	nextvert = node->edge[2];
                	else
                        	nextvert = node->edge[1];
               }
		
     }
}
if ((EVEN(seen)) )
     seen+=2;
}

void Save_Walks(int numfaces)
{
	int x,y,numverts;
	int front_walk, back_walk;
	ListHead *pListHead;
	PF_FACES temp = NULL;

	for (x=0; x<numfaces; x++)
	{ 
		/* for each face, get the face */
		pListHead = PolFaces[x];
		temp = (PF_FACES) PeekList(pListHead,LISTHEAD,0);
		numverts = temp->nPolSize;
		front_walk = 0; 
          back_walk = 0;

          /* we are finding patches only for quads */
		if (numverts == 4)
		{
			/* 	for each face not seen yet, do North and South together
				and East and West together
			*/
			for (y=0;y<2;y++)
			{
				/*   Check if the opposite sides were seen already from another
                         starting face, if they were then there is no need to do the walk again
                    */

				if 	( ((*(temp->walked+y) == -1) &&
					(*(temp->walked+y+2) == -1) ))
				{
					/* Find walk for the first edge */
					front_walk = Calculate_Walks(x,y,temp);
					/* Find walk in the opposite direction */
					back_walk = Calculate_Walks(x,y+2,temp);
					/* 	Now put into the data structure the numbers that
						we have found
					*/
                         Assign_Walk(x,temp,front_walk,y,back_walk);
					Assign_Walk(x,temp,back_walk,y+2,front_walk);
	     		}
			}
		}
	}
}