OpenMesh
|
00001 /*===========================================================================*\ 00002 * * 00003 * OpenMesh * 00004 * Copyright (C) 2001-2011 by Computer Graphics Group, RWTH Aachen * 00005 * www.openmesh.org * 00006 * * 00007 *---------------------------------------------------------------------------* 00008 * This file is part of OpenMesh. * 00009 * * 00010 * OpenMesh is free software: you can redistribute it and/or modify * 00011 * it under the terms of the GNU Lesser General Public License as * 00012 * published by the Free Software Foundation, either version 3 of * 00013 * the License, or (at your option) any later version with the * 00014 * following exceptions: * 00015 * * 00016 * If other files instantiate templates or use macros * 00017 * or inline functions from this file, or you compile this file and * 00018 * link it with other files to produce an executable, this file does * 00019 * not by itself cause the resulting executable to be covered by the * 00020 * GNU Lesser General Public License. This exception does not however * 00021 * invalidate any other reasons why the executable file might be * 00022 * covered by the GNU Lesser General Public License. * 00023 * * 00024 * OpenMesh is distributed in the hope that it will be useful, * 00025 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00026 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 00027 * GNU Lesser General Public License for more details. * 00028 * * 00029 * You should have received a copy of the GNU LesserGeneral Public * 00030 * License along with OpenMesh. If not, * 00031 * see <http://www.gnu.org/licenses/>. * 00032 * * 00033 \*===========================================================================*/ 00034 00035 /*===========================================================================*\ 00036 * * 00037 * $Revision: 512 $ * 00038 * $Date: 2012-01-19 20:12:39 +0100 (Do, 19 Jan 2012) $ * 00039 * * 00040 \*===========================================================================*/ 00041 00042 00043 //============================================================================= 00044 // 00045 // CLASS PolyMeshT 00046 // 00047 //============================================================================= 00048 00049 00050 #ifndef OPENMESH_POLYMESHT_HH 00051 #define OPENMESH_POLYMESHT_HH 00052 00053 00054 //== INCLUDES ================================================================= 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 //== NAMESPACES =============================================================== 00064 00065 00066 namespace OpenMesh { 00067 00068 00069 //== CLASS DEFINITION ========================================================= 00070 00071 00086 template <class Kernel> 00087 class PolyMeshT : public Kernel 00088 { 00089 public: 00090 00092 typedef PolyMeshT<Kernel> This; 00093 //--- item types --- 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 //--- handle types --- 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 //--- circulators --- 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 // --- constructor/destructor 00181 PolyMeshT() {} 00182 virtual ~PolyMeshT() {} 00183 00188 // --- creation --- 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 // --- normal vectors --- 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 // calculates the average of the vertices defining _fh 00227 void calc_face_centroid(FaceHandle _fh, Point& _pt) const; 00228 00230 void update_normal(HalfedgeHandle _heh, const double _feature_angle = 0.8) 00231 { set_normal(_heh, calc_halfedge_normal(_heh)); } 00232 00235 void update_halfedge_normals(const double _feature_angle = 0.8); 00236 00239 virtual Normal calc_halfedge_normal(HalfedgeHandle _fh, const double _feature_angle = 0.8) const; 00240 00241 00244 bool is_estimated_feature_edge(HalfedgeHandle _heh, const double _feature_angle) const; 00245 00247 void update_normal(VertexHandle _vh) 00248 { set_normal(_vh, calc_vertex_normal(_vh)); } 00249 00254 void update_vertex_normals(); 00255 00259 Normal calc_vertex_normal(VertexHandle _vh) const; 00260 00268 void calc_vertex_normal_fast(VertexHandle _vh, Normal& _n) const; 00269 void calc_vertex_normal_correct(VertexHandle _vh, Normal& _n) const; 00270 void calc_vertex_normal_loop(VertexHandle _vh, Normal& _n) const; 00271 00272 00274 00275 // --- Geometry API - still in development --- 00276 00279 void calc_edge_vector(EdgeHandle _eh, Normal& _edge_vec) const 00280 { calc_edge_vector(halfedge_handle(_eh,0), _edge_vec); } 00281 00284 void calc_edge_vector(HalfedgeHandle _heh, Normal& _edge_vec) const 00285 { 00286 _edge_vec = point(to_vertex_handle(_heh)); 00287 _edge_vec -= point(from_vertex_handle(_heh)); 00288 } 00289 00290 // Calculates the length of the edge _eh 00291 Scalar calc_edge_length(EdgeHandle _eh) const 00292 { return calc_edge_length(halfedge_handle(_eh,0)); } 00293 00296 Scalar calc_edge_length(HalfedgeHandle _heh) const 00297 { return (Scalar)sqrt(calc_edge_sqr_length(_heh)); } 00298 00299 Scalar calc_edge_sqr_length(EdgeHandle _eh) const 00300 { return calc_edge_sqr_length(halfedge_handle(_eh,0)); } 00301 00302 Scalar calc_edge_sqr_length(HalfedgeHandle _heh) const 00303 { 00304 Normal edge_vec; 00305 calc_edge_vector(_heh, edge_vec); 00306 return edge_vec.sqrnorm(); 00307 } 00308 00313 void calc_sector_vectors(HalfedgeHandle _in_heh, Normal& _vec0, Normal& _vec1) const 00314 { 00315 calc_edge_vector(next_halfedge_handle(_in_heh), _vec0);//p2 - p1 00316 calc_edge_vector(opposite_halfedge_handle(_in_heh), _vec1);//p0 - p1 00317 } 00318 00324 Scalar calc_sector_angle(HalfedgeHandle _in_heh) const 00325 { 00326 Normal v0, v1; 00327 calc_sector_vectors(_in_heh, v0, v1); 00328 Scalar denom = v0.norm()*v1.norm(); 00329 if (is_zero(denom)) 00330 { 00331 return 0; 00332 } 00333 Scalar cos_a = dot(v0 , v1) / denom; 00334 if (is_boundary(_in_heh)) 00335 {//determine if the boundary sector is concave or convex 00336 FaceHandle fh(face_handle(opposite_halfedge_handle(_in_heh))); 00337 Normal f_n(calc_face_normal(fh));//this normal is (for convex fh) OK 00338 Scalar sign_a = dot(cross(v0, v1), f_n); 00339 return angle(cos_a, sign_a); 00340 } 00341 else 00342 { 00343 return acos(sane_aarg(cos_a)); 00344 } 00345 } 00346 00347 // calculate the cos and the sin of angle <(_in_heh,next_halfedge(_in_heh)) 00348 /* 00349 void calc_sector_angle_cos_sin(HalfedgeHandle _in_heh, Scalar& _cos_a, Scalar& _sin_a) const 00350 { 00351 Normal in_vec, out_vec; 00352 calc_edge_vector(_in_heh, in_vec); 00353 calc_edge_vector(next_halfedge_handle(_in_heh), out_vec); 00354 Scalar denom = in_vec.norm()*out_vec.norm(); 00355 if (is_zero(denom)) 00356 { 00357 _cos_a = 1; 00358 _sin_a = 0; 00359 } 00360 else 00361 { 00362 _cos_a = dot(in_vec, out_vec)/denom; 00363 _sin_a = cross(in_vec, out_vec).norm()/denom; 00364 } 00365 } 00366 */ 00369 void calc_sector_normal(HalfedgeHandle _in_heh, Normal& _sector_normal) const 00370 { 00371 Normal vec0, vec1; 00372 calc_sector_vectors(_in_heh, vec0, vec1); 00373 _sector_normal = cross(vec0, vec1);//(p2-p1)^(p0-p1) 00374 } 00375 00379 Scalar calc_sector_area(HalfedgeHandle _in_heh) const 00380 { 00381 Normal sector_normal; 00382 calc_sector_normal(_in_heh, sector_normal); 00383 return sector_normal.norm()/2; 00384 } 00385 00388 Scalar calc_dihedral_angle_fast(HalfedgeHandle _heh) const 00389 { 00390 // Make sure that we have face normals on the mesh 00391 assert(Kernel::has_face_normals()); 00392 00393 if (is_boundary(edge_handle(_heh))) 00394 {//the dihedral angle at a boundary edge is 0 00395 return 0; 00396 } 00397 const Normal& n0 = normal(face_handle(_heh)); 00398 const Normal& n1 = normal(face_handle(opposite_halfedge_handle(_heh))); 00399 Normal he; 00400 calc_edge_vector(_heh, he); 00401 Scalar da_cos = dot(n0, n1); 00402 //should be normalized, but we need only the sign 00403 Scalar da_sin_sign = dot(cross(n0, n1), he); 00404 return angle(da_cos, da_sin_sign); 00405 } 00406 00409 Scalar calc_dihedral_angle_fast(EdgeHandle _eh) const 00410 { return calc_dihedral_angle_fast(halfedge_handle(_eh,0)); } 00411 00412 // calculates the dihedral angle on the halfedge _heh 00413 Scalar calc_dihedral_angle(HalfedgeHandle _heh) const 00414 { 00415 if (is_boundary(edge_handle(_heh))) 00416 {//the dihedral angle at a boundary edge is 0 00417 return 0; 00418 } 00419 Normal n0, n1, he; 00420 calc_sector_normal(_heh, n0); 00421 calc_sector_normal(opposite_halfedge_handle(_heh), n1); 00422 calc_edge_vector(_heh, he); 00423 Scalar denom = n0.norm()*n1.norm(); 00424 if (denom == Scalar(0)) 00425 { 00426 return 0; 00427 } 00428 Scalar da_cos = dot(n0, n1)/denom; 00429 //should be normalized, but we need only the sign 00430 Scalar da_sin_sign = dot(cross(n0, n1), he); 00431 return angle(da_cos, da_sin_sign); 00432 } 00433 00434 // calculates the dihedral angle on the edge _eh 00435 Scalar calc_dihedral_angle(EdgeHandle _eh) const 00436 { return calc_dihedral_angle(halfedge_handle(_eh,0)); } 00437 00440 uint find_feature_edges(Scalar _angle_tresh = OpenMesh::deg_to_rad(44.0)); 00441 // --- misc --- 00442 00444 inline void split(FaceHandle _fh, const Point& _p) 00445 { Kernel::split(_fh, add_vertex(_p)); } 00446 00447 inline void split(FaceHandle _fh, VertexHandle _vh) 00448 { Kernel::split(_fh, _vh); } 00449 00450 inline void split(EdgeHandle _eh, const Point& _p) 00451 { Kernel::split_edge(_eh, add_vertex(_p)); } 00452 00453 inline void split(EdgeHandle _eh, VertexHandle _vh) 00454 { Kernel::split_edge(_eh, _vh); } 00455 00456 }; 00457 00458 00459 //============================================================================= 00460 } // namespace OpenMesh 00461 //============================================================================= 00462 #if defined(OM_INCLUDE_TEMPLATES) && !defined(OPENMESH_POLYMESH_C) 00463 # define OPENMESH_POLYMESH_TEMPLATES 00464 # include "PolyMeshT.cc" 00465 #endif 00466 //============================================================================= 00467 #endif // OPENMESH_POLYMESHT_HH defined 00468 //=============================================================================