shape_doc 0.1
|
00001 /***************************************************************************** 00002 * M a t h e m a g i x 00003 ***************************************************************************** 00004 * Cell 00005 * 2008-03-20 00006 * Julien Wintz & Bernard Mourrain & Angelos Mantzaflaris 00007 ***************************************************************************** 00008 * Copyright (C) 2008 INRIA Sophia-Antipolis 00009 ***************************************************************************** 00010 * Comments : 00011 ****************************************************************************/ 00012 # ifndef shape_cell3d_hpp 00013 # define shape_cell3d_hpp 00014 00015 # include <shape/vertex.hpp> 00016 # include <shape/edge.hpp> 00017 # include <shape/face.hpp> 00018 # include <shape/bounding_box.hpp> 00019 # include <shape/cell.hpp> 00020 # include <shape/graph.hpp> 00021 # include <shape/topology.hpp> 00022 //# include <shape/tpl3d.hpp> 00023 # define TMPL template<class C, class V> 00024 # define TMPL1 template<class K> 00025 # define SELF cell3d<C,V> 00026 //==================================================================== 00027 namespace mmx { namespace shape { 00028 00029 TMPL struct cell3d; 00030 TMPL struct tpl3d; 00031 //-------------------------------------------------------------------- 00032 struct cell3d_def {}; 00033 template<> struct use<cell3d_def> 00034 :public use<cell_def> 00035 { 00036 typedef cell3d<double,double> Cell3d; 00037 }; 00038 00039 //-------------------------------------------------------------------- 00040 template<class C, class V=default_env> 00041 class cell3d : public bounding_box<C,V> 00042 { 00043 public: 00044 typedef topology<C,REF_OF(V)> Topology; 00045 typedef tpl3d<C,V> Topology3d; 00046 typedef typename Topology::Point Point; 00047 typedef typename Topology::Edge Edge; 00048 00049 typedef cell3d<C,V> CellBase; 00050 typedef cell<C,V> Cell; 00051 typedef typename Cell::BoundingBox BoundingBox; 00052 00053 cell3d(void) {}; 00054 cell3d(const BoundingBox& bx): BoundingBox(bx) {} ; 00055 virtual ~cell3d(void) {}; 00056 00057 virtual bool is_regular(void) = 0 ; 00058 virtual bool is_active (void) const = 0 ; 00059 virtual bool is_intersected(void) = 0 ; 00060 virtual int subdivide(SELF*& left, SELF*& right); 00061 virtual void subdivide(SELF*& left, SELF*& right, int v, double s)=0; 00062 00063 virtual void split_position(int &v, double& s) ; 00064 virtual bool insert_regular (Topology*) = 0 ; 00065 virtual bool insert_singular(Topology*) = 0 ; 00066 00067 virtual Point center(void) const { 00068 // XXX ??? 00069 return Point(this->xmax()-this->xmin(), 00070 this->ymax()-this->ymin(), 00071 this->zmax()-this->zmin()); 00072 } 00073 00074 BoundingBox boundingBox() const { return (BoundingBox)*this; } 00075 00076 00077 virtual bool topology_regular (Topology*) = 0 ; 00078 virtual void polygonise (Topology3d*) =0; 00079 00080 inline void disconnect(); 00081 inline void connect0(SELF * a, SELF * b); 00082 inline void connect1(SELF * a, SELF * b) ; 00083 inline void connect2(SELF * a, SELF * b) ; 00084 inline void join0( SELF * b) ; 00085 inline void join1( SELF * b) ; 00086 inline void join2( SELF * b) ; 00087 00088 Seq<Point *> m_boundary; 00089 Seq<Point *> m_singular ; 00090 int m_type; 00091 00092 /*Pointer to graph instance of this cell*/ 00093 gNode<cell3d*>* m_gnode; 00094 00095 /*Neighbor cells*/ 00096 Seq<cell3d *> neighbors(){ 00097 Seq<cell3d *> t; 00098 t<< s_neighbors ; 00099 t<< e_neighbors ; 00100 t<< n_neighbors ; 00101 t<< b_neighbors ; 00102 t<< w_neighbors ; 00103 t<< f_neighbors ; 00104 return t; } ; 00105 00106 Seq<cell3d *> s_neighbors ; 00107 Seq<cell3d *> e_neighbors ; 00108 Seq<cell3d *> n_neighbors ; 00109 Seq<cell3d *> w_neighbors ; 00110 Seq<cell3d *> f_neighbors ; 00111 Seq<cell3d *> b_neighbors ; 00112 00113 }; 00114 00115 //==================================================================== 00116 TMPL int 00117 SELF::subdivide(SELF*& Left, SELF*& Right) { 00118 int v; double s; 00119 this->split_position(v,s); 00120 this->subdivide(Left,Right,v,s); 00121 return v; 00122 } 00123 //==================================================================== 00124 TMPL void 00125 SELF::split_position(int& v, double& s) { 00126 double sx = (this->xmax()-this->xmin()); 00127 double sy = (this->ymax()-this->ymin()); 00128 double sz = (this->zmax()-this->zmin()); 00129 00130 if(sx<sy) 00131 if(sy<sz) { 00132 v=2; 00133 s=(this->zmax()+this->zmin())/2; 00134 } else { 00135 v=1; 00136 s=(this->ymax()+this->ymin())/2; 00137 } 00138 else 00139 if(sx<sz) { 00140 v=2; 00141 s=(this->zmax()+this->zmin())/2; 00142 } else { 00143 v=0; 00144 s=(this->xmax()+this->xmin())/2; 00145 } 00146 } 00147 00148 TMPL inline void 00149 SELF::join0(SELF * b) //left,right 00150 { 00151 this->e_neighbors << b; 00152 b->w_neighbors << this; 00153 } 00154 00155 TMPL inline void 00156 SELF::join1(SELF * b) //up,down 00157 { 00158 b->s_neighbors << this; 00159 this->n_neighbors << b; 00160 } 00161 00162 TMPL inline void 00163 SELF::join2(SELF * b) //front,back 00164 { 00165 b->f_neighbors << this; 00166 this->b_neighbors << b; 00167 } 00168 00169 TMPL inline void 00170 SELF::connect0(SELF * a, SELF * b) 00171 { 00172 int i; 00173 bool flag; 00174 00175 //copy horizontally 00176 b->e_neighbors= this->e_neighbors ; 00177 foreach(SELF* cl,b->e_neighbors) { 00178 i= cl->w_neighbors.search(this); 00179 cl->w_neighbors[i]= b; 00180 } 00181 00182 a->w_neighbors= this->w_neighbors ; 00183 foreach(SELF* cl,a->w_neighbors) { 00184 i= cl->e_neighbors.search(this); 00185 cl->e_neighbors[i]= a; 00186 } 00187 00188 //update vertically 00189 foreach(SELF* cl,this->s_neighbors) { 00190 flag=false; 00191 if ( check_overlap(cl,a,0) //) 00192 && ( check_overlap(cl,a,1) || check_overlap(cl,a,2)) ) 00193 { 00194 //assert( cl->ymax()== a->ymin() ); 00195 a->s_neighbors<< cl; 00196 i= cl->n_neighbors.search(this); 00197 cl->n_neighbors[i]= a; 00198 flag=true; 00199 } 00200 if ( check_overlap(cl,b,0) //) 00201 && ( check_overlap(cl,a,1) || check_overlap(cl,a,2)) ) 00202 { 00203 //assert( cl->ymax()== b->ymin() ); 00204 b->s_neighbors<< cl; 00205 if (!flag) 00206 { 00207 i= cl->n_neighbors.search(this); 00208 cl->n_neighbors[i]= b; 00209 } 00210 else 00211 cl->n_neighbors << b; 00212 } 00213 } 00214 foreach(SELF* cl,this->n_neighbors) { 00215 flag=false; 00216 if ( check_overlap(cl,a,0) //) 00217 && ( check_overlap(cl,a,1) || check_overlap(cl,a,2)) ) 00218 { 00219 a->n_neighbors<< cl; 00220 i= cl->s_neighbors.search(this); 00221 cl->s_neighbors[i]= a; 00222 flag=true; 00223 } 00224 if ( check_overlap(cl,b,0) //) 00225 && ( check_overlap(cl,a,1) || check_overlap(cl,a,2)) ) 00226 { 00227 b->n_neighbors<< cl; 00228 if (!flag) 00229 { 00230 i= cl->s_neighbors.search(this); 00231 cl->s_neighbors[i]= b; 00232 } 00233 else 00234 cl->s_neighbors << b; 00235 } 00236 } 00237 00238 //update depth 00239 foreach(SELF* cl,this->f_neighbors) { 00240 flag=false; 00241 if ( check_overlap(cl,a,0) //) 00242 && ( check_overlap(cl,a,1) || check_overlap(cl,a,2)) ) 00243 { 00244 //assert( cl->ymax()== a->ymin() ); 00245 a->f_neighbors<< cl; 00246 i= cl->b_neighbors.search(this); 00247 cl->b_neighbors[i]= a; 00248 flag=true; 00249 } 00250 if ( check_overlap(cl,b,0) //) 00251 && ( check_overlap(cl,a,1) || check_overlap(cl,a,2)) ) 00252 { 00253 //assert( cl->ymax()== b->ymin() ); 00254 b->f_neighbors<< cl; 00255 if (!flag) 00256 { 00257 i= cl->b_neighbors.search(this); 00258 cl->b_neighbors[i]= b; 00259 } 00260 else 00261 cl->b_neighbors << b; 00262 } 00263 } 00264 foreach(SELF* cl,this->b_neighbors) { 00265 flag=false; 00266 if ( check_overlap(cl,a,0) //) 00267 && ( check_overlap(cl,a,1) || check_overlap(cl,a,2)) ) 00268 { 00269 a->b_neighbors<< cl; 00270 i= cl->f_neighbors.search(this); 00271 cl->f_neighbors[i]= a; 00272 flag=true; 00273 } 00274 if ( check_overlap(cl,b,0) //) 00275 && ( check_overlap(cl,a,1) || check_overlap(cl,a,2)) ) 00276 { 00277 b->b_neighbors<< cl; 00278 if (!flag) 00279 { 00280 i= cl->f_neighbors.search(this); 00281 cl->f_neighbors[i]= b; 00282 } 00283 else 00284 cl->f_neighbors << b; 00285 } 00286 } 00287 } 00288 00289 TMPL inline void 00290 SELF::connect1(SELF * a, SELF * b) 00291 { 00292 int i; 00293 bool flag; 00294 00295 //copy vertically 00296 a->s_neighbors= this->s_neighbors ; 00297 foreach(SELF* cl,a->s_neighbors) { 00298 i= cl->n_neighbors.search(this); 00299 cl->n_neighbors[i]= a; 00300 } 00301 b->n_neighbors= this->n_neighbors ; 00302 foreach(SELF* cl,b->n_neighbors) { 00303 i= cl->s_neighbors.search(this); 00304 cl->s_neighbors[i]= b; 00305 } 00306 00307 //update horizontally 00308 foreach(SELF* cl,this->w_neighbors) { 00309 flag=false; 00310 if ( check_overlap(cl,a,1) //) 00311 && ( check_overlap(cl,a,0) || check_overlap(cl,a,2)) ) 00312 { 00313 //assert( cl->xmax()== a->xmin() ); 00314 a->w_neighbors<< cl; 00315 i= cl->e_neighbors.search(this); 00316 cl->e_neighbors[i]= a; 00317 flag=true; 00318 } 00319 if ( check_overlap(cl,b,1) //) 00320 && ( check_overlap(cl,a,0) || check_overlap(cl,a,2)) ) 00321 { 00322 //assert( cl->xmax()== b->xmin() ); 00323 b->w_neighbors<< cl; 00324 if (!flag) 00325 { 00326 i= cl->e_neighbors.search(this); 00327 cl->e_neighbors[i]= b; 00328 } 00329 else 00330 cl->e_neighbors << b; 00331 } 00332 } 00333 foreach(SELF* cl,this->e_neighbors) { 00334 flag=false; 00335 if ( check_overlap(cl,a,1) //) 00336 && ( check_overlap(cl,a,0) || check_overlap(cl,a,2)) ) 00337 { 00338 a->e_neighbors<< cl; 00339 i= cl->w_neighbors.search(this); 00340 cl->w_neighbors[i]= a; 00341 flag=true; 00342 } 00343 if ( check_overlap(cl,b,1) //) 00344 && ( check_overlap(cl,a,0) || check_overlap(cl,a,2)) ) 00345 { 00346 b->e_neighbors<< cl; 00347 if (!flag) 00348 { 00349 i= cl->w_neighbors.search(this); 00350 cl->w_neighbors[i]= b; 00351 } 00352 else 00353 cl->w_neighbors << b; 00354 } 00355 } 00356 00357 00358 //update depth 00359 foreach(SELF* cl,this->f_neighbors) { 00360 flag=false; 00361 if ( check_overlap(cl,a,1) //) 00362 && ( check_overlap(cl,a,0) || check_overlap(cl,a,2)) ) 00363 { 00364 //assert( cl->xmax()== a->xmin() ); 00365 a->f_neighbors<< cl; 00366 i= cl->b_neighbors.search(this); 00367 cl->b_neighbors[i]= a; 00368 flag=true; 00369 } 00370 if ( check_overlap(cl,b,1) //) 00371 && ( check_overlap(cl,a,0) || check_overlap(cl,a,2)) ) 00372 { 00373 //assert( cl->xmax()== b->xmin() ); 00374 b->f_neighbors<< cl; 00375 if (!flag) 00376 { 00377 i= cl->b_neighbors.search(this); 00378 cl->b_neighbors[i]= b; 00379 } 00380 else 00381 cl->b_neighbors << b; 00382 } 00383 } 00384 foreach(SELF* cl,this->b_neighbors) { 00385 flag=false; 00386 if ( check_overlap(cl,a,1) //) 00387 && ( check_overlap(cl,a,0) || check_overlap(cl,a,2)) ) 00388 { 00389 a->b_neighbors<< cl; 00390 i= cl->f_neighbors.search(this); 00391 cl->f_neighbors[i]= a; 00392 flag=true; 00393 } 00394 if ( check_overlap(cl,b,1) //) 00395 && ( check_overlap(cl,a,0) || check_overlap(cl,a,2)) ) 00396 { 00397 b->b_neighbors<< cl; 00398 if (!flag) 00399 { 00400 i= cl->f_neighbors.search(this); 00401 cl->f_neighbors[i]= b; 00402 } 00403 else 00404 cl->f_neighbors << b; 00405 } 00406 } 00407 } 00408 00409 //-------------------------------------------------------------------- 00410 TMPL inline void 00411 SELF::connect2(SELF * a, SELF * b) 00412 { 00413 int i; 00414 bool flag; 00415 00416 //copy vertically 00417 a->f_neighbors= this->f_neighbors ; 00418 foreach(SELF* cl,a->f_neighbors) { 00419 i= cl->b_neighbors.search(this); 00420 cl->b_neighbors[i]= a; 00421 } 00422 b->b_neighbors= this->b_neighbors ; 00423 foreach(SELF* cl,b->b_neighbors) { 00424 i= cl->f_neighbors.search(this); 00425 cl->f_neighbors[i]= b; 00426 } 00427 00428 //update horizontally 00429 foreach(SELF* cl,this->w_neighbors) { 00430 flag=false; 00431 if ( check_overlap(cl,a,2) //) 00432 && ( check_overlap(cl,a,0) || check_overlap(cl,a,1)) ) 00433 { 00434 //assert( cl->xmax()== a->xmin() ); 00435 a->w_neighbors<< cl; 00436 i= cl->e_neighbors.search(this); 00437 cl->e_neighbors[i]= a; 00438 flag=true; 00439 } 00440 if ( check_overlap(cl,b,2) //) 00441 && ( check_overlap(cl,a,0) || check_overlap(cl,a,1)) ) 00442 { 00443 //assert( cl->xmax()== b->xmin() ); 00444 b->w_neighbors<< cl; 00445 if (!flag) 00446 { 00447 i= cl->e_neighbors.search(this); 00448 cl->e_neighbors[i]= b; 00449 } 00450 else 00451 cl->e_neighbors << b; 00452 } 00453 } 00454 foreach(SELF* cl,this->e_neighbors) { 00455 flag=false; 00456 if ( check_overlap(cl,a,2) //) 00457 && ( check_overlap(cl,a,0) || check_overlap(cl,a,1)) ) 00458 { 00459 a->e_neighbors<< cl; 00460 i= cl->w_neighbors.search(this); 00461 cl->w_neighbors[i]= a; 00462 flag=true; 00463 } 00464 if ( check_overlap(cl,b,2) //) 00465 && ( check_overlap(cl,a,0) || check_overlap(cl,a,1)) ) 00466 { 00467 b->e_neighbors<< cl; 00468 if (!flag) 00469 { 00470 i= cl->w_neighbors.search(this); 00471 cl->w_neighbors[i]= b; 00472 } 00473 else 00474 cl->w_neighbors << b; 00475 } 00476 } 00477 //update vertically 00478 foreach(SELF* cl,this->s_neighbors) { 00479 flag=false; 00480 if ( check_overlap(cl,a,0) //) 00481 && ( check_overlap(cl,a,0) || check_overlap(cl,a,1)) ) 00482 { 00483 //assert( cl->ymax()== a->ymin() ); 00484 a->s_neighbors<< cl; 00485 i= cl->n_neighbors.search(this); 00486 cl->n_neighbors[i]= a; 00487 flag=true; 00488 } 00489 if ( check_overlap(cl,b,0) //) 00490 && ( check_overlap(cl,a,0) || check_overlap(cl,a,1)) ) 00491 { 00492 //assert( cl->ymax()== b->ymin() ); 00493 b->s_neighbors<< cl; 00494 if (!flag) 00495 { 00496 i= cl->n_neighbors.search(this); 00497 cl->n_neighbors[i]= b; 00498 } 00499 else 00500 cl->n_neighbors << b; 00501 } 00502 } 00503 foreach(SELF* cl,this->n_neighbors) { 00504 flag=false; 00505 if ( check_overlap(cl,a,2) //) 00506 && ( check_overlap(cl,a,0) || check_overlap(cl,a,1)) ) 00507 { 00508 a->n_neighbors<< cl; 00509 i= cl->s_neighbors.search(this); 00510 cl->s_neighbors[i]= a; 00511 flag=true; 00512 } 00513 if ( check_overlap(cl,b,2) //) 00514 && ( check_overlap(cl,a,0) || check_overlap(cl,a,1)) ) 00515 { 00516 b->n_neighbors<< cl; 00517 if (!flag) { 00518 i= cl->s_neighbors.search(this); 00519 cl->s_neighbors[i]= b; 00520 } 00521 else 00522 cl->s_neighbors << b; 00523 } 00524 } 00525 } 00526 //-------------------------------------------------------------------- 00527 TMPL inline void 00528 SELF::disconnect() 00529 { 00530 this->e_neighbors.clear(); 00531 this->w_neighbors.clear(); 00532 this->n_neighbors.clear(); 00533 this->s_neighbors.clear(); 00534 this->b_neighbors.clear(); 00535 this->f_neighbors.clear(); 00536 } 00537 //-------------------------------------------------------------------- 00538 TMPL 00539 inline bool check_overlap(SELF * a, SELF * b, int v) //left,right or up,down 00540 {// check if a,b overlap wrt v-th coordinate 00541 if (v==0) //direction v=0 00542 return !( a->xmax()<= b->xmin() || 00543 b->xmax()<= a->xmin() ); 00544 if (v==1) //direction v=1 00545 return !( a->ymax()<= b->ymin() || 00546 b->ymax()<= a->ymin() ); 00547 if (v==2) //direction v=2 00548 return !( a->zmax()<= b->zmin() || 00549 b->zmax()<= a->zmin() ); 00550 return false; 00551 } 00552 00553 //-------------------------------------------------------------------- 00554 template<class CELL> inline void 00555 cell3d_split(CELL * left, CELL * right, CELL* cl, int v, double s) { 00556 if(v==0) { 00557 left = new CELL(*cl); 00558 right = new CELL(*cl); 00559 left->set_xmax(s); 00560 right->set_xmin(s); 00561 cl->connect0(left,right); 00562 left->join0(right); 00563 } else if (v==1) { 00564 left = new CELL(*cl); 00565 right = new CELL(*cl); 00566 left->set_ymax(s); 00567 right->set_ymin(s); 00568 cl->connect1(left,right); 00569 left->join2(right); 00570 } else if (v==2) { 00571 left = new CELL(*cl); 00572 right = new CELL(*cl); 00573 left->set_zmax(s); 00574 right->set_zmin(s); 00575 cl->connect2(left,right); 00576 left->join2(right); 00577 } 00578 } 00579 //-------------------------------------------------------------------- 00580 template<class CELL> bool 00581 is_adjacentpl3d(CELL* c1,CELL* c2){ 00582 if(c1->xmax()<c2->xmin() || c2->xmax()<c1->xmin()) 00583 return false; 00584 if(c1->ymax()<c2->ymin() || c2->ymax()<c1->ymin()) 00585 return false; 00586 if(c1->zmax()<c2->zmin() || c2->zmax()<c1->zmin()) 00587 return false; 00588 if((c1->xmax()==c2->xmin() || c2->xmax()==c1->xmin())) { 00589 if((c1->ymax()==c2->ymin() || c2->ymax()==c1->ymin()) || 00590 (c1->zmax()==c2->zmin() || c2->zmax()==c1->zmin()) ) 00591 return false; 00592 } else if((c1->ymax()==c2->ymin() || c2->ymax()==c1->ymin()) && 00593 (c1->zmax()==c2->zmin() || c2->zmax()==c1->zmin()) ) 00594 return false; 00595 return true; 00596 } 00597 //-------------------------------------------------------------------- 00598 #define xMIN (c2->xmin()<c3->xmin()?c3->xmin():c2->xmin()) 00599 #define xMAX (c2->xmax()<c3->xmax()?c2->xmax():c3->xmax()) 00600 #define yMIN (c2->ymin()<c3->ymin()?c3->ymin():c2->ymin()) 00601 #define yMAX (c2->ymax()<c3->ymax()?c2->ymax():c3->ymax()) 00602 #define zMIN (c2->zmin()<c3->zmin()?c3->zmin():c2->zmin()) 00603 #define zMAX (c2->zmax()<c3->zmax()?c2->zmax():c3->zmax()) 00604 00605 template<class CELL> bool 00606 is_adjacentpl3d(CELL* c1,CELL* c2, CELL* c3){ 00607 00608 if(c1->xmax()< xMIN || xMAX <c1->xmin()) 00609 return false; 00610 if(c1->ymax()<yMIN || yMAX<c1->ymin()) 00611 return false; 00612 if(c1->zmax()<zMIN || zMAX<c1->zmin()) 00613 return false; 00614 00615 if((c1->xmax()==xMIN || xMAX==c1->xmin())) { 00616 if((c1->ymax()==yMIN || yMAX==c1->ymin()) || 00617 (c1->zmax()==zMIN || zMAX==c1->zmin()) ) 00618 return false; 00619 } else if((c1->ymax()==yMIN || yMAX==c1->ymin()) && 00620 (c1->zmax()==zMIN || zMAX==c1->zmin()) ) 00621 return false; 00622 return true; 00623 } 00624 #undef xMIN 00625 #undef xMAX 00626 #undef yMIN 00627 #undef yMAX 00628 #undef zMIN 00629 #undef zMAX 00630 //==================================================================== 00631 } ; // namespace shape 00632 } ; // namespace mmx 00633 # undef TMPL 00634 # undef TMPL1 00635 # undef SELF 00636 # endif // shape_cell3d_hpp