glu_tesselator.h
Go to the documentation of this file.
00001 /****************************************************************************
00002 * VCGLib                                                            o o     *
00003 * Visual and Computer Graphics Library                            o     o   *
00004 *                                                                _   O  _   *
00005 * Copyright(C) 2004                                                \/)\/    *
00006 * Visual Computing Lab                                            /\/|      *
00007 * ISTI - Italian National Research Council                           |      *
00008 *                                                                    \      *
00009 * All rights reserved.                                                      *
00010 *                                                                           *
00011 * This program is free software; you can redistribute it and/or modify      *
00012 * it under the terms of the GNU General Public License as published by      *
00013 * the Free Software Foundation; either version 2 of the License, or         *
00014 * (at your option) any later version.                                       *
00015 *                                                                           *
00016 * This program is distributed in the hope that it will be useful,           *
00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of            *
00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             *
00019 * GNU General Public License (http://www.gnu.org/licenses/gpl.txt)          *
00020 * for more details.                                                         *
00021 *                                                                           *
00022 ****************************************************************************/
00023 #ifndef __VCGLIB_GLU_TESSELATOR_H
00024 #define __VCGLIB_GLU_TESSELATOR_H
00025 #include <vcg/space/point2.h>
00026 #include <vector>
00027 
00028 #ifndef GL_VERSION_1_1
00029 #error "Please include OpenGL before including this file"
00030 #endif
00031 
00032 
00033 // The inclusion of glu should be always safe (if someone has already included gl stuff).
00034 #ifndef GLU_VERSIONS
00035 #ifdef __APPLE__
00036 #include <OpenGL/glu.h>
00037 #else
00038 #ifdef _WIN32
00039   #include <windows.h>
00040 #endif
00041 #include <GL/glu.h>
00042 #endif
00043 #endif
00044 
00045 #ifndef CALLBACK
00046 #ifdef _WIN32
00047 #define CALLBACK __stdcall
00048 #else
00049 #define CALLBACK
00050 #endif
00051 #endif
00052 
00053 namespace vcg
00054 {
00055 
00056 class glu_tesselator
00057 {
00058     public:
00059 
00060         typedef glu_tesselator this_type;
00061 
00062         /*
00063             Works with Point2 and Point3;
00064 
00065             sample usage:
00066 
00067             // tesselation input: each outline represents a polygon contour
00068             std::vector< std::vector<point_type> > outlines = ...;
00069 
00070             // tesselation output (triangles indices)
00071             std::vector<int> indices;
00072 
00073             // compute triangles indices
00074             glu_tesselator::tesselate(outlines, indices);
00075 
00076             // unroll input contours points
00077             std::vector<point_type> points;
00078 
00079             for (size_t i=0; i<outlines.size(); ++i)
00080             {
00081                 for (size_t j=0; j<outlines[i].size(); ++j)
00082                 {
00083                     points.push_back(outlines[i][j]);
00084                 }
00085             }
00086             // or simply call glu_tesselator::unroll(outlines, points);
00087 
00088             // create triangles
00089             for (size_t i=0; i<indices.size(); i+=3)
00090             {
00091                 create_triangle(
00092                     points[ indices[i+0] ],
00093                     points[ indices[i+1] ],
00094                     points[ indices[i+2] ]);
00095             }
00096         */
00097 
00098         template <class point_type>
00099         static inline void unroll(const std::vector< std::vector<point_type> > & outlines, std::vector<point_type> & points)
00100         {
00101             for (size_t i=0; i<outlines.size(); ++i)
00102             {
00103                 for (size_t j=0; j<outlines[i].size(); ++j)
00104                 {
00105                     points.push_back(outlines[i][j]);
00106                 }
00107             }
00108         }
00109 
00110         template <class point_type>
00111         static inline void tesselate(const std::vector< std::vector<point_type> > & outlines, std::vector<int> & indices)
00112         {
00113             tess_prim_data_vec t_data;
00114 
00115             this_type::do_tesselation(outlines, t_data);
00116 
00117             //int k = 0;
00118             for (size_t i=0; i<t_data.size(); ++i)
00119             {
00120                 const size_t st = t_data[i].indices.size();
00121                 if (st < 3) continue;
00122 
00123                 switch (t_data[i].type)
00124                 {
00125                     case GL_TRIANGLES:
00126                         for (size_t j=0; j<st; ++j)
00127                         {
00128                             indices.push_back(t_data[i].indices[j]);
00129                         }
00130                         break;
00131 
00132                     case GL_TRIANGLE_STRIP:
00133                         {
00134                         int i0 = t_data[i].indices[0];
00135                         int i1 = t_data[i].indices[1];
00136 
00137                         bool ccw = true;
00138 
00139                         for (size_t j=2; j<st; ++j)
00140                         {
00141                             const int i2 = t_data[i].indices[j];
00142 
00143                             indices.push_back(i0);
00144                             indices.push_back(i1);
00145                             indices.push_back(i2);
00146 
00147                             if (ccw) i0 = i2;
00148                             else     i1 = i2;
00149 
00150                             ccw = !ccw;
00151                         }                                                                                                                                       }
00152                         break;
00153 
00154                     case GL_TRIANGLE_FAN:
00155                         {
00156                         const int first = t_data[i].indices[0];
00157                         int prev = t_data[i].indices[1];
00158 
00159                         for (size_t j=2; j<st; ++j)
00160                         {
00161                             const int curr = t_data[i].indices[j];
00162 
00163                             indices.push_back(first);
00164                             indices.push_back(prev);
00165                             indices.push_back(curr);
00166 
00167                             prev = curr;
00168                         }
00169                         }
00170                         break;
00171 
00172                     default:
00173                         break;
00174                 }
00175             }
00176         }
00177 
00178     protected:
00179 
00180         class tess_prim_data
00181         {
00182             public:
00183 
00184                 typedef tess_prim_data this_type;
00185 
00186                 GLenum type;
00187                 std::vector<int> indices;
00188 
00189                 tess_prim_data(void) { }
00190                 tess_prim_data(GLenum t) : type(t) { }
00191         };
00192 
00193         typedef std::vector<tess_prim_data> tess_prim_data_vec;
00194 
00195         static void CALLBACK begin_cb(GLenum type, void * polygon_data)
00196         {
00197             tess_prim_data_vec * t_data = (tess_prim_data_vec *)polygon_data;
00198             t_data->push_back(tess_prim_data(type));
00199         }
00200 
00201         static void CALLBACK end_cb(void * polygon_data)
00202         {
00203             (void)polygon_data;
00204         }
00205 
00206         static void CALLBACK vertex_cb(void * vertex_data, void * polygon_data)
00207         {
00208             tess_prim_data_vec * t_data = (tess_prim_data_vec *)polygon_data;
00209             t_data->back().indices.push_back((int)((size_t)vertex_data));
00210         }
00211 
00212         template <class point_type>
00213         static void do_tesselation(const std::vector< std::vector<point_type> > & outlines, tess_prim_data_vec & t_data)
00214         {
00215             GLUtesselator * tess = gluNewTess();
00216 //#ifdef __APPLE__
00217 //                      gluTessCallback(tess, GLU_TESS_BEGIN_DATA,  (GLvoid (CALLBACK *)(...))(this_type::begin_cb));
00218 //                      gluTessCallback(tess, GLU_TESS_END_DATA,    (GLvoid (CALLBACK *)(...))(this_type::end_cb));
00219 //                      gluTessCallback(tess, GLU_TESS_VERTEX_DATA, (GLvoid (CALLBACK *)(...))(this_type::vertex_cb));
00220 //#else
00221             gluTessCallback(tess, GLU_TESS_BEGIN_DATA,  (GLvoid (CALLBACK *)())(this_type::begin_cb));
00222             gluTessCallback(tess, GLU_TESS_END_DATA,    (GLvoid (CALLBACK *)())(this_type::end_cb));
00223             gluTessCallback(tess, GLU_TESS_VERTEX_DATA, (GLvoid (CALLBACK *)())(this_type::vertex_cb));
00224 //#endif
00225             void * polygon_data = (void *)(&t_data);
00226 
00227             GLdouble vertex[3];
00228 
00229             size_t k = 0;
00230             gluTessBeginPolygon(tess, polygon_data);
00231             for (size_t i=0; i<outlines.size(); ++i)
00232             {
00233                 gluTessBeginContour(tess);
00234                 for (size_t j=0; j<outlines[i].size(); ++j)
00235                 {
00236                     this_type::get_position(outlines[i][j], vertex);
00237                     gluTessVertex(tess, vertex, (void *)k);
00238                     ++k;
00239                 }
00240                 gluTessEndContour(tess);
00241             }
00242             gluTessEndPolygon(tess);
00243 
00244             gluDeleteTess(tess);
00245         }
00246 
00247         template <class scalar_type>
00248         static inline void get_position(const vcg::Point2<scalar_type> & p, GLdouble * d)
00249         {
00250             d[0] = (GLdouble)(p[0]);
00251             d[1] = (GLdouble)(p[1]);
00252             d[2] = (GLdouble)(0);
00253         }
00254 
00255         template <class scalar_type>
00256         static inline void get_position(const vcg::Point3<scalar_type> & p, GLdouble * d)
00257         {
00258             d[0] = (GLdouble)(p[0]);
00259             d[1] = (GLdouble)(p[1]);
00260             d[2] = (GLdouble)(p[2]);
00261         }
00262 };
00263 
00264 } // end namespace vcg
00265 
00266 #endif // __VCGLIB_GLU_TESSELATOR_H


shape_reconstruction
Author(s): Roberto Martín-Martín
autogenerated on Sat Jun 8 2019 18:31:27