# Visualization Library

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

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

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

Visualization Library v2011.05.1142 Reference Documentation
Copyright 2005-2011 Michele Bosi. All rights reserved.
Updated on Thu May 26 2011 22:51:25.
Permission is granted to use this page to write and publish articles regarding Visualization Library.