- Main Page
- Modules
- Namespaces
- Classes
- Files
- Related Pages

- File List
- File Members

# Core/Mesh/PolyMeshT.hh

    00001 //=============================================================================
    00002 //
    00003 //                               OpenMesh
    00004 //      Copyright (C) 2001-2005 by Computer Graphics Group, RWTH Aachen
    00005 //                           www.openmesh.org
    00006 //
    00007 //-----------------------------------------------------------------------------
    00008 //
    00009 //                                License
    00010 //
    00011 //   This library is free software; you can redistribute it and/or modify it
    00012 //   under the terms of the GNU Library General Public License as published
    00013 //   by the Free Software Foundation, version 2.
    00014 //
    00015 //   This library is distributed in the hope that it will be useful, but
    00016 //   WITHOUT ANY WARRANTY; without even the implied warranty of
    00017 //   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    00018 //   Library General Public License for more details.
    00019 //
    00020 //   You should have received a copy of the GNU Library General Public
    00021 //   License along with this library; if not, write to the Free Software
    00022 //   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
    00023 //
    00024 //-----------------------------------------------------------------------------
    00025 //
    00026 //   $Revision: 1.4 $
    00027 //   $Date: 2005-12-21 13:51:49 $
    00028 //
    00029 //=============================================================================
    00030
    00031
    00032 //=============================================================================
    00033 //
    00034 //  CLASS PolyMeshT
    00035 //
    00036 //=============================================================================
    00037
    00038
    00039 #ifndef OPENMESH_POLYMESHT_HH
    00040 #define OPENMESH_POLYMESHT_HH
    00041
    00042
    00043 //== INCLUDES =================================================================
    00044
    00045
    00046 #include <OpenMesh/Core/System/config.hh>
    00047 #include <OpenMesh/Core/Mesh/BaseMesh.hh>
    00048 #include <OpenMesh/Core/Mesh/Iterators/IteratorsT.hh>
    00049 #include <OpenMesh/Core/Mesh/Iterators/CirculatorsT.hh>
    00050 #include <OpenMesh/Core/Attributes/Attributes.hh>
    00051 #include <OpenMesh/Core/Math/MathDefs.hh>
    00052 #include <vector>
    00053
    00054
    00055 //== NAMESPACES ===============================================================
    00056
    00057
    00058 namespace OpenMesh {
    00059
    00060
    00061 //== CLASS DEFINITION =========================================================
    00062
    00063
    00078 template <class Kernel>
    00079 class PolyMeshT : public Kernel, public BaseMesh
    00080 {
    00081 public:
    00082
    00084   typedef PolyMeshT<Kernel>   This;
    00085
    00087
    00088   enum { IsPolyMesh = 1 };
    00089   enum { IsTriMesh  = 0 };
    00090   static bool is_polymesh() { return true;  }
    00091   static bool is_trimesh()  { return false; }
    00093
    00094
    00095   //--- item types ---
    00096
    00098
    00099
    00100   typedef typename Kernel::Scalar    Scalar;
    00102   typedef typename Kernel::Point     Point;
    00103
    00105   typedef typename Kernel::Normal    Normal;
    00106
    00108   typedef typename Kernel::Color     Color;
    00109
    00111   typedef typename Kernel::TexCoord1D  TexCoord1D;
    00113   typedef typename Kernel::TexCoord2D  TexCoord2D;
    00115   typedef typename Kernel::TexCoord3D  TexCoord3D;
    00116
    00118   typedef typename Kernel::Vertex    Vertex;
    00120   typedef typename Kernel::Halfedge  Halfedge;
    00122   typedef typename Kernel::Edge      Edge;
    00124   typedef typename Kernel::Face      Face;
    00126
    00127
    00128
    00129   //--- handle types ---
    00130
    00132
    00133
    00134   typedef typename Kernel::VertexHandle       VertexHandle;
    00135   typedef typename Kernel::HalfedgeHandle     HalfedgeHandle;
    00136   typedef typename Kernel::EdgeHandle         EdgeHandle;
    00137   typedef typename Kernel::FaceHandle         FaceHandle;
    00138
    00140   static const VertexHandle    InvalidVertexHandle;
    00142   static const HalfedgeHandle  InvalidHalfedgeHandle;
    00144   static const EdgeHandle      InvalidEdgeHandle;
    00146   static const FaceHandle      InvalidFaceHandle;
    00148
    00149
    00150
    00151   //--- iterators ---
    00152
    00158
    00159   typedef Iterators::VertexIterT<This>                VertexIter;
    00160   typedef Iterators::HalfedgeIterT<This>              HalfedgeIter;
    00161   typedef Iterators::EdgeIterT<This>                  EdgeIter;
    00162   typedef Iterators::FaceIterT<This>                  FaceIter;
    00163
    00164   typedef Iterators::ConstVertexIterT<This>           ConstVertexIter;
    00165   typedef Iterators::ConstHalfedgeIterT<This>         ConstHalfedgeIter;
    00166   typedef Iterators::ConstEdgeIterT<This>             ConstEdgeIter;
    00167   typedef Iterators::ConstFaceIterT<This>             ConstFaceIter;
    00169
    00170
    00171
    00172   //--- circulators ---
    00173
    00179
    00180   typedef Iterators::VertexVertexIterT<This>          VertexVertexIter;
    00181   typedef Iterators::VertexOHalfedgeIterT<This>       VertexOHalfedgeIter;
    00182   typedef Iterators::VertexIHalfedgeIterT<This>       VertexIHalfedgeIter;
    00183   typedef Iterators::VertexEdgeIterT<This>            VertexEdgeIter;
    00184   typedef Iterators::VertexFaceIterT<This>            VertexFaceIter;
    00185   typedef Iterators::FaceVertexIterT<This>            FaceVertexIter;
    00186   typedef Iterators::FaceHalfedgeIterT<This>          FaceHalfedgeIter;
    00187   typedef Iterators::FaceEdgeIterT<This>              FaceEdgeIter;
    00188   typedef Iterators::FaceFaceIterT<This>              FaceFaceIter;
    00189
    00190   typedef Iterators::ConstVertexVertexIterT<This>     ConstVertexVertexIter;
    00191   typedef Iterators::ConstVertexOHalfedgeIterT<This>  ConstVertexOHalfedgeIter;
    00192   typedef Iterators::ConstVertexIHalfedgeIterT<This>  ConstVertexIHalfedgeIter;
    00193   typedef Iterators::ConstVertexEdgeIterT<This>       ConstVertexEdgeIter;
    00194   typedef Iterators::ConstVertexFaceIterT<This>       ConstVertexFaceIter;
    00195   typedef Iterators::ConstFaceVertexIterT<This>       ConstFaceVertexIter;
    00196   typedef Iterators::ConstFaceHalfedgeIterT<This>     ConstFaceHalfedgeIter;
    00197   typedef Iterators::ConstFaceEdgeIterT<This>         ConstFaceEdgeIter;
    00198   typedef Iterators::ConstFaceFaceIterT<This>         ConstFaceFaceIter;
    00200
    00201
    00202
    00203
    00204   // --- shortcuts
    00205
    00210
    00211   typedef VertexHandle    VHandle;
    00212   typedef HalfedgeHandle  HHandle;
    00213   typedef EdgeHandle      EHandle;
    00214   typedef FaceHandle      FHandle;
    00215
    00216   typedef VertexIter    VIter;
    00217   typedef HalfedgeIter  HIter;
    00218   typedef EdgeIter      EIter;
    00219   typedef FaceIter      FIter;
    00220
    00221   typedef ConstVertexIter    CVIter;
    00222   typedef ConstHalfedgeIter  CHIter;
    00223   typedef ConstEdgeIter      CEIter;
    00224   typedef ConstFaceIter      CFIter;
    00225
    00226   typedef VertexVertexIter      VVIter;
    00227   typedef VertexOHalfedgeIter   VOHIter;
    00228   typedef VertexIHalfedgeIter   VIHIter;
    00229   typedef VertexEdgeIter        VEIter;
    00230   typedef VertexFaceIter        VFIter;
    00231   typedef FaceVertexIter        FVIter;
    00232   typedef FaceHalfedgeIter      FHIter;
    00233   typedef FaceEdgeIter          FEIter;
    00234   typedef FaceFaceIter          FFIter;
    00235
    00236   typedef ConstVertexVertexIter      CVVIter;
    00237   typedef ConstVertexOHalfedgeIter   CVOHIter;
    00238   typedef ConstVertexIHalfedgeIter   CVIHIter;
    00239   typedef ConstVertexEdgeIter        CVEIter;
    00240   typedef ConstVertexFaceIter        CVFIter;
    00241   typedef ConstFaceVertexIter        CFVIter;
    00242   typedef ConstFaceHalfedgeIter      CFHIter;
    00243   typedef ConstFaceEdgeIter          CFEIter;
    00244   typedef ConstFaceFaceIter          CFFIter;
    00246
    00247
    00248
    00249   // --- constructor/destructor
    00250
    00252   PolyMeshT()  {}
    00253
    00255   ~PolyMeshT() {}
    00256
    00262   PolyMeshT& operator=(const PolyMeshT& _rhs) {
    00263     if (this!=&_rhs) Kernel::operator=(_rhs); return *this;
    00264   }
    00265
    00266
    00267
    00268
    00269
    00270   // --- creation ---
    00271
    00275
    00277   VertexHandle add_vertex(const Point& _p) {
    00278     return new_vertex(_p);
    00279   }
    00280
    00282   FaceHandle add_face(const std::vector<VertexHandle>& _vhandles);
    00283
    00298   template <class OtherMesh>
    00299   PolyMeshT& assign(const OtherMesh& _rhs)
    00300 #if OM_OUT_OF_CLASS_TEMPLATE || defined(DOXYGEN)
    00301      ;
    00302 #else
    00303 #  include "PolyMeshT_assign.hh"
    00304 #endif
    00305
    00307
    00308
    00309
    00310
    00311
    00312   // --- deletion ---
    00313
    00315
    00316
    00322   void delete_vertex(VertexHandle _vh, bool _delete_isolated_vertices = true);
    00323
    00332   void delete_edge(EdgeHandle _eh, bool _delete_isolated_vertices=true);
    00333
    00344   void delete_face(FaceHandle _fh, bool _delete_isolated_vertices=true);
    00345
    00347
    00348
    00349
    00350
    00351   // --- iterators begin() and end() ---
    00352
    00353
    00357
    00359   VertexIter vertices_begin()
    00360   { return VertexIter(*this, VertexHandle(0)); }
    00362   ConstVertexIter vertices_begin() const
    00363   { return ConstVertexIter(*this, VertexHandle(0)); }
    00365   VertexIter vertices_end()
    00366   { return VertexIter(*this, VertexHandle(This::n_vertices())); }
    00368   ConstVertexIter vertices_end() const
    00369   { return ConstVertexIter(*this, VertexHandle(This::n_vertices())); }
    00370
    00372   HalfedgeIter halfedges_begin()
    00373   { return HalfedgeIter(*this, HalfedgeHandle(0)); }
    00375   ConstHalfedgeIter halfedges_begin() const
    00376   { return ConstHalfedgeIter(*this, HalfedgeHandle(0)); }
    00378   HalfedgeIter halfedges_end()
    00379   { return HalfedgeIter(*this, HalfedgeHandle(This::n_halfedges())); }
    00381   ConstHalfedgeIter halfedges_end() const
    00382   { return ConstHalfedgeIter(*this, HalfedgeHandle(This::n_halfedges())); }
    00383
    00385   EdgeIter edges_begin()
    00386   { return EdgeIter(*this, EdgeHandle(0)); }
    00388   ConstEdgeIter edges_begin() const
    00389   { return ConstEdgeIter(*this, EdgeHandle(0)); }
    00391   EdgeIter edges_end()
    00392   { return EdgeIter(*this, EdgeHandle(This::n_edges())); }
    00394   ConstEdgeIter edges_end() const
    00395   { return ConstEdgeIter(*this, EdgeHandle(This::n_edges())); }
    00396
    00398   FaceIter faces_begin()
    00399   { return FaceIter(*this, FaceHandle(0)); }
    00401   ConstFaceIter faces_begin() const
    00402   { return ConstFaceIter(*this, FaceHandle(0)); }
    00404   FaceIter faces_end()
    00405   { return FaceIter(*this, FaceHandle(This::n_faces())); }
    00407   ConstFaceIter faces_end() const
    00408   { return ConstFaceIter(*this, FaceHandle(This::n_faces())); }
    00409
    00411
    00412
    00413
    00417
    00419   VertexIter vertices_sbegin()
    00420   { return VertexIter(*this, VertexHandle(0), true); }
    00422   ConstVertexIter vertices_sbegin() const
    00423   { return ConstVertexIter(*this, VertexHandle(0), true); }
    00424
    00426   HalfedgeIter halfedges_sbegin()
    00427   { return HalfedgeIter(*this, HalfedgeHandle(0), true); }
    00429   ConstHalfedgeIter halfedges_sbegin() const
    00430   { return ConstHalfedgeIter(*this, HalfedgeHandle(0), true); }
    00431
    00433   EdgeIter edges_sbegin()
    00434   { return EdgeIter(*this, EdgeHandle(0), true); }
    00436   ConstEdgeIter edges_sbegin() const
    00437   { return ConstEdgeIter(*this, EdgeHandle(0), true); }
    00438
    00440   FaceIter faces_sbegin()
    00441   { return FaceIter(*this, FaceHandle(0), true); }
    00443   ConstFaceIter faces_sbegin() const
    00444   { return ConstFaceIter(*this, FaceHandle(0), true); }
    00445
    00447
    00448
    00449
    00450
    00451   //--- circulators ---
    00452
    00456
    00458   VertexVertexIter vv_iter(VertexHandle _vh) {
    00459     return VertexVertexIter(*this, _vh); }
    00461   VertexIHalfedgeIter vih_iter(VertexHandle _vh) {
    00462     return VertexIHalfedgeIter(*this, _vh); }
    00464   VertexOHalfedgeIter voh_iter(VertexHandle _vh) {
    00465     return VertexOHalfedgeIter(*this, _vh); }
    00467   VertexEdgeIter ve_iter(VertexHandle _vh) {
    00468     return VertexEdgeIter(*this, _vh); }
    00470   VertexFaceIter vf_iter(VertexHandle _vh) {
    00471     return VertexFaceIter(*this, _vh); }
    00472
    00474   ConstVertexVertexIter cvv_iter(VertexHandle _vh) const {
    00475     return ConstVertexVertexIter(*this, _vh); }
    00477   ConstVertexIHalfedgeIter cvih_iter(VertexHandle _vh) const {
    00478     return ConstVertexIHalfedgeIter(*this, _vh); }
    00480   ConstVertexOHalfedgeIter cvoh_iter(VertexHandle _vh) const {
    00481     return ConstVertexOHalfedgeIter(*this, _vh); }
    00483   ConstVertexEdgeIter cve_iter(VertexHandle _vh) const {
    00484     return ConstVertexEdgeIter(*this, _vh); }
    00486   ConstVertexFaceIter cvf_iter(VertexHandle _vh) const {
    00487     return ConstVertexFaceIter(*this, _vh); }
    00488
    00490   FaceVertexIter fv_iter(FaceHandle _fh) {
    00491     return FaceVertexIter(*this, _fh); }
    00493   FaceHalfedgeIter fh_iter(FaceHandle _fh) {
    00494     return FaceHalfedgeIter(*this, _fh); }
    00496   FaceEdgeIter fe_iter(FaceHandle _fh) {
    00497     return FaceEdgeIter(*this, _fh); }
    00499   FaceFaceIter ff_iter(FaceHandle _fh) {
    00500     return FaceFaceIter(*this, _fh); }
    00501
    00503   ConstFaceVertexIter cfv_iter(FaceHandle _fh) const {
    00504     return ConstFaceVertexIter(*this, _fh); }
    00506   ConstFaceHalfedgeIter cfh_iter(FaceHandle _fh) const {
    00507     return ConstFaceHalfedgeIter(*this, _fh); }
    00509   ConstFaceEdgeIter cfe_iter(FaceHandle _fh) const {
    00510     return ConstFaceEdgeIter(*this, _fh); }
    00512   ConstFaceFaceIter cff_iter(FaceHandle _fh) const {
    00513     return ConstFaceFaceIter(*this, _fh); }
    00515
    00516
    00517
    00518
    00519   // --- boundary / manifold checks ---
    00520
    00524   bool is_boundary(HalfedgeHandle _heh) const
    00525   {
    00526     return Kernel::is_boundary(_heh);
    00527   }
    00528
    00531   bool is_boundary(EdgeHandle _eh) const {
    00532     return (is_boundary(halfedge_handle(_eh, 0)) ||
    00533             is_boundary(halfedge_handle(_eh, 1)));
    00534   }
    00536   bool is_boundary(VertexHandle _vh) const {
    00537     HalfedgeHandle heh(halfedge_handle(_vh));
    00538     return (!(heh.is_valid() && face_handle(heh).is_valid()));
    00539   }
    00540
    00547   bool is_boundary(FaceHandle _fh, bool _check_vertex=false) const
    00548   {
    00549      for (ConstFaceEdgeIter cfeit = cfe_iter( _fh ); cfeit; ++cfeit)
    00550         if (is_boundary( cfeit.handle() ) )
    00551            return true;
    00552
    00553      if (_check_vertex)
    00554      {
    00555         for (ConstFaceVertexIter cfvit = cfv_iter( _fh ); cfvit; ++cfvit)
    00556            if (is_boundary( cfvit.handle() ) )
    00557               return true;
    00558      }
    00559      return false;
    00560   }
    00561
    00563   bool is_manifold(VertexHandle _vh) const
    00564   {
    00565     /* The vertex is non-manifold if more than one gap exists, i.e.
    00566        more than one outgoing boundary halfedge. If (at least) one
    00567        boundary halfedge exists, the vertex' halfedge must be a
    00568        boundary halfedge. If iterating around the vertex finds another
    00569        boundary halfedge, the vertex is non-manifold. */
    00570
    00571     ConstVertexOHalfedgeIter vh_it(*this, _vh);
    00572     if (vh_it)
    00573       for (++vh_it; vh_it; ++vh_it)
    00574           if (is_boundary(vh_it.handle()))
    00575             return false;
    00576     return true;
    00577   }
    00578
    00580
    00581
    00582
    00583
    00584   // --- normal vectors ---
    00585
    00589
    00591   enum VertexNormalMode
    00592   {
    00593     FAST,
    00594     CORRECT,
    00595     ANGLE_WEIGHTED,
    00596     LOOP
    00597   };
    00598
    00599
    00602   void update_normals(VertexNormalMode _mode=FAST);
    00603
    00605   void update_normal(FaceHandle _fh)
    00606   {
    00607     set_normal(_fh, calc_face_normal(_fh));
    00608   }
    00609
    00613   void update_face_normals();
    00614
    00616   Normal calc_face_normal(FaceHandle _fh) const;
    00617
    00619   Normal calc_face_normal(const Point& _p0,
    00620                           const Point& _p1,
    00621                           const Point& _p2) const;
    00622
    00624   void update_normal(VertexHandle _vh)
    00625   {
    00626     set_normal(_vh, calc_vertex_normal(_vh));
    00627   }
    00628
    00629
    00633   void update_vertex_normals(VertexNormalMode _mode=FAST);
    00634
    00635
    00640   Normal calc_vertex_normal(VertexHandle _vh) const;
    00641
    00642
    00643   void calc_vertex_normal_fast(VertexHandle _vh, Normal& _n) const;
    00644   void calc_vertex_normal_correct(VertexHandle _vh, Normal& _n) const;
    00645   void calc_vertex_normal_loop(VertexHandle _vh, Normal& _n) const;
    00646   void calc_vertex_normal_angle_weighted(VertexHandle _vh, Normal& _n) const;
    00647
    00648
    00650
    00651   // --- Geometry API - still in development ---
    00652
    00656   void calc_edge_vector(EdgeHandle _eh, Normal& _edge_vec) const
    00657   {
    00658     calc_edge_vector(halfedge_handle(_eh,0), _edge_vec);
    00659   }
    00660
    00664   void calc_edge_vector(HalfedgeHandle _heh, Normal& _edge_vec) const
    00665   {
    00666     _edge_vec = (Normal)point(to_vertex_handle(_heh));
    00667     _edge_vec -= (Normal)point(from_vertex_handle(_heh));
    00668   }
    00669
    00672   Scalar calc_edge_length(EdgeHandle _eh) const
    00673   {
    00674     return calc_edge_length(halfedge_handle(_eh,0));
    00675   }
    00676
    00679   Scalar calc_edge_length(HalfedgeHandle _heh) const
    00680   {
    00681     return (Scalar)sqrt(calc_edge_sqr_length(_heh));
    00682   }
    00683
    00684   Scalar calc_edge_sqr_length(EdgeHandle _eh) const
    00685   {
    00686     return calc_edge_sqr_length(halfedge_handle(_eh,0));
    00687   }
    00688
    00689   Scalar calc_edge_sqr_length(HalfedgeHandle _heh) const
    00690   {
    00691     Normal edge_vec;
    00692     calc_edge_vector(_heh, edge_vec);
    00693     return edge_vec.sqrnorm();
    00694   }
    00695
    00701   void calc_sector_vectors(HalfedgeHandle _in_heh, Normal& _vec0, Normal& _vec1) const
    00702   {
    00703     calc_edge_vector(next_halfedge_handle(_in_heh), _vec0);//p2 - p1
    00704     calc_edge_vector(opposite_halfedge_handle(_in_heh), _vec1);//p0 - p1
    00705   }
    00706
    00710   Scalar calc_sector_angle(HalfedgeHandle _in_heh) const
    00711   {
    00712     Normal v0, v1;
    00713     calc_sector_vectors(_in_heh, v0, v1);
    00714     Scalar denom = v0.norm()*v1.norm();
    00715     if (is_zero(denom))
    00716     {
    00717       return 0;
    00718     }
    00719     Scalar cos_a = v0*v1/denom;
    00720     if (is_boundary(_in_heh))
    00721     {//determine if the boundary sector is concave or convex
    00722       FaceHandle fh(face_handle(opposite_halfedge_handle(_in_heh)));
    00723       Normal f_n(calc_face_normal(fh));//this normal is (for convex fh) OK
    00724       Scalar sign_a = dot(cross(v0, v1), f_n);
    00725       return angle(cos_a, sign_a);
    00726     }
    00727     else
    00728     {
    00729       return acos(sane_aarg(cos_a));
    00730     }
    00731   }
    00732
    00735   /*
    00736   void calc_sector_angle_cos_sin(HalfedgeHandle _in_heh, Scalar& _cos_a, Scalar& _sin_a) const
    00737   {
    00738     Normal in_vec, out_vec;
    00739     calc_edge_vector(_in_heh, in_vec);
    00740     calc_edge_vector(next_halfedge_handle(_in_heh), out_vec);
    00741     Scalar denom = in_vec.norm()*out_vec.norm();
    00742     if (is_zero(denom))
    00743     {
    00744       _cos_a = 1;
    00745       _sin_a = 0;
    00746     }
    00747     else
    00748     {
    00749       _cos_a = dot(in_vec, out_vec)/denom;
    00750       _sin_a = cross(in_vec, out_vec).norm()/denom;
    00751     }
    00752   }
    00753   */
    00757   void calc_sector_normal(HalfedgeHandle _in_heh, Normal& _sector_normal) const
    00758   {
    00759     Normal vec0, vec1;
    00760     calc_sector_vectors(_in_heh, vec0, vec1);
    00761     _sector_normal = cross(vec0, vec1);//(p2-p1)^(p0-p1)
    00762   }
    00763
    00768   Scalar calc_sector_area(HalfedgeHandle _in_heh) const
    00769   {
    00770     Normal sector_normal;
    00771     calc_sector_normal(_in_heh, sector_normal);
    00772     return sector_normal.norm()/2;
    00773   }
    00774
    00777   Scalar calc_dihedral_angle(HalfedgeHandle _heh) const
    00778   {
    00779     if (is_boundary(edge_handle(_heh)))
    00780     {//the dihedral angle at a boundary edge is 0
    00781       return 0;
    00782     }
    00783     Normal n0, n1, he;
    00784     calc_sector_normal(_heh, n0);
    00785     calc_sector_normal(opposite_halfedge_handle(_heh), n1);
    00786     calc_edge_vector(_heh, he);
    00787     Scalar denom = n0.norm()*n1.norm();
    00788     if (is_zero(denom))
    00789     {
    00790       return 0;
    00791     }
    00792     Scalar da_cos = dot(n0, n1)/denom;
    00793     //should be normalized, but we need only the sign
    00794     Scalar da_sin_sign = cross(n0, n1)*he;
    00795     return angle(da_cos, da_sin_sign);
    00796   }
    00797
    00800   Scalar calc_dihedral_angle(EdgeHandle _eh) const
    00801   {
    00802     return calc_dihedral_angle(halfedge_handle(_eh,0));
    00803   }
    00804
    00807   uint find_feature_edges(Scalar _angle_tresh = deg_to_rad(44.0));
    00808   // --- misc ---
    00809
    00811   HalfedgeHandle find_halfedge(VertexHandle _start_vertex_handle,
    00812                                VertexHandle _end_vertex_habdle) const;
    00813
    00816   void adjust_outgoing_halfedge(VertexHandle _vh);
    00817
    00819   void split(FaceHandle _fh, VertexHandle _vh);
    00821   void split(FaceHandle _fh, const Point& _p) { split(_fh, add_vertex(_p)); }
    00822
    00824   void triangulate(FaceHandle _fh);
    00825
    00827   void triangulate();
    00828
    00829
    00831   unsigned int valence(VertexHandle _vh) const;
    00832
    00834   unsigned int valence(FaceHandle _fh) const;
    00835
    00836
    00842
    00843   const Vertex&    deref(VertexHandle _h)   const { return vertex(_h); }
    00844   Vertex&          deref(VertexHandle _h)         { return vertex(_h); }
    00845   const Halfedge&  deref(HalfedgeHandle _h) const { return halfedge(_h); }
    00846   Halfedge&        deref(HalfedgeHandle _h)       { return halfedge(_h); }
    00847   const Edge&      deref(EdgeHandle _h)     const { return edge(_h); }
    00848   Edge&            deref(EdgeHandle _h)           { return edge(_h); }
    00849   const Face&      deref(FaceHandle _h)     const { return face(_h); }
    00850   Face&            deref(FaceHandle _h)           { return face(_h); }
    00852 };
    00853
    00854
    00855
    00856 //=============================================================================
    00857 } // namespace OpenMesh
    00858 //=============================================================================
    00859 #if defined(OM_INCLUDE_TEMPLATES) && !defined(OPENMESH_POLYMESH_C)
    00860 #  define OPENMESH_POLYMESH_TEMPLATES
    00861 #  include "PolyMeshT.cc"
    00862 #endif
    00863 //=============================================================================
    00864 #endif // OPENMESH_POLYMESHT_HH defined
    00865 //=============================================================================