00001
00002
00003
00004
00005
00006
00007
00008
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/bcell.hpp>
00022 # include <shape/kdtree_cell.hpp>
00023 # include <algorithm>
00024
00025 # define TMPL template<class C,class V,class Cell>
00026 # define TMPL1 template<class K>
00027 # define SELF subdivision<C,V,Cell>
00028
00029 namespace mmx {
00030 namespace shape {
00031
00032 TMPL class subdivision;
00033
00034 template <class C> class surface ;
00035 template <class CELL> class node;
00036 template <class CELL> class kdtree;
00037
00038
00039 struct subdivision_def {};
00040
00041 template<class C> struct use<subdivision_def, C, default_env>
00042 :public use<topology_def>
00043 {
00044 typedef bcell<double> Cell;
00045
00046 template<class Self, class CELL>
00047 static bool is_not_out(Self* self, CELL* cl) {
00048 return cl->is_active();
00049 }
00050
00051 template<class Self, class CELL>
00052 static bool is_regular(Self* self, CELL* cl) {
00053 return cl->is_regular();
00054 }
00055
00056 template<class Out, class CELL> static void
00057 process_regular(Out* out, CELL* cl) {
00058
00059 out->m_leaves <<cl;
00060
00061
00062 }
00063
00064 template<class Out, class CELL> static void
00065 process_singular(Out* out, CELL* cl) {
00066
00067 }
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078 template<class Out, class CELL, class Node> static unsigned
00079 subdivide_node(Out* self, CELL* cl, Node * node) {
00080 typedef typename CELL::CellBase CellBase;
00081 CELL * left=0, * right=0;
00082 int v; double s;
00083 cl->split_position(v,s);
00084 cl->subdivide((CellBase*&)left,(CellBase*&)right,v,s);
00085
00086 node->m_left = new Node(node, left, Node::LEFT , v) ; self->m_nodes << node->m_left ;
00087 node->m_right= new Node(node, right, Node::RIGHT, v) ; self->m_nodes << node->m_right;
00088 self->m_map[node->m_left->get_cell()] = node->m_left;
00089 self->m_map[node->m_right->get_cell()] = node->m_right;
00090 return v ;
00091 }
00092 };
00093
00094
00095 template<class C, class V, class Cell=cell<C,V> >
00096 class subdivision {
00097 public:
00098
00099 typedef C Scalar;
00100 typedef typename Cell::BoundingBox BoundingBox;
00101
00102 typedef node<Cell*> Node;
00103 typedef Cell Input;
00104 typedef kdtree_cell<Cell> Output;
00105
00106 subdivision(double e1= 0.1, double e2=0.001);
00107
00108 ~subdivision(void) ;
00109
00110
00111
00112 void set_input(Cell* bx);
00113 Input* get_input (void) { return m_input; }
00114
00115 Output* get_output (void) { return m_output; }
00116
00117 void set_precision (double);
00118 void set_smoothness(double);
00119
00120 double get_precision (void) const { return m_minprec ; }
00121 double get_smoothness(void) const { return m_maxprec ; }
00122
00123 void run(void);
00124
00125
00126 virtual void clear();
00127
00128
00129 double m_maxprec ;
00130 double m_minprec ;
00131
00132 private:
00133 Cell* m_input;
00134 Output* m_output;
00135 };
00136
00137 TMPL SELF::subdivision(double e1, double e2): m_maxprec(e1), m_minprec(e2)
00138 {
00139 m_output = new Output;
00140 }
00141
00142 TMPL SELF::~subdivision(void) {
00143 delete m_output;
00144 }
00145
00146 TMPL void SELF::set_input(Cell* c0)
00147 {
00148 Node* root = this->get_output()->root();
00149 root->set_cell(c0);
00150 m_output->m_nodes.push_back(root) ;
00151 }
00152
00153 TMPL void SELF::set_smoothness(double eps) {
00154 m_maxprec = eps;
00155 }
00156
00157 TMPL void SELF::set_precision(double eps) {
00158 m_minprec = eps;
00159 }
00160
00161 TMPL void SELF::clear() {
00162
00163 }
00164
00165 TMPL void SELF::run() {
00166
00167 typedef use<subdivision_def,C,V> USE;
00168
00169 double maxsz = this->get_smoothness()*this->get_output()->root()->get_cell()->size();
00170 double minsz = this->get_precision()*this->get_output()->root()->get_cell()->size();
00171
00172 std::cout<<"Size :"<< maxsz<< " "<<minsz<<std::endl;
00173
00174 while(!this->get_output()->m_nodes.empty()) {
00175 Node* node = this->get_output()->m_nodes.front() ;
00176 Cell* cl = node->get_cell() ;
00177
00178 if( USE::is_not_out(this,cl)) {
00179 if(cl->size() > maxsz)
00180 {
00181 USE::subdivide_node(this->get_output(), cl, node) ;
00182 }
00183 else if(USE::is_regular(this,cl))
00184 {
00185 USE::process_regular(this->get_output(),cl) ;
00186 }
00187 else if(cl->size() > minsz )
00188 {
00189 USE::subdivide_node(this->get_output(), cl, node) ;
00190 }
00191 else {
00192 std::cout<<"Singular cell"<<std::endl;
00193 USE::process_singular(this->get_output(), cl);
00194 }
00195 }
00196 this->get_output()->m_nodes.pop_front() ;
00197 }
00198 }
00199
00200
00201
00202 } ;
00203 } ;
00204
00205 # undef TMPL1
00206 # undef TMPL
00207 # undef SELF
00208 # endif