OpenMesh
ImporterT.hh
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 
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 
289  virtual void set_texcoord(HalfedgeHandle _heh, const Vec2f& _texcoord) override
290  {
291  if (mesh_.has_halfedge_texcoords2D())
292  mesh_.set_texcoord2D(_heh, vector_cast<TexCoord2D>(_texcoord));
293  }
294 
295  virtual void set_texcoord(VertexHandle _vh, const Vec3f& _texcoord) override
296  {
297  if (mesh_.has_vertex_texcoords3D())
298  mesh_.set_texcoord3D(_vh, vector_cast<TexCoord3D>(_texcoord));
299  }
300 
301  virtual void set_texcoord(HalfedgeHandle _heh, const Vec3f& _texcoord) override
302  {
303  if (mesh_.has_halfedge_texcoords3D())
304  mesh_.set_texcoord3D(_heh, vector_cast<TexCoord3D>(_texcoord));
305  }
306 
307  virtual void set_status(HalfedgeHandle _heh, const OpenMesh::Attributes::StatusInfo& _status) override
308  {
309  if (!mesh_.has_halfedge_status())
310  mesh_.request_halfedge_status();
311  mesh_.status(_heh) = _status;
312  }
313 
314  // edge attributes
315 
316  virtual void set_color(EdgeHandle _eh, const Vec4uc& _color) override
317  {
318  if (mesh_.has_edge_colors())
319  mesh_.set_color(_eh, color_cast<Color>(_color));
320  }
321 
322  virtual void set_color(EdgeHandle _eh, const Vec3uc& _color) override
323  {
324  if (mesh_.has_edge_colors())
325  mesh_.set_color(_eh, color_cast<Color>(_color));
326  }
327 
328  virtual void set_color(EdgeHandle _eh, const Vec4f& _color) override
329  {
330  if (mesh_.has_edge_colors())
331  mesh_.set_color(_eh, color_cast<Color>(_color));
332  }
333 
334  virtual void set_color(EdgeHandle _eh, const Vec3f& _color) override
335  {
336  if (mesh_.has_edge_colors())
337  mesh_.set_color(_eh, color_cast<Color>(_color));
338  }
339 
340  virtual void set_status(EdgeHandle _eh, const OpenMesh::Attributes::StatusInfo& _status) override
341  {
342  if (!mesh_.has_edge_status())
343  mesh_.request_edge_status();
344  mesh_.status(_eh) = _status;
345  }
346 
347  // face attributes
348 
349  virtual void set_normal(FaceHandle _fh, const Vec3f& _normal) override
350  {
351  if (mesh_.has_face_normals())
352  mesh_.set_normal(_fh, vector_cast<Normal>(_normal));
353  }
354 
355  virtual void set_normal(FaceHandle _fh, const Vec3d& _normal) override
356  {
357  if (mesh_.has_face_normals())
358  mesh_.set_normal(_fh, vector_cast<Normal>(_normal));
359  }
360 
361  virtual void set_color(FaceHandle _fh, const Vec3uc& _color) override
362  {
363  if (mesh_.has_face_colors())
364  mesh_.set_color(_fh, color_cast<Color>(_color));
365  }
366 
367  virtual void set_color(FaceHandle _fh, const Vec4uc& _color) override
368  {
369  if (mesh_.has_face_colors())
370  mesh_.set_color(_fh, color_cast<Color>(_color));
371  }
372 
373  virtual void set_color(FaceHandle _fh, const Vec3f& _color) override
374  {
375  if (mesh_.has_face_colors())
376  mesh_.set_color(_fh, color_cast<Color>(_color));
377  }
378 
379  virtual void set_color(FaceHandle _fh, const Vec4f& _color) override
380  {
381  if (mesh_.has_face_colors())
382  mesh_.set_color(_fh, color_cast<Color>(_color));
383  }
384 
385  virtual void set_status(FaceHandle _fh, const OpenMesh::Attributes::StatusInfo& _status) override
386  {
387  if (!mesh_.has_face_status())
388  mesh_.request_face_status();
389  mesh_.status(_fh) = _status;
390  }
391 
392  virtual void add_face_texcoords( FaceHandle _fh, VertexHandle _vh, const std::vector<Vec2f>& _face_texcoords) override
393  {
394  // get first halfedge handle
395  HalfedgeHandle cur_heh = mesh_.halfedge_handle(_fh);
396  HalfedgeHandle end_heh = mesh_.prev_halfedge_handle(cur_heh);
397 
398  // find start heh
399  while( mesh_.to_vertex_handle(cur_heh) != _vh && cur_heh != end_heh )
400  cur_heh = mesh_.next_halfedge_handle( cur_heh);
401 
402  for(unsigned int i=0; i<_face_texcoords.size(); ++i)
403  {
404  set_texcoord( cur_heh, _face_texcoords[i]);
405  cur_heh = mesh_.next_halfedge_handle( cur_heh);
406  }
407  }
408 
409  virtual void add_face_texcoords( FaceHandle _fh, VertexHandle _vh, const std::vector<Vec3f>& _face_texcoords) override
410  {
411  // get first halfedge handle
412  HalfedgeHandle cur_heh = mesh_.halfedge_handle(_fh);
413  HalfedgeHandle end_heh = mesh_.prev_halfedge_handle(cur_heh);
414 
415  // find start heh
416  while( mesh_.to_vertex_handle(cur_heh) != _vh && cur_heh != end_heh )
417  cur_heh = mesh_.next_halfedge_handle( cur_heh);
418 
419  for(unsigned int i=0; i<_face_texcoords.size(); ++i)
420  {
421  set_texcoord( cur_heh, _face_texcoords[i]);
422  cur_heh = mesh_.next_halfedge_handle( cur_heh);
423  }
424  }
425 
426  virtual void set_face_texindex( FaceHandle _fh, int _texId ) override
427  {
428  if ( mesh_.has_face_texture_index() ) {
429  mesh_.set_texture_index(_fh , _texId);
430  }
431  }
432 
433  virtual void add_texture_information( int _id , std::string _name ) override
434  {
436 
437  if ( !mesh_.get_property_handle(property,"TextureMapping") ) {
438  mesh_.add_property(property,"TextureMapping");
439  }
440 
441  if ( mesh_.property(property).find( _id ) == mesh_.property(property).end() )
442  mesh_.property(property)[_id] = _name;
443  }
444 
445  // low-level access to mesh
446 
447  virtual BaseKernel* kernel() override { return &mesh_; }
448 
449  bool is_triangle_mesh() const override
450  { return Mesh::is_triangles(); }
451 
452  void reserve(unsigned int nV, unsigned int nE, unsigned int nF) override
453  {
454  mesh_.reserve(nV, nE, nF);
455  }
456 
457  // query number of faces, vertices, normals, texcoords
458  size_t n_vertices() const override { return mesh_.n_vertices(); }
459  size_t n_faces() const override { return mesh_.n_faces(); }
460  size_t n_edges() const override { return mesh_.n_edges(); }
461 
462 
463  void prepare() override{ }
464 
465 
466  void finish() override { }
467 
468 
469 private:
470 
471  Mesh& mesh_;
472  // stores normals for halfedges of the next face
473  std::map<VertexHandle,Normal> halfedgeNormals_;
474 };
475 
476 
477 //=============================================================================
478 } // namespace IO
479 } // namespace OpenMesh
480 //=============================================================================
481 #endif
482 //=============================================================================
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:235
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:545

Project OpenMesh, ©  Computer Graphics Group, RWTH Aachen. Documentation generated using doxygen .