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
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050 #ifndef OPENMESH_POLYMESHT_HH
00051 #define OPENMESH_POLYMESHT_HH
00052
00053
00054
00055
00056
00057 #include <OpenMesh/Core/System/config.h>
00058 #include <OpenMesh/Core/Geometry/MathDefs.hh>
00059 #include <OpenMesh/Core/Mesh/PolyConnectivity.hh>
00060 #include <vector>
00061
00062
00063
00064
00065
00066 namespace OpenMesh {
00067
00068
00069
00070
00071
00086 template <class Kernel>
00087 class PolyMeshT : public Kernel
00088 {
00089 public:
00090
00092 typedef PolyMeshT<Kernel> This;
00093
00094
00096
00097 enum { IsPolyMesh = 1 };
00098 enum { IsTriMesh = 0 };
00099 static bool is_polymesh() { return true; }
00100 static bool is_trimesh() { return false; }
00102
00104
00105
00106 typedef typename Kernel::Scalar Scalar;
00108 typedef typename Kernel::Point Point;
00110 typedef typename Kernel::Normal Normal;
00112 typedef typename Kernel::Color Color;
00114 typedef typename Kernel::TexCoord1D TexCoord1D;
00116 typedef typename Kernel::TexCoord2D TexCoord2D;
00118 typedef typename Kernel::TexCoord3D TexCoord3D;
00120 typedef typename Kernel::Vertex Vertex;
00122 typedef typename Kernel::Halfedge Halfedge;
00124 typedef typename Kernel::Edge Edge;
00126 typedef typename Kernel::Face Face;
00128
00129
00130
00132 typedef typename Kernel::VertexHandle VertexHandle;
00133 typedef typename Kernel::HalfedgeHandle HalfedgeHandle;
00134 typedef typename Kernel::EdgeHandle EdgeHandle;
00135 typedef typename Kernel::FaceHandle FaceHandle;
00136
00137
00138
00139 typedef typename Kernel::VertexIter VertexIter;
00140 typedef typename Kernel::HalfedgeIter HalfedgeIter;
00141 typedef typename Kernel::EdgeIter EdgeIter;
00142 typedef typename Kernel::FaceIter FaceIter;
00143
00144 typedef typename Kernel::ConstVertexIter ConstVertexIter;
00145 typedef typename Kernel::ConstHalfedgeIter ConstHalfedgeIter;
00146 typedef typename Kernel::ConstEdgeIter ConstEdgeIter;
00147 typedef typename Kernel::ConstFaceIter ConstFaceIter;
00149
00150
00151
00157
00158 typedef typename Kernel::VertexVertexIter VertexVertexIter;
00159 typedef typename Kernel::VertexOHalfedgeIter VertexOHalfedgeIter;
00160 typedef typename Kernel::VertexIHalfedgeIter VertexIHalfedgeIter;
00161 typedef typename Kernel::VertexEdgeIter VertexEdgeIter;
00162 typedef typename Kernel::VertexFaceIter VertexFaceIter;
00163 typedef typename Kernel::FaceVertexIter FaceVertexIter;
00164 typedef typename Kernel::FaceHalfedgeIter FaceHalfedgeIter;
00165 typedef typename Kernel::FaceEdgeIter FaceEdgeIter;
00166 typedef typename Kernel::FaceFaceIter FaceFaceIter;
00167
00168 typedef typename Kernel::ConstVertexVertexIter ConstVertexVertexIter;
00169 typedef typename Kernel::ConstVertexOHalfedgeIter ConstVertexOHalfedgeIter;
00170 typedef typename Kernel::ConstVertexIHalfedgeIter ConstVertexIHalfedgeIter;
00171 typedef typename Kernel::ConstVertexEdgeIter ConstVertexEdgeIter;
00172 typedef typename Kernel::ConstVertexFaceIter ConstVertexFaceIter;
00173 typedef typename Kernel::ConstFaceVertexIter ConstFaceVertexIter;
00174 typedef typename Kernel::ConstFaceHalfedgeIter ConstFaceHalfedgeIter;
00175 typedef typename Kernel::ConstFaceEdgeIter ConstFaceEdgeIter;
00176 typedef typename Kernel::ConstFaceFaceIter ConstFaceFaceIter;
00178
00179
00180
00181 PolyMeshT() {}
00182 virtual ~PolyMeshT() {}
00183
00188
00189 inline VertexHandle new_vertex()
00190 { return Kernel::new_vertex(); }
00191
00192 inline VertexHandle new_vertex(const Point& _p)
00193 {
00194 VertexHandle vh(Kernel::new_vertex());
00195 set_point(vh, _p);
00196 return vh;
00197 }
00198
00199 inline VertexHandle add_vertex(const Point& _p)
00200 { return new_vertex(_p); }
00201
00202
00203
00207
00210 void update_normals();
00211
00213 void update_normal(FaceHandle _fh)
00214 { set_normal(_fh, calc_face_normal(_fh)); }
00215
00218 void update_face_normals();
00219
00221 virtual Normal calc_face_normal(FaceHandle _fh) const;
00222
00224 Normal calc_face_normal(const Point& _p0, const Point& _p1,
00225 const Point& _p2) const;
00226
00227 void calc_face_centroid(FaceHandle _fh, Point& _pt) const;
00229 void update_normal(VertexHandle _vh)
00230 { set_normal(_vh, calc_vertex_normal(_vh)); }
00231
00236 void update_vertex_normals();
00237
00241 Normal calc_vertex_normal(VertexHandle _vh) const;
00242
00250 void calc_vertex_normal_fast(VertexHandle _vh, Normal& _n) const;
00251 void calc_vertex_normal_correct(VertexHandle _vh, Normal& _n) const;
00252 void calc_vertex_normal_loop(VertexHandle _vh, Normal& _n) const;
00253
00254
00256
00257
00258
00261 void calc_edge_vector(EdgeHandle _eh, Normal& _edge_vec) const
00262 { calc_edge_vector(halfedge_handle(_eh,0), _edge_vec); }
00263
00266 void calc_edge_vector(HalfedgeHandle _heh, Normal& _edge_vec) const
00267 {
00268 _edge_vec = point(to_vertex_handle(_heh));
00269 _edge_vec -= point(from_vertex_handle(_heh));
00270 }
00271
00272
00273 Scalar calc_edge_length(EdgeHandle _eh) const
00274 { return calc_edge_length(halfedge_handle(_eh,0)); }
00275
00278 Scalar calc_edge_length(HalfedgeHandle _heh) const
00279 { return (Scalar)sqrt(calc_edge_sqr_length(_heh)); }
00280
00281 Scalar calc_edge_sqr_length(EdgeHandle _eh) const
00282 { return calc_edge_sqr_length(halfedge_handle(_eh,0)); }
00283
00284 Scalar calc_edge_sqr_length(HalfedgeHandle _heh) const
00285 {
00286 Normal edge_vec;
00287 calc_edge_vector(_heh, edge_vec);
00288 return edge_vec.sqrnorm();
00289 }
00290
00295 void calc_sector_vectors(HalfedgeHandle _in_heh, Normal& _vec0, Normal& _vec1) const
00296 {
00297 calc_edge_vector(next_halfedge_handle(_in_heh), _vec0);
00298 calc_edge_vector(opposite_halfedge_handle(_in_heh), _vec1);
00299 }
00300
00306 Scalar calc_sector_angle(HalfedgeHandle _in_heh) const
00307 {
00308 Normal v0, v1;
00309 calc_sector_vectors(_in_heh, v0, v1);
00310 Scalar denom = v0.norm()*v1.norm();
00311 if (is_zero(denom))
00312 {
00313 return 0;
00314 }
00315 Scalar cos_a = (v0 | v1) / denom;
00316 if (is_boundary(_in_heh))
00317 {
00318 FaceHandle fh(face_handle(opposite_halfedge_handle(_in_heh)));
00319 Normal f_n(calc_face_normal(fh));
00320 Scalar sign_a = dot(cross(v0, v1), f_n);
00321 return angle(cos_a, sign_a);
00322 }
00323 else
00324 {
00325 return acos(sane_aarg(cos_a));
00326 }
00327 }
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00351 void calc_sector_normal(HalfedgeHandle _in_heh, Normal& _sector_normal) const
00352 {
00353 Normal vec0, vec1;
00354 calc_sector_vectors(_in_heh, vec0, vec1);
00355 _sector_normal = cross(vec0, vec1);
00356 }
00357
00361 Scalar calc_sector_area(HalfedgeHandle _in_heh) const
00362 {
00363 Normal sector_normal;
00364 calc_sector_normal(_in_heh, sector_normal);
00365 return sector_normal.norm()/2;
00366 }
00367
00370 Scalar calc_dihedral_angle_fast(HalfedgeHandle _heh) const
00371 {
00372
00373 assert(Kernel::has_face_normals());
00374
00375 if (is_boundary(edge_handle(_heh)))
00376 {
00377 return 0;
00378 }
00379 const Normal& n0 = normal(face_handle(_heh));
00380 const Normal& n1 = normal(face_handle(opposite_halfedge_handle(_heh)));
00381 Normal he;
00382 calc_edge_vector(_heh, he);
00383 Scalar da_cos = dot(n0, n1);
00384
00385 Scalar da_sin_sign = dot(cross(n0, n1), he);
00386 return angle(da_cos, da_sin_sign);
00387 }
00388
00391 Scalar calc_dihedral_angle_fast(EdgeHandle _eh) const
00392 { return calc_dihedral_angle_fast(halfedge_handle(_eh,0)); }
00393
00394
00395 Scalar calc_dihedral_angle(HalfedgeHandle _heh) const
00396 {
00397 if (is_boundary(edge_handle(_heh)))
00398 {
00399 return 0;
00400 }
00401 Normal n0, n1, he;
00402 calc_sector_normal(_heh, n0);
00403 calc_sector_normal(opposite_halfedge_handle(_heh), n1);
00404 calc_edge_vector(_heh, he);
00405 Scalar denom = n0.norm()*n1.norm();
00406 if (denom == Scalar(0))
00407 {
00408 return 0;
00409 }
00410 Scalar da_cos = dot(n0, n1)/denom;
00411
00412 Scalar da_sin_sign = dot(cross(n0, n1), he);
00413 return angle(da_cos, da_sin_sign);
00414 }
00415
00416
00417 Scalar calc_dihedral_angle(EdgeHandle _eh) const
00418 { return calc_dihedral_angle(halfedge_handle(_eh,0)); }
00419
00422 uint find_feature_edges(Scalar _angle_tresh = OpenMesh::deg_to_rad(44.0));
00423
00424
00426 inline void split(FaceHandle _fh, const Point& _p)
00427 { Kernel::split(_fh, add_vertex(_p)); }
00428
00429 inline void split(FaceHandle _fh, VertexHandle _vh)
00430 { Kernel::split(_fh, _vh); }
00431
00432 inline void split(EdgeHandle _eh, const Point& _p)
00433 { Kernel::split(_eh, add_vertex(_p)); }
00434
00435 inline void split(EdgeHandle _eh, VertexHandle _vh)
00436 { Kernel::split(_eh, _vh); }
00437 };
00438
00439
00440
00441 }
00442
00443 #if defined(OM_INCLUDE_TEMPLATES) && !defined(OPENMESH_POLYMESH_C)
00444 # define OPENMESH_POLYMESH_TEMPLATES
00445 # include "PolyMeshT.cc"
00446 #endif
00447
00448 #endif // OPENMESH_POLYMESHT_HH defined
00449