OpenMesh: OpenMesh/Tools/Kernel_OSG/bindT.hh Source File

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