shape_doc 0.1
/Users/mourrain/Devel/mmx/shape/include/shape/cell3d.hpp
Go to the documentation of this file.
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