00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef LOOPSCHEMEMASKT_HH
00027 #define LOOPSCHEMEMASKT_HH
00028
00029 #include <math.h>
00030 #include <vector>
00031
00032 #include <OpenMesh/Core/Utils/SingletonT.hh>
00033
00034 namespace OpenMesh
00035 {
00036
00045 template <class T_, unsigned int cache_size_ = 100>
00046 class LoopSchemeMaskT
00047 {
00048 public:
00049 enum { cache_size = cache_size_ };
00050 typedef T_ Scalar;
00051 typedef unsigned int uint;
00052
00053 protected:
00054
00055 Scalar proj_weights_[cache_size];
00056 Scalar limit_weights_[cache_size];
00057 Scalar step_weights_[cache_size];
00058 std::vector<Scalar> tang0_weights_[cache_size];
00059 std::vector<Scalar> tang1_weights_[cache_size];
00060
00061 protected:
00062
00063 inline static Scalar compute_proj_weight(uint _valence)
00064 {
00065
00066 double denom = (3.0 + 2.0*cos(2.0*M_PI/(double)_valence));
00067 double weight = (64.0*_valence)/(40.0 - denom*denom) - _valence;
00068 return (Scalar) weight;
00069 }
00070
00071 inline static Scalar compute_limit_weight(uint _valence)
00072 {
00073 double proj_weight = compute_proj_weight(_valence);
00074 proj_weight = proj_weight/(proj_weight + _valence);
00075 double weight = (3.0/8.0)/(1.0 - proj_weight + (3.0/8.0));
00076 return (Scalar)weight;
00077 }
00078
00079 inline static Scalar compute_step_weight(uint _valence)
00080 {
00081 double proj_weight = compute_proj_weight(_valence);
00082 proj_weight = proj_weight/(proj_weight + _valence);
00083 double weight = proj_weight - (3.0/8.0);
00084 return (Scalar)weight;
00085 }
00086
00087 inline static Scalar compute_tang0_weight(uint _valence, uint _ver_id)
00088 {
00089 return (Scalar)cos(2.0*M_PI*(double)_ver_id/(double)_valence);
00090 }
00091
00092 inline static Scalar compute_tang1_weight(uint _valence, uint _ver_id)
00093 {
00094 return (Scalar)sin(2.0*M_PI*(double)_ver_id/(double)_valence);
00095 }
00096
00097 void cache_weights()
00098 {
00099 proj_weights_[0] = 1;
00100 for (uint k = 1; k < cache_size; ++k)
00101 {
00102 proj_weights_[k] = compute_proj_weight(k);
00103 limit_weights_[k] = compute_limit_weight(k);
00104 step_weights_[k] = compute_step_weight(k);
00105 tang0_weights_[k].resize(k);
00106 tang1_weights_[k].resize(k);
00107 for (uint i = 0; i < k; ++i)
00108 {
00109 tang0_weights_[k][i] = compute_tang0_weight(k,i);
00110 tang1_weights_[k][i] = compute_tang1_weight(k,i);
00111 }
00112 }
00113 }
00114
00115 public:
00116
00117 LoopSchemeMaskT()
00118 {
00119 cache_weights();
00120 }
00121
00122 inline Scalar proj_weight(uint _valence) const
00123 {
00124 assert(_valence < cache_size );
00125 return proj_weights_[_valence];
00126 }
00127
00128 inline Scalar limit_weight(uint _valence) const
00129 {
00130 assert(_valence < cache_size );
00131 return limit_weights_[_valence];
00132 }
00133
00134 inline Scalar step_weight(uint _valence, uint _step) const
00135 {
00136 assert(_valence < cache_size);
00137 return pow(step_weights_[_valence], _step);
00138 }
00139
00140 inline Scalar tang0_weight(uint _valence, uint _ver_id) const
00141 {
00142 assert(_valence < cache_size );
00143 assert(_ver_id < _valence);
00144 return tang0_weights_[_valence][_ver_id];
00145 }
00146
00147 inline Scalar tang1_weight(uint _valence, uint _ver_id) const
00148 {
00149 assert(_valence < cache_size );
00150 assert(_ver_id < _valence);
00151 return tang1_weights_[_valence][_ver_id];
00152 }
00153
00154 void dump(uint _max_valency = cache_size - 1) const
00155 {
00156 assert(_max_valency <= cache_size - 1);
00157
00158 for (uint i = 0; i <= _max_valency; ++i)
00159 {
00160
00161 }
00162
00163 }
00164 };
00165
00166 typedef LoopSchemeMaskT<double, 100> LoopSchemeMaskDouble;
00167 typedef SingletonT<LoopSchemeMaskDouble> LoopSchemeMaskDoubleSingleton;
00168
00169 };
00170
00171 #endif//LOOPSCHEMEMASKT_HH
00172