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

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