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
00234 void update_vertex_normals();
00235
00239 Normal calc_vertex_normal(VertexHandle _vh) const;
00240
00248 void calc_vertex_normal_fast(VertexHandle _vh, Normal& _n) const;
00249 void calc_vertex_normal_correct(VertexHandle _vh, Normal& _n) const;
00250 void calc_vertex_normal_loop(VertexHandle _vh, Normal& _n) const;
00251
00252
00254
00255
00256
00259 void calc_edge_vector(EdgeHandle _eh, Normal& _edge_vec) const
00260 { calc_edge_vector(halfedge_handle(_eh,0), _edge_vec); }
00261
00264 void calc_edge_vector(HalfedgeHandle _heh, Normal& _edge_vec) const
00265 {
00266 _edge_vec = point(to_vertex_handle(_heh));
00267 _edge_vec -= point(from_vertex_handle(_heh));
00268 }
00269
00270
00271 Scalar calc_edge_length(EdgeHandle _eh) const
00272 { return calc_edge_length(halfedge_handle(_eh,0)); }
00273
00276 Scalar calc_edge_length(HalfedgeHandle _heh) const
00277 { return (Scalar)sqrt(calc_edge_sqr_length(_heh)); }
00278
00279 Scalar calc_edge_sqr_length(EdgeHandle _eh) const
00280 { return calc_edge_sqr_length(halfedge_handle(_eh,0)); }
00281
00282 Scalar calc_edge_sqr_length(HalfedgeHandle _heh) const
00283 {
00284 Normal edge_vec;
00285 calc_edge_vector(_heh, edge_vec);
00286 return edge_vec.sqrnorm();
00287 }
00288
00293 void calc_sector_vectors(HalfedgeHandle _in_heh, Normal& _vec0, Normal& _vec1) const
00294 {
00295 calc_edge_vector(next_halfedge_handle(_in_heh), _vec0);
00296 calc_edge_vector(opposite_halfedge_handle(_in_heh), _vec1);
00297 }
00298
00304 Scalar calc_sector_angle(HalfedgeHandle _in_heh) const
00305 {
00306 Normal v0, v1;
00307 calc_sector_vectors(_in_heh, v0, v1);
00308 Scalar denom = v0.norm()*v1.norm();
00309 if (is_zero(denom))
00310 {
00311 return 0;
00312 }
00313 Scalar cos_a = (v0 | v1) / denom;
00314 if (is_boundary(_in_heh))
00315 {
00316 FaceHandle fh(face_handle(opposite_halfedge_handle(_in_heh)));
00317 Normal f_n(calc_face_normal(fh));
00318 Scalar sign_a = dot(cross(v0, v1), f_n);
00319 return angle(cos_a, sign_a);
00320 }
00321 else
00322 {
00323 return acos(sane_aarg(cos_a));
00324 }
00325 }
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00349 void calc_sector_normal(HalfedgeHandle _in_heh, Normal& _sector_normal) const
00350 {
00351 Normal vec0, vec1;
00352 calc_sector_vectors(_in_heh, vec0, vec1);
00353 _sector_normal = cross(vec0, vec1);
00354 }
00355
00359 Scalar calc_sector_area(HalfedgeHandle _in_heh) const
00360 {
00361 Normal sector_normal;
00362 calc_sector_normal(_in_heh, sector_normal);
00363 return sector_normal.norm()/2;
00364 }
00365
00368 Scalar calc_dihedral_angle_fast(HalfedgeHandle _heh) const
00369 {
00370
00371 assert(Kernel::has_face_normals());
00372
00373 if (is_boundary(edge_handle(_heh)))
00374 {
00375 return 0;
00376 }
00377 const Normal& n0 = normal(face_handle(_heh));
00378 const Normal& n1 = normal(face_handle(opposite_halfedge_handle(_heh)));
00379 Normal he;
00380 calc_edge_vector(_heh, he);
00381 Scalar da_cos = dot(n0, n1);
00382
00383 Scalar da_sin_sign = dot(cross(n0, n1), he);
00384 return angle(da_cos, da_sin_sign);
00385 }
00386
00389 Scalar calc_dihedral_angle_fast(EdgeHandle _eh) const
00390 { return calc_dihedral_angle_fast(halfedge_handle(_eh,0)); }
00391
00392
00393 Scalar calc_dihedral_angle(HalfedgeHandle _heh) const
00394 {
00395 if (is_boundary(edge_handle(_heh)))
00396 {
00397 return 0;
00398 }
00399 Normal n0, n1, he;
00400 calc_sector_normal(_heh, n0);
00401 calc_sector_normal(opposite_halfedge_handle(_heh), n1);
00402 calc_edge_vector(_heh, he);
00403 Scalar denom = n0.norm()*n1.norm();
00404 if (denom == Scalar(0))
00405 {
00406 return 0;
00407 }
00408 Scalar da_cos = dot(n0, n1)/denom;
00409
00410 Scalar da_sin_sign = dot(cross(n0, n1), he);
00411 return angle(da_cos, da_sin_sign);
00412 }
00413
00414
00415 Scalar calc_dihedral_angle(EdgeHandle _eh) const
00416 { return calc_dihedral_angle(halfedge_handle(_eh,0)); }
00417
00420 uint find_feature_edges(Scalar _angle_tresh = OpenMesh::deg_to_rad(44.0));
00421
00422
00424 inline void split(FaceHandle _fh, const Point& _p)
00425 { Kernel::split(_fh, add_vertex(_p)); }
00426
00427 inline void split(FaceHandle _fh, VertexHandle _vh)
00428 { Kernel::split(_fh, _vh); }
00429
00430 inline void split(EdgeHandle _eh, const Point& _p)
00431 { Kernel::split(_eh, add_vertex(_p)); }
00432
00433 inline void split(EdgeHandle _eh, VertexHandle _vh)
00434 { Kernel::split(_eh, _vh); }
00435 };
00436
00437
00438
00439 }
00440
00441 #if defined(OM_INCLUDE_TEMPLATES) && !defined(OPENMESH_POLYMESH_C)
00442 # define OPENMESH_POLYMESH_TEMPLATES
00443 # include "PolyMeshT.cc"
00444 #endif
00445
00446 #endif // OPENMESH_POLYMESHT_HH defined
00447