OpenMesh
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
bindT.hh
Go to the documentation of this file.
1 /*===========================================================================*\
2  * *
3  * OpenMesh *
4  * Copyright (C) 2001-2015 by Computer Graphics Group, RWTH Aachen *
5  * www.openmesh.org *
6  * *
7  *---------------------------------------------------------------------------*
8  * This file is part of OpenMesh. *
9  * *
10  * OpenMesh is free software: you can redistribute it and/or modify *
11  * it under the terms of the GNU Lesser General Public License as *
12  * published by the Free Software Foundation, either version 3 of *
13  * the License, or (at your option) any later version with the *
14  * following exceptions: *
15  * *
16  * If other files instantiate templates or use macros *
17  * or inline functions from this file, or you compile this file and *
18  * link it with other files to produce an executable, this file does *
19  * not by itself cause the resulting executable to be covered by the *
20  * GNU Lesser General Public License. This exception does not however *
21  * invalidate any other reasons why the executable file might be *
22  * covered by the GNU Lesser General Public License. *
23  * *
24  * OpenMesh is distributed in the hope that it will be useful, *
25  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
26  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
27  * GNU Lesser General Public License for more details. *
28  * *
29  * You should have received a copy of the GNU LesserGeneral Public *
30  * License along with OpenMesh. If not, *
31  * see <http://www.gnu.org/licenses/>. *
32  * *
33 \*===========================================================================*/
34 
35 /*===========================================================================*\
36  * *
37  * $Revision: 1188 $ *
38  * $Date: 2015-01-05 16:34:10 +0100 (Mo, 05 Jan 2015) $ *
39  * *
40 \*===========================================================================*/
41 
42 
51 //=============================================================================
52 //
53 // CLASS Traits
54 //
55 //=============================================================================
56 
57 #ifndef OPENMESH_KERNEL_OSG_BINDT_HH
58 #define OPENMESH_KERNEL_OSG_BINDT_HH
59 
60 
61 //== INCLUDES =================================================================
62 
63 
64 #include <functional>
65 #include <algorithm>
66 //
67 #include <OpenMesh/Core/Mesh/TriMeshT.hh>
68 #include <OpenMesh/Core/Utils/color_cast.hh>
69 #include <OpenMesh/Tools/Utils/GLConstAsString.hh>
70 #include <OpenSG/OSGGeometry.h>
71 //
72 #include "color_cast.hh"
73 
74 //== NAMESPACES ===============================================================
75 
76 namespace OpenMesh {
77 namespace Kernel_OSG {
78 
79 
80 //== CLASS DEFINITION =========================================================
81 
82 inline
83 bool type_is_valid( unsigned char _t )
84 {
85  return _t == GL_TRIANGLES
86  || _t == GL_TRIANGLE_STRIP
87  || _t == GL_QUADS
88  || _t == GL_POLYGON;
89 }
90 
91 
98 template < typename Mesh > inline
99 bool bind( osg::GeometryPtr& _geo, Mesh& _mesh )
100 {
101  _geo = _mesh.createGeometryPtr();
102 }
103 
112 template < typename Mesh > inline
113 bool bind( Mesh& _mesh, osg::GeometryPtr& _geo )
114 {
115  using namespace OpenMesh;
116  using namespace osg;
117  using namespace std;
118 
119  bool ok = true;
120 
121  // pre-check if types are supported
122 
123  GeoPTypesPtr types = _geo->getTypes();
124 
125  if ( (size_t)count_if( types->getData(), types->getData()+types->size(),
126  ptr_fun(type_is_valid) ) != (size_t)types->size() )
127  return false;
128 
129  // pre-check if it is a multi-indexed geometry, which is not supported!
130 
131  if ( _geo->getIndexMapping().getSize() > 1 )
132  {
133  omerr << "OpenMesh::Kernel_OSG::bind(): Multi-indexed geometry is not supported!\n";
134  return false;
135  }
136 
137 
138  // create shortcuts
139 
140  GeoPLengthsPtr lengths = _geo->getLengths();
141  GeoIndicesPtr indices = _geo->getIndices();
142  GeoPositionsPtr pos = _geo->getPositions();
143  GeoNormalsPtr normals = _geo->getNormals();
144  GeoColorsPtr colors = _geo->getColors();
145 
146 
147  // -------------------- now convert everything to polygon/triangles
148 
149  size_t tidx, bidx; // types; base index into indices
150  vector< VertexHandle > vhandles;
151 
152  // ---------- initialize geometry
153 
154  {
155  VertexHandle vh;
156  typedef typename Mesh::Color color_t;
157 
158  bool bind_normal = (normals!=NullFC) && _mesh.has_vertex_normals();
159  bool bind_color = (colors !=NullFC) && _mesh.has_vertex_colors();
160 
161  for (bidx=0; bidx < pos->size(); ++bidx)
162  {
163  vh = _mesh.add_vertex( pos->getValue(bidx) );
164  if ( bind_normal )
165  _mesh.set_normal(vh, normals->getValue(bidx));
166  if ( bind_color )
167  _mesh.set_color(vh, color_cast<color_t>(colors->getValue(bidx)));
168  }
169  }
170 
171  // ---------- create topology
172 
173  FaceHandle fh;
174 
175  size_t max_bidx = indices != NullFC ? indices->size() : pos->size();
176 
177  for (bidx=tidx=0; ok && tidx<types->size() && bidx < max_bidx; ++tidx)
178  {
179  switch( types->getValue(tidx) )
180  {
181  case GL_TRIANGLES:
182  vhandles.resize(3);
183  for(size_t lidx=0; lidx < lengths->getValue(tidx)-2; lidx+=3)
184  {
185  if (indices == NullFC ) {
186  vhandles[0] = VertexHandle(bidx+lidx);
187  vhandles[1] = VertexHandle(bidx+lidx+1);
188  vhandles[2] = VertexHandle(bidx+lidx+2);
189  }
190  else {
191  vhandles[0] = VertexHandle(indices->getValue(bidx+lidx ) );
192  vhandles[1] = VertexHandle(indices->getValue(bidx+lidx+1) );
193  vhandles[2] = VertexHandle(indices->getValue(bidx+lidx+2) );
194  }
195 
196  if ( !(fh = _mesh.add_face( vhandles )).is_valid() )
197  {
198  // if fh is complex try swapped order
199  swap(vhandles[2], vhandles[1]);
200  fh = _mesh.add_face( vhandles );
201  }
202  ok = fh.is_valid();
203  }
204  break;
205 
206  case GL_TRIANGLE_STRIP:
207  vhandles.resize(3);
208  for (size_t lidx=0; lidx < lengths->getValue(tidx)-2; ++lidx)
209  {
210  if (indices == NullFC ) {
211  vhandles[0] = VertexHandle(bidx+lidx);
212  vhandles[1] = VertexHandle(bidx+lidx+1);
213  vhandles[2] = VertexHandle(bidx+lidx+2);
214  }
215  else {
216  vhandles[0] = VertexHandle(indices->getValue(bidx+lidx ) );
217  vhandles[1] = VertexHandle(indices->getValue(bidx+lidx+1) );
218  vhandles[2] = VertexHandle(indices->getValue(bidx+lidx+2) );
219  }
220 
221  if (vhandles[0]!=vhandles[2] &&
222  vhandles[0]!=vhandles[1] &&
223  vhandles[1]!=vhandles[2])
224  {
225  // if fh is complex try swapped order
226  bool swapped(false);
227 
228  if (lidx % 2) // odd numbered triplet must be reordered
229  swap(vhandles[2], vhandles[1]);
230 
231  if ( !(fh = _mesh.add_face( vhandles )).is_valid() )
232  {
233  omlog << "OpenMesh::Kernel_OSG::bind(): complex entity!\n";
234 
235  swap(vhandles[2], vhandles[1]);
236  fh = _mesh.add_face( vhandles );
237  swapped = true;
238  }
239  ok = fh.is_valid();
240  }
241  }
242  break;
243 
244  case GL_QUADS:
245  vhandles.resize(4);
246  for(size_t nf=_mesh.n_faces(), lidx=0;
247  lidx < lengths->getValue(tidx)-3; lidx+=4)
248  {
249  if (indices == NullFC ) {
250  vhandles[0] = VertexHandle(bidx+lidx);
251  vhandles[1] = VertexHandle(bidx+lidx+1);
252  vhandles[2] = VertexHandle(bidx+lidx+2);
253  vhandles[3] = VertexHandle(bidx+lidx+3);
254  }
255  else {
256  vhandles[0] = VertexHandle(indices->getValue(bidx+lidx ) );
257  vhandles[1] = VertexHandle(indices->getValue(bidx+lidx+1) );
258  vhandles[2] = VertexHandle(indices->getValue(bidx+lidx+2) );
259  vhandles[3] = VertexHandle(indices->getValue(bidx+lidx+3) );
260  }
261 
262  fh = _mesh.add_face( vhandles );
263  ok = ( Mesh::Face::is_triangle() && (_mesh.n_faces()==(nf+2)))
264  || fh.is_valid();
265  nf = _mesh.n_faces();
266  }
267  break;
268 
269  case GL_POLYGON:
270  {
271  size_t ne = lengths->getValue(tidx);
272  size_t nf = _mesh.n_faces();
273 
274  vhandles.resize(ne);
275 
276  for(size_t lidx=0; lidx < ne; ++lidx)
277  vhandles[lidx] = (indices == NullFC)
278  ? VertexHandle(bidx+lidx)
279  : VertexHandle(indices->getValue(bidx+lidx) );
280 
281  fh = _mesh.add_face( vhandles );
282  ok = ( Mesh::Face::is_triangle() && (_mesh.n_faces()==nf+ne-2) )
283  || fh.is_valid();
284 
285  break;
286  }
287  default:
288  cerr << "Warning! Skipping unsupported type "
289  << types->getValue(tidx) << " '"
290  << Utils::GLenum_as_string( types->getValue(tidx) ) << "'\n";
291  }
292 
293  // update base index into indices for next face type
294  bidx += lengths->getValue(tidx);
295  }
296 
297  if (ok)
298  ok=_mesh.bind(_geo);
299  else
300  _mesh.clear();
301 
302  return ok;
303 }
304 
305 
306 //=============================================================================
307 } // namespace Kernel_OSG
308 } // namespace OpenMesh
309 //=============================================================================
310 #endif // OPENMESH_KERNEL_OSG_BINDT_HH defined
311 //=============================================================================
312 
Handle for a vertex entity.
Definition: Handles.hh:114
Kernel::Color Color
Color type.
Definition: PolyMeshT.hh:112
STL namespace.
Handle for a face entity.
Definition: Handles.hh:135
Contains all the mesh ingredients like the polygonal mesh, the triangle mesh, different mesh kernels ...
Definition: MeshItems.hh:56
bool is_valid() const
The handle is valid iff the index is not equal to -1.
Definition: Handles.hh:70
bool bind(osg::GeometryPtr &_geo, Mesh &_mesh)
Bind a OpenSG geometry to a mesh.
Definition: bindT.hh:99

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