00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00040
00041
00042
00043
00044
00045
00046 #ifndef OPENMESH_KERNEL_OSG_BINDT_HH
00047 #define OPENMESH_KERNEL_OSG_BINDT_HH
00048
00049
00050
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
00064
00065 namespace OpenMesh {
00066 namespace Kernel_OSG {
00067
00068
00069
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
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
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
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
00138
00139 size_t tidx, bidx;
00140 vector< VertexHandle > vhandles;
00141
00142
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
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
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
00216 bool swapped(false);
00217
00218 if (lidx % 2)
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
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 }
00298 }
00299
00300 #endif // OPENMESH_KERNEL_OSG_BINDT_HH defined
00301
00302