OpenMesh
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
PolyMeshT.hh
1 /*===========================================================================*\
2  * *
3  * OpenMesh *
4  * Copyright (C) 2001-2012 by Computer Graphics Group, RWTH Aachen *
5  * www.openmesh.org *
6  * *
7  *---------------------------------------------------------------------------*
8  * This file is part of OpenMesh. *
9  * *
10  * OpenMesh is free software: you can redistribute it and/or modify *
11  * it under the terms of the GNU Lesser General Public License as *
12  * published by the Free Software Foundation, either version 3 of *
13  * the License, or (at your option) any later version with the *
14  * following exceptions: *
15  * *
16  * If other files instantiate templates or use macros *
17  * or inline functions from this file, or you compile this file and *
18  * link it with other files to produce an executable, this file does *
19  * not by itself cause the resulting executable to be covered by the *
20  * GNU Lesser General Public License. This exception does not however *
21  * invalidate any other reasons why the executable file might be *
22  * covered by the GNU Lesser General Public License. *
23  * *
24  * OpenMesh is distributed in the hope that it will be useful, *
25  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
26  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
27  * GNU Lesser General Public License for more details. *
28  * *
29  * You should have received a copy of the GNU LesserGeneral Public *
30  * License along with OpenMesh. If not, *
31  * see <http://www.gnu.org/licenses/>. *
32  * *
33 \*===========================================================================*/
34 
35 /*===========================================================================*\
36  * *
37  * $Revision: 757 $ *
38  * $Date: 2012-11-02 08:28:25 +0100 (Fr, 02 Nov 2012) $ *
39  * *
40 \*===========================================================================*/
41 
42 
43 //=============================================================================
44 //
45 // CLASS PolyMeshT
46 //
47 //=============================================================================
48 
49 
50 #ifndef OPENMESH_POLYMESHT_HH
51 #define OPENMESH_POLYMESHT_HH
52 
53 
54 //== INCLUDES =================================================================
55 
56 
57 #include <OpenMesh/Core/System/config.h>
58 #include <OpenMesh/Core/Geometry/MathDefs.hh>
59 #include <OpenMesh/Core/Mesh/PolyConnectivity.hh>
60 #include <vector>
61 
62 
63 //== NAMESPACES ===============================================================
64 
65 
66 namespace OpenMesh {
67 
68 
69 //== CLASS DEFINITION =========================================================
70 
71 
86 template <class Kernel>
87 class PolyMeshT : public Kernel
88 {
89 public:
90 
93  //--- item types ---
94 
96 
97  enum { IsPolyMesh = 1 };
98  enum { IsTriMesh = 0 };
99  static bool is_polymesh() { return true; }
100  static bool is_trimesh() { return false; }
102 
104 
105 
106  typedef typename Kernel::Scalar Scalar;
108  typedef typename Kernel::Point Point;
110  typedef typename Kernel::Normal Normal;
112  typedef typename Kernel::Color Color;
114  typedef typename Kernel::TexCoord1D TexCoord1D;
116  typedef typename Kernel::TexCoord2D TexCoord2D;
118  typedef typename Kernel::TexCoord3D TexCoord3D;
120  typedef typename Kernel::Vertex Vertex;
122  typedef typename Kernel::Halfedge Halfedge;
124  typedef typename Kernel::Edge Edge;
126  typedef typename Kernel::Face Face;
128 
129  //--- handle types ---
130 
132  typedef typename Kernel::VertexHandle VertexHandle;
133  typedef typename Kernel::HalfedgeHandle HalfedgeHandle;
134  typedef typename Kernel::EdgeHandle EdgeHandle;
135  typedef typename Kernel::FaceHandle FaceHandle;
136 
137 
138 
139  typedef typename Kernel::VertexIter VertexIter;
140  typedef typename Kernel::HalfedgeIter HalfedgeIter;
141  typedef typename Kernel::EdgeIter EdgeIter;
142  typedef typename Kernel::FaceIter FaceIter;
143 
144  typedef typename Kernel::ConstVertexIter ConstVertexIter;
145  typedef typename Kernel::ConstHalfedgeIter ConstHalfedgeIter;
146  typedef typename Kernel::ConstEdgeIter ConstEdgeIter;
147  typedef typename Kernel::ConstFaceIter ConstFaceIter;
149 
150  //--- circulators ---
151 
157 
158  typedef typename Kernel::VertexVertexIter VertexVertexIter;
159  typedef typename Kernel::VertexOHalfedgeIter VertexOHalfedgeIter;
160  typedef typename Kernel::VertexIHalfedgeIter VertexIHalfedgeIter;
161  typedef typename Kernel::VertexEdgeIter VertexEdgeIter;
162  typedef typename Kernel::VertexFaceIter VertexFaceIter;
163  typedef typename Kernel::FaceVertexIter FaceVertexIter;
164  typedef typename Kernel::FaceHalfedgeIter FaceHalfedgeIter;
165  typedef typename Kernel::FaceEdgeIter FaceEdgeIter;
166  typedef typename Kernel::FaceFaceIter FaceFaceIter;
167 
168  typedef typename Kernel::ConstVertexVertexIter ConstVertexVertexIter;
169  typedef typename Kernel::ConstVertexOHalfedgeIter ConstVertexOHalfedgeIter;
170  typedef typename Kernel::ConstVertexIHalfedgeIter ConstVertexIHalfedgeIter;
171  typedef typename Kernel::ConstVertexEdgeIter ConstVertexEdgeIter;
172  typedef typename Kernel::ConstVertexFaceIter ConstVertexFaceIter;
173  typedef typename Kernel::ConstFaceVertexIter ConstFaceVertexIter;
174  typedef typename Kernel::ConstFaceHalfedgeIter ConstFaceHalfedgeIter;
175  typedef typename Kernel::ConstFaceEdgeIter ConstFaceEdgeIter;
176  typedef typename Kernel::ConstFaceFaceIter ConstFaceFaceIter;
178 
179 
180  // --- constructor/destructor
181  PolyMeshT() {}
182  virtual ~PolyMeshT() {}
183 
188  // --- creation ---
190  { return Kernel::new_vertex(); }
191 
192  inline VertexHandle new_vertex(const Point& _p)
193  {
194  VertexHandle vh(Kernel::new_vertex());
195  this->set_point(vh, _p);
196  return vh;
197  }
198 
199  inline VertexHandle add_vertex(const Point& _p)
200  { return new_vertex(_p); }
201 
202  // --- normal vectors ---
203 
207 
215  void update_normals();
216 
218  void update_normal(FaceHandle _fh)
219  { this->set_normal(_fh, calc_face_normal(_fh)); }
220 
226  void update_face_normals();
227 
229  virtual Normal calc_face_normal(FaceHandle _fh) const;
230 
232  Normal calc_face_normal(const Point& _p0, const Point& _p1,
233  const Point& _p2) const;
235  void calc_face_centroid(FaceHandle _fh, Point& _pt) const;
236 
238  void update_normal(HalfedgeHandle _heh, const double _feature_angle = 0.8)
239  { this->set_normal(_heh, calc_halfedge_normal(_heh)); }
240 
250  void update_halfedge_normals(const double _feature_angle = 0.8);
251 
264  virtual Normal calc_halfedge_normal(HalfedgeHandle _heh, const double _feature_angle = 0.8) const;
265 
266 
269  bool is_estimated_feature_edge(HalfedgeHandle _heh, const double _feature_angle) const;
270 
273  { this->set_normal(_vh, calc_vertex_normal(_vh)); }
274 
284  void update_vertex_normals();
285 
299 
307  void calc_vertex_normal_fast(VertexHandle _vh, Normal& _n) const;
308  void calc_vertex_normal_correct(VertexHandle _vh, Normal& _n) const;
309  void calc_vertex_normal_loop(VertexHandle _vh, Normal& _n) const;
310 
311 
313 
314  // --- Geometry API - still in development ---
315 
318  void calc_edge_vector(EdgeHandle _eh, Normal& _edge_vec) const
319  { calc_edge_vector( this->halfedge_handle(_eh,0), _edge_vec); }
320 
323  void calc_edge_vector(HalfedgeHandle _heh, Normal& _edge_vec) const
324  {
325  _edge_vec = this->point(this->to_vertex_handle(_heh));
326  _edge_vec -= this->point(this->from_vertex_handle(_heh));
327  }
328 
329  // Calculates the length of the edge _eh
330  Scalar calc_edge_length(EdgeHandle _eh) const
331  { return calc_edge_length(this->halfedge_handle(_eh,0)); }
332 
335  Scalar calc_edge_length(HalfedgeHandle _heh) const
336  { return (Scalar)sqrt(calc_edge_sqr_length(_heh)); }
337 
338  Scalar calc_edge_sqr_length(EdgeHandle _eh) const
339  { return calc_edge_sqr_length(halfedge_handle(_eh,0)); }
340 
341  Scalar calc_edge_sqr_length(HalfedgeHandle _heh) const
342  {
343  Normal edge_vec;
344  calc_edge_vector(_heh, edge_vec);
345  return edge_vec.sqrnorm();
346  }
347 
352  void calc_sector_vectors(HalfedgeHandle _in_heh, Normal& _vec0, Normal& _vec1) const
353  {
354  calc_edge_vector(this->next_halfedge_handle(_in_heh), _vec0);//p2 - p1
355  calc_edge_vector(this->opposite_halfedge_handle(_in_heh), _vec1);//p0 - p1
356  }
357 
363  Scalar calc_sector_angle(HalfedgeHandle _in_heh) const
364  {
365  Normal v0, v1;
366  calc_sector_vectors(_in_heh, v0, v1);
367  Scalar denom = v0.norm()*v1.norm();
368  if (is_zero(denom))
369  {
370  return 0;
371  }
372  Scalar cos_a = dot(v0 , v1) / denom;
373  if (this->is_boundary(_in_heh))
374  {//determine if the boundary sector is concave or convex
375  FaceHandle fh(this->face_handle(this->opposite_halfedge_handle(_in_heh)));
376  Normal f_n(calc_face_normal(fh));//this normal is (for convex fh) OK
377  Scalar sign_a = dot(cross(v0, v1), f_n);
378  return angle(cos_a, sign_a);
379  }
380  else
381  {
382  return acos(sane_aarg(cos_a));
383  }
384  }
385 
386  // calculate the cos and the sin of angle <(_in_heh,next_halfedge(_in_heh))
387  /*
388  void calc_sector_angle_cos_sin(HalfedgeHandle _in_heh, Scalar& _cos_a, Scalar& _sin_a) const
389  {
390  Normal in_vec, out_vec;
391  calc_edge_vector(_in_heh, in_vec);
392  calc_edge_vector(next_halfedge_handle(_in_heh), out_vec);
393  Scalar denom = in_vec.norm()*out_vec.norm();
394  if (is_zero(denom))
395  {
396  _cos_a = 1;
397  _sin_a = 0;
398  }
399  else
400  {
401  _cos_a = dot(in_vec, out_vec)/denom;
402  _sin_a = cross(in_vec, out_vec).norm()/denom;
403  }
404  }
405  */
408  void calc_sector_normal(HalfedgeHandle _in_heh, Normal& _sector_normal) const
409  {
410  Normal vec0, vec1;
411  calc_sector_vectors(_in_heh, vec0, vec1);
412  _sector_normal = cross(vec0, vec1);//(p2-p1)^(p0-p1)
413  }
414 
418  Scalar calc_sector_area(HalfedgeHandle _in_heh) const
419  {
420  Normal sector_normal;
421  calc_sector_normal(_in_heh, sector_normal);
422  return sector_normal.norm()/2;
423  }
424 
427  Scalar calc_dihedral_angle_fast(HalfedgeHandle _heh) const
428  {
429  // Make sure that we have face normals on the mesh
430  assert(Kernel::has_face_normals());
431 
432  if (this->is_boundary(this->edge_handle(_heh)))
433  {//the dihedral angle at a boundary edge is 0
434  return 0;
435  }
436  const Normal& n0 = this->normal(this->face_handle(_heh));
437  const Normal& n1 = this->normal(this->face_handle(this->opposite_halfedge_handle(_heh)));
438  Normal he;
439  calc_edge_vector(_heh, he);
440  Scalar da_cos = dot(n0, n1);
441  //should be normalized, but we need only the sign
442  Scalar da_sin_sign = dot(cross(n0, n1), he);
443  return angle(da_cos, da_sin_sign);
444  }
445 
448  Scalar calc_dihedral_angle_fast(EdgeHandle _eh) const
449  { return calc_dihedral_angle_fast(this->halfedge_handle(_eh,0)); }
450 
451  // calculates the dihedral angle on the halfedge _heh
452  Scalar calc_dihedral_angle(HalfedgeHandle _heh) const
453  {
454  if (this->is_boundary(this->edge_handle(_heh)))
455  {//the dihedral angle at a boundary edge is 0
456  return 0;
457  }
458  Normal n0, n1, he;
459  calc_sector_normal(_heh, n0);
460  calc_sector_normal(this->opposite_halfedge_handle(_heh), n1);
461  calc_edge_vector(_heh, he);
462  Scalar denom = n0.norm()*n1.norm();
463  if (denom == Scalar(0))
464  {
465  return 0;
466  }
467  Scalar da_cos = dot(n0, n1)/denom;
468  //should be normalized, but we need only the sign
469  Scalar da_sin_sign = dot(cross(n0, n1), he);
470  return angle(da_cos, da_sin_sign);
471  }
472 
473  // calculates the dihedral angle on the edge _eh
474  Scalar calc_dihedral_angle(EdgeHandle _eh) const
475  { return calc_dihedral_angle(this->halfedge_handle(_eh,0)); }
476 
479  unsigned int find_feature_edges(Scalar _angle_tresh = OpenMesh::deg_to_rad(44.0));
480  // --- misc ---
481 
483  inline void split(FaceHandle _fh, const Point& _p)
484  { Kernel::split(_fh, add_vertex(_p)); }
485 
486  inline void split(FaceHandle _fh, VertexHandle _vh)
487  { Kernel::split(_fh, _vh); }
488 
489  inline void split(EdgeHandle _eh, const Point& _p)
490  { Kernel::split_edge(_eh, add_vertex(_p)); }
491 
492  inline void split(EdgeHandle _eh, VertexHandle _vh)
493  { Kernel::split_edge(_eh, _vh); }
494 
495 };
496 
497 
498 //=============================================================================
499 } // namespace OpenMesh
500 //=============================================================================
501 #if defined(OM_INCLUDE_TEMPLATES) && !defined(OPENMESH_POLYMESH_C)
502 # define OPENMESH_POLYMESH_TEMPLATES
503 # include "PolyMeshT.cc"
504 #endif
505 //=============================================================================
506 #endif // OPENMESH_POLYMESHT_HH defined
507 //=============================================================================

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