OpenMesh
OpenMesh/Tools/Subdivider/Adaptive/Composite/RuleInterfaceT.hh
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 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines