00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #ifndef OPENMESH_POLYMESHT_HH
00040 #define OPENMESH_POLYMESHT_HH
00041
00042
00043
00044
00045
00046 #include <OpenMesh/Core/System/config.h>
00047 #include <OpenMesh/Core/Geometry/MathDefs.hh>
00048 #include <OpenMesh/Core/Mesh/PolyConnectivity.hh>
00049 #include <vector>
00050
00051
00052
00053
00054
00055 namespace OpenMesh {
00056
00057
00058
00059
00060
00075 template <class Kernel>
00076 class PolyMeshT : public Kernel
00077 {
00078 public:
00079
00081 typedef PolyMeshT<Kernel> This;
00082
00083
00085
00086 enum { IsPolyMesh = 1 };
00087 enum { IsTriMesh = 0 };
00088 static bool is_polymesh() { return true; }
00089 static bool is_trimesh() { return false; }
00091
00093
00094
00095 typedef typename Kernel::Scalar Scalar;
00097 typedef typename Kernel::Point Point;
00099 typedef typename Kernel::Normal Normal;
00101 typedef typename Kernel::Color Color;
00103 typedef typename Kernel::TexCoord1D TexCoord1D;
00105 typedef typename Kernel::TexCoord2D TexCoord2D;
00107 typedef typename Kernel::TexCoord3D TexCoord3D;
00109 typedef typename Kernel::Vertex Vertex;
00111 typedef typename Kernel::Halfedge Halfedge;
00113 typedef typename Kernel::Edge Edge;
00115 typedef typename Kernel::Face Face;
00117
00118
00119
00121 typedef typename Kernel::VertexHandle VertexHandle;
00122 typedef typename Kernel::HalfedgeHandle HalfedgeHandle;
00123 typedef typename Kernel::EdgeHandle EdgeHandle;
00124 typedef typename Kernel::FaceHandle FaceHandle;
00125
00126
00127
00128 typedef typename Kernel::VertexIter VertexIter;
00129 typedef typename Kernel::HalfedgeIter HalfedgeIter;
00130 typedef typename Kernel::EdgeIter EdgeIter;
00131 typedef typename Kernel::FaceIter FaceIter;
00132
00133 typedef typename Kernel::ConstVertexIter ConstVertexIter;
00134 typedef typename Kernel::ConstHalfedgeIter ConstHalfedgeIter;
00135 typedef typename Kernel::ConstEdgeIter ConstEdgeIter;
00136 typedef typename Kernel::ConstFaceIter ConstFaceIter;
00138
00139
00140
00146
00147 typedef typename Kernel::VertexVertexIter VertexVertexIter;
00148 typedef typename Kernel::VertexOHalfedgeIter VertexOHalfedgeIter;
00149 typedef typename Kernel::VertexIHalfedgeIter VertexIHalfedgeIter;
00150 typedef typename Kernel::VertexEdgeIter VertexEdgeIter;
00151 typedef typename Kernel::VertexFaceIter VertexFaceIter;
00152 typedef typename Kernel::FaceVertexIter FaceVertexIter;
00153 typedef typename Kernel::FaceHalfedgeIter FaceHalfedgeIter;
00154 typedef typename Kernel::FaceEdgeIter FaceEdgeIter;
00155 typedef typename Kernel::FaceFaceIter FaceFaceIter;
00156
00157 typedef typename Kernel::ConstVertexVertexIter ConstVertexVertexIter;
00158 typedef typename Kernel::ConstVertexOHalfedgeIter ConstVertexOHalfedgeIter;
00159 typedef typename Kernel::ConstVertexIHalfedgeIter ConstVertexIHalfedgeIter;
00160 typedef typename Kernel::ConstVertexEdgeIter ConstVertexEdgeIter;
00161 typedef typename Kernel::ConstVertexFaceIter ConstVertexFaceIter;
00162 typedef typename Kernel::ConstFaceVertexIter ConstFaceVertexIter;
00163 typedef typename Kernel::ConstFaceHalfedgeIter ConstFaceHalfedgeIter;
00164 typedef typename Kernel::ConstFaceEdgeIter ConstFaceEdgeIter;
00165 typedef typename Kernel::ConstFaceFaceIter ConstFaceFaceIter;
00167
00168
00169
00170 PolyMeshT() {}
00171 virtual ~PolyMeshT() {}
00172
00177
00178 inline VertexHandle new_vertex()
00179 { return Kernel::new_vertex(); }
00180
00181 inline VertexHandle new_vertex(const Point& _p)
00182 {
00183 VertexHandle vh(Kernel::new_vertex());
00184 set_point(vh, _p);
00185 return vh;
00186 }
00187
00188 inline VertexHandle add_vertex(const Point& _p)
00189 { return new_vertex(_p); }
00190
00191
00192
00196
00199 void update_normals();
00200
00202 void update_normal(FaceHandle _fh)
00203 { set_normal(_fh, calc_face_normal(_fh)); }
00204
00207 void update_face_normals();
00208
00210 Normal calc_face_normal(FaceHandle _fh) const;
00211
00213 Normal calc_face_normal(const Point& _p0, const Point& _p1,
00214 const Point& _p2) const;
00215
00216 void calc_face_centroid(FaceHandle _fh, Point& _pt) const;
00218 void update_normal(VertexHandle _vh)
00219 { set_normal(_vh, calc_vertex_normal(_vh)); }
00220
00223 void update_vertex_normals();
00224
00228 Normal calc_vertex_normal(VertexHandle _vh) const;
00229
00237 void calc_vertex_normal_fast(VertexHandle _vh, Normal& _n) const;
00238 void calc_vertex_normal_correct(VertexHandle _vh, Normal& _n) const;
00239 void calc_vertex_normal_loop(VertexHandle _vh, Normal& _n) const;
00240
00241
00243
00244
00245
00248 void calc_edge_vector(EdgeHandle _eh, Normal& _edge_vec) const
00249 { calc_edge_vector(halfedge_handle(_eh,0), _edge_vec); }
00250
00253 void calc_edge_vector(HalfedgeHandle _heh, Normal& _edge_vec) const
00254 {
00255 _edge_vec = point(to_vertex_handle(_heh));
00256 _edge_vec -= point(from_vertex_handle(_heh));
00257 }
00258
00259
00260 Scalar calc_edge_length(EdgeHandle _eh) const
00261 { return calc_edge_length(halfedge_handle(_eh,0)); }
00262
00265 Scalar calc_edge_length(HalfedgeHandle _heh) const
00266 { return (Scalar)sqrt(calc_edge_sqr_length(_heh)); }
00267
00268 Scalar calc_edge_sqr_length(EdgeHandle _eh) const
00269 { return calc_edge_sqr_length(halfedge_handle(_eh,0)); }
00270
00271 Scalar calc_edge_sqr_length(HalfedgeHandle _heh) const
00272 {
00273 Normal edge_vec;
00274 calc_edge_vector(_heh, edge_vec);
00275 return edge_vec.sqrnorm();
00276 }
00277
00282 void calc_sector_vectors(HalfedgeHandle _in_heh, Normal& _vec0, Normal& _vec1) const
00283 {
00284 calc_edge_vector(next_halfedge_handle(_in_heh), _vec0);
00285 calc_edge_vector(opposite_halfedge_handle(_in_heh), _vec1);
00286 }
00287
00290 Scalar calc_sector_angle(HalfedgeHandle _in_heh) const
00291 {
00292 Normal v0, v1;
00293 calc_sector_vectors(_in_heh, v0, v1);
00294 Scalar denom = v0.norm()*v1.norm();
00295 if (is_zero(denom))
00296 {
00297 return 0;
00298 }
00299 Scalar cos_a = (v0 | v1) / denom;
00300 if (is_boundary(_in_heh))
00301 {
00302 FaceHandle fh(face_handle(opposite_halfedge_handle(_in_heh)));
00303 Normal f_n(calc_face_normal(fh));
00304 Scalar sign_a = dot(cross(v0, v1), f_n);
00305 return angle(cos_a, sign_a);
00306 }
00307 else
00308 {
00309 return acos(sane_aarg(cos_a));
00310 }
00311 }
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00335 void calc_sector_normal(HalfedgeHandle _in_heh, Normal& _sector_normal) const
00336 {
00337 Normal vec0, vec1;
00338 calc_sector_vectors(_in_heh, vec0, vec1);
00339 _sector_normal = cross(vec0, vec1);
00340 }
00341
00345 Scalar calc_sector_area(HalfedgeHandle _in_heh) const
00346 {
00347 Normal sector_normal;
00348 calc_sector_normal(_in_heh, sector_normal);
00349 return sector_normal.norm()/2;
00350 }
00351
00354 Scalar calc_dihedral_angle_fast(HalfedgeHandle _heh) const
00355 {
00356 CHECK(Kernel::has_face_normals());
00357 if (is_boundary(edge_handle(_heh)))
00358 {
00359 return 0;
00360 }
00361 const Normal& n0 = normal(face_handle(_heh));
00362 const Normal& n1 = normal(face_handle(opposite_halfedge_handle(_heh)));
00363 Normal he;
00364 calc_edge_vector(_heh, he);
00365 Scalar da_cos = dot(n0, n1);
00366
00367 Scalar da_sin_sign = dot(cross(n0, n1), he);
00368 return angle(da_cos, da_sin_sign);
00369 }
00370
00373 Scalar calc_dihedral_angle_fast(EdgeHandle _eh) const
00374 { return calc_dihedral_angle_fast(halfedge_handle(_eh,0)); }
00375
00376
00377 Scalar calc_dihedral_angle(HalfedgeHandle _heh) const
00378 {
00379 if (is_boundary(edge_handle(_heh)))
00380 {
00381 return 0;
00382 }
00383 Normal n0, n1, he;
00384 calc_sector_normal(_heh, n0);
00385 calc_sector_normal(opposite_halfedge_handle(_heh), n1);
00386 calc_edge_vector(_heh, he);
00387 Scalar denom = n0.norm()*n1.norm();
00388 if (denom == Scalar(0))
00389 {
00390 return 0;
00391 }
00392 Scalar da_cos = dot(n0, n1)/denom;
00393
00394 Scalar da_sin_sign = dot(cross(n0, n1), he);
00395 return angle(da_cos, da_sin_sign);
00396 }
00397
00398
00399 Scalar calc_dihedral_angle(EdgeHandle _eh) const
00400 { return calc_dihedral_angle(halfedge_handle(_eh,0)); }
00401
00404 uint find_feature_edges(Scalar _angle_tresh = OpenMesh::deg_to_rad(44.0));
00405
00406
00408 inline void split(FaceHandle _fh, const Point& _p)
00409 { Kernel::split(_fh, add_vertex(_p)); }
00410
00411 inline void split(FaceHandle _fh, VertexHandle _vh)
00412 { Kernel::split(_fh, _vh); }
00413
00414 inline void split(EdgeHandle _eh, const Point& _p)
00415 { Kernel::split(_eh, add_vertex(_p)); }
00416
00417 inline void split(EdgeHandle _eh, VertexHandle _vh)
00418 { Kernel::split(_eh, _vh); }
00419 };
00420
00421
00422
00423 }
00424
00425 #if defined(OM_INCLUDE_TEMPLATES) && !defined(OPENMESH_POLYMESH_C)
00426 # define OPENMESH_POLYMESH_TEMPLATES
00427 # include "PolyMeshT.cc"
00428 #endif
00429
00430 #endif // OPENMESH_POLYMESHT_HH defined
00431