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 }
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
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
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
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
00137
00138 size_t tidx, bidx;
00139 vector< VertexHandle > vhandles;
00140
00141
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
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
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
00215 bool swapped(false);
00216
00217 if (lidx % 2)
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
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 }
00297 }
00298
00299 #endif // OPENMESH_KERNEL_OSG_BINDT_HH defined
00300
00301