00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 # ifndef shape_isosurface_hpp
00012 # define shape_isosurface_hpp
00013
00014 # include <shape/subdivision.hpp>
00015 # include <shape/topology3d.hpp>
00016 # include <shape/dualize3d.hpp>
00017 # include <shape/polygonizer.hpp>
00018
00019 # define TMPL template<class C,class V,class Cell>
00020 # define SELF isosurface<C,V,Cell>
00021
00022 namespace mmx { namespace shape {
00023
00024 struct isovalue_env {};
00025
00026 template<class C> struct use<subdivision_def,C,isovalue_env>
00027 {
00028 template<class Self, class CELL>
00029 static bool is_not_out(Self* self, CELL* cl) {
00030 double m = cl ->lower_bound(),
00031 M = cl ->upper_bound();
00032 return (m <=this->m_max && M >= this-> m_min);
00033 }
00034
00035 template<class Self, class CELL>
00036 static bool is_in(Self* self, CELL* cl) {
00037 return cl->is_regular();
00038 }
00039
00040
00041 template<class Out, class CELL> static void
00042 process_regular(Out* out, CELL* cl) {
00043
00044 out->m_leaves <<cl;
00045 }
00046
00047 template<class Out, class CELL> static void
00048 process_singular(Out* out, CELL* cl) {
00049
00050 }
00051
00052 };
00053
00054
00055 template<class C,class V=isosurface_env, class Cell=cell3d<C,V> >
00056 struct isosurface : public PROCESS_OF(V)
00057 {
00058 typedef Cell Input;
00059 typedef tpl3d<C,V> Output;
00060 typedef typename Output::Point Point;
00061 typedef typename Output::Edge Edge;
00062 typedef typename Output::Face Face;
00063 typedef typename Cell::BoundingBox BoundingBox;
00064
00065 isosurface(double m=0, double M=1, double e1= 0.1, double e2=0.01);
00066 ~isosurface(void) ;
00067
00068 void set_input (Cell* cl) { m_input= cl; }
00069 Input* get_input (void) { return m_input; }
00070
00071 Output* get_output (void) { return m_output; }
00072
00073 void set_smoothness(double e) { m_smooth = e; }
00074 void set_precision (double e) { m_prec = e; }
00075
00076 double get_smoothness(void) { return m_smooth; }
00077 double get_precision (void) { return m_prec; }
00078
00079 void run(void);
00080 void clear(void);
00081
00082 private:
00083 double m_smooth ;
00084 double m_prec ;
00085
00086 double m_min, m_max;
00087 Cell* m_input;
00088 Output* m_output;
00089
00090 };
00091
00092 TMPL SELF::isosurface(double m, double M, double e1, double e2):
00093 m_min(m), m_max(M), m_smooth(e1), m_prec(e2)
00094 {
00095 m_output = new Output;
00096 }
00097
00098 TMPL SELF::~isosurface(void) {
00099 delete m_output;
00100 }
00101
00102 TMPL void SELF::run(void) {
00103
00104 typedef subdivision<C,V,Cell> Subdivisor;
00105 Subdivisor* sbd = new Subdivisor(m_smooth,m_prec);
00106 sbd->set_input(this->input());
00107 sbd->run();
00108
00109 std::cout<< ">> leaves = "<< sbd->get_output()->m_leaves.size()<<"\n";
00110
00111 typedef dualize<C,V,Cell> Dualize;
00112 Dualize* dl = new Dualize;
00113 dl->set_input(sbd->get_output());
00114 dl->run();
00115
00116 std::cout<< "\nCells = "<< sbd->get_output()->m_leaves.size()<<"\n";
00117 std::cout<< "Dual edges = "<< dl->get_output()->m_edges.size()/2<<"\n";
00118 std::cout<< "Dual faces = "<< dl->get_output()->m_faces.size()/4<<"\n";
00119 std::cout<< "Dual cells = "<< dl->get_output()->m_cells.size()/8<<"\n";
00120
00121 typedef polygonizer<C,V,Seq<Cell*> > Polygonizer;
00122 Polygonizer* plg = new Polygonizer;
00123 plg->set_input(&dl->get_output()->m_cells);
00124 plg->set_output(this->get_output());
00125 plg->run(m_n,m_min,m_max);
00126
00127 }
00128
00129
00130 TMPL void SELF::clear(void) {
00131 this->output()->clear();
00132 }
00133
00134
00135
00136 } ;
00137 } ;
00138
00139 # undef TMPL
00140 # undef Shape
00141 # undef Viewer
00142 # undef Graphic
00143 # undef SELF
00144 # endif