00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 # ifndef shape_mesher3d_hpp
00012 # define shape_mesher3d_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 TMPL1 template<class V>
00021 # define SELF mesher3d<C,V,Cell>
00022
00023 namespace mmx { namespace shape {
00024
00025 class mesher3d_def {};
00026
00027 template<class C,class V>
00028 struct use< mesher3d_def,C,V> {
00029
00030 template<class POINT, class CELL> static void
00031 edge_points(POINT* edges, const POINT* points, const CELL* cl, int cubeindex) {
00032
00033
00034
00035
00036 if (marching_cube_edge_table[cubeindex] == 0) return ;
00037
00038 if (marching_cube_edge_table[cubeindex] & 1)
00039 cl->point(edges[0], points[0],points[1]);
00040 if (marching_cube_edge_table[cubeindex] & 2)
00041 cl->point(edges[1], points[1],points[2]);
00042 if (marching_cube_edge_table[cubeindex] & 4)
00043 cl->point(edges[2], points[2],points[3]);
00044 if (marching_cube_edge_table[cubeindex] & 8)
00045 cl->point(edges[3], points[3],points[0]);
00046 if (marching_cube_edge_table[cubeindex] & 16)
00047 cl->point(edges[4], points[4],points[5]);
00048 if (marching_cube_edge_table[cubeindex] & 32)
00049 cl->point(edges[5], points[5],points[6]);
00050 if (marching_cube_edge_table[cubeindex] & 64)
00051 cl->point(edges[6], points[6],points[7]);
00052 if (marching_cube_edge_table[cubeindex] & 128)
00053 cl->point(edges[7], points[7],points[4]);
00054 if (marching_cube_edge_table[cubeindex] & 256)
00055 cl->point(edges[8], points[0],points[4]);
00056 if (marching_cube_edge_table[cubeindex] & 512)
00057 cl->point(edges[9], points[1],points[5]);
00058 if (marching_cube_edge_table[cubeindex] & 1024)
00059 cl->point(edges[10], points[2],points[6]);
00060 if (marching_cube_edge_table[cubeindex] & 2048)
00061 cl->point(edges[11], points[3],points[7]);
00062 }
00063 };
00064
00065
00066 template<class C,class V=default_env, class Cell=cell3d<C,V> >
00067 struct mesher3d : public PROCESS_OF(V)
00068 {
00069 typedef subdivision<C,V,Cell> Subdivisor;
00070
00071 typedef Cell Input;
00072 typedef typename use<mesh3d_def,C,V>::Mesh Output;
00073 typedef use<topology3d_def,C,V> Topology;
00074
00075 typedef typename Output::Point Point;
00076 typedef typename Output::Edge Edge;
00077
00078 mesher3d(double e1= 0.1, double e2=0.01);
00079 ~mesher3d(void) ;
00080
00081 void set_input (Cell* cl) { m_input= cl; }
00082
00083 void set_smoothness(double e) { m_smooth = e; }
00084 void set_precision (double e) { m_prec = e; }
00085
00086 double get_smoothness(void) { return m_smooth; }
00087 double get_precision (void) { return m_prec; }
00088
00089
00090 Input* get_input (void) { return m_input; }
00091 Output* get_output (void) { return m_output; }
00092
00093 void run(void);
00094 void clear(void);
00095
00096 private:
00097 double m_smooth ;
00098 double m_prec ;
00099
00100 Cell* m_input;
00101 Output* m_output;
00102
00103 };
00104
00105 TMPL SELF::mesher3d(double e1, double e2): m_smooth(e1), m_prec(e2)
00106 {
00107 m_output = new Output;
00108 }
00109
00110 TMPL SELF::~mesher3d(void) {
00111 delete m_output;
00112 }
00113
00114 TMPL void SELF::run(void) {
00115
00116 std::cout<< ">> Prec "<< m_smooth <<" " << m_prec<<"\n";
00117
00118 Subdivisor* sbd = new Subdivisor(m_smooth,m_prec);
00119 sbd->set_input(this->get_input());
00120 sbd->run();
00121
00122 std::cout<< ">> leaves = "<< sbd->get_output()->m_leaves.size()<<"\n";
00123
00124 typedef dualize<C,V,Cell> Dualize;
00125 Dualize* dl = new Dualize;
00126 dl->set_input(sbd->get_output());
00127 dl->run();
00128
00129 std::cout<< "\n>> Cells = "<< sbd->get_output()->m_leaves.size()<<"\n";
00130 std::cout<< ">> Dual edges = "<< dl->get_output()->m_edges.size()/2<<"\n";
00131 std::cout<< ">> Dual faces = "<< dl->get_output()->m_faces.size()/4<<"\n";
00132 std::cout<< ">> Dual cells = "<< dl->get_output()->m_cells.size()/8<<"\n";
00133
00134
00135 Point points[8];
00136 Point edges[12];
00137 C values[8];
00138 int idx;
00139
00140 for(unsigned i=0; i< dl->get_output()->m_edges.size(); i+=2) {
00141
00142 Cell* c1= dl->get_output()->m_edges[i];
00143 Cell* c2= dl->get_output()->m_edges[i+1];
00144
00145
00146
00147
00148
00149
00150 if (c1 != c2) {
00151 C xm=std::max(c1->xmin(),c2->xmin()), xM=std::min(c1->xmax(),c2->xmax()),
00152 ym=std::max(c1->ymin(),c2->ymin()), yM=std::min(c1->ymax(),c2->ymax()),
00153 zm=std::max(c1->zmin(),c2->zmin()), zM=std::min(c1->zmax(),c2->zmax());
00154
00155 if (zm == zM) {
00156 points[0].x()= xm; points[0].y()=ym; points[0].z()=zm; values[0]= c1->value(xm,ym,zm);
00157 points[1].x()= xM; points[1].y()=ym; points[1].z()=zm; values[1]= c1->value(xM,ym,zm);
00158 points[2].x()= xM; points[2].y()=yM; points[2].z()=zm; values[2]= c1->value(xM,yM,zm);
00159 points[3].x()= xm; points[3].y()=yM; points[3].z()=zm; values[3]= c1->value(xm,yM,zm);
00160
00161
00162 if(c1->is_active()) {
00163 for(unsigned j=4; j<8; j++) {
00164 points[j] = c1->center();
00165 values[j] = c1->center_value();
00166 }
00167
00168 idx = marching_cube::index(values);
00169
00170 use<mesher3d_def,C,V>::edge_points(edges, points, c1, idx);
00171 marching_cube::polygonize(*this->get_output(), edges, idx);
00172 }
00173
00174 if (c2->is_active()) {
00175 for(unsigned j=4; j<8; j++) {
00176 points[j] = c2->center();
00177 values[j] = c2->center_value();
00178 }
00179
00180 idx = marching_cube::index(values);
00181
00182 use<mesher3d_def,C,V>::edge_points(edges, points, c2, idx);
00183 marching_cube::polygonize(*this->get_output(), edges, idx);
00184 }
00185
00186 } else if (ym == yM) {
00187 points[0].x()= xm; points[0].y()=ym; points[0].z()=zm; values[0]= c1->value(xm,ym,zm);
00188 points[1].x()= xM; points[1].y()=ym; points[1].z()=zm; values[1]= c1->value(xM,ym,zm);
00189 points[2].x()= xM; points[2].y()=ym; points[2].z()=zM; values[2]= c1->value(xM,ym,zM);
00190 points[3].x()= xm; points[3].y()=ym; points[3].z()=zM; values[3]= c1->value(xm,ym,zM);
00191
00192
00193 if(c1->is_active()) {
00194 for(unsigned j=4; j<8; j++) {
00195 points[j] = c1->center();
00196 values[j] = c1->center_value();
00197 }
00198
00199 idx = marching_cube::index(values);
00200
00201 use<mesher3d_def,C,V>::edge_points(edges, points, c1, idx);
00202 marching_cube::polygonize(*this->get_output(), edges, idx);
00203
00204 }
00205
00206 if(c2->is_active()) {
00207 for(unsigned j=4; j<8; j++) {
00208 points[j] = c2->center();
00209 values[j] = c2->center_value();
00210 }
00211 idx = marching_cube::index(values);
00212
00213 use<mesher3d_def,C,V>::edge_points(edges, points, c2, idx);
00214 marching_cube::polygonize(*this->get_output(), edges, idx);
00215
00216 }
00217 } else if (xm == xM ) {
00218 points[0].x()= xm; points[0].y()=ym; points[0].z()=zm; values[0]= c1->value(xm,ym,zm);
00219 points[1].x()= xm; points[1].y()=yM; points[1].z()=zm; values[1]= c1->value(xm,yM,zm);
00220 points[2].x()= xm; points[2].y()=yM; points[2].z()=zM; values[2]= c1->value(xm,yM,zM);
00221 points[3].x()= xm; points[3].y()=ym; points[3].z()=zM; values[3]= c1->value(xm,ym,zM);
00222
00223
00224 if(c1->is_active()) {
00225 for(unsigned j=4; j<8; j++) {
00226 points[j] = c1->center();
00227 values[j] = c1->center_value();
00228 }
00229
00230 idx = marching_cube::index(values);
00231
00232 use<mesher3d_def,C,V>::edge_points(edges, points, c1, idx);
00233 marching_cube::polygonize(*this->get_output(), edges, idx);
00234 }
00235
00236
00237 if(c2->is_active()) {
00238 for(unsigned j=4; j<8; j++) {
00239 points[j] = c2->center();
00240 values[j] = c2->center_value();
00241 }
00242 idx = marching_cube::index(values);
00243
00244 use<mesher3d_def,C,V>::edge_points(edges, points, c2, idx);
00245 marching_cube::polygonize(*this->get_output(), edges, idx);
00246 }
00247
00248 }
00249 }
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305 }
00306 }
00307
00308
00309 TMPL void SELF::clear(void) {
00310 this->output()->clear();
00311 }
00312
00313 } ;
00314 } ;
00315
00316 # undef TMPL
00317 # undef TMPL1
00318 # undef Shape
00319 # undef Graphic
00320 # undef SELF
00321 # endif