Visualization Library

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

X:/dropbox/visualizationlibrary/src/vlGraphics/LineIterator.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 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 // TriangleIteratorAbstract
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 // LineIteratorIndexed
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; // 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       // if we are not at the end then add base vertices
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       // reached the end
00143       if ( mCurrentIndex == mEnd )
00144         return false;
00145 
00146       switch(mPrimType)
00147       {
00148 
00149       case PT_LINES:
00150         mCurrentIndex += 2;
00151         // check for the end
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       // if we are not at the end then add base vertices
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 // TriangleIteratorDirect
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         // VL_CHECK( (end - start) % 3 == 0 ) /* primitive restart might screw up this */
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       // reached the end
00284       if ( mCurrentIndex == mEnd )
00285         return false;
00286 
00287       switch(mPrimType)
00288       {
00289 
00290       case PT_LINES:
00291         mCurrentIndex += 2;
00292         // check for the end
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;        // Back to the begining
00329         break;
00330         
00331       default:
00332         VL_TRAP();
00333         break;
00334       }
00335 
00336       // if we are not at the end then add base vertices
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 // TriangleIteratorMulti
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       // abort if could not initialize (primitive not supported)
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 // TriangleIterator
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

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