changed: gcc8 base update
[opensg.git] / Source / System / NodeCores / Drawables / Geometry / Util / OSGStriperHalfEdgeGraph.cpp
blob48bc8b367390d5a6ca1a2a3358b1df241497aa69
1 /*---------------------------------------------------------------------------*\
2 * OpenSG *
3 * *
4 * *
5 * Copyright (C) 2000-2002 by the OpenSG Forum *
6 * *
7 * www.opensg.org *
8 * *
9 * contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de *
10 * *
11 \*---------------------------------------------------------------------------*/
12 /*---------------------------------------------------------------------------*\
13 * License *
14 * *
15 * This library is free software; you can redistribute it and/or modify it *
16 * under the terms of the GNU Library General Public License as published *
17 * by the Free Software Foundation, version 2. *
18 * *
19 * This library is distributed in the hope that it will be useful, but *
20 * WITHOUT ANY WARRANTY; without even the implied warranty of *
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
22 * Library General Public License for more details. *
23 * *
24 * You should have received a copy of the GNU Library General Public *
25 * License along with this library; if not, write to the Free Software *
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
27 * *
28 \*---------------------------------------------------------------------------*/
29 /*---------------------------------------------------------------------------*\
30 * Changes *
31 * *
32 * *
33 * *
34 * *
35 * *
36 * *
37 \*---------------------------------------------------------------------------*/
39 // System declarations
40 #include <iostream>
41 #include <stdlib.h>
42 #include <math.h>
44 #include <map>
46 #include "OSGGL.h"
48 // Application declarations
51 // Class declarations
52 #include "OSGStriperHalfEdgeGraph.h"
55 using namespace std;
57 OSG_USING_NAMESPACE
59 #if !defined(OSG_DO_DOC) || defined(OSG_DOC_DEV)
61 // Static Class Varible implementations:
63 //----------------------------------------------------------------------
64 // Method: HalfEdgeGraph
65 // Author: jbehr
66 // Date: Tue Feb 15 18:16:59 2000
67 // Description:
68 // Default Constructor
69 //----------------------------------------------------------------------
70 StriperHalfEdgeGraph::StriperHalfEdgeGraph (void) :
71 _edgeLinkVec (),
72 _trianglePool (),
74 _validTriangleBag (),
75 _invalidTriangleBag(),
77 _stripBag (),
78 _fanBag (),
79 _triBag ()
83 //----------------------------------------------------------------------
84 // Method: HalfEdgeGraph
85 // Author: jbehr
86 // Date: Tue Feb 15 18:16:59 2000
87 // Description:
88 // Copy Constructor
89 //----------------------------------------------------------------------
90 #if 0
91 StriperHalfEdgeGraph::StriperHalfEdgeGraph(
92 const StriperHalfEdgeGraph &OSG_CHECK_ARG(obj))
94 SWARNING << "Run HalfEdgeGraph copy constructor; not impl.\n" << endl;
96 #endif
98 //----------------------------------------------------------------------
99 // Method: ~HalfEdgeGraph
100 // Author: jbehr
101 // Date: Tue Feb 15 18:16:59 2000
102 // Description:
103 // Destructor
104 //----------------------------------------------------------------------
105 StriperHalfEdgeGraph::~StriperHalfEdgeGraph (void )
107 clear();
110 //----------------------------------------------------------------------
111 // Method: ~HalfEdgeGraph
112 // Author: jbehr
113 // Date: Tue Feb 15 18:16:59 2000
114 // Description:
115 // Destructor
116 //----------------------------------------------------------------------
117 bool StriperHalfEdgeGraph::Triangle::verify (void)
119 bool retCode = true;
120 Triangle *neighbor[3];
122 neighbor[0] = halfEdgeVec[0].twin ? halfEdgeVec[0].twin->triangle : 0;
123 neighbor[1] = halfEdgeVec[1].twin ? halfEdgeVec[1].twin->triangle : 0;
124 neighbor[2] = halfEdgeVec[2].twin ? halfEdgeVec[2].twin->triangle : 0;
126 if ( ( neighbor[0] &&
127 ( (neighbor[0] == neighbor[1] ) ||
128 (neighbor[0] == neighbor[2] )
130 ) ||
131 ( neighbor[1] &&
132 ( (neighbor[1] == neighbor[0] ) ||
133 (neighbor[1] == neighbor[2] ) )
134 ) ||
135 ( neighbor[2] &&
136 ( (neighbor[2] == neighbor[0] ) ||
137 (neighbor[2] == neighbor[1] ) )
141 FINFO(("StriperHalfEdgeGraph::Triangle::verify: Neighbor linked more "
142 "than once: %p/%p/%p\n", static_cast<void *>(neighbor[0]),
143 static_cast<void *>(neighbor[1]),
144 static_cast<void *>(neighbor[2])));
145 retCode = false;
148 if((halfEdgeVec[0].vertexStart() == halfEdgeVec[1].vertexStart()) ||
149 (halfEdgeVec[0].vertexStart() == halfEdgeVec[2].vertexStart()) ||
150 (halfEdgeVec[1].vertexStart() == halfEdgeVec[2].vertexStart()))
152 SINFO << "StriperHalfEdgeGraph::Triangle::verify: "
153 << "Invalid collapsed Triangle"
154 << endl;
155 retCode = false;
158 if((halfEdgeVec[0].triangle != this) ||
159 (halfEdgeVec[1].triangle != this) ||
160 (halfEdgeVec[2].triangle != this))
162 SINFO << "StriperHalfEdgeGraph::Triangle::verify: Invalid halfEdge->"
163 << "triangle pointer" << endl;
164 retCode = false;
167 if((halfEdgeVec[0].next != &halfEdgeVec[1]) ||
168 (halfEdgeVec[1].next != &halfEdgeVec[2]) ||
169 (halfEdgeVec[2].next != &halfEdgeVec[0]))
171 SINFO << "StriperHalfEdgeGraph::Triangle::verify: Edge next link error"
172 << endl;
173 retCode = false;
176 return retCode;
179 //----------------------------------------------------------------------
180 // Method: reserve
181 // Author: jbehr
182 // Date: Tue Feb 15 18:16:59 2000
183 // Description:
185 //----------------------------------------------------------------------
186 void StriperHalfEdgeGraph::reserve(UInt32 vertexNum, UInt32 triangleNum,
187 UInt32 reserveEdges )
189 UInt32 i;
191 _trianglePool.setChunkSize(triangleNum);
192 _edgeLinkVec.resize(vertexNum);
194 if(reserveEdges > 0)
196 for(i = 0; i < vertexNum; ++i)
197 _edgeLinkVec[i].reserve(reserveEdges);
201 //----------------------------------------------------------------------
202 // Method: verify
203 // Author: jbehr
204 // Date: Tue Feb 15 18:16:59 2000
205 // Description:
207 //----------------------------------------------------------------------
208 bool StriperHalfEdgeGraph::verify (bool verbose)
210 bool retCode = true;
211 UInt32 i, n;
212 Triangle *triangle, *nt0, *nt1, *nt2;
213 Int32 triangleState[4];
214 Int32 invalidTriangles = 0;
215 Int32 halfEdgeCount = 0;
216 map< Int32, Int32 > connectionMap;
217 map< Int32, Int32 >::iterator connectionI;
218 Int32 connectionCount;
219 bool validTri = false;
221 for(i = 0; i < 4; ++i)
222 triangleState[i] = 0;
224 for( i = 0, triangle = _validTriangleBag.first;
225 triangle;
226 i++, triangle = triangle->next)
228 // Looks strange (GV)
229 if((triangle->verify() && (triangle->state >= 0)) ||
230 (triangle->state <= 3))
232 triangleState[triangle->state]++;
233 validTri = true;
235 else
237 ++invalidTriangles;
238 validTri = false;
241 if ( verbose )
243 nt0 = triangle->halfEdgeVec[0].twin ?
244 triangle->halfEdgeVec[0].twin->triangle : 0;
245 nt1 = triangle->halfEdgeVec[1].twin ?
246 triangle->halfEdgeVec[1].twin->triangle : 0;
247 nt2 = triangle->halfEdgeVec[2].twin ?
248 triangle->halfEdgeVec[2].twin->triangle : 0;
250 FINFO ( ( "HEG: Triangle %p: %d %d %d, %p %p %p: %s\n",
251 static_cast<void *>(triangle),
252 triangle->halfEdgeVec[0].vertexStart(),
253 triangle->halfEdgeVec[1].vertexStart(),
254 triangle->halfEdgeVec[2].vertexStart(),
255 static_cast<void *>(nt0),
256 static_cast<void *>(nt1),
257 static_cast<void *>(nt2),
258 (validTri ? "VALID" : "INVALID" ) ) );
262 SINFO << "HEG: linked triangle count " << _validTriangleBag.countElem()
263 << endl;
264 SINFO << "HEG: invalid triangle " << invalidTriangles
265 << endl;
266 SINFO << "HEG: nonmanifold split: " << _invalidTriangleBag.countElem()
267 << endl;
269 SINFO << "HEG: triangle state: "
270 << triangleState[0]
271 << "/"
272 << triangleState[1]
273 << "/"
274 << triangleState[2]
275 << "/"
276 << triangleState[3]
277 << endl;
279 n = UInt32(_edgeLinkVec.size());
280 halfEdgeCount = 0;
281 for (i = 0; i < n; ++i)
283 connectionCount = UInt32(_edgeLinkVec[i].size());
285 halfEdgeCount += connectionCount;
286 if (connectionMap.find(connectionCount) == connectionMap.end())
287 connectionMap[connectionCount] = 1;
288 else
289 connectionMap[connectionCount]++;
291 if (verbose)
293 HalfEdgeLink::iterator lI;
294 for ( lI = _edgeLinkVec[i].begin();
295 lI != _edgeLinkVec[i].end(); ++lI )
297 FINFO (( "HEG: HalfEdge %p: %d to %d, twin: %p\n",
298 static_cast<void *>(lI->second),
299 lI->second->vertexStart(),
300 lI->second->vertexEnd(),
301 static_cast<void *>(lI->second->twin)));
305 for(connectionI = connectionMap.begin();
306 connectionI != connectionMap.end(); ++connectionI)
308 SINFO << "HEG: Connection: " << connectionI->first << '/'
309 << connectionI->second << ' ' << std::endl;
312 SINFO << "HEG: HalfEdgeCount: " << halfEdgeCount << endl;
314 return retCode;
317 //----------------------------------------------------------------------
318 // Method: calcOptPrim
319 // Author: jbehr
320 // Date: Tue Feb 15 18:16:59 2000
321 // Description:
323 //----------------------------------------------------------------------
324 UInt32 StriperHalfEdgeGraph::calcOptPrim(UInt32 extIteration,
325 bool doStrip, bool doFan,
326 UInt32 minFanTriangles)
328 Int32 iteration = extIteration;
329 bool sample = iteration > 1 ? true : false;
330 bool checkRevOrder = sample;
331 TriangleList degreeBag[4];
332 TriangleList *fList = 0;
333 Int32 cost = 0, sampleCost = 0;
334 Int32 stripCost = 0, revCost = 0, fanCost = 0, triCost = 0;
335 Int32 bestCost = 0, worstCost = 0, lowDegree;
336 UInt32 i, n;
337 WalkCase walkCase = START;
338 Triangle *triangle, *next;
339 HalfEdge *twin = 0, *gateEdge = 0, *halfEdge = 0;
340 bool doMainLoop = true;
341 UInt32 seed = 1, bestSeed = 1;
342 Int32 mostDegree = 3;
343 UInt32 triangleLeft = _trianglePool.countElem();
344 srand(1);
346 if(doFan)
348 n = UInt32(_edgeLinkVec.size());
349 fanCost = 0;
351 // find fans
352 for(i = 0; i < n; ++i)
354 if((_edgeLinkVec[i].size() >= minFanTriangles) &&
355 (gateEdge = _edgeLinkVec[i][0].second) &&
356 (gateEdge->triangle->valid()))
358 for(halfEdge = gateEdge->next->next->twin;
359 (halfEdge && halfEdge->triangle->valid() &&
360 (halfEdge != gateEdge));
361 halfEdge = halfEdge->next->next->twin)
363 if(halfEdge == gateEdge)
365 // fan is closed; mark every triangle
366 triangle = 0;
367 fList = new TriangleList;
368 for(halfEdge = gateEdge;
369 !triangle || (halfEdge != gateEdge);
370 halfEdge = halfEdge->next->next->twin)
372 triangle = halfEdge->triangle;
373 _validTriangleBag.release(*triangle);
374 triangle->drop();
375 triangle->state = FAN_PART;
376 fList->add(*triangle);
378 _fanBag.push_back(Primitive(i,fList));
379 fanCost += (UInt32(_edgeLinkVec[i].size()) + 2);
380 triangleLeft -= UInt32(_edgeLinkVec[i].size());
386 if(doStrip && iteration)
388 // push every triangle into the according degree bag
389 degreeBag[mostDegree].paste(_validTriangleBag);
390 for(triangle = degreeBag[mostDegree].first; triangle; triangle = next)
392 next = triangle->next;
393 if(triangle->valid())
395 if(triangle->state != mostDegree)
397 degreeBag[mostDegree].release(*triangle);
398 _validTriangleBag.release(*triangle);
399 degreeBag[triangle->state].add( *triangle);
402 else
404 SWARNING << "INVALID TRIANGLE IN VALID TRIANGLE BAG\n" << endl;
408 for(iteration--; iteration >= 0; iteration--)
410 seed = iteration ? rand() : bestSeed;
411 srand (seed);
413 fList = 0;
414 cost = 0;
415 doMainLoop = true;
416 walkCase = START;
418 // run the main loop
419 while(doMainLoop)
421 switch(walkCase)
423 case START:
424 stripCost = 0;
425 triangle = 0;
427 for(lowDegree = 1; lowDegree < 4; ++lowDegree)
429 if((degreeBag[lowDegree].empty() == false))
431 if(sample)
433 // pick a random triangle
434 n = degreeBag[lowDegree].countElem() - 1;
435 i = Int32(float(n)*rand()/float(RAND_MAX));
436 triangle = degreeBag[lowDegree].first;
437 while (i--)
438 triangle = triangle->next;
440 else
442 // pick the first triangle
443 triangle = degreeBag[lowDegree].first;
445 break;
449 if(triangle)
451 // create the new list
452 fList = new TriangleList;
454 // find the best neighbour
455 gateEdge = 0;
456 for (i = 0; i < 3; ++i)
458 if((twin = triangle->halfEdgeVec[i].twin) &&
459 (twin->triangle->state > 0))
461 if(twin->next->next->twin &&
462 (twin->next->next->twin->triangle->state > 0))
464 gateEdge = &triangle->halfEdgeVec[i];
465 break;
467 else
469 if(twin->next->twin &&
470 (twin->next->twin->triangle->state > 0))
472 gateEdge = &triangle->halfEdgeVec[i];
474 else
476 if((twin->triangle->state > 0))
477 gateEdge = &triangle->halfEdgeVec[i];
483 // release and store the first triangle
484 dropOutTriangle (*triangle,degreeBag);
485 fList->add(*triangle);
486 stripCost += 3;
488 // set the next step
489 if(gateEdge)
491 walkCase = LEFT;
492 ++stripCost;
494 else
496 walkCase = FINISH;
499 else
501 doMainLoop = false;
503 break;
505 case LEFT:
506 gateEdge = gateEdge->twin;
507 triangle = gateEdge->triangle;
509 // find the next gate
510 if(triangle->state == DEGREE_0)
512 gateEdge = 0;
513 walkCase = FINISH;
515 else
517 if((twin = gateEdge->next->next->twin) &&
518 (twin->triangle->state > 0))
520 gateEdge = gateEdge->next->next;
521 ++stripCost;
522 walkCase = RIGHT;
524 else
526 gateEdge = gateEdge->next;
527 stripCost += 2;
528 walkCase = LEFT;
531 // store the current triangle
532 dropOutTriangle (*triangle,degreeBag);
533 fList->add(*triangle);
534 break;
536 case RIGHT:
537 gateEdge = gateEdge->twin;
538 triangle = gateEdge->triangle;
540 // find the next gate
541 if(triangle->state == DEGREE_0)
543 gateEdge = 0;
544 walkCase = FINISH;
546 else
548 if((twin = gateEdge->next->twin) &&
549 (twin->triangle->state > 0))
551 gateEdge = gateEdge->next;
552 ++stripCost;
553 walkCase = LEFT;
555 else
557 gateEdge = gateEdge->next->next;
558 stripCost += 2;
559 walkCase = RIGHT;
562 // store the current triangle
563 dropOutTriangle (*triangle,degreeBag);
564 fList->add(*triangle);
565 break;
567 case FINISH:
568 // try to reverse the strip
569 if(checkRevOrder &&
570 (revCost = calcStripCost(*fList,true)) &&
571 (revCost < stripCost))
573 _stripBag.push_back(Primitive(1,fList));
574 cost += revCost;
576 else
578 _stripBag.push_back(Primitive(0,fList));
579 cost += stripCost;
581 walkCase = START;
582 fList = 0;
583 break;
587 if(sample)
589 sampleCost = cost + (degreeBag[0].countElem() * 3) + fanCost;
590 if(!bestCost || (sampleCost < bestCost))
592 bestCost = sampleCost;
593 bestSeed = seed;
595 if(sampleCost > worstCost)
596 worstCost = sampleCost;
598 SINFO << " cost/best/worst: "
599 << sampleCost << '/' << bestCost << '/' << worstCost
600 << endl;
603 if(iteration)
605 // reinit the four degree bags
606 degreeBag[mostDegree].paste(degreeBag[0]);
607 n = UInt32(_stripBag.size());
608 for(i = 0; i < n; ++i)
610 degreeBag[mostDegree].paste(*_stripBag[i].second);
611 delete _stripBag[i].second;
613 _stripBag.clear();
614 for(triangle = degreeBag[mostDegree].first; triangle;
615 triangle = next)
617 next = triangle->next;
618 triangle->resetDegreeState(STRIP_PART);
619 if (triangle->valid())
621 if(triangle->state != mostDegree)
623 degreeBag[mostDegree].release(*triangle);
624 degreeBag[triangle->state].add(*triangle);
627 else
629 SWARNING << "INVALID TRIANGLE IN REINIT\n" << endl;
630 SWARNING << triangle->state << endl;
636 else
638 // push every valid triangle in degree 0; we don't strip anything
639 degreeBag[0].paste(_validTriangleBag);
642 if(sample)
644 SWARNING << "range: "
645 << bestCost << '/' << worstCost << ' '
646 << float(100 * (worstCost-bestCost))/float(bestCost) << '%'
647 << endl;
650 // collect isolated triangles
651 degreeBag[0].paste(_invalidTriangleBag);
652 triCost = degreeBag[0].countElem() * 3;
653 if(triCost)
655 fList = new TriangleList;
656 fList->paste(degreeBag[0]);
657 _triBag.push_back(Primitive(0,fList));
660 return (cost + fanCost + triCost);
663 //----------------------------------------------------------------------
664 // Method: calcStripCost
665 // Author: jbehr
666 // Date: Tue Feb 15 18:16:59 2000
667 // Description:
669 //----------------------------------------------------------------------
670 Int32 StriperHalfEdgeGraph::calcStripCost(TriangleList &strip, bool rev)
672 Triangle *triangle = rev ? strip.last : strip.first, *nextTriangle;
673 HalfEdge /* *firstEdge, */ *halfEdge, *gate;
674 WalkCase walkCase;
675 Int32 cost = 0;
677 if (triangle)
679 cost = 3;
680 if ((nextTriangle = rev ? triangle->prev : triangle->next))
682 gate = findGateEdge(triangle,nextTriangle);
683 //firstEdge = gate->next->next;
684 ++cost;
685 walkCase = LEFT;
686 for(triangle = nextTriangle;
687 (nextTriangle = (rev ? triangle->prev : triangle->next));
688 triangle = nextTriangle)
690 halfEdge = gate->twin;
691 gate = findGateEdge(triangle,nextTriangle);
692 if (walkCase == RIGHT)
694 // RIGHT
695 if(halfEdge->next == gate)
697 ++cost;
698 walkCase = LEFT;
700 else
702 // swap; walkCase stays RIGHT;
703 cost += 2;
706 else
708 // LEFT
709 if(halfEdge->next->next == gate)
711 ++cost;
712 walkCase = RIGHT;
714 else
716 // swap; walkCase stays LEFT;
717 cost += 2;
724 return cost;
727 //----------------------------------------------------------------------
728 // Method: fillPrimFromStrip
729 // Author: jbehr
730 // Date: Tue Feb 15 18:16:59 2000
731 // Description:
733 //----------------------------------------------------------------------
734 Int32 StriperHalfEdgeGraph::fillIndexFromStrip(
735 std::vector<StriperHalfEdgeGraph::IndexT> &indexVec,
736 TriangleList &strip, bool rev)
738 Triangle *triangle = rev ? strip.last : strip.first, *nextTriangle;
739 HalfEdge *firstEdge, *halfEdge, *gate;
740 WalkCase walkCase;
741 StriperHalfEdgeGraph::IndexT vertex;
742 Int32 cost = 0;
744 if (triangle)
746 cost = 3;
747 indexVec.reserve(32); // find better value
748 indexVec.resize(3);
749 if((nextTriangle = (rev ? triangle->prev : triangle->next)))
751 ++cost;
752 gate = findGateEdge(triangle,nextTriangle);
753 firstEdge = gate->next->next;
754 indexVec.push_back(vertex = gate->twin->next->vertexEnd());
756 walkCase = LEFT;
757 for(triangle = nextTriangle;
758 (nextTriangle = (rev ? triangle->prev : triangle->next));
759 triangle = nextTriangle)
761 halfEdge = gate->twin;
762 gate = findGateEdge(triangle,nextTriangle);
763 if(walkCase == RIGHT)
765 // RIGHT
766 if(halfEdge->next == gate)
768 indexVec.push_back(vertex = gate->twin->next->vertexEnd());
769 walkCase = LEFT;
770 ++cost;
772 else
774 // swap; walkCase stays RIGHT;
775 indexVec.back() = gate->vertexEnd();
776 indexVec.push_back(gate->vertexStart());
777 indexVec.push_back(vertex = gate->twin->next->vertexEnd());
778 cost += 2;
781 else
783 // LEFT
784 if (halfEdge->next->next == gate)
786 indexVec.push_back(vertex = gate->twin->next->vertexEnd());
787 walkCase = RIGHT;
788 ++cost;
790 else
792 // swap; walkCase stays LEFT;
793 indexVec.back() = gate->vertexStart();
794 indexVec.push_back(gate->vertexEnd());
795 indexVec.push_back(vertex = gate->twin->next->vertexEnd());
796 cost += 2;
801 else
803 firstEdge = &triangle->halfEdgeVec[0];
806 indexVec[0] = vertex = firstEdge->vertexStart();
807 indexVec[1] = vertex = firstEdge->next->vertexStart();
808 indexVec[2] = vertex = firstEdge->next->next->vertexStart();
811 return cost;
814 //----------------------------------------------------------------------
815 // Method: fillPrimFromFan
816 // Author: jbehr
817 // Date: Tue Feb 15 18:16:59 2000
818 // Description:
820 //----------------------------------------------------------------------
821 Int32 StriperHalfEdgeGraph::fillIndexFromFan(
822 std::vector<StriperHalfEdgeGraph::IndexT> &indexVec,
823 HalfEdge &firstEdge )
825 Int32 count = 0;
826 HalfEdge *halfEdge(&firstEdge);
827 HalfEdge *gateEdge = 0;
829 if(halfEdge)
831 count = 3;
832 indexVec.resize(2);
833 indexVec[0] = halfEdge->vertexStart();
834 indexVec[1] = halfEdge->vertexEnd();
835 for(gateEdge = halfEdge->next->next->twin;
836 gateEdge != halfEdge;
837 gateEdge = gateEdge->next->next->twin)
839 indexVec.push_back(gateEdge->vertexEnd());
840 ++count;
842 indexVec.push_back(halfEdge->vertexEnd());
844 else
846 SWARNING << "Invalid fac in fillIndexFromFan()" << endl;
848 return count;
851 //----------------------------------------------------------------------
852 // Method: calcEdgeLines
853 // Author: jbehr
854 // Date: Tue Feb 15 18:16:59 2000
855 // Description:
857 //----------------------------------------------------------------------
858 Int32 StriperHalfEdgeGraph::getPrimitive(
859 vector<StriperHalfEdgeGraph::IndexT> &indexVec,
860 Int32 type)
862 UInt32 i = 0, n = 0;
863 Triangle *triangle;
864 std::vector<Primitive> *bag = 0;
866 indexVec.clear();
868 // fan
869 if(!bag && (n = UInt32(_fanBag.size())) &&
870 ((type == GL_TRIANGLE_FAN) || !type))
872 i = n - 1;
873 bag = &_fanBag;
874 fillIndexFromFan(indexVec,
875 *_edgeLinkVec[_fanBag[i].first][0].second);
876 type = GL_TRIANGLE_FAN;
879 // strip
880 if(!bag && (n = UInt32(_stripBag.size())) &&
881 ((type == GL_TRIANGLE_STRIP) || !type))
883 i = n - 1;
884 bag = &_stripBag;
885 fillIndexFromStrip(indexVec, *_stripBag[i].second,
886 _stripBag[i].first ? true : false );
887 type = GL_TRIANGLE_STRIP;
890 // tri
891 if(!bag && (n = UInt32(_triBag.size())) &&
892 ((type == GL_TRIANGLES) || !type))
894 bag = &_triBag;
895 if (_triBag[0].second->empty() == false)
897 n = _triBag[0].second->countElem() * 3;
898 indexVec.resize(n);
899 i = 0;
900 for(triangle = _triBag[0].second->first; triangle;
901 triangle = triangle->next )
903 indexVec[i++] = triangle->halfEdgeVec[0].vertexStart();
904 indexVec[i++] = triangle->halfEdgeVec[1].vertexStart();
905 indexVec[i++] = triangle->halfEdgeVec[2].vertexStart();
908 type = GL_TRIANGLES;
909 i = 0;
912 if(bag)
914 _invalidTriangleBag.paste(*((*bag)[i].second));
915 delete (*bag)[i].second;
916 if (i)
917 bag->resize(i);
918 else
919 bag->clear();
921 else
923 type = 0;
925 return type;
928 //----------------------------------------------------------------------
929 // Method: calcEdgeLines
930 // Author: jbehr
931 // Date: Tue Feb 15 18:16:59 2000
932 // Description:
934 //----------------------------------------------------------------------
935 Int32 StriperHalfEdgeGraph::calcEgdeLines(
936 vector<StriperHalfEdgeGraph::IndexT> & indexVec,
937 bool codeBorder )
939 UInt32 i, nN, j, nE, halfEdgeCount = 0;
940 StriperHalfEdgeGraph::IndexT startVertexIndex, endVertexIndex;
941 HalfEdge *halfEdge;
942 bool isBorder;
944 indexVec.clear();
945 nN = UInt32(_edgeLinkVec.size());
946 for (i = 0; i < nN; ++i)
948 nE = UInt32(_edgeLinkVec[i].size());
949 for ( j = 0; j < nE; ++j)
951 halfEdge = _edgeLinkVec[i][j].second;
952 startVertexIndex = halfEdge->vertexStart();
953 endVertexIndex = halfEdge->vertexEnd();
955 if ((isBorder = (halfEdge->twin == 0)) || (startVertexIndex <
956 endVertexIndex))
958 indexVec.push_back(startVertexIndex);
959 indexVec.push_back(endVertexIndex);
960 if(codeBorder)
961 indexVec.push_back(isBorder ? 0 : 1);
962 ++halfEdgeCount;
966 return halfEdgeCount;
969 //----------------------------------------------------------------------
970 // Method:
971 // Author: jbehr
972 // Date: Tue Feb 15 18:16:59 2000
973 // Description:
975 //----------------------------------------------------------------------
976 void StriperHalfEdgeGraph::clear(void)
978 UInt32 i,n;
980 _edgeLinkVec.clear();
981 _trianglePool.clear();
983 n = UInt32(_stripBag.size());
984 for(i = 0; i < n; ++i)
985 delete _stripBag[i].second;
986 _stripBag.clear();
988 n = UInt32(_fanBag.size());
989 for(i = 0; i < n; ++i)
990 delete _fanBag[i].second;
991 _fanBag.clear();
993 n = UInt32(_triBag.size());
994 for(i = 0; i < n; ++i)
995 delete _triBag[i].second;
996 _triBag.clear();
999 #endif // remove from all but dev docs