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  * $Revision$ *
45  * $Date$ *
46  * *
47 \*===========================================================================*/
48 
49 
58 //=============================================================================
59 //
60 // CLASS Traits
61 //
62 //=============================================================================
63 
64 #ifndef OPENMESH_KERNEL_OSG_BINDT_HH
65 #define OPENMESH_KERNEL_OSG_BINDT_HH
66 
67 
68 //== INCLUDES =================================================================
69 
70 
71 #include <functional>
72 #include <algorithm>
73 //
74 #include <OpenMesh/Core/Mesh/TriMeshT.hh>
75 #include <OpenMesh/Core/Utils/color_cast.hh>
76 #include <OpenMesh/Tools/Utils/GLConstAsString.hh>
77 #include <OpenSG/OSGGeometry.h>
78 //
79 #include "color_cast.hh"
80 
81 //== NAMESPACES ===============================================================
82 
83 namespace OpenMesh {
84 namespace Kernel_OSG {
85 
86 
87 //== CLASS DEFINITION =========================================================
88 
89 inline
90 bool type_is_valid( unsigned char _t )
91 {
92  return _t == GL_TRIANGLES
93  || _t == GL_TRIANGLE_STRIP
94  || _t == GL_QUADS
95  || _t == GL_POLYGON;
96 }
97 
98 
105 template < typename Mesh > inline
106 bool bind( osg::GeometryPtr& _geo, Mesh& _mesh )
107 {
108  _geo = _mesh.createGeometryPtr();
109 }
110 
119 template < typename Mesh > inline
120 bool bind( Mesh& _mesh, osg::GeometryPtr& _geo )
121 {
122  using namespace OpenMesh;
123  using namespace osg;
124  using namespace std;
125 
126  bool ok = true;
127 
128  // pre-check if types are supported
129 
130  GeoPTypesPtr types = _geo->getTypes();
131 
132  if ( (size_t)count_if( types->getData(), types->getData()+types->size(),
133  ptr_fun(type_is_valid) ) != (size_t)types->size() )
134  return false;
135 
136  // pre-check if it is a multi-indexed geometry, which is not supported!
137 
138  if ( _geo->getIndexMapping().getSize() > 1 )
139  {
140  omerr << "OpenMesh::Kernel_OSG::bind(): Multi-indexed geometry is not supported!\n";
141  return false;
142  }
143 
144 
145  // create shortcuts
146 
147  GeoPLengthsPtr lengths = _geo->getLengths();
148  GeoIndicesPtr indices = _geo->getIndices();
149  GeoPositionsPtr pos = _geo->getPositions();
150  GeoNormalsPtr normals = _geo->getNormals();
151  GeoColorsPtr colors = _geo->getColors();
152 
153 
154  // -------------------- now convert everything to polygon/triangles
155 
156  size_t tidx, bidx; // types; base index into indices
157  vector< VertexHandle > vhandles;
158 
159  // ---------- initialize geometry
160 
161  {
162  VertexHandle vh;
163  typedef typename Mesh::Color color_t;
164 
165  bool bind_normal = (normals!=NullFC) && _mesh.has_vertex_normals();
166  bool bind_color = (colors !=NullFC) && _mesh.has_vertex_colors();
167 
168  for (bidx=0; bidx < pos->size(); ++bidx)
169  {
170  vh = _mesh.add_vertex( pos->getValue(bidx) );
171  if ( bind_normal )
172  _mesh.set_normal(vh, normals->getValue(bidx));
173  if ( bind_color )
174  _mesh.set_color(vh, color_cast<color_t>(colors->getValue(bidx)));
175  }
176  }
177 
178  // ---------- create topology
179 
180  FaceHandle fh;
181 
182  size_t max_bidx = indices != NullFC ? indices->size() : pos->size();
183 
184  for (bidx=tidx=0; ok && tidx<types->size() && bidx < max_bidx; ++tidx)
185  {
186  switch( types->getValue(tidx) )
187  {
188  case GL_TRIANGLES:
189  vhandles.resize(3);
190  for(size_t lidx=0; lidx < lengths->getValue(tidx)-2; lidx+=3)
191  {
192  if (indices == NullFC ) {
193  vhandles[0] = VertexHandle(bidx+lidx);
194  vhandles[1] = VertexHandle(bidx+lidx+1);
195  vhandles[2] = VertexHandle(bidx+lidx+2);
196  }
197  else {
198  vhandles[0] = VertexHandle(indices->getValue(bidx+lidx ) );
199  vhandles[1] = VertexHandle(indices->getValue(bidx+lidx+1) );
200  vhandles[2] = VertexHandle(indices->getValue(bidx+lidx+2) );
201  }
202 
203  if ( !(fh = _mesh.add_face( vhandles )).is_valid() )
204  {
205  // if fh is complex try swapped order
206  swap(vhandles[2], vhandles[1]);
207  fh = _mesh.add_face( vhandles );
208  }
209  ok = fh.is_valid();
210  }
211  break;
212 
213  case GL_TRIANGLE_STRIP:
214  vhandles.resize(3);
215  for (size_t lidx=0; lidx < lengths->getValue(tidx)-2; ++lidx)
216  {
217  if (indices == NullFC ) {
218  vhandles[0] = VertexHandle(bidx+lidx);
219  vhandles[1] = VertexHandle(bidx+lidx+1);
220  vhandles[2] = VertexHandle(bidx+lidx+2);
221  }
222  else {
223  vhandles[0] = VertexHandle(indices->getValue(bidx+lidx ) );
224  vhandles[1] = VertexHandle(indices->getValue(bidx+lidx+1) );
225  vhandles[2] = VertexHandle(indices->getValue(bidx+lidx+2) );
226  }
227 
228  if (vhandles[0]!=vhandles[2] &&
229  vhandles[0]!=vhandles[1] &&
230  vhandles[1]!=vhandles[2])
231  {
232  // if fh is complex try swapped order
233  bool swapped(false);
234 
235  if (lidx % 2) // odd numbered triplet must be reordered
236  swap(vhandles[2], vhandles[1]);
237 
238  if ( !(fh = _mesh.add_face( vhandles )).is_valid() )
239  {
240  omlog << "OpenMesh::Kernel_OSG::bind(): complex entity!\n";
241 
242  swap(vhandles[2], vhandles[1]);
243  fh = _mesh.add_face( vhandles );
244  swapped = true;
245  }
246  ok = fh.is_valid();
247  }
248  }
249  break;
250 
251  case GL_QUADS:
252  vhandles.resize(4);
253  for(size_t nf=_mesh.n_faces(), lidx=0;
254  lidx < lengths->getValue(tidx)-3; lidx+=4)
255  {
256  if (indices == NullFC ) {
257  vhandles[0] = VertexHandle(bidx+lidx);
258  vhandles[1] = VertexHandle(bidx+lidx+1);
259  vhandles[2] = VertexHandle(bidx+lidx+2);
260  vhandles[3] = VertexHandle(bidx+lidx+3);
261  }
262  else {
263  vhandles[0] = VertexHandle(indices->getValue(bidx+lidx ) );
264  vhandles[1] = VertexHandle(indices->getValue(bidx+lidx+1) );
265  vhandles[2] = VertexHandle(indices->getValue(bidx+lidx+2) );
266  vhandles[3] = VertexHandle(indices->getValue(bidx+lidx+3) );
267  }
268 
269  fh = _mesh.add_face( vhandles );
270  ok = ( Mesh::Face::is_triangle() && (_mesh.n_faces()==(nf+2)))
271  || fh.is_valid();
272  nf = _mesh.n_faces();
273  }
274  break;
275 
276  case GL_POLYGON:
277  {
278  size_t ne = lengths->getValue(tidx);
279  size_t nf = _mesh.n_faces();
280 
281  vhandles.resize(ne);
282 
283  for(size_t lidx=0; lidx < ne; ++lidx)
284  vhandles[lidx] = (indices == NullFC)
285  ? VertexHandle(bidx+lidx)
286  : VertexHandle(indices->getValue(bidx+lidx) );
287 
288  fh = _mesh.add_face( vhandles );
289  ok = ( Mesh::Face::is_triangle() && (_mesh.n_faces()==nf+ne-2) )
290  || fh.is_valid();
291 
292  break;
293  }
294  default:
295  cerr << "Warning! Skipping unsupported type "
296  << types->getValue(tidx) << " '"
297  << Utils::GLenum_as_string( types->getValue(tidx) ) << "'\n";
298  }
299 
300  // update base index into indices for next face type
301  bidx += lengths->getValue(tidx);
302  }
303 
304  if (ok)
305  ok=_mesh.bind(_geo);
306  else
307  _mesh.clear();
308 
309  return ok;
310 }
311 
312 
313 //=============================================================================
314 } // namespace Kernel_OSG
315 } // namespace OpenMesh
316 //=============================================================================
317 #endif // OPENMESH_KERNEL_OSG_BINDT_HH defined
318 //=============================================================================
319 
Kernel::Color Color
Color type.
Definition: PolyMeshT.hh:119
bool is_valid() const
The handle is valid iff the index is not equal to -1.
Definition: Handles.hh:77
bool bind(osg::GeometryPtr &_geo, Mesh &_mesh)
Definition: bindT.hh:106
Handle for a vertex entity.
Definition: Handles.hh:125
VertexHandle add_vertex(const Point &_p)
Alias for new_vertex(const Point&).
Definition: PolyMeshT.hh:236
Handle for a face entity.
Definition: Handles.hh:146
STL namespace.