- Main Page
- Modules
- Namespaces
- Classes
- Files
- Related Pages

- File List
- File Members

# Tools/Subdivider/Adaptive/Composite/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.2 $
    00027 //   $Date: 2005-12-21 13:58:54 $
    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