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: 362 $ * 00038 * $Date: 2011-01-26 10:21:12 +0100 (Mi, 26 Jan 2011) $ * 00039 * * 00040 \*===========================================================================*/ 00041 00042 00043 //============================================================================= 00044 // 00045 // CLASS RuleInterfaceT 00046 // 00047 //============================================================================= 00048 00049 #ifndef OPENMESH_SUBDIVIDER_ADAPTIVE_RULEINTERFACET_HH 00050 #define OPENMESH_SUBDIVIDER_ADAPTIVE_RULEINTERFACET_HH 00051 00052 00053 //== INCLUDES ================================================================= 00054 00055 #include <string> 00056 #include <OpenMesh/Tools/Subdivider/Adaptive/Composite/CompositeTraits.hh> 00057 00058 //== NAMESPACE ================================================================ 00059 00060 namespace OpenMesh { // BEGIN_NS_OPENMESH 00061 namespace Subdivider { // BEGIN_NS_SUBDIVIDER 00062 namespace Adaptive { // BEGIN_NS_ADAPTIVE 00063 00064 00065 //== FORWARDS ================================================================= 00066 00067 template <typename M> class CompositeT; 00068 template <typename M> class RuleInterfaceT; 00069 00070 //== CLASS DEFINITION ========================================================= 00071 00072 00073 // ---------------------------------------------------------------------------- 00074 00080 template < typename R > 00081 struct RuleHandleT : public BaseHandle 00082 { 00083 explicit RuleHandleT(int _idx=-1) : BaseHandle(_idx) {} 00084 typedef R Rule; 00085 00086 operator bool() const { return is_valid(); } 00087 00088 }; 00089 00093 #define COMPOSITE_RULE( classname, mesh_type ) \ 00094 protected:\ 00095 friend class CompositeT<mesh_type>; \ 00096 public: \ 00097 const char *type() const { return #classname; } \ 00098 typedef classname<mesh_type> Self; \ 00099 typedef RuleHandleT< Self > Handle 00100 00101 00102 // ---------------------------------------------------------------------------- 00106 template <typename M> class RuleInterfaceT 00107 { 00108 public: 00109 00110 typedef M Mesh; 00111 typedef RuleInterfaceT<M> Self; 00112 typedef RuleHandleT< Self > Rule; 00113 00114 typedef typename M::Scalar scalar_t; 00115 00116 protected: 00117 00119 RuleInterfaceT(Mesh& _mesh) : mesh_(_mesh) {}; 00120 00121 public: 00122 00124 virtual ~RuleInterfaceT() {}; 00125 00126 00129 virtual const char *type() const = 0; 00130 00131 public: 00132 00134 00135 00136 virtual void raise(typename M::FaceHandle& _fh, state_t _target_state) 00137 { 00138 if (mesh_.data(_fh).state() < _target_state) { 00139 update(_fh, _target_state); 00140 mesh_.data(_fh).inc_state(); 00141 } 00142 } 00143 00144 virtual void raise(typename M::EdgeHandle& _eh, state_t _target_state) 00145 { 00146 if (mesh_.data(_eh).state() < _target_state) { 00147 update(_eh, _target_state); 00148 mesh_.data(_eh).inc_state(); 00149 } 00150 } 00151 00152 virtual void raise(typename M::VertexHandle& _vh, state_t _target_state) 00153 { 00154 if (mesh_.data(_vh).state() < _target_state) { 00155 update(_vh, _target_state); 00156 mesh_.data(_vh).inc_state(); 00157 } 00158 } 00160 00161 void update(typename M::FaceHandle& _fh, state_t _target_state) 00162 { 00163 typename M::FaceHandle opp_fh; 00164 00165 while (mesh_.data(_fh).state() < _target_state - 1) { 00166 prev_rule()->raise(_fh, _target_state - 1); 00167 } 00168 00169 // Don't use unflipped / unfinal faces!!! 00170 if (subdiv_type() == 3) { 00171 00172 if (mesh_.face_handle(mesh_.opposite_halfedge_handle(mesh_.halfedge_handle(_fh))).is_valid()) { 00173 00174 while (!mesh_.data(_fh).final()) { 00175 00176 opp_fh = mesh_.face_handle(mesh_.opposite_halfedge_handle(mesh_.halfedge_handle(_fh))); 00177 00178 assert (mesh_.data(_fh).state() >= 00179 mesh_.data(opp_fh).state()); 00180 00181 // different states: raise other face 00182 if (mesh_.data(_fh).state() > mesh_.data(opp_fh).state()){ 00183 00184 // raise opposite face 00185 prev_rule()->raise(opp_fh, _target_state - 1); 00186 } 00187 00188 else { 00189 00190 // equal states 00191 00192 // flip edge 00193 // typename M::EdgeHandle eh(mesh_.edge_handle(mesh_.halfedge_handle(_fh))); 00194 00195 // if (mesh_.is_flip_ok(eh)) { 00196 00197 // std::cout << "Flipping Edge...\n"; 00198 00199 // mesh_.flip(eh); 00200 00201 // mesh_.data(_fh).set_final(); 00202 // mesh_.data(opp_fh).set_final(); 00203 // } 00204 00205 // else { 00206 00207 // std::cout << "Flip not okay.\n"; 00208 // } 00209 } 00210 } 00211 } 00212 00213 else { 00214 00215 // mesh_.data(_fh).set_final(); 00216 } 00217 00218 // std::cout << "Raising Face to Level " 00219 // << _target_state 00220 // << " with " 00221 // << type() 00222 // << ".\n"; 00223 00224 } 00225 00226 assert( subdiv_type() != 4 || 00227 mesh_.data(_fh).final() || 00228 _target_state%n_rules() == (subdiv_rule()->number() + 1)%n_rules() ); 00229 00230 typename M::FaceEdgeIter fe_it; 00231 typename M::FaceVertexIter fv_it; 00232 typename M::EdgeHandle eh; 00233 typename M::VertexHandle vh; 00234 00235 std::vector<typename M::FaceHandle> face_vector; 00236 face_vector.clear(); 00237 00238 if (_target_state > 1) { 00239 00240 for (fe_it = mesh_.fe_iter(_fh); fe_it; ++fe_it) { 00241 00242 eh = fe_it.handle(); 00243 prev_rule()->raise(eh, _target_state - 1); 00244 } 00245 00246 for (fv_it = mesh_.fv_iter(_fh); fv_it; ++fv_it) { 00247 00248 vh = fv_it.handle(); 00249 prev_rule()->raise(vh, _target_state - 1); 00250 } 00251 } 00252 } 00253 00254 00255 void update(typename M::EdgeHandle& _eh, state_t _target_state) 00256 { 00257 state_t state(mesh_.data(_eh).state()); 00258 00259 // raise edge to correct state 00260 if (state + 1 < _target_state && _target_state > 0) { 00261 00262 prev_rule()->raise(_eh, _target_state - 1); 00263 } 00264 00265 typename M::VertexHandle vh; 00266 typename M::FaceHandle fh; 00267 00268 if (_target_state > 1) 00269 { 00270 vh = mesh_.to_vertex_handle(mesh_.halfedge_handle(_eh, 0)); 00271 prev_rule()->raise(vh, _target_state - 1); 00272 00273 vh = mesh_.to_vertex_handle(mesh_.halfedge_handle(_eh, 1)); 00274 prev_rule()->raise(vh, _target_state - 1); 00275 00276 fh = mesh_.face_handle(mesh_.halfedge_handle(_eh, 0)); 00277 if (fh.is_valid()) 00278 prev_rule()->raise(fh, _target_state - 1); 00279 00280 fh = mesh_.face_handle(mesh_.halfedge_handle(_eh, 1)); 00281 if (fh.is_valid()) 00282 prev_rule()->raise(fh, _target_state - 1); 00283 } 00284 } 00285 00286 00287 void update(typename M::VertexHandle& _vh, state_t _target_state) { 00288 00289 state_t state(mesh_.data(_vh).state()); 00290 00291 // raise vertex to correct state 00292 if (state + 1 < _target_state) 00293 { 00294 prev_rule()->raise(_vh, _target_state - 1); 00295 } 00296 00297 std::vector<typename M::HalfedgeHandle> halfedge_vector; 00298 halfedge_vector.clear(); 00299 00300 typename M::VertexOHalfedgeIter voh_it; 00301 typename M::EdgeHandle eh; 00302 typename M::FaceHandle fh; 00303 00304 if (_target_state > 1) 00305 { 00306 00307 for (voh_it = mesh_.voh_iter(_vh); voh_it; ++voh_it) { 00308 halfedge_vector.push_back(voh_it.handle()); 00309 } 00310 00311 while ( !halfedge_vector.empty() ) { 00312 eh = mesh_.edge_handle(halfedge_vector.back()); 00313 halfedge_vector.pop_back(); 00314 00315 prev_rule()->raise(eh, _target_state - 1); 00316 } 00317 00318 for (voh_it = mesh_.voh_iter(_vh); voh_it; ++voh_it) { 00319 halfedge_vector.push_back(voh_it.handle()); 00320 } 00321 00322 while ( !halfedge_vector.empty() ) { 00323 fh = mesh_.face_handle(halfedge_vector.back()); 00324 halfedge_vector.pop_back(); 00325 00326 if (fh.is_valid()) 00327 prev_rule()->raise(fh, _target_state - 1); 00328 } 00329 } 00330 } 00331 00332 public: 00333 00334 00336 int subdiv_type() const { return subdiv_type_; } 00337 00338 00340 int number() const { return number_; } 00341 00343 00344 00346 virtual void set_coeff( scalar_t _coeff ) { coeff_ = _coeff; } 00347 00349 scalar_t coeff() const { return coeff_; } 00350 00352 00353 protected: 00354 00355 void set_prev_rule(Self*& _p) { prev_rule_ = _p; } 00356 Self* prev_rule() { return prev_rule_; } 00357 00358 void set_subdiv_rule(Self*& _n) { subdiv_rule_ = _n; } 00359 Self* subdiv_rule() { return subdiv_rule_; } 00360 00361 void set_number(int _n) { number_ = _n; } 00362 00363 void set_n_rules(int _n) { n_rules_ = _n; } 00364 int n_rules() { return n_rules_; } 00365 00366 void set_subdiv_type(int _n) 00367 { assert(_n == 3 || _n == 4); subdiv_type_ = _n; } 00368 00369 friend class CompositeT<M>; 00370 00371 protected: 00372 00373 Mesh& mesh_; 00374 00375 private: 00376 00377 Self* prev_rule_; 00378 Self* subdiv_rule_; 00379 00380 int subdiv_type_; 00381 int number_; 00382 int n_rules_; 00383 00384 scalar_t coeff_; 00385 00386 private: // Noncopyable 00387 00388 RuleInterfaceT(const RuleInterfaceT&); 00389 RuleInterfaceT& operator=(const RuleInterfaceT&); 00390 00391 }; 00392 00393 //============================================================================= 00394 } // END_NS_ADAPTIVE 00395 } // END_NS_SUBDIVIDER 00396 } // END_NS_OPENMESH 00397 //============================================================================= 00398 #endif // OPENMESH_SUBDIVIDER_ADAPTIVE_RULEINTERFACET_HH defined 00399 //============================================================================= 00400