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

bindT.hh

Go to the documentation of this file.
00001 //=============================================================================
00002 //                                                                            
00003 //                               OpenMesh                                     
00004 //      Copyright (C) 2001-2005 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.2 $
00027 //   $Date: 2004/10/14 12:44: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   return true;
00092 }
00093 
00102 template < typename Mesh > inline
00103 bool bind( Mesh& _mesh, osg::GeometryPtr& _geo )
00104 {
00105   using namespace OpenMesh;
00106   using namespace osg;
00107   using namespace std;
00108 
00109   bool ok = true;
00110 
00111   // pre-check if types are supported
00112 
00113   GeoPTypesPtr types = _geo->getTypes();
00114 
00115   if ( (size_t)count_if( types->getData(), types->getData()+types->size(),
00116                          ptr_fun(type_is_valid) ) != (size_t)types->size() )
00117     return false;
00118 
00119   // pre-check if it is a multi-indexed geometry, which is not supported!
00120 
00121   if ( _geo->getIndexMapping().getSize() > 1 )
00122   {
00123     omerr() << "OpenMesh::Kernel_OSG::bind(): Multi-indexed geometry is not supported!\n";
00124     return false;
00125   }
00126 
00127 
00128   // create shortcuts
00129 
00130   GeoPLengthsPtr  lengths = _geo->getLengths();
00131   GeoIndicesPtr   indices = _geo->getIndices();
00132   GeoPositionsPtr pos     = _geo->getPositions();
00133   GeoNormalsPtr   normals = _geo->getNormals();
00134   GeoColorsPtr    colors  = _geo->getColors();
00135  
00136   
00137   // -------------------- now convert everything to polygon/triangles
00138 
00139   size_t tidx, bidx; // types; base index into indices
00140   vector< VertexHandle > vhandles;
00141 
00142   // ---------- initialize geometry
00143 
00144   {
00145     VertexHandle vh;
00146     typedef typename Mesh::Color color_t;
00147 
00148     bool bind_normal = (normals!=NullFC) && _mesh.has_vertex_normals();
00149     bool bind_color  = (colors !=NullFC) && _mesh.has_vertex_colors();
00150 
00151     for (bidx=0; bidx < pos->size(); ++bidx)
00152     {
00153       vh = _mesh.add_vertex( pos->getValue(bidx) );
00154       if ( bind_normal )
00155         _mesh.set_normal(vh, normals->getValue(bidx));
00156       if ( bind_color )
00157         _mesh.set_color(vh, color_cast<color_t>(colors->getValue(bidx)));
00158     }
00159   }
00160 
00161   // ---------- create topology
00162 
00163   FaceHandle   fh;
00164 
00165   size_t max_bidx = indices != NullFC ? indices->size() : pos->size();
00166 
00167   for (bidx=tidx=0; ok && tidx<types->size() && bidx < max_bidx; ++tidx)
00168   {
00169     switch( types->getValue(tidx) )
00170     {
00171       case GL_TRIANGLES:
00172         vhandles.resize(3);
00173         for(size_t lidx=0; lidx < lengths->getValue(tidx)-2; lidx+=3)
00174         {
00175           if (indices == NullFC ) {
00176             vhandles[0] = VertexHandle(bidx+lidx);
00177             vhandles[1] = VertexHandle(bidx+lidx+1);
00178             vhandles[2] = VertexHandle(bidx+lidx+2);
00179           }
00180           else {
00181             vhandles[0] = VertexHandle(indices->getValue(bidx+lidx  ) );
00182             vhandles[1] = VertexHandle(indices->getValue(bidx+lidx+1) );
00183             vhandles[2] = VertexHandle(indices->getValue(bidx+lidx+2) );
00184           }
00185 
00186           if ( !(fh = _mesh.add_face( vhandles )).is_valid() )
00187           {
00188             // if fh is complex try swapped order
00189             swap(vhandles[2], vhandles[1]);
00190             fh = _mesh.add_face( vhandles );
00191           }
00192           ok = fh.is_valid();
00193         }
00194         break;
00195 
00196       case GL_TRIANGLE_STRIP:
00197         vhandles.resize(3);
00198         for (size_t lidx=0; lidx < lengths->getValue(tidx)-2; ++lidx)
00199         {
00200           if (indices == NullFC ) {
00201             vhandles[0] = VertexHandle(bidx+lidx);
00202             vhandles[1] = VertexHandle(bidx+lidx+1);
00203             vhandles[2] = VertexHandle(bidx+lidx+2);
00204           }
00205           else {
00206             vhandles[0] = VertexHandle(indices->getValue(bidx+lidx  ) );
00207             vhandles[1] = VertexHandle(indices->getValue(bidx+lidx+1) );
00208             vhandles[2] = VertexHandle(indices->getValue(bidx+lidx+2) );
00209           }
00210 
00211           if (vhandles[0]!=vhandles[2] &&
00212               vhandles[0]!=vhandles[1] &&
00213               vhandles[1]!=vhandles[2])
00214           {
00215             // if fh is complex try swapped order
00216             bool swapped(false);
00217 
00218             if (lidx % 2) // odd numbered triplet must be reordered
00219               swap(vhandles[2], vhandles[1]);
00220               
00221             if ( !(fh = _mesh.add_face( vhandles )).is_valid() )
00222             {
00223               omlog() << "OpenMesh::Kernel_OSG::bind(): complex entity!\n";
00224 
00225               swap(vhandles[2], vhandles[1]);
00226               fh = _mesh.add_face( vhandles );
00227               swapped = true;
00228             }
00229             ok = fh.is_valid();
00230           }
00231         }
00232         break;
00233 
00234       case GL_QUADS:
00235         vhandles.resize(4);
00236         for(size_t nf=_mesh.n_faces(), lidx=0; 
00237             lidx < lengths->getValue(tidx)-3; lidx+=4)
00238         {
00239           if (indices == NullFC ) {
00240             vhandles[0] = VertexHandle(bidx+lidx);
00241             vhandles[1] = VertexHandle(bidx+lidx+1);
00242             vhandles[2] = VertexHandle(bidx+lidx+2);
00243             vhandles[3] = VertexHandle(bidx+lidx+3);
00244           }
00245           else {
00246             vhandles[0] = VertexHandle(indices->getValue(bidx+lidx  ) );
00247             vhandles[1] = VertexHandle(indices->getValue(bidx+lidx+1) );
00248             vhandles[2] = VertexHandle(indices->getValue(bidx+lidx+2) );
00249             vhandles[3] = VertexHandle(indices->getValue(bidx+lidx+3) );
00250           }
00251 
00252           fh = _mesh.add_face( vhandles );
00253           ok = ( Mesh::Face::is_triangle() && (_mesh.n_faces()==(nf+2)))
00254             || fh.is_valid();
00255           nf = _mesh.n_faces();
00256         }
00257         break;
00258 
00259       case GL_POLYGON:
00260       {
00261         size_t ne = lengths->getValue(tidx);
00262         size_t nf = _mesh.n_faces();
00263 
00264         vhandles.resize(ne);
00265 
00266         for(size_t lidx=0; lidx < ne; ++lidx)
00267           vhandles[lidx] = (indices == NullFC)
00268             ? VertexHandle(bidx+lidx)
00269             : VertexHandle(indices->getValue(bidx+lidx) );
00270 
00271         fh = _mesh.add_face( vhandles );
00272         ok = ( Mesh::Face::is_triangle() && (_mesh.n_faces()==nf+ne-2) )
00273           || fh.is_valid();
00274         
00275         break;
00276       }
00277       default:
00278         cerr << "Warning! Skipping unsupported type " 
00279              << types->getValue(tidx) << " '"
00280              << Utils::GLenum_as_string( types->getValue(tidx) ) << "'\n";
00281     }
00282 
00283     // update base index into indices for next face type
00284     bidx += lengths->getValue(tidx);
00285   }
00286 
00287   if (ok)
00288     ok=_mesh.bind(_geo);
00289   else
00290     _mesh.clear();
00291 
00292   return ok;
00293 }
00294 
00295 
00296 //=============================================================================
00297 } // namespace Kernel_OSG
00298 } // namespace OpenMesh
00299 //=============================================================================
00300 #endif // OPENMESH_KERNEL_OSG_BINDT_HH defined
00301 //=============================================================================
00302 

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