Main Page   Modules   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

bindT.hh

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

acg pic Project OpenMesh, ©  Computer Graphics Group, RWTH Aachen. Documentation generated using doxygen .