OpenMesh
|
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