# Visualization Library

A lightweight C++ OpenGL middleware for 2D/3D graphics

[Home] [Tutorials] [All Classes] [Grouped Classes]

- Main Page
- Related Pages
- Namespaces
- Classes
- Files

- File List
- File Members

# D:/VL/BuildSystem/VL_DISTRO/Visualization_Library_SDK/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 v2011.09.1162 Reference Documentation
Copyright 2005-2011 Michele Bosi. All rights reserved.
Updated on Thu Jan 26 2012 00:43:44.
Permission is granted to use this page to write and publish articles regarding Visualization Library.