Visualization Library

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

X:/dropbox/visualizationlibrary/src/vlGraphics/Tessellator.cpp

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 #include <vlGraphics/Tessellator.hpp>
00033 
00034 using namespace vl;
00035 
00036 //-----------------------------------------------------------------------------
00037 Tessellator::Tessellator()
00038 {
00039   VL_DEBUG_SET_OBJECT_NAME()
00040   mTessNormal = fvec3(0,0,0);
00041   mBoundaryOnly = false;
00042   mTolerance = 0.0;
00043   mWindingRule = TW_TESS_WINDING_ODD;
00044   mTessellateIntoSinglePolygon = true;
00045 }
00046 //-----------------------------------------------------------------------------
00047 Tessellator::~Tessellator()
00048 {
00049   freeCombinedVertices();
00050 }
00051 //-----------------------------------------------------------------------------
00052 bool Tessellator::tessellate(bool append_tessellated_tris)
00053 {
00054   if (!append_tessellated_tris)
00055     mTessellatedTris.clear();
00056   mFans.clear();
00057   mTriStrips.clear();
00058   mLineLoops.clear();
00059   mPrimitiveType = 0;
00060   freeCombinedVertices();
00061   if (mContours.empty() || mContourVerts.empty())
00062   {
00063     vl::Log::error("Tessellator::tessellate(): no contours specified.\n");
00064     return false;
00065   }
00066 
00067   GLUtesselator* tobj = gluNewTess();
00068   // callbacks
00069   gluTessCallback(tobj, GLU_TESS_BEGIN_DATA,   (callback_type)tessBeginData);
00070   gluTessCallback(tobj, GLU_TESS_VERTEX_DATA,  (callback_type)tessVertexData);
00071   gluTessCallback(tobj, GLU_TESS_COMBINE_DATA, (callback_type)tessCombineData);
00072   gluTessCallback(tobj, GLU_TESS_END,     (callback_type)tessEnd);
00073   gluTessCallback(tobj, GLU_TESS_ERROR,        (callback_type)tessError);
00074   // normal
00075    gluTessNormal( tobj, tessNormal().x(), tessNormal().y(), tessNormal().z() );
00076   // properties
00077    gluTessProperty(tobj, GLU_TESS_BOUNDARY_ONLY, boundaryOnly() ? GL_TRUE : GL_FALSE);
00078    gluTessProperty(tobj, GLU_TESS_TOLERANCE, tolerance());
00079    gluTessProperty(tobj, GLU_TESS_WINDING_RULE, windingRule());
00080   // tessellation
00081   if (tessellateIntoSinglePolygon())
00082   {
00083     gluTessBeginPolygon(tobj, this);
00084     for(unsigned cont=0, idx=0; cont<mContours.size(); ++cont)
00085     {
00086       gluTessBeginContour(tobj);
00087       for(int i=0; i<mContours[cont]; ++i, ++idx)
00088         gluTessVertex(tobj, mContourVerts[idx].ptr(), mContourVerts[idx].ptr());
00089       gluTessEndContour(tobj);
00090     }
00091     gluTessEndPolygon(tobj);
00092   }
00093   else
00094   {
00095     for(unsigned cont=0, idx=0; cont<mContours.size(); ++cont)
00096     {
00097       gluTessBeginPolygon(tobj, this);
00098       gluTessBeginContour(tobj);
00099       for(int i=0; i<mContours[cont]; ++i, ++idx)
00100         gluTessVertex(tobj, mContourVerts[idx].ptr(), mContourVerts[idx].ptr());
00101       gluTessEndContour(tobj);
00102       gluTessEndPolygon(tobj);
00103     }
00104   }
00105   gluDeleteTess(tobj);
00106 
00107   // triangulate fans
00108   for(unsigned fan=0; fan<mFans.size();    ++fan)
00109   for(unsigned iv =1; iv<mFans[fan].size()-1; ++iv)
00110   {
00111     mTessellatedTris.push_back(mFans[fan][0]);
00112     mTessellatedTris.push_back(mFans[fan][iv]);
00113     mTessellatedTris.push_back(mFans[fan][iv+1]);
00114   }
00115 
00116   // triangulate strips
00117   for(unsigned strip=0; strip<mTriStrips.size(); ++strip)
00118   for(unsigned iv=0; iv<mTriStrips[strip].size()-2; ++iv)
00119   {
00120     if (iv % 2)
00121     {
00122       mTessellatedTris.push_back(mTriStrips[strip][iv+0]);
00123       mTessellatedTris.push_back(mTriStrips[strip][iv+2]);
00124       mTessellatedTris.push_back(mTriStrips[strip][iv+1]);
00125     }
00126     else
00127     {
00128       mTessellatedTris.push_back(mTriStrips[strip][iv+0]);
00129       mTessellatedTris.push_back(mTriStrips[strip][iv+1]);
00130       mTessellatedTris.push_back(mTriStrips[strip][iv+2]);
00131     }
00132   }
00133 
00134   mContours.clear();
00135   mContourVerts.clear();
00136 
00137   #if 0
00138     if (tessellatedTris().empty())
00139     {
00140       vl::Log::warning("Tessellator::tessellate(): no triangles generated.\n");
00141       return false;
00142     }
00143   #endif
00144 
00145   return true;
00146 }
00147 //-----------------------------------------------------------------------------
00148 void Tessellator::freeCombinedVertices()
00149 {
00150   for(unsigned i=0; i<mCombinedVertices.size(); ++i)
00151     delete mCombinedVertices[i];
00152   mCombinedVertices.clear();
00153 }
00154 //-----------------------------------------------------------------------------
00155 ref<Geometry> Tessellator::tessellateGeometry(bool append_tessellated_tris)
00156 {
00157   tessellate(append_tessellated_tris);
00158 
00159   if (mTessellatedTris.empty())
00160     return NULL;
00161 
00162   ref<Geometry> geom = new Geometry;
00163   ref<ArrayFloat3> vert_array = new ArrayFloat3;
00164   
00165   vert_array->initFrom(mTessellatedTris);
00166 
00167   geom->setVertexArray(vert_array.get());
00168   geom->drawCalls()->push_back( new vl::DrawArrays(PT_TRIANGLES, 0, vert_array->size()) );
00169   geom->computeNormals();
00170   return geom;
00171 }
00172 //-----------------------------------------------------------------------------
00173 // Tessellation callbacks
00174 //-----------------------------------------------------------------------------
00175 void CALLBACK Tessellator::tessBeginData( GLenum type, Tessellator* tessellator )
00176 {
00177   tessellator->mPrimitiveType = type;
00178   if(type == GL_TRIANGLES)
00179   {
00180     // do nothing
00181   }
00182   else
00183   if(type == GL_TRIANGLE_FAN)
00184     tessellator->mFans.resize( tessellator->mFans.size() + 1 );
00185   else
00186   if(type == GL_TRIANGLE_STRIP)
00187     tessellator->mTriStrips.resize( tessellator->mTriStrips.size() + 1 );
00188   else
00189   if(type == GL_LINE_LOOP)
00190     tessellator->mLineLoops.resize( tessellator->mLineLoops.size() + 1 );
00191   else
00192   {
00193     Log::error("Tessellator::beginData() unknown primitive.\n");
00194   }
00195 }
00196 //-----------------------------------------------------------------------------
00197 void CALLBACK Tessellator::tessVertexData( dvec3* vec, Tessellator* tessellator )
00198 {
00199   if(tessellator->mPrimitiveType == GL_TRIANGLES)
00200     tessellator->mTessellatedTris.push_back( (fvec3)(*vec) );
00201   else
00202   if(tessellator->mPrimitiveType == GL_TRIANGLE_FAN)
00203     tessellator->mFans.back().push_back( (fvec3)(*vec) );
00204   else
00205   if(tessellator->mPrimitiveType == GL_TRIANGLE_STRIP)
00206     tessellator->mTriStrips.back().push_back( (fvec3)(*vec) );
00207   else
00208   if(tessellator->mPrimitiveType == GL_LINE_LOOP)
00209     tessellator->mLineLoops.back().push_back( (fvec3)(*vec) );
00210   else
00211   {
00212     Log::error("Tessellator::vertexData() unknown primitive.\n");
00213   }
00214 }
00215 //-----------------------------------------------------------------------------
00216 void CALLBACK Tessellator::tessCombineData( GLdouble coords[3], dvec3*[4], GLfloat[4], dvec3 **dataOut, Tessellator* tessellator )
00217 {
00218   dvec3 *vec = new dvec3;
00219   vec->x() = coords[0];
00220   vec->y() = coords[1];
00221   vec->z() = coords[2];
00222   *dataOut = vec;
00223   tessellator->mCombinedVertices.push_back( vec );
00224 }
00225 //-----------------------------------------------------------------------------
00226 void CALLBACK Tessellator::tessEnd(void)
00227 {
00228 }
00229 //-----------------------------------------------------------------------------
00230 void CALLBACK Tessellator::tessError( GLenum errno )
00231 {
00232   const GLubyte* estring = gluErrorString(errno);
00233   Log::error( Say("Tessellator error: %s.\n") << estring );
00234 }
00235 //-----------------------------------------------------------------------------

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