OpenMesh

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
bindT.hh
Go to the documentation of this file.
1 /*===========================================================================*\
2 * *
3 * OpenMesh *
4 * Copyright (C) 2001-2012 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: 736 $ *
38 * $Date: 2012-10-08 09:30:49 +0200 (Mo, 08. Okt 2012) $ *
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