Developer Documentation
bindT.hh
Go to the documentation of this file.
1 /* ========================================================================= *
2  * *
3  * OpenMesh *
4  * Copyright (c) 2001-2015, RWTH-Aachen University *
5  * Department of Computer Graphics and Multimedia *
6  * All rights reserved. *
7  * www.openmesh.org *
8  * *
9  *---------------------------------------------------------------------------*
10  * This file is part of OpenMesh. *
11  *---------------------------------------------------------------------------*
12  * *
13  * Redistribution and use in source and binary forms, with or without *
14  * modification, are permitted provided that the following conditions *
15  * are met: *
16  * *
17  * 1. Redistributions of source code must retain the above copyright notice, *
18  * this list of conditions and the following disclaimer. *
19  * *
20  * 2. Redistributions in binary form must reproduce the above copyright *
21  * notice, this list of conditions and the following disclaimer in the *
22  * documentation and/or other materials provided with the distribution. *
23  * *
24  * 3. Neither the name of the copyright holder nor the names of its *
25  * contributors may be used to endorse or promote products derived from *
26  * this software without specific prior written permission. *
27  * *
28  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
29  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
30  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
31  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
32  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
33  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
34  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
35  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
36  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
37  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
38  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
39  * *
40  * ========================================================================= */
41 
42 
43 
44 
53 //=============================================================================
54 //
55 // CLASS Traits
56 //
57 //=============================================================================
58 
59 #ifndef OPENMESH_KERNEL_OSG_BINDT_HH
60 #define OPENMESH_KERNEL_OSG_BINDT_HH
61 
62 
63 //== INCLUDES =================================================================
64 
65 
66 #include <functional>
67 #include <algorithm>
68 //
69 #include <OpenMesh/Core/Mesh/TriMeshT.hh>
70 #include <OpenMesh/Core/Utils/color_cast.hh>
71 #include <OpenMesh/Tools/Utils/GLConstAsString.hh>
72 #include <OpenSG/OSGGeometry.h>
73 //
74 #include "color_cast.hh"
75 
76 //== NAMESPACES ===============================================================
77 
78 namespace OpenMesh {
79 namespace Kernel_OSG {
80 
81 
82 //== CLASS DEFINITION =========================================================
83 
84 inline
85 bool type_is_valid( unsigned char _t )
86 {
87  return _t == GL_TRIANGLES
88  || _t == GL_TRIANGLE_STRIP
89  || _t == GL_QUADS
90  || _t == GL_POLYGON;
91 }
92 
93 
100 template < typename Mesh > inline
101 bool bind( osg::GeometryPtr& _geo, Mesh& _mesh )
102 {
103  _geo = _mesh.createGeometryPtr();
104 }
105 
114 template < typename Mesh > inline
115 bool bind( Mesh& _mesh, osg::GeometryPtr& _geo )
116 {
117  using namespace OpenMesh;
118  using namespace osg;
119  using namespace std;
120 
121  bool ok = true;
122 
123  // pre-check if types are supported
124 
125  GeoPTypesPtr types = _geo->getTypes();
126 
127  if ( (size_t)count_if( types->getData(), types->getData()+types->size(),
128  ptr_fun(type_is_valid) ) != (size_t)types->size() )
129  return false;
130 
131  // pre-check if it is a multi-indexed geometry, which is not supported!
132 
133  if ( _geo->getIndexMapping().getSize() > 1 )
134  {
135  omerr << "OpenMesh::Kernel_OSG::bind(): Multi-indexed geometry is not supported!\n";
136  return false;
137  }
138 
139 
140  // create shortcuts
141 
142  GeoPLengthsPtr lengths = _geo->getLengths();
143  GeoIndicesPtr indices = _geo->getIndices();
144  GeoPositionsPtr pos = _geo->getPositions();
145  GeoNormalsPtr normals = _geo->getNormals();
146  GeoColorsPtr colors = _geo->getColors();
147 
148 
149  // -------------------- now convert everything to polygon/triangles
150 
151  size_t tidx, bidx; // types; base index into indices
152  vector< VertexHandle > vhandles;
153 
154  // ---------- initialize geometry
155 
156  {
157  VertexHandle vh;
158  typedef typename Mesh::Color color_t;
159 
160  bool bind_normal = (normals!=NullFC) && _mesh.has_vertex_normals();
161  bool bind_color = (colors !=NullFC) && _mesh.has_vertex_colors();
162 
163  for (bidx=0; bidx < pos->size(); ++bidx)
164  {
165  vh = _mesh.add_vertex( pos->getValue(bidx) );
166  if ( bind_normal )
167  _mesh.set_normal(vh, normals->getValue(bidx));
168  if ( bind_color )
169  _mesh.set_color(vh, color_cast<color_t>(colors->getValue(bidx)));
170  }
171  }
172 
173  // ---------- create topology
174 
175  FaceHandle fh;
176 
177  size_t max_bidx = indices != NullFC ? indices->size() : pos->size();
178 
179  for (bidx=tidx=0; ok && tidx<types->size() && bidx < max_bidx; ++tidx)
180  {
181  switch( types->getValue(tidx) )
182  {
183  case GL_TRIANGLES:
184  vhandles.resize(3);
185  for(size_t lidx=0; lidx < lengths->getValue(tidx)-2; lidx+=3)
186  {
187  if (indices == NullFC ) {
188  vhandles[0] = VertexHandle(bidx+lidx);
189  vhandles[1] = VertexHandle(bidx+lidx+1);
190  vhandles[2] = VertexHandle(bidx+lidx+2);
191  }
192  else {
193  vhandles[0] = VertexHandle(indices->getValue(bidx+lidx ) );
194  vhandles[1] = VertexHandle(indices->getValue(bidx+lidx+1) );
195  vhandles[2] = VertexHandle(indices->getValue(bidx+lidx+2) );
196  }
197 
198  if ( !(fh = _mesh.add_face( vhandles )).is_valid() )
199  {
200  // if fh is complex try swapped order
201  swap(vhandles[2], vhandles[1]);
202  fh = _mesh.add_face( vhandles );
203  }
204  ok = fh.is_valid();
205  }
206  break;
207 
208  case GL_TRIANGLE_STRIP:
209  vhandles.resize(3);
210  for (size_t lidx=0; lidx < lengths->getValue(tidx)-2; ++lidx)
211  {
212  if (indices == NullFC ) {
213  vhandles[0] = VertexHandle(bidx+lidx);
214  vhandles[1] = VertexHandle(bidx+lidx+1);
215  vhandles[2] = VertexHandle(bidx+lidx+2);
216  }
217  else {
218  vhandles[0] = VertexHandle(indices->getValue(bidx+lidx ) );
219  vhandles[1] = VertexHandle(indices->getValue(bidx+lidx+1) );
220  vhandles[2] = VertexHandle(indices->getValue(bidx+lidx+2) );
221  }
222 
223  if (vhandles[0]!=vhandles[2] &&
224  vhandles[0]!=vhandles[1] &&
225  vhandles[1]!=vhandles[2])
226  {
227  // if fh is complex try swapped order
228  bool swapped(false);
229 
230  if (lidx % 2) // odd numbered triplet must be reordered
231  swap(vhandles[2], vhandles[1]);
232 
233  if ( !(fh = _mesh.add_face( vhandles )).is_valid() )
234  {
235  omlog << "OpenMesh::Kernel_OSG::bind(): complex entity!\n";
236 
237  swap(vhandles[2], vhandles[1]);
238  fh = _mesh.add_face( vhandles );
239  swapped = true;
240  }
241  ok = fh.is_valid();
242  }
243  }
244  break;
245 
246  case GL_QUADS:
247  vhandles.resize(4);
248  for(size_t nf=_mesh.n_faces(), lidx=0;
249  lidx < lengths->getValue(tidx)-3; lidx+=4)
250  {
251  if (indices == NullFC ) {
252  vhandles[0] = VertexHandle(bidx+lidx);
253  vhandles[1] = VertexHandle(bidx+lidx+1);
254  vhandles[2] = VertexHandle(bidx+lidx+2);
255  vhandles[3] = VertexHandle(bidx+lidx+3);
256  }
257  else {
258  vhandles[0] = VertexHandle(indices->getValue(bidx+lidx ) );
259  vhandles[1] = VertexHandle(indices->getValue(bidx+lidx+1) );
260  vhandles[2] = VertexHandle(indices->getValue(bidx+lidx+2) );
261  vhandles[3] = VertexHandle(indices->getValue(bidx+lidx+3) );
262  }
263 
264  fh = _mesh.add_face( vhandles );
265  ok = ( Mesh::Face::is_triangle() && (_mesh.n_faces()==(nf+2)))
266  || fh.is_valid();
267  nf = _mesh.n_faces();
268  }
269  break;
270 
271  case GL_POLYGON:
272  {
273  size_t ne = lengths->getValue(tidx);
274  size_t nf = _mesh.n_faces();
275 
276  vhandles.resize(ne);
277 
278  for(size_t lidx=0; lidx < ne; ++lidx)
279  vhandles[lidx] = (indices == NullFC)
280  ? VertexHandle(bidx+lidx)
281  : VertexHandle(indices->getValue(bidx+lidx) );
282 
283  fh = _mesh.add_face( vhandles );
284  ok = ( Mesh::Face::is_triangle() && (_mesh.n_faces()==nf+ne-2) )
285  || fh.is_valid();
286 
287  break;
288  }
289  default:
290  cerr << "Warning! Skipping unsupported type "
291  << types->getValue(tidx) << " '"
292  << Utils::GLenum_as_string( types->getValue(tidx) ) << "'\n";
293  }
294 
295  // update base index into indices for next face type
296  bidx += lengths->getValue(tidx);
297  }
298 
299  if (ok)
300  ok=_mesh.bind(_geo);
301  else
302  _mesh.clear();
303 
304  return ok;
305 }
306 
307 
308 //=============================================================================
309 } // namespace Kernel_OSG
310 } // namespace OpenMesh
311 //=============================================================================
312 #endif // OPENMESH_KERNEL_OSG_BINDT_HH defined
313 //=============================================================================
314 
Handle for a face entity.
Definition: Handles.hh:141
Kernel::Color Color
Color type.
Definition: PolyMeshT.hh:116
STL namespace.
Handle for a vertex entity.
Definition: Handles.hh:120
bool is_valid() const
The handle is valid iff the index is not negative.
Definition: Handles.hh:72
bool bind(osg::GeometryPtr &_geo, Mesh &_mesh)
Definition: bindT.hh:101
SmartVertexHandle add_vertex(const Point &_p)
Definition: PolyMeshT.hh:245