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

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