| OpenMesh

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
OpenMesh::Kernel_OSG::bind
bool bind(osg::GeometryPtr &_geo, Mesh &_mesh)
Bind a OpenSG geometry to a mesh.
Definition: bindT.hh:101
OpenMesh::VertexHandle
Handle for a vertex entity.
Definition: Handles.hh:120
std
STL namespace.
OpenMesh
Contains all the mesh ingredients like the polygonal mesh, the triangle mesh, different mesh kernels ...
Definition: MeshItems.hh:59
OpenMesh::FaceHandle
Handle for a face entity.
Definition: Handles.hh:141
OpenMesh::PolyMeshT::Color
Kernel::Color Color
Color type.
Definition: PolyMeshT.hh:116
OpenMesh::BaseHandle::is_valid
bool is_valid() const
The handle is valid iff the index is not negative.
Definition: Handles.hh:72