OpenMesh
OpenMesh/Tools/Kernel_OSG/bindT.hh
Go to the documentation of this file.
00001 /*===========================================================================*\
00002  *                                                                           *
00003  *                               OpenMesh                                    *
00004  *      Copyright (C) 2001-2011 by Computer Graphics Group, RWTH Aachen      *
00005  *                           www.openmesh.org                                *
00006  *                                                                           *
00007  *---------------------------------------------------------------------------* 
00008  *  This file is part of OpenMesh.                                           *
00009  *                                                                           *
00010  *  OpenMesh is free software: you can redistribute it and/or modify         * 
00011  *  it under the terms of the GNU Lesser General Public License as           *
00012  *  published by the Free Software Foundation, either version 3 of           *
00013  *  the License, or (at your option) any later version with the              *
00014  *  following exceptions:                                                    *
00015  *                                                                           *
00016  *  If other files instantiate templates or use macros                       *
00017  *  or inline functions from this file, or you compile this file and         *
00018  *  link it with other files to produce an executable, this file does        *
00019  *  not by itself cause the resulting executable to be covered by the        *
00020  *  GNU Lesser General Public License. This exception does not however       *
00021  *  invalidate any other reasons why the executable file might be            *
00022  *  covered by the GNU Lesser General Public License.                        *
00023  *                                                                           *
00024  *  OpenMesh is distributed in the hope that it will be useful,              *
00025  *  but WITHOUT ANY WARRANTY; without even the implied warranty of           *
00026  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            *
00027  *  GNU Lesser General Public License for more details.                      *
00028  *                                                                           *
00029  *  You should have received a copy of the GNU LesserGeneral Public          *
00030  *  License along with OpenMesh.  If not,                                    *
00031  *  see <http://www.gnu.org/licenses/>.                                      *
00032  *                                                                           *
00033 \*===========================================================================*/ 
00034 
00035 /*===========================================================================*\
00036  *                                                                           *             
00037  *   $Revision: 362 $                                                         *
00038  *   $Date: 2011-01-26 10:21:12 +0100 (Mi, 26 Jan 2011) $                   *
00039  *                                                                           *
00040 \*===========================================================================*/
00041 
00042 
00051 //=============================================================================
00052 //
00053 //  CLASS Traits
00054 //
00055 //=============================================================================
00056 
00057 #ifndef OPENMESH_KERNEL_OSG_BINDT_HH
00058 #define OPENMESH_KERNEL_OSG_BINDT_HH
00059 
00060 
00061 //== INCLUDES =================================================================
00062 
00063 
00064 #include <functional>
00065 #include <algorithm>
00066 //
00067 #include <OpenMesh/Core/Mesh/TriMeshT.hh>
00068 #include <OpenMesh/Core/Utils/color_cast.hh>
00069 #include <OpenMesh/Tools/Utils/GLConstAsString.hh>
00070 #include <OpenSG/OSGGeometry.h>
00071 //
00072 #include "color_cast.hh"
00073 
00074 //== NAMESPACES ===============================================================
00075 
00076 namespace OpenMesh  {
00077 namespace Kernel_OSG {
00078 
00079 
00080 //== CLASS DEFINITION =========================================================
00081 
00082 inline
00083 bool type_is_valid( unsigned char _t )
00084 {
00085   return _t == GL_TRIANGLES
00086     ||   _t == GL_TRIANGLE_STRIP
00087     ||   _t == GL_QUADS
00088     ||   _t == GL_POLYGON;
00089 }
00090 
00091 
00098 template < typename Mesh > inline
00099 bool bind( osg::GeometryPtr& _geo, Mesh& _mesh )
00100 {
00101   _geo = _mesh.createGeometryPtr();
00102 }
00103 
00112 template < typename Mesh > inline
00113 bool bind( Mesh& _mesh, osg::GeometryPtr& _geo )
00114 {
00115   using namespace OpenMesh;
00116   using namespace osg;
00117   using namespace std;
00118 
00119   bool ok = true;
00120 
00121   // pre-check if types are supported
00122 
00123   GeoPTypesPtr types = _geo->getTypes();
00124 
00125   if ( (size_t)count_if( types->getData(), types->getData()+types->size(),
00126                          ptr_fun(type_is_valid) ) != (size_t)types->size() )
00127     return false;
00128 
00129   // pre-check if it is a multi-indexed geometry, which is not supported!
00130 
00131   if ( _geo->getIndexMapping().getSize() > 1 )
00132   {
00133     omerr << "OpenMesh::Kernel_OSG::bind(): Multi-indexed geometry is not supported!\n";
00134     return false;
00135   }
00136 
00137 
00138   // create shortcuts
00139 
00140   GeoPLengthsPtr  lengths = _geo->getLengths();
00141   GeoIndicesPtr   indices = _geo->getIndices();
00142   GeoPositionsPtr pos     = _geo->getPositions();
00143   GeoNormalsPtr   normals = _geo->getNormals();
00144   GeoColorsPtr    colors  = _geo->getColors();
00145  
00146   
00147   // -------------------- now convert everything to polygon/triangles
00148 
00149   size_t tidx, bidx; // types; base index into indices
00150   vector< VertexHandle > vhandles;
00151 
00152   // ---------- initialize geometry
00153 
00154   {
00155     VertexHandle vh;
00156     typedef typename Mesh::Color color_t;
00157 
00158     bool bind_normal = (normals!=NullFC) && _mesh.has_vertex_normals();
00159     bool bind_color  = (colors !=NullFC) && _mesh.has_vertex_colors();
00160 
00161     for (bidx=0; bidx < pos->size(); ++bidx)
00162     {
00163       vh = _mesh.add_vertex( pos->getValue(bidx) );
00164       if ( bind_normal )
00165         _mesh.set_normal(vh, normals->getValue(bidx));
00166       if ( bind_color )
00167         _mesh.set_color(vh, color_cast<color_t>(colors->getValue(bidx)));
00168     }
00169   }
00170 
00171   // ---------- create topology
00172 
00173   FaceHandle   fh;
00174 
00175   size_t max_bidx = indices != NullFC ? indices->size() : pos->size();
00176 
00177   for (bidx=tidx=0; ok && tidx<types->size() && bidx < max_bidx; ++tidx)
00178   {
00179     switch( types->getValue(tidx) )
00180     {
00181       case GL_TRIANGLES:
00182         vhandles.resize(3);
00183         for(size_t lidx=0; lidx < lengths->getValue(tidx)-2; lidx+=3)
00184         {
00185           if (indices == NullFC ) {
00186             vhandles[0] = VertexHandle(bidx+lidx);
00187             vhandles[1] = VertexHandle(bidx+lidx+1);
00188             vhandles[2] = VertexHandle(bidx+lidx+2);
00189           }
00190           else {
00191             vhandles[0] = VertexHandle(indices->getValue(bidx+lidx  ) );
00192             vhandles[1] = VertexHandle(indices->getValue(bidx+lidx+1) );
00193             vhandles[2] = VertexHandle(indices->getValue(bidx+lidx+2) );
00194           }
00195 
00196           if ( !(fh = _mesh.add_face( vhandles )).is_valid() )
00197           {
00198             // if fh is complex try swapped order
00199             swap(vhandles[2], vhandles[1]);
00200             fh = _mesh.add_face( vhandles );
00201           }
00202           ok = fh.is_valid();
00203         }
00204         break;
00205 
00206       case GL_TRIANGLE_STRIP:
00207         vhandles.resize(3);
00208         for (size_t lidx=0; lidx < lengths->getValue(tidx)-2; ++lidx)
00209         {
00210           if (indices == NullFC ) {
00211             vhandles[0] = VertexHandle(bidx+lidx);
00212             vhandles[1] = VertexHandle(bidx+lidx+1);
00213             vhandles[2] = VertexHandle(bidx+lidx+2);
00214           }
00215           else {
00216             vhandles[0] = VertexHandle(indices->getValue(bidx+lidx  ) );
00217             vhandles[1] = VertexHandle(indices->getValue(bidx+lidx+1) );
00218             vhandles[2] = VertexHandle(indices->getValue(bidx+lidx+2) );
00219           }
00220 
00221           if (vhandles[0]!=vhandles[2] &&
00222               vhandles[0]!=vhandles[1] &&
00223               vhandles[1]!=vhandles[2])
00224           {
00225             // if fh is complex try swapped order
00226             bool swapped(false);
00227 
00228             if (lidx % 2) // odd numbered triplet must be reordered
00229               swap(vhandles[2], vhandles[1]);
00230               
00231             if ( !(fh = _mesh.add_face( vhandles )).is_valid() )
00232             {
00233               omlog << "OpenMesh::Kernel_OSG::bind(): complex entity!\n";
00234 
00235               swap(vhandles[2], vhandles[1]);
00236               fh = _mesh.add_face( vhandles );
00237               swapped = true;
00238             }
00239             ok = fh.is_valid();
00240           }
00241         }
00242         break;
00243 
00244       case GL_QUADS:
00245         vhandles.resize(4);
00246         for(size_t nf=_mesh.n_faces(), lidx=0; 
00247             lidx < lengths->getValue(tidx)-3; lidx+=4)
00248         {
00249           if (indices == NullFC ) {
00250             vhandles[0] = VertexHandle(bidx+lidx);
00251             vhandles[1] = VertexHandle(bidx+lidx+1);
00252             vhandles[2] = VertexHandle(bidx+lidx+2);
00253             vhandles[3] = VertexHandle(bidx+lidx+3);
00254           }
00255           else {
00256             vhandles[0] = VertexHandle(indices->getValue(bidx+lidx  ) );
00257             vhandles[1] = VertexHandle(indices->getValue(bidx+lidx+1) );
00258             vhandles[2] = VertexHandle(indices->getValue(bidx+lidx+2) );
00259             vhandles[3] = VertexHandle(indices->getValue(bidx+lidx+3) );
00260           }
00261 
00262           fh = _mesh.add_face( vhandles );
00263           ok = ( Mesh::Face::is_triangle() && (_mesh.n_faces()==(nf+2)))
00264             || fh.is_valid();
00265           nf = _mesh.n_faces();
00266         }
00267         break;
00268 
00269       case GL_POLYGON:
00270       {
00271         size_t ne = lengths->getValue(tidx);
00272         size_t nf = _mesh.n_faces();
00273 
00274         vhandles.resize(ne);
00275 
00276         for(size_t lidx=0; lidx < ne; ++lidx)
00277           vhandles[lidx] = (indices == NullFC)
00278             ? VertexHandle(bidx+lidx)
00279             : VertexHandle(indices->getValue(bidx+lidx) );
00280 
00281         fh = _mesh.add_face( vhandles );
00282         ok = ( Mesh::Face::is_triangle() && (_mesh.n_faces()==nf+ne-2) )
00283           || fh.is_valid();
00284         
00285         break;
00286       }
00287       default:
00288         cerr << "Warning! Skipping unsupported type " 
00289              << types->getValue(tidx) << " '"
00290              << Utils::GLenum_as_string( types->getValue(tidx) ) << "'\n";
00291     }
00292 
00293     // update base index into indices for next face type
00294     bidx += lengths->getValue(tidx);
00295   }
00296 
00297   if (ok)
00298     ok=_mesh.bind(_geo);
00299   else
00300     _mesh.clear();
00301 
00302   return ok;
00303 }
00304 
00305 
00306 //=============================================================================
00307 } // namespace Kernel_OSG
00308 } // namespace OpenMesh
00309 //=============================================================================
00310 #endif // OPENMESH_KERNEL_OSG_BINDT_HH defined
00311 //=============================================================================
00312