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>
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  {
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 //=============================================================================
This file provides some macros containing attribute usage.
This file provides the streams omlog, omout, and omerr.
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
SmartVertexHandle add_vertex(const Point &_p)
Alias for new_vertex(const Point&).
Definition: PolyMeshT.hh:245
Kernel::TexCoord3D TexCoord3D
TexCoord3D type.
Definition: PolyMeshT.hh:122
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 .