Main Page   Modules   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

ModRoundnessT.hh

Go to the documentation of this file.
00001 //=============================================================================
00002 //                                                                            
00003 //                               OpenMesh                                     
00004 //        Copyright (C) 2003 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.7 $
00027 //   $Date: 2004/01/12 17:36:30 $
00028 //                                                                            
00029 //=============================================================================
00030 
00035 //=============================================================================
00036 //
00037 //  CLASS ModRoundnessT
00038 //
00039 //=============================================================================
00040 
00041 #ifndef OPENMESH_TOOLS_MODROUNDNESST_HH
00042 #define OPENMESH_TOOLS_MODROUNDNESST_HH
00043 
00044 
00045 //== INCLUDES =================================================================
00046 
00047 #include <OpenMesh/Tools/Decimater/ModBaseT.hh>
00048 #include <math.h>
00049 
00050 #if defined(OM_CC_MSVC)
00051 #  define OM_ENABLE_WARNINGS 4244
00052 #  pragma warning(disable : OM_ENABLE_WARNINGS )
00053 #endif
00054 
00055 //== NAMESPACE ================================================================
00056 
00057 namespace OpenMesh { // BEGIN_NS_OPENMESH
00058 namespace Decimater { // BEGIN_NS_DECIMATER
00059 
00060 
00061 //== CLASS DEFINITION =========================================================
00062 
00063 
00066 template <class DecimaterType>
00067 class ModRoundnessT : public ModBaseT<DecimaterType>
00068 {
00069 public:
00070 
00071   DECIMATING_MODULE( ModRoundnessT, DecimaterType, Roundness );
00072 
00073 public:
00074 
00075   // typedefs
00076   typedef typename Mesh::Point                      Point;
00077   typedef typename vector_traits<Point>::value_type value_type;
00078 
00079 public:
00080    
00082   ModRoundnessT( DecimaterType &_dec ) :
00083     Base(_dec, false), 
00084     min_r_(-1.0)
00085   { }
00086  
00088   ~ModRoundnessT() { }
00089 
00090 public: // inherited
00091    
00102   float collapse_priority(const CollapseInfo& _ci)  
00103   {    
00104     using namespace OpenMesh;
00105 
00106     typename Mesh::ConstVertexOHalfedgeIter voh_it(mesh(), _ci.v0);
00107     double                                  r;
00108     double                                  priority = 0.0; //==LEGAL_COLLAPSE
00109     typename Mesh::FaceHandle               fhC, fhB;
00110     Vec3f                                   B,C;
00111     
00112     if ( min_r_ < 0.0 ) // continues mode
00113     {      
00114       C   = vector_cast<Vec3f>(mesh().point( mesh().to_vertex_handle(voh_it)));
00115       fhC = mesh().face_handle( voh_it.handle() );
00116 
00117       for (++voh_it; voh_it; ++voh_it) 
00118       {
00119         B   = C;
00120         fhB = fhC;
00121         C   = vector_cast<Vec3f>(mesh().point(mesh().to_vertex_handle(voh_it)));
00122         fhC = mesh().face_handle( voh_it.handle() );
00123 
00124         if ( fhB == _ci.fl || fhB == _ci.fr )
00125           continue;
00126       
00127         // simulate collapse using position of v1
00128         r = roundness( vector_cast<Vec3f>(_ci.p1), B, C );
00129       
00130         // return the maximum non-roundness
00131         priority = std::max( priority, (1.0-r) );
00132       }
00133     }
00134     else // binary mode
00135     {
00136       C   = vector_cast<Vec3f>(mesh().point( mesh().to_vertex_handle(voh_it)));
00137       fhC = mesh().face_handle( voh_it.handle() );
00138 
00139       for (++voh_it; voh_it && (priority==LEGAL_COLLAPSE); ++voh_it) 
00140       {
00141         B   = C;
00142         fhB = fhC;
00143         C   = vector_cast<Vec3f>(mesh().point(mesh().to_vertex_handle(voh_it)));
00144         fhC = mesh().face_handle( voh_it.handle() );
00145 
00146         if ( fhB == _ci.fl || fhB == _ci.fr )
00147           continue;
00148 
00149         priority = (roundness( vector_cast<Vec3f>(_ci.p1), B, C ) < min_r_)
00150           ? ILLEGAL_COLLAPSE 
00151           : LEGAL_COLLAPSE;
00152       }
00153     }
00154 
00155     return priority;
00156   }
00157   
00158    
00159 
00160 public: // specific methods
00161 
00162   void set_min_angle( float _angle, bool _binary=true )
00163   {
00164     assert( _angle > 0 && _angle < 60 );
00165 
00166     _angle = M_PI * _angle /180.0;
00167 
00168     Vec3f A,B,C;
00169 
00170     A = Vec3f(             0, 0,           0);
00171     B = Vec3f( 2*cos(_angle), 0,           0);
00172     C = Vec3f(   cos(_angle), sin(_angle), 0);
00173 
00174     double r1 = roundness(A,B,C);
00175 
00176     _angle = 0.5 * ( M_PI - _angle );
00177 
00178     A = Vec3f(             0, 0,           0);
00179     B = Vec3f( 2*cos(_angle), 0,           0);
00180     C = Vec3f(   cos(_angle), sin(_angle), 0);
00181 
00182     double r2 = roundness(A,B,C);
00183 
00184     set_min_roundness( std::min(r1,r2), true );
00185   }
00186 
00194   void set_min_roundness( value_type _min_roundness, bool _binary=true )
00195   {
00196     assert( 0.0 <= _min_roundness && _min_roundness <= 1.0 );
00197     min_r_  = _min_roundness;
00198     set_binary(_binary);
00199   }
00200 
00202   void unset_min_roundness()
00203   {
00204     min_r_  = -1.0;
00205     set_binary(false);
00206   }
00207 
00208   // Compute a normalized roundness of a triangle ABC
00209   //
00210   // Having
00211   //   A,B,C corner points of triangle
00212   //   a,b,c the vectors BC,CA,AB
00213   //   Area  area of triangle
00214   //
00215   // then define
00216   //
00217   //      radius of circumference 
00218   // R := -----------------------
00219   //      length of shortest edge
00220   //
00221   //       ||a|| * ||b|| * ||c||    
00222   //       ---------------------
00223   //             4 * Area                 ||a|| * ||b|| * ||c||
00224   //    = ----------------------- = -----------------------------------
00225   //      min( ||a||,||b||,||c||)   4 * Area * min( ||a||,||b||,||c|| )
00226   //
00227   //                      ||a|| * ||b|| * ||c||
00228   //    = -------------------------------------------------------
00229   //      4 *  1/2 * ||cross(B-A,C-A)||  * min( ||a||,||b||,||c|| )
00230   //
00231   //                         a'a * b'b * c'c
00232   // Rē = ----------------------------------------------------------
00233   //       4 * cross(B-A,C-A)'cross(B-A,C-A) * min( a'a, b'b, c'c )
00234   //
00235   //                      a'a * b'b * c'c
00236   // R = 1/2 * sqrt(---------------------------)
00237   //                 AA * min( a'a, b'b, c'c )
00238   //
00239   // At angle 60° R has it's minimum for all edge lengths = sqrt(1/3)
00240   //
00241   // Define normalized roundness 
00242   //
00243   // nR := sqrt(1/3) / R
00244   //
00245   //                         AA * min( a'a, b'b, c'c )
00246   //     = sqrt(4/3) * sqrt(---------------------------)
00247   //                              a'a * b'b * c'c
00248   //
00249   double roundness( const Vec3f& A, const Vec3f& B, const Vec3f &C )
00250   {
00251     const value_type epsilon = value_type(10e-11);
00252 
00253     static const value_type sqrt43 = sqrt(4.0/3.0); // 60°,a=b=c, **)
00254 
00255     Vec3f vecAC     = C-A;
00256     Vec3f vecAB     = B-A;
00257 
00258     // compute squared values to avoid sqrt-computations
00259     value_type aa = (B-C).sqrnorm();
00260     value_type bb = vecAC.sqrnorm();
00261     value_type cc = vecAB.sqrnorm();
00262     value_type AA = cross(vecAC,vecAB).sqrnorm(); // without factor 1/4   **)
00263 
00264     if ( AA < epsilon )
00265       return 0.0;
00266 
00267     double nom   = AA * std::min( std::min(aa,bb),cc );
00268     double denom = aa * bb * cc;
00269     double nR    = sqrt43 * sqrt(nom/denom);
00270 
00271     return nR;
00272   }
00273 
00274 private:
00275   
00276   value_type min_r_;
00277 };
00278 
00279 
00280 //=============================================================================
00281 } // END_NS_DECIMATER
00282 } // END_NS_OPENMESH
00283 //=============================================================================
00284 #if defined(OM_CC_MSVC) && defined(OM_ENABLE_WARNINGS)
00285 #  pragma warning(default : OM_ENABLE_WARNINGS)
00286 #  undef OM_ENABLE_WARNINGS
00287 #endif
00288 //=============================================================================
00289 #endif // OPENMESH_TOOLS_PROGMESHT_HH defined
00290 //=============================================================================
00291 

acg pic Project OpenMesh, ©  Computer Graphics Group, RWTH Aachen. Documentation generated using doxygen .