OpenMesh
OpenMesh/Core/Geometry/LoopSchemeMaskT.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: 393 $                                                         *
00038  *   $Date: 2011-05-24 12:22:17 +0200 (Di, 24 Mai 2011) $                   *
00039  *                                                                           *
00040 \*===========================================================================*/
00041 
00042 #ifndef LOOPSCHEMEMASKT_HH
00043 #define LOOPSCHEMEMASKT_HH
00044 
00045 #include <math.h>
00046 #include <vector>
00047 
00048 #include <OpenMesh/Core/System/config.h>
00049 #include <OpenMesh/Core/Utils/SingletonT.hh>
00050 
00051 namespace OpenMesh
00052 {
00053 
00062 template <class T_, unsigned int cache_size_ = 100>
00063 class LoopSchemeMaskT
00064 {
00065 public:
00066   enum { cache_size = cache_size_ };
00067   typedef T_                                Scalar;
00068 
00069 protected:
00070 
00071   Scalar                                    proj_weights_[cache_size];
00072   Scalar                                    limit_weights_[cache_size];
00073   Scalar                                    step_weights_[cache_size];
00074   std::vector<Scalar>                       tang0_weights_[cache_size];
00075   std::vector<Scalar>                       tang1_weights_[cache_size];
00076 
00077 protected:
00078 
00079   inline static Scalar                      compute_proj_weight(uint _valence)
00080   {
00081     //return pow(3.0 / 2.0 + cos(2.0 * M_PI / _valence), 2) / 2.0 - 1.0;
00082     double denom = (3.0 + 2.0*cos(2.0*M_PI/(double)_valence));
00083     double weight = (64.0*_valence)/(40.0 - denom*denom) - _valence;
00084     return (Scalar) weight;
00085   }
00086 
00087   inline static Scalar                      compute_limit_weight(uint _valence)
00088   {
00089     double proj_weight = compute_proj_weight(_valence);
00090     proj_weight = proj_weight/(proj_weight + _valence);//normalize the proj_weight
00091     double weight = (3.0/8.0)/(1.0 - proj_weight + (3.0/8.0));
00092     return (Scalar)weight;
00093   }
00094 
00095   inline static Scalar                      compute_step_weight(uint _valence)
00096   {
00097     double proj_weight = compute_proj_weight(_valence);
00098     proj_weight = proj_weight/(proj_weight + _valence);//normalize the proj_weight
00099     double weight = proj_weight - (3.0/8.0);
00100     return (Scalar)weight;
00101   }
00102 
00103   inline static Scalar                      compute_tang0_weight(uint _valence, uint _ver_id)
00104   {
00105     return (Scalar)cos(2.0*M_PI*(double)_ver_id/(double)_valence);
00106   }
00107 
00108   inline static Scalar                      compute_tang1_weight(uint _valence, uint _ver_id)
00109   {
00110     return (Scalar)sin(2.0*M_PI*(double)_ver_id/(double)_valence);
00111   }
00112 
00113   void                                      cache_weights()
00114   {
00115     proj_weights_[0] = 1;
00116     for (uint k = 1; k < cache_size; ++k)
00117     {
00118       proj_weights_[k] = compute_proj_weight(k);
00119       limit_weights_[k] = compute_limit_weight(k);
00120       step_weights_[k] = compute_step_weight(k);
00121       tang0_weights_[k].resize(k);
00122       tang1_weights_[k].resize(k);
00123       for (uint i = 0; i < k; ++i)
00124       {
00125         tang0_weights_[k][i] = compute_tang0_weight(k,i);
00126         tang1_weights_[k][i] = compute_tang1_weight(k,i);
00127       }
00128     }
00129   }
00130 
00131 public:
00132 
00133   LoopSchemeMaskT()
00134   {
00135     cache_weights();
00136   }
00137 
00138   inline Scalar                             proj_weight(uint _valence) const
00139   {
00140     assert(_valence < cache_size );
00141     return proj_weights_[_valence];
00142   }
00143 
00144   inline Scalar                             limit_weight(uint _valence) const
00145   {
00146     assert(_valence < cache_size );
00147     return limit_weights_[_valence];
00148   }
00149 
00150   inline Scalar                             step_weight(uint _valence, uint _step) const
00151   {
00152     assert(_valence < cache_size);
00153     return pow(step_weights_[_valence], (int)_step);//can be precomputed
00154   }
00155 
00156   inline Scalar                             tang0_weight(uint _valence, uint _ver_id) const
00157   {
00158     assert(_valence < cache_size );
00159     assert(_ver_id < _valence);
00160     return tang0_weights_[_valence][_ver_id];
00161   }
00162 
00163   inline Scalar                             tang1_weight(uint _valence, uint _ver_id) const
00164   {
00165     assert(_valence < cache_size );
00166     assert(_ver_id < _valence);
00167     return tang1_weights_[_valence][_ver_id];
00168   }
00169 
00170   void                                      dump(uint _max_valency = cache_size - 1) const
00171   {
00172     assert(_max_valency <= cache_size - 1);
00173     //CConsole::printf("(k : pw_k, lw_k): ");
00174     for (uint i = 0;  i <= _max_valency; ++i)
00175     {
00176       //CConsole::stream() << "(" << i << " : " << proj_weight(i) << ", " << limit_weight(i) << ", " << step_weight(i,1) << "), ";
00177     }
00178     //CConsole::printf("\n");
00179   }
00180 };
00181 
00182 typedef LoopSchemeMaskT<double, 100>        LoopSchemeMaskDouble;
00183 typedef SingletonT<LoopSchemeMaskDouble>    LoopSchemeMaskDoubleSingleton;
00184 
00185 }//namespace OpenMesh
00186 
00187 #endif//LOOPSCHEMEMASKT_HH
00188 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines