Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   Related Pages  

sglTriStripper.hpp

00001 /*****************************************************************************
00002  * SGL: A Scene Graph Library
00003  *
00004  * Copyright (C) 1997-2001  Scott McMillan   All Rights Reserved.
00005  *
00006  * This library is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Library General Public
00008  * License as published by the Free Software Foundation; either
00009  * version 2 of the License, or (at your option) any later version.
00010  *
00011  * This library is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Library General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Library General Public
00017  * License along with this library; if not, write to the Free
00018  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00019  *****************************************************************************
00020  *     File: sglTriStripper.hpp 
00021  *  Created: 23 June 1997 (tea time - tee time) 
00022  *  Summary: class containing all of the data for one geoset (a geometry set
00023  *           with vertices, normals, and texcoords and indices). 
00024  *****************************************************************************/
00025 
00026 #ifndef __SGL_TRI_STRIPPER_HPP
00027 #define __SGL_TRI_STRIPPER_HPP
00028 
00029 #include <sgldb.h>
00030 #include <vector>
00031 
00032 #include <sglTriStruct.hpp>
00033 #include <sglHashTable.hpp>
00034 #include <sglVector.hpp>
00035 #include <sglOStream.hpp>
00036 
00037 //============================================================================
00048 template <class T>
00049 class SGLDB_DLL_API sglTriStripper
00050 {
00051 public:
00053    sglTriStripper();
00055    virtual ~sglTriStripper();
00056 
00058    unsigned int getNumTriangles() const {return m_num_triangles;}
00059 
00064    void addTriangleFace(sglTriStruct<T> *tri);
00065 
00067    void addPolyFace(const vector<T>& vertList);
00068 
00070    static void computeFaceNormal(const sglVec3f &v0,
00071                                  const sglVec3f &v1,
00072                                  const sglVec3f &v2,
00073                                  sglVec3f& normal);
00074 
00079    void computeSmoothNormals(const sglVec3f* verts,
00080                              unsigned int (*addNormal)(void*,sglVec3f&),
00081                              void* passThrough);
00082 
00087    void computeFacetedNormals(const sglVec3f* verts,
00088                               unsigned int (*addNormal)(void*,sglVec3f&),
00089                               void* passThrough);
00090 
00092    void triStripify( bool verbose = true );
00093 
00096    void reset();
00097 
00099    void copyTriangleIndexLists(unsigned int *index_vlist,
00100                                unsigned int *index_nlist,
00101                                unsigned int *index_tlist,
00102                                unsigned int *index_clist);
00103 
00105    unsigned int getNumStrips() const {return m_strip.size();}
00106 
00108    vector<T> *getStrip(unsigned int index);
00109 
00110     void copyStrip(unsigned int index,
00111                    unsigned int *index_vlist,
00112                    unsigned int *index_nlist,
00113                    unsigned int *index_tlist,
00114                    unsigned int *index_clist);
00115 
00116 private:
00118    sglTriStripper(const sglTriStripper &);
00119    // assignment operator forbidden
00120    sglTriStripper &operator=(const sglTriStripper &);
00121 
00123    void createStrip(sglTriList<T> *trilist);
00124 
00125    typedef typename sglTriList<T>::iterator list_iterator;
00126 
00128    void removeadjacencies(list_iterator tri);
00129 
00130    void allocLists();
00131    void freeLists();
00132 
00133 private:
00135    unsigned int m_num_triangles;
00139    sglTriList<T> *m_trilist;
00141    sglTriList<T> *m_donetrilist;
00145    sglTriList<T> *m_adjtrilist[4];
00146 
00147 
00149    vector<vector<T>*> m_strip;
00151    unsigned int m_strip_len;
00153    unsigned int m_num_swaps;
00154 };
00155 
00156 //struct edgeStruct;
00157 
00159 template <class T>
00160 class sglEdgeStruct
00161 {
00162 public:
00164    int hash(unsigned int hashsize)
00165       {
00166          int val = (*tri)->v[adjnumber].edgeHash() * 
00167              (*tri)->v[(adjnumber+1)%3].edgeHash();
00168          val = val & 0x7fffffff;
00169          return val % hashsize;
00170       }
00171 
00172 
00174    bool isEqual(sglEdgeStruct *edge2)
00175       {
00176          return ((*tri)->v[adjnumber] == 
00177                  (*(edge2->tri))->v[(edge2->adjnumber+1)%3])
00178              && ((*tri)->v[(adjnumber+1)%3] == 
00179                  (*(edge2->tri))->v[edge2->adjnumber]);
00180       }
00181 
00182 
00183    typedef typename sglTriList<T>::iterator list_iterator;
00184 
00186    list_iterator tri;
00187    unsigned int adjnumber;
00188 };
00189 
00190 
00191 
00192 //============================================================================
00193 // class sglTriStripper
00194 //============================================================================
00195 
00196 //----------------------------------------------------------------------------
00197 template <class T>
00198 inline sglTriStripper<T>::sglTriStripper() :
00199       m_num_triangles(0),
00200       m_strip(),
00201       m_strip_len(0),
00202       m_num_swaps(0)
00203 {
00204    allocLists();
00205 }
00206 
00207 //----------------------------------------------------------------------------
00208 template <class T>
00209 inline sglTriStripper<T>::~sglTriStripper()
00210 {
00211    freeLists();
00212 }
00213 
00214 //----------------------------------------------------------------------------
00215 template <class T>
00216 inline void sglTriStripper<T>::reset()
00217 {
00218    freeLists();
00219    m_num_triangles = 0;
00220    m_strip_len = 0;
00221    m_num_swaps = 0;
00222    allocLists();
00223 }
00224 
00225 //----------------------------------------------------------------------------
00226 template <class T>
00227 inline void sglTriStripper<T>::allocLists()
00228 {
00229    m_trilist = new sglTriList<T>();
00230    m_donetrilist = new sglTriList<T>();
00231    for (int i=0; i<4; i++)
00232       m_adjtrilist[i] = new sglTriList<T>();
00233 }
00234 
00235 //----------------------------------------------------------------------------
00236 template <class T>
00237 inline void sglTriStripper<T>::freeLists()
00238 {
00239    if (m_donetrilist)
00240    {
00241       if (!m_donetrilist->empty())
00242          sglPrintWarning()
00243             << "sglTriStripper logic error: m_donetrilist not empty" << endl;
00244       delete m_donetrilist;
00245    }
00246    if (m_adjtrilist[0])
00247    {
00248        if (!m_adjtrilist[0]->empty())
00249           sglPrintWarning()
00250              << "sglTriStripper logic error: m_adjtrilist[0] not empty"
00251              << endl;
00252        delete m_adjtrilist[0];
00253    }
00254    if (m_adjtrilist[1])
00255    {
00256        if (!m_adjtrilist[1]->empty())
00257           sglPrintWarning()
00258              << "sglTriStripper logic error: m_adjtrilist[1] not empty"
00259              << endl;
00260        delete m_adjtrilist[1];
00261    }
00262    if (m_adjtrilist[2])
00263    {
00264       if (!m_adjtrilist[2]->empty())
00265          sglPrintWarning()
00266             << "sglTriStripper logic error: m_adjtrilist[2] not empty"
00267             << endl;
00268       delete m_adjtrilist[2];
00269    }
00270    if(m_adjtrilist[3])
00271    {
00272       if (!m_adjtrilist[3]->empty())
00273          sglPrintWarning()
00274             << "sglTriStripper logic error: m_adjtrilist[3] not empty "
00275             << endl;
00276       delete m_adjtrilist[3];
00277    }
00278    if (m_trilist)
00279    {
00280        while (!m_trilist->empty())
00281        {
00282            list_iterator tri = m_trilist->begin();
00283            delete *tri;
00284            m_trilist->erase(tri);
00285        }
00286       delete m_trilist;
00287    }
00288 
00289    while (!m_strip.empty())
00290    {
00291       vector<T>* strip = m_strip.back();
00292       m_strip.pop_back();
00293       delete strip;
00294    }
00295 }
00296 
00297 //----------------------------------------------------------------------------
00298 template <class T>
00299 inline void sglTriStripper<T>::addTriangleFace(sglTriStruct<T> *tri)
00300 {
00301    // Do not add degenerate triangles
00302    if (tri->isDegenerate())
00303    {
00304       sglPrintInfo() << "sglTriStripper::addTriangleFace() warning: "
00305                      << "ignoring degenerate triangle" << endl;
00306 
00307       delete tri;
00308       return;
00309    }
00310 
00311    // insert at the head of the list
00312    m_trilist->push_back(tri);
00313 
00314    tri->used = false;
00315    tri->adjcount = 0;
00316    for (int i=0; i<3; i++) tri->adj[i] = NULL;
00317    tri->index = m_num_triangles++;
00318 
00319    sglPrintDebug() << *tri;
00320 }
00321 
00322 //----------------------------------------------------------------------------
00323 template <class T>
00324 inline void sglTriStripper<T>::addPolyFace(const vector<T>& vertList)
00325 {
00326    if (vertList.size() > 2)
00327    {
00328       unsigned int first = 0;
00329       unsigned int middle = 1;
00330       unsigned int last = vertList.size()-1;
00331       unsigned int lower_next = 2;
00332       unsigned int upper_next = vertList.size()-2;
00333       for (unsigned int i = 0; i < vertList.size()-2; ++i)
00334       {
00335          sglTriStruct<T>* tri = new sglTriStruct<T>;
00336          tri->v[0] = vertList[first];
00337          tri->v[1] = vertList[middle];
00338          tri->v[2] = vertList[last];
00339          addTriangleFace(tri);
00340 
00341          if (i%2 == 0)
00342          {
00343             first = last;
00344             last = lower_next++;
00345          }
00346          else
00347          {
00348             middle = last;
00349             last = upper_next--;
00350          }
00351       }
00352    }
00353    else
00354    {
00355       sglPrintInfo() << "sglTriStripper::addPolyFace() warning: "
00356                      << "ignoring degenerate face" << endl;
00357    }
00358 }
00359 
00360 //----------------------------------------------------------------------------
00361 template <class T>
00362 inline void sglTriStripper<T>::computeFaceNormal(const sglVec3f &v0,
00363                                                  const sglVec3f &v1,
00364                                                  const sglVec3f &v2,
00365                                                  sglVec3f& normal)
00366 {
00367    sglVec3f a, b;
00368 
00369    a.sub(v1, v0);
00370    b.sub(v2, v0);
00371 
00372    normal.cross(a, b);
00373    normal.normalize();
00374 }
00375 
00376 //----------------------------------------------------------------------------
00377 template <class T>
00378 inline void sglTriStripper<T>::computeSmoothNormals(
00379     const sglVec3f* verts,
00380     unsigned int (*addNormal)(void*, sglVec3f&),
00381     void* passThrough)
00382 {
00383    // ==============  Compute smooth normals  ==================
00384    // HACK slow and stupid!!
00385    if (T::hasNormals())
00386    {
00387       bool foundOne = false;
00388       for (list_iterator tri = m_trilist->begin(); 
00389            tri != m_trilist->end(); ++tri)
00390       {
00391          for (unsigned int i=0; i<3; ++i)
00392          {
00393             if ((*tri)->v[i].getNormal() == UINT_MAX)
00394             {
00395                if (foundOne == false)
00396                {
00397                   foundOne = true;
00398                   sglPrintInfo()
00399                      << "sglTriStripper: computing normals" << endl;
00400                }
00401                sglVec3f normal = sglVec3f(0,0,0);
00402                vector<T*> sameList;
00403                for (list_iterator tri2 = m_trilist->begin(); 
00404                     tri2 != m_trilist->end(); ++tri2)
00405                {
00406                   T* vert = (*tri2)->findSameLocation(&(*tri)->v[i]);
00407                   if (vert)
00408                   {
00409                      sameList.push_back(vert);
00410                      sglVec3f faceNormal;
00411                      computeFaceNormal(verts[(*tri2)->v[0].vi],
00412                                        verts[(*tri2)->v[1].vi],
00413                                        verts[(*tri2)->v[2].vi],
00414                                        faceNormal);
00415                      normal += faceNormal;
00416                   }
00417                }
00418                normal.normalize();
00419                unsigned int nindex = addNormal(passThrough, normal);
00420                for (typename vector<T*>::iterator v = sameList.begin();
00421                     v != sameList.end(); ++v)
00422                {
00423                   if ((*v)->getNormal() == UINT_MAX)
00424                       (*v)->setNormal(nindex);
00425                }
00426             }
00427          }
00428       }
00429    }
00430 }
00431 
00432 //----------------------------------------------------------------------------
00433 template <class T>
00434 inline void sglTriStripper<T>::computeFacetedNormals(
00435     const sglVec3f* verts,
00436     unsigned int (*addNormal)(void*, sglVec3f&),
00437     void* passThrough)
00438 {
00439    // ==============  Compute faceted normals  ==================
00440    if (T::hasNormals())
00441    {
00442       bool foundOne = false;
00443       for (list_iterator tri = m_trilist->begin(); 
00444            tri != m_trilist->end(); ++tri)
00445       {
00446          if ((*tri)->v[0].getNormal() == UINT_MAX ||
00447              (*tri)->v[1].getNormal() == UINT_MAX ||
00448              (*tri)->v[2].getNormal() == UINT_MAX)
00449          {
00450             if (foundOne == false)
00451             {
00452                foundOne = true;
00453                sglPrintInfo() << "sglTriStripper: computing normals" << endl;
00454             }
00455             sglVec3f faceNormal;
00456             computeFaceNormal(verts[(*tri)->v[0].vi],
00457                               verts[(*tri)->v[1].vi],
00458                               verts[(*tri)->v[2].vi],
00459                               faceNormal);
00460             //sglPrintDebug() << "normal = " << faceNormal << endl;
00461             unsigned int nindex = addNormal(passThrough, faceNormal);
00462             for (unsigned int i=0; i<3; ++i)
00463             {
00464                if ((*tri)->v[i].getNormal() == UINT_MAX)
00465                    (*tri)->v[i].setNormal(nindex);
00466             }
00467          }
00468       }
00469    }
00470 }
00471 
00472 //----------------------------------------------------------------------------
00473 template <class T>
00474 inline void sglTriStripper<T>::triStripify( bool verbose )
00475 {
00476    list_iterator tri;
00477    int i;
00478 
00479    if( verbose )
00480       sglPrintInfo() << "Number of input triangles: "
00481                   << m_num_triangles << endl;
00482 
00483    // =========== Eliminate vertex equivalent triangles ===============
00484 
00485    // initialize hash table for triangles
00486    sglHashTable< sglTriStruct<T> > *thash = 
00487        new sglHashTable< sglTriStruct<T> >((m_num_triangles/8)+1);
00488 
00489    for (tri = m_trilist->begin(); tri != m_trilist->end(); )
00490    {
00491       if (thash->search(*tri))
00492       {
00493          if( verbose )
00494             sglPrintInfo() << "sglTriStripper::triStripify(): removing "
00495                            << "duplicate tri " << *tri
00496                            << (*tri)->v[0].vi << (*tri)->v[1].vi 
00497                            << (*tri)->v[2].vi << endl;
00498 
00499          list_iterator todie = tri++;
00500          delete *todie;
00501          m_trilist->erase(todie);
00502       }
00503       else
00504       {
00505          thash->add(*tri);
00506          ++tri;
00507       }
00508    }
00509    delete thash;
00510 
00511    // ==============  Compute triangle adjacencies  ==================
00512 
00513    // initialize a hash table for edges
00514    sglHashTable< sglEdgeStruct<T> > *ehash = 
00515        new sglHashTable< sglEdgeStruct<T> >(m_num_triangles);
00516    sglEdgeStruct<T>* edges = new sglEdgeStruct<T>[3*m_num_triangles];
00517    sglEdgeStruct<T>* freeedge = edges;
00518 
00519    // add each edge of every triangle to hash table
00520    for (tri = m_trilist->begin(); tri != m_trilist->end(); ++tri)
00521    {
00522       freeedge->tri = tri; 
00523       freeedge->adjnumber = 0;
00524       ehash->add(freeedge++);
00525       freeedge->tri = tri; 
00526       freeedge->adjnumber = 1;
00527       ehash->add(freeedge++);
00528       freeedge->tri = tri; 
00529       freeedge->adjnumber = 2;
00530       ehash->add(freeedge++);
00531    }
00532 
00533    // for each triangle search the list for edges of other triangles
00534    for (tri = m_trilist->begin(); tri != m_trilist->end(); ++tri)
00535    {
00536       for (i=0; i<3; i++)
00537       {
00538          // skip this one if it has already been done
00539          if ((*tri)->adj[i] != 0)
00540          {
00541             continue;
00542          }
00543 
00544          sglEdgeStruct<T> nextedge;
00545          nextedge.tri = tri;
00546          nextedge.adjnumber = i;
00547          sglEdgeStruct<T> *edge = ehash->search(&nextedge);
00548          if (edge)
00549          {
00550             if (edge->tri == tri)
00551                edge = ehash->searchagain(&nextedge, edge);
00552             if (edge)
00553             {
00554                if ((*(edge->tri))->adj[edge->adjnumber] == NULL)
00555                {
00556                   (*tri)->adj[i] = edge->tri;
00557                   (*(edge->tri))->adj[edge->adjnumber] = tri;
00558                }
00559                else
00560                {
00561                   //sglPrintDebug() << "Why does this happen??" << endl;
00562                }
00563             }
00564          }
00565       }
00566    }
00567 
00568    delete[] edges;
00569    delete ehash;
00570 
00571 #ifdef DEBUG
00572    // test adjacency pointers for consistency
00573    int j,k;
00574 
00575    for (tri = m_trilist->begin(); tri != m_trilist->end(); ++tri)
00576    {
00577       for (i = 0; i < 3; i++)
00578       {
00579          sglTriList<T>::iterator nexttri = (*tri)->adj[i];
00580          if (nexttri != 0)
00581          {
00582             k=0;
00583             for (j = 0; j < 3; j++)
00584             {
00585                if (tri == (*nexttri)->adj[j])
00586                {
00587                   k += 1;
00588                }
00589             }
00590             if (k != 1)
00591             {
00592                sglPrintWarning() << *tri << " ERROR: to " << *nexttri
00593                                  << " k = " << k << endl;;
00594                sglPrintWarning() << **tri;
00595                sglPrintWarning() << **nexttri;
00596             }
00597          }
00598       }
00599    }
00600 #endif
00601 
00602    // compute adjacency statistics and add to the appropriate adjtrilist
00603    int count, adjcount[4] = {0,0,0,0};
00604 
00605    for (tri = m_trilist->begin(); tri != m_trilist->end();)
00606    {
00607       for (i=0, count=0; i<3; ++i)
00608       {
00609          if ((*tri)->adj[i] != 0)
00610          {
00611             count += 1;
00612          }
00613       }
00614       (*tri)->adjcount = count;
00615       adjcount[count] += 1;
00616 
00617       list_iterator lasttri = tri++;
00618 
00619       // move it from main list to appropriate adjtrilist
00620       m_adjtrilist[count]->splice(m_adjtrilist[count]->begin(),
00621                                   *m_trilist, lasttri);
00622    }
00623 
00624    if( verbose )
00625       sglPrintInfo() << "adjacencies: 0:" << adjcount[0]
00626                      << ", 1:" << adjcount[1]
00627                      << ", 2:" << adjcount[2]
00628                      << ", 3:" << adjcount[3] << endl;
00629 
00630 // ============ search for connected triangles and output ==============
00631  
00632    // Don't meshify singular triangles just leave them in their list
00633    for (tri = m_adjtrilist[0]->begin(); tri != m_adjtrilist[0]->end(); ++tri)
00634    {
00635       (*tri)->used = true;
00636    }
00637 
00638    for (;;)
00639    {
00640       sglTriList<T> *oldlist;
00641       // choose a seed triangle with the minimum number of adjacencies
00642       if ((tri = m_adjtrilist[1]->begin()) != m_adjtrilist[1]->end())
00643       {
00644          oldlist = m_adjtrilist[1];
00645       }
00646       else if ((tri = m_adjtrilist[2]->begin()) != m_adjtrilist[2]->end())
00647       {
00648          oldlist = m_adjtrilist[2];
00649       }
00650       else if ((tri = m_adjtrilist[3]->begin()) != m_adjtrilist[3]->end())
00651       {
00652          oldlist = m_adjtrilist[3];
00653       }
00654       else
00655          break;
00656 
00657       // start a new list to hold the triangles that belong to this list
00658       sglTriList<T> *newtrilist = new sglTriList<T>();
00659 
00660       newtrilist->splice(newtrilist->begin(), *oldlist, tri);
00661       removeadjacencies(tri);  //remove this tri from adj ptrs of adjacent tris
00662       int tricount = 1;
00663 
00664       // extend in one direction using triangles with min adjacencies
00665       while ((tri = (*tri)->minadj()) != 0)
00666       {
00667          newtrilist->splice(newtrilist->begin(),
00668                             *(m_adjtrilist[(*tri)->adjcount]), tri);
00669          removeadjacencies(tri);
00670          tricount++;
00671       }
00672 
00673       // if seed has two or more adjacencies, extend in other direction
00674       // Big bug fix! - I had to fix this because code before did not do what
00675       // the previous comment says.
00676       tri = newtrilist->end();
00677       --tri;
00678       list_iterator nexttri = NULL;
00679       for (i=0; i<3; i++)
00680       {
00681          list_iterator prevtri = tri;
00682          --prevtri;
00683          if ((*tri)->adj[i] != 0 &&
00684              ((*tri)->adj[i] != prevtri) &&
00685              (!((*((*tri)->adj[i]))->used)))
00686          {
00687             nexttri = (*tri)->adj[i];
00688             break;
00689          }
00690       }
00691 
00692       for (tri = nexttri; tri != 0; tri = (*tri)->minadj())
00693       {
00694          newtrilist->splice(newtrilist->end(),
00695                             *(m_adjtrilist[(*tri)->adjcount]), tri);
00696          removeadjacencies(tri);
00697          tricount++;
00698       }
00699 
00700       sglPrintDebug() << "tricount=" << tricount << ", ";
00701 
00702       // output the resulting mesh
00703       if (tricount > 1)
00704       {
00705          createStrip(newtrilist);
00706       }
00707       if (!newtrilist->empty())
00708          sglPrintWarning()
00709             << "sglTriStripper logic error: newtrilist not empty" << endl;
00710       delete newtrilist;
00711    }
00712 
00713    // free unneeded trilists and move isolated triangles to m_trilist
00714    while (!m_donetrilist->empty())
00715    {
00716        tri = m_donetrilist->begin();
00717        delete *tri;
00718        m_donetrilist->erase(tri);
00719    }
00720    delete m_donetrilist;
00721    m_donetrilist = NULL;
00722 
00723    if (!m_adjtrilist[1]->empty())
00724       sglPrintWarning()
00725          << "sglTriStripper logic error: m_adjtrilist[1] not empty"
00726          << endl;
00727    delete m_adjtrilist[1];
00728    m_adjtrilist[1] = NULL;
00729 
00730    if (!m_adjtrilist[2]->empty())
00731       sglPrintWarning()
00732          << "sglTriStripper logic error: m_adjtrilist[2] not empty" << endl;
00733    delete m_adjtrilist[2];
00734    m_adjtrilist[2] = NULL;
00735 
00736    if (!m_adjtrilist[3]->empty())
00737       sglPrintWarning()
00738          << "sglTriStripper logic error: m_adjtrilist[3] not empty" << endl;
00739    delete m_adjtrilist[3];
00740    m_adjtrilist[3] = NULL;
00741 
00742    if (!m_trilist->empty())
00743       sglPrintWarning()
00744          << "sglTriStripper logic error: m_trilist not empty" << endl;
00745    delete m_trilist;
00746 
00747    m_trilist = m_adjtrilist[0];
00748    m_adjtrilist[0] = NULL;
00749 
00750    // recount the number of isolated triangles
00751    m_num_triangles = 0;
00752    for (tri = m_trilist->begin(); tri != m_trilist->end(); ++tri)
00753    {
00754       m_num_triangles++;
00755    }
00756 
00757    // Output the statistics
00758    if( verbose )
00759    {
00760       sglPrintInfo() << "Number of isolated triangles: "
00761                      << m_num_triangles << endl;
00762       sglPrintInfo() << "Number of stripped triangles: " 
00763                      << (m_strip_len - (2*m_strip.size())) - m_num_swaps
00764                      << endl;
00765       sglPrintInfo() << "Number of triangle strips: "
00766                      << m_strip.size() << endl;
00767       sglPrintInfo() << "Number of triangle swaps: " << m_num_swaps << endl;
00768       if (m_strip.size())
00769       {
00770          sglPrintInfo() << "Avg. strip length: "
00771                         << ((float) m_strip_len/(float) m_strip.size())
00772                         << endl;
00773       }
00774       sglPrintInfo() << "Total vertices to send to the pipe: " 
00775                      << m_strip_len + 3*m_num_triangles << endl;
00776    }
00777 }
00778 
00779 //----------------------------------------------------------------------------
00780 template <class T>
00781 inline void sglTriStripper<T>::createStrip(sglTriList<T> *trilist)
00782 {
00783    vector<T> *tristrip = new vector<T>();
00784 
00785    // ----------------------------------------------------------
00786    // build the list of vertices here
00787    T *vbuf[2];  // last two vertices pushed down the gfx pipeline
00788    list_iterator tri = trilist->begin();
00789 
00790 //   sglPrintDebug() << **tri;
00791 
00792    // *** start output with vertex that is not in the second triangle
00793    list_iterator nexttri = tri;
00794    ++nexttri;
00795    T *vert = sglTriStruct<T>::notCommon(*tri, *nexttri);
00796 
00797    // get index of triangle
00798    int i;
00799    for (i=0; i<3; i++)
00800    {
00801       if (vert == &((*tri)->v[i]))
00802          break;
00803    }
00804 
00805    // bgntmesh();
00806    int vbuf_index = 0;
00807 
00808    // v3f(tri->v[i]);
00809    tristrip->push_back(*vert);
00810    vbuf[vbuf_index] = vert;
00811    vbuf_index = !vbuf_index;
00812 
00813    // v3f(tri->v[(i + 1) % 3]);
00814    tristrip->push_back((*tri)->v[(i + 1) % 3]);
00815    vbuf[vbuf_index] = &((*tri)->v[(i + 1) % 3]);
00816    vbuf_index = !vbuf_index;
00817 
00818    // v3f(tri->v[(i + 2) % 3]);
00819    tristrip->push_back((*tri)->v[(i + 2) % 3]);
00820    vbuf[vbuf_index] = &((*tri)->v[(i + 2) % 3]);
00821    vbuf_index = !vbuf_index;
00822 
00823    // *** find vertex of second triangle that is not in the first
00824    T *nextvert = sglTriStruct<T>::notCommon(*nexttri, *tri);
00825 
00826    // *** transfer triangle to done list
00827    m_donetrilist->splice(m_donetrilist->begin(), *trilist, tri);
00828 
00829    for (tri = nexttri++; nexttri != trilist->end(); tri = nexttri++)
00830    {
00831 //      sglPrintDebug() << **tri;
00832 
00833       // *** check for errors
00834       if ((!(*tri)->isMember(vbuf[0])) || 
00835           (!(*tri)->isMember(vbuf[1])) ||
00836           (!(*tri)->isMember(nextvert)))
00837       {
00838          sglPrintWarning() << "ERROR 1 in mesh generation" << endl;
00839       }
00840       if ((vbuf[0]->vi == vbuf[1]->vi) || (vbuf[0]->vi == nextvert->vi))
00841       {
00842          sglPrintWarning() << "ERROR 2 in mesh generation" << endl;
00843       }
00844       // *** decide whether to swap or not
00845       if ((*nexttri)->isMember(vbuf[vbuf_index]))
00846       {
00847          //swaptmesh();
00848          tristrip->push_back(*(vbuf[vbuf_index]));
00849          vbuf_index = !vbuf_index;
00850          ++m_num_swaps;
00851       }
00852 
00853       // *** output the next vertex
00854       tristrip->push_back(*nextvert);
00855       //REPLACEVERT(nextvert);
00856       vbuf[vbuf_index] = nextvert;
00857       vbuf_index = !vbuf_index;
00858 
00859       // *** determine the next output vertex
00860       nextvert = sglTriStruct<T>::notCommon(*nexttri, *tri);
00861 
00862       // *** transfer tri to the done list
00863       m_donetrilist->splice(m_donetrilist->begin(), *trilist, tri);
00864    }
00865 
00866 //   sglPrintDebug() << **tri;
00867 
00868    // *** output the last vertex
00869    tristrip->push_back(*nextvert);
00870 
00871    m_donetrilist->splice(m_donetrilist->begin(), *trilist, tri);
00872    
00873    // ----------------------------------------------------------
00874    // insert strip into list
00875    m_strip.push_back(tristrip);
00876 
00877    m_strip_len += tristrip->size();
00878 
00879    sglPrintDebug() << "Created strip with " << tristrip->size()
00880                    << " vertices (" << m_strip_len << ")" << endl;
00881 }
00882 
00883 //----------------------------------------------------------------------------
00884 template <class T>
00885 inline void sglTriStripper<T>::removeadjacencies(
00886    sglTriStripper<T>::list_iterator tri)
00887 {
00888    int i, j;
00889    list_iterator adjtri;
00890 
00891    (*tri)->used = true;
00892    for (i = 0; i < 3; i++)
00893    {
00894       if ((adjtri = (*tri)->adj[i]) != 0)
00895       {
00896          for (j = 0; j < 3; j++)
00897          {
00898             if (tri == (*adjtri)->adj[j])
00899             {
00900                (*adjtri)->adj[j] = 0;
00901                break;
00902             }
00903          }
00904          (*adjtri)->adjcount -= 1;
00905          m_adjtrilist[(*adjtri)->adjcount]->splice(
00906              m_adjtrilist[(*adjtri)->adjcount]->begin(),
00907              *m_adjtrilist[(*adjtri)->adjcount+1], adjtri);
00908       }
00909    }
00910 }
00911 
00912 //----------------------------------------------------------------------------
00913 template <class T>
00914 inline vector<T> *sglTriStripper<T>::getStrip(unsigned int index)
00915 {
00916    if (index < m_strip.size())
00917    {
00918       return m_strip[index];
00919    }
00920    return NULL;
00921 }
00922 
00923 //----------------------------------------------------------------------------
00924 template <>
00925 inline void sglTriStripper<sglVertStructVNTC>::copyTriangleIndexLists(
00926     unsigned int *index_vlist,
00927     unsigned int *index_nlist,
00928     unsigned int *index_tlist,
00929     unsigned int *index_clist)
00930 {
00931    sglTriList<sglVertStructVNTC>::iterator ii;
00932    sglTriList<sglVertStructVNTC>::iterator end = m_trilist->end();
00933    unsigned int index = 0;
00934 
00935    for (ii = m_trilist->begin(); ii != end; ++ii)
00936    {
00937       sglVertStructVNTC* v = (*ii)->v;
00938       index_vlist[index]   = v[0].vi;
00939       index_nlist[index]   = v[0].ni;
00940       index_tlist[index]   = v[0].ti;
00941       index_clist[index++] = v[0].ci;
00942       index_vlist[index]   = v[1].vi;
00943       index_nlist[index]   = v[1].ni;
00944       index_tlist[index]   = v[1].ti;
00945       index_clist[index++] = v[1].ci;
00946       index_vlist[index]   = v[2].vi;
00947       index_nlist[index]   = v[2].ni;
00948       index_tlist[index]   = v[2].ti;
00949       index_clist[index++] = v[2].ci;
00950    }
00951 }
00952 
00953 //----------------------------------------------------------------------------
00954 template <>
00955 inline void sglTriStripper<sglVertStructVNT>::copyTriangleIndexLists(
00956     unsigned int *index_vlist,
00957     unsigned int *index_nlist,
00958     unsigned int *index_tlist,
00959     unsigned int *)
00960 {
00961    sglTriList<sglVertStructVNT>::iterator ii;
00962    sglTriList<sglVertStructVNT>::iterator end = m_trilist->end();
00963    unsigned int index = 0;
00964 
00965    for (ii = m_trilist->begin(); ii != end; ++ii)
00966    {
00967       sglVertStructVNT* v = (*ii)->v;
00968       index_vlist[index]   = v[0].vi;
00969       index_nlist[index]   = v[0].ni;
00970       index_tlist[index++] = v[0].ti;
00971       index_vlist[index]   = v[1].vi;
00972       index_nlist[index]   = v[1].ni;
00973       index_tlist[index++] = v[1].ti;
00974       index_vlist[index]   = v[2].vi;
00975       index_nlist[index]   = v[2].ni;
00976       index_tlist[index++] = v[2].ti;
00977    }
00978 }
00979 
00980 //----------------------------------------------------------------------------
00981 template <>
00982 inline void sglTriStripper<sglVertStructVNC>::copyTriangleIndexLists(
00983     unsigned int *index_vlist,
00984     unsigned int *index_nlist,
00985     unsigned int *,
00986     unsigned int *index_clist)
00987 {
00988    sglTriList<sglVertStructVNC>::iterator ii;
00989    sglTriList<sglVertStructVNC>::iterator end = m_trilist->end();
00990    unsigned int index = 0;
00991 
00992    for (ii = m_trilist->begin(); ii != end; ++ii)
00993    {
00994       sglVertStructVNC* v = (*ii)->v;
00995       index_vlist[index]   = v[0].vi;
00996       index_nlist[index]   = v[0].ni;
00997       index_clist[index++] = v[0].ci;
00998       index_vlist[index]   = v[1].vi;
00999       index_nlist[index]   = v[1].ni;
01000       index_clist[index++] = v[1].ci;
01001       index_vlist[index]   = v[2].vi;
01002       index_nlist[index]   = v[2].ni;
01003       index_clist[index++] = v[2].ci;
01004    }
01005 }
01006 
01007 //----------------------------------------------------------------------------
01008 template <>
01009 inline void sglTriStripper<sglVertStructVN>::copyTriangleIndexLists(
01010     unsigned int *index_vlist,
01011     unsigned int *index_nlist,
01012     unsigned int *,
01013     unsigned int *)
01014 {
01015    sglTriList<sglVertStructVN>::iterator ii;
01016    sglTriList<sglVertStructVN>::iterator end = m_trilist->end();
01017    unsigned int index = 0;
01018 
01019    for (ii = m_trilist->begin(); ii != end; ++ii)
01020    {
01021       sglVertStructVN* v = (*ii)->v;
01022       index_vlist[index]   = v[0].vi;
01023       index_nlist[index++] = v[0].ni;
01024       index_vlist[index]   = v[1].vi;
01025       index_nlist[index++] = v[1].ni;
01026       index_vlist[index]   = v[2].vi;
01027       index_nlist[index++] = v[2].ni;
01028    }
01029 }
01030 
01031 //----------------------------------------------------------------------------
01032 template <>
01033 inline void sglTriStripper<sglVertStructVTC>::copyTriangleIndexLists(
01034     unsigned int *index_vlist,
01035     unsigned int *,
01036     unsigned int *index_tlist,
01037     unsigned int *index_clist)
01038 {
01039    sglTriList<sglVertStructVTC>::iterator ii;
01040    sglTriList<sglVertStructVTC>::iterator end = m_trilist->end();
01041    unsigned int index = 0;
01042 
01043    for (ii = m_trilist->begin(); ii != end; ++ii)
01044    {
01045       sglVertStructVTC* v = (*ii)->v;
01046       index_vlist[index]   = v[0].vi;
01047       index_tlist[index]   = v[0].ti;
01048       index_clist[index++] = v[0].ci;
01049       index_vlist[index]   = v[1].vi;
01050       index_tlist[index]   = v[1].ti;
01051       index_clist[index++] = v[1].ci;
01052       index_vlist[index]   = v[2].vi;
01053       index_tlist[index]   = v[2].ti;
01054       index_clist[index++] = v[2].ci;
01055    }
01056 }
01057 
01058 //----------------------------------------------------------------------------
01059 template <>
01060 inline void sglTriStripper<sglVertStructVT>::copyTriangleIndexLists(
01061     unsigned int *index_vlist,
01062     unsigned int *,
01063     unsigned int *index_tlist,
01064     unsigned int *)
01065 {
01066    sglTriList<sglVertStructVT>::iterator ii;
01067    sglTriList<sglVertStructVT>::iterator end = m_trilist->end();
01068    unsigned int index = 0;
01069 
01070    for (ii = m_trilist->begin(); ii != end; ++ii)
01071    {
01072       sglVertStructVT* v = (*ii)->v;
01073       index_vlist[index]   = v[0].vi;
01074       index_tlist[index++] = v[0].ti;
01075       index_vlist[index]   = v[1].vi;
01076       index_tlist[index++] = v[1].ti;
01077       index_vlist[index]   = v[2].vi;
01078       index_tlist[index++] = v[2].ti;
01079    }
01080 }
01081 
01082 //----------------------------------------------------------------------------
01083 template <>
01084 inline void sglTriStripper<sglVertStructVC>::copyTriangleIndexLists(
01085     unsigned int *index_vlist,
01086     unsigned int *,
01087     unsigned int *,
01088     unsigned int *index_clist)
01089 {
01090    sglTriList<sglVertStructVC>::iterator ii;
01091    sglTriList<sglVertStructVC>::iterator end = m_trilist->end();
01092    unsigned int index = 0;
01093 
01094    for (ii = m_trilist->begin(); ii != end; ++ii)
01095    {
01096       sglVertStructVC* v = (*ii)->v;
01097       index_vlist[index]   = v[0].vi;
01098       index_clist[index++] = v[0].ci;
01099       index_vlist[index]   = v[1].vi;
01100       index_clist[index++] = v[1].ci;
01101       index_vlist[index]   = v[2].vi;
01102       index_clist[index++] = v[2].ci;
01103    }
01104 }
01105 
01106 //----------------------------------------------------------------------------
01107 template <>
01108 inline void sglTriStripper<sglVertStructV>::copyTriangleIndexLists(
01109     unsigned int *index_vlist,
01110     unsigned int *,
01111     unsigned int *,
01112     unsigned int *)
01113 {
01114    sglTriList<sglVertStructV>::iterator ii;
01115    sglTriList<sglVertStructV>::iterator end = m_trilist->end();
01116    unsigned int index = 0;
01117 
01118    for (ii = m_trilist->begin(); ii != end; ++ii)
01119    {
01120       sglVertStructV* v = (*ii)->v;
01121       index_vlist[index++] = v[0].vi;
01122       index_vlist[index++] = v[1].vi;
01123       index_vlist[index++] = v[2].vi;
01124    }
01125 }
01126 
01127 //----------------------------------------------------------------------------
01128 template <>
01129 inline void sglTriStripper<sglVertStructVNTC>::copyStrip(unsigned int index,
01130                                                  unsigned int *index_vlist,
01131                                                  unsigned int *index_nlist,
01132                                                  unsigned int *index_tlist,
01133                                                  unsigned int *index_clist)
01134 {
01135    if (index < m_strip.size())
01136    {
01137       unsigned int ii = 0;
01138       for (vector<sglVertStructVNTC>::iterator k = m_strip[index]->begin();
01139            k != m_strip[index]->end(); ++k)
01140       {
01141          index_vlist[ii] = k->vi;
01142          index_nlist[ii] = k->ni;
01143          index_tlist[ii] = k->ti;
01144          index_clist[ii++] = k->ci;
01145       }
01146    }
01147 }
01148 
01149 //----------------------------------------------------------------------------
01150 template <>
01151 inline void sglTriStripper<sglVertStructVNT>::copyStrip(unsigned int index,
01152                                                  unsigned int *index_vlist,
01153                                                  unsigned int *index_nlist,
01154                                                  unsigned int *index_tlist,
01155                                                  unsigned int *)
01156 {
01157    if (index < m_strip.size())
01158    {
01159       unsigned int ii = 0;
01160       for (vector<sglVertStructVNT>::iterator k = m_strip[index]->begin();
01161            k != m_strip[index]->end(); ++k)
01162       {
01163          index_vlist[ii] = k->vi;
01164          index_nlist[ii] = k->ni;
01165          index_tlist[ii++] = k->ti;
01166       }
01167    }
01168 }
01169 
01170 //----------------------------------------------------------------------------
01171 template <>
01172 inline void sglTriStripper<sglVertStructVNC>::copyStrip(unsigned int index,
01173                                                 unsigned int *index_vlist,
01174                                                 unsigned int *index_nlist,
01175                                                 unsigned int *,
01176                                                 unsigned int *index_clist)
01177 {
01178    if (index < m_strip.size())
01179    {
01180       unsigned int ii = 0;
01181       for (vector<sglVertStructVNC>::iterator k = m_strip[index]->begin(); 
01182            k != m_strip[index]->end(); ++k)
01183       {
01184          index_vlist[ii] = k->vi;
01185          index_nlist[ii] = k->ni;
01186          index_clist[ii++] = k->ci;
01187       }
01188    }
01189 }
01190 
01191 //----------------------------------------------------------------------------
01192 template <>
01193 inline void sglTriStripper<sglVertStructVN>::copyStrip(unsigned int index,
01194                                                 unsigned int *index_vlist,
01195                                                 unsigned int *index_nlist,
01196                                                 unsigned int *,
01197                                                 unsigned int *)
01198 {
01199    if (index < m_strip.size())
01200    {
01201       unsigned int ii = 0;
01202       for (vector<sglVertStructVN>::iterator k = m_strip[index]->begin(); 
01203            k != m_strip[index]->end(); ++k)
01204       {
01205          index_vlist[ii] = k->vi;
01206          index_nlist[ii++] = k->ni;
01207       }
01208    }
01209 }
01210 
01211 //----------------------------------------------------------------------------
01212 template <>
01213 inline void sglTriStripper<sglVertStructVTC>::copyStrip(unsigned int index,
01214                                                 unsigned int *index_vlist,
01215                                                 unsigned int *,
01216                                                 unsigned int *index_tlist,
01217                                                 unsigned int *index_clist)
01218 {
01219    if (index < m_strip.size())
01220    {
01221       unsigned int ii = 0;
01222       for (vector<sglVertStructVTC>::iterator k = m_strip[index]->begin(); 
01223            k != m_strip[index]->end(); ++k)
01224       {
01225          index_vlist[ii] = k->vi;
01226          index_tlist[ii] = k->ti;
01227          index_clist[ii++] = k->ci;
01228       }
01229    }
01230 }
01231 
01232 //----------------------------------------------------------------------------
01233 template <>
01234 inline void sglTriStripper<sglVertStructVT>::copyStrip(unsigned int index,
01235                                                 unsigned int *index_vlist,
01236                                                 unsigned int *,
01237                                                 unsigned int *index_tlist,
01238                                                 unsigned int *)
01239 {
01240    if (index < m_strip.size())
01241    {
01242       unsigned int ii = 0;
01243       for (vector<sglVertStructVT>::iterator k = m_strip[index]->begin(); 
01244            k != m_strip[index]->end(); ++k)
01245       {
01246          index_vlist[ii] = k->vi;
01247          index_tlist[ii++] = k->ti;
01248       }
01249    }
01250 }
01251 
01252 //----------------------------------------------------------------------------
01253 template <>
01254 inline void sglTriStripper<sglVertStructVC>::copyStrip(unsigned int index,
01255                                                unsigned int *index_vlist,
01256                                                unsigned int *,
01257                                                unsigned int *,
01258                                                unsigned int *index_clist)
01259 {
01260    if (index < m_strip.size())
01261    {
01262       unsigned int ii = 0;
01263       for (vector<sglVertStructVC>::iterator k = m_strip[index]->begin(); 
01264            k != m_strip[index]->end(); ++k)
01265       {
01266          index_vlist[ii] = k->vi;
01267          index_clist[ii++] = k->ci;
01268       }
01269    }
01270 }
01271 
01272 //----------------------------------------------------------------------------
01273 template <>
01274 inline void sglTriStripper<sglVertStructV>::copyStrip(unsigned int index,
01275                                                unsigned int *index_vlist,
01276                                                unsigned int *,
01277                                                unsigned int *,
01278                                                unsigned int *)
01279 {
01280    if (index < m_strip.size())
01281    {
01282       unsigned int ii = 0;
01283       for (vector<sglVertStructV>::iterator k = m_strip[index]->begin(); 
01284            k != m_strip[index]->end(); ++k)
01285       {
01286          index_vlist[ii++] = k->vi;
01287       }
01288    }
01289 }
01290 
01291 #endif

Generated at Mon Jul 1 18:00:06 2002 for SGL by doxygen1.2.6 written by Dimitri van Heesch, © 1997-2001