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: 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 //=============================================================================