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: 367 $ * 00038 * $Date: 2011-01-27 14:18:47 +0100 (Do, 27 Jan 2011) $ * 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; 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 // --- Geometry API - still in development --- 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 // Calculates the length of the edge _eh 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);//p2 - p1 00298 calc_edge_vector(opposite_halfedge_handle(_in_heh), _vec1);//p0 - p1 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 {//determine if the boundary sector is concave or convex 00318 FaceHandle fh(face_handle(opposite_halfedge_handle(_in_heh))); 00319 Normal f_n(calc_face_normal(fh));//this normal is (for convex fh) OK 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 // calculate the cos and the sin of angle <(_in_heh,next_halfedge(_in_heh)) 00330 /* 00331 void calc_sector_angle_cos_sin(HalfedgeHandle _in_heh, Scalar& _cos_a, Scalar& _sin_a) const 00332 { 00333 Normal in_vec, out_vec; 00334 calc_edge_vector(_in_heh, in_vec); 00335 calc_edge_vector(next_halfedge_handle(_in_heh), out_vec); 00336 Scalar denom = in_vec.norm()*out_vec.norm(); 00337 if (is_zero(denom)) 00338 { 00339 _cos_a = 1; 00340 _sin_a = 0; 00341 } 00342 else 00343 { 00344 _cos_a = dot(in_vec, out_vec)/denom; 00345 _sin_a = cross(in_vec, out_vec).norm()/denom; 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);//(p2-p1)^(p0-p1) 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 // Make sure that we have face normals on the mesh 00373 assert(Kernel::has_face_normals()); 00374 00375 if (is_boundary(edge_handle(_heh))) 00376 {//the dihedral angle at a boundary edge is 0 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 //should be normalized, but we need only the sign 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 // calculates the dihedral angle on the halfedge _heh 00395 Scalar calc_dihedral_angle(HalfedgeHandle _heh) const 00396 { 00397 if (is_boundary(edge_handle(_heh))) 00398 {//the dihedral angle at a boundary edge is 0 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 //should be normalized, but we need only the sign 00412 Scalar da_sin_sign = dot(cross(n0, n1), he); 00413 return angle(da_cos, da_sin_sign); 00414 } 00415 00416 // calculates the dihedral angle on the edge _eh 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 // --- misc --- 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 } // namespace OpenMesh 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 //=============================================================================