OpenMesh
OpenMesh/Core/Mesh/PolyMeshT.hh
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 //=============================================================================
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines