00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 #include <iostream>
00041 #include <stdlib.h>
00042 #include <math.h>
00043
00044 #include <map>
00045
00046 #include <OSGGL.h>
00047
00048
00049
00050
00051
00052 #include "OSGHalfEdgeGraph.h"
00053
00054
00055 using namespace std;
00056
00057 OSG_USING_NAMESPACE
00058
00059 #if !defined(OSG_DO_DOC) || defined(OSG_DOC_DEV)
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070 HalfEdgeGraph::HalfEdgeGraph (void)
00071 {
00072 }
00073
00074
00075
00076
00077
00078
00079
00080
00081 HalfEdgeGraph::HalfEdgeGraph (const HalfEdgeGraph &OSG_CHECK_ARG(obj))
00082 {
00083 SWARNING << "Run HalfEdgeGraph copy constructor; not impl.\n" << endl;
00084 }
00085
00086
00087
00088
00089
00090
00091
00092
00093 HalfEdgeGraph::~HalfEdgeGraph (void )
00094 {
00095 clear();
00096 }
00097
00098
00099
00100
00101
00102
00103
00104
00105 bool HalfEdgeGraph::Triangle::verify (void)
00106 {
00107 bool retCode = true;
00108 Triangle *neighbor[3];
00109 Triangle *tP;
00110
00111 neighbor[0] = halfEdgeVec[0].twin ? halfEdgeVec[0].twin->triangle : 0;
00112 neighbor[1] = halfEdgeVec[1].twin ? halfEdgeVec[1].twin->triangle : 0;
00113 neighbor[2] = halfEdgeVec[2].twin ? halfEdgeVec[2].twin->triangle : 0;
00114
00115 if ( ( neighbor[0] &&
00116 ( (neighbor[0] == neighbor[1] ) ||
00117 (neighbor[0] == neighbor[2] )
00118 )
00119 ) ||
00120 ( neighbor[1] &&
00121 ( (neighbor[1] == neighbor[0] ) ||
00122 (neighbor[1] == neighbor[2] ) )
00123 ) ||
00124 ( neighbor[2] &&
00125 ( (neighbor[2] == neighbor[0] ) ||
00126 (neighbor[2] == neighbor[1] ) )
00127 )
00128 )
00129 {
00130 FINFO(("HalfEdgeGraph::Triangle::verify: Neighbor linked more "
00131 "than once: %p/%p/%p\n", neighbor[0],
00132 neighbor[1],
00133 neighbor[2]));
00134 retCode = false;
00135 }
00136
00137 if((halfEdgeVec[0].vertexStart() == halfEdgeVec[1].vertexStart()) ||
00138 (halfEdgeVec[0].vertexStart() == halfEdgeVec[2].vertexStart()) ||
00139 (halfEdgeVec[1].vertexStart() == halfEdgeVec[2].vertexStart()))
00140 {
00141 SINFO << "HalfEdgeGraph::Triangle::verify: Invalid collapsed Triangle"
00142 << endl;
00143 retCode = false;
00144 }
00145
00146 if((halfEdgeVec[0].triangle != this) ||
00147 (halfEdgeVec[1].triangle != this) ||
00148 (halfEdgeVec[2].triangle != this))
00149 {
00150 SINFO << "HalfEdgeGraph::Triangle::verify: Invalid halfEdge->"
00151 << "triangle pointer" << endl;
00152 retCode = false;
00153 }
00154
00155 if((halfEdgeVec[0].next != &halfEdgeVec[1]) ||
00156 (halfEdgeVec[1].next != &halfEdgeVec[2]) ||
00157 (halfEdgeVec[2].next != &halfEdgeVec[0]))
00158 {
00159 SINFO << "HalfEdgeGraph::Triangle::verify: Edge next link error"
00160 << endl;
00161 retCode = false;
00162 }
00163
00164 return retCode;
00165 }
00166
00167
00168
00169
00170
00171
00172
00173
00174 void HalfEdgeGraph::reserve(UInt32 vertexNum, UInt32 triangleNum,
00175 UInt32 reserveEdges )
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 }
00188
00189
00190
00191
00192
00193
00194
00195
00196 bool HalfEdgeGraph::verify (bool verbose)
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 }
00301
00302
00303
00304
00305
00306
00307
00308
00309 UInt32 HalfEdgeGraph::calcOptPrim(UInt32 extIteration,
00310 bool doStrip, bool doFan,
00311 UInt32 minFanTriangles)
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
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
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
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
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
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
00428 triangle = degreeBag[lowDegree].first;
00429 }
00430 break;
00431 }
00432 }
00433
00434 if(triangle)
00435 {
00436
00437 fList = new TriangleList;
00438
00439
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
00469 dropOutTriangle (*triangle,degreeBag);
00470 fList->add(*triangle);
00471 stripCost += 3;
00472
00473
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
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
00517 dropOutTriangle (*triangle,degreeBag);
00518 fList->add(*triangle);
00519 break;
00520
00521 case RIGHT:
00522 gateEdge = gateEdge->twin;
00523 triangle = gateEdge->triangle;
00524
00525
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
00548 dropOutTriangle (*triangle,degreeBag);
00549 fList->add(*triangle);
00550 break;
00551
00552 case FINISH:
00553
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
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
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
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 }
00647
00648
00649
00650
00651
00652
00653
00654
00655 Int32 HalfEdgeGraph::calcStripCost(TriangleList &strip, bool rev)
00656 {
00657 Triangle *triangle = rev ? strip.last : strip.first, *nextTriangle;
00658 HalfEdge *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
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
00680 if(halfEdge->next == gate)
00681 {
00682 ++cost;
00683 walkCase = LEFT;
00684 }
00685 else
00686 {
00687
00688 cost += 2;
00689 }
00690 }
00691 else
00692 {
00693
00694 if(halfEdge->next->next == gate)
00695 {
00696 ++cost;
00697 walkCase = RIGHT;
00698 }
00699 else
00700 {
00701
00702 cost += 2;
00703 }
00704 }
00705 }
00706 }
00707 }
00708
00709 return cost;
00710 }
00711
00712
00713
00714
00715
00716
00717
00718
00719 Int32 HalfEdgeGraph::fillIndexFromStrip(std::vector<HalfEdgeGraph::IndexT> &indexVec,
00720 TriangleList &strip, bool rev)
00721 {
00722 Triangle *triangle = rev ? strip.last : strip.first, *nextTriangle;
00723 HalfEdge *firstEdge, *halfEdge, *gate;
00724 WalkCase walkCase;
00725 HalfEdgeGraph::IndexT vertex;
00726 Int32 cost = 0;
00727
00728 if (triangle)
00729 {
00730 cost = 3;
00731 indexVec.reserve(32);
00732 indexVec.resize(3);
00733 if((nextTriangle = (rev ? triangle->prev : triangle->next)))
00734 {
00735 ++cost;
00736 gate = findGateEdge(triangle,nextTriangle);
00737 firstEdge = gate->next->next;
00738 indexVec.push_back(vertex = gate->twin->next->vertexEnd());
00739
00740 walkCase = LEFT;
00741 for(triangle = nextTriangle;
00742 (nextTriangle = (rev ? triangle->prev : triangle->next));
00743 triangle = nextTriangle)
00744 {
00745 halfEdge = gate->twin;
00746 gate = findGateEdge(triangle,nextTriangle);
00747 if(walkCase == RIGHT)
00748 {
00749
00750 if(halfEdge->next == gate)
00751 {
00752 indexVec.push_back(vertex = gate->twin->next->vertexEnd());
00753 walkCase = LEFT;
00754 ++cost;
00755 }
00756 else
00757 {
00758
00759 indexVec.back() = gate->vertexEnd();
00760 indexVec.push_back(gate->vertexStart());
00761 indexVec.push_back(vertex = gate->twin->next->vertexEnd());
00762 cost += 2;
00763 }
00764 }
00765 else
00766 {
00767
00768 if (halfEdge->next->next == gate)
00769 {
00770 indexVec.push_back(vertex = gate->twin->next->vertexEnd());
00771 walkCase = RIGHT;
00772 ++cost;
00773 }
00774 else
00775 {
00776
00777 indexVec.back() = gate->vertexStart();
00778 indexVec.push_back(gate->vertexEnd());
00779 indexVec.push_back(vertex = gate->twin->next->vertexEnd());
00780 cost += 2;
00781 }
00782 }
00783 }
00784 }
00785 else
00786 {
00787 firstEdge = &triangle->halfEdgeVec[0];
00788 }
00789
00790 indexVec[0] = vertex = firstEdge->vertexStart();
00791 indexVec[1] = vertex = firstEdge->next->vertexStart();
00792 indexVec[2] = vertex = firstEdge->next->next->vertexStart();
00793 }
00794
00795 return cost;
00796 }
00797
00798
00799
00800
00801
00802
00803
00804
00805 Int32 HalfEdgeGraph::fillIndexFromFan(std::vector<HalfEdgeGraph::IndexT> &indexVec,
00806 HalfEdge &firstEdge )
00807 {
00808 Int32 count = 0;
00809 HalfEdge *halfEdge(&firstEdge);
00810 HalfEdge *gateEdge = 0;
00811
00812 if(halfEdge)
00813 {
00814 count = 3;
00815 indexVec.resize(2);
00816 indexVec[0] = halfEdge->vertexStart();
00817 indexVec[1] = halfEdge->vertexEnd();
00818 for(gateEdge = halfEdge->next->next->twin;
00819 gateEdge != halfEdge;
00820 gateEdge = gateEdge->next->next->twin)
00821 {
00822 indexVec.push_back(gateEdge->vertexEnd());
00823 ++count;
00824 }
00825 indexVec.push_back(halfEdge->vertexEnd());
00826 }
00827 else
00828 {
00829 SWARNING << "Invalid fac in fillIndexFromFan()" << endl;
00830 }
00831 return count;
00832 }
00833
00834
00835
00836
00837
00838
00839
00840
00841 Int32 HalfEdgeGraph::getPrimitive(vector<HalfEdgeGraph::IndexT> &indexVec,
00842 Int32 type)
00843 {
00844 UInt32 i = 0, n = 0;
00845 Triangle *triangle;
00846 std::vector<Primitive> *bag = 0;
00847
00848 indexVec.clear();
00849
00850
00851 if(!bag && (n = _fanBag.size()) &&
00852 ((type == GL_TRIANGLE_FAN) || !type))
00853 {
00854 i = n - 1;
00855 bag = &_fanBag;
00856 fillIndexFromFan(indexVec,
00857 *_edgeLinkVec[_fanBag[i].first][0].second);
00858 type = GL_TRIANGLE_FAN;
00859 }
00860
00861
00862 if(!bag && (n = _stripBag.size()) &&
00863 ((type == GL_TRIANGLE_STRIP) || !type))
00864 {
00865 i = n - 1;
00866 bag = &_stripBag;
00867 fillIndexFromStrip(indexVec, *_stripBag[i].second,
00868 _stripBag[i].first ? true : false );
00869 type = GL_TRIANGLE_STRIP;
00870 }
00871
00872
00873 if(!bag && (n = _triBag.size()) &&
00874 ((type == GL_TRIANGLES) || !type))
00875 {
00876 bag = &_triBag;
00877 if (_triBag[0].second->empty() == false)
00878 {
00879 n = _triBag[0].second->countElem() * 3;
00880 indexVec.resize(n);
00881 i = 0;
00882 for(triangle = _triBag[0].second->first; triangle;
00883 triangle = triangle->next )
00884 {
00885 indexVec[i++] = triangle->halfEdgeVec[0].vertexStart();
00886 indexVec[i++] = triangle->halfEdgeVec[1].vertexStart();
00887 indexVec[i++] = triangle->halfEdgeVec[2].vertexStart();
00888 }
00889 }
00890 type = GL_TRIANGLES;
00891 i = 0;
00892 }
00893
00894 if(bag)
00895 {
00896 _invalidTriangleBag.paste(*((*bag)[i].second));
00897 delete (*bag)[i].second;
00898 if (i)
00899 bag->resize(i);
00900 else
00901 bag->clear();
00902 }
00903 else
00904 {
00905 type = 0;
00906 }
00907 return type;
00908 }
00909
00910
00911
00912
00913
00914
00915
00916
00917 Int32 HalfEdgeGraph::calcEgdeLines(vector<HalfEdgeGraph::IndexT> & indexVec,
00918 bool codeBorder )
00919 {
00920 UInt32 i, nN, j, nE, halfEdgeCount = 0;
00921 HalfEdgeGraph::IndexT startVertexIndex, endVertexIndex;
00922 HalfEdge *halfEdge;
00923 bool isBorder;
00924
00925 indexVec.clear();
00926 nN = _edgeLinkVec.size();
00927 for (i = 0; i < nN; ++i)
00928 {
00929 nE = _edgeLinkVec[i].size();
00930 for ( j = 0; j < nE; ++j)
00931 {
00932 halfEdge = _edgeLinkVec[i][j].second;
00933 startVertexIndex = halfEdge->vertexStart();
00934 endVertexIndex = halfEdge->vertexEnd();
00935
00936 if ((isBorder = (halfEdge->twin == 0)) || (startVertexIndex <
00937 endVertexIndex))
00938 {
00939 indexVec.push_back(startVertexIndex);
00940 indexVec.push_back(endVertexIndex);
00941 if(codeBorder)
00942 indexVec.push_back(isBorder ? 0 : 1);
00943 ++halfEdgeCount;
00944 }
00945 }
00946 }
00947 return halfEdgeCount;
00948 }
00949
00950
00951
00952
00953
00954
00955
00956
00957 void HalfEdgeGraph::clear(void)
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 }
00979
00980 #endif // remove from all but dev docs