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  * $Revision$ *
45  * $Date$ *
46  * *
47 \*===========================================================================*/
48 
49 
50 //=============================================================================
51 //
52 // Implements an importer module for arbitrary OpenMesh meshes
53 //
54 //=============================================================================
55 
56 
57 #ifndef __IMPORTERT_HH__
58 #define __IMPORTERT_HH__
59 
60 
61 //=== INCLUDES ================================================================
62 
63 
64 #include <OpenMesh/Core/IO/importer/BaseImporter.hh>
65 #include <OpenMesh/Core/Utils/vector_cast.hh>
66 #include <OpenMesh/Core/Utils/color_cast.hh>
69 
70 
71 //== NAMESPACES ===============================================================
72 
73 
74 namespace OpenMesh {
75 namespace IO {
76 
77 
78 //=== IMPLEMENTATION ==========================================================
79 
80 
84 template <class Mesh>
85 class ImporterT : public BaseImporter
86 {
87 public:
88 
89  typedef typename Mesh::Point Point;
90  typedef typename Mesh::Normal Normal;
91  typedef typename Mesh::Color Color;
92  typedef typename Mesh::TexCoord2D TexCoord2D;
93  typedef typename Mesh::TexCoord3D TexCoord3D;
94  typedef std::vector<VertexHandle> VHandles;
95 
96 
97  ImporterT(Mesh& _mesh) : mesh_(_mesh), halfedgeNormals_() {}
98 
99 
100  virtual VertexHandle add_vertex(const Vec3f& _point)
101  {
102  return mesh_.add_vertex(vector_cast<Point>(_point));
103  }
104 
105  virtual VertexHandle add_vertex()
106  {
107  return mesh_.new_vertex();
108  }
109 
110  virtual FaceHandle add_face(const VHandles& _indices)
111  {
112  FaceHandle fh;
113 
114  if (_indices.size() > 2)
115  {
116  VHandles::const_iterator it, it2, end(_indices.end());
117 
118 
119  // test for valid vertex indices
120  for (it=_indices.begin(); it!=end; ++it)
121  if (! mesh_.is_valid_handle(*it))
122  {
123  omerr() << "ImporterT: Face contains invalid vertex index\n";
124  return fh;
125  }
126 
127 
128  // don't allow double vertices
129  for (it=_indices.begin(); it!=end; ++it)
130  for (it2=it+1; it2!=end; ++it2)
131  if (*it == *it2)
132  {
133  omerr() << "ImporterT: Face has equal vertices\n";
134  return fh;
135  }
136 
137 
138  // try to add face
139  fh = mesh_.add_face(_indices);
140  // separate non-manifold faces and mark them
141  if (!fh.is_valid())
142  {
143  VHandles vhandles(_indices.size());
144 
145  // double vertices
146  for (unsigned int j=0; j<_indices.size(); ++j)
147  {
148  // DO STORE p, reference may not work since vertex array
149  // may be relocated after adding a new vertex !
150  Point p = mesh_.point(_indices[j]);
151  vhandles[j] = mesh_.add_vertex(p);
152 
153  // Mark vertices of failed face as non-manifold
154  if (mesh_.has_vertex_status()) {
155  mesh_.status(vhandles[j]).set_fixed_nonmanifold(true);
156  }
157  }
158 
159  // add face
160  FaceHandle fh = mesh_.add_face(vhandles);
161 
162  // Mark failed face as non-manifold
163  if (mesh_.has_face_status())
164  mesh_.status(fh).set_fixed_nonmanifold(true);
165 
166  // Mark edges of failed face as non-two-manifold
167  if (mesh_.has_edge_status()) {
168  typename Mesh::FaceEdgeIter fe_it = mesh_.fe_iter(fh);
169  for(; fe_it.is_valid(); ++fe_it) {
170  mesh_.status(*fe_it).set_fixed_nonmanifold(true);
171  }
172  }
173  }
174 
175  //write the half edge normals
176  if (mesh_.has_halfedge_normals())
177  {
178  //iterate over all incoming haldedges of the added face
179  for (typename Mesh::FaceHalfedgeIter fh_iter = mesh_.fh_begin(fh);
180  fh_iter != mesh_.fh_end(fh); ++fh_iter)
181  {
182  //and write the normals to it
183  typename Mesh::HalfedgeHandle heh = *fh_iter;
184  typename Mesh::VertexHandle vh = mesh_.to_vertex_handle(heh);
185  typename std::map<VertexHandle,Normal>::iterator it_heNs = halfedgeNormals_.find(vh);
186  if (it_heNs != halfedgeNormals_.end())
187  mesh_.set_normal(heh,it_heNs->second);
188  }
189  halfedgeNormals_.clear();
190  }
191  }
192  return fh;
193  }
194 
195  // vertex attributes
196 
197  virtual void set_point(VertexHandle _vh, const Vec3f& _point)
198  {
199  mesh_.set_point(_vh,vector_cast<Point>(_point));
200  }
201 
202  virtual void set_normal(VertexHandle _vh, const Vec3f& _normal)
203  {
204  if (mesh_.has_vertex_normals())
205  mesh_.set_normal(_vh, vector_cast<Normal>(_normal));
206 
207  //saves normals for half edges.
208  //they will be written, when the face is added
209  if (mesh_.has_halfedge_normals())
210  halfedgeNormals_[_vh] = vector_cast<Normal>(_normal);
211  }
212 
213  virtual void set_color(VertexHandle _vh, const Vec4uc& _color)
214  {
215  if (mesh_.has_vertex_colors())
216  mesh_.set_color(_vh, color_cast<Color>(_color));
217  }
218 
219  virtual void set_color(VertexHandle _vh, const Vec3uc& _color)
220  {
221  if (mesh_.has_vertex_colors())
222  mesh_.set_color(_vh, color_cast<Color>(_color));
223  }
224 
225  virtual void set_color(VertexHandle _vh, const Vec4f& _color)
226  {
227  if (mesh_.has_vertex_colors())
228  mesh_.set_color(_vh, color_cast<Color>(_color));
229  }
230 
231  virtual void set_color(VertexHandle _vh, const Vec3f& _color)
232  {
233  if (mesh_.has_vertex_colors())
234  mesh_.set_color(_vh, color_cast<Color>(_color));
235  }
236 
237  virtual void set_texcoord(VertexHandle _vh, const Vec2f& _texcoord)
238  {
239  if (mesh_.has_vertex_texcoords2D())
240  mesh_.set_texcoord2D(_vh, vector_cast<TexCoord2D>(_texcoord));
241  }
242 
243  virtual void set_texcoord(HalfedgeHandle _heh, const Vec2f& _texcoord)
244  {
245  if (mesh_.has_halfedge_texcoords2D())
246  mesh_.set_texcoord2D(_heh, vector_cast<TexCoord2D>(_texcoord));
247  }
248 
249  virtual void set_texcoord(VertexHandle _vh, const Vec3f& _texcoord)
250  {
251  if (mesh_.has_vertex_texcoords3D())
252  mesh_.set_texcoord3D(_vh, vector_cast<TexCoord3D>(_texcoord));
253  }
254 
255  virtual void set_texcoord(HalfedgeHandle _heh, const Vec3f& _texcoord)
256  {
257  if (mesh_.has_halfedge_texcoords3D())
258  mesh_.set_texcoord3D(_heh, vector_cast<TexCoord3D>(_texcoord));
259  }
260 
261 
262  // edge attributes
263 
264  virtual void set_color(EdgeHandle _eh, const Vec4uc& _color)
265  {
266  if (mesh_.has_edge_colors())
267  mesh_.set_color(_eh, color_cast<Color>(_color));
268  }
269 
270  virtual void set_color(EdgeHandle _eh, const Vec3uc& _color)
271  {
272  if (mesh_.has_edge_colors())
273  mesh_.set_color(_eh, color_cast<Color>(_color));
274  }
275 
276  virtual void set_color(EdgeHandle _eh, const Vec4f& _color)
277  {
278  if (mesh_.has_edge_colors())
279  mesh_.set_color(_eh, color_cast<Color>(_color));
280  }
281 
282  virtual void set_color(EdgeHandle _eh, const Vec3f& _color)
283  {
284  if (mesh_.has_edge_colors())
285  mesh_.set_color(_eh, color_cast<Color>(_color));
286  }
287 
288  // face attributes
289 
290  virtual void set_normal(FaceHandle _fh, const Vec3f& _normal)
291  {
292  if (mesh_.has_face_normals())
293  mesh_.set_normal(_fh, vector_cast<Normal>(_normal));
294  }
295 
296  virtual void set_color(FaceHandle _fh, const Vec3uc& _color)
297  {
298  if (mesh_.has_face_colors())
299  mesh_.set_color(_fh, color_cast<Color>(_color));
300  }
301 
302  virtual void set_color(FaceHandle _fh, const Vec4uc& _color)
303  {
304  if (mesh_.has_face_colors())
305  mesh_.set_color(_fh, color_cast<Color>(_color));
306  }
307 
308  virtual void set_color(FaceHandle _fh, const Vec3f& _color)
309  {
310  if (mesh_.has_face_colors())
311  mesh_.set_color(_fh, color_cast<Color>(_color));
312  }
313 
314  virtual void set_color(FaceHandle _fh, const Vec4f& _color)
315  {
316  if (mesh_.has_face_colors())
317  mesh_.set_color(_fh, color_cast<Color>(_color));
318  }
319 
320  virtual void add_face_texcoords( FaceHandle _fh, VertexHandle _vh, const std::vector<Vec2f>& _face_texcoords)
321  {
322  // get first halfedge handle
323  HalfedgeHandle cur_heh = mesh_.halfedge_handle(_fh);
324  HalfedgeHandle end_heh = mesh_.prev_halfedge_handle(cur_heh);
325 
326  // find start heh
327  while( mesh_.to_vertex_handle(cur_heh) != _vh && cur_heh != end_heh )
328  cur_heh = mesh_.next_halfedge_handle( cur_heh);
329 
330  for(unsigned int i=0; i<_face_texcoords.size(); ++i)
331  {
332  set_texcoord( cur_heh, _face_texcoords[i]);
333  cur_heh = mesh_.next_halfedge_handle( cur_heh);
334  }
335  }
336 
337  virtual void add_face_texcoords( FaceHandle _fh, VertexHandle _vh, const std::vector<Vec3f>& _face_texcoords)
338  {
339  // get first halfedge handle
340  HalfedgeHandle cur_heh = mesh_.halfedge_handle(_fh);
341  HalfedgeHandle end_heh = mesh_.prev_halfedge_handle(cur_heh);
342 
343  // find start heh
344  while( mesh_.to_vertex_handle(cur_heh) != _vh && cur_heh != end_heh )
345  cur_heh = mesh_.next_halfedge_handle( cur_heh);
346 
347  for(unsigned int i=0; i<_face_texcoords.size(); ++i)
348  {
349  set_texcoord( cur_heh, _face_texcoords[i]);
350  cur_heh = mesh_.next_halfedge_handle( cur_heh);
351  }
352  }
353 
354  virtual void set_face_texindex( FaceHandle _fh, int _texId ) {
355  if ( mesh_.has_face_texture_index() ) {
356  mesh_.set_texture_index(_fh , _texId);
357  }
358  }
359 
360  virtual void add_texture_information( int _id , std::string _name ) {
362 
363  if ( !mesh_.get_property_handle(property,"TextureMapping") ) {
364  mesh_.add_property(property,"TextureMapping");
365  }
366 
367  if ( mesh_.property(property).find( _id ) == mesh_.property(property).end() )
368  mesh_.property(property)[_id] = _name;
369  }
370 
371  // low-level access to mesh
372 
373  virtual BaseKernel* kernel() { return &mesh_; }
374 
375  bool is_triangle_mesh() const
376  { return Mesh::is_triangles(); }
377 
378  void reserve(unsigned int nV, unsigned int nE, unsigned int nF)
379  {
380  mesh_.reserve(nV, nE, nF);
381  }
382 
383  // query number of faces, vertices, normals, texcoords
384  size_t n_vertices() const { return mesh_.n_vertices(); }
385  size_t n_faces() const { return mesh_.n_faces(); }
386  size_t n_edges() const { return mesh_.n_edges(); }
387 
388 
389  void prepare() { }
390 
391 
392  void finish() { }
393 
394 
395 private:
396 
397  Mesh& mesh_;
398  // stores normals for halfedges of the next face
399  std::map<VertexHandle,Normal> halfedgeNormals_;
400 };
401 
402 
403 //=============================================================================
404 } // namespace IO
405 } // namespace OpenMesh
406 //=============================================================================
407 #endif
408 //=============================================================================
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:64
@ Normal
Add normals to mesh item (vertices/faces)
Definition: Attributes.hh:87
@ TexCoord2D
Add 2D texture coordinates (vertices, halfedges)
Definition: Attributes.hh:92
@ TexCoord3D
Add 3D texture coordinates (vertices, halfedges)
Definition: Attributes.hh:93
@ Color
Add colors to mesh item (vertices/faces/edges)
Definition: Attributes.hh:88
Base class for importer modules.
Definition: BaseImporter.hh:89
This class template provides an importer module for OpenMesh meshes.
Definition: ImporterT.hh:86
This class provides low-level property management like adding/removing properties and access to prope...
Definition: BaseKernel.hh:103
bool is_valid() const
The handle is valid iff the index is not equal to -1.
Definition: Handles.hh:77
Handle for a vertex entity.
Definition: Handles.hh:126
Handle for a halfedge entity.
Definition: Handles.hh:133
Handle for a edge entity.
Definition: Handles.hh:140
Handle for a face entity.
Definition: Handles.hh:147
Handle representing a mesh property.
Definition: Property.hh:544

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