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 LineIterator_INCLUDE_ONCE
00033 #define LineIterator_INCLUDE_ONCE
00034
00035 #include <vlGraphics/Array.hpp>
00036 #include <vlCore/vlnamespace.hpp>
00037
00038 namespace vl
00039 {
00040
00041
00042
00044 class LineIteratorAbstract: public Object
00045 {
00046 VL_INSTRUMENT_ABSTRACT_CLASS(vl::LineIteratorAbstract, 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 };
00054
00055
00056
00058 template<class TArray>
00059 class LineIteratorIndexed: public LineIteratorAbstract
00060 {
00061 VL_INSTRUMENT_CLASS(vl::LineIteratorIndexed<TArray>, LineIteratorAbstract)
00062
00063 public:
00064
00065 LineIteratorIndexed()
00066 {
00067 VL_DEBUG_SET_OBJECT_NAME()
00068 mCurrentIndex = 0;
00069 mEnd = 0;
00070 mA = mB = -1;
00071 mEven = true;
00072 mIndex0 = 0;
00073 mArray = NULL;
00074 mPrimRestartIndex = (unsigned int)-1;
00075 mPrimRestartOn = false;
00076 mBaseVertex = 0;
00077 mPrimType = PT_UNKNOWN;
00078 }
00079
00080 LineIteratorIndexed(const TArray* idx_array, EPrimitiveType prim_type, int base_vert, bool prim_restart_on, unsigned int prim_restart_idx)
00081 {
00082 VL_DEBUG_SET_OBJECT_NAME()
00083 mCurrentIndex = 0;
00084 mEnd = 0;
00085 mA = mB = -1;
00086 mEven = true;
00087 mIndex0 = 0;
00088 mArray = idx_array;
00089 mPrimRestartIndex = prim_restart_idx;
00090 mPrimRestartOn = prim_restart_on;
00091 mBaseVertex = base_vert;
00092 mPrimType = prim_type;
00093 }
00094
00095 bool hasNext() const { return mCurrentIndex != mEnd; }
00096
00097 virtual int a() const { return mA; }
00098 virtual int b() const { return mB; }
00099
00100 void initialize(int start=0, int end=-1)
00101 {
00102 VL_CHECK( start >= 0 )
00103 VL_CHECK( end <= (int)mArray->size() )
00104
00105 if (end == -1)
00106 end = (int)mArray->size();
00107
00108 mCurrentIndex = end;
00109 mA = mB = -1;
00110 mEven = true;
00111 mIndex0 = start;
00112 mEnd = end;
00113 if (mArray->size())
00114 {
00115 switch(mPrimType)
00116 {
00117 case PT_LINES:
00118 case PT_LINE_STRIP:
00119 mCurrentIndex = start;
00120 mA = mArray->at(start+0);
00121 mB = mArray->at(start+1);
00122 break;
00123 default:
00124 break;
00125 }
00126 }
00127
00128
00129 if ( mCurrentIndex != mEnd )
00130 {
00131 mA += mBaseVertex;
00132 mB += mBaseVertex;
00133 }
00134 else
00135 {
00136 mA = mB = -1;
00137 }
00138 }
00139
00140 bool next()
00141 {
00142
00143 if ( mCurrentIndex == mEnd )
00144 return false;
00145
00146 switch(mPrimType)
00147 {
00148
00149 case PT_LINES:
00150 mCurrentIndex += 2;
00151
00152 if ( mCurrentIndex >= mEnd )
00153 mCurrentIndex = mEnd;
00154 else
00155 if ( isPrimRestart(mCurrentIndex) )
00156 {
00157 mCurrentIndex += 1;
00158 mA = mArray->at(mCurrentIndex + 0);
00159 mB = mArray->at(mCurrentIndex + 1);
00160 }
00161 else
00162 {
00163 mA = mArray->at(mCurrentIndex + 0);
00164 mB = mArray->at(mCurrentIndex + 1);
00165 }
00166 break;
00167
00168 case PT_LINE_STRIP:
00169 mCurrentIndex += 1;
00170 if ( mCurrentIndex + 1 >= mEnd )
00171 mCurrentIndex = mEnd;
00172 else
00173 if ( isPrimRestart(mCurrentIndex + 1) )
00174 {
00175 mCurrentIndex += 2;
00176 mEven = true;
00177 mA = mArray->at(mCurrentIndex + 0);
00178 mB = mArray->at(mCurrentIndex + 1);
00179 }
00180 else
00181 {
00182 mEven = !mEven;
00185 mA = mArray->at(mCurrentIndex + 0);
00186 mB = mArray->at(mCurrentIndex + 1);
00193 }
00194 break;
00195
00196 case PT_LINE_LOOP:
00197 break;
00198
00199 default:
00200 VL_TRAP();
00201 break;
00202 }
00203
00204
00205 if (mCurrentIndex != mEnd)
00206 {
00207 mA += mBaseVertex;
00208 mB += mBaseVertex;
00209 return true;
00210 }
00211 else
00212 {
00213 mA = mB = -1;
00214 return false;
00215 }
00216 }
00217
00218 void setBaseVertex(int base_vert) { mBaseVertex = base_vert; }
00219 int baseVertex() const { return mBaseVertex; }
00220
00221 private:
00222 bool isPrimRestart(int i) const { return mPrimRestartOn && mArray->at(i) == mPrimRestartIndex; }
00223
00224 private:
00225 const TArray* mArray;
00226 EPrimitiveType mPrimType;
00227 int mA, mB;
00228 int mCurrentIndex;
00229 int mIndex0;
00230 int mEnd;
00231 int mBaseVertex;
00232 unsigned int mPrimRestartIndex;
00233 bool mPrimRestartOn;
00234 bool mEven;
00235 };
00236
00237
00238
00240 class LineIteratorDirect: public LineIteratorAbstract
00241 {
00242 VL_INSTRUMENT_CLASS(vl::LineIteratorDirect, LineIteratorAbstract)
00243
00244 public:
00245 LineIteratorDirect(EPrimitiveType prim_type=PT_UNKNOWN)
00246 {
00247 VL_DEBUG_SET_OBJECT_NAME()
00248 mCurrentIndex = mStart = mEnd = 0;
00249 mA = mB = -1;
00250 mPrimType = prim_type;
00251 mEven = true;
00252 }
00253
00254 bool hasNext() const { return mCurrentIndex != mEnd; }
00255
00256 virtual int a() const { return mA; }
00257 virtual int b() const { return mB; }
00258
00259 void initialize(int start, int end)
00260 {
00261 VL_CHECK(end >= start)
00262 mStart = start;
00263 mCurrentIndex = mEnd = end;
00264 mA = mB = -1;
00265 mEven = true;
00266 switch(mPrimType)
00267 {
00268 case PT_LINES:
00269 case PT_LINE_STRIP:
00270 case PT_LINE_LOOP:
00271
00272 mCurrentIndex = start;
00273 mA = start + 0;
00274 mB = start + 1;
00275 break;
00276 default:
00277 break;
00278 }
00279 }
00280
00281 bool next()
00282 {
00283
00284 if ( mCurrentIndex == mEnd )
00285 return false;
00286
00287 switch(mPrimType)
00288 {
00289
00290 case PT_LINES:
00291 mCurrentIndex += 2;
00292
00293 if ( mCurrentIndex >= mEnd )
00294 mCurrentIndex = mEnd;
00295 else
00296 {
00297 mA = mCurrentIndex + 0;
00298 mB = mCurrentIndex + 1;
00299 }
00300 break;
00301
00302 case PT_LINE_STRIP:
00303 mCurrentIndex += 1;
00304 if ( mCurrentIndex + 1 > mEnd )
00305 mCurrentIndex = mEnd;
00306 else
00307 {
00308 mEven = !mEven;
00311 mA = mCurrentIndex + 0;
00312 mB = mCurrentIndex + 1;
00319 }
00320 break;
00321
00322 case PT_LINE_LOOP:
00323 ++mCurrentIndex;
00324 mEven = !mEven;
00325 mA = mCurrentIndex + 0;
00326 mB = mCurrentIndex + 1;
00327 if(mB == mEnd)
00328 mB = mStart;
00329 break;
00330
00331 default:
00332 VL_TRAP();
00333 break;
00334 }
00335
00336
00337 if (mCurrentIndex == mEnd)
00338 {
00339 mA = mB = -1;
00340 return false;
00341 }
00342 else
00343 return true;
00344 }
00345
00346 private:
00347 EPrimitiveType mPrimType;
00348 int mA, mB;
00349 int mCurrentIndex;
00350 int mStart;
00351 int mEnd;
00352 bool mEven;
00353 };
00354
00355
00356
00358 template<class TArray>
00359 class LineIteratorMulti: public LineIteratorIndexed<TArray>
00360 {
00361 VL_INSTRUMENT_CLASS(vl::LineIteratorMulti<class TArray>, LineIteratorIndexed<TArray>)
00362
00363 public:
00364 LineIteratorMulti( 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)
00365 :LineIteratorIndexed<TArray>( idx_array, prim_type, 0, prim_restart_on, prim_restart_idx)
00366 {
00367 VL_DEBUG_SET_OBJECT_NAME()
00368 mpBaseVertices = p_base_vertices;
00369 mpCountVector = p_count_vector;
00370 mStart = 0;
00371 mCurPrim = 0;
00372 }
00373
00374 void initialize()
00375 {
00376 VL_CHECK( mpBaseVertices->size() == mpCountVector->size() )
00377 if ( (*mpBaseVertices).size() )
00378 LineIteratorIndexed<TArray>::setBaseVertex( (*mpBaseVertices)[mCurPrim] );
00379 int end = mStart + (*mpCountVector)[mCurPrim];
00380 LineIteratorIndexed<TArray>::initialize( mStart, end );
00381
00382 if ( !LineIteratorIndexed<TArray>::hasNext() )
00383 mCurPrim = (int)(*mpCountVector).size()-1;
00384 }
00385
00386 bool next()
00387 {
00388 if ( LineIteratorIndexed<TArray>::next() )
00389 return true;
00390 else
00391 if ( mCurPrim < (int)(*mpCountVector).size()-1 )
00392 {
00393 mStart += (*mpCountVector)[mCurPrim];
00394 mCurPrim++;
00395 initialize();
00396 return true;
00397 }
00398 else
00399 return false;
00400 }
00401
00402 bool hasNext() const
00403 {
00404 if ( !LineIteratorIndexed<TArray>::hasNext() && mCurPrim == (int)(*mpCountVector).size()-1 )
00405 return false;
00406 else
00407 return true;
00408 }
00409
00410 protected:
00411 const std::vector<GLint>* mpBaseVertices;
00412 const std::vector<GLsizei>* mpCountVector;
00413 int mCurPrim;
00414 int mStart;
00415 };
00416
00417
00418
00422 class LineIterator
00423 {
00424 public:
00425 LineIterator(LineIteratorAbstract* it): mIterator(it) { }
00426
00428 bool next() { return mIterator->next(); }
00429
00430 bool operator++() { return next(); }
00431
00433 bool hasNext() { return mIterator->hasNext(); }
00434
00436 int a() const { return mIterator->a(); }
00437
00439 int b() const { return mIterator->b(); }
00440
00441 protected:
00442 ref<LineIteratorAbstract> mIterator;
00443 };
00444
00445 }
00446
00447 #endif