OpenMesh: OpenMesh/Core/IO/importer/ImporterT.hh Source File

| OpenMesh

ImporterT.hh
1 /* ========================================================================= *
2 * *
3 * OpenMesh *
4 * Copyright (c) 2001-2022, 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
45 //=============================================================================
46 //
47 // Implements an importer module for arbitrary OpenMesh meshes
48 //
49 //=============================================================================
50
51
52 #ifndef __IMPORTERT_HH__
53 #define __IMPORTERT_HH__
54
55
56 //=== INCLUDES ================================================================
57
58
59 #include <OpenMesh/Core/IO/importer/BaseImporter.hh>
60 #include <OpenMesh/Core/Utils/vector_cast.hh>
61 #include <OpenMesh/Core/Utils/color_cast.hh>
62 #include <OpenMesh/Core/Mesh/Attributes.hh>
63 #include <OpenMesh/Core/System/omstream.hh>
64
65
66 //== NAMESPACES ===============================================================
67
68
69 namespace OpenMesh {
70 namespace IO {
71
72
73 //=== IMPLEMENTATION ==========================================================
74
75
79 template <class Mesh>
80 class ImporterT : public BaseImporter
81 {
82 public:
83
84 typedef typename Mesh::Point Point;
85 typedef typename Mesh::Normal Normal;
86 typedef typename Mesh::Color Color;
87 typedef typename Mesh::TexCoord2D TexCoord2D;
88 typedef typename Mesh::TexCoord3D TexCoord3D;
89 typedef std::vector<VertexHandle> VHandles;
90
91
92 explicit ImporterT(Mesh& _mesh) : mesh_(_mesh), halfedgeNormals_() {}
93
94
95 virtual VertexHandle add_vertex(const Vec3f& _point) override
96 {
97 return mesh_.add_vertex(vector_cast<Point>(_point));
98 }
99
100 virtual VertexHandle add_vertex(const Vec3d& _point) override
101 {
102 return mesh_.add_vertex(vector_cast<Point>(_point));
103 }
104
105 virtual VertexHandle add_vertex() override
106 {
107 return mesh_.new_vertex();
108 }
109
110 virtual HalfedgeHandle add_edge(VertexHandle _vh0, VertexHandle _vh1) override
111 {
112 return mesh_.new_edge(_vh0, _vh1);
113 }
114
115 virtual FaceHandle add_face(const VHandles& _indices) override
116 {
117 FaceHandle fh;
118
119 if (_indices.size() > 2)
120 {
121 VHandles::const_iterator it, it2, end(_indices.end());
122
123
124 // test for valid vertex indices
125 for (it=_indices.begin(); it!=end; ++it)
126 if (! mesh_.is_valid_handle(*it))
127 {
128 omerr() << "ImporterT: Face contains invalid vertex index\n";
129 return fh;
130 }
131
132
133 // don't allow double vertices
134 for (it=_indices.begin(); it!=end; ++it)
135 for (it2=it+1; it2!=end; ++it2)
136 if (*it == *it2)
137 {
138 omerr() << "ImporterT: Face has equal vertices\n";
139 return fh;
140 }
141
142
143 // try to add face
144 fh = mesh_.add_face(_indices);
145 // separate non-manifold faces and mark them
146 if (!fh.is_valid())
147 {
148 VHandles vhandles(_indices.size());
149
150 // double vertices
151 for (unsigned int j=0; j<_indices.size(); ++j)
152 {
153 // DO STORE p, reference may not work since vertex array
154 // may be relocated after adding a new vertex !
155 Point p = mesh_.point(_indices[j]);
156 vhandles[j] = mesh_.add_vertex(p);
157
158 // Mark vertices of failed face as non-manifold
159 if (mesh_.has_vertex_status()) {
160 mesh_.status(vhandles[j]).set_fixed_nonmanifold(true);
161 }
162 }
163
164 // add face
165 fh = mesh_.add_face(vhandles);
166
167 // Mark failed face as non-manifold
168 if (mesh_.has_face_status())
169 mesh_.status(fh).set_fixed_nonmanifold(true);
170
171 // Mark edges of failed face as non-two-manifold
172 if (mesh_.has_edge_status()) {
173 typename Mesh::FaceEdgeIter fe_it = mesh_.fe_iter(fh);
174 for(; fe_it.is_valid(); ++fe_it) {
175 mesh_.status(*fe_it).set_fixed_nonmanifold(true);
176 }
177 }
178 }
179
180 //write the half edge normals
181 if (mesh_.has_halfedge_normals())
182 {
183 //iterate over all incoming haldedges of the added face
184 for (typename Mesh::FaceHalfedgeIter fh_iter = mesh_.fh_begin(fh);
185 fh_iter != mesh_.fh_end(fh); ++fh_iter)
186 {
187 //and write the normals to it
188 typename Mesh::HalfedgeHandle heh = *fh_iter;
189 typename Mesh::VertexHandle vh = mesh_.to_vertex_handle(heh);
190 typename std::map<VertexHandle,Normal>::iterator it_heNs = halfedgeNormals_.find(vh);
191 if (it_heNs != halfedgeNormals_.end())
192 mesh_.set_normal(heh,it_heNs->second);
193 }
194 halfedgeNormals_.clear();
195 }
196 }
197 return fh;
198 }
199
200 virtual FaceHandle add_face(HalfedgeHandle _heh) override
201 {
202 auto fh = mesh_.new_face();
203 mesh_.set_halfedge_handle(fh, _heh);
204 return fh;
205 }
206
207 // vertex attributes
208
209 virtual void set_point(VertexHandle _vh, const Vec3f& _point) override
210 {
211 mesh_.set_point(_vh,vector_cast<Point>(_point));
212 }
213
214 virtual void set_halfedge(VertexHandle _vh, HalfedgeHandle _heh) override
215 {
216 mesh_.set_halfedge_handle(_vh, _heh);
217 }
218
219 virtual void set_normal(VertexHandle _vh, const Vec3f& _normal) override
220 {
221 if (mesh_.has_vertex_normals())
222 mesh_.set_normal(_vh, vector_cast<Normal>(_normal));
223
224 //saves normals for half edges.
225 //they will be written, when the face is added
226 if (mesh_.has_halfedge_normals())
227 halfedgeNormals_[_vh] = vector_cast<Normal>(_normal);
228 }
229
230 virtual void set_normal(VertexHandle _vh, const Vec3d& _normal) override
231 {
232 if (mesh_.has_vertex_normals())
233 mesh_.set_normal(_vh, vector_cast<Normal>(_normal));
234
235 //saves normals for half edges.
236 //they will be written, when the face is added
237 if (mesh_.has_halfedge_normals())
238 halfedgeNormals_[_vh] = vector_cast<Normal>(_normal);
239 }
240
241 virtual void set_color(VertexHandle _vh, const Vec4uc& _color) override
242 {
243 if (mesh_.has_vertex_colors())
244 mesh_.set_color(_vh, color_cast<Color>(_color));
245 }
246
247 virtual void set_color(VertexHandle _vh, const Vec3uc& _color) override
248 {
249 if (mesh_.has_vertex_colors())
250 mesh_.set_color(_vh, color_cast<Color>(_color));
251 }
252
253 virtual void set_color(VertexHandle _vh, const Vec4f& _color) override
254 {
255 if (mesh_.has_vertex_colors())
256 mesh_.set_color(_vh, color_cast<Color>(_color));
257 }
258
259 virtual void set_color(VertexHandle _vh, const Vec3f& _color) override
260 {
261 if (mesh_.has_vertex_colors())
262 mesh_.set_color(_vh, color_cast<Color>(_color));
263 }
264
265 virtual void set_texcoord(VertexHandle _vh, const Vec2f& _texcoord) override
266 {
267 if (mesh_.has_vertex_texcoords2D())
268 mesh_.set_texcoord2D(_vh, vector_cast<TexCoord2D>(_texcoord));
269 }
270
271 virtual void set_status(VertexHandle _vh, const OpenMesh::Attributes::StatusInfo& _status) override
272 {
273 if (!mesh_.has_vertex_status())
274 mesh_.request_vertex_status();
275 mesh_.status(_vh) = _status;
276 }
277
278 virtual void set_next(HalfedgeHandle _heh, HalfedgeHandle _next) override
279 {
280 mesh_.set_next_halfedge_handle(_heh, _next);
281 }
282
283 virtual void set_face(HalfedgeHandle _heh, FaceHandle _fh) override
284 {
285 mesh_.set_face_handle(_heh, _fh);
286 }
287
288 virtual void request_face_texcoords2D() override
289 {
290 if(!mesh_.has_halfedge_texcoords2D())
291 mesh_.request_halfedge_texcoords2D();
292 }
293
294 virtual void set_texcoord(HalfedgeHandle _heh, const Vec2f& _texcoord) override
295 {
296 if (mesh_.has_halfedge_texcoords2D())
297 mesh_.set_texcoord2D(_heh, vector_cast<TexCoord2D>(_texcoord));
298 }
299
300 virtual void set_texcoord(VertexHandle _vh, const Vec3f& _texcoord) override
301 {
302 if (mesh_.has_vertex_texcoords3D())
303 mesh_.set_texcoord3D(_vh, vector_cast<TexCoord3D>(_texcoord));
304 }
305
306 virtual void set_texcoord(HalfedgeHandle _heh, const Vec3f& _texcoord) override
307 {
308 if (mesh_.has_halfedge_texcoords3D())
309 mesh_.set_texcoord3D(_heh, vector_cast<TexCoord3D>(_texcoord));
310 }
311
312 virtual void set_status(HalfedgeHandle _heh, const OpenMesh::Attributes::StatusInfo& _status) override
313 {
314 if (!mesh_.has_halfedge_status())
315 mesh_.request_halfedge_status();
316 mesh_.status(_heh) = _status;
317 }
318
319 // edge attributes
320
321 virtual void set_color(EdgeHandle _eh, const Vec4uc& _color) override
322 {
323 if (mesh_.has_edge_colors())
324 mesh_.set_color(_eh, color_cast<Color>(_color));
325 }
326
327 virtual void set_color(EdgeHandle _eh, const Vec3uc& _color) override
328 {
329 if (mesh_.has_edge_colors())
330 mesh_.set_color(_eh, color_cast<Color>(_color));
331 }
332
333 virtual void set_color(EdgeHandle _eh, const Vec4f& _color) override
334 {
335 if (mesh_.has_edge_colors())
336 mesh_.set_color(_eh, color_cast<Color>(_color));
337 }
338
339 virtual void set_color(EdgeHandle _eh, const Vec3f& _color) override
340 {
341 if (mesh_.has_edge_colors())
342 mesh_.set_color(_eh, color_cast<Color>(_color));
343 }
344
345 virtual void set_status(EdgeHandle _eh, const OpenMesh::Attributes::StatusInfo& _status) override
346 {
347 if (!mesh_.has_edge_status())
348 mesh_.request_edge_status();
349 mesh_.status(_eh) = _status;
350 }
351
352 // face attributes
353
354 virtual void set_normal(FaceHandle _fh, const Vec3f& _normal) override
355 {
356 if (mesh_.has_face_normals())
357 mesh_.set_normal(_fh, vector_cast<Normal>(_normal));
358 }
359
360 virtual void set_normal(FaceHandle _fh, const Vec3d& _normal) override
361 {
362 if (mesh_.has_face_normals())
363 mesh_.set_normal(_fh, vector_cast<Normal>(_normal));
364 }
365
366 virtual void set_color(FaceHandle _fh, const Vec3uc& _color) override
367 {
368 if (mesh_.has_face_colors())
369 mesh_.set_color(_fh, color_cast<Color>(_color));
370 }
371
372 virtual void set_color(FaceHandle _fh, const Vec4uc& _color) override
373 {
374 if (mesh_.has_face_colors())
375 mesh_.set_color(_fh, color_cast<Color>(_color));
376 }
377
378 virtual void set_color(FaceHandle _fh, const Vec3f& _color) override
379 {
380 if (mesh_.has_face_colors())
381 mesh_.set_color(_fh, color_cast<Color>(_color));
382 }
383
384 virtual void set_color(FaceHandle _fh, const Vec4f& _color) override
385 {
386 if (mesh_.has_face_colors())
387 mesh_.set_color(_fh, color_cast<Color>(_color));
388 }
389
390 virtual void set_status(FaceHandle _fh, const OpenMesh::Attributes::StatusInfo& _status) override
391 {
392 if (!mesh_.has_face_status())
393 mesh_.request_face_status();
394 mesh_.status(_fh) = _status;
395 }
396
397 virtual void add_face_texcoords( FaceHandle _fh, VertexHandle _vh, const std::vector<Vec2f>& _face_texcoords) override
398 {
399 // get first halfedge handle
400 HalfedgeHandle cur_heh = mesh_.halfedge_handle(_fh);
401 HalfedgeHandle end_heh = mesh_.prev_halfedge_handle(cur_heh);
402
403 // find start heh
404 while( mesh_.to_vertex_handle(cur_heh) != _vh && cur_heh != end_heh )
405 cur_heh = mesh_.next_halfedge_handle( cur_heh);
406
407 for(unsigned int i=0; i<_face_texcoords.size(); ++i)
408 {
409 set_texcoord( cur_heh, _face_texcoords[i]);
410 cur_heh = mesh_.next_halfedge_handle( cur_heh);
411 }
412 }
413
414 virtual void add_face_texcoords( FaceHandle _fh, VertexHandle _vh, const std::vector<Vec3f>& _face_texcoords) override
415 {
416 // get first halfedge handle
417 HalfedgeHandle cur_heh = mesh_.halfedge_handle(_fh);
418 HalfedgeHandle end_heh = mesh_.prev_halfedge_handle(cur_heh);
419
420 // find start heh
421 while( mesh_.to_vertex_handle(cur_heh) != _vh && cur_heh != end_heh )
422 cur_heh = mesh_.next_halfedge_handle( cur_heh);
423
424 for(unsigned int i=0; i<_face_texcoords.size(); ++i)
425 {
426 set_texcoord( cur_heh, _face_texcoords[i]);
427 cur_heh = mesh_.next_halfedge_handle( cur_heh);
428 }
429 }
430
431 virtual void set_face_texindex( FaceHandle _fh, int _texId ) override
432 {
433 if ( mesh_.has_face_texture_index() ) {
434 mesh_.set_texture_index(_fh , _texId);
435 }
436 }
437
438 virtual void add_texture_information( int _id , std::string _name ) override
439 {
440 OpenMesh::MPropHandleT< std::map< int, std::string > > property;
441
442 if ( !mesh_.get_property_handle(property,"TextureMapping") ) {
443 mesh_.add_property(property,"TextureMapping");
444 }
445
446 if ( mesh_.property(property).find( _id ) == mesh_.property(property).end() )
447 mesh_.property(property)[_id] = _name;
448 }
449
450 // low-level access to mesh
451
452 virtual BaseKernel* kernel() override { return &mesh_; }
453
454 bool is_triangle_mesh() const override
455 { return Mesh::is_triangles(); }
456
457 void reserve(unsigned int nV, unsigned int nE, unsigned int nF) override
458 {
459 mesh_.reserve(nV, nE, nF);
460 }
461
462 // query number of faces, vertices, normals, texcoords
463 size_t n_vertices() const override { return mesh_.n_vertices(); }
464 size_t n_faces() const override { return mesh_.n_faces(); }
465 size_t n_edges() const override { return mesh_.n_edges(); }
466
467
468 void prepare() override{ }
469
470
471 void finish() override { }
472
473
474 private:
475
476 Mesh& mesh_;
477 // stores normals for halfedges of the next face
478 std::map<VertexHandle,Normal> halfedgeNormals_;
479 };
480
481
482 //=============================================================================
483 } // namespace IO
484 } // namespace OpenMesh
485 //=============================================================================
486 #endif
487 //=============================================================================
Attributes.hh
This file provides some macros containing attribute usage.
omstream.hh
This file provides the streams omlog, omout, and omerr.
OpenMesh
Contains all the mesh ingredients like the polygonal mesh, the triangle mesh, different mesh kernels ...
Definition: MeshItems.hh:59
OpenMesh::VectorT< float, 3 >
VectorT< float, 4 >
OpenMesh::IO::BaseImporter
Base class for importer modules.
Definition: BaseImporter.hh:84
OpenMesh::IO::ImporterT
This class template provides an importer module for OpenMesh meshes.
Definition: ImporterT.hh:81
OpenMesh::BaseKernel
This class provides low-level property management like adding/removing properties and access to prope...
Definition: BaseKernel.hh:98
OpenMesh::BaseHandle::is_valid
bool is_valid() const
The handle is valid iff the index is not negative.
Definition: Handles.hh:72
OpenMesh::VertexHandle
Handle for a vertex entity.
Definition: Handles.hh:121
OpenMesh::HalfedgeHandle
Handle for a halfedge entity.
Definition: Handles.hh:128
OpenMesh::EdgeHandle
Handle for a edge entity.
Definition: Handles.hh:135
OpenMesh::FaceHandle
Handle for a face entity.
Definition: Handles.hh:142
OpenMesh::PolyMesh_ArrayKernelT
Polygonal mesh based on the ArrayKernel.
Definition: PolyMesh_ArrayKernelT.hh:96
OpenMesh::PolyMeshT::FaceEdgeIter
Kernel::FaceEdgeIter FaceEdgeIter
Circulator.
Definition: PolyMeshT.hh:169
OpenMesh::PolyMeshT::VertexHandle
Kernel::VertexHandle VertexHandle
Handle for referencing the corresponding item.
Definition: PolyMeshT.hh:136
OpenMesh::PolyMeshT::Normal
Kernel::Normal Normal
Normal type.
Definition: PolyMeshT.hh:114
OpenMesh::PolyMeshT::new_vertex
SmartVertexHandle new_vertex()
Uses default copy and assignment operator.
Definition: PolyMeshT.hh:201
OpenMesh::PolyMeshT::TexCoord2D
Kernel::TexCoord2D TexCoord2D
TexCoord2D type.
Definition: PolyMeshT.hh:120
OpenMesh::PolyMeshT::add_vertex
SmartVertexHandle add_vertex(const Point &_p)
Alias for new_vertex(const Point&).
Definition: PolyMeshT.hh:245
OpenMesh::PolyMeshT::TexCoord3D
Kernel::TexCoord3D TexCoord3D
TexCoord3D type.
Definition: PolyMeshT.hh:122
OpenMesh::PolyMeshT::HalfedgeHandle
Kernel::HalfedgeHandle HalfedgeHandle
Scalar type.
Definition: PolyMeshT.hh:137
OpenMesh::PolyMeshT::FaceHalfedgeIter
Kernel::FaceHalfedgeIter FaceHalfedgeIter
Circulator.
Definition: PolyMeshT.hh:168
OpenMesh::PolyMeshT::Point
Kernel::Point Point
Coordinate type.
Definition: PolyMeshT.hh:112
OpenMesh::PolyMeshT::Color
Kernel::Color Color
Color type.
Definition: PolyMeshT.hh:116
OpenMesh::Attributes::StatusInfo
Add status information to a base class.
Definition: Status.hh:95
OpenMesh::MPropHandleT
Handle representing a mesh property.
Definition: Property.hh:477