OpenMesh
|
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