Go to the documentation of this file.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 #ifndef TriangleIterator_INCLUDE_ONCE
00033 #define TriangleIterator_INCLUDE_ONCE
00034
00035 #include <vlGraphics/Array.hpp>
00036 #include <vlCore/vlnamespace.hpp>
00037
00038 namespace vl
00039 {
00040
00041
00042
00044 class TriangleIteratorAbstract: public Object
00045 {
00046 VL_INSTRUMENT_ABSTRACT_CLASS(vl::TriangleIteratorAbstract, Object)
00047
00048 public:
00049 virtual bool next() = 0;
00050 virtual bool hasNext() const = 0;
00051 virtual int a() const = 0;
00052 virtual int b() const = 0;
00053 virtual int c() const = 0;
00054 };
00055
00056
00057
00059 template<class TArray>
00060 class TriangleIteratorIndexed: public TriangleIteratorAbstract
00061 {
00062 VL_INSTRUMENT_CLASS(vl::TriangleIteratorIndexed<TArray>, TriangleIteratorAbstract)
00063
00064 public:
00065
00066 TriangleIteratorIndexed()
00067 {
00068 VL_DEBUG_SET_OBJECT_NAME()
00069 mCurrentIndex = 0;
00070 mEnd = 0;
00071 mA = mB = mC = -1;
00072 mEven = true;
00073 mIndex0 = 0;
00074 mArray = NULL;
00075 mPrimRestartIndex = (unsigned int)-1;
00076 mPrimRestartOn = false;
00077 mBaseVertex = 0;
00078 mPrimType = PT_UNKNOWN;
00079 }
00080
00081 TriangleIteratorIndexed(const TArray* idx_array, EPrimitiveType prim_type, int base_vert, bool prim_restart_on, unsigned int prim_restart_idx)
00082 {
00083 VL_DEBUG_SET_OBJECT_NAME()
00084 mCurrentIndex = 0;
00085 mEnd = 0;
00086 mA = mB = mC = -1;
00087 mEven = true;
00088 mIndex0 = 0;
00089 mArray = idx_array;
00090 mPrimRestartIndex = prim_restart_idx;
00091 mPrimRestartOn = prim_restart_on;
00092 mBaseVertex = base_vert;
00093 mPrimType = prim_type;
00094 }
00095
00096 bool hasNext() const { return mCurrentIndex != mEnd; }
00097
00098 virtual int a() const { return mA; }
00099 virtual int b() const { return mB; }
00100 virtual int c() const { return mC; }
00101
00102 void initialize(int start=0, int end=-1)
00103 {
00104 VL_CHECK( start >= 0 )
00105 VL_CHECK( end <= (int)mArray->size() )
00106
00107 if (end == -1)
00108 end = (int)mArray->size();
00109
00110 mCurrentIndex = end;
00111 mA = mB = mC = -1;
00112 mEven = true;
00113 mIndex0 = start;
00114 mEnd = end;
00115 if (mArray->size())
00116 {
00117 switch(mPrimType)
00118 {
00119 case PT_TRIANGLES:
00120
00121 mCurrentIndex = start;
00122 mA = mArray->at(start+0);
00123 mB = mArray->at(start+1);
00124 mC = mArray->at(start+2);
00125 break;
00126 case PT_TRIANGLE_STRIP:
00127 mCurrentIndex = start;
00128 mA = mArray->at(start+0);
00129 mB = mArray->at(start+1);
00130 mC = mArray->at(start+2);
00131 break;
00132 case PT_TRIANGLE_FAN:
00133 case PT_POLYGON:
00134 mCurrentIndex = start + 1;
00135 mA = mArray->at(start+0);
00136 mB = mArray->at(start+1);
00137 mC = mArray->at(start+2);
00138 break;
00139 case PT_QUADS:
00140
00141 mCurrentIndex = start;
00142 mA = mArray->at(start+0);
00143 mB = mArray->at(start+1);
00144 mC = mArray->at(start+2);
00145 break;
00146 case PT_QUAD_STRIP:
00147
00148 mCurrentIndex = start;
00149 mA = mArray->at(start+0);
00150 mB = mArray->at(start+1);
00151 mC = mArray->at(start+2);
00152 break;
00153 default:
00154 break;
00155 }
00156 }
00157
00158
00159 if ( mCurrentIndex != mEnd )
00160 {
00161 mA += mBaseVertex;
00162 mB += mBaseVertex;
00163 mC += mBaseVertex;
00164 }
00165 else
00166 {
00167 mA = mB = mC = -1;
00168 }
00169 }
00170
00171 bool next()
00172 {
00173
00174 if ( mCurrentIndex == mEnd )
00175 return false;
00176
00177 switch(mPrimType)
00178 {
00179
00180 case PT_TRIANGLES:
00181 mCurrentIndex += 3;
00182
00183 if ( mCurrentIndex >= mEnd )
00184 mCurrentIndex = mEnd;
00185 else
00186 if ( isPrimRestart(mCurrentIndex) )
00187 {
00188 mCurrentIndex += 1;
00189 mA = mArray->at(mCurrentIndex + 0);
00190 mB = mArray->at(mCurrentIndex + 1);
00191 mC = mArray->at(mCurrentIndex + 2);
00192 }
00193 else
00194 {
00195 mA = mArray->at(mCurrentIndex + 0);
00196 mB = mArray->at(mCurrentIndex + 1);
00197 mC = mArray->at(mCurrentIndex + 2);
00198 }
00199 break;
00200
00201 case PT_QUAD_STRIP:
00202 case PT_TRIANGLE_STRIP:
00203 mCurrentIndex += 1;
00204 if ( mCurrentIndex + 2 >= mEnd )
00205 mCurrentIndex = mEnd;
00206 else
00207 if ( isPrimRestart(mCurrentIndex + 2) )
00208 {
00209 mCurrentIndex += 3;
00210 mEven = true;
00211 mA = mArray->at(mCurrentIndex + 0);
00212 mB = mArray->at(mCurrentIndex + 1);
00213 mC = mArray->at(mCurrentIndex + 2);
00214 }
00215 else
00216 {
00217 mEven = !mEven;
00218 if (mEven)
00219 {
00220 mA = mArray->at(mCurrentIndex + 0);
00221 mB = mArray->at(mCurrentIndex + 1);
00222 mC = mArray->at(mCurrentIndex + 2);
00223 }
00224 else
00225 {
00226 mA = mArray->at(mCurrentIndex + 0);
00227 mB = mArray->at(mCurrentIndex + 2);
00228 mC = mArray->at(mCurrentIndex + 1);
00229 }
00230 }
00231 break;
00232
00233 case PT_TRIANGLE_FAN:
00234 case PT_POLYGON:
00235 mCurrentIndex += 1;
00236 if ( mCurrentIndex + 1 >= mEnd )
00237 {
00238 mCurrentIndex = mEnd;
00239 }
00240 else
00241 if ( isPrimRestart(mCurrentIndex + 1) )
00242 {
00243 mIndex0 = mCurrentIndex + 2;
00244 mCurrentIndex = mIndex0 + 1;
00245 mA = mArray->at(mIndex0);
00246 mB = mArray->at(mCurrentIndex + 0);
00247 mC = mArray->at(mCurrentIndex + 1);
00248 }
00249 else
00250 {
00251 mA = mArray->at(mIndex0);
00252 mB = mArray->at(mCurrentIndex + 0);
00253 mC = mArray->at(mCurrentIndex + 1);
00254 }
00255 break;
00256
00257 case PT_QUADS:
00258 mCurrentIndex += 2;
00259 if ( mCurrentIndex >= mEnd )
00260 {
00261 mCurrentIndex = mEnd;
00262 }
00263 else
00264 if ( isPrimRestart(mCurrentIndex) )
00265 {
00266 mCurrentIndex += 1;
00267 mEven = true;
00268 mA = mArray->at(mCurrentIndex+0);
00269 mB = mArray->at(mCurrentIndex+1);
00270 mC = mArray->at(mCurrentIndex+2);
00271 }
00272 else
00273 {
00274 mEven = !mEven;
00275 if ( mEven )
00276 {
00277 mA = mArray->at(mCurrentIndex+0);
00278 mB = mArray->at(mCurrentIndex+1);
00279 mC = mArray->at(mCurrentIndex+2);
00280 }
00281 else
00282 {
00283 mA = mArray->at(mCurrentIndex+0);
00284 mB = mArray->at(mCurrentIndex+1);
00285 mC = mArray->at(mCurrentIndex-2);
00286 }
00287 }
00288 break;
00289
00290 default:
00291 VL_TRAP();
00292 break;
00293 }
00294
00295
00296 if (mCurrentIndex != mEnd)
00297 {
00298 mA += mBaseVertex;
00299 mB += mBaseVertex;
00300 mC += mBaseVertex;
00301 return true;
00302 }
00303 else
00304 {
00305 mA = mB = mC = -1;
00306 return false;
00307 }
00308 }
00309
00310 void setBaseVertex(int base_vert) { mBaseVertex = base_vert; }
00311 int baseVertex() const { return mBaseVertex; }
00312
00313 private:
00314 bool isPrimRestart(int i) const { return mPrimRestartOn && mArray->at(i) == mPrimRestartIndex; }
00315
00316 private:
00317 const TArray* mArray;
00318 EPrimitiveType mPrimType;
00319 int mA, mB, mC;
00320 int mCurrentIndex;
00321 int mIndex0;
00322 int mEnd;
00323 int mBaseVertex;
00324 unsigned int mPrimRestartIndex;
00325 bool mPrimRestartOn;
00326 bool mEven;
00327 };
00328
00329
00330
00332 class TriangleIteratorDirect: public TriangleIteratorAbstract
00333 {
00334 VL_INSTRUMENT_CLASS(vl::TriangleIteratorDirect, TriangleIteratorAbstract)
00335
00336 public:
00337 TriangleIteratorDirect(EPrimitiveType prim_type=PT_UNKNOWN)
00338 {
00339 VL_DEBUG_SET_OBJECT_NAME()
00340 mCurrentIndex = mStart = mEnd = 0;
00341 mA = mB = mC = -1;
00342 mPrimType = prim_type;
00343 mEven = true;
00344 }
00345
00346 bool hasNext() const { return mCurrentIndex != mEnd; }
00347
00348 virtual int a() const { return mA; }
00349 virtual int b() const { return mB; }
00350 virtual int c() const { return mC; }
00351
00352 void initialize(int start, int end)
00353 {
00354 VL_CHECK(end >= start)
00355 mStart = start;
00356 mCurrentIndex = mEnd = end;
00357 mA = mB = mC = -1;
00358 mEven = true;
00359 switch(mPrimType)
00360 {
00361 case PT_TRIANGLES:
00362
00363 mCurrentIndex = start;
00364 mA = start + 0;
00365 mB = start + 1;
00366 mC = start + 2;
00367 break;
00368 case PT_TRIANGLE_STRIP:
00369 mCurrentIndex = start;
00370 mA = start + 0;
00371 mB = start + 1;
00372 mC = start + 2;
00373 break;
00374 case PT_TRIANGLE_FAN:
00375 case PT_POLYGON:
00376 mCurrentIndex = start + 1;
00377 mA = start + 0;
00378 mB = start + 1;
00379 mC = start + 2;
00380 break;
00381 case PT_QUADS:
00382
00383 mCurrentIndex = start;
00384 mA = start + 0;
00385 mB = start + 1;
00386 mC = start + 2;
00387 break;
00388 case PT_QUAD_STRIP:
00389
00390 mCurrentIndex = start;
00391 mA = start + 0;
00392 mB = start + 1;
00393 mC = start + 2;
00394 break;
00395 default:
00396 break;
00397 }
00398 }
00399
00400 bool next()
00401 {
00402
00403 if ( mCurrentIndex == mEnd )
00404 return false;
00405
00406 switch(mPrimType)
00407 {
00408
00409 case PT_TRIANGLES:
00410 mCurrentIndex += 3;
00411
00412 if ( mCurrentIndex >= mEnd )
00413 mCurrentIndex = mEnd;
00414 else
00415 {
00416 mA = mCurrentIndex + 0;
00417 mB = mCurrentIndex + 1;
00418 mC = mCurrentIndex + 2;
00419 }
00420 break;
00421
00422 case PT_QUAD_STRIP:
00423 case PT_TRIANGLE_STRIP:
00424 mCurrentIndex += 1;
00425 if ( mCurrentIndex + 2 >= mEnd )
00426 mCurrentIndex = mEnd;
00427 else
00428 {
00429 mEven = !mEven;
00430 if (mEven)
00431 {
00432 mA = mCurrentIndex + 0;
00433 mB = mCurrentIndex + 1;
00434 mC = mCurrentIndex + 2;
00435 }
00436 else
00437 {
00438 mA = mCurrentIndex + 0;
00439 mB = mCurrentIndex + 2;
00440 mC = mCurrentIndex + 1;
00441 }
00442 }
00443 break;
00444
00445 case PT_TRIANGLE_FAN:
00446 case PT_POLYGON:
00447 mCurrentIndex += 1;
00448 if ( mCurrentIndex + 1 >= mEnd )
00449 {
00450 mCurrentIndex = mEnd;
00451 }
00452 else
00453 {
00454 mA = mStart;
00455 mB = mCurrentIndex+0;
00456 mC = mCurrentIndex+1;
00457 }
00458 break;
00459
00460 case PT_QUADS:
00461 mCurrentIndex += 2;
00462 if ( mCurrentIndex >= mEnd )
00463 {
00464 mCurrentIndex = mEnd;
00465 }
00466 else
00467 {
00468 mEven = !mEven;
00469 if ( mEven )
00470 {
00471 mA = mCurrentIndex+0;
00472 mB = mCurrentIndex+1;
00473 mC = mCurrentIndex+2;
00474 }
00475 else
00476 {
00477 mA = mCurrentIndex+0;
00478 mB = mCurrentIndex+1;
00479 mC = mCurrentIndex-2;
00480 }
00481 }
00482 break;
00483
00484 default:
00485 VL_TRAP();
00486 break;
00487 }
00488
00489
00490 if (mCurrentIndex == mEnd)
00491 {
00492 mA = mB = mC = -1;
00493 return false;
00494 }
00495 else
00496 return true;
00497 }
00498
00499 private:
00500 EPrimitiveType mPrimType;
00501 int mA, mB, mC;
00502 int mCurrentIndex;
00503 int mStart;
00504 int mEnd;
00505 bool mEven;
00506 };
00507
00508
00509
00511 template<class TArray>
00512 class TriangleIteratorMulti: public TriangleIteratorIndexed<TArray>
00513 {
00514 VL_INSTRUMENT_CLASS(vl::TriangleIteratorMulti<class TArray>, TriangleIteratorIndexed<TArray>)
00515
00516 public:
00517 TriangleIteratorMulti( const std::vector<GLint>* p_base_vertices, const std::vector<GLsizei>* p_count_vector, const TArray* idx_array, EPrimitiveType prim_type, bool prim_restart_on, int prim_restart_idx)
00518 :TriangleIteratorIndexed<TArray>( idx_array, prim_type, 0, prim_restart_on, prim_restart_idx)
00519 {
00520 VL_DEBUG_SET_OBJECT_NAME()
00521 mpBaseVertices = p_base_vertices;
00522 mpCountVector = p_count_vector;
00523 mStart = 0;
00524 mCurPrim = 0;
00525 }
00526
00527 void initialize()
00528 {
00529 VL_CHECK( mpBaseVertices->size() == mpCountVector->size() )
00530 if ( (*mpBaseVertices).size() )
00531 TriangleIteratorIndexed<TArray>::setBaseVertex( (*mpBaseVertices)[mCurPrim] );
00532 int end = mStart + (*mpCountVector)[mCurPrim];
00533 TriangleIteratorIndexed<TArray>::initialize( mStart, end );
00534
00535 if ( !TriangleIteratorIndexed<TArray>::hasNext() )
00536 mCurPrim = (int)(*mpCountVector).size()-1;
00537 }
00538
00539 bool next()
00540 {
00541 if ( TriangleIteratorIndexed<TArray>::next() )
00542 return true;
00543 else
00544 if ( mCurPrim < (int)(*mpCountVector).size()-1 )
00545 {
00546 mStart += (*mpCountVector)[mCurPrim];
00547 mCurPrim++;
00548 initialize();
00549 return true;
00550 }
00551 else
00552 return false;
00553 }
00554
00555 bool hasNext() const
00556 {
00557 if ( !TriangleIteratorIndexed<TArray>::hasNext() && mCurPrim == (int)(*mpCountVector).size()-1 )
00558 return false;
00559 else
00560 return true;
00561 }
00562
00563 protected:
00564 const std::vector<GLint>* mpBaseVertices;
00565 const std::vector<GLsizei>* mpCountVector;
00566 int mCurPrim;
00567 int mStart;
00568 };
00569
00570
00571
00575 class TriangleIterator
00576 {
00577 public:
00578 TriangleIterator(TriangleIteratorAbstract* it): mIterator(it) { }
00579
00581 bool next() { return mIterator->next(); }
00582
00583 bool operator++() { return next(); }
00584
00586 bool hasNext() { return mIterator->hasNext(); }
00587
00589 int a() const { return mIterator->a(); }
00590
00592 int b() const { return mIterator->b(); }
00593
00595 int c() const { return mIterator->c(); }
00596
00597 protected:
00598 ref<TriangleIteratorAbstract> mIterator;
00599 };
00600
00601 }
00602
00603 #endif