Ignore:
Timestamp:
09/04/07 13:06:39 (17 years ago)
Author:
gumbau
Message:
 
Location:
GTP/trunk/Lib/Geom/shared/GTGeometry
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • GTP/trunk/Lib/Geom/shared/GTGeometry/include/GeoMesh.h

    r1070 r2549  
    66#include <iostream> 
    77#include <fstream> 
     8#include <algorithm> 
    89 
    910#include "GeoBase.h" 
  • GTP/trunk/Lib/Geom/shared/GTGeometry/include/GeoMeshStripifier.h

    r2341 r2549  
    1515#include "GeoMesh.h" 
    1616 
    17         typedef int                     BOOL; 
    18         typedef void *  PVOID; 
    19  
     17#define MAX_ADJ 60 
    2018 
    2119namespace Geometry 
    2220{ 
    23  
    24         #define TRIANGLE 3 
    25         #define MAGNITUDE 1000000 
    26         #define MAX_TIE 60 
    27                                  
    28         #define FALSE 0 
    29         #define TRUE  1 
    30         #define LISTHEAD  0 
    31         #define LISTTAIL  1 
     21        typedef struct 
     22        { 
     23                int array[3]; 
     24        }  
     25        vector3; 
    3226 
    3327        typedef struct 
    3428        { 
    35     void  *Next; 
    36     void  *Previous; 
    37         } 
    38         myNode, * PNODE; 
     29                int finish; 
     30                int NumAdj; 
     31    } 
     32        adj; 
    3933 
    40         typedef struct List 
    41         { 
    42                 /*  link to the next Listinfo Structure  */ 
    43                 myNode     ListNode; 
    44  
    45         /*  user definable data  */ 
    46         } 
    47         ListInfo, *PLISTINFO; 
    48  
    49         typedef struct LHead 
    50         { 
    51                 PLISTINFO  LHeaders[2]; 
    52                 int         NumList; 
    53         } 
    54         ListHead, *PLISTHEAD; 
    55  
    56         #define PEEKFROMHEAD( lh, ind )     ( PeekList( (lh), LISTHEAD, (ind) ) ) 
    57         #define PEEKFROMTAIL( lh, ind )     ( PeekList( (lh), LISTTAIL, (ind) ) ) 
    58         #define EMPTYLIST( lh )             ( ( (lh)->LHeaders[LISTHEAD] == NULL ) ) 
    59         #define           NumOnList(lh) ( ((lh)->NumList)        ) 
    60         #define           GetNextNode(pli) ( ((pli)->ListNode.Next) ) 
    61         #define           GetPrevNode(pli) ( ((pli)->ListNode.Previous) ) 
    62  
    63 //----- 
    64  
    65         /**     polverts.h 
    66          */ 
    67         typedef struct adjacencies 
    68         { 
    69                 myNode ListNode; 
    70                 int face_id; 
    71         }ADJACENCIES,*P_ADJACENCIES; 
    72  
    73         typedef struct FVerts 
    74         { 
    75                 myNode ListNode; 
    76                 int *pPolygon; 
    77                 int nPolSize; 
    78                 int nId; 
    79         } F_VERTS, *PF_VERTS; 
    80  
    81         /*Every time we need to use this, cast it ( ListInfo*)*/ 
    82         typedef struct FEdges 
    83         { 
    84                 myNode ListNode; 
    85                 int edge[3]; 
    86         }F_EDGES,*PF_EDGES; 
    87  
    88         typedef struct FFaces 
    89         { 
    90                 myNode ListNode; 
    91                 int *pPolygon; 
    92                 int *pNorms; 
    93     int seen; 
    94     int seen2; 
    95     int seen3; 
    96                 int nPolSize; 
    97     int nOrgSize; 
    98                 F_EDGES **VertandId; 
    99                 int *marked; 
    100                 int *walked; 
    101         }F_FACES,*PF_FACES; 
     34        typedef std::vector<int> vector_int; 
     35        typedef std::vector<vector3> vector_vector3; 
    10236         
    103         typedef struct FVertices  
    104   {  
    105      myNode ListNode; 
    106      PF_FACES face; 
    107   }F_VERTICES, *PF_VERTICES; 
    108  
    109         typedef struct Strips 
    110         { 
    111         myNode ListNode; 
    112         int face_id; 
    113         }Strips,*P_STRIPS; 
    114  
    115  
    116         struct vert_added 
    117   { 
    118                 int num; 
    119                 int *normal; 
    120         }; 
    121  
    122         typedef struct face_adjacencies 
    123         { 
    124     P_ADJACENCIES pfNode; 
    125     int bucket; 
    126     ListHead *head; 
    127   } 
    128         FACE_ADJACENCIES, *P_FACE_ADJACENCIES; 
    129  
    130         /**     global.h 
    131          */ 
    132         typedef std::vector<int> mi_vector_tipo; 
    133         //std::vector<mi_vector_tipo> mi_vector; 
    134         enum swap_type {ON,OFF}; 
    135  
    136         #define   VRDATA                double 
    137         #define   MAX1            60 
    138          
    139         #define   GEO_PI                3.1415926573 
    140         #define   ATOI(C)        (C -'0') 
    141         #define   EVEN(x)       (((x) & 1) == 0) 
    142         #define   MAX_BAND      10000 
    143  
    144         struct vert_struct 
    145         { 
    146                 VRDATA  x, y, z;        /* point coordinates */ 
    147         }; 
    148  
    14937        /// Stripifier interface class. 
    15038        /** This module implements methods that extract triangle strips from triangle meshes.  
     
    20189                private: 
    20290 
    203                         /*      Globals */ 
    204                         int     mError; //      0       OK. 
    205                         //      1       Error:  The mesh is not Manifold. 
     91                        // Globals 
     92                        int     mError;  
    20693                        int num_faces; 
    207                         ListHead **PolFaces; 
    208                         ListHead **PolEdges; 
    209                         ListHead *array[60]; 
    210                         P_FACE_ADJACENCIES face_array;  /* Pointers from face_id to face   */ 
    211                         ListHead **Vertices;            /* Pointers from vertex_id to face */ 
    212                         ListHead *strips[1]; 
    213                         int orient; 
     94 
     95                        std::vector<vector3> StripFaces; 
     96                        std::vector<vector_vector3> StripEdges; 
     97 
     98                        vector_int StripArray[MAX_ADJ];  
     99 
     100                        adj* StripFaceAdj;  
     101 
     102                        std::vector<vector_int> StripVertices; 
     103 
     104                        vector_int Strips; 
     105 
    214106                        int num_tiras; 
    215                         int ids[MAX1]; 
    216                         int norms[MAX1]; 
    217                         int *vert_norms; 
    218                         int *vert_texture; 
    219                         int out1;//= -1;                        //      static. 
    220                         int out2;//= -1;                        //      static. 
    221                         int ties_array[60];     //      static. 
    222                         int last;//= 0;                         //      static. 
    223                         int out1Ex;// = -1;             //      static. 
    224                         int out2Ex;// = -1;             //      static. 
    225                         int *vn; 
    226                         int *vt; 
    227                         int norm;       //      static. 
    228                         int text;       //      static. 
    229                         BOOL resetting;// = FALSE;              //      static. 
    230                         int     added_quad;// = 0;      //      static. 
    231                         BOOL reversed;// = FALSE;               //      static. 
    232                         int patch;// = 0;                                       //      static. 
     107                        int ids[3]; 
     108                        int lastTri[3]; 
     109                        int ties_array[60]; 
     110                        int last; 
    233111 
    234                         /**     global.h 
    235                         */ 
    236                         std::vector<mi_vector_tipo> mi_vector; 
     112                        std::vector<vector_int> my_vector; 
    237113 
    238                         /**     auxiliar.h 
    239                         */ 
    240114                        Geometry::Mesh *MeshGlobal; 
    241                         // Structures for the object. 
    242                         vert_struct             *vertices; 
    243                         vert_struct             *nvertices; 
    244                         vert_struct             *pvertices; 
    245                         vert_struct             *pnvertices; 
    246115 
    247                         /*   General utility routines   */ 
    248                         /*        %%s QueRoutines          */ 
    249                         BOOL    InitList      ( PLISTHEAD ); 
     116                        int stripify( Geometry::Mesh *geoMesh); 
    250117 
    251                         /***************************************************************** 
    252 InitList :  Initialize a new list structure for use with the List 
    253 routines 
     118                        void GetLower(int *x, int *y); 
     119                        int Different(int id1,int id2,int id3,int id4,int id5, int id6, int *x, int *y); 
     120                        void Orient(int vertex1,int vertex2,int vertex3); 
     121                        void StoreAdjacencies(int num_faces); 
     122                        void ReadData(Geometry::SubMesh *geoSubMesh,int num_faces, int num_vert); 
     123                        void Stripification(); 
     124                        void AddTri(int id1, int id2, int id3, int flag, int where); 
     125                        void GoBack(int face_id, int *ties,int tie); 
     126                        void StoreTri(int face_id,int NumAdj, int original_adj, int *ties, int tie, int where); 
    254127 
    255 INPUTS   :  LHead : a pointer to a ListHead structure. 
    256 OUTPUT   :  a boolean value TRUE if no errors occured FALSE 
    257 otherwise 
    258                          ******************************************************************/ 
     128                        int GetNumAdjacencies(int id1, int id2, int curr_id); 
     129                        int MinimumAd(int id); 
     130                        int Find_Face(int current_face, int id1,int id2, int *NumAdj); 
     131                        int Look_Up(int id1,int id2,int face_id); 
     132                        void StoreStrip(int id, int where); 
     133                        int NumAdj(int id1, int id2); 
     134                        void FindAdjacencies(int num_faces, int num_verts); 
     135                        void StoreAdjacency(int NumAdj,int face_id); 
     136                        int Prediction(); 
     137                        void AddNewFace(int ids[3],int face_id); 
     138                        void AddAdjEdge(int v1,int v2, int fnum); 
     139                        int GetEdge(    int *edge1,int *edge2,int *index,int face_id); 
     140                        void DeleteAdj(int id1, int id2,        int *next_NumAdj,int *min_face,  
     141                                        int current_face,int *e1,int *e2,int *ties); 
     142                        int UpdateAdjacencies(int face_id,int *next_NumAdj, int *e1, int *e2,int *ties); 
     143                        void UpdateFaces(int *next_NumAdj,int *min_face, int face_id, int *e1,int *e2,int temp1, int temp2,int *ties); 
     144                        int Finished(); 
    259145 
    260146 
    261                         PLISTINFO  PeekList( PLISTHEAD, int, int   ); 
    262  
    263                         /***************************************************************** 
    264 PeekList :  This funciton peeks down a list for the N'th element 
    265 from the HEAD or TAIL of the list 
    266  
    267 INPUTS   :  LHead    :  a pointer to a List head structure. 
    268 from     :  can either search from the HEAD or TAIL 
    269 of the list 
    270 where    :  how many nodes from the begining should the 
    271 List routines look. 
    272 OUTPUT   :  a pointer to a ListInfo structure identified by 
    273 from/where or NULL if an error occurred. 
    274                          ******************************************************************/ 
    275  
    276  
    277                         PLISTINFO   RemoveList( PLISTHEAD LHead, PLISTINFO LInfo ); 
    278  
    279  
    280                         /***************************************************************** 
    281 RemoveList: Remove a ListInfo structure from a List. 
    282  
    283 INPUTS    : LHead  :  a pointer to a ListHead structure. 
    284 LInfo  :  a pointer to the ListInfo structure to remove 
    285 from the list. 
    286 OUTPUT    : a pointer to the ListInfo structure that was removed or 
    287 NULL if an error occurred. 
    288                          ******************************************************************/ 
    289  
    290                         BOOL  InsertNode( PLISTHEAD LHead, int nPos, PLISTINFO LInfo ); 
    291  
    292                         /***************************************************************** 
    293 InsertNode: add a node to a list after a given node 
    294  
    295 INPUTS    : LHead : a pointer to a ListHead structure. 
    296 nPos  : the position to insert the node into 
    297 LInfo : a pointer to the new node to add to the list. 
    298 OUTPUT: a boolean value TRUE if all goes well false otherwise 
    299                          *****************************************************************/ 
    300  
    301                         BOOL   AddHead       ( PLISTHEAD, PLISTINFO ); 
    302  
    303                         /***************************************************************** 
    304 AddHead   : add a ListInfo structure to the HEAD of a list. 
    305  
    306 INPUTS    : LHead  : a pointer to a ListHead structure of the list 
    307 to add to. 
    308 LInfo  : a pointer to the ListInfo structure to add to 
    309 the list. 
    310 OUTPUT    : A boolean value TRUE if no errors occurred FALSE 
    311 otherwise. 
    312                          ******************************************************************/ 
    313  
    314  
    315                         BOOL     AddTail       ( PLISTHEAD, PLISTINFO ); 
    316  
    317                         /***************************************************************** 
    318 AddTail   : Add a ListInfo structure to the TAIL of a list. 
    319  
    320 INPUTS    : LHead  : a pointer to a ListHead structure of the List 
    321 to add to. 
    322 LInfo  : a pointer to the ListInfo structure to add to 
    323 the List. 
    324 OUTPUT    : a boolean value TRUE if no errors occurred FALSE 
    325 otherwise. 
    326                          ******************************************************************/ 
    327  
    328  
    329                         PLISTINFO  RemTail       ( PLISTHEAD ); 
    330  
    331                         /***************************************************************** 
    332 RemTail   : Remove a ListInfo structure from the TAIL of a List. 
    333  
    334 INPUTS    : LHead  : a pointer to a ListHead structure of the List 
    335 to remove from. 
    336 OUTPUT    : a pointer to the ListInfo structure that was removed 
    337 or NULL if an error occurred. 
    338                          ******************************************************************/ 
    339  
    340  
    341                         PLISTINFO  RemHead       ( PLISTHEAD ); 
    342  
    343                         /***************************************************************** 
    344 RemHead   : Remove a ListInfo structure from the Head of a List. 
    345  
    346 INPUTS    : LHead  : a pointer to a ListHead structure of the List 
    347 to remove from. 
    348 OUTPUT    : a pointer to the ListInfo structure that was removed or 
    349 NULL if an error occurred. 
    350                          ******************************************************************/ 
    351  
    352                         PLISTINFO  SearchList( 
    353                                         PLISTHEAD lpListHead, 
    354                                         PVOID lpSKey, 
    355                                         int ( * CompareCallBack) ( PVOID, PVOID ) ); 
    356  
    357                         /***************************************************************** 
    358 SearchList: 
    359 Try to find a specific node in the queue whose key matches with 
    360 searching key. Return the pointer to that node if found, return NULL 
    361 otherwise 
    362  
    363 Input: 
    364 lpHashTbl       => a far pointer to the hash table 
    365 lpKey           => a far poniter to searching key 
    366 CompareCallBack => comparision function 
    367  
    368 Output: a far pointer to the node to be found 
    369  
    370                          ******************************************************************/ 
    371  
    372                         /**     init.h 
    373                         */ 
    374                         BOOL InitVertexTable(int nSize); 
    375                         BOOL InitFaceTable(int nSize); 
    376                         BOOL InitEdgeTable(int nSize); 
    377                         void BuildFaceTable(int nSize); 
    378                         void BuildVertexTable(int nSize); 
    379                         void BuildEdgeTable(int nSize); 
    380                         void init_vert_norms(int num_vert); 
    381                         void init_vert_texture(int num_vert); 
    382                         void InitStripTable(); 
    383                         void Init_Table_SGI(int numfaces); 
    384                         void Start_Vertex_Struct(int numverts); 
    385                         void Start_Face_Struct(int numfaces); 
    386                         void Start_Edge_Struct(int numverts); 
    387  
    388                         /**     util.h 
    389                         */ 
    390                         void switch_lower(int *x, int *y); 
    391                         BOOL member(int x , int id1, int id2, int id3); 
    392                         BOOL Exist(int face_id, int id1, int id2); 
    393                         int Different(  int id1,int id2,int id3,int id4,int id5, 
    394                                         int id6, int *x, int *y); 
    395                         int Return_Other(int *index,int e1,int e2); 
    396                         int Get_Other_Vertex(int id1,int id2,int id3,int *index); 
    397                         PLISTINFO Done(int face_id,  int *bucket); 
    398                         void First_Edge(int *id1,int *id2, int *id3); 
    399                         void Last_Edge(int *id1, int *id2, int *id3, BOOL save); 
    400  
    401                         void preserve_strip_orientation_with_normal( 
    402                                         int             vertex1, 
    403                                         int             normal1, 
    404                                         int             vertex2, 
    405                                         int             normal2, 
    406                                         int             vertex3, 
    407                                         int             normal3); 
    408  
    409                         void preserve_strip_orientation_with_texture( 
    410                                         int             vertex1, 
    411                                         int             texture1, 
    412                                         int             vertex2, 
    413                                         int             texture2, 
    414                                         int             vertex3, 
    415                                         int texture3); 
    416  
    417                         void  preserve_strip_orientation_with_texture_and_normal( 
    418                                         int             vertex1, 
    419                                         int             texture1, 
    420                                         int             normal1, 
    421                                         int             vertex2, 
    422                                         int             texture2, 
    423                                         int             normal2, 
    424                                         int             vertex3, 
    425                                         int             texture3, 
    426                                         int             normal3); 
    427  
    428                         void preserve_strip_orientation( 
    429                                         int vertex1, 
    430                                         int vertex2, 
    431                                         int vertex3); 
    432  
    433                         void find_triangle_orientation( int vertex1, 
    434                                         int vertex2, 
    435                                         int vertex3, 
    436                                         int *original_vertex); 
    437  
    438                         /**     local.h 
    439                         */ 
    440                         void Find_StripsEx(int *ties, int  tie, int triangulate, int  swaps, int *next_id); 
    441                         void SGI_Strip(int num_faces,int ties,int triangulate); 
    442  
    443                         /**     outputex.h 
    444                         */ 
    445                         void Output_TriEx(int id1, int id2, int id3, int flag,int where); 
    446                         void Extend_BackwardsEx(int face_id, int *ties,  
    447                                         int tie, int triangulate,  
    448                                         int swaps,int *next_id); 
    449                         void Polygon_OutputEx(P_ADJACENCIES temp,int face_id,int bucket, 
    450                                         ListHead *pListHead, 
    451                                         int *ties, int tie,int triangulate, int swaps, 
    452                                         int *next_id, int where); 
    453  
    454                         /**     sgi_triang.h 
    455                         */ 
    456                         int Adjacent(int id2,int id1, int *list, int size); 
    457                         void Build_SGI_Table(int num_faces); 
    458                         void Non_Blind_Triangulate(     int size,int *index, 
    459                                         int next_face_id, 
    460                                         int face_id,int where, 
    461                                         int color1,int color2,int color3); 
    462                         void Blind_Triangulate(int size, int *index, BOOL begin, int where); 
    463                         void Rearrange_Index(int *index, int size);     //      static. 
    464                         void Delete_From_List(int id,int *list, int *size);     //      static. 
    465                         void Triangulate_Quad(int out_edge1,int out_edge2,int in_edge1, 
    466                                         int in_edge2,int size,int *index, 
    467                                         int reversed,int where);        //      static. 
    468                         void Triangulate_Polygon(       int out_edge1,int out_edge2, 
    469                                         int in_edge1,   int in_edge2, 
    470                                         int size,                       int *index, 
    471                                         int reversed, 
    472                                         int face_id,    int where, 
    473                                         int color1,             int color2, 
    474                                         int color3);    //      static. 
    475  
    476                         void Triangulate(       int out_edge1,int out_edge2,int in_edge1, 
    477                                         int in_edge2,int size,int *index, 
    478                                         int reversed,int face_id, int where, 
    479                                         int color1, int color2,int color3);     //      static. 
    480  
    481                         /**     struct.h 
    482                         */ 
    483                         int Get_Edge(   int *edge1,int *edge2, 
    484                                         int *index,int face_id, 
    485                                         int size, int id1, int id2); 
    486                         int Update_Adjacencies( int face_id,int *next_bucket, 
    487                                         int *e1,int *e2,int *ties); 
    488                         void Update_Face(       int *next_bucket, int *min_face, 
    489                                         int face_id,                    int *e1, 
    490                                         int *e2,                                        int temp1, 
    491                                         int temp2,                              int *ties);     //      static. 
    492                         void Delete_Adj(int id1, int id2,int *next_bucket, 
    493                                         int *min_face,int current_face,int *e1, 
    494                                         int *e2,int *ties);     //      static. 
    495                         /**     common.h 
    496                         */ 
    497                         int  Old_Adj(int face_id); 
    498                         int Number_Adj(int id1, int id2, int curr_id); 
    499                         int Min_Adj(int id); 
    500                         void Check_In_Polygon(int face_id, int *min, int size); 
    501                         void New_Face (int face_id, int v1, int v2, int v3); 
    502                         void New_Size_Face(int face_id); 
    503                         void Check_In_Quad(int face_id,int *min); 
    504                         int Get_Output_Edge(int face_id, int size, int *index,int id2,int id3); 
    505                         void Get_Input_Edge(int *index,int id1, 
    506                                         int id2,int id3, 
    507                                         int *new1,int *new2, 
    508                                         int size,int face_id); 
    509                         int Find_Face(int current_face, int id1, 
    510                                         int id2, int *bucket); 
    511                         BOOL Look_Up(int id1,int id2,int face_id); 
    512                         void Add_Id_Strips(int id, int where); 
    513                         int Num_Adj(int id1, int id2); 
    514                         void Add_Sgi_Adj(int bucket,int face_id); 
    515                         void Find_Adjacencies(int num_faces); 
    516                         void Edge_Least(int *index,int *new1, 
    517                                         int *new2,int face_id,int size);        //      static. 
    518  
    519                         /**     ties.h 
    520                         */ 
    521                         void Clear_Ties(); 
    522                         void Add_Ties(int id); 
    523                         int Get_Next_Face(int t, int face_id, int triangulate); 
    524                         int Alternate_Tie();    //      static. 
    525                         int Random_Tie();                       //      static. 
    526                         int Look_Ahead(int id); //      static. 
    527                         int Random_Look(int id[],int count);    //      static. 
    528                         int Look_Ahead_Tie();   //      static. 
    529                         int Sequential_Tri(int *index); //      static. 
    530                         int Sequential_Quad(int *index, int triangulate);       //      static. 
    531                         void Whole_Output(int in1,      int *index, int size, 
    532                                         int *out1,int *out2);   //      static. 
    533                         int Sequential_Poly(int size,int *index,int triangulate);       //      static. 
    534                         int Sequential_Tie(int face_id,int triangulate);        //      static. 
    535  
    536                         /**     add.h 
    537                         */ 
    538                         BOOL norm_array(int id,int vertex, 
    539                                         double normal_difference, 
    540                                         struct vert_struct *n,int num_vert); 
    541                         void add_texture(int id,BOOL vertex); 
    542                         int  add_vert_id(int id, int index_count); 
    543                         void add_norm_id(int id, int index_count); 
    544                         void AddNewFace(int ids[MAX1],int vert_count, 
    545                                         int face_id,int norms[MAX1]); 
    546                         void CopyFace(int ids[MAX1],int vert_count, 
    547                                         int face_id,int norms[MAX1]); 
    548                         void Add_AdjEdge(       int v1,int v2, 
    549                                         int fnum,int index1); 
    550                         BOOL new_vertex(double difference,int id1, 
    551                                         int id2,struct vert_struct *n); //      static. 
    552                         BOOL Check_VN(int vertex,int normal, struct vert_added *added); //      static. 
    553  
    554                         /**     options.h 
    555                         */ 
    556                         enum file_options {ASCII,BINARY}; 
    557                         enum tie_options {FIRST, RANDOM, ALTERNA, LOOK, SEQUENTIAL}; 
    558                         enum triangulation_options {PARTIAL,WHOLE}; 
    559  
    560                         void print_usage(void); 
    561                         float get_options(int argc,     char **argv, 
    562                                         int *f,         int *t, 
    563                                         int *tr,        int *group, 
    564                                         int *orientation); 
    565                         int power_10(int power);        //      static. 
    566                         float power_negative(int power);        //      static. 
    567                         float convert_array(int num[],int stack_size);  //      static. 
    568  
    569                         /**     sgi_triangex.h 
    570                         */ 
    571                         int AdjacentEx(int id2,int id1, int *list, int size); 
    572                         void Delete_From_ListEx(int id,int *list, int size); 
    573                         void Triangulate_PolygonEx(     int out_edge1,int out_edge2,int in_edge1, 
    574                                         int in_edge2,int size,int *index, 
    575                                         int reversed,int face_id, 
    576                                         int where); 
    577                         void Non_Blind_TriangulateEx(   int size,int *index, 
    578                                         int next_face_id, 
    579                                         int face_id,int where); 
    580                         void Rearrange_IndexEx(int *index, int size); 
    581                         void Blind_TriangulateEx(       int size,               int *index, 
    582                                         BOOL begin, int where); 
    583                         void Triangulate_QuadEx(int out_edge1,int out_edge2,int in_edge1, 
    584                                         int in_edge2,   int size,                       int *index, 
    585                                         int reversed,   int where);     //      static. 
    586                         void TriangulateEx(     int out_edge1,int out_edge2, 
    587                                         int in_edge1, int in_edge2, 
    588                                         int size,                       int *index, 
    589                                         int reversed, 
    590                                         int face_id,    int where);     //      static. 
    591  
    592                         /**     structex.h 
    593                         */ 
    594                         int Get_EdgeEx( int *edge1,int *edge2,int *index,int face_id, 
    595                                         int size, int id1, int id2); 
    596                         void Delete_AdjEx(int id1, int id2, 
    597                                         int *next_bucket,int *min_face,  
    598                                         int current_face,int *e1, 
    599                                         int *e2,int *ties); 
    600                         int Change_FaceEx(int face_id,int in1,int in2, 
    601                                         ListHead *pListHead, BOOL no_check); 
    602                         int Update_AdjacenciesEx(       int face_id,int *next_bucket, 
    603                                         int *e1, int *e2, 
    604                                         int *ties); 
    605                         int Min_Face_AdjEx(int face_id,int *next_bucket,int *ties); 
    606  
    607                         void Update_FaceEx(     int *next_bucket,int *min_face, 
    608                                         int face_id, int *e1, 
    609                                         int *e2,int temp1, 
    610                                         int temp2,int *ties);   //      static. 
    611  
    612                         void Find_Adj_TallyEx(int id1,                                  int id2, 
    613                                         int *next_bucket,       int *min_face, 
    614                                         int current_face,       int *ties);     //      static. 
    615  
    616                         /**     partial.h 
    617                         */ 
    618                         void Partial_Triangulate(int size,              int *index, 
    619                                         int next_face_id, 
    620                                         int face_id,    int *next_id, 
    621                                         ListHead *pListHead, 
    622                                         P_ADJACENCIES temp, int where); 
    623  
    624  
    625                         void Inside_Polygon(int size,                   int *index, 
    626                                         int face_id,    ListHead *pListHead, 
    627                                         int where); 
    628  
    629                         void P_Triangulate_Quad(int out_edge1,int out_edge2, 
    630                                         int in_edge1, int in_edge2, 
    631                                         int size,                       int *index, 
    632                                         int reversed, int face_id, 
    633                                         ListHead *pListHead,  
    634                                         P_ADJACENCIES temp, 
    635                                         int where);     //      static. 
    636                         void P_Triangulate_Polygon(     int out_edge1,int out_edge2, 
    637                                         int in_edge1, int in_edge2, 
    638                                         int size,               int *index, 
    639                                         int reversed, 
    640                                         int face_id,    int *next_id, 
    641                                         ListHead *pListHead, 
    642                                         P_ADJACENCIES temp2, 
    643                                         int where);     //      static. 
    644                         void P_Triangulate(     int out_edge1,int out_edge2,int in_edge1, 
    645                                         int in_edge2,   int size,                       int *index, 
    646                                         int reversed,   int face_id, 
    647                                         int *next_id,   ListHead *pListHead,  
    648                                         P_ADJACENCIES temp,int where);  //      static. 
    649                         void Input_Edge(int face_id,    int *index, 
    650                                         int size,               int in_edge1, 
    651                                         int in_edge2, ListHead *pListHead, 
    652                                         int where);     //      static. 
    653  
    654                         /**     output.h 
    655                         */ 
    656                         int Finished(int *swap, int startnewstrip); 
    657                         void Output_Tri(int id1, int id2, int id3,BOOL end); 
    658                         int Extend_Face(int face_id,int e1,int e2,int *swaps, 
    659                                         int color1,int color2,int color3,int *vert_norm, 
    660                                         int normals,int *vert_texture,int texture); 
    661                         int Polygon_Output(     P_ADJACENCIES temp,     int face_id, 
    662                                         int bucket,                             ListHead *pListHead, 
    663                                         BOOL first,                             int *swaps, 
    664                                         int color1,                                     int color2,                                      
    665                                         int color3, 
    666                                         BOOL global,                    BOOL end);      //      static. 
    667                         /**     free.h 
    668                         */ 
    669                         void Free_Strips(); 
    670                         void End_Face_Struct(int numfaces); 
    671                         void End_Edge_Struct(int numverts); 
    672                         void ParseAndFreeList( ListHead *pListHead );   //      static. 
    673                         void FreeFaceTable(int nSize);  //      static. 
    674                         void FreeEdgeTable(int nSize);  //      static. 
    675  
    676                         /**     newpolve.h 
    677                         */ 
    678                         void Find_Bands(int numfaces, int *swaps, int *bands,  
    679                                         int *cost, int *tri, int norms, int *vert_norms, 
    680                                         int texture, int *vert_texture); 
    681                         void Save_Walks(int numfaces); 
    682                         void Save_Rest(int *numfaces); 
    683                         int Calculate_Walks(int lastvert,int y, PF_FACES temp2);        //      static. 
    684                         BOOL Check_Right(       int last_seen,PF_FACES temp2, 
    685                                         int y,int face_id);             //      static. 
    686                         int Update_and_Test(PF_FACES temp2,int y, 
    687                                         BOOL first,int distance, 
    688                                         int lastvert, int val); //      static. 
    689                         int Test_Adj(   PF_FACES temp2,int x, 
    690                                         int north,int distance, 
    691                                         int lastvert, int value);       //      static. 
    692                         int Find_Max(   PF_FACES temp2, int lastvert, 
    693                                         int north,                      int left, 
    694                                         int *lastminup, int *lastminleft);      //      static. 
    695                         void Mark_Face( PF_FACES temp2,                 int color1, 
    696                                         int color2,                     int color3, 
    697                                         BOOL end, 
    698                                         int *edge1,                                     int *edge2, 
    699                                         int *face_id,                           int norms, 
    700                                         int texture);   //      static. 
    701                         void Assign_Walk(       int lastvert,           PF_FACES temp2, 
    702                                         int front_walk, int y, 
    703                                         int back_walk); //      static. 
    704                         void Fast_Reset(int x); //      static. 
    705                         void Reset_Max( PF_FACES temp2,int face_id, 
    706                                         int north,int last_north, 
    707                                         int orientation,int last_left, 
    708                                         int color1, 
    709                                         int color2,int color3, 
    710                                         BOOL start);    //      static. 
    711                         int Peel_Max(   PF_FACES temp2,int face_id, 
    712                                         int north,int last_north, 
    713                                         int orientation,int last_left, 
    714                                         int color1, 
    715                                         int color2,int color3, 
    716                                         BOOL start, int *swaps_added, 
    717                                         int norms, int texture);        //      static. 
    718  
    719                         /**     auxiliar.h 
    720                         */ 
    721 //                      FILE *OpenOutputFile(char *fname); 
    722                         void AllocateStruct(int num_faces, 
    723                                         int num_vert, 
    724                                         int num_nvert, 
    725                                         int num_texture); 
    726                         void miReadFile(char *fname, char *file_open, Geometry::SubMesh *geoSubMesh); 
    727                         int stripify(   char                                            *fname, 
    728                                                                                 Geometry::Mesh  *geoMesh); 
    729147 
    730148                public: 
  • GTP/trunk/Lib/Geom/shared/GTGeometry/src/GeoMeshStripifier.cpp

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