OpenMesh

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

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
92 typedef PolyMeshT<Kernel> This;
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 ---
189 inline VertexHandle new_vertex()
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
272 void update_normal(VertexHandle _vh)
273 { this->set_normal(_vh, calc_vertex_normal(_vh)); }
274
284 void update_vertex_normals();
285
298 Normal calc_vertex_normal(VertexHandle _vh) const;
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 //=============================================================================