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

RuleInterfaceT.hh

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

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