Ignore:
Timestamp:
05/24/06 10:47:49 (19 years ago)
Author:
gumbau
Message:
 
Location:
GTP/trunk/Lib/Geom/shared/GTGeometry/src
Files:
1 deleted
6 edited

Legend:

Unmodified
Added
Removed
  • GTP/trunk/Lib/Geom/shared/GTGeometry/src/GeoMesh.cpp

    r891 r980  
    44using namespace std; 
    55 
    6 //---------------------------------------------------------------------------- 
     6//--------------------------------------------------------------------------- 
     7//      Cosntructor. 
     8//--------------------------------------------------------------------------- 
    79Mesh::Mesh(): 
    8         mVertexBuffer(0), mSubMeshCount(0), mSubMesh(0) 
    9 { 
    10 } 
    11  
     10        mVertexBuffer(0), mSubMeshCount(0), mSubMesh(0), hasSkeleton(false) 
     11{ 
     12        mMeshBounds.maxX                                        =       0.0; 
     13        mMeshBounds.maxY                                        =       0.0; 
     14        mMeshBounds.maxZ                                        =       0.0; 
     15        mMeshBounds.minX                                        =       0.0; 
     16        mMeshBounds.minY                                        =       0.0; 
     17        mMeshBounds.minZ                                        =       0.0; 
     18        mMeshBounds.scaleFactor =       0.0; 
     19} 
     20 
     21//--------------------------------------------------------------------------- 
     22//      Destroyer. 
     23//--------------------------------------------------------------------------- 
    1224Mesh::~Mesh() 
    1325{ 
     
    1729 
    1830 
     31//--------------------------------------------------------------------------- 
     32//      Copy constructor. 
     33//--------------------------------------------------------------------------- 
    1934Mesh::Mesh(const Mesh &objmesh)  
    2035{ 
    2136        // constructor copia 
    22         mVertexBuffer=new VertexBuffer(); 
    23         mSubMeshCount=objmesh.mSubMeshCount; 
    24         mSubMesh = new Geometry::SubMesh[objmesh.mSubMeshCount]; 
    25         for(size_t i=0;i<objmesh.mSubMeshCount;i++) 
    26         { 
    27                 mSubMesh[i].mSharedVertexBuffer=false; 
    28                 mSubMesh[i].mVertexBuffer = new Geometry::VertexBuffer(); 
    29                 mSubMesh[i].mVertexBuffer->mPosition = new Geometry::Vector3[objmesh.mSubMesh[i].mVertexBuffer->mVertexCount]; 
    30                 mSubMesh[i].mVertexBuffer->mNormal = new Geometry::Vector3[objmesh.mSubMesh[i].mVertexBuffer->mVertexCount]; 
    31                 mSubMesh[i].mVertexBuffer->mTexCoords = new Geometry::Vector2[objmesh.mSubMesh[i].mVertexBuffer->mVertexCount]; 
    32                 mSubMesh[i].mVertexBuffer->mVertexCount = objmesh.mSubMesh[i].mVertexBuffer->mVertexCount; 
    33                 mSubMesh[i].mVertexBuffer->mVertexInfo = objmesh.mSubMesh[i].mVertexBuffer->mVertexInfo; 
    34                 mSubMesh[i].mType       =       objmesh.mSubMesh[i].mType; 
    35                  
    36                 // De momento con esto se parte de un geomesh con vértices compartidos y se obtiene un geomesh sin vértices 
    37                 // compartidos. Los vértices se replican en cada uno de los submeshes. 
    38                 // HAY QUE CAMBIARLO. 
    39                 if(objmesh.mSubMesh[i].mSharedVertexBuffer == true)  
    40                 { 
    41                         for(size_t s=0;s<objmesh.mSubMesh[i].mVertexBuffer->mVertexCount;s++) 
    42                         { 
    43                                 //Copiamos mPosition 
    44                                 if (objmesh.mSubMesh[i].mVertexBuffer->mVertexInfo & Geometry::VERTEX_POSITION) 
     37        mVertexBuffer   =       new VertexBuffer(); 
     38        mSubMeshCount   =       objmesh.mSubMeshCount; 
     39        mSubMesh                        =       new SubMesh[objmesh.mSubMeshCount]; 
     40 
     41        //      Fill up bounding box settings. 
     42        mMeshBounds.maxX                                        =       objmesh.mMeshBounds.maxX; 
     43        mMeshBounds.maxY                                        =       objmesh.mMeshBounds.maxY; 
     44        mMeshBounds.maxZ                                        =       objmesh.mMeshBounds.maxZ; 
     45        mMeshBounds.minX                                        =       objmesh.mMeshBounds.minX; 
     46        mMeshBounds.minY                                        =       objmesh.mMeshBounds.minY; 
     47        mMeshBounds.minZ                                        =       objmesh.mMeshBounds.minZ; 
     48        mMeshBounds.radius                              =       objmesh.mMeshBounds.radius; 
     49        mMeshBounds.scaleFactor         =       objmesh.mMeshBounds.scaleFactor; 
     50         
     51        //      For each submesh. 
     52        for(size_t i = 0; i < objmesh.mSubMeshCount; i++) 
     53        { 
     54                mSubMesh[i].mSharedVertexBuffer                                 =       false; 
     55                mSubMesh[i].mVertexBuffer                                                               =       new VertexBuffer(); 
     56                mSubMesh[i].mVertexBuffer->mPosition            =       new Vector3[objmesh.mSubMesh[i].mVertexBuffer->mVertexCount]; 
     57                mSubMesh[i].mVertexBuffer->mNormal                      =       new Vector3[objmesh.mSubMesh[i].mVertexBuffer->mVertexCount]; 
     58                mSubMesh[i].mVertexBuffer->mTexCoords   = new Vector2[objmesh.mSubMesh[i].mVertexBuffer->mVertexCount]; 
     59                mSubMesh[i].mVertexBuffer->mVertexCount =       objmesh.mSubMesh[i].mVertexBuffer->mVertexCount; 
     60                mSubMesh[i].mVertexBuffer->mVertexInfo  =       objmesh.mSubMesh[i].mVertexBuffer->mVertexInfo; 
     61                mSubMesh[i].mType                                                                                               =       objmesh.mSubMesh[i].mType; 
     62                strcpy(mSubMesh[i].mMaterialName,objmesh.mSubMesh[i].mMaterialName); 
     63                 
     64                if(objmesh.mSubMesh[i].mSharedVertexBuffer)  
     65                { 
     66                        for(size_t s    =       0; 
     67                                        s<objmesh.mSubMesh[i].mVertexBuffer->mVertexCount; 
     68                                        s++) 
     69                        { 
     70                                //      Copy mPosition. 
     71                                if (objmesh.mSubMesh[i].mVertexBuffer->mVertexInfo & VERTEX_POSITION) 
    4572                                { 
    4673                                        mSubMesh[i].mVertexBuffer->mPosition[s].x = objmesh.mVertexBuffer->mPosition[s].x; 
     
    4875                                        mSubMesh[i].mVertexBuffer->mPosition[s].z = objmesh.mVertexBuffer->mPosition[s].z; 
    4976                                } 
    50                                 //Copiamos mNormal 
    51                                 if (objmesh.mSubMesh[i].mVertexBuffer->mVertexInfo & Geometry::VERTEX_NORMAL) 
     77                                 
     78                                //      Copy mNormal. 
     79                                if (objmesh.mSubMesh[i].mVertexBuffer->mVertexInfo & VERTEX_NORMAL) 
    5280                                { 
    5381                                        mSubMesh[i].mVertexBuffer->mNormal[s].x = objmesh.mVertexBuffer->mNormal[s].x; 
     
    5684                                } 
    5785 
    58                                 //Copiamos mTexCoords 
    59                                 if (objmesh.mSubMesh[i].mVertexBuffer->mVertexInfo & Geometry::VERTEX_TEXCOORDS) 
     86                                //      Copy mTexCoords. 
     87                                if (objmesh.mSubMesh[i].mVertexBuffer->mVertexInfo & VERTEX_TEXCOORDS) 
    6088                                { 
    6189                                        mSubMesh[i].mVertexBuffer->mTexCoords[s].x = objmesh.mVertexBuffer->mTexCoords[s].x; 
     
    6795                else 
    6896                { 
    69                         for(size_t s=0;s<objmesh.mSubMesh[i].mVertexBuffer->mVertexCount;s++) 
    70                         { 
    71                                 //Copiamos mPosition 
    72                                 if (objmesh.mSubMesh[i].mVertexBuffer->mVertexInfo & Geometry::VERTEX_POSITION) 
     97                        for(size_t s = 0; s < objmesh.mSubMesh[i].mVertexBuffer->mVertexCount; s++) 
     98                        { 
     99                                //      Copy mPosition. 
     100                                if (objmesh.mSubMesh[i].mVertexBuffer->mVertexInfo & VERTEX_POSITION) 
    73101                                { 
    74102                                        mSubMesh[i].mVertexBuffer->mPosition[s].x = objmesh.mSubMesh[i].mVertexBuffer->mPosition[s].x; 
     
    76104                                        mSubMesh[i].mVertexBuffer->mPosition[s].z = objmesh.mSubMesh[i].mVertexBuffer->mPosition[s].z; 
    77105                                } 
     106                                 
    78107                                //Copiamos mNormal 
    79                                 if (objmesh.mSubMesh[i].mVertexBuffer->mVertexInfo & Geometry::VERTEX_NORMAL) 
     108                                if (objmesh.mSubMesh[i].mVertexBuffer->mVertexInfo & VERTEX_NORMAL) 
    80109                                { 
    81110                                        mSubMesh[i].mVertexBuffer->mNormal[s].x = objmesh.mSubMesh[i].mVertexBuffer->mNormal[s].x; 
     
    85114 
    86115                                //Copiamos mTexCoords 
    87                                 if (objmesh.mSubMesh[i].mVertexBuffer->mVertexInfo & Geometry::VERTEX_TEXCOORDS) 
     116                                if (objmesh.mSubMesh[i].mVertexBuffer->mVertexInfo & VERTEX_TEXCOORDS) 
    88117                                { 
    89118                                        mSubMesh[i].mVertexBuffer->mTexCoords[s].x = objmesh.mSubMesh[i].mVertexBuffer->mTexCoords[s].x; 
     
    93122 
    94123                } 
    95                 // Copiar los indices 
    96                 mSubMesh[i].mIndexCount=objmesh.mSubMesh[i].mIndexCount; 
    97                 mSubMesh[i].mIndex = new Index[mSubMesh[i].mIndexCount]; 
    98                 memcpy(mSubMesh[i].mIndex,objmesh.mSubMesh[i].mIndex,objmesh.mSubMesh[i].mIndexCount*sizeof(Geometry::Index)); 
    99  
    100                 // Copiar las tiras 
    101                 // TENER EN CUENTA SI ES UN MESH DE TIRAS O LISTA DE TRIANGULOS 
    102                 __w64 int Desp=0; // desplazamiento entre posiciones de memoria. 
     124                 
     125                // Copy indices. 
     126                mSubMesh[i].mIndexCount =       objmesh.mSubMesh[i].mIndexCount; 
     127                mSubMesh[i].mIndex                      =       new Index[mSubMesh[i].mIndexCount]; 
     128                 
     129                memcpy(mSubMesh[i].mIndex,objmesh.mSubMesh[i].mIndex,objmesh.mSubMesh[i].mIndexCount*sizeof(Index)); 
     130 
     131                // Copy strips. 
     132                __w64 int offset        =       0; // offset between memory positions. 
    103133                mSubMesh[i].mStripCount=objmesh.mSubMesh[i].mStripCount; 
    104134                if (objmesh.mSubMesh[i].mStripCount>0)  
     
    106136                        mSubMesh[i].mStrip = new Index*[objmesh.mSubMesh[i].mStripCount]; 
    107137 
    108                         Desp= &(mSubMesh[i].mIndex[0]) - &(objmesh.mSubMesh[i].mIndex[0]); 
    109                         for (size_t j=0;j<objmesh.mSubMesh[i].mStripCount;j++)  
    110                         { 
    111                                 mSubMesh[i].mStrip[j]=objmesh.mSubMesh[i].mStrip[j] + Desp; 
    112                         } 
    113                 } 
    114         } 
    115 } 
    116  
     138                        offset  = &(mSubMesh[i].mIndex[0]) - &(objmesh.mSubMesh[i].mIndex[0]); 
     139                        for (size_t j=0;j<objmesh.mSubMesh[i].mStripCount;j++) 
     140                        { 
     141                                mSubMesh[i].mStrip[j]=objmesh.mSubMesh[i].mStrip[j] + offset; 
     142                        } 
     143                } 
     144 
     145                //      Copy submesh bones. 
     146                if (!objmesh.mSubMesh[i].mBones.empty()) 
     147                { 
     148                        for (int j = 0; j < objmesh.mSubMesh[i].mBones.size(); j++) 
     149                        { 
     150                                mSubMesh[i].mBones.push_back(objmesh.mSubMesh[i].mBones[j]); 
     151                        } 
     152                } 
     153        } 
     154         
     155        //      Copy skeleton name. 
     156        if (objmesh.hasSkeleton) 
     157        { 
     158                hasSkeleton     =       true; 
     159                 
     160                strcpy(mSkeletonName,objmesh.mSkeletonName); 
     161        } 
     162 
     163        //      Copy mesh bones. 
     164        if (!objmesh.mBones.empty()) 
     165        { 
     166                for (int j = 0; j < objmesh.mBones.size(); j++) 
     167                { 
     168                        mBones.push_back(objmesh.mBones[j]); 
     169                } 
     170        } 
     171 
     172} 
     173 
     174//--------------------------------------------------------------------------- 
     175//      Assignment operator. 
     176//--------------------------------------------------------------------------- 
    117177Mesh &Mesh::operator =(const Geometry::Mesh &objmesh) 
    118178{ 
     
    122182        mSubMeshCount   =       objmesh.mSubMeshCount; 
    123183        mSubMesh                        =       new Geometry::SubMesh[objmesh.mSubMeshCount]; 
    124  
     184         
     185        //      Fill up bounding box settings. 
     186        mMeshBounds.maxX                                        =       objmesh.mMeshBounds.maxX; 
     187        mMeshBounds.maxY                                        =       objmesh.mMeshBounds.maxY; 
     188        mMeshBounds.maxZ                                        =       objmesh.mMeshBounds.maxZ; 
     189        mMeshBounds.minX                                        =       objmesh.mMeshBounds.minX; 
     190        mMeshBounds.minY                                        =       objmesh.mMeshBounds.minY; 
     191        mMeshBounds.minZ                                        =       objmesh.mMeshBounds.minZ; 
     192        mMeshBounds.radius                              =       objmesh.mMeshBounds.radius; 
     193        mMeshBounds.scaleFactor         =       objmesh.mMeshBounds.scaleFactor; 
     194 
     195        //      For each submesh. 
    125196        for(size_t i = 0; i < objmesh.mSubMeshCount; i++) 
    126197        { 
    127                 //      Debug. 
    128                 /* 
    129                 cout    <<      "VertexCount[" 
    130                                         <<      i 
    131                                         <<      "]: " 
    132                                         <<      objmesh.mSubMesh[i].mVertexBuffer->mVertexCount 
    133                                         <<      endl; 
    134                 */ 
    135                 //-------------------------------------------------------------------------------------------- 
    136  
    137198                mSubMesh[i].mSharedVertexBuffer                                 =       objmesh.mSubMesh[i].mSharedVertexBuffer; //.false; 
    138199                mSubMesh[i].mVertexBuffer                                                               =       new Geometry::VertexBuffer(); 
     
    142203                mSubMesh[i].mVertexBuffer->mVertexCount =       objmesh.mSubMesh[i].mVertexBuffer->mVertexCount; 
    143204                mSubMesh[i].mVertexBuffer->mVertexInfo  =       objmesh.mSubMesh[i].mVertexBuffer->mVertexInfo; 
    144                 mSubMesh[i].mType       =       objmesh.mSubMesh[i].mType; 
     205                mSubMesh[i].mType                                       =       objmesh.mSubMesh[i].mType; 
     206                strcpy(mSubMesh[i].mMaterialName,objmesh.mSubMesh[i].mMaterialName); 
    145207 
    146208                if (objmesh.mSubMesh[i].mSharedVertexBuffer && !copiados) 
     
    179241                mSubMesh[i].mIndex                      =       new Index[mSubMesh[i].mIndexCount]; 
    180242 
    181                 memcpy(mSubMesh[i].mIndex,objmesh.mSubMesh[i].mIndex,objmesh.mSubMesh[i].mIndexCount*sizeof(Geometry::Index)); 
     243                memcpy( mSubMesh[i].mIndex, 
     244                                                objmesh.mSubMesh[i].mIndex, 
     245                                                objmesh.mSubMesh[i].mIndexCount*sizeof(Geometry::Index)); 
    182246 
    183247                // Copiar las tiras 
    184                 __w64 Desp                                                      =       0; // desplazamiento entre posiciones de memoria. 
     248                __w64 offset    =       0; // desplazamiento entre posiciones de memoria. 
    185249                mSubMesh[i].mStripCount =       objmesh.mSubMesh[i].mStripCount; 
    186250 
     
    188252                { 
    189253                        mSubMesh[i].mStrip      =       new Index*[objmesh.mSubMesh[i].mStripCount]; 
    190                         Desp                                                            =       &(mSubMesh[i].mIndex[0]) - &(objmesh.mSubMesh[i].mIndex[0]); 
     254                        offset  =       &(mSubMesh[i].mIndex[0]) - &(objmesh.mSubMesh[i].mIndex[0]); 
    191255                         
    192256                        for (size_t j = 0; j < objmesh.mSubMesh[i].mStripCount; j++) 
    193257                        { 
    194                                 mSubMesh[i].mStrip[j]   =       objmesh.mSubMesh[i].mStrip[j] + Desp; 
    195                         } 
    196                 } 
    197                  
    198                 //OSCAR 
    199                 //Copio los bones 
     258                                mSubMesh[i].mStrip[j]   =       objmesh.mSubMesh[i].mStrip[j] + offset; 
     259                        } 
     260                } 
     261                 
     262                //      Copy submesh bones. 
    200263                if (!objmesh.mSubMesh[i].mBones.empty()) 
    201264                { 
     
    207270        } 
    208271 
    209         //OSCAR 
    210         //Copio el nombre del esqueleto 
     272        //      Copy skeleton name. 
    211273        if (objmesh.hasSkeleton) 
    212274        { 
     
    216278        } 
    217279 
    218         //OSCAR 
    219         //Copio los bones 
     280        //      Copy mesh bones. 
    220281        if (!objmesh.mBones.empty()) 
    221282        { 
     
    229290} 
    230291 
     292//--------------------------------------------------------------------------- 
     293//      Load mesh. 
     294//--------------------------------------------------------------------------- 
    231295void Mesh::Load(Serializer &s) 
    232296{ 
     
    256320} 
    257321 
     322//--------------------------------------------------------------------------- 
     323//      Save mesh. 
     324//--------------------------------------------------------------------------- 
    258325void Mesh::Save(Serializer &s) 
    259326{ 
     
    271338} 
    272339 
    273 // 26-12-2005 
     340//--------------------------------------------------------------------------- 
     341//      Export to obj mesh. 
     342//--------------------------------------------------------------------------- 
    274343void Mesh::exportToOBJ(char *nomfich) 
    275344{ 
     
    279348        obj << "begin" << std::endl; 
    280349        // Vértices 
    281         for (size_t i=0; i<this->mSubMeshCount; i++)  
    282         { 
    283                 for (size_t j=0; j<this->mSubMesh[i].mVertexBuffer->mVertexCount; j++)  
     350        for (size_t i=0; i < mSubMeshCount; i++)  
     351        { 
     352                for (size_t j=0; j < mSubMesh[i].mVertexBuffer->mVertexCount; j++)  
    284353                {        
    285                         obj << "v " <<  this->mSubMesh[i].mVertexBuffer->mPosition[j].x << " " << 
    286                                 this->mSubMesh[i].mVertexBuffer->mPosition[j].y << " " << 
    287                                 this->mSubMesh[i].mVertexBuffer->mPosition[j].z << " " << std::endl; 
     354                        obj << "v " <<  mSubMesh[i].mVertexBuffer->mPosition[j].x << " " << 
     355                                mSubMesh[i].mVertexBuffer->mPosition[j].y << " " << 
     356                                mSubMesh[i].mVertexBuffer->mPosition[j].z << " " << std::endl; 
    288357                } 
    289358        } 
     
    291360 
    292361        // Caras 
    293         for (size_t i=0; i<this->mSubMeshCount; i++)  
    294         { 
    295                 for (size_t j=0; j<this->mSubMesh[i].mIndexCount; j=j+3)  
     362        for (size_t i=0; i < mSubMeshCount; i++)  
     363        { 
     364                for (size_t j=0; j < mSubMesh[i].mIndexCount; j=j+3)  
    296365                {        
    297                         obj << "f " <<  this->mSubMesh[i].mIndex[j]+1 << " " <<  
    298                                 this->mSubMesh[i].mIndex[j+1]+1 << " " <<  
    299                                 this->mSubMesh[i].mIndex[j+2]+1 << std::endl; 
     366                        obj << "f " <<  mSubMesh[i].mIndex[j]+1 << " " <<  
     367                                mSubMesh[i].mIndex[j+1]+1 << " " <<  
     368                                mSubMesh[i].mIndex[j+2]+1 << std::endl; 
    300369                } 
    301370        } 
     
    305374} 
    306375 
    307 // 26-12-2005 
    308 Geometry::Mesh *Mesh::toSharedVertex()  
     376//--------------------------------------------------------------------------- 
     377// Transform to shared vertex mesh. 
     378//--------------------------------------------------------------------------- 
     379Mesh *Mesh::toSharedVertex()  
    309380{ 
    310381 
    311382        // Move all vertex to the shared vertex buffer. 
    312         Geometry::Mesh *mesh = new Geometry::Mesh(); 
    313  
    314         if (this->mSubMesh[0].mSharedVertexBuffer) 
     383        Mesh *mesh = new Mesh(); 
     384 
     385        if (mSubMesh[0].mSharedVertexBuffer) 
    315386        { 
    316387                *mesh   =       *this; 
     388                 
    317389                return  mesh; 
    318390        } 
    319391         
    320         mesh->mVertexBuffer=new VertexBuffer(); 
    321         mesh->mSubMeshCount = this->mSubMeshCount; 
     392        mesh->mVertexBuffer     =       new VertexBuffer(); 
     393        mesh->mSubMeshCount =   mSubMeshCount; 
     394         
    322395        // Reserva memoria para los submeshes 
    323         mesh->mSubMesh = new Geometry::SubMesh[this->mSubMeshCount]; 
    324  
    325         // construcción de los submeshes 
    326         long int acumVerts=0; 
    327         for (size_t i=0; i<mesh->mSubMeshCount; i++)  
    328         { 
    329                 mesh->mSubMesh[i].mSharedVertexBuffer=true; 
    330                 mesh->mSubMesh[i].mVertexBuffer=mesh->mVertexBuffer; 
    331                 mesh->mSubMesh[i].mStripCount=0; 
    332                 mesh->mSubMesh[i].mStrip=NULL; 
    333  
     396        mesh->mSubMesh  =       new SubMesh[mSubMeshCount]; 
     397 
     398        //      Fill up bounding box settings. 
     399        mesh->mMeshBounds.maxX                                  =       mMeshBounds.maxX; 
     400        mesh->mMeshBounds.maxY                                  =       mMeshBounds.maxY; 
     401        mesh->mMeshBounds.maxZ                                  =       mMeshBounds.maxZ; 
     402        mesh->mMeshBounds.minX                                  =       mMeshBounds.minX; 
     403        mesh->mMeshBounds.minY                                  =       mMeshBounds.minY; 
     404        mesh->mMeshBounds.minZ                                  =       mMeshBounds.minZ; 
     405        mesh->mMeshBounds.radius                                =       mMeshBounds.radius; 
     406        mesh->mMeshBounds.scaleFactor           =       mMeshBounds.scaleFactor; 
     407         
     408// construcción de los submeshes 
     409        long int acumVerts      =       0; 
     410         
     411        for (size_t i = 0; i < mesh->mSubMeshCount; i++) 
     412        { 
     413                mesh->mSubMesh[i].mSharedVertexBuffer   =       true; 
     414                mesh->mSubMesh[i].mVertexBuffer                         =       mesh->mVertexBuffer; 
     415                mesh->mSubMesh[i].mStripCount                                   =       0; 
     416                mesh->mSubMesh[i].mStrip                                                        =       NULL; 
     417                mesh->mSubMesh[i].mType                                                         =       mSubMesh[i].mType; 
     418                 
     419                strcpy(mesh->mSubMesh[i].mMaterialName,mSubMesh[i].mMaterialName); 
     420                 
    334421                // copiar los índices 
    335                 mesh->mSubMesh[i].mIndexCount=this->mSubMesh[i].mIndexCount; 
    336                 mesh->mSubMesh[i].mIndex=new Geometry::Index[this->mSubMesh[i].mIndexCount]; 
    337  
    338                 for (size_t j=0; j< this->mSubMesh[i].mIndexCount; j++)  
     422                mesh->mSubMesh[i].mIndexCount   =       mSubMesh[i].mIndexCount; 
     423                mesh->mSubMesh[i].mIndex                        =       new Index[mSubMesh[i].mIndexCount]; 
     424 
     425                for (size_t j = 0;      j < mSubMesh[i].mIndexCount;    j++) 
    339426                {  
    340                         mesh->mSubMesh[i].mIndex[j]     =       this->mSubMesh[i].mIndex[j]+acumVerts; 
    341                 } 
    342  
    343                 acumVerts       +=      this->mSubMesh[i].mVertexBuffer->mVertexCount; 
     427                        mesh->mSubMesh[i].mIndex[j]     =       mSubMesh[i].mIndex[j]+acumVerts; 
     428                } 
     429 
     430                acumVerts       +=      mSubMesh[i].mVertexBuffer->mVertexCount; 
    344431 
    345432                // Copiar las tiras 
    346                 int Desp=0; // desplazamiento entre posiciones de memoria. 
    347                 mesh->mSubMesh[i].mStripCount=this->mSubMesh[i].mStripCount; 
    348                 if (this->mSubMesh[i].mStripCount>0)  
    349                 { 
    350                         mesh->mSubMesh[i].mStrip = new Index*[this->mSubMesh[i].mStripCount]; 
    351  
    352                         Desp= &(mesh->mSubMesh[i].mIndex[0]) - &(this->mSubMesh[i].mIndex[0]); 
    353                         for (size_t j=0;j<this->mSubMesh[i].mStripCount;j++)  
    354                         { 
    355                                 mesh->mSubMesh[i].mStrip[j]=this->mSubMesh[i].mStrip[j] + Desp; 
    356                         } 
    357                 } 
    358         } 
    359          
    360         mesh->mVertexBuffer->mVertexCount=acumVerts; 
    361         mesh->mVertexBuffer->mVertexInfo=this->mSubMesh[0].mVertexBuffer->mVertexInfo; 
    362         mesh->mVertexBuffer->mPosition=new Geometry::Vector3[mesh->mVertexBuffer->mVertexCount]; 
    363         mesh->mVertexBuffer->mNormal=new Geometry::Vector3[mesh->mVertexBuffer->mVertexCount]; 
    364         mesh->mVertexBuffer->mTexCoords=new Geometry::Vector2[mesh->mVertexBuffer->mVertexCount]; 
    365          
     433                int offset      =       0; // desplazamiento entre posiciones de memoria. 
     434                 
     435                mesh->mSubMesh[i].mStripCount   =       mSubMesh[i].mStripCount; 
     436                 
     437                if (mSubMesh[i].mStripCount > 0) 
     438                { 
     439                        mesh->mSubMesh[i].mStrip        =       new Index*[mSubMesh[i].mStripCount]; 
     440 
     441                        offset  =       &(mesh->mSubMesh[i].mIndex[0]) - &(mSubMesh[i].mIndex[0]); 
     442                         
     443                        for (size_t j = 0;      j < mSubMesh[i].mStripCount;    j++) 
     444                        { 
     445                                mesh->mSubMesh[i].mStrip[j] = mSubMesh[i].mStrip[j] + offset; 
     446                        } 
     447                } 
     448        } 
     449         
     450        mesh->mVertexBuffer->mVertexCount       =       acumVerts; 
     451        mesh->mVertexBuffer->mVertexInfo        =       mSubMesh[0].mVertexBuffer->mVertexInfo; 
     452         
     453        mesh->mVertexBuffer->mPosition          =       new Vector3[mesh->mVertexBuffer->mVertexCount]; 
     454        mesh->mVertexBuffer->mNormal                    =       new Vector3[mesh->mVertexBuffer->mVertexCount]; 
     455        mesh->mVertexBuffer->mTexCoords         =       new Vector2[mesh->mVertexBuffer->mVertexCount]; 
     456 
    366457        // copiar los vértices 
    367         acumVerts=0; 
    368         size_t newIndex; 
    369         for (size_t i=0; i<this->mSubMeshCount; i++)  
    370         { 
    371                 for(size_t j=0;j<this->mSubMesh[i].mVertexBuffer->mVertexCount;j++) 
    372                 { 
    373                         newIndex=acumVerts+j; 
    374                         mesh->mVertexBuffer->mPosition[newIndex].x=this->mSubMesh[i].mVertexBuffer->mPosition[j].x; 
    375                         mesh->mVertexBuffer->mPosition[newIndex].y=this->mSubMesh[i].mVertexBuffer->mPosition[j].y; 
    376                         mesh->mVertexBuffer->mPosition[newIndex].z=this->mSubMesh[i].mVertexBuffer->mPosition[j].z; 
    377  
    378                         mesh->mVertexBuffer->mNormal[newIndex].x=this->mSubMesh[i].mVertexBuffer->mNormal[j].x; 
    379                         mesh->mVertexBuffer->mNormal[newIndex].y=this->mSubMesh[i].mVertexBuffer->mNormal[j].y; 
    380                         mesh->mVertexBuffer->mNormal[newIndex].z=this->mSubMesh[i].mVertexBuffer->mNormal[j].z; 
    381  
    382                         mesh->mVertexBuffer->mTexCoords[newIndex].x=this->mSubMesh[i].mVertexBuffer->mTexCoords[j].x; 
    383                         mesh->mVertexBuffer->mTexCoords[newIndex].y=this->mSubMesh[i].mVertexBuffer->mTexCoords[j].y; 
    384                 } 
    385                 acumVerts+=this->mSubMesh[i].mVertexBuffer->mVertexCount; 
     458        acumVerts       =       0; 
     459         
     460        size_t  newIndex; 
     461         
     462        for (size_t i = 0; i < mSubMeshCount;   i++) 
     463        { 
     464                for(size_t j = 0; j < mSubMesh[i].mVertexBuffer->mVertexCount; j++) 
     465                { 
     466                        newIndex        =       acumVerts + j; 
     467                         
     468                        mesh->mVertexBuffer-> 
     469                                                mPosition[newIndex].x   =       mSubMesh[i].mVertexBuffer-> 
     470                                                                                                                                                                                                mPosition[j].x; 
     471                         
     472                        mesh->mVertexBuffer-> 
     473                                                mPosition[newIndex].y   =       mSubMesh[i].mVertexBuffer-> 
     474                                                                                                                                                                                                mPosition[j].y; 
     475                         
     476                        mesh->mVertexBuffer-> 
     477                                                mPosition[newIndex].z   =       mSubMesh[i].mVertexBuffer-> 
     478                                                                                                                                                                                                mPosition[j].z; 
     479 
     480                        mesh->mVertexBuffer-> 
     481                                                mNormal[newIndex].x     =       mSubMesh[i].mVertexBuffer-> 
     482                                                                                                                                                                                        mNormal[j].x; 
     483                         
     484                        mesh->mVertexBuffer-> 
     485                                                mNormal[newIndex].y     =       mSubMesh[i].mVertexBuffer-> 
     486                                                                                                                                                                                        mNormal[j].y; 
     487                         
     488                        mesh->mVertexBuffer-> 
     489                                                mNormal[newIndex].z     =       mSubMesh[i].mVertexBuffer-> 
     490                                                                                                                                                                                        mNormal[j].z; 
     491 
     492                        mesh->mVertexBuffer-> 
     493                                                mTexCoords[newIndex].x  =       mSubMesh[i].mVertexBuffer-> 
     494                                                                                                                                                                                                        mTexCoords[j].x; 
     495                         
     496                        mesh->mVertexBuffer-> 
     497                                                mTexCoords[newIndex].y  =       mSubMesh[i].mVertexBuffer-> 
     498                                                                                                                                                                                                        mTexCoords[j].y; 
     499                } 
     500                 
     501                acumVerts       +=      mSubMesh[i].mVertexBuffer->mVertexCount; 
    386502        } 
    387503 
  • GTP/trunk/Lib/Geom/shared/GTGeometry/src/GeoMeshSimplifier.cpp

    r891 r980  
    88using namespace std; 
    99 
    10 MeshSimplifier::MeshSimplifier( const Geometry::Mesh    *m, 
    11                                                                                                                                 Geometry::TIPOFUNC              upb) 
     10//////////////////////////////////////////////////////////////////////////// 
     11//                                                                                                                                                                                                                                                                                              // 
     12//                                                                                      MeshSimplifier class                                                                                                                    // 
     13//                                                                                                                                                                                                                                                                                              // 
     14//////////////////////////////////////////////////////////////////////////// 
     15 
     16//--------------------------------------------------------------------------- 
     17//      MeshSimplifier constructor. 
     18//--------------------------------------------------------------------------- 
     19MeshSimplifier::MeshSimplifier( const Mesh      *m, 
     20                                                                                                                                TIPOFUNC                upb) 
    1221{ 
    1322        objmesh                                 =       m; 
    14         meshsalida                      =       NULL; 
     23        mGeoMesh                                =       NULL; 
    1524        msimpsequence           =       NULL; 
    1625        indexMeshLeaves =       -1; 
     
    2029} 
    2130 
     31//--------------------------------------------------------------------------- 
     32//      MeshSimplifier destroyer. 
     33//--------------------------------------------------------------------------- 
    2234MeshSimplifier::~MeshSimplifier() 
    2335{ 
     
    2537} 
    2638 
     39//--------------------------------------------------------------------------- 
    2740// Returns the simplified mesh. 
    28 Geometry::Mesh *MeshSimplifier::GetMesh () 
    29 { 
    30         return meshsalida; 
    31 } 
    32  
    33 void MeshSimplifier::setMeshLeaves(Geometry::Index index) 
     41//--------------------------------------------------------------------------- 
     42Mesh *  MeshSimplifier::GetMesh() 
     43{ 
     44        return mGeoMesh; 
     45} 
     46 
     47//--------------------------------------------------------------------------- 
     48//      Set submesh leaves 
     49//--------------------------------------------------------------------------- 
     50void MeshSimplifier::setMeshLeaves(Index index) 
    3451{ 
    3552        indexMeshLeaves =       index; 
    3653} 
    3754 
     55//--------------------------------------------------------------------------- 
    3856// Returns the simplification sequence for general meshes. 
    39 Geometry::MeshSimplificationSequence *MeshSimplifier::GetSimplificationSequence() 
     57//--------------------------------------------------------------------------- 
     58MeshSimplificationSequence *MeshSimplifier::GetSimplificationSequence() 
    4059{ 
    4160        return msimpsequence; 
    4261} 
    4362 
    44 GeometryBasedSimplifier::GeometryBasedSimplifier (const Geometry::Mesh  *m, 
    45                                                                                                                                                                                 Geometry::TIPOFUNC              upb) 
    46                                                                                                                                                                                 :MeshSimplifier(m,upb) 
    47 { 
    48 } 
    49  
     63//////////////////////////////////////////////////////////////////////////// 
     64//                                                                                                                                                                                                                                                                                              // 
     65//                                                                      GeometryBasedSimplifier class                                                                                                   // 
     66//                                                                                                                                                                                                                                                                                              // 
     67//////////////////////////////////////////////////////////////////////////// 
     68 
     69//--------------------------------------------------------------------------- 
     70//--------------------------------------------------------------------------- 
     71GeometryBasedSimplifier::GeometryBasedSimplifier(       const Mesh      *m, 
     72                                                                                                                                                                                                        TIPOFUNC                upb) 
     73                                                                                                                                                                                                :MeshSimplifier(m,upb) 
     74{ 
     75} 
     76 
     77//--------------------------------------------------------------------------- 
     78//--------------------------------------------------------------------------- 
    5079GeometryBasedSimplifier::~GeometryBasedSimplifier() 
    5180{ 
    5281} 
    5382 
     83//--------------------------------------------------------------------------- 
    5484// Starts the simplification process. Receives as a parameter the LOD factor in a range of [0,1]. Implements the Simplifier::Simplify method to perform an image based simplification. 
    55 void GeometryBasedSimplifier::Simplify (Geometry::Real paramlod) 
     85//--------------------------------------------------------------------------- 
     86void GeometryBasedSimplifier::Simplify(Real paramlod) 
    5687{ 
    5788        SimplificationMethod *m_qslim   =       new SimplificationMethod(objmesh); 
     
    5990        m_qslim->setMeshLeaves(indexMeshLeaves); 
    6091         
    61         msimpsequence   =       m_qslim->Decimate(paramlod,&meshsalida,0,mUPB); 
     92        msimpsequence   =       m_qslim->Decimate(paramlod,0,mUPB); 
     93         
     94        mGeoMesh        =       m_qslim->GetMesh(); 
    6295         
    6396        delete  m_qslim; 
    6497} 
    6598 
     99//--------------------------------------------------------------------------- 
    66100// Starts the simplification process. Receives as a parameter the number of vertices of the resulting mesh. Implements the Simplifier::Simplify method to perform an image based simplification. 
    67 void GeometryBasedSimplifier::Simplify (Geometry::uint32 numvertices) 
     101//--------------------------------------------------------------------------- 
     102void GeometryBasedSimplifier::Simplify(uint32 numvertices) 
    68103{ 
    69104        SimplificationMethod *m_qslim   =       new SimplificationMethod(objmesh); 
     
    71106        m_qslim->setMeshLeaves(indexMeshLeaves); 
    72107         
    73         msimpsequence   =       m_qslim->Decimate((float)numvertices,&meshsalida,1,mUPB); 
     108        msimpsequence   =       m_qslim->Decimate((float)numvertices,1,mUPB); 
     109 
     110        mGeoMesh        =       m_qslim->GetMesh(); 
    74111         
    75112        delete m_qslim; 
    76113} 
    77114 
     115//////////////////////////////////////////////////////////////////////////// 
     116//                                                                                                                                                                                                                                                                                              // 
     117//                                                              ViewPointDrivenSimplifier class                                                                                                 // 
     118//                                                                                                                                                                                                                                                                                              // 
     119//////////////////////////////////////////////////////////////////////////// 
     120 
     121//--------------------------------------------------------------------------- 
     122/// Class constructor. Will call Simplifier class constructor. 
     123//--------------------------------------------------------------------------- 
     124ViewPointDrivenSimplifier::ViewPointDrivenSimplifier(   const Mesh      *m, 
     125                                                                                                                                                                                                                        TIPOFUNC                upb) 
     126                                                                                                                                                                                                                :MeshSimplifier(m,upb) 
     127{ 
     128        //char s[MAX_CHAR]; 
     129 
     130        //      Set progress update function 
     131        VMI::mUPB       =       upb; 
     132         
     133        VMI::width  = 256; 
     134        VMI::height = 256; 
     135 
     136        VMI::bEnableOffScreen     = GL_TRUE; 
     137        VMI::bBeQuiet             = GL_FALSE; 
     138        VMI::bSaveLog             = GL_FALSE; 
     139        VMI::bLoadCamerasFromFile = GL_FALSE; 
     140 
     141        VMI::cameraType = 1; 
     142        VMI::radius = 1.3; 
     143        VMI::fov = 60.0; 
     144 
     145        printf("w: %d h: %d\n", VMI::width, VMI::height); 
     146 
     147        printf( "t: %d c: %d o: %d r: %f\n", 
     148                        VMI::numDemandedTriangles, 
     149                        VMI::cameraType, 
     150                        VMI::bEnableOffScreen, 
     151                        VMI::radius); 
     152 
     153 
     154        mGeoMesh        =       new Mesh(); 
     155         
     156        *mGeoMesh       =       *m; 
     157         
     158        //      Transform NoSV Mesh to a SV Mesh. 
     159        mGeoMesh        =       mGeoMesh->toSharedVertex(); 
     160 
     161        //      Loads the vmi mesh structure for a geometry mesh given. 
     162        VMI::mesh = initMeshStructure(mGeoMesh); 
     163         
     164        //VMI::printMesh(mesh); 
     165        //getchar(); 
     166 
     167        // Get a filename without extension 
     168        //strncpy(VMI::filename, argv[argc - 1], strlen(argv[argc - 1]) - 4); 
     169 
     170        //glutInit(&argc, argv); 
     171        glutInitDisplayMode(GLUT_DEPTH | GLUT_RGBA | GLUT_DOUBLE | GLUT_ALPHA); /* RGB and Alpha */ 
     172        glutInitWindowSize(VMI::width, VMI::height); 
     173        glutInitWindowPosition(100, 100); 
     174 
     175        //#ifdef KL // Kullback-Leibler 
     176        //    sprintf(s, "VKL - [%s]", argv[argc-1]);  
     177        //#endif 
     178        //#ifdef MI // Mutual Information 
     179        //    sprintf(s, "VMI - [%s]", argv[argc-1]);  
     180        //#endif 
     181        //#ifdef HE // Hellinger 
     182        //    sprintf(s, "VHE - [%s]", argv[argc-1]);  
     183        //#endif 
     184        //#ifdef CS // Chi-Square 
     185        //    sprintf(s, "VCS - [%s]", argv[argc-1]);  
     186        //#endif 
     187 
     188        VMI::vmiWin     =       glutCreateWindow("VMI"/*s*/); 
     189 
     190        glewInit(); 
     191 
     192        VMI::init(); 
     193 
     194        if (VMI::bLoadCamerasFromFile == GL_FALSE) 
     195        { 
     196                switch (VMI::cameraType) 
     197                { 
     198                        case 0: 
     199                                VMI::cameras = VMI::setCameras(VMI::radius, OCTAHEDRON, &VMI::numCameras); 
     200                                printf("Number of cameras: %d\n", OCTAHEDRON); 
     201                                break; 
     202                        case 1: 
     203                                VMI:: cameras = VMI::setCameras(VMI::radius, ICOSAHEDRON, &VMI::numCameras); 
     204                                printf("Number of cameras: %d\n", ICOSAHEDRON); 
     205                                break; 
     206                        case 2: 
     207                                VMI::cameras = VMI::setCameras(VMI::radius, DODECAHEDRON, &VMI::numCameras); 
     208                                printf("Number of cameras: %d\n", DODECAHEDRON); 
     209                                break; 
     210                        default: 
     211                                break; 
     212                } 
     213        } 
     214        else  
     215        { 
     216                // Loads a cameras file 
     217                //sprintf(s,"%s.cam", VMI::filename); 
     218 
     219                //VMI::cameras = VMI::loadCameras(VMI::radius, s, &VMI::numCameras); 
     220                //getchar(); 
     221        } 
     222 
     223        VMI::histogram  =       VMI::initHistogram(     VMI::mesh->currentNumTriangles, 
     224                                                                                                                                                                VMI::numCameras); 
     225 
     226        VMI::initialIs  =       VMI::initIs(VMI::numCameras); 
     227 
     228} 
     229 
     230//--------------------------------------------------------------------------- 
     231/// Class destructor. 
     232//--------------------------------------------------------------------------- 
     233ViewPointDrivenSimplifier::~ViewPointDrivenSimplifier(void) 
     234{ 
     235        // Free memory 
     236         VMI::freeMemory(); 
     237} 
     238 
     239/// Copy constructor 
     240//ViewPointDrivenSimplifier(const ViewPointDrivenSimplifier&); 
     241 
     242/// Assignment operator 
     243//ViewPointDrivenSimplifier& operator =(const ViewPointDrivenSimplifier&); 
     244 
     245/// Starts the simplification process. Receives as a parameter the LOD factor in a range of [0,1]. Implements the Simplifier::Simplify method to perform an image based simplification. 
     246void ViewPointDrivenSimplifier::Simplify(Real percent) 
     247{ 
     248        // TODO: parametros libreria globales 
     249 
     250 
     251        VMI::numDemandedTriangles = (int)(VMI::mesh->numTriangles * percent); 
     252 
     253        if ((VMI::numDemandedTriangles == 0) 
     254                        || 
     255                        (VMI::numDemandedTriangles >= VMI::mesh->currentNumTriangles)) 
     256        { 
     257                printf("Illegal number of triangles.\n"); 
     258        } 
     259 
     260        VMI::display(); 
     261 
     262        //      Load a geometry mesh for vmi mesh. 
     263        loadMesh(); 
     264} 
     265 
     266//--------------------------------------------------------------------------- 
     267/// Starts the simplification process. Receives as a parameter the number of vertices of the resulting mesh. Implements the Simplifier::Simplify method to perform an image based simplification. 
     268//--------------------------------------------------------------------------- 
     269void ViewPointDrivenSimplifier::Simplify(uint32 numVertices) 
     270{ 
     271        float   percent; 
     272 
     273        percent =       (numVertices    *       100.0) / VMI::mesh->numVertices; 
     274 
     275        VMI::numDemandedTriangles = (int)(VMI::mesh->numTriangles * (percent / 100)); 
     276 
     277        if ((VMI::numDemandedTriangles == 0) 
     278                        || 
     279                        (VMI::numDemandedTriangles >= VMI::mesh->currentNumTriangles)) 
     280        { 
     281                printf("Illegal number of triangles.\n"); 
     282        } 
     283 
     284        VMI::display(); 
     285 
     286        //      Load a geometry mesh for vmi mesh. 
     287        loadMesh(); 
     288 
     289} 
     290 
     291// Returns the simplified mesh. 
     292//Mesh  *       ViewPointDrivenSimplifier::GetMesh() 
     293//{ 
     294//      return mGeoMesh; 
     295//} 
     296 
     297//--------------------------------------------------------------------------- 
     298//      Init vmi mesh structure for a geometry mesh given. 
     299//--------------------------------------------------------------------------- 
     300VMI::Mesh *     ViewPointDrivenSimplifier::initMeshStructure(Mesh       *geoMesh) 
     301{ 
     302        GLuint                          i, j, v1, v2, v3, n, e, t; 
     303        VMI::Mesh               *vmi_mesh; 
     304        SubMesh                         *geosubmesh; 
     305        VertexBuffer    *vertex_buffer; 
     306        int                                             mesh_index_count; 
     307        int                                             index; 
     308 
     309        //      Reallocate memory for vmi mesh object. 
     310        vmi_mesh = (VMI::Mesh *)malloc(sizeof(VMI::Mesh)); 
     311 
     312        if (vmi_mesh == NULL) 
     313        { 
     314                fprintf(stderr, "Error allocating memory\n"); 
     315                exit(1); 
     316        } 
     317 
     318        //      Shared vertex buffer. 
     319        vertex_buffer   =       geoMesh->mVertexBuffer; 
     320         
     321        //      Reallocate memory for vertices of mesh. 
     322        vmi_mesh->vertices = (VMI::Vertex *)malloc(sizeof(VMI::Vertex) 
     323                                                                                                                                                                * 
     324                                                                                                                                                                vertex_buffer->mVertexCount); 
     325 
     326        if (vmi_mesh->vertices == NULL) 
     327        { 
     328                fprintf(stderr, "Error allocating memory\n"); 
     329                exit(1); 
     330        } 
     331 
     332        //      Initialize mesh index count. 
     333        mesh_index_count        =       0; 
     334         
     335        for (int submesh        =       0; submesh < mGeoMesh->mSubMeshCount; submesh++) 
     336        { 
     337                mesh_index_count        +=      mGeoMesh->mSubMesh[submesh].mIndexCount; 
     338        } 
     339         
     340        //      Reallocate memory for indices. 
     341        vmi_mesh->triangles = (VMI::Triangle *)malloc(sizeof(VMI::Triangle) 
     342                                                                                                                                                                                * 
     343                                                                                                                                                                                (mesh_index_count / 3)); 
     344 
     345        if (vmi_mesh->triangles == NULL) 
     346        { 
     347                fprintf(stderr, "Error allocating memory\n"); 
     348                exit(1); 
     349        } 
     350 
     351        printf("Adding vertices..."); 
     352         
     353        //      Fill up vertices. 
     354        for (i = 0; i < vertex_buffer->mVertexCount; i++) 
     355        { 
     356                // Vertices start at 0. 
     357                vmi_mesh->vertices[i].x = vertex_buffer->mPosition[i].x; 
     358                vmi_mesh->vertices[i].y = vertex_buffer->mPosition[i].y; 
     359                vmi_mesh->vertices[i].z = vertex_buffer->mPosition[i].z; 
     360                 
     361                vmi_mesh->vertices[i].numTriangles = 0; 
     362                vmi_mesh->vertices[i].triangles = NULL; 
     363                vmi_mesh->vertices[i].enable = GL_TRUE; 
     364        } 
     365         
     366        printf("Ok\n"); 
     367        vmi_mesh->numVertices = vertex_buffer->mVertexCount; 
     368        vmi_mesh->currentNumVertices = vertex_buffer->mVertexCount; 
     369 
     370        //      Fill up triangles. 
     371        printf("Adding triangles..."); 
     372         
     373        //      Initialize index of triangle. 
     374        index   =       0; 
     375         
     376        //      For each submesh. 
     377        for (int submesh        =       0; submesh      <       mGeoMesh->mSubMeshCount; submesh++) 
     378        { 
     379                //      Gets actual submesh. 
     380                geosubmesh      =       &mGeoMesh->mSubMesh[submesh]; 
     381                 
     382                for (i = 0; i < (geosubmesh->mIndexCount / 3); i++) 
     383                { 
     384                        vmi_mesh->triangles[index].id                           = index; 
     385                        vmi_mesh->triangles[index].submesh              = submesh; 
     386                        vmi_mesh->triangles[index].indices[0] = geosubmesh->mIndex[(3 * i)]; 
     387                        vmi_mesh->triangles[index].indices[1] = geosubmesh->mIndex[(3 * i) + 1]; 
     388                        vmi_mesh->triangles[index].indices[2] = geosubmesh->mIndex[(3 * i) + 2]; 
     389 
     390                        vmi_mesh->triangles[index].area = computeTriangleArea(vmi_mesh->vertices,  
     391                                        &vmi_mesh->triangles[index]); 
     392                        //printf("\n%d a: %f",index , vmi_mesh->triangles[index].area); 
     393                        computeTriangleNormal(vmi_mesh->vertices, &vmi_mesh->triangles[index]); 
     394 
     395                        vmi_mesh->triangles[index].saliency = 0.0; 
     396 
     397                        vmi_mesh->triangles[index].enable = GL_TRUE; 
     398 
     399                        for (j = 0; j < 3; j++) 
     400                        { 
     401                                // Adding triangle index adjacent to 3 vertices 
     402                                v1 = vmi_mesh->triangles[index].indices[j]; 
     403 
     404                                // Reallocate memory for the new adjacent triangle 
     405                                vmi_mesh->vertices[v1].triangles = (GLuint *)realloc(vmi_mesh->vertices[v1].triangles, (vmi_mesh->vertices[v1].numTriangles + 1) * sizeof(GLuint)); 
     406                                VMI::addItem((int *)vmi_mesh->vertices[v1].triangles, (int *)&vmi_mesh->vertices[v1].numTriangles, index); 
     407                        } 
     408 
     409                        //      Increments triangle count. 
     410                        index++; 
     411                } 
     412        } 
     413         
     414        //printf("\n"); 
     415        printf("Ok\n"); 
     416 
     417        vmi_mesh->numTriangles                          = mesh_index_count / 3; 
     418        vmi_mesh->currentNumTriangles = mesh_index_count / 3; 
     419 
     420        printf("Num Triangles: %d\n",vmi_mesh->numTriangles); 
     421         
     422        // E = 3 T / 2 
     423        vmi_mesh->edges = (VMI::Edge *)malloc(sizeof(VMI::Edge) 
     424                                                                                                                                                * 
     425                                                                                                                                                vmi_mesh->numTriangles * 3); 
     426 
     427        if (vmi_mesh->edges == NULL) 
     428        { 
     429                fprintf(stderr, "Error allocating memory\n"); 
     430                exit(1); 
     431        } 
     432 
     433        // Init edges 
     434        for (i=0; i<vmi_mesh->numTriangles * 3; i++) 
     435        { 
     436                vmi_mesh->edges[i].triangles    = NULL; 
     437                vmi_mesh->edges[i].numTriangles = 0; 
     438        } 
     439 
     440        printf("Adding edges..."); 
     441        n = 0; 
     442 
     443        for (i=0; i<vmi_mesh->numTriangles; i++) 
     444        { 
     445                t               =       0; 
     446                v1      =       vmi_mesh->triangles[i].indices[0]; 
     447                v2      =       vmi_mesh->triangles[i].indices[1]; 
     448                v3      =       vmi_mesh->triangles[i].indices[2]; 
     449 
     450                if ((e = findEdge(vmi_mesh->edges, n, v1, v2)) == -1) 
     451                { 
     452                        vmi_mesh->edges[n].u                    =       v1; 
     453                        vmi_mesh->edges[n].v                    =       v2; 
     454                        vmi_mesh->edges[n].enable =     GL_TRUE; 
     455 
     456                        // Reallocate memory for the new adjacent triangle 
     457                        vmi_mesh->edges[n].triangles = (GLuint *)realloc(vmi_mesh->edges[n].triangles, (vmi_mesh->edges[n].numTriangles + 1) * sizeof(GLuint)); 
     458                        // Adding triangle i adjacent to edge n 
     459                        VMI::addItem((int *)vmi_mesh->edges[n].triangles, (int *)&vmi_mesh->edges[n].numTriangles, i); 
     460                        //printf("n:%d i:%d\n", n, i); 
     461 
     462                        // Adding edge n adjacent to triangle i 
     463                        VMI::addItem((int *)vmi_mesh->triangles[i].edges, (int *)&t, n); 
     464                        n++; 
     465                } 
     466                else 
     467                { 
     468                        // Reallocate memory for the new adjacent triangle. 
     469                        vmi_mesh->edges[e].triangles = (GLuint *)realloc(vmi_mesh->edges[e].triangles, (vmi_mesh->edges[e].numTriangles + 1) * sizeof(GLuint)); 
     470                        // Adding triangle i adjacent to edge e 
     471                        VMI::addItem((int *)vmi_mesh->edges[e].triangles, (int *)&vmi_mesh->edges[e].numTriangles, i); 
     472                        //printf("n:%d i:%d\n", e, i); 
     473 
     474                        // Adding edge e adjacent to triangle i 
     475                        VMI::addItem((int *)vmi_mesh->triangles[i].edges, (int *)&t, e); 
     476                } 
     477                if ((e = findEdge(vmi_mesh->edges, n, v2, v3)) == -1) 
     478                { 
     479                        vmi_mesh->edges[n].u = v2; 
     480                        vmi_mesh->edges[n].v = v3; 
     481                        vmi_mesh->edges[n].enable = GL_TRUE; 
     482 
     483                        // Reallocate memory for the new adjacent triangle 
     484                        vmi_mesh->edges[n].triangles = (GLuint *)realloc(vmi_mesh->edges[n].triangles, (vmi_mesh->edges[n].numTriangles + 1) * sizeof(GLuint)); 
     485                        // Adding triangle i adjacent to edge n 
     486                        VMI::addItem((int *)vmi_mesh->edges[n].triangles, (int *)&vmi_mesh->edges[n].numTriangles, i); 
     487                        //printf("n:%d i:%d\n", n, i); 
     488 
     489                        // Adding edge n adjacent to triangle i 
     490                        VMI::addItem((int *)vmi_mesh->triangles[i].edges, (int *)&t, n); 
     491                        n++; 
     492                } 
     493                else 
     494                { 
     495                        // Reallocate memory for the new adjacent triangle 
     496                        vmi_mesh->edges[e].triangles = (GLuint *)realloc(vmi_mesh->edges[e].triangles, (vmi_mesh->edges[e].numTriangles + 1) * sizeof(GLuint)); 
     497                        // Adding triangle i adjacent to edge e 
     498                        VMI::addItem((int *)vmi_mesh->edges[e].triangles, (int *)&vmi_mesh->edges[e].numTriangles, i); 
     499                        //printf("n:%d i:%d\n", e, i); 
     500 
     501                        // Adding edge e adjacent to triangle i 
     502                        VMI::addItem((int *)vmi_mesh->triangles[i].edges, (int *)&t, e); 
     503                } 
     504                 
     505                if ((e = findEdge(vmi_mesh->edges, n, v3, v1)) == -1) 
     506                { 
     507                        vmi_mesh->edges[n].u = v3; 
     508                        vmi_mesh->edges[n].v = v1; 
     509                        vmi_mesh->edges[n].enable = GL_TRUE; 
     510 
     511                        // Reallocate memory for the new adjacent triangle 
     512                        vmi_mesh->edges[n].triangles = (GLuint *)realloc(vmi_mesh->edges[n].triangles, (vmi_mesh->edges[n].numTriangles + 1) * sizeof(GLuint)); 
     513                        // Adding triangle i adjacent to edge n 
     514                        VMI::addItem((int *)vmi_mesh->edges[n].triangles, (int *)&vmi_mesh->edges[n].numTriangles, i); 
     515                        //printf("n:%d i:%d\n", n, i); 
     516 
     517                        // Adding edge n adjacent to triangle i 
     518                        VMI::addItem((int *)vmi_mesh->triangles[i].edges, (int *)&t, n); 
     519                        n++; 
     520                } 
     521                else 
     522                { 
     523                        // Reallocate memory for the new adjacent triangle 
     524                        vmi_mesh->edges[e].triangles = (GLuint *)realloc(vmi_mesh->edges[e].triangles, (vmi_mesh->edges[e].numTriangles + 1) * sizeof(GLuint)); 
     525                        // Adding triangle i adjacent to edge e 
     526                        VMI::addItem((int *)vmi_mesh->edges[e].triangles, (int *)&vmi_mesh->edges[e].numTriangles, i); 
     527                        //printf("n:%d i:%d\n", e, i); 
     528 
     529                        // Adding edge e adjacent to triangle i 
     530                        VMI::addItem((int *)vmi_mesh->triangles[i].edges, (int *)&t, e); 
     531                } 
     532        } 
     533         
     534        printf("Ok\n"); 
     535        vmi_mesh->numEdges = n; 
     536 
     537        return vmi_mesh; 
     538} 
     539 
     540//--------------------------------------------------------------------------- 
     541//      Gets the geometry mesh of a  the vmi mesh given. 
     542//--------------------------------------------------------------------------- 
     543void    ViewPointDrivenSimplifier::loadMesh() 
     544{ 
     545        int                                             num_indices; 
     546        SubMesh                         *geosubmesh; 
     547        VertexBuffer    *vertex_buffer; 
     548         
     549        //      Gets old vertex buffer. 
     550        vertex_buffer   =       mGeoMesh->mVertexBuffer; 
     551         
     552        //      Initialize auxiliar vertex buffer. 
     553        mVB     =       new     VertexBuffer(); 
     554         
     555        mVB->mPosition          =       new     Vector3[VMI::mesh->currentNumVertices]; 
     556        mVB->mNormal                    =       new     Vector3[VMI::mesh->currentNumVertices]; 
     557        mVB->mTexCoords         =       new     Vector2[VMI::mesh->currentNumVertices]; 
     558 
     559        mVB->mVertexInfo        =       vertex_buffer->mVertexInfo; 
     560 
     561        //      For each submesh. 
     562        for (int submesh        =       0; submesh < mGeoMesh->mSubMeshCount; submesh++) 
     563        { 
     564                geosubmesh      =       &mGeoMesh->mSubMesh[submesh]; 
     565 
     566                delete  []geosubmesh->mIndex; 
     567 
     568                //      Initialize submesh index count; 
     569                num_indices     =       0; 
     570 
     571                //      For each triangle. 
     572                for (int i = 0; i < VMI::mesh->numTriangles; i++) 
     573                { 
     574                        //      If is enable and of the current submesh. 
     575                        if ((VMI::mesh->triangles[i].enable) 
     576                                        && 
     577                                        (VMI::mesh->triangles[i].submesh == submesh)) 
     578                        { 
     579                                //      Increments submesh index count. 
     580                                num_indices     +=      3; 
     581                        } 
     582                } 
     583 
     584                geosubmesh->mIndexCount =       num_indices; 
     585 
     586                geosubmesh->mIndex      =       new Index[geosubmesh->mIndexCount]; 
     587 
     588                //      Initialize number of indices. 
     589                num_indices     =       0; 
     590 
     591                //      Fill up indices. 
     592                for (int i = 0; i < VMI::mesh->numTriangles; i++) 
     593                { 
     594                        if ((VMI::mesh->triangles[i].enable) 
     595                                        && 
     596                                        (VMI::mesh->triangles[i].submesh == submesh)) 
     597                        { 
     598                                geosubmesh->mIndex[num_indices++]       =       VMI::mesh->triangles[i].indices[0]; 
     599                                geosubmesh->mIndex[num_indices++]       =       VMI::mesh->triangles[i].indices[1]; 
     600                                geosubmesh->mIndex[num_indices++]       =       VMI::mesh->triangles[i].indices[2]; 
     601                        } 
     602                } 
     603 
     604                //      For each index. 
     605                for (int i = 0; i < geosubmesh->mIndexCount; i++) 
     606                { 
     607                        findVertex(submesh,i); 
     608                } 
     609 
     610                geosubmesh->mVertexBuffer       =       mVB; 
     611        } 
     612 
     613        delete  vertex_buffer; 
     614         
     615        mGeoMesh->mVertexBuffer =       mVB; 
     616 
     617} 
     618 
     619//--------------------------------------------------------------------------- 
     620//      Find vertex in auxiliar vertex buffer. 
     621//--------------------------------------------------------------------------- 
     622void    ViewPointDrivenSimplifier::findVertex(size_t    submesh, size_t elem) 
     623{ 
     624        bool                                    found; 
     625        int                                             index; 
     626        int                                             i; 
     627        int                                             new_elem; 
     628        VertexBuffer    *vertex_buffer; 
     629 
     630        found   =       false; 
     631 
     632        //      Shared vertex buffer. 
     633        vertex_buffer   =       mGeoMesh->mVertexBuffer; 
     634         
     635        index   =       mGeoMesh->mSubMesh[submesh].mIndex[elem]; 
     636         
     637        i       =       0; 
     638         
     639        while (!found && (i < mVB->mVertexCount)) 
     640        { 
     641                if ((VMI::mesh->vertices[index].x == mVB->mPosition[i].x) 
     642                                && 
     643                                (VMI::mesh->vertices[index].y == mVB->mPosition[i].y) 
     644                                && 
     645                                (VMI::mesh->vertices[index].z == mVB->mPosition[i].z)) 
     646                { 
     647                        found   =       true; 
     648 
     649                        //      Update index. 
     650                        mGeoMesh->mSubMesh[submesh].mIndex[elem]        =        i; 
     651                } 
     652 
     653                //      Increments index. 
     654                i++; 
     655        } 
     656 
     657        if (!found) 
     658        { 
     659                //      Last element. 
     660                new_elem        =       mVB->mVertexCount; 
     661                 
     662                //      Add to last. 
     663                mVB->mPosition[new_elem].x      =       VMI::mesh->vertices[index].x; 
     664                mVB->mPosition[new_elem].y      =       VMI::mesh->vertices[index].y; 
     665                mVB->mPosition[new_elem].z      =       VMI::mesh->vertices[index].z; 
     666 
     667                mVB->mNormal[new_elem].x        =       vertex_buffer->mNormal[index].x; 
     668                mVB->mNormal[new_elem].y        =       vertex_buffer->mNormal[index].y; 
     669                mVB->mNormal[new_elem].z        =       vertex_buffer->mNormal[index].z; 
     670 
     671                mVB->mTexCoords[new_elem].x     =       vertex_buffer->mTexCoords[index].x; 
     672                mVB->mTexCoords[new_elem].y     =       vertex_buffer->mTexCoords[index].y; 
     673 
     674                //      Update index. 
     675                mGeoMesh->mSubMesh[submesh].mIndex[elem]        =        new_elem; 
     676 
     677                //      Increments vertex count. 
     678                mVB->mVertexCount++; 
     679        } 
     680} 
     681 
  • GTP/trunk/Lib/Geom/shared/GTGeometry/src/GeoMeshStripifier.cpp

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

    r774 r980  
    22 
    33 
    4 namespace Geometry { 
    5  
    6     //--------------------------------------------------------------------- 
     4namespace Geometry 
     5{ 
     6        //--------------------------------------------------------------------- 
    77        Serializer::Serializer(String name, Mode mode) 
    88                : mMode(mode) 
    9         { 
    10                 char *char_mode = 0; 
    11                 switch (mMode) 
    12                 { 
    13                 case READ :  
    14                         char_mode = "rb";  
    15                         break; 
    16                 case APPEND: 
    17                         char_mode = "a+b"; 
    18                         break; 
    19                 case WRITE: 
    20                         char_mode = "wb"; 
    21                         break; 
    22                 } 
    23  
    24                 mFile = fopen(name.c_str(),char_mode); 
    25                 mSize = 0; 
    26                 assert(mFile); 
    27         } 
    28  
    29     //--------------------------------------------------------------------- 
    30     Serializer::~Serializer() 
    31     { 
     9                { 
     10                        char *char_mode = 0; 
     11                        switch (mMode) 
     12                        { 
     13                                case READ :  
     14                                        char_mode = "rb";  
     15                                        break; 
     16                                case APPEND: 
     17                                        char_mode = "a+b"; 
     18                                        break; 
     19                                case WRITE: 
     20                                        char_mode = "wb"; 
     21                                        break; 
     22                        } 
     23 
     24                        mFile = fopen(name.c_str(),char_mode); 
     25                        mSize = 0; 
     26                        assert(mFile); 
     27                } 
     28 
     29        //--------------------------------------------------------------------- 
     30        Serializer::~Serializer() 
     31        { 
    3232                fflush(mFile); 
    3333                fclose(mFile); 
    34     } 
    35  
    36     //--------------------------------------------------------------------- 
    37     void Serializer::WriteArray(const float* const pFloat, size_t count) 
    38     { 
    39 #       if GEO_ENDIAN == GEO_ENDIAN_BIG 
    40             float *float_to_write = (float *)malloc(sizeof(float) * count); 
    41             memcpy(float_to_write, pFloat, sizeof(float) * count); 
    42              
    43             flipToLittleEndian(float_to_write, sizeof(float), count); 
    44             writeData(float_to_write, sizeof(float), count); 
    45              
    46             free(float_to_write); 
     34        } 
     35 
     36        //--------------------------------------------------------------------- 
     37        void Serializer::WriteArray(const float* const pFloat, size_t count) 
     38        { 
     39#       if GEO_ENDIAN == GEO_ENDIAN_BIG 
     40                float *float_to_write = (float *)malloc(sizeof(float) * count); 
     41                memcpy(float_to_write, pFloat, sizeof(float) * count); 
     42 
     43                flipToLittleEndian(float_to_write, sizeof(float), count); 
     44                writeData(float_to_write, sizeof(float), count); 
     45 
     46                free(float_to_write); 
    4747#       else 
    48             WriteData(pFloat, sizeof(float), count); 
    49 #       endif 
    50     } 
    51  
    52     //--------------------------------------------------------------------- 
    53     void Serializer::WriteArray(const uint16* const pShort, size_t count = 1) 
    54     { 
    55 #       if GEO_ENDIAN == GEO_ENDIAN_BIG 
    56             unsigned short *short_to_write = (unsigned short *)malloc(sizeof(unsigned short) * count); 
    57             memcpy(short_to_write, pShort, sizeof(unsigned short) * count); 
    58              
    59             flipToLittleEndian(short_to_write, sizeof(unsigned short), count); 
    60             WriteData(short_to_write, sizeof(unsigned short), count); 
    61              
    62             free(short_to_write); 
     48                WriteData(pFloat, sizeof(float), count); 
     49#       endif 
     50        } 
     51 
     52        //--------------------------------------------------------------------- 
     53        void Serializer::WriteArray(const uint16* const pShort, size_t count = 1) 
     54        { 
     55#       if GEO_ENDIAN == GEO_ENDIAN_BIG 
     56                unsigned short *short_to_write = (unsigned short *)malloc(sizeof(unsigned short) * count); 
     57                memcpy(short_to_write, pShort, sizeof(unsigned short) * count); 
     58 
     59                flipToLittleEndian(short_to_write, sizeof(unsigned short), count); 
     60                WriteData(short_to_write, sizeof(unsigned short), count); 
     61 
     62                free(short_to_write); 
    6363#       else 
    64             WriteData(pShort, sizeof(unsigned short), count); 
    65 #       endif 
    66     } 
    67     //--------------------------------------------------------------------- 
    68     void Serializer::WriteArray(const uint32* const pInt, size_t count = 1) 
    69     { 
    70 #       if GEO_ENDIAN == GEO_ENDIAN_BIG 
    71             unsigned int *int_to_write = (unsigned int *)malloc(sizeof(unsigned int) * count); 
    72             memcpy(int_to_write, pInt, sizeof(unsigned int) * count); 
    73              
    74             FlipToLittleEndian(int_to_write, sizeof(unsigned int), count); 
    75             WriteData(int_to_write, sizeof(unsigned int), count); 
    76              
    77             free(int_to_write); 
     64                WriteData(pShort, sizeof(unsigned short), count); 
     65#       endif 
     66        } 
     67         
     68        //--------------------------------------------------------------------- 
     69        void Serializer::WriteArray(const uint32* const pInt, size_t count = 1) 
     70        { 
     71#       if GEO_ENDIAN == GEO_ENDIAN_BIG 
     72                unsigned int *int_to_write = (unsigned int *)malloc(sizeof(unsigned int) * count); 
     73                memcpy(int_to_write, pInt, sizeof(unsigned int) * count); 
     74 
     75                FlipToLittleEndian(int_to_write, sizeof(unsigned int), count); 
     76                WriteData(int_to_write, sizeof(unsigned int), count); 
     77 
     78                free(int_to_write); 
    7879#       else 
    79             WriteData(pInt, sizeof(unsigned int), count); 
    80 #       endif 
    81     } 
    82  
    83     //--------------------------------------------------------------------- 
    84     void Serializer::WriteArray(const bool* const pBool, size_t count = 1) 
     80                WriteData(pInt, sizeof(unsigned int), count); 
     81#       endif 
     82        } 
     83 
     84        //--------------------------------------------------------------------- 
     85        void Serializer::WriteArray(const bool* const pBool, size_t count = 1) 
    8586        { 
    8687                //TODO: Apple has problems  
    87         WriteData(pBool, sizeof(bool), count); 
    88         } 
     88                WriteData(pBool, sizeof(bool), count); 
     89        } 
     90         
    8991        //--------------------------------------------------------------------- 
    9092        void Serializer::WriteArray(const Vector3* const pDest, size_t count) 
    91     { 
    92         for(size_t i = 0; i < count; ++i) 
     93        { 
     94                for(size_t i = 0; i < count; ++i) 
    9395                { 
    9496                        WriteArray(pDest[i].val,3); 
    9597                } 
    96     } 
     98        } 
     99         
    97100        //--------------------------------------------------------------------- 
    98101        void Serializer::WriteArray(const Vector2* const pDest, size_t count) 
    99     { 
    100         for(size_t i = 0; i < count; ++i) 
     102        { 
     103                for(size_t i = 0; i < count; ++i) 
    101104                { 
    102105                        WriteArray(pDest[i].val,2); 
    103106                } 
    104     } 
    105  
    106     //--------------------------------------------------------------------- 
    107     void Serializer::WriteData(const void* const buf, size_t size, size_t count) 
    108     { 
     107        } 
     108 
     109        //--------------------------------------------------------------------- 
     110        void Serializer::WriteData(const void* const buf, size_t size, size_t count) 
     111        { 
    109112                size_t wcount = fwrite((void* const)buf, size, count, mFile); 
    110113                assert(wcount == count); 
    111114                mSize += size*count; 
    112     } 
     115        } 
    113116 
    114117        //--------------------------------------------------------------------- 
     
    138141        void    Serializer::WriteData(const     String  &string) 
    139142        { 
    140                         fputs(string.c_str(), mFile); 
    141  
    142                         // Write terminating newline char 
    143                         fputc('\n', mFile); 
    144                          
    145                         mSize   +=      string.length() + 1; 
     143                fputs(string.c_str(), mFile); 
     144 
     145                // Write terminating newline char 
     146                //fputc('\n', mFile); 
     147 
     148                mSize   +=      string.length(); 
    146149        } 
    147150        //      fin     GPR 
    148151 
    149  
    150      //--------------------------------------------------------------------- 
    151     void Serializer::ReadArray(bool *pDest, size_t count) 
    152     { 
     152        void    Serializer::WriteData(const char        *string) 
     153        { 
     154                fputs(string, mFile); 
     155 
     156                // Write terminating newline char 
     157                //fputc('\n', mFile); 
     158 
     159                mSize   +=      strlen(string) /*+ 1*/; 
     160        } 
     161 
     162        //--------------------------------------------------------------------- 
     163        void Serializer::ReadArray(bool *pDest, size_t count) 
     164        { 
    153165                //TODO:: Apple has problmes with bools 
    154         ReadData(pDest,sizeof(bool), count); 
    155     } 
    156          
    157     //--------------------------------------------------------------------- 
    158     void Serializer::ReadArray(float *pDest, size_t count) 
    159     { 
    160         ReadData(pDest, sizeof(float), count); 
    161         FlipFromLittleEndian(pDest, sizeof(float), count); 
    162     } 
    163     //--------------------------------------------------------------------- 
    164     void Serializer::ReadArray(unsigned short *pDest, size_t count) 
    165     { 
    166         ReadData(pDest, sizeof(unsigned short), count); 
    167         FlipFromLittleEndian(pDest, sizeof(unsigned short), count); 
    168     } 
    169     //--------------------------------------------------------------------- 
    170     void Serializer::ReadArray(unsigned int *pDest, size_t count) 
    171     { 
    172         ReadData(pDest, sizeof(unsigned int), count); 
    173         FlipFromLittleEndian(pDest, sizeof(unsigned int), count); 
    174     } 
    175     //--------------------------------------------------------------------- 
    176     void Serializer::ReadArray(Vector3 *pDest, size_t count) 
    177     { 
    178         for(size_t i = 0; i < count; ++i) 
     166                ReadData(pDest,sizeof(bool), count); 
     167        } 
     168 
     169        //--------------------------------------------------------------------- 
     170        void Serializer::ReadArray(float *pDest, size_t count) 
     171        { 
     172                ReadData(pDest, sizeof(float), count); 
     173                FlipFromLittleEndian(pDest, sizeof(float), count); 
     174        } 
     175         
     176        //--------------------------------------------------------------------- 
     177        void Serializer::ReadArray(unsigned short *pDest, size_t count) 
     178        { 
     179                ReadData(pDest, sizeof(unsigned short), count); 
     180                FlipFromLittleEndian(pDest, sizeof(unsigned short), count); 
     181        } 
     182         
     183        //--------------------------------------------------------------------- 
     184        void Serializer::ReadArray(unsigned int *pDest, size_t count) 
     185        { 
     186                ReadData(pDest, sizeof(unsigned int), count); 
     187                FlipFromLittleEndian(pDest, sizeof(unsigned int), count); 
     188        } 
     189         
     190        //--------------------------------------------------------------------- 
     191        void Serializer::ReadArray(Vector3 *pDest, size_t count) 
     192        { 
     193                for(size_t i = 0; i < count; ++i) 
    179194                { 
    180195                        ReadArray(pDest[i].val,3); 
    181196                } 
    182     } 
     197        } 
     198         
    183199        //--------------------------------------------------------------------- 
    184200        void Serializer::ReadArray(Vector2 *pDest, size_t count) 
    185     { 
    186         for(size_t i = 0; i < count; ++i) 
     201        { 
     202                for(size_t i = 0; i < count; ++i) 
    187203                { 
    188204                        ReadArray(pDest[i].val,2); 
    189205                } 
    190     } 
    191  
    192  
    193 //--------------------------------------------------------------------- 
    194  
    195  
    196     void Serializer::FlipToLittleEndian(void *pData, size_t size, size_t count) 
    197     { 
    198 #       if GEO_ENDIAN == GEO_ENDIAN_BIG 
    199         FlipEndian(pData, size, count); 
    200 #       endif 
    201     } 
    202      
    203     void Serializer::FlipFromLittleEndian(void *pData, size_t size, size_t count) 
    204     { 
    205 #       if GEO_ENDIAN == GEO_ENDIAN_BIG 
    206         FlipEndian(pData, size, count); 
    207 #       endif 
    208     } 
    209      
    210     void Serializer::FlipEndian(void *pData, size_t size, size_t count) 
    211     { 
    212         for(unsigned int index = 0; index < count; index++) 
    213         { 
    214             FlipEndian((void *)((char*)pData + (index * size)), size); 
    215         } 
    216     } 
    217      
    218     void Serializer::FlipEndian(void *pData, size_t size) 
    219     { 
    220         char swapByte; 
    221         for(unsigned int byteIndex = 0; byteIndex < size/2; byteIndex++) 
    222         { 
    223             swapByte = *((char *)pData + byteIndex); 
    224             *((char *)pData + byteIndex) = *((char *)pData + size - byteIndex - 1); 
    225             *((char *)pData + size - byteIndex - 1) = swapByte; 
    226         } 
    227     } 
    228      
     206        } 
     207 
     208        //--------------------------------------------------------------------- 
     209        void Serializer::FlipToLittleEndian(void *pData, size_t size, size_t count) 
     210        { 
     211#       if GEO_ENDIAN == GEO_ENDIAN_BIG 
     212                FlipEndian(pData, size, count); 
     213#       endif 
     214        } 
     215 
     216        void Serializer::FlipFromLittleEndian(void *pData, size_t size, size_t count) 
     217        { 
     218#       if GEO_ENDIAN == GEO_ENDIAN_BIG 
     219                FlipEndian(pData, size, count); 
     220#       endif 
     221        } 
     222 
     223        void Serializer::FlipEndian(void *pData, size_t size, size_t count) 
     224        { 
     225                for(unsigned int index = 0; index < count; index++) 
     226                { 
     227                        FlipEndian((void *)((char*)pData + (index * size)), size); 
     228                } 
     229        } 
     230 
     231        void Serializer::FlipEndian(void *pData, size_t size) 
     232        { 
     233                char swapByte; 
     234                for(unsigned int byteIndex = 0; byteIndex < size/2; byteIndex++) 
     235                { 
     236                        swapByte = *((char *)pData + byteIndex); 
     237                        *((char *)pData + byteIndex) = *((char *)pData + size - byteIndex - 1); 
     238                        *((char *)pData + size - byteIndex - 1) = swapByte; 
     239                } 
     240        } 
     241 
    229242} 
    230243 
  • GTP/trunk/Lib/Geom/shared/GTGeometry/src/GeoSubMesh.cpp

    r826 r980  
    66        mIndex(0), mVertexBuffer(0), mIndexCount(0),mSharedVertexBuffer(false), mStrip(0), mStripCount(0), mType(GEO_TRIANGLE_LIST) 
    77{ 
     8        strcpy(mMaterialName,""); 
    89} 
    910 
  • GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/SimplificationMethod.h

    r774 r980  
    1212{ 
    1313private: 
     14        Geometry::Mesh  *mGeoMesh; 
    1415        void compute_pair_info(qslim::pair_info*); 
    1516        qslim::Model M0; 
     
    5657        SimplificationMethod(const Geometry::Mesh *m); 
    5758        void geomesh2simplifModel(void); 
    58         Geometry::MeshSimplificationSequence *Decimate(float lod, Geometry::Mesh **mesh, int simpliftype,Geometry::TIPOFUNC     upb=0); 
     59        Geometry::MeshSimplificationSequence *Decimate(float lod, int simpliftype,Geometry::TIPOFUNC    upb=0); 
    5960        void setMeshLeaves(int meshLeaves); 
    6061 
     62        //      Gets mesh simplified. 
     63        Geometry::Mesh  *       GetMesh(); 
     64         
    6165        ///Destructor 
    6266        ~SimplificationMethod(); 
Note: See TracChangeset for help on using the changeset viewer.