shape_doc 0.1
/Users/mourrain/Devel/mmx/shape/include/shape/subdivision.hpp
Go to the documentation of this file.
00001 /*****************************************************************************
00002  * M a t h e m a g i x
00003  *****************************************************************************
00004  * Bernard Mourrain
00005  *****************************************************************************
00006  *               Copyright (C) 2011 INRIA Sophia-Antipolis
00007  *****************************************************************************
00008  * Comments :
00009  ****************************************************************************/
00010 
00011 # ifndef shape_subdivision_surface_hpp_H
00012 # define shape_subdivision_surface_hpp_H
00013 
00014 # include <shape/graphic.hpp>
00015 # include <shape/vertex.hpp>
00016 # include <shape/edge.hpp>
00017 # include <shape/face.hpp>
00018 # include <shape/kdtree.hpp>
00019 # include <shape/list.hpp>
00020 # include <shape/topology.hpp>
00021 # include <shape/algebraic_curve.hpp>
00022 # include <shape/surface_algebraic.hpp>
00023 # include <shape/cell.hpp>
00024 # include <shape/kdtree_cell.hpp>
00025 # include <shape/cell3d_algebraic_curve.hpp>
00026 # include <shape/cell3d_surface_algebraic.hpp>
00027 # include <shape/cell3d_list.hpp>
00028 # include <algorithm>
00029 
00030 # define TMPL  template<class C,class V,  class SURFACE, class Cell>
00031 # define TMPL1 template<class K>
00032 # define SELF  subdivision<C,V,SURFACE,Cell> 
00033 
00034 namespace mmx {
00035 namespace shape {
00036 
00037 TMPL struct subdivision;
00038 
00039 template <class C> class surface ;
00040 template <class Object, class CELL> class node;
00041 template <class Object, class CELL> class kdtree;
00042 
00043 //--------------------------------------------------------------------
00044 struct subdivision_def {};
00045 
00046 template<> struct use<subdivision_def, default_env>
00047   :public use<topology_def> 
00048   ,public use<cell3d_def> 
00049   ,public use<surface_def> 
00050 {
00051   typedef cell<double> Cell;
00052 
00053   template<class Self, class CELL>
00054   static bool is_active(Self* self, CELL* cl) {
00055     return cl->is_active();
00056   }
00057 
00058   template<class Self, class CELL>
00059   static bool is_regular(Self* self, CELL* cl) {
00060     return cl->is_regular();
00061   }
00062 
00063   template<class Out, class CELL>  static void
00064   process_regular(Out* self, CELL* cl) {
00065     // put in the leaves and will be treated at the end
00066     self->m_leaves <<cl;
00067     //    return true; 
00068   }
00069 
00070   template<class Out, class CELL>  static void
00071   process_singular(Out* self, CELL* cl) {
00072     //    return true; 
00073   }
00074 
00075   template<class CI, class CO>  static int
00076   subdivide_cell(CI* cl, CO*& left, CO*& right) {
00077     typedef typename CO::CellBase CellBase;
00078     int v; double s;
00079     cl->split_position(v,s);
00080     cl->subdivide((CellBase*&)left,(CellBase*&)right,v,s);
00081     return v;
00082   }
00083 
00084   template<class Out, class CELL, class Node>  static unsigned 
00085   subdivide_node(Out* self, CELL* cl, Node * node) {
00086     CELL * left=0, * right=0;
00087     int v=subdivide_cell(cl,left,right);
00088     node->m_left = new Node(node, left,  Node::LEFT , v) ; self->m_nodes << node->m_left ;
00089     node->m_right= new Node(node, right, Node::RIGHT, v) ; self->m_nodes << node->m_right;
00090     self->m_map[node->m_left->get_cell()]= node->m_left;
00091     self->m_map[node->m_right->get_cell()]= node->m_right;
00092     return v ;
00093   }
00094 };
00095 
00096 //--------------------------------------------------------------------  
00097 template<class C, class V, class Shape=typename SHAPE_OF(V), class Cell=cell<C,V> >
00098 class subdivision {
00099 public:
00100 
00101   typedef C                                  Scalar;
00102   typedef typename Cell::BoundingBox         BoundingBox;
00103 
00104   typedef node<Shape*, Cell*>                Node;
00105   typedef Cell                               Input;
00106   typedef kdtree_cell<Shape,Cell>            Output;
00107   
00108   subdivision(double e1= 0.1, double e2=0.01);
00109 
00110   ~subdivision(void) ;
00111   
00112   //  Node* root() {return m_output->m_tree.root();}
00113   
00114   Input*  input  (void)     { return m_input; }
00115   Output* output (void)     { return m_output; }
00116 
00117   void    set_input(Cell* bx);
00118 
00119   void    set_precision (double);
00120   void    set_smoothness(double);
00121 
00122   double  get_precision (void) const { return m_minprec ; }
00123   double  get_smoothness(void) const { return m_maxprec ; }
00124 
00125   void run(void);
00126 
00128   virtual void clear();
00129 
00130   //private:
00131   double              m_maxprec ;
00132   double              m_minprec ;
00133   
00134 private:
00135   Cell*               m_input;
00136 
00137   Output*             m_output;
00138 };
00139 //--------------------------------------------------------------------
00140 TMPL SELF::subdivision(double e1, double e2): m_maxprec(e1), m_minprec(e2)
00141 { 
00142   m_output = new Output;
00143 }
00144 //--------------------------------------------------------------------
00145 TMPL SELF::~subdivision(void) {
00146   delete m_output;
00147 }
00148 //--------------------------------------------------------------------
00149 TMPL void SELF::set_input(Cell* c0)
00150 { 
00151   Node* root = this->output()->root();
00152   root->set_cell(c0);
00153   m_output->m_nodes.push_back(root) ;
00154 }
00155 //--------------------------------------------------------------------
00156 TMPL void SELF::set_smoothness(double eps) {
00157   m_maxprec = eps;
00158 }
00159 //--------------------------------------------------------------------
00160 TMPL void SELF::set_precision(double eps) {
00161   m_minprec = eps;
00162 }
00163 //--------------------------------------------------------------------
00164 TMPL void SELF::clear() {
00165 
00166 }
00167 //--------------------------------------------------------------------
00168 TMPL void SELF::run() {
00169 
00170  typedef use<subdivision_def,V> ENV;
00171 
00172  double maxsz = this->get_smoothness()*this->output()->root()->get_cell()->size();
00173  double minsz = this->get_precision()*this->output()->root()->get_cell()->size();
00174     
00175  while(!this->output()->m_nodes.empty()) {
00176    Node* node = this->output()->m_nodes.front() ;
00177    Cell* cl = node->get_cell() ;
00178    
00179    if(ENV::is_active(this,cl)) {
00180      if(cl->size() > maxsz) 
00181        { 
00182          ENV::subdivide_node(this->output(), cl, node) ;
00183        } 
00184      else if(ENV::is_regular(this,cl)) 
00185        { 
00186          ENV::process_regular(this->output(),cl) ;
00187        } 
00188      else if(cl->size() > minsz ) 
00189        { 
00190          ENV::subdivide_node(this->output(), cl, node) ;
00191        } 
00192      else { 
00193        ENV::process_singular(this->output(), cl);
00194      }
00195    }
00196    this->output()->m_nodes.pop_front() ;
00197  }
00198 }
00199 
00200 
00201 //====================================================================
00202 } ; // namespace shape
00203 } ; // namespace mmx
00204 //====================================================================
00205 # undef TMPL1
00206 # undef TMPL
00207 # undef SELF 
00208 # endif