osg::HalfEdgeGraph Class Reference

#include <OSGHalfEdgeGraph.h>

List of all members.

Public Types

typedef UInt32 IndexT

Public Member Functions

 HalfEdgeGraph (void)
 HalfEdgeGraph (const HalfEdgeGraph &obj)
virtual ~HalfEdgeGraph (void)
void reserve (UInt32 vertexNum, UInt32 triangleNum, UInt32 reserveEdges=8)
bool addTriangle (IndexT v0, IndexT v1, IndexT v2)
UInt32 triangleCount (void)
bool verify (bool verbose=false)
UInt32 calcOptPrim (UInt32 iteration=1, bool doStrip=true, bool doFan=true, UInt32 minFanTriangleCount=16)
UInt32 primitiveCount (void)
Int32 getPrimitive (std::vector< IndexT > &indexVec, Int32 type=0)
Int32 calcEgdeLines (std::vector< IndexT > &indexVec, bool codeBorder=false)
void clear (void)

Protected Member Functions

HalfEdgegetHalfEdge (UInt32 startVertexIndex, UInt32 endVertexIndex)
void addHalfEdge (HalfEdge &halfEdge, UInt32 startVertexIndex, UInt32 endVertexIndex)
HalfEdgefindGateEdge (Triangle *triangleOut, Triangle *triangleIn)
Int32 calcStripCost (TriangleList &strip, bool reverse)
Int32 fillIndexFromFan (std::vector< IndexT > &indexVec, HalfEdge &firstEdge)
Int32 fillIndexFromStrip (std::vector< IndexT > &indexVec, TriangleList &strip, bool reverse)

Private Types

enum  TriangleState {
  INVALID = -30, FAN_PART = -20, STRIP_PART = -10, DEGREE_0 = 0,
  DEGREE_1 = 1, DEGREE_2 = 2, DEGREE_3 = 3
}
enum  WalkCase { START, LEFT, RIGHT, FINISH }
typedef std::vector< std::pair
< UInt32, HalfEdge * > > 
HalfEdgeLink
typedef std::pair< IndexT,
TriangleList * > 
Primitive

Private Member Functions

void dropOutTriangle (Triangle &triangle, TriangleList *degreeBag)

Private Attributes

std::vector< HalfEdgeLink_edgeLinkVec
TrianglePool _trianglePool
TriangleList _validTriangleBag
TriangleList _invalidTriangleBag
std::vector< Primitive_stripBag
std::vector< Primitive_fanBag
std::vector< Primitive_triBag

Friends

class HalfEdge
class Triangle
class TriangleList
class TrianglePool
class TrianglePool::Chunk

Classes

class  HalfEdge
class  Triangle
class  TriangleList
class  TrianglePool


Detailed Description

Definition at line 59 of file OSGHalfEdgeGraph.h.


Member Typedef Documentation

Definition at line 63 of file OSGHalfEdgeGraph.h.

typedef std::vector< std::pair<UInt32,HalfEdge *> > osg::HalfEdgeGraph::HalfEdgeLink [private]

Definition at line 165 of file OSGHalfEdgeGraph.h.

typedef std::pair<IndexT,TriangleList*> osg::HalfEdgeGraph::Primitive [private]

Definition at line 176 of file OSGHalfEdgeGraph.h.


Member Enumeration Documentation

Enumerator:
INVALID 
FAN_PART 
STRIP_PART 
DEGREE_0 
DEGREE_1 
DEGREE_2 
DEGREE_3 

Definition at line 67 of file OSGHalfEdgeGraph.h.

00067                        { INVALID = -30, FAN_PART = -20, STRIP_PART = -10,
00068                          DEGREE_0 = 0, DEGREE_1 = 1, DEGREE_2 = 2,
00069                          DEGREE_3 = 3 };

Enumerator:
START 
LEFT 
RIGHT 
FINISH 

Definition at line 71 of file OSGHalfEdgeGraph.h.

00071 { START, LEFT, RIGHT, FINISH };


Constructor & Destructor Documentation

HalfEdgeGraph::HalfEdgeGraph ( void   ) 

Definition at line 70 of file OSGHalfEdgeGraph.cpp.

00071 {
00072 }

HalfEdgeGraph::HalfEdgeGraph ( const HalfEdgeGraph obj  ) 

Definition at line 81 of file OSGHalfEdgeGraph.cpp.

References SWARNING.

00082 {
00083     SWARNING << "Run HalfEdgeGraph copy constructor; not impl.\n" << endl;
00084 }

HalfEdgeGraph::~HalfEdgeGraph ( void   )  [virtual]

Definition at line 93 of file OSGHalfEdgeGraph.cpp.

References clear().

00094 {
00095     clear();
00096 }


Member Function Documentation

void osg::HalfEdgeGraph::dropOutTriangle ( Triangle triangle,
TriangleList degreeBag 
) [inline, private]

Definition at line 287 of file OSGHalfEdgeGraph.inl.

References osg::HalfEdgeGraph::TriangleList::add(), osg::HalfEdgeGraph::Triangle::halfEdgeVec, osg::HalfEdgeGraph::TriangleList::release(), osg::HalfEdgeGraph::Triangle::state, STRIP_PART, osg::HalfEdgeGraph::HalfEdge::triangle, and osg::HalfEdgeGraph::HalfEdge::twin.

Referenced by calcOptPrim().

00289 {
00290     HalfEdge *twin;
00291     degreeBag[triangle.state].release(triangle);
00292     triangle.state = STRIP_PART;
00293 
00294     if((twin = triangle.halfEdgeVec[0].twin) && (twin->triangle->state > 0))
00295     {
00296         degreeBag[twin->triangle->state--].release(*twin->triangle);
00297         degreeBag[twin->triangle->state].add(*twin->triangle);
00298     }
00299 
00300     if((twin = triangle.halfEdgeVec[1].twin) && (twin->triangle->state > 0))
00301     {
00302         degreeBag[twin->triangle->state--].release(*twin->triangle);
00303         degreeBag[twin->triangle->state].add(*twin->triangle);
00304     }
00305 
00306     if((twin = triangle.halfEdgeVec[2].twin) && (twin->triangle->state > 0))
00307     {
00308         degreeBag[twin->triangle->state--].release(*twin->triangle);
00309         degreeBag[twin->triangle->state].add(*twin->triangle);
00310     }
00311 }

HalfEdgeGraph::HalfEdge * osg::HalfEdgeGraph::getHalfEdge ( UInt32  startVertexIndex,
UInt32  endVertexIndex 
) [inline, protected]

Definition at line 314 of file OSGHalfEdgeGraph.inl.

References _edgeLinkVec.

Referenced by addHalfEdge(), and addTriangle().

00316 {
00317     UInt32 i, n = _edgeLinkVec.size();
00318     const HalfEdgeLink *edgeLink((startVertexIndex < n) ?
00319         &_edgeLinkVec[startVertexIndex] : 0);
00320 
00321     HalfEdge *halfEdge = 0;
00322 
00323     if (edgeLink && (n = edgeLink->size()))
00324     {
00325         for (i = 0; i < n; ++i)
00326         {
00327             if ((*edgeLink)[i].first == endVertexIndex)
00328             {
00329                 halfEdge = (*edgeLink)[i].second;
00330                 break;
00331             }
00332         }
00333     }
00334 
00335     return halfEdge;
00336 }

void osg::HalfEdgeGraph::addHalfEdge ( HalfEdge halfEdge,
UInt32  startVertexIndex,
UInt32  endVertexIndex 
) [inline, protected]

Definition at line 339 of file OSGHalfEdgeGraph.inl.

References _edgeLinkVec, getHalfEdge(), osg::HalfEdgeGraph::HalfEdge::setVertex(), osg::HalfEdgeGraph::Triangle::state, osg::HalfEdgeGraph::HalfEdge::triangle, and osg::HalfEdgeGraph::HalfEdge::twin.

Referenced by addTriangle().

00341 {
00342     UInt32 n(_edgeLinkVec.size());
00343     bool     validIndex(startVertexIndex < n);
00344     HalfEdge *twin(validIndex ?
00345         getHalfEdge(endVertexIndex, startVertexIndex) : 0);
00346 
00347     halfEdge.setVertex(startVertexIndex,endVertexIndex);
00348 
00349     if(validIndex == false)
00350         _edgeLinkVec.resize(startVertexIndex * 2);
00351 
00352     _edgeLinkVec[startVertexIndex].
00353         push_back(std::pair<HalfEdgeGraph::IndexT,HalfEdge*>(endVertexIndex,
00354                                                              &halfEdge));
00355 
00356     if((halfEdge.twin = twin))
00357     {
00358         twin->twin = &halfEdge;
00359         halfEdge.triangle->state++;
00360         twin->triangle->state++;
00361     }
00362 } 

HalfEdgeGraph::HalfEdge * osg::HalfEdgeGraph::findGateEdge ( Triangle triangleOut,
Triangle triangleIn 
) [inline, protected]

Definition at line 365 of file OSGHalfEdgeGraph.inl.

References osg::HalfEdgeGraph::Triangle::halfEdgeVec, osg::HalfEdgeGraph::HalfEdge::triangle, and osg::HalfEdgeGraph::HalfEdge::twin.

Referenced by calcStripCost().

00367 {
00368     HalfEdgeGraph::HalfEdge *halfEdge = 0;
00369 
00370     if(triangleOut && triangleIn)
00371         if(!(halfEdge = triangleOut->halfEdgeVec[0].twin) || 
00372             (halfEdge->triangle != triangleIn))
00373             if(!(halfEdge = triangleOut->halfEdgeVec[1].twin) || 
00374                 (halfEdge->triangle != triangleIn))
00375                 if(!(halfEdge = triangleOut->halfEdgeVec[2].twin) || 
00376                     (halfEdge->triangle != triangleIn))
00377                     halfEdge = 0;
00378 
00379     return halfEdge ? halfEdge->twin : 0;
00380 }

Int32 HalfEdgeGraph::calcStripCost ( TriangleList strip,
bool  reverse 
) [protected]

Definition at line 655 of file OSGHalfEdgeGraph.cpp.

References findGateEdge(), osg::HalfEdgeGraph::TriangleList::first, osg::HalfEdgeGraph::TriangleList::last, LEFT, osg::HalfEdgeGraph::HalfEdge::next, osg::HalfEdgeGraph::Triangle::next, osg::HalfEdgeGraph::Triangle::prev, RIGHT, and osg::HalfEdgeGraph::HalfEdge::twin.

Referenced by calcOptPrim().

00656 {
00657     Triangle *triangle = rev ? strip.last : strip.first, *nextTriangle;
00658     HalfEdge /* *firstEdge, */ *halfEdge, *gate;
00659     WalkCase walkCase;
00660     Int32 cost = 0;
00661 
00662     if (triangle)
00663     {
00664         cost = 3;
00665         if ((nextTriangle = rev ? triangle->prev : triangle->next))
00666         {
00667             gate = findGateEdge(triangle,nextTriangle);
00668             //firstEdge = gate->next->next;
00669             ++cost;
00670             walkCase = LEFT;
00671             for(triangle = nextTriangle; 
00672                 (nextTriangle = (rev ? triangle->prev : triangle->next));
00673                 triangle = nextTriangle)
00674             {
00675                 halfEdge = gate->twin;
00676                 gate = findGateEdge(triangle,nextTriangle); 
00677                 if (walkCase == RIGHT)
00678                 {
00679                     // RIGHT
00680                     if(halfEdge->next == gate)
00681                     {
00682                         ++cost;
00683                         walkCase = LEFT;
00684                     }
00685                     else
00686                     {
00687                         // swap; walkCase stays RIGHT;
00688                         cost += 2;
00689                     }
00690                 }
00691                 else
00692                 {
00693                     // LEFT
00694                     if(halfEdge->next->next == gate)
00695                     {
00696                         ++cost;
00697                         walkCase = RIGHT;
00698                     }
00699                     else
00700                     {
00701                         // swap; walkCase stays LEFT;
00702                         cost += 2;
00703                     }
00704                 }
00705             }
00706         }
00707     }
00708 
00709     return cost;
00710 }

Int32 osg::HalfEdgeGraph::fillIndexFromFan ( std::vector< IndexT > &  indexVec,
HalfEdge firstEdge 
) [protected]

Int32 osg::HalfEdgeGraph::fillIndexFromStrip ( std::vector< IndexT > &  indexVec,
TriangleList strip,
bool  reverse 
) [protected]

void HalfEdgeGraph::reserve ( UInt32  vertexNum,
UInt32  triangleNum,
UInt32  reserveEdges = 8 
)

Definition at line 174 of file OSGHalfEdgeGraph.cpp.

References _edgeLinkVec, _trianglePool, and osg::HalfEdgeGraph::TrianglePool::setChunkSize().

Referenced by osg::createOptimizedPrimitives().

00176 {
00177     UInt32 i;
00178 
00179     _trianglePool.setChunkSize(triangleNum);
00180     _edgeLinkVec.resize(vertexNum); 
00181 
00182     if(reserveEdges > 0)
00183     {
00184         for(i = 0; i < vertexNum; ++i)
00185             _edgeLinkVec[i].reserve(reserveEdges);
00186     }
00187 }

bool osg::HalfEdgeGraph::addTriangle ( HalfEdgeGraph::IndexT  v0,
HalfEdgeGraph::IndexT  v1,
HalfEdgeGraph::IndexT  v2 
) [inline]

Definition at line 383 of file OSGHalfEdgeGraph.inl.

References _invalidTriangleBag, _trianglePool, _validTriangleBag, osg::HalfEdgeGraph::TriangleList::add(), addHalfEdge(), osg::HalfEdgeGraph::TrianglePool::createTriangle(), getHalfEdge(), osg::HalfEdgeGraph::Triangle::halfEdgeVec, osg::HalfEdgeGraph::Triangle::init(), INVALID, osg::HalfEdgeGraph::HalfEdge::setVertex(), and osg::HalfEdgeGraph::Triangle::state.

Referenced by osg::createOptimizedPrimitives().

00386 {
00387     Triangle *triangle = 0;
00388     
00389     if ((v0 != v1) && (v0 != v2) && (v2 != v1))
00390     {
00391         // create new triangle
00392         triangle = _trianglePool.createTriangle();
00393         triangle->init();
00394         
00395         // reg edges
00396         if (!getHalfEdge(v0,v1) && !getHalfEdge(v1,v2) && !getHalfEdge(v2,v0))
00397         {
00398             addHalfEdge(triangle->halfEdgeVec[0],v0,v1);
00399             addHalfEdge(triangle->halfEdgeVec[1],v1,v2);
00400             addHalfEdge(triangle->halfEdgeVec[2],v2,v0);
00401             _validTriangleBag.add(*triangle);
00402             return true;
00403         }
00404         else
00405         {
00406             triangle->halfEdgeVec[0].setVertex(v0,v1);
00407             triangle->halfEdgeVec[1].setVertex(v1,v2);
00408             triangle->halfEdgeVec[2].setVertex(v2,v0);
00409             triangle->state = INVALID;
00410             _invalidTriangleBag.add(*triangle);
00411             return false;
00412         }
00413     }
00414     return false;
00415 }

UInt32 osg::HalfEdgeGraph::triangleCount ( void   )  [inline]

Definition at line 418 of file OSGHalfEdgeGraph.inl.

References _trianglePool, and osg::HalfEdgeGraph::TrianglePool::countElem().

00419 {
00420     return _trianglePool.countElem();
00421 }

bool HalfEdgeGraph::verify ( bool  verbose = false  ) 

Definition at line 196 of file OSGHalfEdgeGraph.cpp.

References _edgeLinkVec, _invalidTriangleBag, _validTriangleBag, osg::HalfEdgeGraph::TriangleList::countElem(), FINFO, osg::HalfEdgeGraph::TriangleList::first, osg::HalfEdgeGraph::Triangle::halfEdgeVec, osg::HalfEdgeGraph::Triangle::next, SINFO, osg::HalfEdgeGraph::Triangle::state, osg::HalfEdgeGraph::HalfEdge::triangle, osg::HalfEdgeGraph::HalfEdge::twin, osg::HalfEdgeGraph::Triangle::verify(), and osg::HalfEdgeGraph::HalfEdge::vertexStart().

Referenced by osg::createOptimizedPrimitives().

00197 {
00198     bool retCode = true;
00199     UInt32 i, n;
00200     Triangle *triangle, *nt0, *nt1, *nt2;
00201     Int32 triangleState[4];
00202     Int32 invalidTriangles = 0;
00203     Int32 halfEdgeCount = 0;
00204     map< Int32, Int32 > connectionMap;
00205     map< Int32, Int32 >::iterator connectionI;
00206     Int32 connectionCount;
00207     bool validTri = false;
00208 
00209     for(i = 0; i < 4; ++i)
00210         triangleState[i] = 0;
00211 
00212     for( i = 0, triangle = _validTriangleBag.first; 
00213          triangle; 
00214          i++, triangle = triangle->next)
00215     {
00216         if(triangle->verify() && 
00217            (triangle->state >= 0) || (triangle->state <= 3))
00218         {
00219             triangleState[triangle->state]++;
00220             validTri = true;
00221         }
00222         else
00223         {
00224             ++invalidTriangles;
00225             validTri = false;
00226         }
00227 
00228         if ( verbose ) 
00229         {
00230             nt0 = triangle->halfEdgeVec[0].twin ? 
00231               triangle->halfEdgeVec[0].twin->triangle : 0;
00232             nt1 = triangle->halfEdgeVec[1].twin ? 
00233               triangle->halfEdgeVec[1].twin->triangle : 0;
00234             nt2 = triangle->halfEdgeVec[2].twin ? 
00235               triangle->halfEdgeVec[2].twin->triangle : 0;
00236             
00237             FINFO ( ( "HEG: Triangle %p: %d %d %d, %p %p %p: %s\n",
00238                       triangle, 
00239                       triangle->halfEdgeVec[0].vertexStart(),
00240                       triangle->halfEdgeVec[1].vertexStart(),
00241                       triangle->halfEdgeVec[2].vertexStart(),
00242                       nt0, nt1, nt2,
00243                       (validTri ? "VALID" : "INVALID" ) ) );
00244         }
00245     }
00246 
00247     SINFO << "HEG: linked triangle count " << _validTriangleBag.countElem()
00248           << endl;
00249     SINFO << "HEG: invalid triangle " << invalidTriangles 
00250           << endl;
00251     SINFO << "HEG: nonmanifold split: " << _invalidTriangleBag.countElem() 
00252           << endl;
00253 
00254     SINFO << "HEG: triangle state: "
00255           << triangleState[0]
00256           << "/"
00257           << triangleState[1]
00258           << "/"
00259           << triangleState[2]
00260           << "/"
00261           << triangleState[3]
00262           << endl;
00263     
00264     n = _edgeLinkVec.size();
00265     halfEdgeCount = 0;
00266     for (i = 0; i < n; ++i)
00267     {
00268         connectionCount = _edgeLinkVec[i].size();
00269 
00270         halfEdgeCount += connectionCount;
00271         if (connectionMap.find(connectionCount) == connectionMap.end())
00272             connectionMap[connectionCount] = 1;
00273         else
00274             connectionMap[connectionCount]++;
00275 
00276         if (verbose) 
00277         {
00278             HalfEdgeLink::iterator lI;
00279             for ( lI = _edgeLinkVec[i].begin(); 
00280                   lI != _edgeLinkVec[i].end(); ++lI )
00281             {  
00282               FINFO (( "HEG: HalfEdge %p: %d to %d, twin: %p\n",
00283                        lI->second,
00284                        lI->second->vertexStart(),
00285                        lI->second->vertexEnd(),
00286                        lI->second->twin));
00287             }
00288         }
00289     }
00290     for(connectionI = connectionMap.begin();
00291         connectionI != connectionMap.end(); ++connectionI)
00292     {
00293       SINFO << "HEG: Connection: " << connectionI->first << '/' 
00294             << connectionI->second << ' ' << std::endl;
00295     }
00296 
00297     SINFO << "HEG: HalfEdgeCount: " << halfEdgeCount << endl;
00298 
00299     return retCode;
00300 }

UInt32 HalfEdgeGraph::calcOptPrim ( UInt32  iteration = 1,
bool  doStrip = true,
bool  doFan = true,
UInt32  minFanTriangleCount = 16 
)

Definition at line 309 of file OSGHalfEdgeGraph.cpp.

References _edgeLinkVec, _fanBag, _invalidTriangleBag, _stripBag, _trianglePool, _triBag, _validTriangleBag, osg::HalfEdgeGraph::TriangleList::add(), calcStripCost(), osg::HalfEdgeGraph::TriangleList::countElem(), osg::HalfEdgeGraph::TrianglePool::countElem(), DEGREE_0, osg::HalfEdgeGraph::Triangle::drop(), dropOutTriangle(), FAN_PART, FINISH, osg::HalfEdgeGraph::TriangleList::first, osg::HalfEdgeGraph::Triangle::halfEdgeVec, LEFT, osg::HalfEdgeGraph::HalfEdge::next, osg::HalfEdgeGraph::Triangle::next, next(), osg::HalfEdgeGraph::TriangleList::paste(), osg::HalfEdgeGraph::TriangleList::release(), osg::HalfEdgeGraph::Triangle::resetDegreeState(), RIGHT, SINFO, START, osg::HalfEdgeGraph::Triangle::state, STRIP_PART, SWARNING, osg::HalfEdgeGraph::HalfEdge::triangle, osg::HalfEdgeGraph::HalfEdge::twin, and osg::HalfEdgeGraph::Triangle::valid().

Referenced by osg::createOptimizedPrimitives().

00312 {
00313     Int32 iteration = extIteration;
00314     bool sample = iteration > 1 ? true : false;
00315     bool checkRevOrder = sample;
00316     TriangleList degreeBag[4];
00317     TriangleList *fList = 0;
00318     Int32 cost = 0, sampleCost = 0;
00319     Int32 stripCost = 0, revCost = 0, fanCost = 0, triCost = 0;
00320     Int32 bestCost = 0, worstCost = 0, lowDegree;
00321     UInt32 i, n;
00322     WalkCase walkCase = START;
00323     Triangle *triangle, *next;
00324     HalfEdge *twin = 0, *gateEdge = 0, *halfEdge = 0;
00325     bool doMainLoop = true;
00326     UInt32 seed = 1, bestSeed = 1;
00327     Int32 mostDegree = 3;
00328     UInt32 triangleLeft = _trianglePool.countElem();
00329     srand(1);
00330 
00331     if(doFan)
00332     {
00333         n = _edgeLinkVec.size();
00334         fanCost = 0;
00335 
00336         // find fans 
00337         for(i = 0; i < n; ++i)
00338         {
00339             if((_edgeLinkVec[i].size() >= minFanTriangles) &&
00340                (gateEdge = _edgeLinkVec[i][0].second) &&
00341                (gateEdge->triangle->valid()))
00342             {
00343                 for(halfEdge = gateEdge->next->next->twin;
00344                     (halfEdge && halfEdge->triangle->valid() &&
00345                     (halfEdge != gateEdge));
00346                     halfEdge = halfEdge->next->next->twin)
00347                     ;
00348                 if(halfEdge == gateEdge)
00349                 {
00350                     // fan is closed; mark every triangle          
00351                     triangle = 0;
00352                     fList = new TriangleList;
00353                     for(halfEdge = gateEdge;
00354                         !triangle || (halfEdge != gateEdge);
00355                         halfEdge = halfEdge->next->next->twin)
00356                     {
00357                         triangle = halfEdge->triangle;
00358                         _validTriangleBag.release(*triangle);
00359                         triangle->drop();
00360                         triangle->state = FAN_PART;
00361                         fList->add(*triangle);
00362                     }
00363                     _fanBag.push_back(Primitive(i,fList));
00364                     fanCost += (_edgeLinkVec[i].size() + 2);
00365                     triangleLeft -= _edgeLinkVec[i].size();
00366                 }
00367             }
00368         }
00369     }
00370 
00371     if(doStrip && iteration)
00372     {
00373         // push every triangle into the according degree bag
00374         degreeBag[mostDegree].paste(_validTriangleBag);
00375         for(triangle = degreeBag[mostDegree].first; triangle; triangle = next)
00376         {
00377             next = triangle->next;
00378             if(triangle->valid())
00379             {
00380                 if(triangle->state != mostDegree)
00381                 {
00382                     degreeBag[mostDegree].release(*triangle);
00383                     _validTriangleBag.release(*triangle);
00384                     degreeBag[triangle->state].add( *triangle);
00385                 }
00386             }
00387             else
00388             {
00389                 SWARNING << "INVALID TRIANGLE IN VALID TRIANGLE BAG\n" << endl;
00390             }
00391         }
00392 
00393         for(iteration--; iteration >= 0; iteration--)
00394         {
00395             seed = iteration ? rand() : bestSeed;
00396             srand (seed);
00397 
00398             fList = 0;
00399             cost = 0;
00400             doMainLoop = true;
00401             walkCase = START;
00402 
00403             // run the main loop
00404             while(doMainLoop)
00405             {
00406                 switch(walkCase)
00407                 {
00408                     case START:
00409                         stripCost = 0;
00410                         triangle = 0;
00411 
00412                         for(lowDegree = 1; lowDegree < 4; ++lowDegree)
00413                         {
00414                             if((degreeBag[lowDegree].empty() == false))
00415                             {
00416                                 if(sample)
00417                                 {
00418                                     // pick a random triangle
00419                                     n = degreeBag[lowDegree].countElem() - 1;
00420                                     i = Int32(float(n)*rand()/float(RAND_MAX));
00421                                     triangle = degreeBag[lowDegree].first;
00422                                     while (i--) 
00423                                         triangle = triangle->next;
00424                                 }
00425                                 else
00426                                 {
00427                                     // pick the first triangle
00428                                     triangle = degreeBag[lowDegree].first;
00429                                 }
00430                                 break;
00431                             }
00432                         }
00433 
00434                         if(triangle)
00435                         {
00436                             // create the new list
00437                             fList = new TriangleList;
00438 
00439                             // find the best neighbour
00440                             gateEdge = 0;
00441                             for (i = 0; i < 3; ++i)
00442                             {
00443                                 if((twin = triangle->halfEdgeVec[i].twin) && 
00444                                     (twin->triangle->state > 0))
00445                                 {
00446                                     if(twin->next->next->twin &&
00447                                        (twin->next->next->twin->triangle->state > 0))
00448                                     {
00449                                         gateEdge = &triangle->halfEdgeVec[i];
00450                                         break;
00451                                     }
00452                                     else
00453                                     {
00454                                         if(twin->next->twin &&
00455                                            (twin->next->twin->triangle->state > 0))
00456                                         {
00457                                             gateEdge = &triangle->halfEdgeVec[i];
00458                                         }
00459                                         else
00460                                         {
00461                                             if((twin->triangle->state > 0))
00462                                                 gateEdge = &triangle->halfEdgeVec[i];
00463                                         }
00464                                     }
00465                                 }
00466                             }
00467 
00468                             // release and store the first triangle
00469                             dropOutTriangle (*triangle,degreeBag);
00470                             fList->add(*triangle);
00471                             stripCost += 3;
00472 
00473                             // set the next step
00474                             if(gateEdge)
00475                             {
00476                                 walkCase = LEFT;
00477                                 ++stripCost;
00478                             }
00479                             else
00480                             {
00481                                 walkCase = FINISH;
00482                             }
00483                         }
00484                         else
00485                         {
00486                             doMainLoop = false;
00487                         }
00488                     break;
00489 
00490                     case LEFT:
00491                         gateEdge = gateEdge->twin;
00492                         triangle = gateEdge->triangle;
00493 
00494                         // find the next gate
00495                         if(triangle->state == DEGREE_0)
00496                         {
00497                             gateEdge = 0;
00498                             walkCase = FINISH;
00499                         }
00500                         else
00501                         {
00502                             if((twin = gateEdge->next->next->twin) && 
00503                                (twin->triangle->state > 0))
00504                             {
00505                                 gateEdge = gateEdge->next->next;
00506                                 ++stripCost;
00507                                 walkCase = RIGHT;
00508                             }
00509                             else
00510                             {
00511                                 gateEdge = gateEdge->next;
00512                                 stripCost += 2;
00513                                 walkCase = LEFT;
00514                             }
00515                         }
00516                         // store the current triangle
00517                         dropOutTriangle (*triangle,degreeBag);
00518                         fList->add(*triangle);
00519                     break;
00520 
00521                     case RIGHT:
00522                         gateEdge = gateEdge->twin;
00523                         triangle = gateEdge->triangle;
00524 
00525                         // find the next gate
00526                         if(triangle->state == DEGREE_0)
00527                         {
00528                             gateEdge = 0;
00529                             walkCase = FINISH;
00530                         }
00531                         else
00532                         {
00533                             if((twin = gateEdge->next->twin) &&
00534                                (twin->triangle->state > 0))
00535                             {
00536                                 gateEdge = gateEdge->next;
00537                                 ++stripCost;
00538                                 walkCase = LEFT;
00539                             }
00540                             else
00541                             {
00542                                 gateEdge = gateEdge->next->next;
00543                                 stripCost += 2;
00544                                 walkCase = RIGHT;
00545                             }
00546                         }
00547                         // store the current triangle
00548                         dropOutTriangle (*triangle,degreeBag);
00549                         fList->add(*triangle);
00550                     break;
00551 
00552                     case FINISH:
00553                         // try to reverse the strip
00554                         if(checkRevOrder &&
00555                            (revCost = calcStripCost(*fList,true)) &&
00556                            (revCost < stripCost))
00557                         {
00558                             _stripBag.push_back(Primitive(1,fList));
00559                             cost += revCost;
00560                         }
00561                         else
00562                         {
00563                             _stripBag.push_back(Primitive(0,fList));
00564                             cost += stripCost;
00565                         }
00566                         walkCase = START;
00567                         fList = 0;
00568                     break;
00569                 }
00570             }
00571 
00572             if(sample)
00573             {
00574                 sampleCost = cost + (degreeBag[0].countElem() * 3) + fanCost;
00575                 if(!bestCost || (sampleCost < bestCost))
00576                 {
00577                     bestCost = sampleCost;
00578                     bestSeed = seed;
00579                 }
00580                 if(sampleCost > worstCost)
00581                     worstCost = sampleCost;
00582 
00583                 SINFO << " cost/best/worst: " 
00584                       << sampleCost << '/' << bestCost << '/' << worstCost
00585                       << endl;
00586             }
00587 
00588             if(iteration)
00589             {
00590                 // reinit the four degree bags
00591                 degreeBag[mostDegree].paste(degreeBag[0]);
00592                 n = _stripBag.size();
00593                 for(i = 0; i < n; ++i)
00594                 {
00595                     degreeBag[mostDegree].paste(*_stripBag[i].second);
00596                     delete _stripBag[i].second;
00597                 }
00598                 _stripBag.clear();
00599                 for(triangle = degreeBag[mostDegree].first; triangle; 
00600                     triangle = next)
00601                 {
00602                     next = triangle->next;
00603                     triangle->resetDegreeState(STRIP_PART);
00604                     if (triangle->valid())
00605                     {
00606                         if(triangle->state != mostDegree)
00607                         {
00608                             degreeBag[mostDegree].release(*triangle);
00609                             degreeBag[triangle->state].add(*triangle);
00610                         }
00611                     }
00612                     else
00613                     {
00614                         SWARNING << "INVALID TRIANGLE IN REINIT\n" << endl;
00615                         SWARNING << triangle->state << endl;
00616                     }
00617                 }
00618             }
00619         }
00620     }
00621     else
00622     {
00623         // push every valid triangle in degree 0; we don't strip anything
00624         degreeBag[0].paste(_validTriangleBag);
00625     }
00626 
00627     if(sample)
00628     {
00629         SWARNING << "range: " 
00630              << bestCost << '/' << worstCost << ' '
00631              << float(100 * (worstCost-bestCost))/float(bestCost) << '%'
00632              << endl;
00633     }
00634 
00635     // collect isolated triangles  
00636     degreeBag[0].paste(_invalidTriangleBag);  
00637     triCost = degreeBag[0].countElem() * 3;
00638     if(triCost)
00639     {
00640         fList = new TriangleList;  
00641         fList->paste(degreeBag[0]);
00642         _triBag.push_back(Primitive(0,fList));
00643     }
00644 
00645     return (cost + fanCost + triCost);
00646 }

UInt32 osg::HalfEdgeGraph::primitiveCount ( void   )  [inline]

Definition at line 424 of file OSGHalfEdgeGraph.inl.

References _fanBag, _stripBag, and _triBag.

Referenced by osg::createOptimizedPrimitives().

00425 {
00426     return (_stripBag.size() + _fanBag.size() + _triBag.size());
00427 }

Int32 osg::HalfEdgeGraph::getPrimitive ( std::vector< IndexT > &  indexVec,
Int32  type = 0 
)

Int32 osg::HalfEdgeGraph::calcEgdeLines ( std::vector< IndexT > &  indexVec,
bool  codeBorder = false 
)

void HalfEdgeGraph::clear ( void   ) 

Definition at line 957 of file OSGHalfEdgeGraph.cpp.

References _edgeLinkVec, _fanBag, _stripBag, _trianglePool, _triBag, and osg::HalfEdgeGraph::TrianglePool::clear().

Referenced by ~HalfEdgeGraph().

00958 {
00959     UInt32 i,n;
00960     
00961     _edgeLinkVec.clear();
00962     _trianglePool.clear();
00963     
00964     n = _stripBag.size();
00965     for(i = 0; i < n; ++i)
00966         delete _stripBag[i].second;
00967     _stripBag.clear();
00968     
00969     n = _fanBag.size();
00970     for(i = 0; i < n; ++i)
00971         delete _fanBag[i].second;
00972     _fanBag.clear();
00973     
00974     n = _triBag.size();
00975     for(i = 0; i < n; ++i)
00976         delete _triBag[i].second;
00977     _triBag.clear();
00978 }


Friends And Related Function Documentation

friend class HalfEdge [friend]

Definition at line 76 of file OSGHalfEdgeGraph.h.

friend class Triangle [friend]

Definition at line 79 of file OSGHalfEdgeGraph.h.

friend class TriangleList [friend]

Definition at line 80 of file OSGHalfEdgeGraph.h.

friend class TrianglePool [friend]

Definition at line 81 of file OSGHalfEdgeGraph.h.

friend class TrianglePool::Chunk [friend]

Definition at line 162 of file OSGHalfEdgeGraph.h.


Member Data Documentation

Definition at line 166 of file OSGHalfEdgeGraph.h.

Referenced by addHalfEdge(), calcOptPrim(), clear(), getHalfEdge(), reserve(), and verify().

Definition at line 169 of file OSGHalfEdgeGraph.h.

Referenced by addTriangle(), calcOptPrim(), clear(), reserve(), and triangleCount().

Definition at line 172 of file OSGHalfEdgeGraph.h.

Referenced by addTriangle(), calcOptPrim(), and verify().

Definition at line 173 of file OSGHalfEdgeGraph.h.

Referenced by addTriangle(), calcOptPrim(), and verify().

std::vector<Primitive> osg::HalfEdgeGraph::_stripBag [private]

Definition at line 177 of file OSGHalfEdgeGraph.h.

Referenced by calcOptPrim(), clear(), and primitiveCount().

std::vector<Primitive> osg::HalfEdgeGraph::_fanBag [private]

Definition at line 178 of file OSGHalfEdgeGraph.h.

Referenced by calcOptPrim(), clear(), and primitiveCount().

std::vector<Primitive> osg::HalfEdgeGraph::_triBag [private]

Definition at line 179 of file OSGHalfEdgeGraph.h.

Referenced by calcOptPrim(), clear(), and primitiveCount().


The documentation for this class was generated from the following files:

Generated on Mon Mar 17 12:07:14 2008 for OpenSG by  doxygen 1.5.5