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

Project OpenMesh, ©  Visual Computing Institute, RWTH Aachen. Documentation generated using doxygen .