Visualization Library

A lightweight C++ OpenGL middleware for 2D/3D graphics
[Home] [Tutorials] [All Classes] [Grouped Classes]

X:/dropbox/visualizationlibrary/src/vlGraphics/TriangleIterator.hpp

Go to the documentation of this file.
00001 /**************************************************************************************/
00002 /*                                                                                    */
00003 /*  Visualization Library                                                             */
00004 /*  http://www.visualizationlibrary.org                                               */
00005 /*                                                                                    */
00006 /*  Copyright (c) 2005-2010, Michele Bosi                                             */
00007 /*  All rights reserved.                                                              */
00008 /*                                                                                    */
00009 /*  Redistribution and use in source and binary forms, with or without modification,  */
00010 /*  are permitted provided that the following conditions are met:                     */
00011 /*                                                                                    */
00012 /*  - Redistributions of source code must retain the above copyright notice, this     */
00013 /*  list of conditions and the following disclaimer.                                  */
00014 /*                                                                                    */
00015 /*  - Redistributions in binary form must reproduce the above copyright notice, this  */
00016 /*  list of conditions and the following disclaimer in the documentation and/or       */
00017 /*  other materials provided with the distribution.                                   */
00018 /*                                                                                    */
00019 /*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND   */
00020 /*  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED     */
00021 /*  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE            */
00022 /*  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR  */
00023 /*  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    */
00024 /*  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;      */
00025 /*  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON    */
00026 /*  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT           */
00027 /*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS     */
00028 /*  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                      */
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 // TriangleIteratorAbstract
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 // TriangleIteratorIndexed
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; // 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           // VL_CHECK( (end-start) % 3 == 0 ) /* primitive restart might screw up this */
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           // VL_CHECK( (end-start) % 4 == 0 ) /* primitive restart might screw up this */
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           // VL_CHECK( (end-start) % 2 == 0 ) /* primitive restart might screw up this */
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       // if we are not at the end then add base vertices
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       // reached the end
00174       if ( mCurrentIndex == mEnd )
00175         return false;
00176 
00177       switch(mPrimType)
00178       {
00179 
00180       case PT_TRIANGLES:
00181         mCurrentIndex += 3;
00182         // check for the end
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       // if we are not at the end then add base vertices
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 // TriangleIteratorDirect
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         // VL_CHECK( (end - start) % 3 == 0 ) /* primitive restart might screw up this */
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         // VL_CHECK( (end - start) % 4 == 0 ) /* primitive restart might screw up this */
00383         mCurrentIndex = start;
00384         mA = start + 0;
00385         mB = start + 1;
00386         mC = start + 2;
00387         break;
00388       case PT_QUAD_STRIP:
00389         // VL_CHECK( (end - start) % 2 == 0 ) /* primitive restart might screw up this */
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       // reached the end
00403       if ( mCurrentIndex == mEnd )
00404         return false;
00405 
00406       switch(mPrimType)
00407       {
00408 
00409       case PT_TRIANGLES:
00410         mCurrentIndex += 3;
00411         // check for the end
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       // if we are not at the end then add base vertices
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 // TriangleIteratorMulti
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       // abort if could not initialize (primitive not supported)
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 // TriangleIterator
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

Visualization Library 2011.09.1160 Reference Documentation
Copyright 2005-2011 Michele Bosi. All rights reserved.
Updated on Thu May 2 2013 13:40:42.
Permission is granted to use this page to write and publish articles regarding Visualization Library.