source: GTP/trunk/Lib/Geom/shared/GTGeometry/src/GeoMeshStripifier.cpp @ 980

Revision 980, 236.3 KB checked in by gumbau, 19 years ago (diff)
Line 
1/*      ==========================================================================
2 *      (C) 2005 Universitat Jaume I
3 *      ==========================================================================
4 *      PROYECT:        GAME TOOLS
5 *      ==========================================================================*/
6/**     CONTENT:        Make triangle strip meshes from triangle list meshes.
7        *
8        *
9        *       @file   GeoMeshStripifier.cpp
10/*===========================================================================*/
11
12#include "GeoMeshStripifier.h"
13
14using namespace Geometry;
15using   namespace       std;
16
17//-----------------------------------------------------------------------------
18//      Private.
19//-----------------------------------------------------------------------------
20
21///     InitList:
22BOOL CustomStripifier::InitList(PLISTHEAD LHead)
23{
24        if (LHead == NULL)
25        {
26                return  FALSE;
27        }
28
29        LHead->LHeaders[LISTHEAD] = LHead->LHeaders[LISTTAIL] = NULL;
30        LHead->NumList = 0;
31
32        return  TRUE;
33}
34
35///     AddHead:
36BOOL CustomStripifier::AddHead(PLISTHEAD LHead, PLISTINFO LInfo)
37{
38        if (LHead == NULL || LInfo == NULL)
39        {
40                return(FALSE);
41        }
42
43        if (EMPTYLIST(LHead))
44        {
45                LHead->LHeaders[LISTTAIL] = LInfo;
46        }
47        else
48        {
49                LHead->LHeaders[LISTHEAD]->ListNode.Previous = (void  *) LInfo;
50        }
51
52        LInfo->ListNode.Next                    =       (void  *) LHead->LHeaders[LISTHEAD];
53        LHead->LHeaders[LISTHEAD]       =       LInfo;
54        LInfo->ListNode.Previous        =       NULL;
55        LHead->NumList++;
56
57        return(TRUE);
58}
59
60///     AddTail
61BOOL  CustomStripifier::AddTail(PLISTHEAD LHead, PLISTINFO LInfo)
62{
63        if (LHead == NULL || LInfo == NULL)
64        {
65                return  FALSE;
66        }
67
68        if (EMPTYLIST(LHead))
69        {
70                LHead->LHeaders[LISTHEAD] = LInfo;
71        }
72        else
73        {
74                LHead->LHeaders[LISTTAIL]->ListNode.Next = (void *) LInfo;
75        }
76
77        LInfo->ListNode.Previous        = (void  *) LHead->LHeaders[LISTTAIL];
78        LHead->LHeaders[LISTTAIL] = LInfo;
79        LInfo->ListNode.Next                    = NULL;
80        LHead->NumList++;
81
82        return  TRUE;
83}
84
85///     InsertNode
86BOOL  CustomStripifier::InsertNode( PLISTHEAD LHead, int nPos, PLISTINFO LInfo )
87{
88        PLISTINFO add_node;
89
90  if ( LHead == NULL || LInfo == NULL || nPos > NumOnList( LHead ) )
91        {
92                return  FALSE;
93        }
94
95        if ( nPos == 0 )
96        {
97                AddHead( LHead, LInfo );
98        }
99        else if ( nPos == NumOnList( LHead ) )
100        {
101                AddTail( LHead, LInfo );
102        }
103        else
104        {
105                if ( (add_node = PeekList( LHead, LISTHEAD, nPos - 1 )) == NULL )
106                {
107                        return  FALSE;
108                }
109 
110                ((PLISTINFO)add_node->ListNode.Next)->ListNode.Previous = LInfo;
111
112                LInfo->ListNode.Next      = add_node->ListNode.Next;
113                LInfo->ListNode.Previous  = add_node;
114                add_node->ListNode.Next   = LInfo;
115                LHead->NumList++;
116        }
117
118        return  TRUE;
119}
120
121///     RemHead:
122PLISTINFO  CustomStripifier::RemHead(PLISTHEAD LHead)
123{
124        PLISTINFO t, t1;
125
126        if ( LHead == NULL || EMPTYLIST(LHead) )
127        {
128                return  NULL;
129        }
130
131        t                                                                                                       =       LHead->LHeaders[LISTHEAD];
132        LHead->LHeaders[LISTHEAD] = (PLISTINFO) t->ListNode.Next;
133
134        if (LHead->LHeaders[LISTHEAD] != NULL)
135        {
136                t1                                                                              = (PLISTINFO) t->ListNode.Next;
137                t1->ListNode.Previous = NULL;
138        }
139        else
140        {
141                LHead->LHeaders[LISTTAIL] = NULL;
142        }
143       
144        LHead->NumList--;
145
146        return  t;
147}
148
149///     RemTail:
150PLISTINFO CustomStripifier::RemTail(PLISTHEAD   LHead)
151{
152        PLISTINFO   t, t1;
153
154        if ( LHead == NULL || EMPTYLIST(LHead) )
155        {
156                return  NULL;
157        }
158
159        t                                                                                                       = LHead->LHeaders[LISTTAIL];
160        LHead->LHeaders[LISTTAIL] = (PLISTINFO) t->ListNode.Previous;
161
162        if (LHead->LHeaders[LISTTAIL] != NULL)
163        {
164                t1 = (PLISTINFO) t->ListNode.Previous;
165                t1->ListNode.Next = NULL;
166        }
167        else
168        {
169                LHead->LHeaders[LISTHEAD] = NULL;
170        }
171
172        LHead->NumList--;
173
174        return  t;
175}
176
177///     PeekList:
178PLISTINFO CustomStripifier::PeekList(PLISTHEAD LHead, int wch, int index )
179{
180        PLISTINFO  t;
181
182        if (LHead == NULL)
183        {
184                return  NULL;
185        }
186
187        if ( (t = LHead->LHeaders[wch]) == NULL )
188        {
189                return  NULL;
190        }
191
192        for (; t != NULL && index > 0; index-- )
193        {
194                t = (wch == LISTHEAD)   ?       (PLISTINFO) t->ListNode.Next 
195                                                                                                        :       (PLISTINFO) t->ListNode.Previous;
196        }
197
198        return  t;
199}
200
201///     RemoveList:
202PLISTINFO CustomStripifier::RemoveList(PLISTHEAD LHead, PLISTINFO LInfo )
203{
204        PLISTINFO       t;
205        PLISTINFO       t1;
206
207        t       =       LInfo;
208
209        if (LHead == NULL)
210        {
211                return  NULL;
212        }
213
214        if (LHead->LHeaders[LISTHEAD] == t)
215        {
216                t       =       (PLISTINFO) RemHead(LHead);
217        }
218        else if (LHead->LHeaders[LISTTAIL] == t)
219        {
220                t = (PLISTINFO) RemTail(LHead);
221        }
222        else
223        {
224                t1                    = (PLISTINFO) t->ListNode.Previous;
225                t1->ListNode.Next     = t->ListNode.Next;
226                t1                    = (PLISTINFO) t->ListNode.Next;
227                t1->ListNode.Previous = t->ListNode.Previous;
228                LHead->NumList--;
229        }
230
231        return  t;
232}
233
234///     SearchList:
235///                     Try to find a specific node in the queue whose key matches with
236///                     searching key. Return the pointer to that node if found, return NULL
237///                     otherwise
238///     @param  lpHashTbl       => a far pointer to the hash table.
239///     @param  lpKey           => a far poniter to searching key.
240///     @param  CompareCallBack => comparision function.
241///     @return a far pointer to the node to be found.
242PLISTINFO CustomStripifier::SearchList(
243                        PLISTHEAD listHead,
244                        PVOID lpSKey,
245                        int (* CompareCallBack) ( PVOID, PVOID ) )
246{
247        PLISTINFO list_info;
248
249        list_info = PeekList( listHead, LISTHEAD, 0);
250
251        while ( list_info != NULL )
252        {
253                if ( CompareCallBack( list_info, lpSKey ) )
254                {
255                        break;
256                }
257
258                list_info       =       (PLISTINFO) GetNextNode( list_info );
259        }
260
261        return  list_info;
262}
263
264///     init_vert_norms:
265void CustomStripifier::init_vert_norms(int num_vert)
266{
267  /*   Initialize vertex/normal array to have all zeros to
268       start with.
269  */
270  register int x;
271 
272  for (x = 0; x < num_vert; x++)
273        {
274                *(vert_norms + x) = 0;
275        }
276}
277
278///     init_vert_texture:
279void CustomStripifier::init_vert_texture(int num_vert)
280{
281  /*   Initialize vertex/normal array to have all zeros to
282       start with.
283  */
284  register int x;
285 
286  for (x = 0; x < num_vert; x++)
287        {
288    *(vert_texture + x) = 0;
289        }
290}
291
292///     InitVertexTable:
293BOOL CustomStripifier::InitVertexTable( int size )
294{
295  register int index;
296 
297  /*     Initialize the face table */
298  Vertices      =       (ListHead**) malloc(sizeof(ListHead*) * size );
299 
300  if (Vertices)
301        {
302                for (index      =       0; index < size; index++)
303                {
304                        Vertices[index] = NULL;
305                }
306
307                return  TRUE;
308
309        }
310
311        return  FALSE;
312}
313
314///     InitFaceTable:
315BOOL CustomStripifier::InitFaceTable( int size )
316{
317  register int index;
318 
319  /*     Initialize the face table */
320  PolFaces = (ListHead**) malloc(sizeof(ListHead*) * size);
321 
322  if (PolFaces)
323  {
324        for (index      =       0; index < size; index++)
325                {
326                        PolFaces[index] = NULL;
327                }
328
329                return  TRUE;
330        }
331
332        return  FALSE;
333}
334
335///     InitEdgeTable:
336BOOL CustomStripifier::InitEdgeTable( int size )
337{
338  register int index;
339 
340  /*     Initialize the edge table */
341  PolEdges      =       (ListHead**) malloc(sizeof(ListHead*) * size );
342
343  if (PolEdges)
344        {
345                for (index=0; index < size; index++)
346                {
347                        PolEdges[index] =       NULL;
348                }
349
350                return  TRUE;
351        }
352
353        return  FALSE;
354}
355
356///     InitStripTable:
357void CustomStripifier::InitStripTable( )
358{
359 
360  PLISTHEAD list_head;
361 
362  /*   Initialize the strip table */
363  list_head = (PLISTHEAD) malloc(sizeof(ListHead));
364
365  if (list_head)
366  {
367    InitList(list_head);
368
369    strips[0] = list_head;
370  }
371  else
372  {
373    printf("Out of memory !\n");
374
375    exit(0);
376  }
377 
378}
379
380///     Init_Table_SGI:
381void CustomStripifier::Init_Table_SGI(int numFaces)
382{
383  PLISTHEAD                     list_head;
384  int                                           max_adj         = 60;
385  register                      int     x;
386 
387  /*   This routine will initialize the table that will
388       have the faces sorted by the number of adjacent polygons
389       to it.
390  */
391 
392  for (x=0; x< max_adj; x++)
393  {
394                /*      We are allowing the max number of sides of a polygon
395                                to be max_adj.
396    */                     
397    list_head = (PLISTHEAD) malloc(sizeof(ListHead));
398
399    if (list_head)
400                {
401                        InitList(list_head);
402
403                        array[x]        =       list_head;
404                }
405    else
406                {
407                        printf("Out of memory !\n");
408                        exit(0);
409                }
410        }
411 
412  if (face_array != NULL) /* It seems this function is called more than */
413        {
414    free(face_array);     /* once so we'll free up the old stuff */
415        }
416 
417  face_array = (P_FACE_ADJACENCIES) malloc (sizeof(FACE_ADJACENCIES) * numFaces);
418
419  if (face_array == NULL)
420        {
421    printf("Out of memory !!\n");
422    exit(0);
423  }
424 
425}
426
427///     BuildVertexTable:
428void CustomStripifier::BuildVertexTable(int size)
429{
430  register int  index;
431  PLISTHEAD                     list_head;
432 
433  for (index    =       0; index < size; index++)
434  {
435    list_head   =       (PLISTHEAD) malloc(sizeof(ListHead));
436
437    if (list_head)
438                {
439                        InitList(list_head);
440
441                        Vertices[index] =       list_head;
442                }
443    else
444                {
445                        return;
446                }
447     
448        }
449}
450
451///     BuildFaceTable:
452void CustomStripifier::BuildFaceTable( int size )
453{
454  register int  index;
455  PLISTHEAD                     list_head;
456 
457  for (index    =       0; index < size; index++)
458  {
459    list_head   =       (PLISTHEAD) malloc(sizeof(ListHead));
460
461    if (list_head)
462                {
463                        InitList(list_head);
464
465                        PolFaces[index] =       list_head;
466                }
467                else
468                {
469                        return;
470                }
471        }
472}
473
474///     BuildEdgeTable:
475void CustomStripifier::BuildEdgeTable( int size )
476{
477  register int  index;
478  PLISTHEAD                     list_head;
479 
480  for (index    =       0; index < size; index++)
481  {
482        list_head       =       (PLISTHEAD) malloc(sizeof(ListHead));
483
484                if (list_head)
485                {
486                InitList(list_head);
487
488                PolEdges[index] =       list_head;
489                }
490    else
491                {
492                        return;
493                }
494        }
495}
496
497///     Start_Vertex_Struct:
498void CustomStripifier::Start_Vertex_Struct(int numVerts)
499{
500  if (InitVertexTable(numVerts))
501  {
502    BuildVertexTable(numVerts);
503  }
504}
505
506///     Start_Face_Struct:
507void CustomStripifier::Start_Face_Struct(int numFaces)
508{
509  if (InitFaceTable(numFaces))
510  {
511    BuildFaceTable(numFaces);
512  }
513}
514
515///     Start_Edge_Struct:
516void CustomStripifier::Start_Edge_Struct(int numVerts)
517{
518  if (InitEdgeTable(numVerts))
519  {
520    BuildEdgeTable(numVerts);
521  }
522}
523
524///     switch_lower:
525void CustomStripifier::switch_lower (int *x, int *y)
526{
527  register int temp;
528 
529  /*    Put lower value in x */
530  if (*y < *x)
531  {
532    temp        =       *x;
533    *x          =       *y;
534    *y          =       temp;
535  }
536}
537
538///     member:
539BOOL CustomStripifier::member(int x , int id1, int id2, int id3)
540{
541  /*  Is x in the triangle specified by id1,id2,id3 */
542  if ((x != id1) && (x != id2) && (x != id3))
543        {
544    return      FALSE;
545        }
546
547  return        TRUE;
548}
549
550///     Exist:
551BOOL CustomStripifier::Exist(int faceId, int id1, int id2)
552{
553  /*    Does the edge specified by id1 and id2 exist in this
554        face currently? Maybe we deleted in partial triangulation
555  */
556  ListHead                      *list_head;
557  PF_FACES                      temp;
558  register int  x,size;
559  BOOL                                  a       =       FALSE;
560        BOOL                                    b =     FALSE;
561 
562  list_head     =       PolFaces[faceId];
563
564  temp  =       (PF_FACES) PeekList(list_head, LISTHEAD, 0);
565  size  =       temp->nPolSize;
566
567  for (x=0; x<size; x++)
568  {
569    if (*(temp->pPolygon+x) == id1)
570                {
571                        a = TRUE;
572                }
573     
574                if (*(temp->pPolygon+x) == id2)
575                {
576                        b = TRUE;
577                }
578
579    if (a && b)
580                {
581                        return  TRUE;
582                }
583  }
584
585  return        FALSE;
586}
587
588///     Different:
589int CustomStripifier::Different(int id1,int id2,int id3,int id4,int id5, int id6, int *x, int *y)
590{
591  /*    Find the vertex in the first 3 numbers that does not exist in
592        the last three numbers
593  */
594  if ((id1 != id4) && (id1 != id5) && (id1 != id6))
595    {
596      *x = id2;
597      *y = id3;
598      return id1;
599    }
600  if ((id2 != id4) && (id2 != id5) && (id2 != id6))
601    {
602      *x = id1;
603      *y = id3;
604      return id2;
605    }
606  if ((id3 != id4) && (id3 != id5) && (id3 != id6))
607    {
608      *x = id1;
609      *y = id2;
610      return id3;
611    }
612 
613  /*  Because there are degeneracies in the data, this might occur */
614  *x = id5;
615  *y = id6;
616  return id4;
617}
618
619///     Return_Other:
620int CustomStripifier::Return_Other(int *index,int e1,int e2)
621{
622  /*   We have a triangle and want to know the third vertex of it */
623  register int x;
624 
625  for (x=0;x<3;x++)
626    {
627      if ((*(index+x) != e1) && (*(index+x) != e2))
628        return *(index+x);
629    }
630  /*   If there is a degenerate triangle return arbitrary */
631  return e1;
632}
633
634///     Get_Other_Vertex:
635int CustomStripifier::Get_Other_Vertex(int id1,int id2,int id3,int *index)
636{
637  /*    We have a list index of 4 numbers and we wish to
638        return the number that is not id1,id2 or id3
639  */
640  register int x;
641 
642  for (x=0; x<4; x++)
643    {
644      if ((*(index+x) != id1) && (*(index+x) != id2) &&
645          (*(index+x) != id3))
646        return *(index+x);
647    }
648  /*   If there is some sort of degeneracy this might occur,
649       return arbitrary
650  */
651  if (x==4)
652    return id1;
653}
654
655///     Done:
656PLISTINFO CustomStripifier::Done(int face_id, int *bucket)
657{
658  /*    Check to see whether the polygon with face_id was used
659        already, return NULL if it was, otherwise return a pointer to the face.
660  */
661 
662  PLISTINFO lpListInfo;
663 
664  lpListInfo = (PLISTINFO) face_array[face_id].pfNode;
665  if (lpListInfo != NULL) {
666    *bucket = face_array[face_id].bucket;
667    return lpListInfo;
668  }
669  else
670    return lpListInfo;
671}
672
673///     First_Edge:
674void CustomStripifier::First_Edge(int *id1,int *id2, int *id3)
675{
676  /*  Get the first triangle in the strip we just found, we will use this to
677      try to extend backwards in the strip
678  */
679 
680  ListHead *pListHead;
681  register int num;
682  P_STRIPS temp1,temp2,temp3;
683 
684  pListHead = strips[0];
685  num = NumOnList(pListHead);
686 
687  /*    Did not have a strip */
688  if (num < 3)
689    return;
690 
691  temp1 = ( P_STRIPS ) PeekList( pListHead, LISTHEAD, 0);
692  temp2 = ( P_STRIPS ) PeekList( pListHead, LISTHEAD, 1);
693  temp3 = ( P_STRIPS ) PeekList( pListHead, LISTHEAD, 2);
694  *id1 = temp1->face_id;
695  *id2 = temp2->face_id;
696  *id3 = temp3->face_id;
697 
698}
699
700///     Last_Edge:
701void CustomStripifier::Last_Edge(int *id1, int *id2, int *id3, BOOL save)
702{
703  /*   We need the last edge that we had  */
704  static int v1, v2, v3;
705 
706  if (save)
707    {
708      v1 = *id1;
709      v2 = *id2;
710      v3 = *id3;
711    }
712  else
713    {
714      *id1 = v1;
715      *id2 = v2;
716      *id3 = v3;
717    }
718}
719
720///     find_triangle_orientation:
721void CustomStripifier::find_triangle_orientation(int vertex1,int vertex2,int vertex3,
722                                      int *original_vertex)                                 
723{
724  int vertices,index;
725  PF_VERTICES verts;
726 
727  /* Search through face to match orignal vertices */
728 
729  /* Start with vertex1's Vertices struct */ 
730  verts = (PF_VERTICES) PeekList(Vertices[vertex1-1],LISTHEAD,0);
731  do { 
732    index = 0;
733    for (vertices = 0; vertices < verts->face->nOrgSize;vertices++) {
734      if (vertex1 == verts->face->pPolygon[vertices]+1 ||
735          vertex2 == verts->face->pPolygon[vertices]+1 ||
736          vertex3 == verts->face->pPolygon[vertices]+1 )
737        original_vertex[index++] = verts->face->pPolygon[vertices]+1;     
738      if (index == 3)
739        break;
740    }
741    if (index == 3)
742      break;
743  } while ((verts = (PF_VERTICES) GetNextNode(verts)) != NULL);
744 
745  if (index != 3) {
746    /* Search vertex2's Vertices struct */ 
747    verts = (PF_VERTICES) PeekList(Vertices[vertex2-1],LISTHEAD,0);
748    do {
749      index = 0;
750      for (vertices = 0; vertices < verts->face->nOrgSize;vertices++) {
751        if (vertex1 == verts->face->pPolygon[vertices]+1 ||
752            vertex2 == verts->face->pPolygon[vertices]+1 ||
753            vertex3 == verts->face->pPolygon[vertices]+1 )
754          original_vertex[index++] = verts->face->pPolygon[vertices]+1;     
755        if (index == 3)
756          break;
757      }
758      if (index == 3)
759        break;
760    } while ((verts = (PF_VERTICES) GetNextNode(verts)) != NULL);
761  }
762 
763  if (index != 3) {
764    /* Search vertex3's Vertices struct */ 
765    verts = (PF_VERTICES) PeekList(Vertices[vertex3-1],LISTHEAD,0);
766    do {   
767      index = 0;
768      for (vertices = 0; vertices < verts->face->nOrgSize;vertices++) {
769        if (vertex1 == verts->face->pPolygon[vertices]+1 ||
770            vertex2 == verts->face->pPolygon[vertices]+1 ||
771            vertex3 == verts->face->pPolygon[vertices]+1 )
772          original_vertex[index++] = verts->face->pPolygon[vertices]+1;     
773        if (index == 3)
774          break;
775      }
776      if (index == 3)
777        break;
778    } while ((verts = (PF_VERTICES) GetNextNode(verts)) != NULL);
779  }
780 
781  /*  if (index !=3 )
782      printf("Warning: Didn't find a triangle for %d %d %d\n",
783      vertex1,vertex2,vertex3);
784  */
785}
786
787///     preserve_strip_orientation_with_normal:
788void CustomStripifier::preserve_strip_orientation_with_normal(FILE *output, int vertex1, int normal1, int vertex2, int normal2, int vertex3, int normal3)
789{
790  int original_vertex[3];
791 
792  find_triangle_orientation(vertex1,vertex2,vertex3, original_vertex);
793 
794  if ( ( original_vertex[0] == vertex3 && original_vertex[1] == vertex2 && original_vertex[2] == vertex1) ||
795       ( original_vertex[0] == vertex2 && original_vertex[1] == vertex1 && original_vertex[2] == vertex3   ) ||
796       ( original_vertex[0] == vertex1 && original_vertex[1] == vertex3 && original_vertex[2] == vertex2   ))  {
797        // New Triangle is in an opposite orientation.  Add vertex2 to correct it
798        fprintf(output," %d//%d",vertex2,normal2);
799  }
800
801}
802
803///     preserve_strip_orientation_with_texture:
804void CustomStripifier::preserve_strip_orientation_with_texture(FILE *output,
805                                             int vertex1, int texture1,
806                                             int vertex2, int texture2,
807                                             int vertex3, int texture3)
808{
809  int original_vertex[3];
810 
811  find_triangle_orientation(vertex1,vertex2,vertex3,                   
812                            original_vertex);
813 
814  if ( ( original_vertex[0] == vertex3 &&
815         original_vertex[1] == vertex2 &&
816         original_vertex[2] == vertex1   ) ||
817       ( original_vertex[0] == vertex2 &&
818         original_vertex[1] == vertex1 &&
819         original_vertex[2] == vertex3   ) ||
820       ( original_vertex[0] == vertex1 &&
821         original_vertex[1] == vertex3 &&
822         original_vertex[2] == vertex2   ) ) {
823    /* New Triangle is in an opposite orientation */
824    /* Add vertex2 to correct it */
825    fprintf(output," %d/%d",vertex2,texture2);
826  }
827}
828
829///     preserve_strip_orientation_with_texture_and_normal:
830void  CustomStripifier::preserve_strip_orientation_with_texture_and_normal(FILE *output,
831                                                         int vertex1, int texture1, int normal1,
832                                                         int vertex2, int texture2, int normal2,
833                                                         int vertex3, int texture3, int normal3)
834{
835  int original_vertex[3];
836 
837  find_triangle_orientation(vertex1,vertex2,vertex3,
838                            original_vertex);
839 
840  if ( ( original_vertex[0] == vertex3 &&
841         original_vertex[1] == vertex2 &&
842         original_vertex[2] == vertex1   ) ||
843       ( original_vertex[0] == vertex2 &&
844         original_vertex[1] == vertex1 &&
845         original_vertex[2] == vertex3   ) ||
846       ( original_vertex[0] == vertex1 &&
847         original_vertex[1] == vertex3 &&
848         original_vertex[2] == vertex2   ) ) {
849    /* New Triangle is in an opposite orientation */
850    /* Add vertex2 to correct it */
851    fprintf(output," %d/%d/%d",vertex2,texture2,normal2);
852  }
853}
854
855///     preserve_strip_orientation:
856void CustomStripifier::preserve_strip_orientation(FILE *output,int vertex1, int vertex2,int vertex3)
857{
858  int original_vertex[3];
859 
860  find_triangle_orientation(vertex1,vertex2,vertex3,
861                            original_vertex);
862 
863  if ( ( original_vertex[0] == vertex3 &&
864         original_vertex[1] == vertex2 &&
865         original_vertex[2] == vertex1   ) ||
866       ( original_vertex[0] == vertex2 &&
867         original_vertex[1] == vertex1 &&
868         original_vertex[2] == vertex3   ) ||
869       ( original_vertex[0] == vertex1 &&
870         original_vertex[1] == vertex3 &&
871         original_vertex[2] == vertex2   ))  {
872    /* New Triangle is in an opposite orientation */
873    /* Add vertex2 to correct it */
874    fprintf(output," %d",vertex2);
875        mi_vector[num_tiras].push_back(vertex2-1);
876  }
877}
878
879///     Output_TriEx:
880void CustomStripifier::Output_TriEx(int id1, int id2, int id3, FILE *output,
881                  int flag, int where)
882{
883  /*   We will save everything into a list, rather than output at once,
884       as was done in the old routine. This way for future modifications
885       we can change the strips later on if we want to.
886  */
887 
888  int swap,temp1,temp2,temp3;
889  static int total=0;
890  static int tri=0;
891  static int strips = 0;
892  static int cost = 0;
893 
894  if (flag == -20)
895    {
896      cost = cost + where+total+tri+strips+strips;
897      printf("We will need to send %d vertices to the renderer\n",cost);
898      total = 0;
899      tri = 0;
900      strips = 0;
901      return ;
902    }
903 
904 
905  if (flag == -10)
906    /*    We are finished, now is time to output the triangle list
907     */
908  {
909                fprintf(output,"\nt");
910          mi_vector_tipo nada;
911          mi_vector.push_back(nada);
912          num_tiras++;
913    tri = tri + Finished(&swap,output,1);
914    total = total + swap;
915    strips++;
916      /*printf("There are %d swaps %d tri %d strips\n",total,tri,strips);*/
917  }
918  else
919  {
920      Last_Edge(&temp1,&temp2,&temp3,0);
921      Add_Id_Strips(id1,where);
922      Add_Id_Strips(id2,where);
923      Add_Id_Strips(id3,where);
924      Last_Edge(&id1,&id2,&id3,1);
925  }
926}
927
928///     Extend_BackwardsEx:
929void CustomStripifier::Extend_BackwardsEx(int face_id, FILE *output, int *ties,
930                        int tie, int triangulate,
931                        int swaps,int *next_id)
932{
933  /*  We just made a strip, now we are going to see if we can extend
934      backwards from the starting face, which had 2 or more adjacencies
935      to start with.
936  */
937 
938  int bucket,next_face,num,x,y,z,c,max,f;             
939  ListHead *pListFace;
940  PF_FACES face;
941  P_ADJACENCIES temp;
942 
943  /*  Get the first triangle that we have saved the the strip data
944      structure, so we can see if there are any polygons adjacent
945      to this edge or a neighboring one
946  */
947  First_Edge(&x,&y,&z);
948 
949  pListFace  = PolFaces[face_id];
950  face = (PF_FACES) PeekList(pListFace,LISTHEAD,0);
951 
952  num = face->nPolSize;
953 
954  /*  Go through the edges to see if there is an adjacency
955      with a vertex in common to the first triangle that was
956      outputted in the strip. (maybe edge was deleted....)
957  */
958  for (c=0; c<num ; c++)
959    {
960     
961      if ( (c != (num-1)) &&
962           (( (*(face->pPolygon+c) == x) && (*(face->pPolygon+c+1) == y)) ||
963            (*(face->pPolygon+c) == y) && (*(face->pPolygon+c+1) == x)))
964        {
965          /*  Input edge is still there see if there is an adjacency */
966          next_face = Find_Face(face_id, x, y, &bucket);
967          if (next_face == -1)
968            /*  Could not find a face adjacent to the edge */
969            break;
970          pListFace = array[bucket];
971          max = NumOnList(pListFace);
972          for (f=0;;f++)
973            {
974              temp = (P_ADJACENCIES) PeekList(pListFace,LISTHEAD,f);   
975              if (temp->face_id == next_face)
976                {
977                  Last_Edge(&z,&y,&x,1);
978                  Polygon_OutputEx(temp,temp->face_id,bucket,pListFace,
979                                   output,ties,tie,triangulate,
980                                   swaps,next_id,0);
981                  return;
982                }
983             
984              if (temp == NULL)
985                {
986                  printf("Error in the new buckets%d %d %d\n",bucket,max,0);
987                  exit(0);
988                }
989            }
990         
991        }
992      else if ( (c == (num -1)) &&
993                ( ((*(face->pPolygon) == x) && (*(face->pPolygon+num-1) == y)) ||
994                  (*(face->pPolygon) == y) && (*(face->pPolygon+num-1) == x)))
995        {
996          next_face = Find_Face(face_id,x,y,&bucket);
997          if (next_face == -1)
998            /*  Could not find a face adjacent to the edge */
999            break;
1000          pListFace = array[bucket];
1001          max = NumOnList(pListFace);
1002          for (f=0;;f++)
1003            {
1004              temp = (P_ADJACENCIES) PeekList(pListFace,LISTHEAD,f);
1005              if (temp->face_id == next_face)
1006                {
1007                  Last_Edge(&z,&y,&x,1);
1008                  Polygon_OutputEx(temp,temp->face_id,bucket,pListFace,
1009                                   output,ties,tie,triangulate,
1010                                   swaps,next_id,0);
1011                  return;
1012                }
1013             
1014              if (temp == NULL)
1015                {
1016                  printf("Error in the new buckets%d %d %d\n",bucket,max,0);
1017                  exit(0);
1018                }
1019            }
1020        }
1021    }
1022}
1023
1024///     Polygon_OutputEx:
1025void CustomStripifier::Polygon_OutputEx(P_ADJACENCIES temp,int face_id,int bucket,
1026                      ListHead *pListHead, FILE *output,
1027                      int *ties, int tie,
1028                      int triangulate, int swaps,
1029                      int *next_id, int where)
1030{
1031  ListHead *pListFace;
1032  PF_FACES face;
1033  static BOOL begin = TRUE;
1034  int old_face,next_face_id,next_bucket,e1,e2,e3,other1,other2,other3;
1035  P_ADJACENCIES lpListInfo;
1036 
1037  /*      We have a polygon to output, the id is face id, and the number
1038          of adjacent polygons to it is bucket.
1039  */
1040 
1041  Last_Edge(&e1,&e2,&e3,0);
1042 
1043  /*  Get the polygon with id face_id */
1044  pListFace  = PolFaces[face_id];
1045  face = (PF_FACES) PeekList(pListFace,LISTHEAD,0);
1046 
1047  if (face->nPolSize == 3)
1048    {
1049      /*      It is already a triangle */
1050      if (bucket == 0)
1051        {
1052          /*      It is not adjacent to anything so we do not have to
1053                  worry about the order of the sides or updating adjacencies
1054          */
1055         
1056          Last_Edge(&e1,&e2,&e3,0);
1057          next_face_id = Different(*(face->pPolygon),*(face->pPolygon+1),
1058                                   *(face->pPolygon+2),
1059                                   e1,e2,e3,&other1,&other2);
1060          /*  No input edge, at the start */
1061          if ((e2 ==0) && (e3 == 0))
1062            {
1063              e2 = other1;
1064              e3 = other2;
1065            }
1066         
1067          Output_TriEx(e2,e3,next_face_id,NULL,begin,where);
1068          if (face_array[temp->face_id].head == pListHead)
1069            face_array[temp->face_id].pfNode = NULL;
1070          RemoveList(pListHead,(PLISTINFO) temp);
1071          /*      We will be at the beginning of the next strip. */
1072          begin = TRUE;
1073        }
1074      /*      It is a triangle with adjacencies. This means that we
1075              have to:
1076              1. Update the adjacencies in the list, because we are
1077              using this polygon and it will be deleted.
1078              2. Get the next polygon.
1079      */
1080      else
1081        {
1082          /*   Return the face_id of the next polygon we will be using,
1083               while updating the adjacency list by decrementing the
1084               adjacencies of everything adjacent to the current triangle.
1085          */
1086         
1087          next_face_id = Update_AdjacenciesEx(face_id,&next_bucket, &e1,&e2,ties);
1088          old_face = next_face_id;
1089         
1090          /*  Break the tie,  if there was one */
1091          if (tie != FIRST)
1092            old_face = Get_Next_Face(tie,face_id,triangulate);
1093         
1094          if (next_face_id == -1)
1095            {
1096              Polygon_OutputEx(temp,face_id,0,pListHead,output,ties,tie,
1097                               triangulate,swaps,next_id,where);
1098              return;
1099            }
1100         
1101         
1102          /*  We are using a different face */
1103          if ((tie != FIRST) && (old_face != next_face_id) && (swaps == ON))
1104            {
1105              next_face_id = old_face;
1106              /*  Get the new output edge, since e1 and e2 are for the
1107                  original next face that we got.
1108              */
1109              e3 = Get_EdgeEx(&e1,&e2,face->pPolygon,next_face_id,
1110                              face->nPolSize,0,0);
1111            }
1112         
1113          /*      Find the other vertex to transmit in the triangle */
1114          e3 = Return_Other(face->pPolygon,e1,e2);
1115          Last_Edge(&other1,&other2,&other3,0);
1116         
1117          if ((other1 != 0) && (other2 != 0))
1118            {
1119              /*   See which vertex in the output edge is not in the input edge */
1120              if ((e1 != other2) && (e1 != other3))
1121                e3 = e1;
1122              else if ((e2 != other2) && (e2 != other3))
1123                e3 = e2;
1124              /* can happen with > 2 polys on an edge but won't
1125                 form a good strip so stop the strip here
1126              */
1127              else
1128                {
1129                  Polygon_OutputEx(temp,face_id,0,pListHead,output,
1130                                   ties,tie,triangulate,swaps,next_id,where);
1131                  return;
1132                }
1133             
1134              /*   See which vertex of the input edge is not in the output edge */
1135              if ((other2 != e1) && (other2 != e2))
1136                {
1137                  other1 = other2;
1138                  other2 = other3;
1139                }
1140              else if ((other3 != e1) && (other3 != e2))
1141                other1 = other3;
1142              else
1143                {
1144                  /* Degenerate triangle just return*/
1145                  Output_TriEx(other1,other2,e3,NULL,begin,where);
1146                  if (face_array[temp->face_id].head == pListHead)
1147                    face_array[temp->face_id].pfNode = NULL;
1148                  RemoveList(pListHead,(PLISTINFO) temp);
1149                  begin = FALSE;
1150                  return;
1151                }
1152             
1153            }
1154         
1155          /*  There was not an input edge, we are the first triangle in a strip */
1156          else
1157            {
1158              /*   Find the correct order to transmit the triangle, what is
1159                   the output edge that we want ?
1160              */
1161              other1 = e3;
1162              e3 = e2;
1163              other2 = e1;
1164            }
1165         
1166          /*   At this point the adjacencies have been updated  and we
1167               have the next polygon id
1168          */
1169          Output_TriEx(other1,other2,e3,NULL,begin,where);
1170          if (face_array[temp->face_id].head == pListHead)
1171            face_array[temp->face_id].pfNode = NULL;
1172          RemoveList(pListHead,(PLISTINFO) temp);
1173          begin = FALSE;
1174         
1175          if (Done(next_face_id,&next_bucket) == NULL)
1176            return;
1177         
1178          pListHead = array[next_bucket];
1179          lpListInfo = face_array[next_face_id].pfNode;
1180          if (lpListInfo == NULL)
1181            {
1182              printf("There is an error finding the next polygon3 %d\n",
1183                     next_face_id);
1184              exit(0);
1185            }
1186          Polygon_OutputEx(lpListInfo,next_face_id,next_bucket,
1187                           pListHead, output,ties,tie,
1188                           triangulate,swaps,next_id,where);
1189         
1190        }
1191    }
1192 
1193  else
1194    {
1195      /*      It is not a triangle, we have to triangulate it .
1196              Since it is not adjacent to anything we can triangulate it
1197              blindly
1198      */
1199      if (bucket == 0)
1200        {
1201          /*  Check to see if there is not an input edge */
1202          Last_Edge(&other1,&other2,&other3,0);
1203          if ((other1 == 0) && (other2 ==0))
1204            Blind_TriangulateEx(face->nPolSize,face->pPolygon,
1205                                TRUE,where);
1206          else
1207            Blind_TriangulateEx(face->nPolSize,face->pPolygon,
1208                                FALSE,where);
1209         
1210          if (face_array[temp->face_id].head == pListHead)       
1211            face_array[temp->face_id].pfNode = NULL;
1212          RemoveList(pListHead,(PLISTINFO) temp);
1213          /*      We will be at the beginning of the next strip. */
1214          begin = TRUE;
1215        }
1216     
1217      /*  If we have specified PARTIAL triangulation then
1218          we will go to special routines that will break the
1219          polygon and update the data structure. Else everything
1220          below will simply triangulate the whole polygon
1221      */
1222      else if (triangulate == PARTIAL)
1223        {
1224         
1225          /*  Return the face_id of the next polygon we will be using,
1226           */
1227          next_face_id = Min_Face_AdjEx(face_id,&next_bucket,ties);
1228         
1229         
1230          /* Don't do it partially, because we can go inside and get
1231             less adjacencies, for a quad we can do the whole thing.
1232          */
1233          if ((face_id == next_face_id) && (face->nPolSize == 4) && (swaps == ON))
1234            {
1235              next_face_id = Update_AdjacenciesEx(face_id, &next_bucket,
1236                                                  &e1,&e2,ties);
1237              if (next_face_id == -1)
1238                {
1239                  /*  There is no sequential face to go to, end the strip */
1240                  Polygon_OutputEx(temp,face_id,0,pListHead,output,
1241                                   ties,tie,triangulate,swaps,next_id,where);
1242                  return;
1243                }
1244             
1245              /* Break the tie,  if there was one */
1246              if (tie != FIRST)
1247                next_face_id = Get_Next_Face(tie,face_id,triangulate);
1248              Non_Blind_TriangulateEx(face->nPolSize,face->pPolygon,
1249                                      output,next_face_id,face_id,where);
1250             
1251              if (face_array[temp->face_id].head == pListHead)         
1252                face_array[temp->face_id].pfNode = NULL;
1253              RemoveList(pListHead,(PLISTINFO) temp);
1254            }
1255         
1256          /*   Was not a quad but we still do not want to do it partially for
1257               now, since we want to only do one triangle at a time
1258          */
1259          else if ((face_id == next_face_id) && (swaps == ON))
1260            Inside_Polygon(face->nPolSize,face->pPolygon,
1261                           face_id,pListHead,where);
1262         
1263          else
1264            {
1265              if ((tie != FIRST) && (swaps == ON))
1266                next_face_id = Get_Next_Face(tie,face_id,triangulate);
1267              Partial_Triangulate(face->nPolSize,face->pPolygon,
1268                                  output,next_face_id,face_id,next_id,
1269                                  pListHead,temp,where);
1270              /*    Check the next bucket again ,maybe it changed
1271                    We calculated one less, but that might not be the case
1272              */
1273            }
1274         
1275          if (Done(next_face_id,&next_bucket) == NULL)
1276            {
1277              /*  Check to see if there is not an input edge */
1278              Last_Edge(&other1,&other2,&other3,0);
1279              if ((other1 == 0) && (other2 ==0))
1280                Blind_TriangulateEx(face->nPolSize,face->pPolygon,
1281                                    TRUE,where);
1282              else
1283                Blind_TriangulateEx(face->nPolSize,face->pPolygon,
1284                                    FALSE,where);
1285             
1286              if (Done(face_id,&bucket) != NULL)
1287                {
1288                  pListHead = array[bucket];
1289                  lpListInfo = face_array[face_id].pfNode;
1290                  if (face_array[temp->face_id].head == pListHead)
1291                    face_array[lpListInfo->face_id].pfNode = NULL;
1292                  RemoveList(pListHead,(PLISTINFO)lpListInfo);
1293                }
1294              begin = TRUE;
1295              return;
1296            }
1297         
1298          begin = FALSE;
1299          pListHead = array[next_bucket];
1300          lpListInfo = face_array[next_face_id].pfNode;
1301          if (lpListInfo == NULL)
1302            {
1303              printf("There is an error finding the next polygon1 %d %d\n",
1304                     next_face_id,next_bucket);
1305              exit(0);
1306            }
1307          Polygon_OutputEx(lpListInfo,next_face_id,next_bucket,
1308                           pListHead, output,ties,tie,
1309                           triangulate,swaps,next_id,where);
1310        }
1311     
1312     
1313      else
1314        {
1315          /*  WHOLE triangulation */
1316          /*  It is not a triangle and has adjacencies.
1317              This means that we have to:
1318              1. TriangulateEx this polygon, not blindly because
1319              we have an edge that we want to come out on, that
1320              is the edge that is adjacent to a polygon with the
1321              least number of adjacencies. Also we must come in
1322              on the last seen edge.
1323              2. Update the adjacencies in the list, because we are
1324              using this polygon .
1325              3. Get the next polygon.
1326          */
1327          /*   Return the face_id of the next polygon we will be using,
1328               while updating the adjacency list by decrementing the
1329               adjacencies of everything adjacent to the current polygon.
1330          */
1331         
1332          next_face_id = Update_AdjacenciesEx(face_id,&next_bucket, &e1,&e2,ties);
1333         
1334          if (Done(next_face_id,&next_bucket) == NULL)
1335            {
1336              Polygon_OutputEx(temp,face_id,0,pListHead,output,ties,tie,
1337                               triangulate,swaps,next_id,where);
1338              /*    Because maybe there was more than 2 polygons on the edge */
1339              return;
1340            }
1341         
1342          /*      Break the tie,  if there was one */
1343          else if (tie != FIRST)
1344            next_face_id = Get_Next_Face(tie,face_id,triangulate);
1345         
1346          Non_Blind_TriangulateEx(face->nPolSize,face->pPolygon,
1347                                  output,next_face_id,face_id,where);
1348         
1349          if (face_array[temp->face_id].head == pListHead)
1350            face_array[temp->face_id].pfNode = NULL;
1351          RemoveList(pListHead,(PLISTINFO) temp);
1352          begin = FALSE;
1353          pListHead = array[next_bucket];
1354          lpListInfo = face_array[next_face_id].pfNode;
1355         
1356          if (lpListInfo == NULL)
1357            {
1358              printf("There is an error finding the next polygon2 %d %d\n",
1359                     next_face_id,next_bucket);
1360              exit(0);
1361            }
1362          Polygon_OutputEx(lpListInfo,next_face_id,next_bucket,
1363                           pListHead, output,ties,tie,
1364                           triangulate,swaps,next_id,where);
1365        }
1366     
1367    }
1368  Last_Edge(&e1,&e2,&e3,0);
1369}
1370
1371///     Adjacent:
1372int CustomStripifier::Adjacent(int id2,int id1, int *list, int size)
1373{
1374  /*    Return the vertex that is adjacent to id1,
1375        but is not id2, in the list of integers.
1376  */
1377 
1378  register int x=0;
1379 
1380  while (x < size)
1381    {
1382      if (*(list+x) == id1)
1383        {
1384          if ((x != (size -1)) && (x != 0))
1385            {
1386              if ( *(list+x+1) != id2)
1387                return *(list+x+1);
1388              else
1389                return *(list+x-1);
1390            }
1391          else if (x == (size -1))
1392            {
1393              if (*(list) != id2)
1394                return *(list);
1395              else
1396                return *(list+x-1);
1397            }
1398          else
1399            {
1400              if (*(list+size-1) != id2)
1401                return *(list+size-1);
1402              else
1403                return *(list+x+1);
1404            }
1405        }
1406      x++;
1407    }
1408  /*   if there are degeneracies */
1409  return id1;
1410}
1411
1412///     Rearrange_Index:
1413void CustomStripifier::Rearrange_Index(int *index, int size)
1414{
1415  /*    If we are in the middle of a strip we must find the
1416        edge to start on, which is the last edge that we had
1417        transmitted.
1418  */
1419  int x,f,y,e1,e2,e3;
1420  register int increment = 1;
1421  int *temp;
1422 
1423  /*    Find where the input edge is in the input list */
1424  Last_Edge(&e1,&e2,&e3,0);
1425  for (y = 0; y < size; y++)
1426    {
1427      if (*(index+y) == e2)
1428        {
1429          if ((y != (size - 1)) && (*(index+y+1) == e3))
1430            break;
1431          else if ((y == (size - 1)) && (*(index) == e3))
1432            break;
1433          else if ((y != 0) && (*(index+y-1) == e3))
1434            {
1435              increment = -1;
1436              break;
1437            }
1438          else if ((y==0) && (*(index+size-1) == e3))
1439            {
1440              increment = -1;
1441              break;
1442            }
1443        }
1444      if (*(index+y) == e3)
1445        {
1446          if ((y != (size - 1)) && (*(index+y+1) == e2))
1447            break;
1448          else if ((y == (size - 1)) && (*(index) == e2))
1449            break;
1450          else if ((y != 0) && (*(index+y-1) == e2))
1451            {
1452              increment = -1;
1453              break;
1454            }
1455          else if ((y==0) && (*(index+size-1) == e2))
1456            {
1457              increment = -1;
1458              break;
1459            }
1460        }
1461      /*        Edge is not here, we are at the beginning */
1462      if ((y == (size-1)) && (increment != -1))
1463        return;
1464    }
1465 
1466  /*    Now put the list into a new list, starting with the
1467        input edge. Increment tells us whether we have to go
1468        forward or backward.
1469  */
1470  /*    Was in good position already */
1471  if ((y == 0) && (increment == 1))
1472    return;
1473 
1474  temp = (int *) malloc(sizeof(int) * size);
1475  memcpy(temp,index,sizeof(int)*size);
1476 
1477  if (increment == 1)
1478    {
1479      x=0;
1480      for (f = y ; f< size; f++)
1481        {
1482          *(index+x) = *(temp+f);
1483          x++;
1484        }
1485      /*        Finish the rest of the list */ 
1486      for(f = 0; f < y ; f++)
1487        {
1488          *(index+x) = *(temp+f);
1489          x++;
1490        }
1491    }
1492  else
1493    {
1494      x=0;
1495      for (f = y ; f >= 0; f--)
1496        {
1497          *(index+x) = *(temp+f);
1498          x++;
1499        }
1500      /*        Finish the rest of the list */ 
1501      for(f = (size - 1); f > y ; f--)
1502        {
1503          *(index+x) = *(temp+f);
1504          x++;
1505        }
1506    }
1507}
1508
1509///     Delete_From_List:
1510void CustomStripifier::Delete_From_List(int id,int *list, int *size)
1511{
1512  /*    Delete the occurence of id in the list.
1513        (list has size size)
1514  */
1515 
1516  int *temp;
1517  register int x,y=0;
1518 
1519  temp = (int *) malloc(sizeof(int) * (*size));
1520  for (x=0; x<(*size); x++)
1521    {
1522      if (*(list+x) != id)
1523        {
1524          *(temp+y) = *(list+x);
1525          y++;
1526        }
1527    }
1528  *(temp+y) = -1;
1529  *size = *size - (*size - y - 1);
1530  memcpy(list,temp,sizeof(int)*(*size));
1531}
1532
1533///     Build_SGI_Table:
1534void CustomStripifier::Build_SGI_Table(int num_faces)
1535{
1536  /*      Build a table that has the polygons sorted by the
1537          number of adjacent polygons.
1538  */
1539  int x,y,size,tally=0;
1540  ListHead *pListHead;
1541  PF_FACES temp = NULL;
1542 
1543  /* For each face....*/
1544  for (x=0;x < num_faces;x++)
1545    {
1546      pListHead = PolFaces[x];
1547      temp = ( PF_FACES ) PeekList( pListHead, LISTHEAD, 0 );
1548      /*   Check each edge of the face and tally the number of adjacent
1549           polygons to this face.
1550      */                     
1551      if ( temp != NULL )
1552        {
1553          /*      Size of the polygon */
1554          size = temp->nPolSize;
1555          if (size != 1)
1556            {
1557              for (y = 0; y< size; y++)
1558                {
1559                  if (y != (size-1))
1560                    tally += Num_Adj(*(temp->pPolygon+y),*(temp->pPolygon+y+1));
1561                  else
1562                    tally+= Num_Adj(*(temp->pPolygon),*(temp->pPolygon+(size-1)));
1563                }
1564             
1565              /*   Tally is the number of polygons that is adjacent to
1566                   the current polygon.
1567              */
1568              /*      Now put the face in the proper bucket depending on tally. */
1569              Add_Sgi_Adj(tally,x);
1570              temp = NULL;
1571              tally=0;
1572            }
1573        }
1574    }
1575}
1576
1577///     Triangulate_Quad:
1578void CustomStripifier::Triangulate_Quad(int out_edge1,int out_edge2,int in_edge1,
1579                             int in_edge2,int size,int *index,
1580                             int reversed,int where)
1581{
1582  int vertex4,vertex5;
1583 
1584  /*    This routine will nonblindly triangulate a quad, meaning
1585        that there is a definite input and a definite output
1586        edge that we must adhere to. Reversed will tell the orientation
1587        of the input edge. (Reversed is -1 is we do not have an input
1588        edge, in other words we are at the beginning of a strip.)
1589        Out_edge* is the output edge, and in_edge* is the input edge.
1590        Index are the edges of the polygon
1591        and size is the size of the polygon. Begin is whether we are
1592        at the start of a new strip.
1593  */
1594 
1595  /*    If we do not have an input edge, then we can make our input
1596        edge whatever we like, therefore it will be easier to come
1597        out on the output edge.
1598  */
1599  if (reversed == -1)
1600    {
1601      vertex4 = Adjacent(out_edge1,out_edge2,index,size);
1602      vertex5 = Get_Other_Vertex(vertex4,out_edge1,out_edge2,index);
1603      Output_Tri(vertex5,vertex4,out_edge1,where);
1604      Output_Tri(vertex4,out_edge1,out_edge2,where);
1605      return;
1606    }
1607 
1608  /*    These are the 5 cases that we can have for the output edge */
1609 
1610  /*  Are they consecutive so that we form a triangle to
1611      peel off, but cannot use the whole quad?
1612  */
1613 
1614  if (in_edge2 == out_edge1)
1615    {
1616      /*        Output the triangle that comes out the correct
1617                edge last. First output the triangle that comes out
1618                the wrong edge.
1619      */
1620      vertex4 = Get_Other_Vertex(in_edge1,in_edge2,out_edge2,index);
1621      Output_Tri(in_edge1,in_edge2,vertex4,where);
1622      Output_Tri(vertex4,in_edge2,out_edge2,where);
1623      return;
1624    }
1625  /*    The next case is where it is impossible to come out the
1626        edge that we want. So we will have to start a new strip to
1627        come out on that edge. We will output the one triangle
1628        that we can, and then start the new strip with the triangle
1629        that comes out on the edge that we want to come out on.
1630  */
1631  else if (in_edge1 == out_edge1)
1632    {
1633      /*        We want to output the first triangle (whose output
1634                edge is not the one that we want.
1635                We have to find the vertex that we need, which is
1636                the other vertex which we do not have.
1637      */
1638      vertex4 = Get_Other_Vertex(in_edge2,in_edge1,out_edge2,index);
1639      Output_Tri(in_edge2,in_edge1,vertex4,where);
1640      Output_Tri(vertex4,in_edge1,out_edge2,where);
1641      return;
1642    }
1643 
1644  /*    Consecutive cases again, but with the output edge reversed */
1645  else if (in_edge1 == out_edge2)
1646    {
1647      vertex4 = Get_Other_Vertex(in_edge1,in_edge2,out_edge1,index);
1648      Output_Tri(in_edge2,in_edge1,vertex4,where);
1649      Output_Tri(vertex4,in_edge1,out_edge1,where);
1650      return;
1651    }
1652  else if (in_edge2 == out_edge2)
1653    {
1654      vertex4 = Get_Other_Vertex(in_edge1,in_edge2,out_edge1,index);
1655      Output_Tri(in_edge1,in_edge2,vertex4,where);
1656      Output_Tri(vertex4,in_edge2,out_edge1,where);
1657      return;
1658    }
1659 
1660  /*    The final case is where we want to come out the opposite
1661        edge.
1662  */
1663  else
1664    {
1665      if( ((!reversed) &&
1666           (out_edge1 == (Adjacent(in_edge1,in_edge2,index,size)))) ||
1667          ((reversed) &&
1668           (out_edge2 == (Adjacent(in_edge2,in_edge1,index,size)))))
1669        {
1670          /*    We need to know the orientation of the input
1671                edge, so we know which way to put the diagonal.
1672                And also the output edge, so that we triangulate
1673                correctly.
1674          */
1675          Output_Tri(in_edge1,in_edge2,out_edge2,where);
1676          Output_Tri(in_edge2,out_edge2,out_edge1,where);
1677        }
1678      else
1679        {
1680          /*      Input and output orientation was reversed, so diagonal will
1681                  be reversed from above.
1682          */
1683          Output_Tri(in_edge1,in_edge2,out_edge1,where);
1684          Output_Tri(in_edge2,out_edge1,out_edge2,where);
1685        }
1686      return;
1687    }
1688}
1689
1690///     Triangulate_Polygon:
1691void CustomStripifier::Triangulate_Polygon(     int out_edge1,int out_edge2,
1692                                                                                                                                                                                int in_edge1,   int in_edge2,
1693                                                                                                                                                                                int size,                       int *index,
1694                                                                                                                                                                                FILE *output,   int reversed,
1695                                                                                                                                                                                int face_id,    int where,
1696                                                                                                                                                                                int color1,             int color2,
1697                                                                                                                                                                                int color3)
1698{
1699  /*    We have a polygon that we need to nonblindly triangulate.
1700        We will recursively try to triangulate it, until we are left
1701        with a polygon of size 4, which can use the quad routine
1702        from above. We will be taking off a triangle at a time
1703        and outputting it. We will have 3 cases similar to the
1704        cases for the quad above. The inputs to this routine
1705        are the same as for the quad routine.
1706  */
1707 
1708  int vertex4;
1709  int *temp;
1710 
1711 
1712  /*    Since we are calling this recursively, we have to check whether
1713        we are down to the case of the quad.
1714  */
1715 
1716  if (size == 4)
1717    {
1718      Triangulate_Quad(out_edge1,out_edge2,in_edge1,in_edge2,size,
1719                       index,reversed,where);
1720      return;
1721    }
1722 
1723 
1724 
1725  /*    We do not have a specified input edge, and therefore we
1726        can make it anything we like, as long as we still come out
1727        the output edge that we want.
1728  */
1729  if (reversed  == -1)
1730    {
1731      /*        Get the vertex for the last triangle, which is
1732                the one coming out the output edge, before we do
1733                any deletions to the list. We will be doing this
1734                bottom up.
1735      */
1736      vertex4 = Adjacent(out_edge1,out_edge2,index,size);
1737      temp = (int *) malloc(sizeof(int) * size);
1738      memcpy(temp,index,sizeof(int)*size);
1739      Delete_From_List(out_edge2,index,&size);
1740      Triangulate_Polygon(out_edge1,vertex4,in_edge2,
1741                          vertex4,size-1,index,output,reversed,face_id,
1742                          where,color1,color2,color3);
1743      memcpy(index,temp,sizeof(int)*size);
1744      /*        Lastly do the triangle that comes out the output
1745                edge.
1746      */
1747      Output_Tri(vertex4,out_edge1,out_edge2,where);
1748      return;
1749    }
1750 
1751  /*    These are the 5 cases that we can have for the output edge */
1752 
1753  /*  Are they consecutive so that we form a triangle to
1754      peel off that comes out the correct output edge,
1755      but we cannot use the whole polygon?
1756  */
1757  if (in_edge2 == out_edge1)
1758    {
1759      /*        Output the triangle that comes out the correct
1760                edge last. First recursively do the rest of the
1761                polygon.
1762      */
1763      /*        Do the rest of the polygon without the triangle.
1764                We will be doing a fan triangulation.
1765      */
1766      /*        Get the vertex adjacent to in_edge1, but is not
1767                in_edge2.
1768      */
1769      vertex4 = Adjacent(in_edge2,in_edge1,index,size);
1770      Output_Tri(in_edge1,in_edge2,vertex4,where);
1771      /*        Create a new edgelist without the triangle that
1772                was just outputted.
1773      */
1774      temp = (int *) malloc(sizeof(int) * size);
1775      memcpy(temp,index,sizeof(int)*size);
1776      Delete_From_List(in_edge1,index,&size);
1777      Triangulate_Polygon(out_edge1,out_edge2,in_edge2,
1778                          vertex4,size-1,index,output,!reversed,face_id,
1779                          where,color1,color2,color3);
1780      memcpy(index,temp,sizeof(int)*size);
1781      return;
1782    }
1783 
1784  /*    Next case is where it is again consecutive, but the triangle
1785        formed by the consecutive edges do not come out of the
1786        correct output edge. For this case, we can not do much to
1787        keep it sequential. Try and do the fan.
1788  */
1789  else if (in_edge1 == out_edge1)
1790    {
1791      /*        Get vertex adjacent to in_edge2, but is not in_edge1 */
1792      vertex4 = Adjacent(in_edge1,in_edge2,index,size);
1793      Output_Tri(in_edge1,in_edge2,vertex4,where);
1794      /*        Since that triangle goes out of the polygon (the
1795                output edge of it), we can make our new input edge
1796                anything we like, so we will try to make it good for
1797                the strip. (This will be like starting a new strip,
1798                all so that we can go out the correct output edge.)
1799      */
1800      temp = (int *) malloc(sizeof(int) * size);
1801      memcpy(temp,index,sizeof(int)*size);
1802      Delete_From_List(in_edge2,index,&size);
1803      Triangulate_Polygon(out_edge1,out_edge2,in_edge1,
1804                          vertex4,size-1,index,output,reversed,face_id,
1805                          where,color1,color2,color3);
1806      memcpy(index,temp,sizeof(int)*size);
1807      return;
1808    }
1809  /*    Consecutive cases again, but with the output edge reversed */
1810  else if (in_edge1 == out_edge2)
1811    {
1812      /*        Get vertex adjacent to in_edge2, but is not in_edge1 */
1813      vertex4 = Adjacent(in_edge1,in_edge2,index,size);
1814      Output_Tri(in_edge2,in_edge1,vertex4,where);
1815      temp = (int *) malloc(sizeof(int) * size);
1816      memcpy(temp,index,sizeof(int)*size);
1817      Delete_From_List(in_edge2,index,&size);
1818      Triangulate_Polygon(out_edge1,out_edge2,in_edge1,
1819                          vertex4,size-1,index,output,reversed,face_id,
1820                          where,color1,color2,color3);
1821      memcpy(index,temp,sizeof(int)*size);
1822      return;
1823    }
1824  else if (in_edge2 == out_edge2)
1825    {
1826      /*        Get vertex adjacent to in_edge2, but is not in_edge1 */
1827      vertex4 = Adjacent(in_edge2,in_edge1,index,size);
1828      Output_Tri(in_edge1,in_edge2,vertex4,where);
1829      temp = (int *) malloc(sizeof(int) * size);
1830      memcpy(temp,index,sizeof(int)*size);
1831      Delete_From_List(in_edge1,index,&size);
1832      Triangulate_Polygon(out_edge1,out_edge2,vertex4,
1833                          in_edge2,size-1,index,output,reversed,face_id,
1834                          where,color1,color2,color3);
1835      memcpy(index,temp,sizeof(int)*size);
1836      return;
1837    }
1838 
1839  /*    Else the edge is not consecutive, and it is sufficiently
1840        far away, for us not to make a conclusion at this time.
1841        So we can take off a triangle and recursively call this
1842        function.
1843  */
1844  else
1845    {
1846      vertex4 = Adjacent(in_edge2,in_edge1,index,size);
1847      Output_Tri(in_edge1,in_edge2,vertex4,where);
1848      temp = (int *) malloc(sizeof(int) * size);
1849      memcpy(temp,index,sizeof(int)*size);
1850      Delete_From_List(in_edge1,index,&size);
1851      Triangulate_Polygon(out_edge1,out_edge2,in_edge2,
1852                          vertex4,size-1,index,output,!reversed,face_id,
1853                          where,color1,color2,color3);
1854      memcpy(index,temp,sizeof(int)*size);
1855      return;
1856    }
1857}
1858
1859///     Triangulate:
1860void CustomStripifier::Triangulate(int out_edge1,int out_edge2,int in_edge1,
1861                        int in_edge2,int size,int *index,
1862                        FILE *output,int reversed,int face_id, int where,
1863                        int color1, int color2,int color3)
1864{
1865  /*    We have the info we need to triangulate a polygon */
1866 
1867  if (size == 4)
1868    Triangulate_Quad(out_edge1,out_edge2,in_edge1,in_edge2,size,
1869                     index,reversed,where);
1870  else
1871    Triangulate_Polygon(out_edge1,out_edge2,in_edge1,in_edge2,size,
1872                        index,output,reversed,face_id,where,color1,color2,color3);
1873}
1874
1875///     Non_Blind_Triangulate:
1876void CustomStripifier::Non_Blind_Triangulate(int size,int *index,
1877                           FILE *output,int next_face_id,int face_id,int where,
1878                           int color1,int color2,int color3)
1879{
1880  int id1,id2,id3;
1881  int nedge1,nedge2;
1882  int reversed;
1883  /*    We have a polygon that has to be triangulated and we cannot
1884        do it blindly, ie we will try to come out on the edge that
1885        has the least number of adjacencies
1886  */
1887 
1888  Last_Edge(&id1,&id2,&id3,0);
1889  /*    Find the edge that is adjacent to the new face ,
1890        also return whether the orientation is reversed in the
1891        face of the input edge, which is id2 and id3.
1892  */
1893  if (next_face_id == -1)
1894    {
1895      printf("The face is -1 and the size is %d\n",size);
1896      exit(0);
1897    }
1898 
1899  reversed = Get_Edge(&nedge1,&nedge2,index,next_face_id,size,id2,id3);
1900  /* Do the triangulation */
1901 
1902  /* If reversed is -1, the input edge is not in the polygon,
1903     therefore we can have the input edge to be anything we like,
1904     since we are at the beginning of a strip
1905  */
1906  Triangulate(nedge1,nedge2,id2,id3,size,index,output,reversed,
1907              face_id, where,color1,color2,color3);
1908}
1909
1910///     Blind_Triangulate:
1911void CustomStripifier::Blind_Triangulate(int size, int *index, BOOL begin, int where)
1912{
1913  /*    save sides in temp array, we need it so we know
1914        about swaps.
1915  */
1916  int mode, decreasing,increasing,e1,e2,e3;
1917 
1918  /*    Rearrange the index list so that the input edge is first
1919   */
1920  if (!begin)
1921    Rearrange_Index(index,size);
1922 
1923  /*    We are given a polygon of more than 3 sides
1924        and want to triangulate it. We will output the
1925        triangles to the output file.
1926  */
1927 
1928  /*    Find where the input edge is in the input list */
1929  Last_Edge(&e1,&e2,&e3,0);
1930  if (( (!begin) && (*(index) == e2) ) || (begin))
1931    {
1932      Output_Tri(*(index+0),*(index+1),*(index+size-1),where);
1933      /*        If we have a quad, (chances are yes), then we know that
1934                we can just add one diagonal and be done. (divide the
1935                quad into 2 triangles.
1936      */
1937      if (size == 4)
1938        {
1939          Output_Tri(*(index+1),*(index+size-1),*(index+2),where);
1940          return;
1941        }
1942      increasing = 1;
1943      mode = 1;
1944     
1945    }
1946  else if (!begin)
1947    {
1948      Output_Tri(*(index+1),*(index+0),*(index+size-1),where);
1949      if (size == 4)
1950        {
1951          Output_Tri(*(index+0),*(index+size-1),*(index+2),where);
1952          return;
1953        }
1954      Output_Tri(*(index+0),*(index+size-1),*(index+2),where);
1955      increasing = 2;
1956      mode = 0;
1957    }
1958  if (size != 4)
1959    {
1960      /*        We do not have a quad, we have something bigger. */
1961      decreasing = size - 1;           
1962      do
1963        {
1964          /*    Will be alternating diagonals, so we will be increasing
1965                and decreasing around the polygon.
1966          */
1967          if (mode)
1968            {
1969              Output_Tri(*(index+increasing),*(index+decreasing),
1970                         *(index+increasing+1),where);
1971              increasing++;
1972            }
1973          else
1974            {
1975              Output_Tri(*(index+decreasing),*(index+increasing),
1976                         *(index+decreasing-1),where);
1977              decreasing--;
1978            }
1979          mode = !mode;
1980        } while ((decreasing - increasing) >= 2);
1981     
1982    }
1983}
1984
1985///     Get_Edge:
1986int CustomStripifier::Get_Edge(int *edge1,int *edge2,int *index,int face_id,
1987             int size, int id1, int id2)
1988{
1989  /*    Put the edge that is adjacent to face_id into edge1
1990        and edge2. For each edge see if it is adjacent to
1991        face_id. Id1 and id2 is the input edge, so see if
1992        the orientation is reversed, and save it in reversed.
1993  */
1994  register int x;
1995  int reversed = -1;
1996  BOOL set = FALSE;
1997 
1998  for (x=0; x< size; x++)
1999    {
2000      if (x == (size-1))
2001        {
2002          if ((*(index) == id1) && (*(index+size-1)==id2))
2003            {
2004              if (set)
2005                return 1;
2006              reversed = 1;
2007            }
2008          else if ((*(index) == id2) && (*(index+size-1)==id1))
2009            {
2010              if (set)
2011                return 0;
2012              reversed = 0;
2013            }
2014         
2015          if (Look_Up(*(index),*(index+size-1),face_id))
2016            {
2017              if ( (out1 != -1) &&
2018                   ( (out1 == *(index)) ||
2019                     (out1 == *(index+size-1)) ) &&
2020                   ( (out2 == *(index)) ||
2021                     (out2 == *(index+size-1)) ))
2022                {
2023                  set = TRUE;
2024                  *edge1 = *(index);
2025                  *edge2 = *(index+size-1);
2026                }
2027              else if (out1 == -1)
2028                {
2029                  set = TRUE;
2030                  *edge1 = *(index);
2031                  *edge2 = *(index+size-1);
2032                }
2033              if ((reversed != -1) && (set)) 
2034                return reversed;
2035            }
2036        }               
2037      else
2038        {
2039          if ((*(index+x) == id1) && (*(index+x+1)==id2))
2040            {
2041              if (set)
2042                return 0;
2043              reversed = 0;
2044            }
2045          else if ((*(index+x) == id2) && (*(index+x+1)==id1))
2046            {
2047              if (set)
2048                return 1;
2049              reversed = 1;
2050            }
2051         
2052          if (Look_Up(*(index+x),*(index+x+1),face_id))
2053            {
2054              if ( (out1 != -1) &&
2055                   ( (out1 == *(index+x)) ||
2056                     (out1 == *(index+x+1)) ) &&
2057                   ((out2 == *(index+x)) ||
2058                    (out2 == *(index+x+1))))
2059                {
2060                  set = TRUE;
2061                  *edge1 = *(index+x);
2062                  *edge2 = *(index+x+1);
2063                }
2064              else if (out1 == -1)
2065                {
2066                  set = TRUE;
2067                  *edge1 = *(index+x);
2068                  *edge2 = *(index+x + 1);
2069                }
2070              if ((reversed != -1) && (set))
2071                return reversed;
2072            }
2073        }
2074    }                   
2075  if ((x == size) && (reversed != -1))
2076    {
2077      /*        Could not find the output edge */
2078      printf("Error in the Lookup %d %d %d %d %d %d %d %d\n",
2079             face_id,id1,id2,reversed,*edge1,*edge2,out1,out2);
2080      exit(0);
2081    }
2082  return reversed;
2083}
2084
2085///     Udate_Face:
2086void CustomStripifier::Update_Face(int *next_bucket, int *min_face, int face_id, int *e1,
2087                        int *e2,int temp1,int temp2,int *ties)
2088{
2089  /*    We have a face id that needs to be decremented.
2090        We have to determine where it is in the structure,
2091        so that we can decrement it.
2092  */
2093  /*    The number of adjacencies may have changed, so to locate
2094        it may be a little tricky. However we know that the number
2095        of adjacencies is less than or equal to the original number
2096        of adjacencies,
2097  */
2098  int y,size;
2099  ListHead *pListHead;
2100  PF_FACES temp = NULL;
2101  PLISTINFO lpListInfo;
2102  static int each_poly = 0;
2103  BOOL there = FALSE;
2104 
2105  pListHead = PolFaces[face_id];
2106  temp = ( PF_FACES ) PeekList( pListHead, LISTHEAD, 0 );
2107  /*    Check each edge of the face and tally the number of adjacent
2108        polygons to this face.
2109  */                   
2110  if ( temp != NULL )
2111    {
2112      /*        Size of the polygon */
2113      size = temp->nPolSize;
2114      /*  We did it already */
2115      if (size == 1)
2116        return;
2117      for (y = 0; y< size; y++)
2118        {
2119          /*    If we are doing partial triangulation, we must check
2120                to see whether the edge is still there in the polygon,
2121                since we might have done a portion of the polygon
2122                and saved the rest for later.
2123          */
2124          if (y != (size-1))
2125            {
2126              if( ((temp1 == *(temp->pPolygon+y)) &&
2127                   (temp2 ==*(temp->pPolygon+y+1))) ||
2128                  ((temp2 == *(temp->pPolygon+y)) &&
2129                   (temp1 ==*(temp->pPolygon+y+1))))
2130                /*      edge is still there we are ok */
2131                there = TRUE;
2132            }
2133          else
2134            {
2135              if( ((temp1 == *(temp->pPolygon)) &&
2136                   (temp2 == *(temp->pPolygon+size-1))) ||
2137                  ((temp2 == *(temp->pPolygon)) &&
2138                   (temp1 ==*(temp->pPolygon+size-1))))
2139                /*      edge is still there we are ok */
2140                there = TRUE;
2141            }
2142        }
2143     
2144      if (!there)
2145        /*      Original edge was already used, we cannot use this polygon */
2146        return;
2147     
2148      /*        We have a starting point to start our search to locate
2149                this polygon.
2150      */
2151     
2152      /*        Check to see if this polygon was done */
2153      lpListInfo = Done(face_id,&y);
2154     
2155      if (lpListInfo == NULL)
2156        return;
2157     
2158      /*  Was not done, but there is an error in the adjacency calculations */
2159      if (y == 0)
2160        {
2161          printf("There is an error in finding the adjacencies\n");
2162          exit(0);
2163        }
2164     
2165      /*        Now put the face in the proper bucket depending on tally. */
2166      /*        First add it to the new bucket, then remove it from the old */
2167      Add_Sgi_Adj(y-1,face_id);
2168      RemoveList(array[y],lpListInfo);
2169     
2170      /*        Save it if it was the smallest seen so far since then
2171                it will be the next face
2172                Here we will have different options depending on
2173                what we want for resolving ties:
2174                1) First one we see we will use
2175                2) Random resolving
2176                3) Look ahead
2177                4) Alternating direction
2178      */
2179      /*        At a new strip */
2180      if (*next_bucket == 60)
2181        *ties = *ties + each_poly;
2182      /*        Have a tie */
2183      if (*next_bucket == (y-1))
2184        {
2185          Add_Ties(face_id);
2186          each_poly++;
2187        }
2188      /*        At a new minimum */
2189      if (*next_bucket > (y-1))
2190        {
2191          *next_bucket = y-1;
2192          *min_face = face_id;
2193          *e1 = temp1;
2194          *e2 = temp2;
2195          each_poly = 0;
2196          Clear_Ties();
2197          Add_Ties(face_id);
2198        }
2199    }
2200}
2201
2202///     Delete_Adj:
2203void CustomStripifier::Delete_Adj(int id1, int id2,int *next_bucket,int *min_face,
2204                       int current_face,int *e1,int *e2,int *ties)
2205{
2206  /*    Find the face that is adjacent to the edge and is not the
2207        current face. Delete one adjacency from it. Save the min
2208        adjacency seen so far.
2209  */
2210  register int count=0;
2211  PF_EDGES temp = NULL;
2212  ListHead *pListHead;
2213  int next_face;
2214 
2215  /*    Always want smaller id first */
2216  switch_lower(&id1,&id2);
2217 
2218  pListHead = PolEdges[id1];
2219  temp = (PF_EDGES) PeekList(pListHead,LISTHEAD,count);
2220  if (temp == NULL)
2221    /*  It could be a new edge that we created. So we can
2222        exit, since there is not a face adjacent to it.
2223    */
2224    return;
2225  while (temp->edge[0] != id2)
2226    {
2227      count++;
2228      temp = ( PF_EDGES )GetNextNode(temp);                                       
2229     
2230      if (temp == NULL)
2231        /*      Was a new edge that was created and therefore
2232                does not have anything adjacent to it
2233        */
2234        return;
2235    }
2236  /*    Was not adjacent to anything else except itself */
2237  if (temp->edge[2] == -1)
2238    return;
2239 
2240  /*    Was adjacent to something */
2241  else
2242    {
2243      if (temp->edge[2] == current_face)
2244        next_face =  temp->edge[1];
2245      else
2246        next_face = temp->edge[2];
2247    }
2248  /*    We have the other face adjacent to this edge, it is
2249        next_face. Now we need to decrement this faces' adjacencies.
2250  */
2251  Update_Face(next_bucket, min_face, next_face,e1,e2,id1,id2,ties);
2252}
2253
2254///     Update_Adjacencies:
2255int CustomStripifier::Update_Adjacencies(int face_id, int *next_bucket, int *e1, int *e2,
2256                       int *ties)
2257{
2258  /*    Give the face with id face_id, we want to decrement
2259        all the faces that are adjacent to it, since we will
2260        be deleting face_id from the data structure.
2261        We will return the face that has the least number
2262        of adjacencies.
2263  */
2264  PF_FACES temp = NULL;
2265  ListHead *pListHead;
2266  int size,y,min_face = -1;
2267 
2268  *next_bucket = 60;
2269  pListHead = PolFaces[face_id];
2270  temp = ( PF_FACES ) PeekList( pListHead, LISTHEAD, 0 );
2271 
2272  if ( temp == NULL )
2273    {
2274      printf("The face was already deleted, there is an error\n");
2275      exit(0);
2276    }
2277 
2278  /*    Size of the polygon */
2279  size = temp->nPolSize;
2280  for (y = 0; y< size; y++)
2281    {
2282      if (y != (size-1))
2283        Delete_Adj(*(temp->pPolygon+y),*(temp->pPolygon+y+1),
2284                   next_bucket,&min_face,face_id,e1,e2,ties);
2285      else
2286        Delete_Adj(*(temp->pPolygon),*(temp->pPolygon+(size-1)),
2287                   next_bucket,&min_face,face_id,e1,e2,ties);
2288    }
2289  return (min_face);
2290}
2291
2292///     Old_Adj:
2293int CustomStripifier::Old_Adj(int face_id)
2294{
2295  /*    Find the bucket that the face_id is currently in,
2296        because maybe we will be deleting it.
2297  */
2298  PF_FACES temp = NULL;
2299  ListHead *pListHead;
2300  int y;
2301 
2302  pListHead = PolFaces[face_id];
2303  temp = ( PF_FACES ) PeekList( pListHead, LISTHEAD, 0 );
2304  if ( temp == NULL )
2305    {
2306      printf("The face was already deleted, there is an error\n");
2307      exit(0);
2308    }
2309 
2310  if (Done(face_id,&y) == NULL)
2311    {
2312      printf("There is an error in finding the face\n");
2313      exit(0);
2314    }
2315  return y;
2316}
2317
2318///     Number_Adj:
2319int CustomStripifier::Number_Adj(int id1, int id2, int curr_id)
2320{
2321  /*    Given edge whose endpoints are specified by id1 and id2,
2322        determine how many polygons share this edge and return that
2323        number minus one (since we do not want to include the polygon
2324        that the caller has already).
2325  */
2326 
2327  int size,y,count=0;
2328  PF_EDGES temp = NULL;
2329  PF_FACES temp2 = NULL;
2330  ListHead *pListHead;
2331  BOOL there= FALSE;
2332 
2333  /*    Always want smaller id first */
2334  switch_lower(&id1,&id2);
2335 
2336  pListHead = PolEdges[id1];
2337  temp = (PF_EDGES) PeekList(pListHead,LISTHEAD,count);
2338  if (temp == NULL)
2339    /*  new edge that was created might not be here */
2340    return 0;
2341  while (temp->edge[0] != id2)
2342    {
2343      count++;
2344      temp = ( PF_EDGES )GetNextNode(temp);                               
2345     
2346      if (temp == NULL)
2347        /*      This edge was not there in the original, which
2348                mean that we created it in the partial triangulation.
2349                So it is adjacent to nothing.
2350        */
2351        return 0;
2352    }
2353  /*    Was not adjacent to anything else except itself */
2354  if (temp->edge[2] == -1)
2355    return 0;
2356  else
2357    {
2358      /* It was adjacent to another polygon, but maybe we did this
2359         polygon already, and it was done partially so that this edge
2360         could have been done
2361      */
2362      if (curr_id != temp->edge[1])
2363        {
2364          /* Did we use this polygon already?and it was deleted
2365             completely from the structure
2366          */
2367          pListHead = PolFaces[temp->edge[1]];
2368          temp2 = ( PF_FACES ) PeekList( pListHead, LISTHEAD, 0 );
2369          if (Done(temp->edge[1],&size) == NULL)
2370            return 0;
2371        }
2372      else
2373        {
2374          pListHead = PolFaces[temp->edge[2]];
2375          temp2 = ( PF_FACES ) PeekList( pListHead, LISTHEAD, 0 );
2376          if (Done(temp->edge[2],&size)== NULL)
2377            return 0;
2378        }
2379     
2380      /* Now we have to check whether it was partially done, before
2381         we can say definitely if it is adjacent.
2382         Check each edge of the face and tally the number of adjacent
2383         polygons to this face.
2384      */                       
2385      if ( temp2 != NULL )
2386        {
2387          /* Size of the polygon */
2388          size = temp2->nPolSize;
2389          for (y = 0; y< size; y++)
2390            {
2391              /* If we are doing partial triangulation, we must check
2392                 to see whether the edge is still there in the polygon,
2393                 since we might have done a portion of the polygon
2394                 and saved the rest for later.
2395              */
2396              if (y != (size-1))
2397                {
2398                  if(((id1 == *(temp2->pPolygon+y)) &&
2399                      (id2 ==*(temp2->pPolygon+y+1))) ||
2400                     ((id2 == *(temp2->pPolygon+y)) &&
2401                      (id1 ==*(temp2->pPolygon+y+1))))
2402                    /*  edge is still there we are ok */
2403                    there = TRUE;
2404                }
2405              else
2406                {
2407                  if(((id1 == *(temp2->pPolygon)) &&
2408                      (id2 == *(temp2->pPolygon+size-1))) ||
2409                     ((id2 == *(temp2->pPolygon)) &&
2410                      (id1 ==*(temp2->pPolygon+size-1))))
2411                    /*  edge is still there we are ok */
2412                    there = TRUE;
2413                }
2414            }
2415        }
2416     
2417      if (there )
2418        return 1;
2419      return 0;
2420    }
2421}
2422
2423///     Min_Adj:
2424int CustomStripifier::Min_Adj(int id)
2425{
2426  /*    Used for the lookahead to break ties. It will
2427        return the minimum adjacency found at this face.
2428  */
2429  int y,numverts,t,x=60;
2430  PF_FACES temp=NULL;
2431  ListHead *pListHead;
2432 
2433  /*    If polygon was used then we can't use this face */
2434  if (Done(id,&y) == NULL)
2435    return 60;
2436 
2437  /*    It was not used already */
2438  pListHead = PolFaces[id];
2439  temp = ( PF_FACES ) PeekList( pListHead, LISTHEAD, 0 );
2440  if ( temp != NULL )
2441    {
2442      numverts = temp->nPolSize;
2443      for (y = 0; y< numverts; y++)
2444        {
2445          if (y != (numverts-1))
2446            t = Number_Adj(*(temp->pPolygon+y),*(temp->pPolygon+y+1),id);
2447          else
2448            t = Number_Adj(*(temp->pPolygon),*(temp->pPolygon+(numverts-1)),id);
2449          if (t < x)
2450            x = t;
2451        }
2452    }
2453  if (x == -1)
2454    {
2455      printf("Error in the look\n");
2456      exit(0);
2457    }
2458  return x;
2459}
2460
2461///     Edje_Least:
2462void CustomStripifier::Edge_Least(int *index,int *new1,int *new2,int face_id,int size)
2463{
2464  /*   We had a polygon without an input edge and now we re going to pick one
2465       of the edges with the least number of adjacencies to be the input
2466       edge
2467  */
2468  register int x,value,smallest=60;
2469 
2470  for (x = 0; x<size; x++)
2471    {
2472      if (x != (size -1) )
2473        value = Number_Adj(*(index+x),*(index+x+1),face_id);
2474      else
2475        value = Number_Adj(*(index),*(index+size-1),face_id);
2476      if (value < smallest)
2477        {
2478          smallest = value;
2479          if (x != (size -1))
2480            {
2481              *new1 = *(index+x);
2482              *new2 = *(index+x+1);
2483            }
2484          else
2485            {
2486              *new1 = *(index);
2487              *new2 = *(index+size-1);
2488            }
2489        }
2490    }
2491  if ((smallest == 60) || (smallest < 0))
2492    {
2493      printf("There is an error in getting the least edge\n");
2494      exit(0);
2495    }
2496}
2497
2498///     Check_In_Polygon:
2499void CustomStripifier::Check_In_Polygon(int face_id, int *min, int size)
2500{
2501  /*  Check to see the adjacencies by going into a polygon that has
2502      greater than 4 sides.
2503  */
2504 
2505  ListHead *pListHead;
2506  PF_FACES temp;
2507  int y,id1,id2,id3,x=0,z=0;
2508  int saved[2];
2509  int big_saved[60];
2510 
2511  pListHead = PolFaces[face_id];
2512  temp = ( PF_FACES ) PeekList( pListHead, LISTHEAD, 0 );
2513 
2514  /*   Get the input edge that we came in on */
2515  Last_Edge(&id1,&id2,&id3,0);
2516 
2517  /*  Find the number of adjacencies to the edges that are adjacent
2518      to the input edge.
2519  */
2520  for (y=0; y< size; y++)
2521    {
2522      if (y != (size-1))
2523        {
2524          if (((*(temp->pPolygon+y) == id2) && (*(temp->pPolygon+y+1) != id3))
2525              || ((*(temp->pPolygon+y) == id3) && (*(temp->pPolygon+y+1) != id2)))
2526            {
2527              saved[x++] = Number_Adj(*(temp->pPolygon+y),
2528                                      *(temp->pPolygon+y+1),face_id);
2529              big_saved[z++] = saved[x-1];
2530            }
2531          else
2532            big_saved[z++] = Number_Adj(*(temp->pPolygon+y),
2533                                        *(temp->pPolygon+y+1),face_id);
2534        }
2535      else
2536        {
2537          if (((*(temp->pPolygon) == id2) &&
2538               (*(temp->pPolygon+size-1) != id3)) ||
2539              ((*(temp->pPolygon) == id3) &&
2540               (*(temp->pPolygon+size-1) != id2)))
2541            {
2542              saved[x++] = Number_Adj(*(temp->pPolygon),
2543                                      *(temp->pPolygon+size-1),face_id);
2544              big_saved[z++] = saved[x-1];
2545            }
2546          else
2547            big_saved[z++] = Number_Adj(*(temp->pPolygon),
2548                                        *(temp->pPolygon+size-1),face_id);
2549        }
2550    }
2551  /*  There was an input edge */
2552  if (x == 2)
2553    {
2554      if (saved[0] < saved[1])
2555        /*  Count the polygon that we will be cutting as another adjacency*/
2556        *min = saved[0] + 1;
2557      else
2558        *min = saved[1] + 1;
2559    }
2560  /*  There was not an input edge */
2561  else
2562    {
2563      if (z != size)
2564        {
2565          printf("There is an error with the z %d %d\n",size,z);
2566          exit(0);
2567        }
2568      *min = 60;
2569      for (x = 0; x < size; x++)
2570        {
2571          if (*min > big_saved[x])
2572            *min = big_saved[x];
2573        }
2574    }
2575}
2576
2577///     New_Face:
2578void CustomStripifier::New_Face (int face_id, int v1, int v2, int v3)
2579{
2580  /*    We want to change the face that was face_id, we will
2581        change it to a triangle, since the rest of the polygon
2582        was already outputtted
2583  */
2584  ListHead *pListHead;
2585  PF_FACES temp = NULL;
2586 
2587  pListHead = PolFaces[face_id];
2588  temp = ( PF_FACES ) PeekList( pListHead, LISTHEAD, 0);
2589  /*    Check each edge of the face and tally the number of adjacent
2590        polygons to this face.
2591  */                   
2592  if ( temp != NULL )
2593    {
2594      /*        Size of the polygon */
2595      if (temp->nPolSize != 4)
2596        {
2597          printf("There is a miscalculation in the partial\n");
2598          exit (0);
2599        }
2600      temp->nPolSize = 3;
2601      *(temp->pPolygon) = v1;
2602      *(temp->pPolygon+1) = v2;
2603      *(temp->pPolygon+2) = v3;
2604    }
2605}
2606
2607///     New_Size_Face:
2608void CustomStripifier::New_Size_Face(int face_id)
2609{
2610  /*    We want to change the face that was face_id, we will
2611        change it to a triangle, since the rest of the polygon
2612        was already outputtted
2613  */
2614  ListHead *pListHead;
2615  PF_FACES temp = NULL;
2616 
2617  pListHead = PolFaces[face_id];
2618  temp = ( PF_FACES ) PeekList( pListHead, LISTHEAD, 0 );
2619  /*    Check each edge of the face and tally the number of adjacent
2620        polygons to this face.
2621  */                   
2622  if ( temp != NULL )
2623    (temp->nPolSize)--;
2624  else
2625    printf("There is an error in updating the size\n");
2626}
2627
2628///     Check_In_Quad:
2629void  CustomStripifier::Check_In_Quad(int face_id,int *min)
2630{
2631  /*   Check to see what the adjacencies are for the polygons that
2632       are inside the quad, ie the 2 triangles that we can form.
2633  */
2634  ListHead *pListHead;
2635  int y,id1,id2,id3,x=0;
2636  int saved[4];
2637  PF_FACES temp;
2638  register int size = 4;
2639 
2640  pListHead = PolFaces[face_id];
2641  temp = ( PF_FACES ) PeekList( pListHead, LISTHEAD, 0 );
2642 
2643  /*   Get the input edge that we came in on */
2644  Last_Edge(&id1,&id2,&id3,0);
2645 
2646  /*    Now find the adjacencies for the inside triangles */
2647  for (y = 0; y< size; y++)
2648    {
2649      /*     Will not do this if the edge is the input edge */
2650      if (y != (size-1))
2651        {
2652          if ((((*(temp->pPolygon+y) == id2) &&
2653                (*(temp->pPolygon+y+1) == id3))) ||
2654              (((*(temp->pPolygon+y) == id3) &&
2655                (*(temp->pPolygon+y+1) == id2))))
2656            saved[x++] = -1;
2657          else
2658            {
2659              if (x == 4)
2660                {
2661                  printf("There is an error in the check in quad \n");
2662                  exit(0);
2663                }
2664              /*    Save the number of Adjacent Polygons to this edge */
2665              saved[x++] = Number_Adj(*(temp->pPolygon+y),
2666                                      *(temp->pPolygon+y+1),face_id);
2667            }
2668        }
2669      else if ((((*(temp->pPolygon) == id2) &&
2670                 (*(temp->pPolygon+size-1) == id3))) ||
2671               (((*(temp->pPolygon) == id3) &&
2672                 (*(temp->pPolygon+size-1) == id2))) )
2673        saved[x++] = -1;
2674      else
2675        {
2676          if (x == 4)
2677            {
2678              printf("There is an error in the check in quad \n");
2679              exit(0);
2680            }
2681          /*    Save the number of Adjacent Polygons to this edge */
2682          saved[x++] = Number_Adj(*(temp->pPolygon),
2683                                  *(temp->pPolygon+size-1),face_id);
2684         
2685        }
2686    }
2687  if (x != 4)
2688    {
2689      printf("Did not enter all the values %d \n",x);
2690      exit(0);
2691    }
2692 
2693  *min = 10;
2694  for (x=0; x<4; x++)
2695    {
2696      if (x!= 3)
2697        {
2698          if ((saved[x] != -1) && (saved[x+1] != -1) &&
2699              ((saved[x] + saved[x+1]) < *min))
2700            *min = saved[x] + saved[x+1];
2701        }
2702      else
2703        {
2704          if ((saved[0] != -1) && (saved[x] != -1) &&
2705              ((saved[x] + saved[0]) < *min))
2706            *min = saved[0] + saved[x];
2707        }
2708    }
2709}
2710
2711///     Get_Output_Edge:
2712int CustomStripifier::Get_Output_Edge(int face_id, int size, int *index,int id2,int id3)
2713{
2714  /*  Return the vertex adjacent to either input1 or input2 that
2715      is adjacent to the least number of polygons on the edge that
2716      is shared with either input1 or input2.
2717  */
2718  register int x=0,y;
2719  int saved[2];
2720  int edges[2][1];
2721 
2722  for (y = 0; y < size; y++)
2723    {
2724      if (y != (size-1))
2725        {
2726          if (((*(index+y) == id2) && (*(index+y+1) != id3))
2727              || ((*(index+y) == id3) && (*(index+y+1) != id2)))
2728            {
2729              saved[x++] = Number_Adj(*(index+y),*(index+y+1),face_id);
2730              edges[x-1][0] = *(index+y+1);
2731            }
2732          else if (y != 0)
2733            {
2734              if (( (*(index+y) == id2) && (*(index+y-1) != id3) ) ||
2735                  ( (*(index+y) == id3) && (*(index+y-1) != id2)) )
2736                {
2737                  saved[x++] = Number_Adj(*(index+y),*(index+y-1),face_id);
2738                  edges[x-1][0] = *(index+y-1);
2739                }
2740            }
2741          else if (y == 0)
2742            {
2743              if (( (*(index) == id2) && (*(index+size-1) != id3) ) ||
2744                  ( (*(index) == id3) && (*(index+size-1) != id2)) )
2745                {
2746                  saved[x++] = Number_Adj(*(index),*(index+size-1),face_id);
2747                  edges[x-1][0] = *(index+size-1);
2748                }
2749            }
2750         
2751        }
2752      else
2753        {
2754          if (((*(index+size-1) == id2) && (*(index) != id3))
2755              || ((*(index+size-1) == id3) && (*(index) != id2)))
2756            {
2757              saved[x++] = Number_Adj(*(index),*(index+size-1),face_id);
2758              edges[x-1][0] = *(index);
2759            }
2760         
2761          if (( (*(index+size-1) == id2) && (*(index+y-1) != id3) ) ||
2762              ( (*(index+size-1) == id3) && (*(index+y-1) != id2)) )
2763            {
2764              saved[x++] = Number_Adj(*(index+size-1),*(index+y-1),face_id);
2765              edges[x-1][0] = *(index+y-1);
2766            }
2767        }
2768    }
2769  if ((x != 2))
2770    {
2771      printf("There is an error in getting the input edge %d \n",x);
2772      exit(0);
2773    }
2774  if (saved[0] < saved[1])
2775    return edges[0][0];
2776  else
2777    return edges[1][0];
2778 
2779}
2780
2781///     Get_Input_Edge:
2782void CustomStripifier::Get_Input_Edge(int *index,int id1,int id2,int id3,
2783                    int *new1,int *new2,int size,int face_id)
2784{
2785  /*  We had a polygon without an input edge and now we are going to pick one
2786      as the input edge. The last triangle was id1,id2,id3, we will try to
2787      get an edge to have something in common with one of those vertices,
2788      otherwise we will pick the edge with the least number of adjacencies.
2789  */
2790 
2791  register int x;
2792  int saved[3];
2793 
2794  saved[0] = -1;
2795  saved[1] = -1;
2796  saved[2] = -1;
2797 
2798  /*  Go through the edges to see if there is one in common with one
2799      of the vertices of the last triangle that we had, preferably id2 or
2800      id3 since those are the last 2 things in the stack of size 2.
2801  */
2802  for (x=0; x< size; x++)
2803    {
2804      if (*(index+x) == id1)
2805        {
2806          if (x != (size-1))
2807            saved[0] = *(index+x+1);
2808          else
2809            saved[0] = *(index);
2810        }
2811     
2812      if (*(index+x) == id2)
2813        {
2814          if (x != (size-1))
2815            saved[1] = *(index+x+1);
2816          else
2817            saved[1] = *(index);
2818        }
2819     
2820      if (*(index+x) == id3)
2821        {
2822          if (x != (size -1))
2823            saved[2] = *(index+x+1);
2824          else
2825            saved[2] = *(index);
2826        }
2827    }
2828  /*  Now see what we saved */
2829  if (saved[2] != -1)
2830    {
2831      *new1 = id3;
2832      *new2 = saved[2];
2833      return;
2834    }
2835  else if (saved[1] != -1)
2836    {
2837      *new1 = id2;
2838      *new2 = saved[1];
2839      return;
2840    }
2841  else if (saved[0] != -1)
2842    {
2843      *new1 = id1;
2844      *new2 = saved[0];
2845      return;
2846    }
2847  /*  We did not find anything so get the edge with the
2848      least number of adjacencies
2849  */
2850  Edge_Least(index,new1,new2,face_id,size);
2851 
2852}
2853
2854///     Find_Face:
2855int CustomStripifier::Find_Face(int current_face, int id1, int id2, int *bucket)
2856{
2857  /*    Find the face that is adjacent to the edge and is not the
2858        current face.
2859  */
2860  register int size,y,count=0;   
2861  PF_EDGES temp = NULL;
2862  PF_FACES temp2 = NULL;
2863  ListHead *pListHead;
2864  int next_face;
2865  BOOL there = FALSE;
2866 
2867 
2868  /*    Always want smaller id first */
2869  switch_lower(&id1,&id2);
2870 
2871  pListHead = PolEdges[id1];
2872  temp = (PF_EDGES) PeekList(pListHead,LISTHEAD,count);
2873  /*  The input edge was a new edge */
2874  if (temp == NULL)
2875    return -1;
2876 
2877  while (temp->edge[0] != id2)
2878    {
2879      count++;
2880      temp = ( PF_EDGES )GetNextNode(temp);                                   
2881     
2882      /*  The input edge was a new edge */
2883      if (temp == NULL)
2884        return -1;
2885    }
2886  /*    Was not adjacent to anything else except itself */
2887  if (temp->edge[2] == -1)
2888    return -1;
2889  else
2890    {
2891      if (temp->edge[2] == current_face)
2892        next_face =  temp->edge[1];
2893      else
2894        next_face = temp->edge[2];
2895    }
2896  /* We have the other face adjacent to this edge, it is
2897     next_face.
2898  */
2899  pListHead = PolFaces[next_face];
2900  temp2 = ( PF_FACES ) PeekList( pListHead, LISTHEAD, 0 );
2901 
2902  /* See if the face was already deleted, and where
2903     it is if it was not
2904  */
2905 
2906  if (Done(next_face,bucket) == NULL)
2907    return -1;
2908 
2909  /*  Make sure the edge is still in this polygon, and that it is not
2910      done
2911  */
2912  /* Size of the polygon */
2913  size = temp2->nPolSize;
2914  for (y = 0; y< size; y++)
2915    {
2916      /*  Make sure that the edge is still in the
2917          polygon and was not deleted, because if the edge was
2918          deleted, then we used it already.
2919      */
2920      if (y != (size-1))
2921        {
2922          if( ((id1 == *(temp2->pPolygon+y)) && (id2 ==*(temp2->pPolygon+y+1)))
2923              || ((id2 == *(temp2->pPolygon+y)) && (id1 ==*(temp2->pPolygon+y+1))))
2924            /*  edge is still there we are ok */
2925            there = TRUE;
2926        }
2927      else
2928        {               
2929          if(((id1 == *(temp2->pPolygon)) && (id2 ==*(temp2->pPolygon+size-1))) ||
2930             ((id2 == *(temp2->pPolygon)) && (id1 ==*(temp2->pPolygon+size-1))))
2931            /*  edge is still there we are ok */
2932            there = TRUE;
2933        }
2934    }
2935 
2936  if (!there)
2937    /*  Edge already used and deleted from the polygon*/
2938    return -1;
2939  else
2940    return next_face;
2941}
2942
2943///     Look_Up:
2944BOOL CustomStripifier::Look_Up(int id1,int id2,int face_id)
2945{
2946  /*    See if the endpoints of the edge specified by id1 and id2
2947        are adjacent to the face with face_id
2948  */
2949  register int count = 0;
2950  PF_EDGES temp  = NULL;
2951  ListHead *pListHead;
2952 
2953  /*    Always want smaller id first */
2954  switch_lower(&id1,&id2);
2955 
2956  pListHead = PolEdges[id1];
2957  temp = (PF_EDGES) PeekList(pListHead,LISTHEAD,count);
2958  if (temp == NULL)
2959    /*  Was a new edge that we created */
2960    return 0;
2961 
2962  while (temp->edge[0] != id2)
2963    {
2964      count++;
2965      temp = ( PF_EDGES )GetNextNode(temp);                                 
2966     
2967      if (temp == NULL)
2968        /*      Was a new edge that we created */
2969        return 0;
2970    }
2971  /*    Was not adjacent to anything else except itself */
2972  if ((temp->edge[2] == face_id) || (temp->edge[1] == face_id))
2973    {
2974      /*        Edge was adjacent to face, make sure that edge is
2975                still there
2976      */
2977      if (Exist(face_id,id1,id2))
2978        return 1;
2979      else
2980        return 0;
2981    }
2982  else
2983    return 0;
2984}
2985
2986///     Add_Id_Strips:
2987void CustomStripifier::Add_Id_Strips(int id, int where)
2988{
2989  /*    Just save the triangle for later  */
2990  P_STRIPS pfNode;
2991 
2992  pfNode = (P_STRIPS) malloc(sizeof(Strips) );
2993  if ( pfNode )
2994    {
2995      pfNode->face_id = id;
2996      if (where == 1)
2997        AddTail(strips[0],(PLISTINFO) pfNode);
2998      /* We are backtracking in the strip */
2999      else
3000        AddHead(strips[0],(PLISTINFO) pfNode);
3001    }
3002  else
3003    {
3004      printf("There is not enough memory to allocate for the strips\n");
3005      exit(0);
3006    }
3007}
3008
3009///     Num_Adj:
3010int CustomStripifier::Num_Adj(int id1, int id2)
3011{
3012  /*   Given edge whose endpoints are specified by id1 and id2,
3013       determine how many polygons share this edge and return that
3014       number minus one (since we do not want to include the polygon
3015       that the caller has already).
3016  */
3017 
3018  PF_EDGES temp = NULL;
3019  ListHead *pListHead;
3020  register count=-1;
3021 
3022  /*    Always want smaller id first */
3023  switch_lower(&id1,&id2);
3024 
3025  pListHead = PolEdges[id1];
3026  temp = (PF_EDGES) PeekList(pListHead,LISTHEAD,count);
3027  if (temp == NULL)
3028    {
3029      printf("There is an error in the creation of the table \n");
3030      exit(0);
3031    }
3032  while (temp->edge[0] != id2)
3033    {
3034      count++;
3035      temp = ( PF_EDGES )GetNextNode(temp);                                   
3036     
3037      if (temp == NULL)
3038        {
3039          printf("There is an error in the creation of the table\n");
3040          exit(0);
3041        }
3042    }
3043  /*      Was not adjacent to anything else except itself */
3044  if (temp->edge[2] == -1)
3045    return 0;
3046  return 1;
3047}
3048
3049///     Add_Sgi_Adj:
3050void CustomStripifier::Add_Sgi_Adj(int bucket,int face_id)
3051{
3052  /*   This routine will add the face to the proper bucket,
3053       depending on how many faces are adjacent to it (what the
3054       value bucket should be).
3055  */
3056  P_ADJACENCIES pfNode;
3057 
3058  pfNode = (P_ADJACENCIES) malloc(sizeof(ADJACENCIES) );
3059  if ( pfNode )
3060    {
3061      pfNode->face_id = face_id;
3062      AddHead(array[bucket],(PLISTINFO) pfNode);
3063      face_array[face_id].bucket = bucket;
3064      face_array[face_id].pfNode = pfNode;
3065      face_array[face_id].head = array[bucket];
3066    }
3067  else
3068    {
3069      printf("Out of memory for the SGI adj list!\n");
3070      exit(0);
3071    }
3072}
3073
3074///     Find_Adjacencies:
3075void CustomStripifier::Find_Adjacencies(int num_faces)
3076{
3077  register int  x,y;
3078  register int  numverts;
3079  PF_FACES                      temp    =NULL;
3080  ListHead*                     pListHead;
3081 
3082  /*   Fill in the adjacencies data structure for all the faces */
3083  for (x=0;x<num_faces;x++)
3084  {
3085    pListHead = PolFaces[x];
3086    temp = ( PF_FACES ) PeekList( pListHead, LISTHEAD, 0 );
3087    if ( temp != NULL )
3088                {
3089                numverts = temp->nPolSize;
3090                if (numverts != 1)
3091            {
3092              for (y = 0; y< numverts; y++)
3093                                {
3094                                if (y != (numverts-1))
3095                                Add_AdjEdge(*(temp->pPolygon+y),
3096                                                                                                *(temp->pPolygon+y+1),x,y);
3097                 
3098                                else
3099                                Add_AdjEdge(*(temp->pPolygon),
3100                                                                                                *(temp->pPolygon+(numverts-1)),x,numverts-1);
3101                 
3102                                }
3103            }
3104                temp = NULL;
3105                }
3106        }
3107}
3108
3109///     Clear_Ties:
3110void CustomStripifier::Clear_Ties()
3111{
3112  /*    Clear the buffer, because we do not have the tie
3113        any more that we had before */
3114  last = 0;
3115}
3116
3117///     Add_Ties:
3118void CustomStripifier::Add_Ties(int id)
3119{
3120  /*    We have a tie to add to the buffer */
3121  ties_array[last++] = id;
3122}
3123
3124///     Alternate_Tie:
3125int CustomStripifier::Alternate_Tie()
3126{
3127  /*    Alternate in what we choose to break the tie
3128        We are just alternating between the first and
3129        second thing that we found
3130  */
3131  static int x = 0;
3132  register int t;
3133 
3134  t = ties_array[x];
3135  x++;
3136  if (x == 2)
3137    x = 0;
3138  return t;
3139}
3140
3141///     Random_Tie:
3142int CustomStripifier::Random_Tie()
3143{
3144  /*    Randomly choose the next face with which
3145        to break the tie
3146  */
3147  register int num;
3148 
3149  num = rand();
3150  while (num >= last)
3151    num = num/20;
3152  return (ties_array[num]);
3153}
3154
3155///     Look_Ahead:
3156int CustomStripifier::Look_Ahead(int id)
3157{
3158  /*    Look ahead at this face and save the minimum
3159        adjacency of all the faces that are adjacent to
3160        this face.
3161  */
3162  return Min_Adj(id);
3163}
3164
3165///     Random_Look:
3166int CustomStripifier::Random_Look(int id[],int count)
3167{
3168  /*    We had a tie within a tie in the lookahead,
3169        break it randomly
3170  */
3171  register int num;
3172 
3173  num = rand();
3174  while (num >= count)
3175    num = num/20;
3176  return (id[num]);
3177}
3178
3179///     Look_Ahead_Tie:
3180int CustomStripifier::Look_Ahead_Tie()
3181{
3182  /*    Look ahead and find the face to go to that
3183        will give the least number of adjacencies
3184  */
3185  int id[60],t,x,f=0,min = 60;
3186 
3187  for (x = 0; x < last; x++)
3188    {
3189      t = Look_Ahead(ties_array[x]);
3190      /*        We have a tie */
3191      if (t == min)
3192        id[f++] = ties_array[x];
3193      if (t < min)
3194        {
3195          f = 0;
3196          min = t;
3197          id[f++] = ties_array[x];
3198        }
3199    }
3200  /*    No tie within the tie */
3201  if ( f == 1)
3202    return id[0];
3203  /*    Or ties, but we are at the end of strips */
3204  if (min == 0)
3205    return id[0];
3206  return (Random_Look(id,f));
3207}
3208
3209///     Sequential_Tri:
3210int CustomStripifier::Sequential_Tri(int *index)
3211{
3212  /*  We have a triangle and need to break the ties at it.
3213      We will choose the edge that is sequential. There
3214      is definitely one since we know we have a triangle
3215      and that there is a tie and there are only 2 edges
3216      for the tie.
3217  */
3218  int reversed,e1,e2,e3,output1,output2,output3,output4;
3219 
3220  /*  e2 and e3 are the input edge to the triangle */
3221  Last_Edge(&e1,&e2,&e3,0);
3222 
3223  if ((e2 == 0) && (e3 == 0))
3224    /*  Starting the strip, don't need to do this */
3225    return ties_array[0];
3226 
3227  /*  For the 2 ties find the edge adjacent to face id */
3228  reversed = Get_EdgeEx(&output1,&output2,index,ties_array[0],3,0,0);
3229  reversed = Get_EdgeEx(&output3,&output4,index,ties_array[1],3,0,0);
3230 
3231  if ((output1 == e3) || (output2 == e3))
3232    return ties_array[0];
3233  if ((output3 == e3) || (output4 == e3))
3234    return ties_array[1];
3235  printf("There is an error trying to break sequential triangle \n");
3236}
3237
3238///     Sequential_Quad:
3239int CustomStripifier::Sequential_Quad(int *index,       int triangulate)
3240{
3241  /*  We have a quad that need to break its ties, we will try
3242      and choose a side that is sequential, otherwise use lookahead
3243  */
3244  int reversed,output1,output2,x,e1,e2,e3;
3245 
3246  /*  e2 and e3 are the input edge to the quad */
3247  Last_Edge(&e1,&e2,&e3,0);
3248 
3249  /*  No input edge */
3250  if ((e2 == 0) && (e3 == 0))
3251    return ties_array[0];
3252 
3253  /*  Go through the ties and see if there is a sequential one */
3254  for (x = 0; x < last; x++)
3255    {
3256      reversed = Get_EdgeEx(&output1,&output2,index,ties_array[x],4,0,0);
3257      /*  Partial and whole triangulation will have different requirements */
3258      if (((output1 == e3) || (output2 == e3)) && (triangulate == PARTIAL))
3259        return ties_array[x];
3260      if (((output1 != e3) && (output1 != e2) &&
3261           (output2 != e3) && (output2 != e2)))
3262        return ties_array[x];
3263    }
3264  /*  There was not a tie that was sequential */
3265  return Look_Ahead_Tie();
3266}
3267
3268///     Whole_Output:
3269void CustomStripifier::Whole_Output(int in1, int *index, int size, int *out1, int *out2)
3270{
3271  /*  Used to sequentially break ties in the whole triangulation for polygons
3272      greater than 4 sides. We will find the output edge that is good
3273      for sequential triangulation.
3274  */
3275 
3276  int half;
3277 
3278  /*  Put the input edge first in the list */
3279  Rearrange_IndexEx(index,size);
3280 
3281  if (!(EVEN(size)))
3282    {
3283      if (*(index) == in1)
3284        half = size/2 ;
3285      else
3286        half = size/2 +1;
3287    }
3288  else
3289    half = size/2;
3290 
3291  *out1 = *(index+half);
3292  *out2 = *(index+half+1);
3293}
3294
3295///     Sequential_Poly:
3296int CustomStripifier::Sequential_Poly(int size, int *index, int triangulate)
3297{
3298  /*  We have a polygon of greater than 4 sides and wish to break the
3299      tie in the most sequential manner.
3300  */
3301 
3302  int x,reversed,output1,output2,e1,e2,e3,saved1=-1,saved2=-1,output3,output4;
3303 
3304  /*  e2 and e3 are the input edge to the quad */
3305  Last_Edge(&e1,&e2,&e3,0);
3306 
3307  /*  If we are using whole, find the output edge that is sequential */
3308  if (triangulate == WHOLE)
3309    Whole_Output(e2,index,size,&output3,&output4);
3310 
3311  /*  No input edge */
3312  if ((e2 == 0) && (e3 == 0))
3313    return ties_array[0];
3314 
3315  for (x = 0; x < last ; x++)
3316    {
3317      reversed = Get_EdgeEx(&output1,&output2,index,ties_array[x],size,0,0);
3318      /*  Partial that can be removed in just one triangle */
3319      if (((output1 == e3) || (output2 == e3)) && (triangulate == PARTIAL))
3320        saved1 = ties_array[x];
3321      /*  Partial removed in more than one triangle */
3322      if ((output1 != e3) && (output1 != e2) &&
3323          (output2 != e3) && (output2 != e2) &&
3324          (triangulate == PARTIAL) && (saved2 != -1))
3325        saved2 = ties_array[x];
3326      /*  Whole is not so easy, since the whole polygon must be done. Given
3327          an input edge there is only one way to come out, approximately half
3328          way around the polygon.
3329      */
3330      if (((output1 == output3) && (output2 == output4)) ||
3331          ((output1 == output4) && (output2 == output3)) &&
3332          (triangulate == WHOLE))
3333        return ties_array[x];
3334    }
3335 
3336  if (saved1 != -1)
3337    return saved1;
3338  if (saved2 != -1)
3339    return saved2;
3340 
3341  /*  There was not a tie that was sequential */
3342  return Look_Ahead_Tie();
3343}
3344
3345///     Sequential_Tie:
3346int CustomStripifier::Sequential_Tie(int face_id,int triangulate)
3347{
3348  /*  Break the tie by choosing the face that will
3349      not give us a swap and is sequential. If there
3350      is not one, then do the lookahead to break the
3351      tie.
3352  */
3353  /*  Separate into 3 cases for simplicity, if the current
3354      polygon has 3 sides, 4 sides or if the sides were
3355      greater. We can do the smaller cases faster, so that
3356      is why I separated the cases.
3357  */
3358 
3359  ListHead *pListFace;
3360  PF_FACES face;
3361 
3362  /*    Get the polygon with id face_id */
3363  pListFace  = PolFaces[face_id];
3364  face = (PF_FACES) PeekList(pListFace,LISTHEAD,0);
3365 
3366  if (face->nPolSize == 3)
3367    return(Sequential_Tri(face->pPolygon));
3368  if (face->nPolSize == 4)
3369    return(Sequential_Quad(face->pPolygon,triangulate));
3370  else
3371    return(Sequential_Poly(face->nPolSize,face->pPolygon,triangulate));
3372 
3373}
3374
3375///     Get_Next_Face:
3376int CustomStripifier::Get_Next_Face(int t, int face_id, int triangulate)
3377{
3378  /*    Get the next face depending on what
3379        the user specified
3380  */
3381 
3382  /*    Did not have a tie, don't do anything */
3383  if (last == 1)
3384    return(ties_array[0]);
3385  if (t == RANDOM)
3386    return Random_Tie();
3387  if (t == ALTERNA)
3388    return Alternate_Tie();
3389  if (t == LOOK)
3390    return Look_Ahead_Tie();
3391  if (t == SEQUENTIAL)
3392    return Sequential_Tie(face_id,triangulate);
3393 
3394  printf("Illegal option specified for ties, using first \n");
3395  return (ties_array[0]);
3396}
3397
3398///     new_vertex:
3399BOOL CustomStripifier::new_vertex(double difference, int id1,int id2,
3400                       struct vert_struct *n)
3401{
3402  /*   Is the difference between id1 and id2 (2 normal vertices that
3403       mapped to the same vertex) greater than the
3404       threshold that was specified?
3405  */
3406  struct vert_struct *pn1,*pn2;
3407  double dot_product;
3408  double distance1, distance2,distance;
3409  double rad;
3410  char arg1[100];
3411  char arg2[100];
3412 
3413  pn1 = n + id1;
3414  pn2 = n + id2;
3415 
3416  dot_product = ((pn1->x) * (pn2->x)) +
3417    ((pn1->y) * (pn2->y)) +
3418    ((pn1->z) * (pn2->z));
3419  /*   Get the absolute value */
3420  if (dot_product < 0)
3421    dot_product = dot_product * -1;
3422 
3423  distance1 = sqrt( (pn1->x * pn1->x) +
3424                    (pn1->y * pn1->y) +
3425                    (pn1->z * pn1->z) );
3426  distance2 = sqrt( (pn2->x * pn2->x) +
3427                    (pn2->y * pn2->y) +
3428                    (pn2->z * pn2->z) );
3429  distance = distance1 * distance2;
3430 
3431  rad = acos((double)dot_product/(double)distance);
3432  /*   convert to degrees */
3433  rad = (180 * rad)/GEO_PI;
3434 
3435  if ( rad <= difference)
3436    return FALSE;
3437 
3438  /*   double checking because of imprecision with floating
3439       point acos function
3440  */
3441  sprintf( arg1,"%.5f", rad );
3442  sprintf( arg2,"%.5f", difference );
3443  if ( strcmp( arg1, arg2 ) <=0 )
3444    return( FALSE );
3445  if ( rad <= difference)
3446    return FALSE;
3447  else
3448    return TRUE;
3449}
3450
3451///     Check_VN:
3452BOOL CustomStripifier::Check_VN(int vertex,int normal, struct vert_added *added)
3453{
3454  /*   Check to see if we already added this vertex and normal */
3455  register int x,n;
3456 
3457  n = (added+vertex)->num;
3458  for (x = 0; x < n; x++)
3459    {
3460      if (*((added+vertex)->normal+x) == normal)
3461        return TRUE;
3462    }
3463  return FALSE;
3464}
3465
3466///     norm_array:
3467BOOL CustomStripifier::norm_array(int id, int vertex, double normal_difference,
3468                struct vert_struct *n, int num_vert)
3469{
3470  static int last;
3471  static struct vert_added *added;
3472  register int x;
3473  static BOOL first = TRUE;
3474 
3475  if (first)
3476    {
3477      /*   This is the first time that we are in here, so we will allocate
3478           a structure that will save the vertices that we added, so that we
3479           do not add the same thing twice
3480      */
3481      first = FALSE;
3482      added = (struct vert_added *) malloc (sizeof (struct vert_added ) * num_vert);
3483      /*   The number of vertices added for each vertex must be initialized to
3484           zero
3485      */
3486      for (x = 0; x < num_vert; x++)
3487        (added+x)->num = 0;
3488    }
3489 
3490  if (vertex)
3491    /*   Set the pointer to the vertex, we will be calling again with the
3492         normal to fill it with
3493    */
3494    last = id;
3495  else
3496    {   
3497      /*   Fill the pointer with the id of the normal */
3498      if (*(vert_norms + last) == 0)
3499        *(vert_norms + last) = id;
3500      else if ((*(vert_norms + last) != id) && ((int)normal_difference != 360))
3501        {
3502          /*   difference is big enough, we need to create a new vertex */
3503          if (new_vertex(normal_difference,id,*(vert_norms + last),n))
3504            {
3505              /*  First check to see if we added this vertex and normal already */
3506              if (Check_VN(last,id,added))
3507                return FALSE;
3508              /*  OK, create the new vertex, and have its id = the number of
3509                  vertices and its normal what we have here
3510              */
3511              vert_norms = (int *)realloc(vert_norms, sizeof(int) * (num_vert + 1));
3512              if (!vert_norms)
3513                {
3514                  printf("Allocation error - aborting\n");
3515                  exit(1);
3516                }
3517              *(vert_norms + num_vert) = id;
3518              /*   We created a new vertex, now put it in our added structure so
3519                   we do not add the same thing twice
3520              */
3521              (added+last)->num = (added+last)->num + 1;
3522              if ((added+last)->num == 1)
3523                {
3524                  /*   First time */
3525                  (added+last)->normal =  (int *) malloc (sizeof (int ) * 1);
3526                  *((added+last)->normal) =  id;
3527                }
3528              else
3529                {
3530                  /*   Not the first time, reallocate space */
3531                  (added+last)->normal = (int *)realloc((added+last)->normal, sizeof(int) * (added+last)->num);
3532                  *((added+last)->normal+((added+last)->num-1)) = id;
3533                }
3534              return TRUE;
3535            }
3536        }
3537    }
3538  return FALSE;
3539}
3540
3541///     add_texture:
3542void CustomStripifier::add_texture(int id,BOOL vertex)
3543{
3544  /*   Save the texture with its vertex for future use when outputting */
3545  static int last;
3546 
3547  if (vertex)
3548    last = id;
3549  else
3550    *(vert_texture+last) = id;
3551}
3552
3553///     add_vert_id:
3554int     CustomStripifier::add_vert_id(int id, int       index_count)
3555{
3556  register int x;
3557 
3558  //   Test if degenerate, if so do not add degenerate vertex
3559  for (x = 1; x < index_count ; x++)
3560  {
3561        if (ids[x] == id)
3562                return 0;
3563  }
3564  ids[index_count] = id;
3565
3566  return 1;
3567}
3568
3569///     add_norm_id:
3570void CustomStripifier::add_norm_id(int id, int index_count)
3571{
3572  norms[index_count] = id;
3573}
3574
3575///     AddNewFace:
3576void CustomStripifier::AddNewFace(int ids[MAX1], int vert_count, int face_id, int norms[MAX1])
3577{
3578  PF_FACES                      pfNode;
3579  PF_VERTICES           pfVertNode;
3580  int                                           *pTempInt;
3581  int                                           *pnorms;
3582  F_EDGES                               **pTempVertptr;
3583  int                                           *pTempmarked;
3584        int                                             *pTempwalked;
3585  register      int     y;
3586        register        int     count = 0;
3587
3588  //  Add a new face into our face data structure
3589  pfNode = (PF_FACES) malloc(sizeof(F_FACES));
3590
3591  if (pfNode)
3592  {
3593                pfNode->pPolygon        =       (int*) malloc(sizeof(int) * (vert_count) );
3594                pfNode->pNorms          =       (int*) malloc(sizeof(int) * (vert_count) );
3595
3596                pfNode->VertandId       =       (F_EDGES**)malloc(sizeof(F_EDGES*)
3597                                                                                                *
3598                                                                                                (vert_count));
3599
3600                pfNode->marked          =       (int*)malloc(sizeof(int) * (vert_count));
3601                pfNode->walked          =       (int*)malloc(sizeof(int) * (vert_count));
3602  }
3603
3604  pTempInt                                      =       pfNode->pPolygon;
3605  pnorms                                                =       pfNode->pNorms;
3606  pTempmarked                           =       pfNode->marked;
3607  pTempwalked                           =       pfNode->walked;
3608  pTempVertptr                  =       pfNode->VertandId;
3609  pfNode->nPolSize      =       vert_count;
3610  pfNode->nOrgSize      =       vert_count;
3611  pfNode->seen                  =       -1;
3612  pfNode->seen2                 =       -1;
3613
3614  for (y = 1; y <= vert_count; y++)
3615  {
3616                *(pTempInt + count)                     =       ids[y];
3617                *(pnorms + count)                               =       norms[y];
3618                *(pTempmarked + count)  =       FALSE;
3619                *(pTempwalked + count)  =       -1;
3620                *(pTempVertptr+count)           =       NULL;
3621
3622                count++;
3623
3624                /* Add this FaceNode to the Vertices Structure */
3625                pfVertNode                              =       (PF_VERTICES) malloc(sizeof(F_VERTICES));
3626                pfVertNode->face        =       pfNode;
3627
3628                AddHead(Vertices[ids[y]],(PLISTINFO) pfVertNode);
3629  }
3630
3631  AddHead(PolFaces[face_id-1],(PLISTINFO) pfNode);
3632 
3633}
3634
3635///     CopyFace:
3636void CustomStripifier::CopyFace(int ids[MAX1], int vert_count, int face_id, int norms[MAX1])
3637{
3638  PF_FACES                      pfNode;
3639  int                                           *pTempInt;
3640  int                                           *pnorms;
3641  F_EDGES                               **pTempVertptr;
3642  int                                           *pTempmarked;
3643        int                                             *pTempwalked;
3644  register      int     y;
3645        register        int     count = 0;
3646 
3647  /*   Copy a face node into a new node, used after the global algorithm
3648       is run, so that we can save whatever is left into a new structure
3649  */
3650 
3651  pfNode        =       (PF_FACES) malloc(sizeof(F_FACES));
3652
3653  if ( pfNode )
3654  {
3655      pfNode->pPolygon  =       (int*) malloc(  sizeof(int)
3656                                                                                                                                                                        *
3657                                                                                                                                                                        (vert_count));
3658
3659      pfNode->pNorms            =       (int*) malloc(  sizeof(int)
3660                                                                                                                                                                        *
3661                                                                                                                                                                        (vert_count));
3662
3663      pfNode->VertandId =       (F_EDGES**) malloc(     sizeof(F_EDGES*)
3664                                                                                                                                                                                        *
3665                                                                                                                                                                                        (vert_count));
3666
3667      pfNode->marked    =       (int*)malloc(sizeof(int) * (vert_count));
3668      pfNode->walked    =       (int*)malloc(sizeof(int) * (vert_count));
3669  }
3670
3671  pTempInt                                      =       pfNode->pPolygon;
3672  pnorms                                                =       pfNode->pNorms;
3673  pTempmarked                           =       pfNode->marked;
3674  pTempwalked                           =       pfNode->walked;
3675  pTempVertptr                  =       pfNode->VertandId;
3676  pfNode->nPolSize      =       vert_count;
3677  pfNode->nOrgSize      =       vert_count;
3678  pfNode->seen                  =       -1;
3679  pfNode->seen2                 =       -1;
3680
3681  for (y = 0; y < vert_count; y++)
3682  {
3683                *(pTempInt + count)                     =       ids[y];
3684                *(pnorms + count)                               =       norms[y];
3685                *(pTempmarked + count)  =       FALSE;
3686                *(pTempwalked + count)  =       -1;
3687                *(pTempVertptr+count)           =       NULL;
3688
3689                count++;
3690  }
3691
3692  AddHead(PolFaces[face_id-1],(PLISTINFO) pfNode);
3693}
3694
3695///     Add_AdjEdge:
3696void CustomStripifier::Add_AdjEdge(int v1,int v2,int fnum,int index1 )
3697{
3698  PF_EDGES                      temp    =       NULL;
3699  PF_FACES                      temp2 = NULL;
3700  PF_EDGES                      pfNode;
3701  ListHead                      *pListHead;
3702  ListHead                      *pListFace;
3703  BOOL                                  flag    =       TRUE;
3704  register      int     count = 0;
3705  register      int     t;
3706        register        int     v3              =       -1;
3707 
3708  if (v1 > v2)
3709  {
3710                t               =       v1;
3711                v1      =       v2;
3712                v2      =       t;
3713  }
3714
3715  pListFace     =       PolFaces[fnum];
3716  temp2                 =       (PF_FACES) PeekList(pListFace,LISTHEAD,0);
3717  pListHead     =       PolEdges[v1];
3718  temp                  =       (PF_EDGES) PeekList(pListHead,LISTHEAD,count);
3719
3720  if (temp == NULL)
3721        {
3722                flag    =       FALSE;
3723        }
3724
3725  count++;
3726
3727  while (flag)
3728  {
3729                if (v2 == temp->edge[0])
3730                {
3731                        /*      If greater than 2 polygons adjacent to an edge,
3732                                        then we will only save the first 2 that we found.
3733                                        We will have a small performance hit,
3734                                        but this does not happen often.
3735                        */
3736                        if (temp->edge[2] == -1)
3737                        {
3738                                temp->edge[2]   =       fnum;
3739                        }
3740                        else
3741                        {
3742                                v3      =       temp->edge[2];
3743
3744                                //      More than 3 edges are adjacent.
3745                                //      The mesh is not Manifold.
3746                                mError  =       1;
3747                        }
3748
3749                        flag    =       FALSE;
3750                }
3751                else
3752                {
3753                        temp    =       ( PF_EDGES ) GetNextNode(temp);
3754
3755                        count++;
3756
3757                        if (temp == NULL)
3758                        {
3759                                flag    =       FALSE;
3760                        }
3761                }
3762        }
3763 
3764  /*   Did not find it */
3765  if (temp == NULL)
3766  {
3767    pfNode      =       (PF_EDGES) malloc(sizeof(F_EDGES));
3768
3769    if (pfNode)
3770                {
3771                        pfNode->edge[0] =       v2;
3772                        pfNode->edge[1] =       fnum;
3773                        pfNode->edge[2] =       v3;
3774
3775                        AddTail(PolEdges[v1], (PLISTINFO) pfNode);
3776                }
3777                else
3778                {
3779                        printf("Out of memory!\n");
3780                        exit(1);
3781                }
3782
3783                *(temp2->VertandId+index1)      =       pfNode;
3784        }
3785  else
3786        {
3787                *(temp2->VertandId+index1)      =       temp;
3788        }
3789}
3790
3791///     power_10:
3792int CustomStripifier::power_10(int power)
3793{
3794  /*    Raise 10 to the power */
3795  register int i,p;
3796 
3797  p = 1;
3798  for (i = 1; i <= power; ++i)
3799    p = p * 10;
3800  return p;
3801}
3802
3803///     power_negative:
3804float CustomStripifier::power_negative(int power)
3805{
3806  /*   Raise 10 to the negative power */
3807 
3808  register int i;
3809  float p;
3810 
3811  p = (float)1;
3812  for (i = 1; i<=power; i++)
3813    p = p * (float).1;
3814  return p;
3815}
3816
3817///     convert_array:
3818float CustomStripifier::convert_array(int num[],int stack_size)
3819{
3820  /* Convert an array of characters to an integer */
3821 
3822  register int counter,c;
3823  float temp =(float)0.0;
3824 
3825  for (c=(stack_size-1), counter = 0; c>=0; c--, counter++)
3826    {
3827      if (num[c] == -1)
3828        /*   We are at the decimal point, convert to decimal
3829             less than 1
3830        */
3831        {
3832          counter = -1;
3833          temp = power_negative(stack_size - c - 1) * temp;
3834        }
3835      else
3836        temp += power_10(counter) * num[c];
3837    }
3838 
3839  return(temp);
3840}
3841
3842///     print_usage:
3843void CustomStripifier::print_usage(void)
3844{
3845  printf("Usage: stripe [abfglopqrw] file_name\n");
3846  printf("Options:\n");
3847  printf(" -b\tSpecifies that the input file is in binary\n");
3848  printf(" -g\tFind triangle strips only within the groups specified in the data file\n");
3849  printf(" -o\tTurn off orientation checking\n\n");
3850 
3851  printf("Tie Breaking:\n");
3852  printf(" -a\tAlternate left-right direction in choosing next polygon\n");
3853  printf(" -f\tChoose the first polygon that it found\n");
3854  printf(" -l\tLook ahead one level in choosing the next polygon\n");
3855  printf(" -q\tChoose the polygon which does not produce a swap\n");
3856  printf(" -r\tRandomly choose the next polygon\n\n");
3857 
3858  printf("Triangulation:\n");
3859  printf(" -p\tPartially triangulate faces\n");
3860  printf(" -w\tFully triangluate faces\n");
3861}
3862
3863///     get_options:
3864float CustomStripifier::get_options(int         argc,
3865                                                                                                                                                char    **argv,
3866                                                                                                                                                int             *f,
3867                                                                                                                                                int             *t,
3868                                                                                                                                                int             *tr,
3869                                                                                                                                                int             *group,
3870                                                                                                                                                int             *orientation)
3871{
3872  char c;
3873  int count = 0;
3874  int buffer[MAX1];
3875  int next = 0;
3876  /*    tie variable */
3877  enum tie_options tie = FIRST;
3878  /*   triangulation variable */
3879  enum triangulation_options triangulate = WHOLE;
3880  /*   normal difference variable (in degrees) */
3881  float norm_difference = (float)360.0;
3882  /*   file-type variable */
3883  enum file_options file_type = ASCII;
3884 
3885  *orientation = 1;
3886 
3887  /*      User has the wrong number of options */
3888  if ((argc > 6) || (argc < 2))
3889  {
3890    print_usage();
3891    exit(0);
3892  }
3893 
3894  /* Interpret the options specified */
3895  while (--argc > 0 && (*++argv)[0] == '-')
3896  {
3897    /*   At the next option that was specified */
3898    next = 1;
3899    while ((c = *++argv[0]))
3900                        switch (c)
3901                        {
3902                                case 'f':
3903                                        /*      Use the first polygon we see. */
3904                                        tie = FIRST;
3905                                        break;
3906                           
3907                                case 'r':
3908                                        /*      Randomly choose the next polygon */
3909                                        tie = RANDOM;
3910                                        break;
3911                           
3912                                case 'a':
3913                                        /*      Alternate direction in choosing the next polygon */
3914                                        tie = ALTERNA;
3915                                        break;
3916                           
3917                                case 'l':
3918                                        /*      Use lookahead to choose the next polygon */
3919                                        tie = LOOK;
3920                                        break;
3921                           
3922                                case 'q':
3923                                        /*  Try to reduce swaps */
3924                                        tie = SEQUENTIAL;
3925                                        break;
3926                           
3927                                case 'p':
3928                                        /*      Use partial triangulation of polygons */
3929                                        triangulate = PARTIAL;
3930                                        break;
3931                           
3932                                case 'w':
3933                                        /*      Use whole triangulation of polygons */
3934                                        triangulate = WHOLE;
3935                                        break;
3936                           
3937                                case 'b':
3938                                        /*      Input file is in binary */
3939                                        file_type = BINARY;
3940                                        break;
3941                           
3942                                case 'g':
3943                                        /*   Strips will be grouped according to the groups in
3944                                the data file. We will have to restrict strips to be
3945                                in the grouping of the data file.
3946                                        */
3947                                        *group = 1;
3948                                        break;
3949                           
3950                                                        case 'o':
3951                                        *orientation = 0;
3952                           
3953                                        /*      Get each the value of the integer */
3954                                        /*      We have an integer */
3955                                default:
3956                                        if ((c >= '0') && (c <= '9'))
3957                                                {
3958                                /* More than one normal difference specified, use the last one */
3959                                if (next == 1)
3960                                        {
3961                                                count = 0;
3962                                                next = 0;
3963                                        }
3964                                buffer[count++] = ATOI(c);
3965                                                }
3966                                        /*   At the decimal point */
3967                                        else if (c == '.')
3968                                                {
3969                                /* More than one normal difference specified, use the last one */
3970                                if (next == 1)
3971                                        {
3972                                                count = 0;
3973                                                next = 0;
3974                                        }
3975                                buffer[count++] = -1;
3976                                                }
3977                                        else
3978                                                break;
3979                        }
3980    }
3981  /*   Convert the buffer of characters to a floating pt integer */
3982  if (count != 0)
3983    norm_difference = convert_array(buffer,count);
3984  *f = file_type;
3985  *t = tie;
3986  *tr = triangulate;
3987  return norm_difference;
3988}
3989
3990///     AdjacentEx:
3991int CustomStripifier::AdjacentEx(int id2,int id1, int *list, int size)
3992{
3993  /*    Return the vertex that is adjacent to id1,
3994        but is not id2, in the list of integers.
3995  */
3996 
3997  register int x=0;
3998 
3999  while (x < size)
4000    {
4001      if (*(list+x) == id1)
4002        {
4003          if ((x != (size -1)) && (x != 0))
4004            {
4005              if ( *(list+x+1) != id2)
4006                return *(list+x+1);
4007              else
4008                return *(list+x-1);
4009            }
4010          else if (x == (size -1))
4011            {
4012              if (*(list) != id2)
4013                return *(list);
4014              else
4015                return *(list+x-1);
4016            }
4017          else
4018            {
4019              if (*(list+size-1) != id2)
4020                return *(list+size-1);
4021              else
4022                return *(list+x+1);
4023            }
4024        }
4025      x++;
4026    }
4027  printf("Error in the list\n");
4028  exit(0);
4029}
4030
4031///     Delete_From_ListEx:
4032void CustomStripifier::Delete_From_ListEx(int id,int *list, int size)
4033{
4034  /*    Delete the occurence of id in the list.
4035        (list has size size)
4036  */
4037 
4038  int *temp;
4039  register int x,y=0;
4040 
4041  temp = (int *) malloc(sizeof(int) * size);
4042  for (x=0; x<size; x++)
4043    {
4044      if (*(list+x) != id)
4045        {
4046          *(temp+y) = *(list+x);
4047          y++;
4048        }
4049    }
4050  if(y != (size-1))
4051    {
4052      printf("There is an error in the delete\n");
4053      exit(0);
4054    }
4055  *(temp+size-1) = -1;
4056  memcpy(list,temp,sizeof(int)*size);
4057 
4058}
4059
4060///     Triangulate_QuadEx:
4061void CustomStripifier::Triangulate_QuadEx(int out_edge1,int out_edge2,int in_edge1,
4062                               int in_edge2,int size,int *index,
4063                               int reversed,
4064                               int where)
4065{
4066  int vertex4,vertex5;
4067 
4068  /*    This routine will nonblindly triangulate a quad, meaning
4069        that there is a definite input and a definite output
4070        edge that we must adhere to. Reversed will tell the orientation
4071        of the input edge. (Reversed is -1 is we do not have an input
4072        edge, in other words we are at the beginning of a strip.)
4073        Out_edge* is the output edge, and in_edge* is the input edge.
4074        Index are the edges of the polygon
4075        and size is the size of the polygon. Begin is whether we are
4076        at the start of a new strip.
4077  */
4078 
4079  /*    If we do not have an input edge, then we can make our input
4080        edge whatever we like, therefore it will be easier to come
4081        out on the output edge.
4082  */
4083  if (reversed == -1)
4084    {
4085      vertex4 = AdjacentEx(out_edge1,out_edge2,index,size);
4086      vertex5 = Get_Other_Vertex(vertex4,out_edge1,out_edge2,index);
4087      Output_TriEx(vertex5,vertex4,out_edge1,NULL,-1,where);
4088      Output_TriEx(vertex4,out_edge1,out_edge2,NULL,-1,where);
4089      return;
4090    }
4091 
4092  /*    These are the 5 cases that we can have for the output edge */
4093 
4094  /*   Are they consecutive so that we form a triangle to
4095       peel off, but cannot use the whole quad?
4096  */
4097 
4098  if (in_edge2 == out_edge1)
4099    {
4100      /*        Output the triangle that comes out the correct
4101                edge last. First output the triangle that comes out
4102                the wrong edge.
4103      */
4104      vertex4 = Get_Other_Vertex(in_edge1,in_edge2,out_edge2,index);
4105      Output_TriEx(in_edge1,in_edge2,vertex4,NULL,-1,where);
4106      Output_TriEx(vertex4,in_edge2,out_edge2,NULL,-1,where);
4107      return;
4108    }
4109  /*    The next case is where it is impossible to come out the
4110        edge that we want. So we will have to start a new strip to
4111        come out on that edge. We will output the one triangle
4112        that we can, and then start the new strip with the triangle
4113        that comes out on the edge that we want to come out on.
4114  */
4115  else if (in_edge1 == out_edge1)
4116    {
4117      /*        We want to output the first triangle (whose output
4118                edge is not the one that we want.
4119                We have to find the vertex that we need, which is
4120                the other vertex which we do not have.
4121      */
4122      vertex4 = Get_Other_Vertex(in_edge2,in_edge1,out_edge2,index);
4123      Output_TriEx(in_edge2,in_edge1,vertex4,NULL,-1,where);
4124      Output_TriEx(vertex4,in_edge1,out_edge2,NULL,-1,where);
4125      return;
4126    }
4127 
4128  /*    Consecutive cases again, but with the output edge reversed */
4129  else if (in_edge1 == out_edge2)
4130    {
4131      vertex4 = Get_Other_Vertex(in_edge1,in_edge2,out_edge1,index);
4132      Output_TriEx(in_edge2,in_edge1,vertex4,NULL,-1,where);
4133      Output_TriEx(vertex4,in_edge1,out_edge1,NULL,-1,where);
4134      return;
4135    }
4136  else if (in_edge2 == out_edge2)
4137    {
4138      vertex4 = Get_Other_Vertex(in_edge1,in_edge2,out_edge1,index);
4139      Output_TriEx(in_edge1,in_edge2,vertex4,NULL,-1,where);
4140      Output_TriEx(vertex4,in_edge2,out_edge1,NULL,-1,where);
4141      return;
4142    }
4143 
4144  /*    The final case is where we want to come out the opposite edge.*/
4145  else
4146    {
4147      if( ((!reversed) &&
4148           (out_edge1 == (AdjacentEx(in_edge1,in_edge2,index,size)))) ||
4149          ((reversed) &&
4150           (out_edge2 == (AdjacentEx(in_edge2,in_edge1,index,size)))))
4151        {
4152          /*    We need to know the orientation of the input
4153                edge, so we know which way to put the diagonal.
4154                And also the output edge, so that we triangulate correctly.
4155          */
4156          Output_TriEx(in_edge1,in_edge2,out_edge2,NULL,-1,where);
4157          Output_TriEx(in_edge2,out_edge2,out_edge1,NULL,-1,where);
4158        }
4159      else
4160        {
4161          /*   Input and output orientation was reversed, so diagonal will
4162               be reversed from above.
4163          */
4164          Output_TriEx(in_edge1,in_edge2,out_edge1,NULL,-1,where);
4165          Output_TriEx(in_edge2,out_edge1,out_edge2,NULL,-1,where);
4166        }
4167      return;
4168    }
4169}
4170
4171///     Triangulate_PolygonEx:
4172void CustomStripifier::Triangulate_PolygonEx(   int out_edge1,int out_edge2,
4173                                                                                                                                                                                        int in_edge1, int in_edge2,
4174                                                                                                                                                                                        int size,                       int *index,
4175                                                                                                                                                                                FILE *fp,                       int reversed,
4176                                                                                                                                                                                        int face_id,  int where)
4177{
4178  /*    We have a polygon that we need to nonblindly triangulate.
4179        We will recursively try to triangulate it, until we are left
4180        with a polygon of size 4, which can use the quad routine
4181        from above. We will be taking off a triangle at a time
4182        and outputting it. We will have 3 cases similar to the
4183        cases for the quad above. The inputs to this routine
4184        are the same as for the quad routine.
4185  */
4186 
4187  int vertex4;
4188  int *temp;
4189 
4190 
4191  /*    Since we are calling this recursively, we have to check whether
4192        we are down to the case of the quad.
4193  */
4194 
4195  if (size == 4)
4196    {
4197      Triangulate_QuadEx(out_edge1,out_edge2,in_edge1,in_edge2,size,
4198                         index,reversed,where);
4199      return;
4200    }
4201 
4202 
4203 
4204  /*    We do not have a specified input edge, and therefore we
4205        can make it anything we like, as long as we still come out
4206        the output edge that we want.
4207  */
4208  if (reversed  == -1)
4209    {
4210      /*        Get the vertex for the last triangle, which is
4211                the one coming out the output edge, before we do
4212                any deletions to the list. We will be doing this
4213                bottom up.
4214      */
4215      vertex4 = AdjacentEx(out_edge1,out_edge2,index,size);
4216      temp = (int *) malloc(sizeof(int) * size);
4217      memcpy(temp,index,sizeof(int)*size);
4218      Delete_From_ListEx(out_edge2,index,size);
4219      Triangulate_PolygonEx(out_edge1,vertex4,in_edge2,
4220                            vertex4,size-1,index,
4221                            fp,reversed,face_id,where);
4222      memcpy(index,temp,sizeof(int)*size);
4223      /*        Lastly do the triangle that comes out the output
4224                edge.
4225      */
4226      Output_TriEx(vertex4,out_edge1,out_edge2,NULL,-1,where);
4227      return;
4228    }
4229 
4230  /*    These are the 5 cases that we can have for the output edge */
4231 
4232  /*  Are they consecutive so that we form a triangle to
4233      peel off that comes out the correct output edge,
4234      but we cannot use the whole polygon?
4235  */
4236  if (in_edge2 == out_edge1)
4237    {
4238      /*        Output the triangle that comes out the correct
4239                edge last. First recursively do the rest of the
4240                polygon.
4241      */
4242      /*        Do the rest of the polygon without the triangle.
4243                We will be doing a fan triangulation.
4244      */
4245      /*        Get the vertex adjacent to in_edge1, but is not
4246                in_edge2.
4247      */
4248      vertex4 = AdjacentEx(in_edge2,in_edge1,index,size);
4249      Output_TriEx(in_edge1,in_edge2,vertex4,NULL,-1,where);
4250      /*        Create a new edgelist without the triangle that
4251                was just outputted.
4252      */
4253      temp = (int *) malloc(sizeof(int) * size);
4254      memcpy(temp,index,sizeof(int)*size);
4255      Delete_From_ListEx(in_edge1,index,size);
4256      Triangulate_PolygonEx(out_edge1,out_edge2,in_edge2,
4257                            vertex4,size-1,index,fp,
4258                            !reversed,face_id,where);
4259      memcpy(index,temp,sizeof(int)*size);
4260      return;
4261    }
4262 
4263  /*    Next case is where it is again consecutive, but the triangle
4264        formed by the consecutive edges do not come out of the
4265        correct output edge. For this case, we can not do much to
4266        keep it sequential. Try and do the fan.
4267  */
4268  else if (in_edge1 == out_edge1)
4269    {
4270      /*        Get vertex adjacent to in_edge2, but is not in_edge1 */
4271      vertex4 = AdjacentEx(in_edge1,in_edge2,index,size);
4272      Output_TriEx(in_edge1,in_edge2,vertex4,fp,-1,where);
4273      /*        Since that triangle goes out of the polygon (the
4274                output edge of it), we can make our new input edge
4275                anything we like, so we will try to make it good for
4276                the strip. (This will be like starting a new strip,
4277                all so that we can go out the correct output edge.)
4278      */
4279      temp = (int *) malloc(sizeof(int) * size);
4280      memcpy(temp,index,sizeof(int)*size);
4281      Delete_From_ListEx(in_edge2,index,size);
4282      Triangulate_PolygonEx(out_edge1,out_edge2,in_edge1,
4283                            vertex4,size-1,index,fp,
4284                            reversed,face_id,where);
4285      memcpy(index,temp,sizeof(int)*size);
4286      return;
4287    }
4288  /*    Consecutive cases again, but with the output edge reversed */
4289  else if (in_edge1 == out_edge2)
4290    {
4291      /*        Get vertex adjacent to in_edge2, but is not in_edge1 */
4292      vertex4 = AdjacentEx(in_edge1,in_edge2,index,size);
4293      Output_TriEx(in_edge2,in_edge1,vertex4,fp,-1,where);
4294      temp = (int *) malloc(sizeof(int) * size);
4295      memcpy(temp,index,sizeof(int)*size);
4296      Delete_From_ListEx(in_edge2,index,size);
4297      Triangulate_PolygonEx(out_edge1,out_edge2,in_edge1,
4298                            vertex4,size-1,index,fp,
4299                            reversed,face_id,where);
4300      memcpy(index,temp,sizeof(int)*size);
4301      return;
4302    }
4303  else if (in_edge2 == out_edge2)
4304    {
4305      /*        Get vertex adjacent to in_edge2, but is not in_edge1 */
4306      vertex4 = AdjacentEx(in_edge2,in_edge1,index,size);
4307      Output_TriEx(in_edge1,in_edge2,vertex4,fp,-1,where);
4308      temp = (int *) malloc(sizeof(int) * size);
4309      memcpy(temp,index,sizeof(int)*size);
4310      Delete_From_ListEx(in_edge1,index,size);
4311      Triangulate_PolygonEx(out_edge1,out_edge2,vertex4,
4312                            in_edge2,size-1,index,fp,
4313                            reversed,face_id,where);
4314      memcpy(index,temp,sizeof(int)*size);
4315      return;
4316    }
4317 
4318  /*    Else the edge is not consecutive, and it is sufficiently
4319        far away, for us not to make a conclusion at this time.
4320        So we can take off a triangle and recursively call this
4321        function.
4322  */
4323  else
4324    {
4325      vertex4 = AdjacentEx(in_edge2,in_edge1,index,size);
4326      Output_TriEx(in_edge1,in_edge2,vertex4,fp,-1,where);
4327      temp = (int *) malloc(sizeof(int) * size);
4328      memcpy(temp,index,sizeof(int)*size);
4329      Delete_From_ListEx(in_edge1,index,size);
4330      Triangulate_PolygonEx(out_edge1,out_edge2,in_edge2,
4331                            vertex4,size-1,index,fp,
4332                            !reversed,face_id,where);
4333      memcpy(index,temp,sizeof(int)*size);
4334      return;
4335    }
4336}
4337
4338///     TriangulateEx:
4339void CustomStripifier::TriangulateEx(int out_edge1,int out_edge2,int in_edge1,
4340                          int in_edge2,int size,int *index,
4341                          FILE *output,int reversed,int face_id, int where)
4342{
4343  /*    We have the info we need to triangulate a polygon */
4344 
4345  if (size == 4)
4346    Triangulate_QuadEx(out_edge1,out_edge2,in_edge1,in_edge2,size,
4347                       index,reversed,where);
4348  else
4349    Triangulate_PolygonEx(out_edge1,out_edge2,in_edge1,in_edge2,size,
4350                          index,output,reversed,face_id,where);
4351}
4352
4353///     Non_Blind_TriangulateEx:
4354void CustomStripifier::Non_Blind_TriangulateEx(int size,int *index,
4355                             FILE *output,int next_face_id,int face_id,int where)
4356{
4357  int id1,id2,id3;
4358  int nedge1,nedge2;
4359  int reversed;
4360  /*    We have a polygon that has to be triangulated and we cannot
4361        do it blindly, ie we will try to come out on the edge that
4362        has the least number of adjacencies
4363  */
4364 
4365  Last_Edge(&id1,&id2,&id3,0);
4366  /*    Find the edge that is adjacent to the new face ,
4367        also return whether the orientation is reversed in the
4368        face of the input edge, which is id2 and id3.
4369  */
4370  if (next_face_id == -1)
4371    {
4372      printf("The face is -1 and the size is %d\n",size);
4373      exit(0);
4374    }
4375 
4376  reversed = Get_EdgeEx(&nedge1,&nedge2,index,next_face_id,size,id2,id3);
4377  /*    Do the triangulation */
4378 
4379  /*    If reversed is -1, the input edge is not in the polygon,
4380        therefore we can have the input edge to be anything we like,
4381        since we are at the beginning of a strip
4382  */
4383  TriangulateEx(nedge1,nedge2,id2,id3,size,index,output,reversed,
4384                face_id, where);
4385}
4386
4387///     Rearrange_IndexEx:
4388void CustomStripifier::Rearrange_IndexEx(int *index, int size)
4389{
4390  /*    If we are in the middle of a strip we must find the
4391        edge to start on, which is the last edge that we had
4392        transmitted.
4393  */
4394  int x,f,y,e1,e2,e3;
4395  int increment = 1;
4396  int *temp;
4397 
4398  /*    Find where the input edge is in the input list */
4399  Last_Edge(&e1,&e2,&e3,0);
4400  for (y = 0; y < size; y++)
4401    {
4402      if (*(index+y) == e2)
4403        {
4404          if ((y != (size - 1)) && (*(index+y+1) == e3))
4405            break;
4406          else if ((y == (size - 1)) && (*(index) == e3))
4407            break;
4408          else if ((y != 0) && (*(index+y-1) == e3))
4409            {
4410              increment = -1;
4411              break;
4412            }
4413          else if ((y==0) && (*(index+size-1) == e3))
4414            {
4415              increment = -1;
4416              break;
4417            }
4418        }
4419      if (*(index+y) == e3)
4420        {
4421          if ((y != (size - 1)) && (*(index+y+1) == e2))
4422            break;
4423          else if ((y == (size - 1)) && (*(index) == e2))
4424            break;
4425          else if ((y != 0) && (*(index+y-1) == e2))
4426            {
4427              increment = -1;
4428              break;
4429            }
4430          else if ((y==0) && (*(index+size-1) == e2))
4431            {
4432              increment = -1;
4433              break;
4434            }
4435        }
4436      /*        Edge is not here, we are at the beginning */
4437      if ((y == (size-1)) && (increment != -1))
4438        return;
4439    }
4440 
4441  /*    Now put the list into a new list, starting with the
4442        input edge. Increment tells us whether we have to go
4443        forward or backward.
4444  */
4445  /*    Was in good position already */
4446  if ((y == 0) && (increment == 1))
4447    return;
4448 
4449 
4450  temp = (int *) malloc(sizeof(int) * size);
4451  memcpy(temp,index,sizeof(int)*size);
4452 
4453  if (increment == 1)
4454    {
4455      x=0;
4456      for (f = y ; f< size; f++)
4457        {
4458          *(index+x) = *(temp+f);
4459          x++;
4460        }
4461      /*        Finish the rest of the list */ 
4462      for(f = 0; f < y ; f++)
4463        {
4464          *(index+x) = *(temp+f);
4465          x++;
4466        }
4467    }
4468  else
4469    {
4470      x=0;
4471      for (f = y ; f >= 0; f--)
4472        {
4473          *(index+x) = *(temp+f);
4474          x++;
4475        }
4476      /*        Finish the rest of the list */ 
4477      for(f = (size - 1); f > y ; f--)
4478        {
4479          *(index+x) = *(temp+f);
4480          x++;
4481        }
4482    }
4483}
4484
4485///     Blind_TriangulateEx:
4486void CustomStripifier::Blind_TriangulateEx(int size, int *index,
4487                         BOOL begin, int where )
4488{
4489  /*    save sides in temp array, we need it so we know
4490        about swaps.
4491  */
4492  int mode, decreasing,increasing,e1,e2,e3;
4493 
4494  /*    Rearrange the index list so that the input edge is first
4495   */
4496  if (!begin)
4497    Rearrange_IndexEx(index,size);
4498 
4499  /*    We are given a polygon of more than 3 sides
4500        and want to triangulate it. We will output the
4501        triangles to the output file.
4502  */
4503 
4504  /*    Find where the input edge is in the input list */
4505  Last_Edge(&e1,&e2,&e3,0);
4506  if (( (!begin) && (*(index) == e2) ) || (begin))
4507    {
4508      Output_TriEx(*(index+0),*(index+1),*(index+size-1),NULL,-1,where);
4509      /*        If we have a quad, (chances are yes), then we know that
4510                we can just add one diagonal and be done. (divide the
4511                quad into 2 triangles.
4512      */
4513      if (size == 4)
4514        {
4515          Output_TriEx(*(index+1),*(index+size-1),*(index+2),NULL,-1,where);
4516          return;
4517        }
4518      increasing = 1;
4519      mode = 1;
4520     
4521    }
4522  else if (!begin)
4523    {
4524      Output_TriEx(*(index+1),*(index+0),*(index+size-1),NULL,-1,where);
4525      if (size == 4)
4526        {
4527          Output_TriEx(*(index+0),*(index+size-1),*(index+2),NULL,-1,where);
4528          return;
4529        }
4530      Output_TriEx(*(index+0),*(index+size-1),*(index+2),NULL,-1,where);
4531      increasing = 2;
4532      mode = 0;
4533    }
4534  if (size != 4)
4535    {
4536      /*        We do not have a quad, we have something bigger. */
4537      decreasing = size - 1;
4538     
4539      do
4540        {
4541          /*    Will be alternating diagonals, so we will be increasing
4542                and decreasing around the polygon.
4543          */
4544          if (mode)
4545            {
4546              Output_TriEx(*(index+increasing),*(index+decreasing),
4547                           *(index+increasing+1),NULL,-1,where);
4548              increasing++;
4549            }
4550          else
4551            {
4552              Output_TriEx(*(index+decreasing),*(index+increasing),
4553                           *(index+decreasing-1),NULL,-1,where);
4554              decreasing--;
4555            }
4556          mode = !mode;
4557        } while ((decreasing - increasing) >= 2);
4558     
4559    }
4560}
4561
4562///     Get_EdgeEx:
4563int CustomStripifier::Get_EdgeEx(int *edge1,int *edge2,int *index,int face_id,
4564               int size, int id1, int id2)
4565{
4566  /*    Put the edge that is adjacent to face_id into edge1
4567        and edge2. For each edge see if it is adjacent to
4568        face_id. Id1 and id2 is the input edge, so see if
4569        the orientation is reversed, and save it in reversed.
4570  */
4571  int x;
4572  int reversed = -1;
4573  BOOL set = FALSE;
4574 
4575  for (x=0; x< size; x++)
4576    {
4577      if (x == (size-1))
4578        {
4579          if ((*(index) == id1) && (*(index+size-1)==id2))
4580            {
4581              if (set)
4582                return 1;
4583              reversed = 1;
4584            }
4585          else if ((*(index) == id2) && (*(index+size-1)==id1))
4586            {
4587              if (set)
4588                return 0;
4589              reversed = 0;
4590            }
4591         
4592          if (Look_Up(*(index),*(index+size-1),face_id))
4593            {
4594              if ( (out1Ex != -1) &&
4595                   ( (out1Ex == *(index)) || (out1Ex == *(index+size-1)) ) &&
4596                   ( (out2Ex == *(index)) || (out2Ex == *(index+size-1)) ))
4597                {
4598                  set = TRUE;
4599                  *edge1 = *(index);
4600                  *edge2 = *(index+size-1);
4601                }
4602              else if (out1Ex == -1)
4603                {
4604                  set = TRUE;
4605                  *edge1 = *(index);
4606                  *edge2 = *(index+size-1);
4607                }
4608              if ((reversed != -1) && (set)) 
4609                return reversed;
4610            }
4611        }               
4612      else
4613        {
4614          if ((*(index+x) == id1) && (*(index+x+1)==id2))
4615            {
4616              if (set)
4617                return 0;
4618              reversed = 0;
4619            }
4620          else if ((*(index+x) == id2) && (*(index+x+1)==id1))
4621            {
4622              if (set)
4623                return 1;
4624              reversed = 1;
4625            }
4626         
4627          if (Look_Up(*(index+x),*(index+x+1),face_id))
4628            {
4629              if ( (out1Ex != -1) &&
4630                   ( (out1Ex == *(index+x)) || (out1Ex == *(index+x+1)) ) &&
4631                   ((out2Ex == *(index+x)) || (out2Ex == *(index+x+1))))
4632                {
4633                  set = TRUE;
4634                  *edge1 = *(index+x);
4635                  *edge2 = *(index+x+1);
4636                }
4637              else if (out1Ex == -1)
4638                {
4639                  set = TRUE;
4640                  *edge1 = *(index+x);
4641                  *edge2 = *(index+x + 1);
4642                }
4643              if ((reversed != -1) && (set))
4644                return reversed;
4645            }
4646        }
4647    }                   
4648  if ((x == size) && (reversed != -1))
4649    {
4650      /*        Could not find the output edge */
4651      printf("Error in the Lookup %d %d %d %d %d %d %d %d\n",
4652             face_id,id1,id2,reversed,*edge1,*edge2,out1Ex,out2Ex);
4653      exit(0);
4654    }
4655  return reversed;
4656}
4657
4658///     Update_FaceEx:
4659void CustomStripifier::Update_FaceEx(   int *next_bucket,int *min_face,
4660                                                                                                                                                        int face_id, int *e1,
4661                                                                                                                                                int *e2,int temp1,
4662                                                                                                                                                        int temp2,int *ties)
4663{
4664  /*    We have a face id that needs to be decremented.
4665        We have to determine where it is in the structure,
4666        so that we can decrement it.
4667  */
4668  /*    The number of adjacencies may have changed, so to locate
4669        it may be a little tricky. However we know that the number
4670        of adjacencies is less than or equal to the original number
4671        of adjacencies,
4672  */
4673  int y,size;
4674  ListHead *pListHead;
4675  PF_FACES temp = NULL;
4676  PLISTINFO lpListInfo;
4677  static int each_poly = 0;
4678  BOOL there = FALSE;
4679 
4680  pListHead = PolFaces[face_id];
4681  temp = ( PF_FACES ) PeekList( pListHead, LISTHEAD, 0 );
4682  /*    Check each edge of the face and tally the number of adjacent
4683        polygons to this face.
4684  */                   
4685  if ( temp != NULL )
4686    {
4687      /*        Size of the polygon */
4688      size = temp->nPolSize;
4689      for (y = 0; y< size; y++)
4690        {
4691          /*    If we are doing partial triangulation, we must check
4692                to see whether the edge is still there in the polygon,
4693                since we might have done a portion of the polygon
4694                and saved the rest for later.
4695          */
4696          if (y != (size-1))
4697            {
4698              if( ((temp1 == *(temp->pPolygon+y)) &&
4699                   (temp2 ==*(temp->pPolygon+y+1))) ||
4700                  ((temp2 == *(temp->pPolygon+y)) &&
4701                   (temp1 ==*(temp->pPolygon+y+1))))
4702                /*      edge is still there we are ok */
4703                there = TRUE;
4704            }
4705          else
4706            {
4707              if( ((temp1 == *(temp->pPolygon)) &&
4708                   (temp2 == *(temp->pPolygon+size-1))) ||
4709                  ((temp2 == *(temp->pPolygon)) &&
4710                   (temp1 ==*(temp->pPolygon+size-1))))
4711                /*      edge is still there we are ok */
4712                there = TRUE;
4713            }
4714        }
4715     
4716      if (!there)
4717        /*      Original edge was already used, we cannot use this polygon */
4718        return;
4719     
4720      /*        We have a starting point to start our search to locate
4721                this polygon.
4722      */
4723     
4724      /*        Check to see if this polygon was done */
4725      lpListInfo = Done(face_id,&y);
4726     
4727      if (lpListInfo == NULL)
4728        return;
4729     
4730      /*  Was not done, but there is an error in the adjacency calculations */
4731      /*     If more than one edge is adj to it then maybe it was not updated */
4732      if (y == 0)
4733        return;
4734     
4735      /*        Now put the face in the proper bucket depending on tally. */
4736      /*        First add it to the new bucket, then remove it from the old */
4737      Add_Sgi_Adj(y-1,face_id);
4738      RemoveList(array[y],lpListInfo);
4739     
4740      /*        Save it if it was the smallest seen so far since then
4741                it will be the next face
4742                Here we will have different options depending on
4743                what we want for resolving ties:
4744                1) First one we see we will use
4745                2) Random resolving
4746                3) Look ahead
4747                4) Alternating direction
4748      */
4749      /*        At a new strip */
4750      if (*next_bucket == 60)
4751        *ties = *ties + each_poly;
4752      /*        Have a tie */
4753      if (*next_bucket == (y-1))
4754        {
4755          Add_Ties(face_id);
4756          each_poly++;
4757        }
4758      /*        At a new minimum */
4759      if (*next_bucket > (y-1))
4760        {
4761          *next_bucket = y-1;
4762          *min_face = face_id;
4763          *e1 = temp1;
4764          *e2 = temp2;
4765          each_poly = 0;
4766          Clear_Ties();
4767          Add_Ties(face_id);
4768        }
4769    }
4770}
4771
4772///     Delete_AdjEx:
4773void CustomStripifier::Delete_AdjEx(int id1,                                    int id2,
4774                                                                                                                                                int *next_bucket,       int *min_face,
4775                                                                                                                                        int current_face,       int *e1,
4776                                                                                                                                                int *e2,                                        int *ties)
4777{
4778  /*    Find the face that is adjacent to the edge and is not the
4779        current face. Delete one adjacency from it. Save the min
4780        adjacency seen so far.
4781  */
4782  register int count=0;
4783  PF_EDGES temp = NULL;
4784  ListHead *pListHead;
4785  int next_face;
4786 
4787  /*    Always want smaller id first */
4788  switch_lower(&id1,&id2);
4789 
4790  pListHead = PolEdges[id1];
4791  temp = (PF_EDGES) PeekList(pListHead,LISTHEAD,count);
4792  if (temp == NULL)
4793    /*  It could be a new edge that we created. So we can
4794        exit, since there is not a face adjacent to it.
4795    */
4796    return;
4797  while (temp->edge[0] != id2)
4798    {
4799      count++;
4800      temp = ( PF_EDGES )GetNextNode(temp);                                     
4801     
4802      if (temp == NULL)
4803        /*      Was a new edge that was created and therefore
4804                does not have anything adjacent to it
4805        */
4806        return;
4807    }
4808  /*    Was not adjacent to anything else except itself */
4809  if (temp->edge[2] == -1)
4810    return;
4811 
4812  /*    Was adjacent to something */
4813  else
4814    {
4815      if (temp->edge[2] == current_face)
4816        next_face =  temp->edge[1];
4817      else
4818        next_face = temp->edge[2];
4819    }
4820  /*    We have the other face adjacent to this edge, it is
4821        next_face. Now we need to decrement this faces' adjacencies.
4822  */
4823  Update_FaceEx(next_bucket, min_face, next_face,e1,e2,id1,id2,ties);
4824}
4825
4826///     Change_FaceEx:
4827int CustomStripifier::Change_FaceEx(int face_id,int in1,int in2,
4828                  ListHead *pListHead, BOOL no_check)
4829{
4830  /*    We are doing a partial triangulation and we need to
4831        put the new face of triangle into the correct bucket
4832  */
4833  int input_adj,y;
4834  P_ADJACENCIES lpListInfo; 
4835 
4836  /*    Find the old number of adjacencies to this face,
4837        so we know where to delete it from
4838  */
4839  y = Old_Adj(face_id);
4840  pListHead = array[y];
4841  lpListInfo = face_array[face_id].pfNode;
4842 
4843  if (lpListInfo == NULL)
4844    {
4845      printf("There is an error finding the next polygon3 %d\n",face_id);
4846      exit(0);
4847    }
4848 
4849  /*    Do we need to change the adjacency? Maybe the edge on the triangle
4850        that was outputted was not adjacent to anything. We know if we
4851        have to check by "check". We came out on the output edge
4852        that we needed, then we know that the adjacencies will decrease
4853        by exactly one.
4854  */
4855  if (!no_check)
4856    {
4857      input_adj = Number_Adj(in1,in2,face_id);
4858      /*        If there weren't any then don't do anything */
4859      if (input_adj == 0)
4860        return y;
4861    }
4862 
4863  if (face_array[lpListInfo->face_id].head == pListHead)
4864    face_array[lpListInfo->face_id].pfNode = NULL;
4865  RemoveList(pListHead,(PLISTINFO)/*(temp*/lpListInfo);
4866  /*    Before we had a quad with y adjacencies. The in edge
4867        did not have an adjacency, since it was just deleted,
4868        since we came in on it. The outedge must have an adjacency
4869        otherwise we would have a bucket 0, and would not be in this
4870        routine. Therefore the new adjacency must be y-1
4871  */
4872 
4873  Add_Sgi_Adj(y-1,face_id);
4874  return (y-1);
4875}
4876
4877///     Update_AdjacenciesEx:
4878int CustomStripifier::Update_AdjacenciesEx(int face_id, int *next_bucket, int *e1, int *e2,
4879                         int *ties)
4880{
4881  /*    Give the face with id face_id, we want to decrement
4882        all the faces that are adjacent to it, since we will
4883        be deleting face_id from the data structure.
4884        We will return the face that has the least number
4885        of adjacencies.
4886  */
4887  PF_FACES temp = NULL;
4888  ListHead *pListHead;
4889  int size,y,min_face = -1;
4890 
4891  *next_bucket = 60;
4892  pListHead = PolFaces[face_id];
4893  temp = ( PF_FACES ) PeekList( pListHead, LISTHEAD, 0 );
4894 
4895  if ( temp == NULL )
4896    {
4897      printf("The face was already deleted, there is an error\n");
4898      exit(0);
4899    }
4900 
4901  /*    Size of the polygon */
4902  size = temp->nPolSize;
4903  for (y = 0; y< size; y++)
4904    {
4905      if (y != (size-1))
4906        Delete_AdjEx(*(temp->pPolygon+y),*(temp->pPolygon+y+1),
4907                     next_bucket,&min_face,face_id,e1,e2,ties);
4908      else
4909        Delete_AdjEx(*(temp->pPolygon),*(temp->pPolygon+(size-1)),
4910                     next_bucket,&min_face,face_id,e1,e2,ties);
4911    }
4912  return (min_face);
4913}
4914
4915///     Find_Adj_TallyEx:
4916void CustomStripifier::Find_Adj_TallyEx(int id1,                                        int id2,
4917                                                                                                                                                                int *next_bucket,       int *min_face,
4918                                                                                                                                                int current_face,       int *ties)
4919{
4920  /*    Find the face that is adjacent to the edge and is not the
4921        current face. Save the min adjacency seen so far.
4922  */
4923  int size,each_poly=0,y,count=0;           
4924  PF_EDGES temp = NULL;
4925  PF_FACES temp2 = NULL;
4926  ListHead *pListHead;
4927  int next_face;
4928  BOOL there = FALSE;
4929 
4930 
4931  /*    Always want smaller id first */
4932  switch_lower(&id1,&id2);
4933 
4934  pListHead = PolEdges[id1];
4935  temp = (PF_EDGES) PeekList(pListHead,LISTHEAD,count);
4936  if (temp == NULL)
4937    /*  This was a new edge that was created, so it is
4938        adjacent to nothing.
4939    */
4940    return;
4941  while (temp->edge[0] != id2)
4942    {
4943      count++;
4944      temp =( PF_EDGES ) GetNextNode(temp);                                       
4945     
4946      if (temp == NULL)
4947        /*      This was a new edge that we created */
4948        return;
4949    }
4950  /*    Was not adjacent to anything else except itself */
4951  if (temp->edge[2] == -1)
4952    return;
4953  else
4954    {
4955      if (temp->edge[2] == current_face)
4956        next_face =  temp->edge[1];
4957      else
4958        next_face = temp->edge[2];
4959    }
4960  /*    We have the other face adjacent to this edge, it is
4961        next_face. Find how many faces it is adjacent to.
4962  */
4963  pListHead = PolFaces[next_face];
4964  temp2 = ( PF_FACES ) PeekList( pListHead, LISTHEAD, 0 );
4965  /*    Check each edge of the face and tally the number of adjacent
4966        polygons to this face. This will be the original number of
4967        polygons adjacent to this polygon, we must then see if this
4968        number has been decremented
4969  */                   
4970  if ( temp2 != NULL )
4971    {
4972      /*        Size of the polygon */
4973      size = temp2->nPolSize;
4974      for (y = 0; y< size; y++)
4975        {
4976          /*    Make sure that the edge is still in the
4977                polygon and was not deleted, because if the edge was
4978                deleted, then we used it already.
4979          */
4980          if (y != (size-1))
4981            {
4982              if( ((id1 == *(temp2->pPolygon+y)) &&
4983                   (id2 ==*(temp2->pPolygon+y+1))) ||
4984                  ((id2 == *(temp2->pPolygon+y)) &&
4985                   (id1 ==*(temp2->pPolygon+y+1))))
4986                /*      edge is still there we are ok */
4987                there = TRUE;
4988            }
4989          else
4990            {           
4991              if( ((id1 == *(temp2->pPolygon)) &&
4992                   (id2 ==*(temp2->pPolygon+size-1))) ||
4993                  ((id2 == *(temp2->pPolygon)) &&
4994                   (id1 ==*(temp2->pPolygon+size-1))))
4995                /*      edge is still there we are ok */
4996                there = TRUE;
4997            }
4998        }
4999     
5000      if (!there)
5001        /*      Edge already used and deleted from the polygon*/
5002        return;
5003     
5004      /*        See if the face was already deleted, and where
5005                it is if it was not
5006      */
5007      if (Done(next_face,&y) == NULL)
5008        return;
5009     
5010      /*        Save it if it was the smallest seen so far since then
5011                it will be the next face
5012                Here we will have different options depending on
5013                what we want for resolving ties:
5014                1) First one we see we will use
5015                2) Random resolving
5016                3) Look ahead
5017                4) Alternating direction
5018      */
5019     
5020      /*        At a new strip */
5021      if (*next_bucket == 60)
5022        *ties = *ties + each_poly;
5023      /*        Have a tie */
5024      if (*next_bucket == (y-1))
5025        {
5026          Add_Ties(next_face);
5027          each_poly++;
5028        }
5029      /*        At a new minimum */
5030      if (*next_bucket > (y-1))
5031        {
5032          *next_bucket = y-1;
5033          *min_face = next_face;
5034          each_poly = 0;
5035          Clear_Ties();
5036          Add_Ties(next_face);
5037        }
5038    }
5039}
5040
5041///     Min_Face_AdjEx:
5042int CustomStripifier::Min_Face_AdjEx(int face_id, int *next_bucket, int *ties)
5043{
5044  /*    Used for the Partial triangulation to find the next
5045        face. It will return the minimum adjacency face id
5046        found at this face.
5047  */
5048  PF_FACES temp = NULL;
5049  ListHead *pListHead;
5050  int size,y,min_face,test_face;
5051 
5052  *next_bucket = 60;
5053  pListHead = PolFaces[face_id];
5054  temp = ( PF_FACES ) PeekList( pListHead, LISTHEAD, 0 );
5055 
5056  if ( temp == NULL )
5057    {
5058      printf("The face was already deleted, there is an error\n");
5059      exit(0);
5060    }
5061 
5062  /*    Size of the polygon */
5063  size = temp->nPolSize;
5064  for (y = 0; y< size; y++)
5065    {
5066      if (y != (size-1))
5067        Find_Adj_TallyEx(*(temp->pPolygon+y),*(temp->pPolygon+y+1),
5068                         next_bucket,&min_face,face_id,ties);
5069      else
5070        Find_Adj_TallyEx(*(temp->pPolygon),*(temp->pPolygon+(size-1)),
5071                         next_bucket,&min_face,face_id,ties);
5072    }
5073  /*    Maybe we can do better by triangulating the face, because
5074        by triangulating the face we will go to a polygon of lesser
5075        adjacencies
5076  */
5077  if (size == 4)
5078    {
5079      /*    Checking for a quad whether to do the whole polygon will
5080            result in better performance because the triangles in the polygon
5081            have less adjacencies
5082      */
5083      Check_In_Quad(face_id,&test_face);
5084      if (*next_bucket > test_face)
5085        /*    We can do better by going through the polygon */
5086        min_face = face_id;
5087    }
5088 
5089  /*  We have a polygon with greater than 4 sides, check to see if going
5090      inside is better than going outside the polygon for the output edge.
5091  */
5092  else
5093    {
5094      Check_In_Polygon(face_id,&test_face,size);
5095      if (*next_bucket > test_face)
5096        /*  We can do better by going through the polygon */
5097        min_face = face_id;
5098    }
5099 
5100  return (min_face);
5101}
5102
5103///     Find_StripsEx:
5104void CustomStripifier::Find_StripsEx(FILE *output,int *ties,
5105                          int  tie, int triangulate,
5106                          int  swaps,int *next_id)
5107{
5108  /*    This routine will peel off the strips from the model */
5109 
5110  ListHead                      *pListHead;
5111  P_ADJACENCIES temp                            =       NULL;
5112  register int  max,bucket      =       0;
5113  BOOL                                  whole_flag      =       TRUE;
5114  int                                           dummy                           = 0;
5115  int                                           cont                            =       0;
5116 
5117  /*  Set the last known input edge to be null */
5118  Last_Edge(&dummy,&dummy,&dummy,1);
5119 
5120  /*    Search for lowest adjacency polygon and output strips */
5121  while (whole_flag)
5122        {
5123                bucket = -1;
5124    /*  Search for polygons in increasing number of adjacencies */
5125    while (bucket < 59)
5126                {
5127                        bucket++;
5128                        pListHead = array[bucket];
5129                        max = NumOnList(pListHead);
5130                        if (max > 0)
5131            {
5132                                temp = (P_ADJACENCIES) PeekList(pListHead,LISTHEAD,0);
5133              if (temp == NULL)
5134                                {
5135                                        printf("Error in the buckets%d %d %d\n",bucket,max,0);
5136                                        exit(0);
5137                                }
5138
5139              Polygon_OutputEx(temp,temp->face_id,bucket,pListHead, output,ties,tie,triangulate,swaps,next_id,1);
5140              /*  Try to extend backwards, if the starting polygon in the
5141                                                strip had 2 or more adjacencies to begin with
5142              */
5143              if (bucket >= 2)
5144                                        Extend_BackwardsEx(temp->face_id,output,ties,tie, triangulate,swaps,next_id);
5145
5146                                break; 
5147                        }
5148                }
5149                /*      Went through the whole structure, it is empty and we are done.
5150                */
5151                if ((bucket == 59) && (max == 0))
5152                        whole_flag = FALSE;
5153     
5154    /*  We just finished a strip, send dummy data to signal the end
5155                                of the strip so that we can output it.
5156    */
5157    else
5158                {
5159                        Output_TriEx(-1,-2,-3,output,-10,1);
5160                        Last_Edge(&dummy,&dummy,&dummy,1);
5161                        cont++;
5162                }
5163  }
5164        printf("We got %d strips\n",cont);
5165}
5166
5167///     SGI_Strip:
5168void CustomStripifier::SGI_Strip(int    num_faces,
5169                                                                                                                                 FILE *output,
5170                                                                                                                                 int    ties,
5171                                                                                                                                 int    triangulate)
5172{
5173  int next_id = -1,t=0;
5174 
5175  /* We are going to output and find triangle strips
5176     according the the method that SGI uses, ie always
5177     choosing as the next triangle in our strip the triangle
5178     that has the least number of adjacencies. We do not have
5179     all triangles and will be triangulating on the fly those
5180     polygons that have more than 3 sides.
5181  */
5182 
5183  /* Build a table that has all the polygons sorted by the number
5184     of polygons adjacent to it.
5185  */
5186  /* Initialize it */
5187  Init_Table_SGI(num_faces);
5188  /* Build it */
5189  Build_SGI_Table(num_faces);
5190 
5191  /* We will have a structure to hold all the strips, until
5192     outputted.
5193  */
5194  InitStripTable();
5195  /*  Now we have the structure built to find the polygons according
5196      to the number of adjacencies. Now use the SGI Method to find
5197      strips according to the adjacencies
5198  */
5199
5200  Find_StripsEx(output,&t,ties,triangulate,ON,&next_id);
5201 
5202}
5203
5204///     P_Triangulate_Quad:
5205void CustomStripifier::P_Triangulate_Quad(int out_edge1,int out_edge2,
5206                                                                                                                                                                        int in_edge1, int in_edge2,
5207                                                                                                                                                                        int size,                       int *index,
5208                                                                                                                                                int reversed, int face_id,
5209                                                                                                                                                                        ListHead *pListHead,
5210                                                                                                                                                P_ADJACENCIES temp,
5211                                                                                                                                                int where)
5212{
5213  int vertex4,vertex5,dummy=60;
5214 
5215  /*    This routine will nonblindly triangulate a quad, meaning
5216        that there is a definite input and a definite output
5217        edge that we must adhere to. Reversed will tell the orientation
5218        of the input edge. (Reversed is -1 is we do not have an input
5219        edge, in other words we are at the beginning of a strip.)
5220        Out_edge* is the output edge, and in_edge* is the input edge.
5221        Index are the edges of the polygon
5222        and size is the size of the polygon. Begin is whether we are
5223        at the start of a new strip.
5224        Note that we will not necessarily triangulate the whole quad;
5225        maybe we will do half and leave the other half (a triangle)
5226        for later.
5227  */
5228 
5229 
5230  /*    If we do not have an input edge, then we can make our input
5231        edge whatever we like, therefore it will be easier to come
5232        out on the output edge. In this case the whole quad is done.
5233  */
5234  if (reversed == -1)
5235    {
5236      vertex4 = AdjacentEx(out_edge1,out_edge2,index,size);
5237      vertex5 = Get_Other_Vertex(vertex4,out_edge1,out_edge2,index);
5238      Output_TriEx(vertex5,vertex4,out_edge1,NULL,-1,where);
5239      Output_TriEx(vertex4,out_edge1,out_edge2,NULL,-1,where);
5240      dummy = Update_AdjacenciesEx(face_id, &dummy, &dummy,&dummy,&dummy);
5241     
5242      if (face_array[temp->face_id].head == pListHead)
5243        face_array[temp->face_id].pfNode = NULL;
5244      RemoveList(pListHead,(PLISTINFO) temp);
5245      return;
5246    }
5247 
5248  /*    These are the 5 cases that we can have for the output edge */
5249 
5250  /*  Are they consecutive so that we form a triangle to
5251      peel off, but cannot use the whole quad?
5252  */
5253 
5254  if (in_edge2 == out_edge1)
5255    {
5256      /*        Output the triangle that comes out the correct
5257                edge. Save the other half for later.
5258      */
5259      vertex4 = Get_Other_Vertex(in_edge1,in_edge2,out_edge2,index);
5260      Output_TriEx(in_edge1,in_edge2,out_edge2,NULL,-1,where);
5261      /*        Now we have a triangle used, and a triangle that is
5262                left for later.
5263      */
5264     
5265      /*        Now delete the adjacencies by one for all the faces
5266                that are adjacent to the triangle that we just outputted.
5267      */
5268      Delete_AdjEx(in_edge1,in_edge2,&dummy,&dummy,
5269                   face_id,&dummy,&dummy,&dummy);
5270      Delete_AdjEx(out_edge2,in_edge2,&dummy,&dummy,
5271                   face_id,&dummy,&dummy,&dummy);
5272      /*        Put the new face in the proper bucket of adjacencies
5273                There are 2 edges that need to be checked for the triangle
5274                that was just outputted. For the output edge we definitely
5275                will be decreasing the adjacency, but we must check for the
5276                input edge.
5277      */
5278     
5279      dummy = Change_FaceEx(face_id,in_edge1,in_edge2,pListHead,FALSE);
5280      dummy = Change_FaceEx(face_id,in_edge2,out_edge2,pListHead,TRUE);
5281     
5282      /*        Update the face data structure, by deleting the old
5283                face and putting in the triangle as the new face
5284      */
5285      New_Face(face_id,in_edge1,out_edge2,vertex4);
5286      return;                                                                     
5287    }
5288  else if (in_edge1 == out_edge1)
5289    {
5290      /*        We want to output the first triangle (whose output
5291                edge is not the one that we want.
5292                We have to find the vertex that we need, which is
5293                the other vertex which we do not have.
5294      */                                               
5295      vertex4 = Get_Other_Vertex(in_edge1,in_edge2,out_edge2,index);
5296      Output_TriEx(in_edge2,in_edge1,out_edge2,NULL,-1,where);
5297      /*        Now we have a triangle used, and a triangle that is
5298                left for later.
5299      */
5300     
5301      /*        Now delete the adjacencies by one for all the faces
5302                that are adjacent to the triangle that we just outputted.
5303      */
5304      Delete_AdjEx(in_edge1,in_edge2,&dummy,&dummy,face_id,
5305                   &dummy,&dummy,&dummy);
5306      Delete_AdjEx(out_edge2,out_edge1,&dummy,&dummy,
5307                   face_id,&dummy,&dummy,&dummy);
5308     
5309      /*        Put the new face in the proper bucket of adjacencies */
5310      dummy = Change_FaceEx(face_id,in_edge1,in_edge2,pListHead,FALSE);
5311      dummy = Change_FaceEx(face_id,in_edge1,out_edge2,pListHead,TRUE);
5312     
5313      /*        Update the face data structure, by deleting the old
5314                face and putting in the triangle as the new face
5315      */
5316      New_Face(face_id,in_edge2,out_edge2,vertex4);
5317      return;
5318    }
5319 
5320  /*    Consecutive cases again, but with the output edge reversed */
5321  else if (in_edge1 == out_edge2)
5322    {
5323      vertex4 = Get_Other_Vertex(in_edge1,in_edge2,out_edge1,index);
5324      Output_TriEx(in_edge2,in_edge1,out_edge1,NULL,-1,where);
5325      /*        Now we have a triangle used, and a triangle that is
5326                left for later.
5327      */
5328     
5329      /*        Now delete the adjacencies by one for all the faces
5330                that are adjacent to the triangle that we just outputted.
5331      */
5332      Delete_AdjEx(in_edge1,in_edge2,&dummy,&dummy,face_id,
5333                   &dummy,&dummy,&dummy);
5334      Delete_AdjEx(out_edge2,out_edge1,&dummy,&dummy,
5335                   face_id,&dummy,&dummy,&dummy);
5336     
5337      /*        Put the new face in the proper bucket of adjacencies */
5338      dummy = Change_FaceEx(face_id,in_edge1,in_edge2,pListHead,FALSE);
5339      dummy = Change_FaceEx(face_id,out_edge1,out_edge2,pListHead,TRUE);
5340     
5341      /*        Update the face data structure, by deleting the old
5342                face and putting in the triangle as the new face
5343      */
5344      New_Face(face_id,in_edge2,out_edge1,vertex4);
5345      return;
5346    }
5347  else if (in_edge2 == out_edge2)
5348    {
5349      vertex4 = Get_Other_Vertex(in_edge1,in_edge2,out_edge1,index);
5350      Output_TriEx(in_edge1,in_edge2,out_edge1,NULL,-1,where);
5351      /*        Now we have a triangle used, and a triangle that is
5352                left for later.
5353      */
5354      /*        Now delete the adjacencies by one for all the faces
5355                that are adjacent to the triangle that we just outputted.
5356      */
5357      Delete_AdjEx(in_edge1,in_edge2,&dummy,&dummy,face_id,
5358                   &dummy,&dummy,&dummy);
5359      Delete_AdjEx(out_edge2,out_edge1,&dummy,&dummy,
5360                   face_id,&dummy,&dummy,&dummy);
5361     
5362      /*        Put the new face in the proper bucket of adjacencies */
5363      dummy = Change_FaceEx(face_id,in_edge1,in_edge2,pListHead,FALSE);
5364      dummy = Change_FaceEx(face_id,out_edge1,out_edge2,pListHead,TRUE);
5365     
5366      /*        Update the face data structure, by deleting the old
5367                face and putting in the triangle as the new face
5368      */
5369      New_Face(face_id,in_edge1,out_edge1,vertex4);
5370      return;
5371    }
5372 
5373  /*    The final case is where we want to come out the opposite
5374        edge.
5375  */
5376  else
5377    {
5378      if( ((!reversed) &&
5379           (out_edge1 == (AdjacentEx(in_edge1,in_edge2,index,size)))) ||
5380          ((reversed) &&
5381           (out_edge2 == (AdjacentEx(in_edge2,in_edge1,index,size)))))
5382        {
5383          /*    We need to know the orientation of the input
5384                edge, so we know which way to put the diagonal.
5385                And also the output edge, so that we triangulate
5386                correctly. Does not need partial.
5387          */
5388          Output_TriEx(in_edge1,in_edge2,out_edge2,NULL,-1,where);
5389          Output_TriEx(in_edge2,out_edge2,out_edge1,NULL,-1,where);
5390          dummy = Update_AdjacenciesEx(face_id, &dummy, &dummy,&dummy,&dummy);
5391         
5392          if (face_array[temp->face_id].head == pListHead)
5393            face_array[temp->face_id].pfNode = NULL;
5394          RemoveList(pListHead,(PLISTINFO) temp);
5395        }
5396      else
5397        {
5398          /*      Input and output orientation was reversed, so diagonal will
5399                  be reversed from above.
5400          */
5401          Output_TriEx(in_edge1,in_edge2,out_edge1,NULL,-1,where);
5402          Output_TriEx(in_edge2,out_edge1,out_edge2,NULL,-1,where);
5403          dummy = Update_AdjacenciesEx(face_id, &dummy, &dummy,&dummy,&dummy);
5404         
5405          if (face_array[temp->face_id].head == pListHead)
5406            face_array[temp->face_id].pfNode = NULL;
5407          RemoveList(pListHead,(PLISTINFO) temp);
5408        }
5409      return;
5410    }
5411}
5412
5413///     P_Triangulate_Polygon:
5414void CustomStripifier::P_Triangulate_Polygon(   int out_edge1,int out_edge2,
5415                                                                                                                                                                                        int in_edge1, int in_edge2,
5416                                                                                                                                                                                        int size,               int *index,
5417                                                                                                                                                                                        FILE *fp,                 int reversed,
5418                                                                                                                                                                                        int face_id,    int *next_id,
5419                                                                                                                                                                                ListHead *pListHead,
5420                                                                                                                                                                                        P_ADJACENCIES temp2,
5421                                                                                                                                                                                int where)
5422{
5423  /*    We have a polygon greater than 4 sides, which we wish
5424        to partially triangulate
5425  */
5426  int next_bucket,vertex4,dummy = 60;
5427  int *temp;
5428 
5429 
5430  /*    Since we are calling this recursively, we have to check whether         
5431        we are down to the case of the quad.
5432  */
5433  if (size == 4)
5434    {
5435      P_Triangulate_Quad(out_edge1,out_edge2,in_edge1,in_edge2,size,
5436                         index,reversed,face_id,
5437                         pListHead,temp2,where);
5438      return;
5439    }
5440 
5441  /*    We do not have a specified input edge, and therefore we
5442        can make it anything we like, as long as we still come out
5443        the output edge that we want.
5444  */
5445  if (reversed  == -1)
5446    {
5447      /*        Get the vertex for the last triangle, which is
5448                the one coming out the output edge, before we do
5449                any deletions to the list. We will be doing this
5450                bottom up.
5451      */
5452      vertex4 = AdjacentEx(out_edge1,out_edge2,index,size);
5453      temp = (int *) malloc(sizeof(int) * size);
5454      memcpy(temp,index,sizeof(int)*size);
5455      Delete_From_ListEx(out_edge2,index,size);
5456      /*        We do not have to partially triangulate, since
5457                we will do the whole thing, so use the whole routine
5458      */
5459      Triangulate_PolygonEx(vertex4,out_edge1,in_edge2,
5460                            vertex4,size-1,index,fp,
5461                            reversed,face_id,
5462                            where);
5463      memcpy(index,temp,sizeof(int)*size);
5464      /*        Lastly do the triangle that comes out the output
5465                edge.
5466      */
5467      Output_TriEx(vertex4,out_edge1,out_edge2,NULL,-1,where);
5468      /*        We were able to do the whole polygon, now we
5469                can delete the whole thing from our data structure.
5470      */
5471      dummy = Update_AdjacenciesEx(face_id, &dummy, &dummy,&dummy,&dummy);
5472     
5473      if (face_array[temp2->face_id].head == pListHead)
5474        face_array[temp2->face_id].pfNode = NULL;
5475      RemoveList(pListHead,(PLISTINFO) temp2);
5476      return;
5477    }     
5478 
5479  /*    These are the 5 cases that we can have for the output edge */
5480 
5481  /*  Are they consecutive so that we form a triangle to
5482      peel off that comes out the correct output edge,
5483      but we cannot use the whole polygon?
5484  */
5485  if (in_edge2 == out_edge1)
5486    {
5487      Output_TriEx(in_edge1,out_edge1,out_edge2,NULL,-1,where);
5488     
5489      /*        Now delete the adjacencies by one for all the faces
5490                that are adjacent to the triangle that we just outputted.
5491      */
5492      Delete_AdjEx(in_edge1,in_edge2,&dummy,&dummy,face_id,
5493                   &dummy,&dummy,&dummy);
5494      Delete_AdjEx(out_edge2,out_edge1,&dummy,&dummy,
5495                   face_id,&dummy,&dummy,&dummy);
5496     
5497      /*        Put the new face in the proper bucket of adjacencies */
5498      next_bucket=Change_FaceEx(face_id,in_edge1,in_edge2,pListHead,FALSE);
5499      next_bucket=Change_FaceEx(face_id,out_edge1,out_edge2,pListHead,TRUE);
5500     
5501      /*        Create a new edgelist without the triangle that
5502                was just outputted.
5503      */
5504      Delete_From_ListEx(in_edge2,index,size);
5505      /*        Update the face data structure, by deleting the old
5506                face and putting in the polygon minus the triangle
5507                as the new face, here we will be decrementing the size
5508                by one.
5509      */
5510      New_Size_Face(face_id);
5511      return;
5512    }
5513 
5514  /*    Next case is where it is again consecutive, but the triangle
5515        formed by the consecutive edges do not come out of the
5516        correct output edge. (the input edge will be reversed in
5517        the next triangle)
5518  */
5519  else if (in_edge1 == out_edge1)
5520    {
5521      /*        Get vertex adjacent to in_edge2, but is not in_edge1 */
5522      Output_TriEx(in_edge2,in_edge1,out_edge2,NULL,-1,where);
5523     
5524      /*        Now delete the adjacencies by one for all the faces
5525                that are adjacent to the triangle that we just outputted.
5526      */
5527      Delete_AdjEx(in_edge1,in_edge2,&dummy,&dummy,face_id,
5528                   &dummy,&dummy,&dummy);
5529      Delete_AdjEx(out_edge2,out_edge1,&dummy,&dummy,
5530                   face_id,&dummy,&dummy,&dummy);
5531     
5532      /*        Put the new face in the proper bucket of adjacencies */
5533      next_bucket=Change_FaceEx(face_id,in_edge1,in_edge2,pListHead,FALSE);
5534      next_bucket=Change_FaceEx(face_id,out_edge1,out_edge2,pListHead,TRUE);
5535     
5536      /*        Create a new edgelist without the triangle that
5537                was just outputted.
5538      */
5539      Delete_From_ListEx(in_edge1,index,size);
5540      /*        Update the face data structure, by deleting the old
5541                face and putting in the polygon minus the triangle
5542                as the new face, here we will be decrementing the size
5543                by one.
5544      */
5545      New_Size_Face(face_id);
5546      return;
5547    }
5548 
5549  /*    Consecutive cases again, but with the output edge reversed */
5550  else if (in_edge1 == out_edge2)
5551    {
5552      Output_TriEx(in_edge2,in_edge1,out_edge1,NULL,-1,where);
5553     
5554      /*        Now delete the adjacencies by one for all the faces
5555                that are adjacent to the triangle that we just outputted.
5556      */
5557      Delete_AdjEx(in_edge1,in_edge2,&dummy,&dummy,face_id,
5558                   &dummy,&dummy,&dummy);
5559      Delete_AdjEx(out_edge1,out_edge2,&dummy,&dummy,
5560                   face_id,&dummy,&dummy,&dummy);
5561     
5562      /*        Put the new face in the proper bucket of adjacencies */
5563      next_bucket=Change_FaceEx(face_id,in_edge1,in_edge2,pListHead,FALSE);
5564      next_bucket=Change_FaceEx(face_id,out_edge1,out_edge2,pListHead,TRUE);
5565     
5566      /*        Create a new edgelist without the triangle that
5567                was just outputted.
5568      */
5569      Delete_From_ListEx(in_edge1,index,size);
5570      /*        Update the face data structure, by deleting the old
5571                face and putting in the polygon minus the triangle
5572                as the new face, here we will be decrementing the size
5573                by one.
5574      */
5575      New_Size_Face(face_id);
5576      return;
5577    }
5578  else if (in_edge2 == out_edge2)
5579    {
5580      Output_TriEx(in_edge1,in_edge2,out_edge1,NULL,-1,where);
5581     
5582      /*        Now delete the adjacencies by one for all the faces
5583                that are adjacent to the triangle that we just outputted.
5584      */
5585      Delete_AdjEx(in_edge1,in_edge2,&dummy,&dummy,face_id,
5586                   &dummy,&dummy,&dummy);
5587      Delete_AdjEx(out_edge2,out_edge1,&dummy,&dummy,
5588                   face_id,&dummy,&dummy,&dummy);
5589     
5590      /*        Put the new face in the proper bucket of adjacencies */
5591      next_bucket=Change_FaceEx(face_id,in_edge1,in_edge2,pListHead,FALSE);
5592      next_bucket=Change_FaceEx(face_id,out_edge1,out_edge2,pListHead,TRUE);
5593     
5594      /*        Create a new edgelist without the triangle that
5595                was just outputted.
5596      */
5597      Delete_From_ListEx(in_edge2,index,size);
5598      /*        Update the face data structure, by deleting the old
5599                face and putting in the polygon minus the triangle
5600                as the new face, here we will be decrementing the size
5601                by one.
5602      */
5603      New_Size_Face(face_id);
5604      return;
5605    }
5606 
5607  /*    Else the edge is not consecutive, and it is sufficiently
5608        far away, for us not to make a conclusion at this time.
5609        So we can take off a triangle and recursively call this
5610        function.
5611  */
5612  else
5613    {
5614      if (!reversed)
5615        {
5616          vertex4 = AdjacentEx(in_edge2,in_edge1,index,size);
5617          Output_TriEx(in_edge1,in_edge2,vertex4,NULL,-1,where);
5618         
5619          /*    Now delete the adjacencies by one for all the faces
5620                that are adjacent to the triangle that we just outputted.
5621          */
5622          Delete_AdjEx(in_edge1,in_edge2,&dummy,&dummy,face_id,
5623                       &dummy,&dummy,&dummy);
5624          Delete_AdjEx(in_edge1,vertex4,&dummy,&dummy,
5625                       face_id,&dummy,&dummy,&dummy);
5626         
5627          /*    Put the new face in the proper bucket of adjacencies */
5628          next_bucket = Change_FaceEx(face_id,in_edge1,in_edge2,
5629                                      pListHead,FALSE);
5630          next_bucket = Change_FaceEx(face_id,in_edge1,vertex4,
5631                                      pListHead,FALSE);
5632         
5633          /*    Create a new edgelist without the triangle that
5634                was just outputted.
5635          */
5636          Delete_From_ListEx(in_edge1,index,size);
5637          /*    Update the face data structure, by deleting the old
5638                face and putting in the polygon minus the triangle
5639                as the new face, here we will be decrementing the size
5640                by one.
5641          */
5642          New_Size_Face(face_id);
5643         
5644          /*    Save the info for the new bucket, we will need it on
5645                the next pass for the variables, pListHead and temp
5646          */
5647          pListHead = array[next_bucket];
5648          temp2 = face_array[face_id].pfNode;
5649          if (temp2 == NULL)
5650            {
5651              printf("There is an error finding the next polygon10\n",
5652                     next_bucket,face_id);
5653              exit(0);
5654            }
5655         
5656          P_Triangulate_Polygon(out_edge1,out_edge2,in_edge2,
5657                                vertex4,size-1,index,fp,!reversed,
5658                                face_id,next_id,pListHead,temp2,where);
5659        }
5660      else
5661        {
5662          vertex4 = AdjacentEx(in_edge1,in_edge2,index,size);
5663          Output_TriEx(in_edge2,in_edge1,vertex4,NULL,-1,where);
5664         
5665          /*    Now delete the adjacencies by one for all the faces
5666                that are adjacent to the triangle that we just outputted.
5667          */
5668          Delete_AdjEx(in_edge1,in_edge2,&dummy,&dummy,face_id,
5669                       &dummy,&dummy,&dummy);
5670          Delete_AdjEx(in_edge2,vertex4,&dummy,&dummy,
5671                       face_id,&dummy,&dummy,&dummy);
5672         
5673          /*    Put the new face in the proper bucket of adjacencies */
5674          next_bucket = Change_FaceEx(face_id,in_edge1,in_edge2,
5675                                      pListHead,FALSE);
5676          next_bucket = Change_FaceEx(face_id,in_edge2,vertex4,
5677                                      pListHead,FALSE);
5678         
5679          /*    Create a new edgelist without the triangle that
5680                was just outputted.
5681          */
5682          Delete_From_ListEx(in_edge2,index,size);
5683         
5684          /*    Update the face data structure, by deleting the old
5685                face and putting in the polygon minus the triangle
5686                as the new face, here we will be decrementing the size
5687                by one.
5688          */
5689          New_Size_Face(face_id);
5690         
5691          /*    Save the info for the new bucket, we will need it on
5692                the next pass for the variables, pListHead and temp
5693          */
5694          pListHead = array[next_bucket];
5695          temp2 = face_array[face_id].pfNode;
5696          if (temp2 == NULL)
5697            {
5698              printf("There is an error finding the next polygon11 %d %d\n",
5699                     face_id,next_bucket);
5700              exit(0);
5701            }
5702         
5703          P_Triangulate_Polygon(out_edge1,out_edge2,vertex4,
5704                                in_edge1,size-1,index,fp,!reversed,
5705                                face_id,next_id,pListHead,temp2,where);
5706        }
5707      return;
5708    }
5709}
5710
5711///     P_Triangulate:
5712void CustomStripifier::P_Triangulate(   int out_edge1,int out_edge2,int in_edge1,
5713                                                                                                                                                int in_edge2,   int size,                       int *index,
5714                                                                                                                                                FILE *output,   int reversed,   int face_id,
5715                                                                                                                                                int *next_id,   ListHead *pListHead,
5716                                                                                                                                                P_ADJACENCIES temp,int where)
5717{
5718 
5719  if (size == 4)
5720    P_Triangulate_Quad(out_edge1,out_edge2,in_edge1,in_edge2,size,
5721                       index,reversed,face_id,
5722                       pListHead,temp,where);
5723  else
5724    P_Triangulate_Polygon(out_edge1,out_edge2,in_edge1,in_edge2,size,
5725                          index,output,reversed,face_id,next_id,
5726                          pListHead,temp,where);
5727}
5728
5729void CustomStripifier::Partial_Triangulate(int size,int *index,
5730                         FILE *output,int next_face_id,int face_id,
5731                         int *next_id,ListHead *pListHead,
5732                         P_ADJACENCIES temp, int where)
5733{
5734  int id1,id2,id3;
5735  int nedge1,nedge2;
5736  int reversed;
5737 
5738  /*    We have a polygon that has to be triangulated and we cannot
5739        do it blindly, ie we will try to come out on the edge that
5740        has the least number of adjacencies, But also we do not
5741        want to triangulate the whole polygon now, so that means
5742        we will output the least number of triangles that we can
5743        and then update the data structures, with the polygon
5744        that is left after we are done.
5745  */
5746  Last_Edge(&id1,&id2,&id3,0);
5747 
5748  /*    Find the edge that is adjacent to the new face ,
5749        also return whether the orientation is reversed in the
5750        face of the input edge, which is id2 and id3.
5751  */
5752  reversed = Get_EdgeEx(&nedge1,&nedge2,index,next_face_id,size,id2,id3);
5753 
5754  /*   Input edge and output edge can be the same if there are more than
5755       one polygon on an edge
5756  */
5757  if ( ((nedge1 == id2) && (nedge2 == id3)) ||
5758       ((nedge1 == id3) && (nedge2 == id2)) )
5759    /*   Set output edge arbitrarily but when come out of here the
5760         next face will be on the old output edge (identical one)
5761    */
5762    nedge2 = Return_Other(index,id2,id3);
5763 
5764  /*    Do the triangulation */
5765  P_Triangulate(nedge1,nedge2,id2,id3,size,index,output,reversed,
5766                face_id,next_id,pListHead,temp,where);
5767}
5768
5769///     Input_Edge:
5770void CustomStripifier::Input_Edge(int face_id,  int *index,
5771                                                                                                                                        int size,               int in_edge1,
5772                                                                                                                                        int in_edge2, ListHead *pListHead,
5773                                                                                                                int where)
5774{
5775  /* The polygon had an input edge, specified by input1 and input2 */
5776 
5777  int output1,next_bucket;
5778  int vertex4, vertex5,dummy=60;
5779 
5780  output1 = Get_Output_Edge(face_id,size,index,in_edge1,in_edge2);
5781  vertex5 = AdjacentEx(in_edge2,in_edge1,index,size);
5782  vertex4 = AdjacentEx(in_edge1,in_edge2,index,size);
5783 
5784  if (vertex4 == output1)
5785    {
5786      Output_TriEx(in_edge2,in_edge1,output1,NULL,-1,where);
5787      /*        Now delete the adjacencies by one for all the faces
5788                that are adjacent to the triangle that we just outputted.
5789      */
5790      Delete_AdjEx(in_edge1,in_edge2,&dummy,&dummy,face_id,
5791                   &dummy,&dummy,&dummy);
5792      Delete_AdjEx(in_edge2,output1,&dummy,&dummy,
5793                   face_id,&dummy,&dummy,&dummy);
5794      /*        Put the new face in the proper bucket of adjacencies */
5795      next_bucket=Change_FaceEx(face_id,in_edge1,in_edge2,pListHead,FALSE);
5796      next_bucket=Change_FaceEx(face_id,in_edge2,output1,pListHead,FALSE);
5797     
5798      /*        Create a new edgelist without the triangle that
5799                was just outputted.
5800      */
5801      Delete_From_ListEx(in_edge2,index,size);
5802     
5803    }   
5804  else if (vertex5 == output1)
5805    {
5806      Output_TriEx(in_edge1,in_edge2,vertex5,NULL,-1,where);
5807      /*        Now delete the adjacencies by one for all the faces
5808                that are adjacent to the triangle that we just outputted.
5809      */
5810      Delete_AdjEx(in_edge1,in_edge2,&dummy,&dummy,face_id,
5811                   &dummy,&dummy,&dummy);
5812      Delete_AdjEx(in_edge1,vertex5,&dummy,&dummy,
5813                   face_id,&dummy,&dummy,&dummy);
5814      /*        Put the new face in the proper bucket of adjacencies */
5815      next_bucket=Change_FaceEx(face_id,in_edge1,in_edge2,pListHead,FALSE);
5816      next_bucket=Change_FaceEx(face_id,in_edge1,vertex5,pListHead,FALSE);
5817     
5818      /*        Create a new edgelist without the triangle that
5819                was just outputted.
5820      */
5821      Delete_From_ListEx(in_edge1,index,size);
5822    }
5823 
5824  /*    Update the face data structure, by deleting the old
5825        face and putting in the polygon minus the triangle
5826        as the new face, here we will be decrementing the size
5827        by one.
5828  */
5829  New_Size_Face(face_id);
5830  return;
5831}
5832
5833///     Inside_Polygon:
5834void CustomStripifier::Inside_Polygon(int size,int *index,
5835                    int face_id,ListHead *pListHead, int where)
5836{
5837  /* We know that we have a polygon that is greater than 4 sides, and
5838     that it is better for us to go inside the polygon for the next
5839     one, since inside will have less adjacencies than going outside.
5840     So, we are not doing partial for a part of the polygon.
5841  */
5842  int id1,id2,id3;
5843  int new1,new2;
5844 
5845  Last_Edge(&id1,&id2,&id3,0);
5846 
5847  /*  See if the input edge existed in the polygon, that will help us */
5848  if (Exist(face_id,id2,id3))
5849    Input_Edge(face_id,index,size,id2,id3,pListHead,where);
5850  else
5851    {
5852      /*  Make one of the input edges
5853          We will choose it by trying to get an edge that has something
5854          in common with the last triangle, or by getting the edge that
5855          is adjacent to the least number of thigs, with preference given
5856          to the first option
5857      */
5858     
5859      Get_Input_Edge(index,id1,id2,id3,&new1,&new2,size,face_id);
5860      Input_Edge(face_id,index,size,new1,new2,pListHead,where);
5861    }
5862}
5863
5864///     Finished:
5865int CustomStripifier::Finished(int *swap, FILE *output, int startnewstrip)
5866{
5867  /*   We have finished all the triangles, now is time to output to
5868       the data file. In the strips data structure, every three ids
5869       is  a triangle. Now we see whether we can swap, or make a new strip
5870       or continue the strip, and output the data accordingly to the
5871       data file.
5872  */
5873  int num,x,vertex1,vertex2;
5874  ListHead *pListHead;
5875  int id[2],other1,other2,index = 0,a,b,c;
5876  P_STRIPS temp1,temp2,temp3,temp4,temp5,temp6;
5877  BOOL cptexture;
5878  *swap =0;
5879 
5880  cptexture = text;
5881  pListHead = strips[0];
5882  if (pListHead == NULL)
5883        return 0;
5884 
5885  num = NumOnList(pListHead);
5886  //printf ("There are %d triangles in the extend\n",num/3);
5887 
5888  // Go through the list triangle by triangle
5889  temp1 = ( P_STRIPS ) PeekList( pListHead, LISTHEAD, 0);
5890  temp2 = ( P_STRIPS ) PeekList( pListHead, LISTHEAD, 1);
5891  temp3 = ( P_STRIPS ) PeekList( pListHead, LISTHEAD, 2);
5892 
5893  // Next triangle for lookahead
5894  temp4 = ( P_STRIPS ) PeekList( pListHead, LISTHEAD, 3);
5895
5896  // There is only one polygon in the strip
5897  if (temp4 == NULL)
5898  {
5899        // Data might be mixed and we do not have textures for some of the vertices
5900    if ((text) &&  (vt[temp3->face_id] == 0))
5901                cptexture = FALSE;
5902    if ((norm) && (!cptexture)) {
5903                if (startnewstrip && orient) // If we want to keep orientation
5904                        preserve_strip_orientation_with_normal(output, temp3->face_id+1,vn[temp3->face_id]+1,
5905                                                temp2->face_id+1,vn[temp2->face_id]+1, temp1->face_id+1,vn[temp1->face_id]+1);
5906               
5907                fprintf(output," %d//%d %d//%d %d//%d", temp3->face_id+1,vn[temp3->face_id]+1,
5908                                        temp2->face_id+1,vn[temp2->face_id]+1, temp1->face_id+1,vn[temp1->face_id]+1);
5909        }
5910        else if ((cptexture) && (!norm)) {
5911                if (startnewstrip && orient) /* If we want to keep orientation */
5912                        preserve_strip_orientation_with_texture(output, temp3->face_id+1,vt[temp3->face_id]+1,
5913                                temp2->face_id+1,vt[temp2->face_id]+1,  temp1->face_id+1,vt[temp1->face_id]+1);
5914               
5915                fprintf(output," %d/%d %d/%d %d/%d", temp3->face_id+1,vt[temp3->face_id]+1,
5916                                        temp2->face_id+1,vt[temp2->face_id]+1, temp1->face_id+1,vt[temp1->face_id]+1);
5917        }
5918    else if ((cptexture)&& (norm)) {
5919        if (startnewstrip && orient) /* If we want to keep orientation */
5920          preserve_strip_orientation_with_texture_and_normal(output, temp3->face_id+1,vt[temp3->face_id]+1,vn[temp3->face_id]+1,
5921                                temp2->face_id+1,vt[temp2->face_id]+1,vn[temp2->face_id]+1, temp1->face_id+1,vt[temp1->face_id]+1,vn[temp1->face_id]+1);
5922       
5923        fprintf(output," %d/%d/%d %d/%d/%d %d/%d/%d", temp3->face_id+1,vt[temp3->face_id]+1,vn[temp3->face_id]+1,
5924                temp2->face_id+1,vt[temp2->face_id]+1,vn[temp2->face_id]+1, temp1->face_id+1,vt[temp1->face_id]+1,vn[temp1->face_id]+1);
5925    }
5926    else
5927    {
5928                if (startnewstrip && orient) /* If we want to keep orientation */
5929                        preserve_strip_orientation(output, temp3->face_id+1,temp2->face_id+1,temp1->face_id+1);
5930         
5931                fprintf(output," %d %d %d", temp3->face_id+1,temp2->face_id+1,temp1->face_id+1);
5932                mi_vector[num_tiras].push_back(temp3->face_id);
5933                mi_vector[num_tiras].push_back(temp2->face_id);
5934                mi_vector[num_tiras].push_back(temp1->face_id);
5935    }
5936    Free_Strips();
5937
5938    return 1;
5939  }
5940 
5941  // We have a real strip
5942  temp5 = ( P_STRIPS ) PeekList( pListHead, LISTHEAD, 4);
5943  temp6 = ( P_STRIPS ) PeekList( pListHead, LISTHEAD, 5);
5944 
5945  if ((temp1 == NULL) || (temp2 == NULL) || (temp3 == NULL) || (temp5 == NULL) || (temp6 == NULL))
5946  {
5947        printf("There is an error in the output of the triangles\n");
5948    exit(0);
5949  }
5950 
5951  // Find the vertex in the first triangle that is not in the second
5952  vertex1 = Different(temp1->face_id,temp2->face_id,temp3->face_id, temp4->face_id,temp5->face_id,temp6->face_id, &other1,&other2);
5953  // Find the vertex in the second triangle that is not in the first
5954  vertex2 = Different(temp4->face_id,temp5->face_id,temp6->face_id, temp1->face_id,temp2->face_id,temp3->face_id, &other1,&other2);
5955 
5956  // Lookahead for the correct order of the 2nd and 3rd vertex of the first triangle
5957  temp1 = ( P_STRIPS ) PeekList( pListHead, LISTHEAD, 6);
5958  temp2 = ( P_STRIPS ) PeekList( pListHead, LISTHEAD, 7);
5959  temp3 = ( P_STRIPS ) PeekList( pListHead, LISTHEAD, 8);
5960 
5961  if (temp1 != NULL)
5962    other1 = Different(temp3->face_id,temp4->face_id,temp5->face_id, temp1->face_id,temp2->face_id,temp3->face_id,&other1,&a);
5963 
5964  id[index] = vertex1; index = !index;
5965  id[index] = other1; index = !index;
5966  id[index] = other2; index = !index;
5967 
5968  a = temp4->face_id;
5969  b = temp5->face_id;
5970  c = temp6->face_id;
5971 
5972        /*
5973  // If we need to rearrange the first sequence because otherwise there would have been a swap.
5974  if ((temp3 != NULL) && (text) && ( vt[temp3->face_id]==0))
5975    cptexture = FALSE;
5976  if ((norm) && (!cptexture)) {
5977    if (orient && startnewstrip) // If we want to keep orientation
5978      preserve_strip_orientation_with_normal(output, vertex1+1,vn[vertex1]+1, other1+1,vn[other1]+1, other2+1,vn[other2]+1);
5979   
5980    fprintf(output," %d//%d %d//%d %d//%d", vertex1+1,vn[vertex1]+1, other1+1,vn[other1]+1, other2+1,vn[other2]+1);
5981  }
5982  else if ((cptexture) && (!norm)) {
5983    if (orient && startnewstrip) // If we want to keep orientation
5984      preserve_strip_orientation_with_texture(output, vertex1+1,vt[vertex1]+1, other1+1,vt[other1]+1, other2+1,vt[other2]+1);
5985   
5986    fprintf(output," %d/%d %d/%d %d/%d", vertex1+1,vt[vertex1]+1, other1+1,vt[other1]+1, other2+1,vt[other2]+1);
5987  }
5988  else if ((cptexture) && (norm)) {
5989    if (orient && startnewstrip) // If we want to keep orientation
5990      preserve_strip_orientation_with_texture_and_normal(output, vertex1+1,vt[vertex1]+1,vn[vertex1]+1,
5991                                                         other1+1,vt[other1]+1,vn[other1]+1, other2+1,vt[other2]+1,vn[other2]+1);
5992   
5993    fprintf(output," %d/%d/%d %d/%d/%d %d/%d/%d", vertex1+1,vt[vertex1]+1,vn[vertex1]+1,
5994            other1+1,vt[other1]+1,vn[other1]+1, other2+1,vt[other2]+1,vn[other2]+1);
5995  }
5996  else
5997  {
5998        */
5999        if (orient && startnewstrip) // If we want to keep orientation
6000                preserve_strip_orientation(output,vertex1+1,other1+1,other2+1);
6001   
6002    fprintf(output," %d %d %d",vertex1+1,other1+1,other2+1);
6003        mi_vector[num_tiras].push_back(vertex1);
6004        mi_vector[num_tiras].push_back(other1);
6005        mi_vector[num_tiras].push_back(other2);
6006
6007        /*
6008  }
6009  */
6010  for (x = 6; x < num ; x = x+3)
6011  {
6012        //    Get the next triangle
6013    temp1 = ( P_STRIPS ) PeekList( pListHead, LISTHEAD, x);       
6014    temp2 = ( P_STRIPS ) GetNextNode(temp1);                                     
6015    temp3 = ( P_STRIPS ) GetNextNode(temp2);                                     
6016     
6017    //    Error checking
6018    if (!(member(id[0],a,b,c)) || !(member(id[1],a,b,c)) || !(member(vertex2,a,b,c)))
6019    {
6020                // If we used partial we might have a break in the middle of a strip
6021                fprintf(output,"\nt");
6022        startnewstrip = 1;
6023                mi_vector_tipo nada;
6024                mi_vector.push_back(nada);
6025                num_tiras++;
6026        // Find the vertex in the first triangle that is not in the second
6027        vertex1 = Different(a,b,c,temp1->face_id,temp2->face_id,temp3->face_id,&other1,&other2);
6028        // Find the vertex in the second triangle that is not in the first
6029        vertex2 = Different(temp1->face_id,temp2->face_id,temp3->face_id, a,b,c,&other1,&other2);
6030         
6031        id[index] = vertex1; index = !index;
6032        id[index] = other1; index = !index;
6033        id[index] = other2; index = !index;
6034        }
6035     
6036    if ((temp1 == NULL ) || (temp2 == NULL) || (temp3 == NULL))
6037    {
6038                printf("There is an error in the triangle list \n");
6039        exit(0);
6040    }
6041     
6042    if ((id[0] == id[1]) || (id[0] == vertex2))
6043        continue;
6044     
6045    if ((member(id[index],temp1->face_id,temp2->face_id,temp3->face_id)))
6046    {
6047                if ((text) && ( vt[id[index]]==0))
6048                        cptexture = FALSE;
6049        if ((!norm) && (!cptexture))
6050                {
6051            fprintf(output," %d",id[index]+1);
6052                        mi_vector[num_tiras].push_back(id[index]);
6053                }
6054        else if ((norm) && (!cptexture))
6055            fprintf(output," %d//%d",id[index]+1,vn[id[index]]+1);
6056        else if ((!norm) && (cptexture))
6057            fprintf(output," %d/%d",id[index]+1,vt[id[index]]+1);
6058        else
6059            fprintf(output," %d/%d/%d", id[index]+1,vt[id[index]]+1,vn[id[index]]+1);
6060
6061        index = !index;
6062        *swap = *swap + 1;
6063        }
6064     
6065    if ((text) && ( vt[vertex2]==0))
6066                cptexture = FALSE;
6067    if ((!norm) && (!cptexture))
6068        {
6069        fprintf(output,"\nq %d",vertex2+1);
6070                mi_vector[num_tiras].push_back(vertex2);
6071        }
6072    else if ((norm) && (!cptexture))
6073        fprintf(output,"\nq %d//%d",vertex2+1,vn[vertex2]+1);
6074    else if ((!norm) && (cptexture))
6075        fprintf(output,"\nq %d/%d",vertex2+1,vt[vertex2]+1);
6076    else
6077        fprintf(output,"\nq %d/%d/%d",vertex2+1,vt[vertex2]+1,vn[vertex2]+1);
6078     
6079    id[index] = vertex2; index = !index;
6080     
6081    //    Get the next vertex not in common
6082                vertex2 =       Different(temp1->face_id,temp2->face_id,temp3->face_id, a,b,c,&other1,&other2);
6083                a                               =       temp1->face_id;
6084                b                               =       temp2->face_id;
6085                c                               =       temp3->face_id;
6086  }
6087  //   Do the last vertex
6088  if ((text) && (vt[vertex2]==0))
6089  {
6090        if (cptexture)
6091                fprintf(output,"\nq");
6092    cptexture = FALSE;
6093  }
6094
6095  if ((!norm) && (!cptexture))
6096  {
6097    fprintf(output," %d",vertex2+1);
6098        mi_vector[num_tiras].push_back(vertex2);
6099  }
6100  else if ((norm) && (!cptexture))
6101    fprintf(output," %d//%d",vertex2+1,vn[vertex2]+1);
6102  else if ((!norm) && (cptexture))
6103    fprintf(output," %d/%d",vertex2+1,vt[vertex2]+1);
6104  else
6105    fprintf(output," %d/%d/%d",vertex2+1,vt[vertex2]+1,vn[vertex2]+1);
6106 
6107  Free_Strips();
6108  return (num/3);       
6109}
6110
6111///     Output_Tri:
6112void CustomStripifier::Output_Tri(int id1, int id2, int id3,BOOL end)
6113{
6114  /*   We will save everything into a list, rather than output at once,
6115       as was done in the old routine. This way for future modifications
6116       we can change the strips later on if we want to.
6117  */
6118 
6119  int temp1,temp2,temp3;
6120 
6121  /*  Make sure we do not have an error */
6122  /*    There are degeneracies in some of the files */
6123  if ( (id1 == id2) || (id1 == id3) || (id2 == id3))
6124    {
6125      printf("Degenerate triangle %d %d %d\n",id1,id2,id3);
6126      exit(0);
6127    }
6128  else
6129    {
6130      Last_Edge(&temp1,&temp2,&temp3,0);
6131      Add_Id_Strips(id1,end);
6132      Add_Id_Strips(id2,end);
6133      Add_Id_Strips(id3,end);
6134      Last_Edge(&id1,&id2,&id3,1);
6135    }
6136}
6137
6138///     Polygon_Output:
6139int CustomStripifier::Polygon_Output(   P_ADJACENCIES temp,     int face_id,
6140                                                                                                                                                        int bucket,                             ListHead *pListHead,
6141                                                                                                                                                        BOOL first,                             int *swaps,
6142                                                                                                                                                FILE *bands,                            int color1,
6143                                                                                                                                                        int color2,                                     int color3,
6144                                                                                                                                                        BOOL global,                    BOOL end)
6145{
6146  ListHead *pListFace;
6147  PF_FACES face;
6148  int next_face_id,next_bucket,e1,e2,e3,other1,other2,other3;
6149  P_ADJACENCIES lpListInfo;
6150  int ties=0;
6151 
6152  /* We have a polygon to output, the id is face id, and the number
6153     of adjacent polygons to it is bucket. This routine extends the patches from
6154     either end to make longer triangle strips.
6155  */
6156 
6157 
6158  /*  Now get the edge */
6159  Last_Edge(&e1,&e2,&e3,0);
6160 
6161  /*  Get the polygon with id face_id */
6162  pListFace  = PolFaces[face_id];
6163  face = (PF_FACES) PeekList(pListFace,LISTHEAD,0);
6164 
6165  /*  We can't go any more */
6166  if ((face->nPolSize == 1) || ((face->nPolSize == 4) && (global)))
6167    /* if global, then we are still doing patches */
6168    {
6169      /*     Remove it from the list so we do not have to waste
6170             time visiting it in the future, or winding up in an infinite loop
6171             if it is the first on that we are looking at for a possible strip
6172      */
6173      if (face->nPolSize == 1) {
6174        if (face_array[temp->face_id].head == pListHead)
6175          face_array[temp->face_id].pfNode = NULL;
6176        RemoveList(pListHead,(PLISTINFO) temp);
6177      }
6178      if (first)
6179        return 0;
6180      else
6181        return (Finished(swaps,bands,0));
6182    }
6183 
6184  if (face->nPolSize == 3)
6185    {
6186      /*      It is already a triangle */
6187      if (bucket == 0)
6188        {
6189          /*      It is not adjacent to anything so we do not have to
6190                  worry about the order of the sides or updating adjacencies
6191          */
6192         
6193          next_face_id = Different(*(face->pPolygon),*(face->pPolygon+1),
6194                                   *(face->pPolygon+2),
6195                                   e1,e2,e3,&other1,&other2); 
6196          face->nPolSize = 1;
6197         
6198          /* If this is the first triangle in the strip */
6199          if ((e2 == 0) && (e3 ==0))
6200            {
6201              e2 = other1;
6202              e3 = other2;
6203            }
6204         
6205          Output_Tri(e2,e3,next_face_id,end);
6206          if (face_array[temp->face_id].head == pListHead)
6207            face_array[temp->face_id].pfNode = NULL;
6208          RemoveList(pListHead,(PLISTINFO) temp);
6209          return (Finished(swaps,bands,0));
6210        }
6211     
6212     
6213      /*  It is a triangle with adjacencies. This means that we
6214          have to:
6215          1. Update the adjacencies in the list, because we are
6216          using this polygon and it will be deleted.
6217          2. Get the next polygon.
6218      */
6219      else
6220        {
6221          /*   Return the face_id of the next polygon we will be using,
6222               while updating the adjacency list by decrementing the
6223               adjacencies of everything adjacent to the current triangle.
6224          */
6225         
6226          next_face_id = Update_Adjacencies(face_id, &next_bucket, &e1,&e2,&ties);
6227          /*  Maybe we deleted something in a patch and could not
6228              find an adj polygon */
6229          if (next_face_id == -1)
6230            {
6231              Output_Tri(*(face->pPolygon),*(face->pPolygon+1),
6232                         *(face->pPolygon+2),end);
6233              face->nPolSize = 1;
6234              if (face_array[temp->face_id].head == pListHead)
6235                face_array[temp->face_id].pfNode = NULL;
6236              RemoveList(pListHead,(PLISTINFO) temp);
6237              return (Finished(swaps,bands,0));
6238            }
6239         
6240         
6241          /*      Find the other vertex to transmit in the triangle */
6242          e3 = Return_Other(face->pPolygon,e1,e2);
6243          Last_Edge(&other1,&other2,&other3,0);
6244         
6245          if ((other2 != 0) && (other3 != 0))
6246            {
6247              /*   See which vertex in the output edge is not in the input edge */
6248              if ((e1 != other2) && (e1 != other3))
6249                e3 = e1;
6250              else if ((e2 != other2) && (e2 != other3))
6251                e3 = e2;
6252              else
6253                {
6254                  printf("There is an error in the tri with adj\n");
6255                  exit(0);
6256                }
6257             
6258              /*   See which vertex of the input edge is not in the output edge */
6259              if ((other2 != e1) && (other2 != e2))
6260                {
6261                  other1 = other2;
6262                  other2 = other3;
6263                }
6264              else if ((other3 != e1) && (other3 != e2))
6265                other1 = other3;
6266              else
6267                {
6268                  printf("There is an error in getting the tri with adj\n");
6269                  exit(0);
6270                }
6271             
6272            }
6273          else
6274            {
6275              /*     We are the first triangle in the strip and the starting edge
6276                     has not been set yet
6277              */
6278              /*  Maybe we deleted something in a patch and could not
6279                  find an adj polygon */
6280              if (next_face_id == -1)
6281                {
6282                  Output_Tri(*(face->pPolygon),*(face->pPolygon+1),
6283                             *(face->pPolygon+2),end);
6284                  face->nPolSize = 1;
6285                  face_array[temp->face_id].pfNode = NULL;
6286                  RemoveList(pListHead,(PLISTINFO) temp);
6287                  return (Finished(swaps,bands,0));
6288                }
6289             
6290              other1 = e3;
6291              e3 = e2;
6292              other2 = e1;
6293            }
6294         
6295          /*   At this point the adjacencies have been updated  and we
6296               have the next polygon id
6297          */
6298         
6299          Output_Tri(other1,other2,e3,end);
6300          face->nPolSize = 1;
6301          if (face_array[temp->face_id].head == pListHead)
6302            face_array[temp->face_id].pfNode = NULL;
6303          RemoveList(pListHead,(PLISTINFO) temp);
6304         
6305          /*  Maybe we deleted something in a patch and could not
6306              find an adj polygon */
6307          if (next_face_id == -1)
6308            return (Finished(swaps,bands,0));
6309         
6310          if (Done(next_face_id,&next_bucket) == NULL)
6311            {
6312              printf("We deleted the next face 4%d\n",next_face_id);
6313              exit(0);
6314            }
6315         
6316          pListHead = array[next_bucket];
6317          lpListInfo = face_array[next_face_id].pfNode;
6318          if (lpListInfo == NULL)
6319            {
6320              printf("There is an error finding the next polygon3 %d\n",
6321                     next_face_id);
6322              exit(0);
6323            }
6324          return (Polygon_Output(lpListInfo,next_face_id,next_bucket,
6325                                 pListHead, FALSE, swaps,bands,
6326                                 color1,color2,color3,global,end));
6327         
6328        }
6329    }
6330 
6331  else
6332    {
6333      /*   It is not a triangle, we have to triangulate it .
6334           Since it is not adjacent to anything we can triangulate it
6335           blindly
6336      */
6337      if (bucket == 0)
6338        {
6339          /*   It is the first polygon in the strip, therefore there is no
6340               input edge to start with.
6341          */
6342          if ((e2 == 0) && (e3 ==0))
6343            Blind_Triangulate(face->nPolSize,face->pPolygon,TRUE,1);
6344         
6345          else
6346            Blind_Triangulate(face->nPolSize,face->pPolygon,FALSE,1);
6347         
6348          if (face_array[temp->face_id].head == pListHead)
6349            face_array[temp->face_id].pfNode = NULL;
6350          RemoveList(pListHead,(PLISTINFO) temp);
6351         
6352          /*      We will be at the beginning of the next strip. */
6353          face->nPolSize = 1;
6354          return (Finished(swaps,bands,0));
6355        }
6356     
6357     
6358      else
6359        {
6360         
6361         
6362          /*  WHOLE triangulation */
6363          /*  It is not a triangle and has adjacencies.
6364              This means that we have to:
6365              1. Triangulate this polygon, not blindly because
6366              we have an edge that we want to come out on, that
6367              is the edge that is adjacent to a polygon with the
6368              least number of adjacencies. Also we must come in
6369              on the last seen edge.
6370              2. Update the adjacencies in the list, because we are
6371              using this polygon .
6372              3. Get the next polygon.
6373          */
6374          /*      Return the face_id of the next polygon we will be using,
6375                  while updating the adjacency list by decrementing the
6376                  adjacencies of everything adjacent to the current polygon.
6377          */
6378         
6379          next_face_id = Update_Adjacencies(face_id, &next_bucket, &e1,&e2,&ties);
6380         
6381          /*  Maybe we deleted something in a patch and could not
6382              find an adj polygon */
6383          if (next_face_id == -1)
6384            {
6385             
6386              /*   If we are at the first polygon in the strip and
6387                   there is no input
6388                   edge, then begin is TRUE
6389              */
6390              if ((e2 == 0) && (e3 == 0))
6391                Blind_Triangulate(face->nPolSize,face->pPolygon,TRUE,1);
6392             
6393              else
6394                Blind_Triangulate(face->nPolSize,face->pPolygon,FALSE,1);
6395             
6396              if (face_array[temp->face_id].head == pListHead)
6397                face_array[temp->face_id].pfNode = NULL;
6398              RemoveList(pListHead,(PLISTINFO) temp);
6399             
6400              /*      We will be at the beginning of the next strip. */
6401              face->nPolSize = 1;
6402              return (Finished(swaps,bands,0));
6403            }
6404         
6405          if (Done(next_face_id,&next_bucket) == NULL)
6406            {
6407              printf("We deleted the next face 6 %d %d\n",next_face_id,face_id);
6408              exit(0);
6409            }
6410         
6411          Non_Blind_Triangulate(face->nPolSize,face->pPolygon,
6412                                bands,next_face_id,face_id,1,
6413                                color1,color2,color3);
6414         
6415          if (face_array[temp->face_id].head == pListHead)       
6416            face_array[temp->face_id].pfNode = NULL;
6417          RemoveList(pListHead,(PLISTINFO) temp);
6418          face->nPolSize = 1;
6419          pListHead = array[next_bucket];
6420          lpListInfo = face_array[next_face_id].pfNode;
6421         
6422          if (lpListInfo == NULL)
6423            {
6424              printf("There is an error finding the next polygon2 %d %d\n",
6425                     next_face_id,next_bucket);
6426              exit(0);
6427            }
6428          return (Polygon_Output(lpListInfo,next_face_id,next_bucket,
6429                                 pListHead, FALSE, swaps,bands,
6430                                 color1,color2,color3,global,end));
6431        }
6432     
6433    }
6434}       
6435
6436///     Extend_Face:
6437int CustomStripifier::Extend_Face(int           face_id,
6438                                                                                                                                        int             e1,
6439                                                                                                                                        int             e2,
6440                                                                                                                                        int             *swaps,
6441                                                                                                                                        FILE    *bands,
6442                                                                                                                                        int             color1,
6443                                                                                                                                        int             color2,
6444                                                                                                                                        int             color3,
6445                                                                                                                                        int             *vert_norm,
6446                                                                                                                                        int             normals,
6447                                                                                                                                        int             *vert_texture,
6448                                                                                                                                        int             texture)
6449{
6450  int                                           dummy   =       0;
6451        int                                             next_bucket;
6452  P_ADJACENCIES lpListInfo;   
6453  ListHead                      *pListHead;
6454 
6455  /*    Try to extend backwards off of the local strip that we just found */
6456 
6457  vn = vert_norm;
6458  vt = vert_texture;
6459  norm = normals;
6460  text = texture;
6461 
6462  *swaps = 0;
6463  /*    Find the face that is adjacent to the edge and is not the
6464        current face.
6465  */
6466  face_id = Find_Face(face_id, e1, e2,&next_bucket);
6467  if (face_id == -1)
6468    return 0;
6469 
6470  pListHead = array[next_bucket];
6471  lpListInfo = face_array[face_id].pfNode;
6472 
6473  if (lpListInfo == NULL)
6474    {
6475      printf("There is an error finding the next polygon3 %d\n",face_id);
6476      exit(0);
6477    }
6478  Last_Edge(&dummy,&e1,&e2,1);
6479 
6480  /*  Find a strip extending from the patch and return the cost */
6481  return (Polygon_Output(lpListInfo,face_id,next_bucket,pListHead,TRUE,swaps,
6482                         bands,color1,color2,color3,TRUE,TRUE));
6483}
6484
6485///     ParseAndFreeList:
6486void CustomStripifier::ParseAndFreeList( ListHead *pListHead )
6487{
6488  PLISTINFO                     value;
6489  register      int     c;
6490        register        int     num;
6491 
6492  /*    Freeing a linked list */
6493  num   =       NumOnList(pListHead);
6494
6495  for (c = 0; c< num; c++)
6496        {
6497    value =   RemHead(pListHead);
6498        }
6499}
6500
6501///     Free_Strips:
6502void CustomStripifier::Free_Strips()
6503{
6504  /*    Free strips data structure */
6505  if (strips[0] == NULL)
6506    return;
6507  else
6508    ParseAndFreeList(strips[0]);
6509}
6510
6511///     FreeFaceTable:
6512void CustomStripifier::FreeFaceTable(int nSize)
6513{
6514  register int nIndex;
6515 
6516  for ( nIndex=0; nIndex < nSize; nIndex++ )
6517    {
6518      if ( PolFaces[nIndex] != NULL )
6519        ParseAndFreeList( PolFaces[nIndex] );
6520    }
6521  free( PolFaces );
6522}
6523
6524///     FreeEdgeTable:
6525void CustomStripifier::FreeEdgeTable(int nSize)
6526{
6527  register int nIndex;
6528 
6529  for ( nIndex=0; nIndex < nSize; nIndex++ )
6530    {
6531      if ( PolEdges[nIndex] != NULL )
6532        ParseAndFreeList( PolEdges[nIndex] );
6533    }
6534  free( PolEdges );
6535}
6536
6537///     End_Face_Struct:
6538void CustomStripifier::End_Face_Struct(int numfaces)
6539{
6540  FreeFaceTable(numfaces);
6541}
6542
6543///     End_Edge_Struct:
6544void CustomStripifier::End_Edge_Struct(int numverts)
6545{
6546  FreeEdgeTable(numverts);
6547}
6548
6549///     Calculate_Walks:
6550int CustomStripifier::Calculate_Walks(int lastvert,int y, PF_FACES temp2)
6551{
6552  /* Find the length of the walk */
6553 
6554  int previous_edge1, previous_edge2;
6555  register int nextvert,numverts,counter,walk=0;
6556  BOOL flag;
6557  F_EDGES *node;
6558  ListHead *pListHead;
6559  static int seen = 0;
6560 
6561  /* Find the edge that we are currently on */
6562  if (y != 3)
6563    {
6564      previous_edge1 = *(temp2->pPolygon +y);
6565      previous_edge2 = *(temp2->pPolygon + y + 1);
6566    }
6567  else
6568    {
6569      previous_edge1 = *(temp2->pPolygon +y);
6570      previous_edge2 = *(temp2->pPolygon);
6571    }
6572 
6573  temp2->seen = seen;
6574  counter = y;
6575 
6576  /*Find the adjacent face to this edge */
6577  node = *(temp2->VertandId+y);                 
6578  if (node->edge[2] != lastvert)
6579    nextvert = node->edge[2];
6580  else
6581    nextvert = node->edge[1];
6582 
6583  /* Keep walking in this direction until we cannot do so */
6584  while ((nextvert != lastvert) && (nextvert != -1))
6585    {
6586      walk++;
6587      pListHead = PolFaces[nextvert];
6588      temp2 = (PF_FACES) PeekList(pListHead,LISTHEAD,0);
6589      numverts = temp2->nPolSize;
6590      if ((numverts != 4) || (temp2->seen == seen))
6591        {
6592          walk--;
6593          nextvert = -1;
6594        }
6595      else
6596        {
6597          temp2->seen = seen;
6598          /* Find edge that is not adjacent to the previous one */
6599          counter = 0;
6600          flag = TRUE;
6601          while ((counter < 3) && (flag))
6602            {
6603              if ( ((*(temp2->pPolygon+counter) == previous_edge1) ||
6604                    (*(temp2->pPolygon+counter+1) == previous_edge2)) ||
6605                   ((*(temp2->pPolygon+counter) == previous_edge2) ||
6606                    (*(temp2->pPolygon+counter+1) == previous_edge1)) )
6607                counter++;             
6608              else
6609                flag = FALSE;   
6610            }
6611          /* Get the IDs of the next edge */
6612          if (counter < 3)
6613            {
6614              previous_edge1 = *(temp2->pPolygon + counter);
6615              previous_edge2 = *(temp2->pPolygon + counter + 1);
6616            }
6617          else
6618            {
6619              previous_edge1 = *(temp2->pPolygon + counter);
6620              previous_edge2 = *(temp2->pPolygon);
6621            }
6622         
6623          node = *(temp2->VertandId + counter);
6624          if (node->edge[1] == nextvert)
6625            nextvert = node->edge[2];
6626          else
6627            nextvert = node->edge[1];
6628        }
6629    }
6630  seen++;
6631  return walk;
6632}
6633
6634///     Check_Right:
6635BOOL CustomStripifier::Check_Right(     int last_seen,PF_FACES temp2,
6636                                                                                                                                                int y,int face_id)
6637{
6638  /* Check when we last saw the face to the right of the current
6639     one. We want to have seen it just before we started this strip
6640  */
6641 
6642  F_EDGES *node;
6643  ListHead *pListHead;
6644  register int nextvert,oldy;
6645  PF_FACES t;
6646 
6647  oldy = y;
6648  if (y != 3)
6649    y = y+1;
6650  else
6651    y = 0;
6652  node = *(temp2->VertandId + y);
6653  if (face_id == node->edge[1])
6654    nextvert = node->edge[2];
6655  else
6656    nextvert = node->edge[1];
6657 
6658  if (nextvert == -1)
6659    return FALSE;
6660 
6661  pListHead = PolFaces[nextvert];
6662  t = (PF_FACES) PeekList(pListHead,LISTHEAD,0);
6663  if (t->seen != (last_seen - 1))
6664    {
6665      /* maybe because of the numbering, we are not
6666         on the right orientation, so we have to check the
6667         opposite one to be sure
6668      */
6669      if (oldy != 0)
6670        y = oldy-1;
6671      else
6672        y = 3;
6673      node = *(temp2->VertandId + y);
6674      if (face_id == node->edge[1])
6675        nextvert = node->edge[2];
6676      else
6677        nextvert = node->edge[1];
6678      if (nextvert == -1)
6679        return FALSE;
6680      pListHead = PolFaces[nextvert];
6681      t = (PF_FACES) PeekList(pListHead,LISTHEAD,0);
6682      if (t->seen != (last_seen - 1))
6683        return FALSE;
6684    }
6685  return TRUE;
6686}
6687
6688///     Update_and_Test:
6689int CustomStripifier::Update_and_Test(PF_FACES temp2,int y,
6690                                                                                                                                                        BOOL first,int distance,
6691                                                                                                                                                int lastvert, int val)
6692{
6693 
6694  static int last_seen = 17;
6695  int previous_edge1, previous_edge2;
6696  register int original_distance,nextvert,numverts,counter;
6697  BOOL flag;
6698  F_EDGES *node;
6699  ListHead *pListHead;
6700 
6701  original_distance = distance;
6702  /* Find the edge that we are currently on */
6703  if (y != 3)
6704    {
6705      previous_edge1 = *(temp2->pPolygon +y);
6706      previous_edge2 = *(temp2->pPolygon + y + 1);
6707    }
6708  else
6709    {
6710      previous_edge1 = *(temp2->pPolygon +y);
6711      previous_edge2 = *(temp2->pPolygon);
6712    }
6713 
6714  temp2->seen = val;
6715  temp2->seen2 = val;
6716 
6717  node = *(temp2->VertandId+y);                   
6718  if (lastvert != node->edge[2])
6719    nextvert = node->edge[2];
6720  else
6721    nextvert = node->edge[1];
6722 
6723  /* Keep walking in this direction until we cannot do so  or
6724     we go to distance */
6725  while ((distance > 0)  && (nextvert != lastvert) && (nextvert != -1))
6726    {
6727      distance--;
6728     
6729      pListHead = PolFaces[nextvert];
6730      temp2 = (PF_FACES) PeekList(pListHead,LISTHEAD,0);
6731      temp2->seen = val;
6732     
6733      if (temp2->seen2 == val)
6734        {
6735          last_seen++;
6736          return (original_distance - distance);
6737        }
6738     
6739      temp2->seen2 = val;
6740     
6741      numverts = temp2->nPolSize;
6742     
6743      if (numverts != 4)
6744        nextvert = -1;
6745     
6746      else if ((!first) && (!(Check_Right(last_seen,temp2,y,nextvert))))
6747        {
6748          last_seen++;
6749          return (original_distance - distance);
6750        }
6751      else
6752        {
6753          /* Find edge that is not adjacent to the previous one */
6754          counter = 0;
6755          flag = TRUE;
6756          while ((counter < 3) && (flag))
6757            {
6758              if ( ((*(temp2->pPolygon+counter) == previous_edge1) ||
6759                    (*(temp2->pPolygon+counter+1) == previous_edge2)) ||
6760                   ((*(temp2->pPolygon+counter) == previous_edge2) ||
6761                    (*(temp2->pPolygon+counter+1) == previous_edge1)) )
6762                counter++;
6763              else
6764                flag = FALSE;
6765            }
6766          /* Get the IDs of the next edge */
6767          if (counter < 3)
6768            {
6769              previous_edge1 = *(temp2->pPolygon + counter);
6770              previous_edge2 = *(temp2->pPolygon + counter + 1);
6771            }
6772          else
6773            {
6774              previous_edge1 = *(temp2->pPolygon + counter);
6775              previous_edge2 = *(temp2->pPolygon);
6776            }
6777          if      ( ((*(temp2->walked+counter) == -1) &&
6778                     (*(temp2->walked+counter+2) == -1)))
6779            {
6780              printf("There is an error in the walks!\n");
6781              printf("1Code %d %d \n",*(temp2->walked+counter),
6782                     *(temp2->walked+counter+2));
6783              exit(0);
6784            }
6785          else
6786            {
6787              if      ((*(temp2->walked+counter) == -1) &&
6788                       (*(temp2->walked+counter-2) ==  -1))
6789                {
6790                  printf("There is an error in the walks!\n");
6791                  printf("2Code %d %d \n",*(temp2->walked+counter),
6792                         *(temp2->walked+counter-2));
6793                  exit(0);
6794                }
6795            }
6796          node = *(temp2->VertandId + counter);
6797          y = counter;
6798          if (node->edge[1] == nextvert)
6799            nextvert = node->edge[2];
6800          else
6801            nextvert = node->edge[1];
6802        }
6803    }
6804 
6805  last_seen++;
6806 
6807  if  (distance != 0) 
6808    {
6809      if (((nextvert == -1) || (nextvert == lastvert)) && (distance != 1))
6810        return (original_distance - distance);
6811    }
6812  return original_distance;
6813}
6814
6815///     Test_Adj:
6816int CustomStripifier::Test_Adj(PF_FACES temp2,int x,int north,int distance,int lastvert, int value)
6817{
6818  /* if first time, then just update the last seen field */
6819  if (x==1)
6820    return(Update_and_Test(temp2,north,TRUE,distance,lastvert,value));
6821  /* else we have to check if we are adjacent to the last strip */
6822  else
6823    return(Update_and_Test(temp2,north,FALSE,distance,lastvert,value));
6824}
6825
6826///     Find_Max:
6827int CustomStripifier::Find_Max( PF_FACES temp2, int lastvert,
6828                                                                                                                                int north,                      int left,
6829                                                                                                                int *lastminup, int *lastminleft)
6830{
6831  int temp,walk,counter,minup,x,band_value;
6832  int previous_edge1, previous_edge2;
6833  F_EDGES       *node;
6834  ListHead *pListHead;
6835  BOOL flag;   
6836  static int last_seen = 0;
6837  register int smallest_so_far,nextvert,max=-1;         
6838 
6839  *lastminup = MAX_BAND;
6840  *lastminleft = 1;
6841 
6842  if (left == 3)
6843    {
6844      previous_edge1 = *(temp2->pPolygon + left);
6845      previous_edge2 = *(temp2->pPolygon);
6846    }
6847 
6848  else
6849    {
6850      previous_edge1 = *(temp2->pPolygon + left + 1);
6851      previous_edge2 = *(temp2->pPolygon + left);
6852    }
6853 
6854  temp2->seen = last_seen;
6855  walk = *(temp2->walked + left);
6856 
6857  for (x=1;x<=(walk+1); x++)
6858    {
6859      /*   test to see if we have a true band
6860           that is, are they adjacent to each other
6861      */
6862     
6863      minup = *(temp2->walked + north) + 1;
6864     
6865      /*        if we are at the very first face, then we do not
6866                have to check the adjacent faces going up
6867                and our north distance is the distance of this face's
6868                north direction.
6869      */
6870      if (x == 1)
6871        {
6872          *lastminup = minup;
6873          minup = Test_Adj(temp2,x,north,*lastminup,lastvert,last_seen);
6874          *lastminup = minup;
6875          smallest_so_far = minup;     
6876        }
6877     
6878     
6879      /* find the largest band that we can have */
6880      if (minup < (*lastminup))
6881        {
6882          /*    see if we really can go up all the way
6883                temp should by less than our equal to minup
6884                if it is less, then one of the faces was not
6885                adjacent to those next to it and the band height
6886                will be smaller
6887          */
6888          temp = Test_Adj(temp2,x,north,minup,lastvert,last_seen);
6889          if (temp > minup)
6890            {
6891              printf("There is an error in the test adj\n");
6892              exit(0);
6893            }
6894          minup = temp;
6895          band_value = x * minup;
6896          if (minup < smallest_so_far)
6897            {
6898              if (band_value > max)
6899                {
6900                  smallest_so_far = minup;
6901                  *lastminup = minup;
6902                  *lastminleft = x;
6903                  max = band_value;
6904                }
6905              else
6906                smallest_so_far = minup;
6907            }
6908          else
6909            {
6910              band_value = x * smallest_so_far;
6911              if (band_value > max)
6912                {
6913                  *lastminup = smallest_so_far;
6914                  *lastminleft = x;
6915                  max = band_value;
6916                }
6917            }
6918        }
6919      else
6920        {
6921          if (x != 1)
6922            {
6923              temp = Test_Adj(temp2,x,north,smallest_so_far,lastvert,last_seen);
6924              if (temp > smallest_so_far)
6925                {
6926                  printf("There is an error in the test adj\n");
6927                  exit(0);
6928                }
6929              smallest_so_far = temp;
6930            }
6931          band_value = x * smallest_so_far;
6932          if (band_value > max)
6933            {
6934              *lastminup = smallest_so_far;
6935              *lastminleft = x;
6936              max = band_value;
6937            }
6938        }
6939      if ( x != (walk + 1))
6940        {
6941          node = *(temp2->VertandId+left);
6942          if (lastvert == node->edge[1])
6943            nextvert = node->edge[2];
6944          else
6945            nextvert = node->edge[1];
6946         
6947          lastvert = nextvert;
6948         
6949          if (nextvert == -1)
6950            return max;
6951         
6952          pListHead = PolFaces[nextvert];
6953          temp2 = (PF_FACES) PeekList(pListHead, LISTHEAD, 0);
6954         
6955          /* if we have visited this face before, then there is an error */
6956          if (((*(temp2->walked) == -1) && (*(temp2->walked+1) == -1) &&
6957               (*(temp2->walked+2) == -1) && (*(temp2->walked+3) == -1))
6958              || (temp2->nPolSize !=4) || (temp2->seen == last_seen))
6959            {
6960             
6961              if (lastvert == node->edge[1])
6962                nextvert = node->edge[2];
6963              else
6964                nextvert = node->edge[1];
6965              if (nextvert == -1)
6966                return max;
6967              lastvert = nextvert;
6968              /*   Last attempt to get the face ... */
6969              pListHead = PolFaces[nextvert];
6970              temp2 = (PF_FACES) PeekList(pListHead, LISTHEAD, 0);
6971              if (((*(temp2->walked) == -1) && (*(temp2->walked+1) == -1) &&
6972                   (*(temp2->walked+2) == -1) && (*(temp2->walked+3) == -1))
6973                  || (temp2->nPolSize !=4) || (temp2->seen == last_seen))
6974                return max;    /*   The polygon was not saved with the edge, not
6975                                    enough room. We will get the walk when we come
6976                                    to that polygon later.
6977                               */
6978            }
6979          else
6980            {
6981              counter = 0;
6982              flag = TRUE;
6983              temp2->seen = last_seen;
6984             
6985              while ((counter < 3) && (flag))
6986                {
6987                 
6988                  if ( ((*(temp2->pPolygon+counter) == previous_edge1) ||
6989                        (*(temp2->pPolygon+counter+1) == previous_edge2)) ||
6990                       ((*(temp2->pPolygon+counter) == previous_edge2) ||
6991                        (*(temp2->pPolygon+counter+1) == previous_edge1)) )
6992                    counter++;
6993                  else
6994                    flag = FALSE;
6995                }
6996            }
6997         
6998          /* Get the IDs of the next edge */
6999          left = counter;
7000          north = left+1;
7001          if (left ==3)
7002            north = 0; 
7003          if (counter < 3)
7004            {
7005              previous_edge1 = *(temp2->pPolygon + counter + 1);
7006              previous_edge2 = *(temp2->pPolygon + counter);
7007            }
7008          else
7009            {
7010              previous_edge1 = *(temp2->pPolygon + counter);
7011              previous_edge2 = *(temp2->pPolygon);
7012            }
7013         
7014        }
7015     
7016    }
7017  last_seen++;
7018  return max;
7019}
7020
7021///     Mark_Face:
7022void CustomStripifier::Mark_Face(       PF_FACES temp2,                 int color1,
7023                                                                                                                                        int color2,                     int color3,
7024                                                                                                                                        FILE *output_file,      BOOL end,
7025                                                                                                                                        int *edge1,                                     int *edge2,
7026                                                                                                                int *face_id,                           int norms,
7027                                                                                                                                        int texture)
7028{
7029  static int last_quad[4];
7030  register int x,y,z=0;
7031  int saved[2];
7032  static int output1, output2,last_id;
7033  BOOL cptexture;
7034 
7035  /*   Are we done with the patch? If so return the last edge that
7036       we will come out on, and that will be the edge that we will
7037       start to extend upon.
7038  */
7039 
7040  cptexture = texture;
7041  if (end)
7042    {
7043      *edge1 = output1;
7044      *edge2 = output2;
7045      *face_id = last_id;
7046      return;
7047    }
7048 
7049  last_id = *face_id;
7050  *(temp2->walked) = -1;
7051  *(temp2->walked+1) = -1;
7052  *(temp2->walked+2) = -1;
7053  *(temp2->walked+3) = -1;
7054  added_quad++;
7055  temp2->nPolSize = 1;
7056 
7057  if (patch == 0)
7058    {
7059      /*   At the first quad in the strip -- save it */
7060      last_quad[0] = *(temp2->pPolygon);
7061      last_quad[1] = *(temp2->pPolygon+1);
7062      last_quad[2] = *(temp2->pPolygon+2);
7063      last_quad[3] = *(temp2->pPolygon+3);
7064      patch++;
7065    }
7066  else
7067    {
7068      /*   Now we have a triangle to output, find the edge in common */
7069      for (x=0; x < 4 ;x++)
7070        {
7071          for (y=0; y< 4; y++)
7072            {
7073              if (last_quad[x] == *(temp2->pPolygon+y))
7074                {
7075                  saved[z++] = last_quad[x];               
7076                  if (z > 2)
7077                    {
7078                      /*    This means that there was a non convex or
7079                            an overlapping polygon
7080                      */
7081                      z--;
7082                      break;
7083                    }
7084                }                             
7085            }
7086        }
7087     
7088      if (z != 2)
7089        {
7090          printf("Z is not 2 %d \n",patch);
7091          printf("4 %d %d %d %d %d %d %d\n",*(temp2->pPolygon),
7092                 *(temp2->pPolygon+1),*(temp2->pPolygon+2),*(temp2->pPolygon+3),
7093                 color1,color2,color3);
7094          printf("%d %d %d %d\n",last_quad[0],last_quad[1],
7095                 last_quad[2],last_quad[3]);
7096          exit(1);
7097        }
7098     
7099      if (patch == 1)
7100        {
7101          /*   First one to output, there was no output edge */
7102          patch++;
7103          x = Adjacent(saved[0],saved[1],last_quad,4);
7104          y = Adjacent(saved[1],saved[0],last_quad,4);
7105         
7106          /*   Data might be mixed and we do not have textures
7107               for some of the vertices
7108          */
7109          if ((texture) &&
7110              (((vt[x]) == 0) ||
7111               ((vt[y])==0) ||
7112               ((vt[saved[1]])==0)))
7113            cptexture = FALSE;
7114         
7115          if ((!norms) && (!cptexture))
7116            {
7117              fprintf(output_file,"\nt");
7118              if (orient) /* If we want to preserve normal orientation */
7119                preserve_strip_orientation(output_file,x+1,y+1,saved[1]+1);
7120             
7121              fprintf(output_file," %d %d %d",x+1,y+1,saved[1]+1);
7122              fprintf(output_file," %d",saved[0]+1);
7123            }
7124          else if ((norms) && (!cptexture))
7125            {
7126              fprintf(output_file,"\nt");
7127              if (orient) /* If we want to preserve normal orientation */
7128                preserve_strip_orientation_with_normal(output_file,
7129                                                       x+1,vn[x] +1,
7130                                                       y+1,vn[y] +1,
7131                                                       saved[1]+1,vn[saved[1]]+1);
7132             
7133              fprintf(output_file," %d//%d %d//%d %d//%d",
7134                      x+1,vn[x] +1,
7135                      y+1,vn[y] +1,
7136                      saved[1]+1,vn[saved[1]]+1);
7137              fprintf(output_file," %d//%d",saved[0]+1,vn[saved[0]]+1);
7138            }
7139          else if ((cptexture) && (!norms))
7140            {
7141              fprintf(output_file,"\nt");
7142              if (orient) /* If we want to preserve normal orientation */
7143                preserve_strip_orientation_with_texture(output_file,
7144                                                        x+1,vt[x] +1,
7145                                                        y+1,vt[y] +1,
7146                                                        saved[1]+1,vt[saved[1]]+1);
7147             
7148              fprintf(output_file," %d/%d %d/%d %d/%d",
7149                      x+1,vt[x] +1,
7150                      y+1,vt[y] +1,
7151                      saved[1]+1,vt[saved[1]]+1);
7152             
7153              fprintf(output_file," %d//%d",saved[0]+1,vt[saved[0]]+1);
7154            }
7155          else
7156            {
7157              fprintf(output_file,"\nt");
7158              if (orient) /* If we want to preserve normal orientation */
7159                preserve_strip_orientation_with_texture_and_normal(output_file,
7160                                                                   x+1,vt[x]+1,vn[x] +1,
7161                                                                   y+1,vt[y]+1,vn[y] +1,
7162                                                                   saved[1]+1,vt[saved[1]]+1,vn[saved[1]]+1);
7163             
7164              fprintf(output_file," %d/%d/%d %d/%d/%d %d/%d/%d",
7165                      x+1,vt[x]+1,vn[x] +1,
7166                      y+1,vt[y]+1,vn[y] +1,
7167                      saved[1]+1,vt[saved[1]]+1,vn[saved[1]]+1);
7168             
7169              fprintf(output_file," %d/%d/%d",
7170                      saved[0]+1,vt[saved[0]]+1,vn[saved[0]]+1);
7171            }
7172         
7173          x = Adjacent(saved[0],saved[1],temp2->pPolygon,4);
7174          y = Adjacent(saved[1],saved[0],temp2->pPolygon,4);
7175         
7176          /*   Data might be mixed and we do not have textures
7177               for some of the vertices
7178          */
7179          if ((texture) && ( (vt[x] == 0) || (vt[y]==0)))
7180            {
7181              if (cptexture)
7182                fprintf(output_file,"\nq");
7183              cptexture = FALSE;
7184            }
7185          if ((!norms) && (!cptexture))
7186            {
7187              fprintf(output_file," %d",x+1);
7188              fprintf(output_file," %d",y+1);
7189            }
7190          else if ((norms) && (!cptexture))
7191            {
7192              fprintf(output_file," %d//%d",x+1,vn[x]+1);
7193              fprintf(output_file," %d//%d",y+1,vn[y]+1);
7194            }
7195          else if ((cptexture) && (!norms))
7196            {
7197              fprintf(output_file," %d/%d",x+1,vt[x]+1);
7198              fprintf(output_file," %d/%d",y+1,vt[y]+1);
7199            }
7200          else
7201            {
7202              fprintf(output_file," %d/%d/%d",x+1,vt[x]+1,vn[x]+1);
7203              fprintf(output_file," %d/%d/%d",y+1,vt[y]+1,vn[y]+1);
7204            }
7205         
7206          output1 = x;
7207          output2 = y;
7208        }
7209     
7210      else
7211        {
7212          x = Adjacent(output2,output1,temp2->pPolygon,4);
7213          y = Adjacent(output1,output2,temp2->pPolygon,4);
7214          /*   Data might be mixed and we do not have textures
7215               for some of the vertices */
7216          if ((texture) && ( ((vt[x]) == 0) || ((vt[y])==0) ))
7217            texture = FALSE;
7218         
7219          if ((!norms) && (!texture))
7220            {
7221              fprintf(output_file,"\nq %d",x+1);
7222              fprintf(output_file," %d",y+1);
7223            }
7224          else if ((norms) && (!texture))
7225            {
7226              fprintf(output_file,"\nq %d//%d",x+1,vn[x]+1);
7227              fprintf(output_file," %d//%d" ,y+1,vn[y]+1);
7228            }
7229          else if ((texture) && (!norms))
7230            {
7231              fprintf(output_file,"\nq %d/%d",x+1,vt[x]+1);
7232              fprintf(output_file," %d/%d",y+1,vt[y]+1);
7233            }
7234          else
7235            {
7236              fprintf(output_file,"\nq %d/%d/%d",x+1,vt[x]+1,vn[x]+1);
7237              fprintf(output_file," %d/%d/%d",y+1,vt[y]+1,vn[y]+1);
7238            }
7239         
7240          output1 = x;
7241          output2 = y;
7242        }
7243     
7244      last_quad[0] = *(temp2->pPolygon);
7245      last_quad[1] = *(temp2->pPolygon+1);
7246      last_quad[2] = *(temp2->pPolygon+2);
7247      last_quad[3] = *(temp2->pPolygon+3);
7248    }
7249}
7250
7251///     Assign_Walk:
7252void CustomStripifier::Assign_Walk(     int lastvert,           PF_FACES temp2,
7253                                                                                                                                                int front_walk, int y,
7254                                                                                                                                                int back_walk)
7255{
7256  /*      Go back and do the walk again, but this time save the lengths inside
7257          the data structure.
7258          y was the starting edge number for the front_walk length
7259          back_walk is the length of the walk along the opposite edge
7260  */
7261  int previous_edge1, previous_edge2;
7262  register int walk = 0,nextvert,numverts,counter;
7263  BOOL flag;
7264  F_EDGES *node;
7265  ListHead *pListHead;
7266  static int seen = 0;
7267  static BOOL first = TRUE;         
7268  BOOL wrap = FALSE, set = FALSE;             
7269 
7270 
7271  /*     In the "Fast_Reset" resetting will be true */
7272  if ((resetting) && (first))
7273    {
7274      seen = 0;
7275      first = FALSE;
7276    }
7277 
7278  seen++;
7279 
7280  /*     Had a band who could be a cycle  */
7281  if (front_walk == back_walk)
7282    wrap = TRUE;
7283 
7284  /* Find the edge that we are currently on */
7285  if (y != 3)
7286    {
7287      previous_edge1 = *(temp2->pPolygon +y);
7288      previous_edge2 = *(temp2->pPolygon + y + 1);
7289    }
7290  else
7291    {
7292      previous_edge1 = *(temp2->pPolygon +y);
7293      previous_edge2 = *(temp2->pPolygon);
7294    }
7295 
7296  /* Assign the lengths */
7297  if (y < 2)
7298    {
7299      *(temp2->walked+y) = front_walk--;
7300      *(temp2->walked+y+2) = back_walk++;
7301    }
7302  else
7303    {                           
7304      *(temp2->walked+y) = front_walk--;
7305      *(temp2->walked+y-2) = back_walk++;
7306    }
7307 
7308  /*Find the adjacent face to this edge */
7309  node = *(temp2->VertandId+y);                   
7310 
7311  if (node->edge[2] != lastvert)
7312    nextvert = node->edge[2];
7313  else
7314    nextvert = node->edge[1];
7315 
7316  temp2->seen3 = seen;
7317 
7318  /* Keep walking in this direction until we cannot do so */
7319  while ((nextvert != lastvert) && (nextvert != -1) && (front_walk >= 0))
7320    {
7321      walk++;
7322      pListHead = PolFaces[nextvert];
7323     
7324      temp2 = (PF_FACES) PeekList(pListHead,LISTHEAD,0);
7325      numverts = temp2->nPolSize;
7326      if ((numverts != 4))
7327        {
7328          nextvert = -1;
7329          /* Don't include this face in the walk */
7330          walk--;
7331        }
7332      else
7333        {
7334          /* Find edge that is not adjacent to the previous one */
7335          counter = 0;
7336          flag = TRUE;
7337          while ((counter < 3) && (flag))
7338            {
7339              if ( ((*(temp2->pPolygon+counter) == previous_edge1) ||
7340                    (*(temp2->pPolygon+counter+1) == previous_edge2)) ||
7341                   ((*(temp2->pPolygon+counter) == previous_edge2) ||
7342                    (*(temp2->pPolygon+counter+1) == previous_edge1)) )
7343                counter++;
7344              else
7345                flag = FALSE;
7346            }
7347          /* Get the IDs of the next edge */
7348          if (counter < 3)
7349            {
7350              previous_edge1 = *(temp2->pPolygon + counter);
7351              previous_edge2 = *(temp2->pPolygon + counter + 1);
7352            }
7353          else
7354            {
7355              previous_edge1 = *(temp2->pPolygon + counter);
7356              previous_edge2 = *(temp2->pPolygon);
7357            }
7358         
7359         
7360          /*      Put in the walk lengths */
7361          if (counter < 2)
7362            {
7363              if (((*(temp2->walked + counter) >= 0)
7364                   || (*(temp2->walked +counter + 2) >= 0)))
7365                {
7366                  if ((resetting == FALSE) && ((temp2->seen3) != (seen-1)))
7367                    {
7368                      /*   If there are more than 2 polygons adjacent
7369                           to an edge then we can be trying to assign more than
7370                           once. We will save the smaller one
7371                      */
7372                      temp2->seen3 = seen;
7373                      if ( (*(temp2->walked+counter) <= front_walk) &&
7374                           (*(temp2->walked+counter+2) <= back_walk) )
7375                        return;
7376                      if (*(temp2->walked+counter) > front_walk)
7377                        *(temp2->walked+counter) = front_walk--;
7378                      else
7379                        front_walk--;
7380                      if (*(temp2->walked+counter+2) > back_walk)
7381                        *(temp2->walked+counter+2) = back_walk++;
7382                      else
7383                        back_walk++;
7384                    }
7385                  else if (resetting == FALSE)
7386                    {
7387                      /* if there was a cycle then all lengths are the same */
7388                      walk--;
7389                      back_walk--;
7390                      front_walk++;
7391                      temp2->seen3 = seen;
7392                      *(temp2->walked+counter) = front_walk--;
7393                      *(temp2->walked+counter+2) = back_walk++;
7394                    }
7395                  else if (((temp2->seen3 == (seen-1))
7396                            && (wrap) && (walk == 1)) || (set))
7397                    {
7398                      /* if there was a cycle then all lengths are the same */
7399                      set = TRUE;
7400                      walk--;
7401                      back_walk--;
7402                      front_walk++;
7403                      temp2->seen3 = seen;
7404                      *(temp2->walked+counter) = front_walk--;
7405                      *(temp2->walked+counter+2) = back_walk++;
7406                    }
7407                  else
7408                    {
7409                      temp2->seen3 = seen;
7410                      *(temp2->walked+counter) = front_walk--;
7411                      *(temp2->walked+counter+2) = back_walk++;
7412                    }
7413                } /* if was > 0 */     
7414              else
7415                {
7416                  temp2->seen3 = seen;
7417                  *(temp2->walked+counter) = front_walk--;
7418                  *(temp2->walked+counter+2) = back_walk++;
7419                }
7420            }
7421         
7422          else
7423            {
7424              if (((*(temp2->walked + counter) >= 0 )
7425                   || (*(temp2->walked +counter - 2) >= 0)) )
7426                {
7427                  if ((temp2->seen3 != (seen-1))  && (resetting == FALSE))
7428                    {
7429                      /*   If there are more than 2 polygons adjacent
7430                           to an edge then we can be trying to assign more than
7431                           once. We will save the smaller one
7432                      */
7433                      temp2->seen3 = seen;
7434                      if ( (*(temp2->walked+counter) <= front_walk) &&
7435                           (*(temp2->walked+counter-2) <= back_walk) )
7436                        return;
7437                      if (*(temp2->walked+counter) > front_walk)
7438                        *(temp2->walked+counter) = front_walk--;
7439                      else
7440                        front_walk--;
7441                      if (*(temp2->walked+counter-2) > back_walk)
7442                        *(temp2->walked+counter-2) = back_walk++;
7443                      else
7444                        back_walk++;
7445                    }
7446                  else if (resetting == FALSE)
7447                    {
7448                      walk--;
7449                      back_walk--;
7450                      front_walk++;
7451                      temp2->seen3 = seen;
7452                      *(temp2->walked+counter) = front_walk--;
7453                      *(temp2->walked+counter-2) = back_walk++;
7454                    }
7455                  else if (((temp2->seen3 == (seen-1)) && (walk == 1) && (wrap))
7456                           || (set))
7457                    {
7458                      /* if there was a cycle then all lengths are the same */
7459                      set = TRUE;
7460                      walk--;
7461                      back_walk--;
7462                      front_walk++;
7463                      temp2->seen3 = seen;
7464                      *(temp2->walked+counter) = front_walk--;
7465                      *(temp2->walked+counter-2) = back_walk++;
7466                    }
7467                  else
7468                    {
7469                      temp2->seen3 = seen;
7470                      *(temp2->walked+counter) = front_walk--;
7471                      *(temp2->walked+counter-2) = back_walk++;
7472                    }
7473                }
7474              else
7475                {
7476                  temp2->seen3 = seen;
7477                  *(temp2->walked+counter) = front_walk--;
7478                  *(temp2->walked+counter-2) = back_walk++;
7479                }
7480             
7481            }
7482          if (nextvert != -1)
7483            {
7484              node = *(temp2->VertandId + counter);
7485              if (node->edge[1] == nextvert)
7486                nextvert = node->edge[2];
7487              else
7488                nextvert = node->edge[1];
7489            }
7490         
7491        }
7492    }
7493  if ((EVEN(seen)) )
7494    seen+=2;
7495}
7496
7497///     Fast_Reset:
7498void CustomStripifier::Fast_Reset(int x)
7499{
7500  register int y,numverts;
7501  register int front_walk, back_walk;
7502  ListHead *pListHead;
7503  PF_FACES temp = NULL;
7504 
7505  pListHead = PolFaces[x];
7506  temp = (PF_FACES) PeekList(pListHead,LISTHEAD,0);
7507  numverts = temp->nPolSize;
7508 
7509  front_walk = 0;
7510  back_walk = 0;         
7511  resetting = TRUE;
7512 
7513  /* we are doing this only for quads */
7514  if (numverts == 4)
7515    {
7516      /*        for each face not seen yet, do North and South together
7517                and East and West together
7518      */
7519      for (y=0;y<2;y++)
7520        {
7521          /* Check if the opposite sides were seen already */
7522          /* Find walk for the first edge */
7523          front_walk = Calculate_Walks(x,y,temp);
7524          /* Find walk in the opposite direction */
7525          back_walk = Calculate_Walks(x,y+2,temp);
7526          /*    Now put into the data structure the numbers that
7527                we have found
7528          */
7529          Assign_Walk(x,temp,front_walk,y,back_walk);
7530          Assign_Walk(x,temp,back_walk,y+2,front_walk);
7531        }
7532    }
7533  resetting = FALSE;
7534}
7535
7536///     Reset_Max:
7537void CustomStripifier::Reset_Max(       PF_FACES temp2,int face_id,
7538                                                                                                                                        int north,int last_north,
7539                                                                                                                int orientation,int last_left,
7540                                                                                                                                        FILE *output_file,int color1,
7541                                                                                                                                        int color2,int color3,
7542                                                                                                                BOOL start)
7543{
7544  int previous_edge1,previous_edge2;
7545  F_EDGES *node;
7546  ListHead *pListHead;
7547  int f,t,nextvert,counter;
7548  BOOL flag;
7549 
7550 
7551  /*   Reset walks on faces, since we just found a patch */
7552  if (orientation !=3)
7553    {
7554      previous_edge1 = *(temp2->pPolygon + orientation+1);
7555      previous_edge2 = *(temp2->pPolygon + orientation );
7556    }
7557  else
7558    {
7559      previous_edge1 = *(temp2->pPolygon + orientation );
7560      previous_edge2 = *(temp2->pPolygon);
7561    }
7562 
7563  /* only if we are going left, otherwise there will be -1 there */
7564  /*Find the adjacent face to this edge */
7565 
7566  for (t = 0; t <=3 ; t++)
7567    {
7568      node = *(temp2->VertandId+t);
7569     
7570      if (face_id == node->edge[1])
7571        f = node->edge[2];
7572      else
7573        f = node->edge[1];
7574     
7575      if (f != -1)
7576        Fast_Reset(f);
7577    }
7578 
7579  node = *(temp2->VertandId+orientation);
7580  if (face_id == node->edge[1])
7581    nextvert = node->edge[2];
7582  else
7583    nextvert = node->edge[1];
7584 
7585  while ((last_left--) > 1)
7586    {
7587     
7588      if (start)
7589        Reset_Max(temp2,face_id,orientation,last_left,north,last_north,
7590                  output_file,color1,color2,color3,FALSE);             
7591     
7592      face_id = nextvert;
7593      pListHead = PolFaces[nextvert];               
7594      temp2 = (PF_FACES) PeekList(pListHead,LISTHEAD,0);
7595      if ((temp2->nPolSize != 4) && (temp2->nPolSize != 1))
7596        {
7597          /*   There is more than 2 polygons on the edge, and we could have
7598               gotten the wrong one
7599          */
7600          if (nextvert != node->edge[1])
7601            nextvert = node->edge[1];
7602          else
7603            nextvert = node->edge[2];
7604          pListHead = PolFaces[nextvert];         
7605          temp2 = (PF_FACES) PeekList(pListHead,LISTHEAD,0);
7606          node = *(temp2->VertandId+orientation);
7607        }
7608     
7609     
7610      if (!start)
7611        {
7612          for (t = 0; t <=3 ; t++)
7613            {
7614              node = *(temp2->VertandId+t);
7615             
7616              if (face_id == node->edge[1])
7617                f = node->edge[2];
7618              else
7619                f = node->edge[1];
7620             
7621              if (f != -1)
7622                Fast_Reset(f);
7623            }
7624        }
7625     
7626     
7627      counter = 0;
7628      flag = TRUE;
7629      while ((counter < 3) && (flag))
7630        {
7631          if ( ((*(temp2->pPolygon+counter) == previous_edge1) ||
7632                (*(temp2->pPolygon+counter+1) == previous_edge2)) ||
7633               ((*(temp2->pPolygon+counter) == previous_edge2) ||
7634                (*(temp2->pPolygon+counter+1) == previous_edge1)) )
7635            counter++;
7636          else
7637            flag = FALSE;
7638        }
7639     
7640      /* Get the IDs of the next edge */
7641      if (counter < 3)
7642        {
7643          previous_edge1 = *(temp2->pPolygon + counter+1);
7644          previous_edge2 = *(temp2->pPolygon + counter);
7645        }
7646      else
7647        {
7648          previous_edge1 = *(temp2->pPolygon + counter);
7649          previous_edge2 = *(temp2->pPolygon);
7650        }
7651      orientation = counter;
7652     
7653      node = *(temp2->VertandId + counter);
7654      if (node->edge[1] == nextvert)
7655        nextvert = node->edge[2];
7656      else
7657        nextvert = node->edge[1];
7658     
7659      if (!reversed)
7660        {
7661          if (counter != 3)
7662            north = counter +1;
7663          else
7664            north = 0;
7665        }
7666      else
7667        {
7668          if (counter != 0)
7669            north = counter -1;
7670          else
7671            north = 3;
7672         
7673        }
7674    }
7675  if (start)
7676    Reset_Max(temp2,face_id,orientation,last_left,north,last_north,output_file,
7677              color1,color2,color3,FALSE);
7678  else if (nextvert != -1)       
7679    Fast_Reset(nextvert);
7680 
7681}
7682
7683///     Peel_Max
7684int CustomStripifier::Peel_Max( PF_FACES temp2,int face_id,
7685                                                                                                                                int north,int last_north,
7686                                                                                                                                int orientation,int last_left,
7687                                                                                                                                FILE *output_file,int color1,
7688                                                                                                                                int color2,int color3,
7689                                                                                                                BOOL start, int *swaps_added,
7690                                                                                                                                int norms, int texture)
7691{
7692  int end1,end2,last_id,s=0,walk = 0;
7693  int previous_edge1,previous_edge2;
7694  int static last_seen = 1000;
7695  F_EDGES *node;
7696  ListHead *pListHead;
7697  int nextvert,numverts,counter,dummy,tris=0;
7698  BOOL flag;
7699 
7700  /* Peel the patch from the model.
7701     We will try and extend off the end of each strip in the patch. We will return
7702     the number of triangles completed by this extension only, and the number of
7703     swaps in the extension only.
7704  */   
7705  patch = 0;
7706 
7707  if (orientation !=3)
7708    {
7709      previous_edge1 = *(temp2->pPolygon + orientation+1);
7710      previous_edge2 = *(temp2->pPolygon + orientation );
7711    }
7712  else
7713    {
7714      previous_edge1 = *(temp2->pPolygon + orientation );
7715      previous_edge2 = *(temp2->pPolygon);
7716    }
7717 
7718 
7719  walk = *(temp2->walked + orientation);
7720 
7721  /* only if we are going left, otherwise there will be -1 there */
7722  if ((start) && ((walk+1) < last_left))
7723    {
7724      printf("There is an error in the left %d %d\n",walk,last_left);
7725      exit(0);
7726    }
7727 
7728  /* Find the adjacent face to this edge */
7729  node = *(temp2->VertandId+orientation);
7730  if (face_id == node->edge[1])
7731    nextvert = node->edge[2];
7732  else
7733    nextvert = node->edge[1];
7734  temp2->seen = last_seen;
7735 
7736 
7737  while ((last_left--) > 1)
7738    {
7739      if (start)
7740        tris += Peel_Max(temp2,face_id,orientation,last_left,north,last_north,
7741                         output_file,color1,color2,color3,FALSE,swaps_added,
7742                         norms,texture);                   
7743      else
7744        Mark_Face(temp2,color1,color2,color3,output_file,FALSE,
7745                  &dummy,&dummy,&face_id,norms,texture);
7746     
7747     
7748      pListHead = PolFaces[nextvert];     
7749      temp2 = (PF_FACES) PeekList(pListHead,LISTHEAD,0);
7750      numverts = temp2->nPolSize;
7751     
7752      if ((numverts != 4) || (temp2->seen == last_seen)
7753          ||  (nextvert == -1))
7754        {
7755         
7756          /*   There is more than 2 polygons on the edge, and we could have
7757               gotten the wrong one
7758          */
7759          if (nextvert != node->edge[1])
7760            nextvert = node->edge[1];
7761          else
7762            nextvert = node->edge[2];
7763          pListHead = PolFaces[nextvert];
7764          temp2 = (PF_FACES) PeekList(pListHead,LISTHEAD,0);
7765          numverts = temp2->nPolSize;
7766          if ((numverts != 4) || (temp2->seen == last_seen) )
7767            {
7768              printf("Peel 2 %d\n",numverts);
7769              exit(1);
7770            }
7771        }
7772     
7773      face_id = nextvert;
7774      temp2->seen = last_seen;
7775     
7776      counter = 0;
7777      flag = TRUE;
7778      while ((counter < 3) && (flag))
7779        {
7780          if ( ((*(temp2->pPolygon+counter) == previous_edge1) ||
7781                (*(temp2->pPolygon+counter+1) == previous_edge2)) ||
7782               ((*(temp2->pPolygon+counter) == previous_edge2) ||
7783                (*(temp2->pPolygon+counter+1) == previous_edge1)) )
7784            counter++;
7785          else
7786            flag = FALSE;
7787        }
7788      /* Get the IDs of the next edge */
7789      if (counter < 3)
7790        {
7791          previous_edge1 = *(temp2->pPolygon + counter+1);
7792          previous_edge2 = *(temp2->pPolygon + counter);
7793        }
7794      else
7795        {
7796          previous_edge1 = *(temp2->pPolygon + counter);
7797          previous_edge2 = *(temp2->pPolygon);
7798        }
7799      orientation = counter;
7800     
7801      node = *(temp2->VertandId + counter);
7802      if (node->edge[1] == nextvert)
7803        nextvert = node->edge[2];
7804      else
7805        nextvert = node->edge[1];
7806     
7807      if (!reversed)
7808        {
7809          if (counter != 3)
7810            north = counter +1;
7811          else
7812            north = 0;
7813        }
7814      else
7815        {
7816          if (counter != 0)
7817            north = counter -1;
7818          else
7819            north = 3;
7820        }
7821    }
7822 
7823  if (start)
7824    tris += Peel_Max(temp2,face_id,orientation,last_left,north,last_north,
7825                     output_file,color1,color2,color3,FALSE,swaps_added,
7826                     norms,texture);   
7827  else
7828    Mark_Face(temp2,color1,color2,color3,output_file,FALSE,
7829              &dummy,&dummy,&face_id,norms,texture);/* do the last face */
7830 
7831  last_seen++;
7832 
7833  /*    Get the edge that we came out on the last strip of the patch */
7834  Mark_Face(NULL,0,0,0,output_file,TRUE,&end1,&end2,&last_id,norms,texture);
7835  tris += Extend_Face(last_id,end1,end2,&s,output_file,color1,color2,color3,
7836                      vn,norms,vt,texture);
7837  *swaps_added = *swaps_added + s;
7838  return tris;
7839}
7840
7841///     Find_Bands:
7842void CustomStripifier::Find_Bands(int numfaces, FILE *output_file,
7843                                                                                                                                        int *swaps,             int *bands,
7844                                                                                        int *cost,              int *tri,
7845                                                                                                                                        int norms,              int *vert_norms,
7846                                                                                                                                        int texture,    int *vert_texture)
7847{
7848 
7849  register int x,y,max1,max2,numverts,face_id,flag,maximum = 25;
7850  ListHead *pListHead;
7851  PF_FACES temp = NULL;
7852  int color1 = 0, color2 = 100, color3 = 255;
7853  int smaller;                       
7854  int north_length1,last_north,left_length1,last_left,north_length2,left_length2;
7855  int total_tri = 0, total_swaps = 0,last_id;
7856  int end1, end2,s=0;
7857  register int cutoff = 20;
7858 
7859  /*   Code that will find the patches. "Cutoff" will be
7860       the cutoff of the area of the patches that we will be allowing. After
7861       we reach this cutoff length, then we will run the local algorithm on the
7862       remaining faces.
7863  */
7864 
7865  /*    For each faces that is left find the largest possible band that we can
7866        have with the remaining faces. Note that we will only be finding patches
7867        consisting of quads.
7868  */
7869 
7870  vn = vert_norms;
7871  vt = vert_texture;
7872  y=1;
7873  *bands = 0;
7874 
7875  while ((maximum >= cutoff))
7876    {
7877      y++;
7878      maximum = -1;
7879      for (x=0; x<numfaces; x++)
7880        {
7881         
7882          /*   Used to produce the triangle strips */
7883         
7884          /* for each face, get the face */
7885          pListHead = PolFaces[x];
7886          temp = (PF_FACES) PeekList(pListHead,LISTHEAD,0);
7887          numverts = temp->nPolSize;
7888         
7889          /* we are doing this only for quads */
7890          if (numverts == 4)
7891            {
7892              /*   We want a face that is has not been used yet,
7893                   since we know that that face must be part of
7894                   a band. Then we will find the largest band that
7895                   the face may be contained in
7896              */
7897             
7898              /*  Doing the north and the left */
7899              if ((*(temp->walked) != -1) && (*(temp->walked+3) != -1))
7900                max1 = Find_Max(temp,x,0,3,&north_length1,&left_length1);
7901              if ((*(temp->walked+1) != -1) && (*(temp->walked+2) != -1))
7902                max2 = Find_Max(temp,x,2,1,&north_length2,&left_length2);
7903              if ((max1 != (north_length1 * left_length1)) ||
7904                  (max2 != (north_length2 * left_length2)))
7905                {
7906                  printf("Max1 %d, %d %d        Max2 %d, %d %d\n",
7907                         max1,north_length1,left_length1,max2,
7908                         north_length2,left_length2);
7909                  exit(0);
7910                }
7911             
7912             
7913              if ((max1 > max2) && (max1 > maximum))
7914                {
7915                  maximum = max1;
7916                  face_id = x;
7917                  flag = 1;
7918                  last_north = north_length1;
7919                  last_left = left_length1;
7920                  /* so we know we saved max1 */
7921                }
7922              else if ((max2 > maximum) )
7923                {
7924                  maximum = max2;
7925                  face_id = x;
7926                  flag = 2;
7927                  last_north = north_length2;
7928                  last_left = left_length2;
7929                  /* so we know we saved max2 */
7930                }
7931            }
7932        }
7933      if ((maximum < cutoff) && (*bands == 0))
7934        return;
7935      pListHead = PolFaces[face_id];
7936      temp = (PF_FACES) PeekList(pListHead,LISTHEAD,0);
7937      /*   There are no patches that we found in this pass */
7938      if (maximum == -1)
7939        break;
7940      /*printf("The maximum is  face %d area %d: lengths %d %d\n",face_id,maximum,last_north,last_left);*/
7941     
7942      if (last_north > last_left)
7943        {
7944          smaller = last_left;
7945        }
7946      else
7947        {
7948          smaller = last_north;
7949        }
7950     
7951     
7952      if (flag == 1)
7953        {
7954          if (last_north > last_left) /*     go north sequentially */
7955            {
7956              total_tri += Peel_Max(temp,face_id,0,last_north,3,last_left,
7957                                    output_file,color1,color2,color3,TRUE,
7958                                    &s,norms,texture);
7959              Reset_Max(temp,face_id,0,last_north,3,last_left,
7960                        output_file,color1,color2,color3,TRUE);
7961              total_swaps += s;
7962            }
7963          else
7964            {
7965              reversed = TRUE;
7966              total_tri += Peel_Max(temp,face_id,3,last_left,0,last_north,
7967                                    output_file,color1,color2,color3,TRUE,
7968                                    &s,norms,texture);
7969              Reset_Max(temp,face_id,3,last_left,0,last_north,output_file,
7970                        color1,color2,color3,TRUE);
7971              reversed = FALSE;
7972              total_swaps += s;
7973            }
7974         
7975         
7976          /*    Get the edge that we came out on the last strip of the patch */
7977          Mark_Face(NULL,0,0,0,NULL,TRUE,&end1,&end2,&last_id,norms,texture);
7978          total_tri += Extend_Face(last_id,end1,end2,&s,output_file,
7979                                   color1,color2,color3,vn,norms,vt,texture);
7980          total_swaps += s;
7981         
7982        }
7983      else
7984        {
7985          if (last_north > last_left)
7986            {
7987              total_tri += Peel_Max(temp,face_id,2,last_north,1,last_left,
7988                                    output_file,color1,color2,color3,TRUE,
7989                                    &s,norms,texture);
7990              Reset_Max(temp,face_id,2,last_north,1,last_left,output_file,
7991                        color1,color2,color3,TRUE);
7992              total_swaps += s;
7993            }
7994          else
7995            {
7996              reversed = TRUE;
7997              total_tri += Peel_Max(temp,face_id,1,last_left,2,last_north,
7998                                    output_file,color1,color2,color3,TRUE,
7999                                    &s,norms,texture);
8000              Reset_Max(temp,face_id,1,last_left,2,last_north,output_file,
8001                        color1,color2,color3,TRUE);
8002              reversed = FALSE;
8003              total_swaps += s;
8004            }
8005         
8006          /*    Get the edge that we came out on on the patch */
8007          Mark_Face(NULL,0,0,0,NULL,TRUE,&end1,&end2,&last_id,norms,texture);
8008          total_tri += Extend_Face(last_id,end1,end2,&s,output_file,
8009                                   color1,color2,color3,vn,norms,vt,texture);
8010          total_swaps += s;
8011        }
8012     
8013      /*  Now compute the cost of transmitting this band, is equal to
8014          going across the larger portion sequentially,
8015          and swapping 3 times per other dimension
8016      */
8017     
8018      total_tri += (maximum * 2);
8019      *bands = *bands + smaller;
8020     
8021    }
8022 
8023  /*printf("We transmitted %d triangles,using %d swaps and %d strips\n",total_tri,
8024    total_swaps, *bands);
8025    printf("COST %d\n",total_tri + total_swaps + *bands + *bands);*/
8026  *cost = total_tri + total_swaps + *bands + *bands;
8027  *tri = total_tri;
8028  added_quad = added_quad * 4;
8029  *swaps = total_swaps;
8030}
8031
8032///     Save_Rest:
8033void CustomStripifier::Save_Rest(int *numfaces)
8034{
8035  /*  Put the polygons that are left into a data structure so that we can run the
8036      stripping code on it.
8037  */
8038  register int x,y=0,numverts;
8039  ListHead *pListHead;
8040  PF_FACES temp=NULL;
8041 
8042  for (x=0; x<*numfaces; x++)
8043    {
8044      /* for each face, get the face */
8045      pListHead = PolFaces[x];
8046      temp = (PF_FACES) PeekList(pListHead,LISTHEAD,0);
8047      numverts = temp->nPolSize;
8048      /*  If we did not do the face before add it to data structure with new
8049          face id number
8050      */
8051      if (numverts != 1)
8052        {
8053          CopyFace(temp->pPolygon,numverts,y+1,temp->pNorms);
8054          y++;
8055        }
8056      /*   Used it, so remove it */
8057      else
8058        RemoveList(pListHead,(PLISTINFO) temp);
8059     
8060    }
8061  *numfaces = y;
8062}
8063
8064///     Save_Walks:
8065void CustomStripifier::Save_Walks(int numfaces)
8066{
8067  int x,y,numverts;
8068  int front_walk, back_walk;
8069  ListHead *pListHead;
8070  PF_FACES temp = NULL;
8071 
8072  for (x=0; x<numfaces; x++)
8073    {
8074      /* for each face, get the face */
8075      pListHead = PolFaces[x];
8076      temp = (PF_FACES) PeekList(pListHead,LISTHEAD,0);
8077      numverts = temp->nPolSize;
8078      front_walk = 0;
8079      back_walk = 0;
8080     
8081      /* we are finding patches only for quads */
8082      if (numverts == 4)
8083        {
8084          /*    for each face not seen yet, do North and South together
8085                and East and West together
8086          */
8087          for (y=0;y<2;y++)
8088            {
8089              /*   Check if the opposite sides were seen already from another
8090                   starting face, if they were then there is no need to do
8091                   the walk again
8092              */
8093             
8094              if        ( ((*(temp->walked+y) == -1) &&
8095                           (*(temp->walked+y+2) == -1) ))
8096                {
8097                  /* Find walk for the first edge */
8098                  front_walk = Calculate_Walks(x,y,temp);
8099                  /* Find walk in the opposite direction */
8100                  back_walk = Calculate_Walks(x,y+2,temp);
8101                  /*    Now put into the data structure the numbers that
8102                        we have found
8103                  */
8104                  Assign_Walk(x,temp,front_walk,y,back_walk);
8105                  Assign_Walk(x,temp,back_walk,y+2,front_walk);
8106                }
8107            }
8108        }
8109    }
8110}
8111
8112///     OpenOutputFile:
8113FILE *  CustomStripifier::OpenOutputFile(char *fname)
8114{
8115  FILE  *bands;
8116  int           flength =       0;
8117  char  *newfname;
8118 
8119  // get the length of the fname.
8120  flength       =       strlen(fname);
8121
8122  // make a new string in memory one larger than fname.
8123  newfname      =       (char *) malloc(sizeof(char) * (flength+2));
8124
8125  // Copy the fname to the newfname.
8126  strcpy(newfname,fname);
8127
8128  // Add an 'f' to the end of it.
8129  newfname[flength]             =       'f';
8130  newfname[flength+1]   =       '\0';
8131 
8132  printf("   Output file : %s\n",newfname);
8133 
8134  // File that will contain the triangle strip data
8135  bands =       fopen(newfname,"w");
8136  fprintf(bands,"#%s: a triangle strip representation created by STRIPE.\n#This is a .objf file\n#by Francine Evans\n",fname);
8137 
8138  return        bands;
8139}
8140
8141///     AllocateStruct: Reserves memory for structures.
8142void CustomStripifier::AllocateStruct(int num_faces,
8143                                                                                int num_vert,
8144                                                                                int num_nvert,
8145                                                                                int num_texture)
8146{
8147  /* Allocate structures for the information */
8148  Start_Face_Struct(num_faces);
8149  Start_Vertex_Struct(num_vert);
8150 
8151  vertices      =       (struct vert_struct *)
8152                                                        malloc (sizeof (struct vert_struct) * num_vert);
8153 
8154  if (num_nvert > 0)
8155  {
8156                nvertices               =       (struct vert_struct *)
8157                                                                        malloc (sizeof (struct vert_struct) * num_nvert);
8158
8159                vert_norms      =       (int *)
8160                                                                        malloc (sizeof (int) * num_vert);
8161
8162                /*      Initialize entries to zero, in case there are 2 hits
8163                                to the same vertex we will know it - used for determining
8164                                the normal difference
8165                */
8166                init_vert_norms(num_vert);
8167  }
8168  else
8169    nvertices = NULL;
8170 
8171  if (num_texture > 0)
8172        {
8173                vert_texture    =       (int *) malloc (sizeof(int) * num_vert);
8174
8175                init_vert_texture(num_vert);
8176        }
8177 
8178  /*   Set up the temporary 'p' pointers  */
8179  pvertices             =       vertices;
8180  pnvertices    =       nvertices;
8181 
8182}
8183
8184///     miReadFile: Loads the object in memory.
8185void CustomStripifier::miReadFile(char *fname, char *file_open, FILE *bands, Geometry::SubMesh *geoSubMesh)
8186{
8187  BOOL  texture;
8188        BOOL    normal;
8189        BOOL    normal_and_texture;
8190  char  *all;
8191        char    *ptr;
8192        char    *ptr2;
8193  char  aux[255];
8194        FILE    *file;
8195  float center[3];
8196  int           num2;
8197  int           face_id =       0;
8198  int           aux1;
8199        int             aux2;
8200        int             aux3;
8201  int           swaps;
8202        int             strips;
8203        int             triangles;
8204  int           vert_count;
8205        int             loop;
8206        int             num_vert=0;
8207  int           vertex;
8208        int             vertex2;
8209  int           temp[MAX1];
8210        int             i       =       0;
8211        int             num_buffers     =       0;
8212  Geometry::VertexBuffer        *geoVertexBuffer        =       geoSubMesh->mVertexBuffer;
8213       
8214        /**
8215         * Faces
8216         */
8217        for(int j = 0; j < geoSubMesh->mIndexCount; j = j + 3)
8218        {
8219               
8220                // loop on the number of vertices in this line of face data.
8221                vert_count = 0;
8222               
8223                //      3 vertices of a triangle.
8224                for(int k = 0;k < 3;k++)
8225                {
8226                        // no nvertices.
8227                        vertex                                          =       geoSubMesh->mIndex[j+k];
8228                        temp[vert_count]        =       vertex;
8229
8230                        vert_count++;
8231
8232                        add_vert_id(vertex,vert_count);
8233                }
8234
8235                //      Increment the number of faces.
8236                face_id++;
8237
8238                //      Add a new face to the list.
8239                AddNewFace(ids,vert_count,face_id,norms);
8240
8241        }
8242
8243  // Done reading in all the information into data structures.
8244  num_faces     =       face_id;
8245
8246  printf(" Done.\n\n");
8247
8248  free(vertices);
8249  free(nvertices);
8250
8251}
8252
8253///     stripify:       Make triangle strips for a given mesh.
8254int CustomStripifier::stripify (char                                                            *fname,
8255                                                                                                                                Geometry::Mesh                  *geoMesh)
8256{
8257  BOOL                                                          quads = FALSE;
8258        BOOL                                                            oddStrip;
8259        FILE                                                            *bands;
8260        char                                                            *file_open;
8261  float                                                         norm_difference;
8262        int                                                                     i;
8263        int                                                                     j;
8264  int                                                                   swaps;
8265        int                                                                     strips;
8266        int                                                                     triangles;
8267        int                                                                     f;
8268        int                                                                     t;
8269        int                                                                     tr;
8270        int                                                                     g;
8271        int                                                                     num_buffers     =       0;
8272        int                                                                     cost                            =       0;
8273  int                                                                   num_vert                =       0;
8274        int                                                                     num_faces               =       0;
8275        int                                                                     num_nvert   = 0;
8276        int                                                                     num_texture     = 0;
8277        int                                                                     num_tris    = 0;
8278        int                                                                     totalIndices;
8279        int                                                                     totalStripIndices;
8280        unsigned int                            lui_Index;
8281        Geometry::SubMesh*      geoSubMesh;
8282  mi_vector_tipo                        v_indices;
8283   
8284  /*  Scan the file once to find out the number of vertices,
8285                        vertice normals, and faces so we can set up some memory structures.*/
8286  f                                     =       ASCII;
8287  file_open =   "w+";
8288  tr                            =       1;
8289  t                                     =       3;
8290  orient                =       1;
8291
8292        //      Proces OK.
8293        mError                  =       0;
8294
8295
8296        //      2006-02-14
8297        //      Progress bar.
8298        float   percent;
8299        percent =       100.0 / (geoMesh->mSubMeshCount * 10.0);
8300        //--------------------------
8301
8302        //      For all submeshes.
8303        for(int k = 0; k < geoMesh->mSubMeshCount; k++)
8304        {
8305                //      Leaves submesh doesn't stripify.
8306                if (mSubMeshLeaves != k)
8307                {
8308                        v_indices.clear();
8309                        mi_vector.clear();
8310                        mi_vector.push_back(v_indices);
8311                        num_tiras       =       0;
8312
8313                        //      Actual submesh.
8314                        geoSubMesh      =       &geoMesh->mSubMesh[k];
8315
8316                        //      Mesh type.
8317                        geoSubMesh->mType       =       GEO_TRIANGLE_STRIPS;
8318
8319                        num_vert        =       geoSubMesh->mVertexBuffer->mVertexCount;
8320                        num_faces       =       geoSubMesh->mIndexCount / 3;
8321                        num_tris        =       num_faces;
8322
8323                        //      Debug.
8324                        //vt    =       new     int[num_vert];
8325                        //vn    =       new int[num_vert];
8326                        text    =       0;
8327                        norm    =       0;
8328
8329                        //      2006-02-14.
8330                        //      Updtate progress bar.
8331                        if (mUPB)
8332                        {
8333                                mUPB(percent);
8334                        }
8335                        //-----------------------
8336
8337                        // Open the output file.
8338                        bands   =       OpenOutputFile(fname);
8339
8340                        //      2006-02-14.
8341                        //      Updtate progress bar.
8342                        if (mUPB)
8343                        {
8344                                mUPB(percent);
8345                        }
8346                        //-----------------------
8347
8348                        //      Reserve memory for the mesh structure.
8349                        AllocateStruct(num_faces,num_vert,num_nvert,num_texture);
8350
8351                        //      2006-02-14.
8352                        //      Updtate progress bar.
8353                        if (mUPB)
8354                        {
8355                                mUPB(percent);
8356                        }
8357                        //-----------------------
8358
8359                        //      Load the object into memory.
8360                        miReadFile(fname,file_open,bands,geoSubMesh);
8361
8362                        //      2006-02-14.
8363                        //      Updtate progress bar.
8364                        if (mUPB)
8365                        {
8366                                mUPB(percent);
8367                        }
8368                        //-----------------------
8369
8370                        Start_Edge_Struct(num_vert);
8371                        Find_Adjacencies(num_faces);
8372
8373                        //      2006-02-14.
8374                        //      Updtate progress bar.
8375                        if (mUPB)
8376                        {
8377                                mUPB(percent);
8378                        }
8379                        //-----------------------
8380
8381                        //      If the mesh is not manifold.
8382                        if (mError)
8383                        {
8384                                return  0;
8385                        }
8386
8387                        // Initialize it.
8388                        face_array = NULL;
8389                        Init_Table_SGI(num_faces);
8390
8391                        //      2006-02-14.
8392                        //      Updtate progress bar.
8393                        if (mUPB)
8394                        {
8395                                mUPB(percent);
8396                        }
8397                        //-----------------------
8398
8399                        //      Build it.
8400                        Build_SGI_Table(num_faces);
8401                        InitStripTable();
8402
8403                        //      2006-02-14.
8404                        //      Updtate progress bar.
8405                        if (mUPB)
8406                        {
8407                                mUPB(percent);
8408                        }
8409                        //-----------------------
8410
8411                        SGI_Strip(num_faces,bands,t,tr);
8412
8413                        //      2006-02-14.
8414                        //      Updtate progress bar.
8415                        if (mUPB)
8416                        {
8417                                mUPB(percent);
8418                        }
8419                        //-----------------------
8420
8421                        //      Get the total cost.
8422                        Output_TriEx(-1,-2,-3,NULL,-20,cost);
8423
8424                        End_Face_Struct(num_faces);
8425                        End_Edge_Struct(num_vert);
8426                        fclose(bands);
8427
8428                        //      2006-02-14.
8429                        //      Updtate progress bar.
8430                        if (mUPB)
8431                        {
8432                                mUPB(percent);
8433                        }
8434                        //-----------------------
8435
8436                        num_vert        =       num_tiras;
8437
8438                        totalStripIndices       =       0;
8439
8440
8441                        //      Asigna el numero de tiras.
8442                        geoSubMesh->mStripCount =       num_tiras;
8443
8444                        //      Reserva memoria para el array de punteros al inicio
8445                        //      de las tiras.
8446                        //for(i = 0; i < geoSubMesh->mStripCount; i++)
8447                        //{
8448                        geoSubMesh->mStrip      =       (Index**) malloc(       sizeof(Index*)
8449                                        *
8450                                        geoSubMesh->mStripCount);
8451                        //}
8452
8453                        //      2006-02-28.
8454                        //      La primera sera diferente.
8455                        v_indices       =       mi_vector[1];
8456
8457                        //      Number of vertices of a strip odd or even.
8458                        if(v_indices.size() % 2)
8459                        {
8460                                oddStrip        = TRUE;
8461                        }
8462                        else
8463                        {
8464                                oddStrip        =       FALSE;
8465                        }
8466
8467                        //      Obtiene el total de indices de la primera strip.
8468                        geoSubMesh->mIndexCount =       v_indices.size();
8469
8470                        //      Calculate the Index Count.
8471                        for (i = 2; i <= num_tiras; i++)
8472                        {
8473                                v_indices                                                               =               mi_vector[i];
8474                                geoSubMesh->mIndexCount +=      v_indices.size() + 2;
8475
8476                                //      Insert a new vertex if the strip es odd.
8477                                if(oddStrip)
8478                                {
8479                                        geoSubMesh->mIndexCount++;
8480                                }
8481
8482                                //      Number of vertices of a strip odd or even.
8483                                if(v_indices.size() % 2)
8484                                {
8485                                        oddStrip        = TRUE;
8486                                }
8487                                else
8488                                {
8489                                        oddStrip        =       FALSE;
8490                                }
8491                        }
8492
8493                        //      Delete the actual indices.
8494                        delete[]        geoSubMesh->mIndex;
8495                        geoSubMesh->mIndex      =       new     Index[geoSubMesh->mIndexCount];
8496                        //--------------------------------------------
8497
8498                        //      La primera sera diferente.
8499                        v_indices       =       mi_vector[1];
8500
8501                        //      Obtiene el total de indices de la primera strip.
8502                        //geoSubMesh->mIndexCount       =       v_indices.size();
8503
8504
8505
8506                        //      Copia la primera tira en el array de indices.
8507                        for(j   =       0;j < v_indices.size();j++)
8508                        {
8509                                geoSubMesh->mIndex[totalStripIndices++] =       v_indices[j];
8510                        }
8511
8512                        //      Asigna el inicio de la primera tira de triangulos.
8513                        geoSubMesh->mStrip[0]   =       &geoSubMesh->mIndex[0];
8514
8515                        //      2006-02-14.
8516                        //      Updtate progress bar.
8517                        if (mUPB)
8518                        {
8519                                mUPB(percent);
8520                        }
8521                        //-----------------------
8522
8523
8524                        //      Number of vertices of a strip odd or even.
8525                        if(v_indices.size() % 2)
8526                        {
8527                                oddStrip        = TRUE;
8528                        }
8529                        else
8530                        {
8531                                oddStrip        =       FALSE;
8532                        }
8533
8534                        //      Para todas las tiras menos la primera.
8535                        for(i   =       2;i <= num_tiras;i++)
8536                        {
8537                                /*      copia en el inicio de la tira el final de la anterior.
8538                                                triangulos degenerados. */
8539                                geoSubMesh->mIndex[totalStripIndices++] =       geoSubMesh->
8540                                        mIndex[totalStripIndices-1];
8541
8542                                v_indices                                                               =       mi_vector[i];
8543
8544                                //geoSubMesh->mIndexCount       =       geoSubMesh->mIndexCount +       v_indices.size() + 2;
8545
8546                                /*      copia el inicio de la tira 2 veces.
8547                                                triangulos degenerados.
8548                                                */
8549                                geoSubMesh->mIndex[totalStripIndices++] =       v_indices[0];
8550
8551                                //      Asigna el inicio de la tira de triangulos.
8552                                geoSubMesh->mStrip[i-1] =       &geoSubMesh->mIndex[totalStripIndices - 1];
8553
8554                                //      Triangulo Degenerado.
8555                                geoSubMesh->mIndex[totalStripIndices++] =       v_indices[0];
8556
8557                                //      Insert a new vertex if the strip es odd.
8558                                if(oddStrip)
8559                                {
8560                                        //      geoSubMesh->mIndexCount++;
8561                                        geoSubMesh->mIndex[totalStripIndices++] =       v_indices[0];
8562                                }
8563
8564                                //      Number of vertices of a strip odd or even.
8565                                if(v_indices.size() % 2)
8566                                {
8567                                        oddStrip        = TRUE;
8568                                }
8569                                else
8570                                {
8571                                        oddStrip        =       FALSE;
8572                                }
8573
8574                                //      Copia la tira en curso en el array de indices.
8575                                for(j=1;j<v_indices.size();j++)
8576                                {
8577                                        geoSubMesh->mIndex[totalStripIndices++] =       v_indices[j];
8578                                }
8579                        }
8580                }
8581        }//     End For. SubMeshes.
8582
8583        //      2006-02-14.
8584        //      Updtate progress bar.
8585        if (mUPB)
8586        {
8587                mUPB(100.0);
8588        }
8589        //-----------------------
8590
8591        return  1;
8592}
8593
8594//-----------------------------------------------------------------------------
8595//      Constructors.
8596//-----------------------------------------------------------------------------
8597
8598MeshStripifier::MeshStripifier()
8599{
8600}
8601
8602MeshStripifier::MeshStripifier( const   Geometry::Mesh  *geoMesh)
8603{
8604}
8605
8606CustomStripifier::CustomStripifier()
8607{
8608}
8609CustomStripifier::CustomStripifier(     const   Geometry::Mesh  *geoMesh)
8610{
8611        MeshGlobal      =       new Geometry::Mesh();
8612        *MeshGlobal     =       *geoMesh;
8613
8614        //      Initialize the leaves submesh index.
8615        mSubMeshLeaves  =       -1;
8616
8617        //      Sets the actual progress bar function.
8618        mUPB    =       NULL;
8619}
8620
8621//-----------------------------------------------------------------------------
8622//      Destroyers.
8623//-----------------------------------------------------------------------------
8624CustomStripifier::~CustomStripifier()
8625{       
8626        delete  MeshGlobal;
8627}
8628
8629MeshStripifier::~MeshStripifier()
8630{
8631}
8632
8633//-----------------------------------------------------------------------------
8634//      Public.
8635//-----------------------------------------------------------------------------
8636
8637///     Stripify:
8638int CustomStripifier::Stripify()
8639{
8640        //      Init variables.
8641        resetting               =       FALSE;
8642        added_quad      =       0;
8643        reversed                =       FALSE;
8644        patch                           =       0;
8645        out1                            =       -1;
8646        out2                            =       -1;
8647        out1Ex                  =       -1;
8648        out2Ex                  =       -1;
8649        last                            =       0;
8650
8651        //      Make Triangle Strips.
8652        return  stripify("out.obj",MeshGlobal);
8653}
8654
8655///     GetMesh: Return de current Mesh.
8656Mesh*   CustomStripifier::GetMesh()
8657{
8658        Mesh            *mesh_stripified;
8659
8660        mesh_stripified                 =       new Mesh();
8661        *mesh_stripified                =       *MeshGlobal;
8662
8663        return  mesh_stripified;
8664}
8665
8666//      Set the progress bar function.
8667void    CustomStripifier::SetProgressFunc(TIPOFUNC upb)
8668{
8669        //      Sets the actual progress bar function.
8670        mUPB    =       upb;
8671}
8672
8673// Sets what is the submesh that stores the leaves.
8674void CustomStripifier::SetSubMeshLeaves(size_t  submesh)
8675{
8676        mSubMeshLeaves  =       submesh;
8677}
8678
Note: See TracBrowser for help on using the repository browser.