- Main Page
- Modules
- Namespaces
- Classes
- Files
- Related Pages

- File List
- File Members

# Tools/Kernel_OSG/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.3 $
    00027 //   $Date: 2005-12-21 13:58:47 $
    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