shape_doc 0.1
|
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