shape_doc 0.1
/Users/mourrain/Devel/mmx/shape/include/shape/voronoi2d.hpp
Go to the documentation of this file.
00001 /*****************************************************************************
00002  * M a t h e m a g i x
00003  *****************************************************************************
00004  * Voronoi2d
00005  * 2010-04-05 
00006 * Angelos Mantzaflaris
00007  *****************************************************************************
00008  *               Copyright (C) 2010 INRIA Sophia-Antipolis
00009  *****************************************************************************
00010  * Comments :
00011  ****************************************************************************/
00012 # ifndef shape_voronoi2d_hpp
00013 # define shape_voronoi2d_hpp
00014 
00015 # include <shape/topology2d.hpp>
00016 # include <shape/voronoi_site2d.hpp>
00017 # include <shape/cell2d_voronoi_site2d.hpp>
00018 # include <shape/cell2d_voronoi_diagram.hpp>
00019 
00020 # include <shape/semialgebraic_domain2d_axel.hpp>
00021 # include <stack>
00022 
00023 # define  STACK std::stack<Cell2d *>
00024 
00025 # define TMPL template<class C, class V>
00026 # define Shape geometric<V>
00027 # define VoronoiCurve voronoi_bisector<C,V>
00028 # define VoronoiSite2d voronoi_site2d<C,V >
00029 # define VSite voronoi_site2d<C,V >
00030 # define Cell2dVoronoiSite2d cell2d_voronoi_site2d<C,V>
00031 # define SELF voronoi2d<C,V>
00032 # define Viewer viewer<V>
00033 //# define Cell  cell2d_voronoi_diagram<C,V>
00034 # define VCell cell2d_voronoi_diagram<C,V>
00035 # undef Cell
00036 //====================================================================
00037 namespace mmx {
00038 namespace shape {
00039 
00040 template<class C, class V=default_env>
00041 class voronoi2d
00042 {
00043 
00044 public:
00045 
00046   typedef typename topology2d<C,V>::Point        Point;  
00047   typedef typename topology2d<C,V>::Edge         Edge;
00048   typedef typename topology2d<C,V>::Face         Face;
00049   typedef typename topology2d<C,V>::BoundingBox BoundingBox;
00050   typedef typename topology2d<C,V>::Cell         Cell;
00051   typedef typename topology2d<C,V>::Cell2d       Cell2d;
00052   typedef typename topology2d<C,V>::Curve        Curve;
00053   typedef topology<C,V>       Topology;
00054   
00055   typedef node<Curve*, Cell*>               Node;
00056   typedef kdtree<Curve*, Cell*>             Kdtree;
00057 
00058 public:
00059   
00060   voronoi2d(const BoundingBox& bx): m_maxprec(0.1), m_minprec(0.01), m_bbx(bx) { };
00061 
00062   voronoi2d(Curve * curve) ;
00063   ~voronoi2d(void) {};//   delete this->m_tree ;  };
00064 
00065   void run(void)  ;
00066   void push_back(VoronoiSite2d *v);
00067 
00068   unsigned const size() { return m_sites.size(); };
00069 
00070   void set_precision (double);
00071   void set_smoothness(double);
00072 
00073 protected:
00074   bool is_regular (Cell * cell) 
00075     { 
00076       return cell->is_regular();
00077       //return topology2d<C,V>::is_regular(cell); 
00078     };
00079 
00080   bool insert_regular(Cell * cell) 
00081     { 
00082       //return cell->insert_regular(this);
00083 
00084   Seq<Point*> l;
00085     l= ((VCell*)cell)->intersections();
00086 
00087   int * sz;
00088   int * st;
00089   Point *q;
00090 
00091   if ( l.size()==2 )
00092   {
00093     this->m_graph.push_vertex(l[0]);
00094     this->m_graph.push_vertex(l[1]);
00095     this->m_graph.push_uedge(l[0],l[1]);
00096 
00097     return true;
00098   }
00099 
00100   if ( l.size()==4 ) // two dublicated
00101   {
00102     this->m_graph.push_vertex(l[0]);
00103     this->m_graph.push_vertex(l[1]);
00104     this->m_graph.push_uedge(l[0],l[1]);
00105     return true;
00106   }
00107   
00108   if ( l.size()==1)
00109   {
00110     std::cout<< "SIZE ONE, "<< *cell<<std::endl;
00111 
00112     this->m_graph.push_vertex(l[0]);
00113 
00114     foreach( Cell* c, ((VCell*)cell)->m_objects )
00115       if ( ((Cell2d*)c)->nb_intersect()==1 )
00116       {
00117         sz= ((Cell2dVoronoiSite2d*)c)->m_polynomial.rep().szs();
00118         st= ((Cell2dVoronoiSite2d*)c)->m_polynomial.rep().str();
00119         if ( ((Cell2dVoronoiSite2d*)c)->m_polynomial[0]<EPSILON )
00120         {
00121           q= new Point(cell->xmin(),cell->ymin(),0); 
00122 //          std::cout<< "1.add ("<< *q <<")->("<< *l[0] << ") in "<< *this<<std::endl;
00123 
00124           this->m_graph.push_vertex(q);
00125           this->m_graph.push_uedge(l[0],q);
00126 
00127           ((Cell2dVoronoiSite2d*)c)->n_intersections<< q;
00128 
00129           foreach( Cell2d *nb, ((Cell2d*)cell)->s_neighbors )
00130             foreach( Cell* cc, ((VCell*)nb)->m_objects )
00131             if ( cc->is_active() )
00132             {
00133               ((Cell2dVoronoiSite2d*)cc)->n_intersections<< q;
00134               std::cout<<"This Intersections: "<< ((VCell*)cell)->intersections().size() << std::endl;
00135               std::cout<<"Neib Intersections: "<< nb->intersections().size() << std::endl;
00136               return true;
00137             }
00138           foreach( Cell2d *nb, ((Cell2d*)cell)->w_neighbors )
00139             foreach( Cell* cc, ((VCell*)nb)->m_objects )
00140             if ( cc->is_active() )
00141             {
00142               ((Cell2dVoronoiSite2d*)cc)->e_intersections<< q;
00143               std::cout<<"This Intersections: "<< ((VCell*)cell)->intersections().size() << std::endl;
00144               std::cout<<"Neib Intersections: "<< nb->intersections().size() << std::endl;
00145               return true;
00146             }
00147 
00148         } else if ( ((Cell2dVoronoiSite2d*)c)->m_polynomial[(sz[0]-1)*st[0]]<EPSILON )
00149         {
00150           q= new Point(cell->xmax(),cell->ymax(),0);
00151           std::cout<< "2.add ("<< *q <<")->("<< *l[0] << ") in "<< *cell<<std::endl;
00152 
00153           this->m_graph.push_vertex(q);
00154           this->m_graph.push_uedge(l[0],q);
00155           ((Cell2dVoronoiSite2d*)c)->s_intersections<< q;
00156 
00157 
00158           foreach( Cell2d *nb, ((VCell*)cell)->e_neighbors )
00159             foreach( Cell* cc, ((VCell*)nb)->m_objects )
00160             if ( cc->is_active() )
00161             {
00162               ((Cell2dVoronoiSite2d*)cc)->w_intersections<< q;
00163               std::cout<<"This Intersections: "<< ((VCell*)cell)->intersections().size() << std::endl;
00164               std::cout<<"Neib Intersections: "<< nb->intersections().size() << std::endl;
00165               return true;
00166             }
00167           foreach( Cell2d *nb, ((VCell*)cell)->n_neighbors )
00168             foreach( Cell* cc, ((VCell*)nb)->m_objects )
00169             if ( cc->is_active() )
00170             {
00171               ((Cell2dVoronoiSite2d*)cc)->s_intersections<< q;
00172               std::cout<<"This Intersections: "<< ((VCell*)cell)->intersections().size() << std::endl;
00173               std::cout<<"Neib Intersections: "<< nb->intersections().size() << std::endl;
00174               return true;
00175             }
00176 
00177         } else if ( ((Cell2dVoronoiSite2d*)c)->m_polynomial[sz[0]*sz[1]-1]<EPSILON )
00178         {
00179           q= new Point(cell->xmin(),cell->ymax(),0);
00180 //          std::cout<< "3.add ("<< *q <<")->("<< *l[0] << ") in "<< *this<<std::endl;
00181           this->m_graph.push_vertex(q);
00182           this->m_graph.push_uedge(l[0],q);
00183 
00184           ((Cell2dVoronoiSite2d*)c)->w_intersections<< q;
00185           return true;
00186         } else if ( ((Cell2dVoronoiSite2d*)c)->m_polynomial[(sz[1]-1)*st[1]]<EPSILON )
00187         {
00188           q= new Point(cell->xmax(),cell->ymin(),0);
00189 //          std::cout<< "4.add ("<< *q <<")->("<< *l[0] << ") in "<< *this<<std::endl;
00190           this->m_graph.push_vertex(q);
00191           this->m_graph.push_uedge(l[0],q);
00192           ((Cell2dVoronoiSite2d*)c)->e_intersections<< q;
00193           return true;
00194         }  
00195       }
00196   }
00197 
00198   if ( l.size()==0)
00199   {
00200     std::cout<< "SIZE ZERO, "<< *cell<<std::endl;
00201     return true;
00202 
00203     foreach( Cell* c, ((VCell*)cell)->m_objects )
00204       {
00205         sz= ((Cell2dVoronoiSite2d*)c)->m_polynomial.rep().szs();
00206         st= ((Cell2dVoronoiSite2d*)c)->m_polynomial.rep().str();
00207         if ( ((Cell2dVoronoiSite2d*)c)->m_polynomial[0]<EPSILON )
00208         {
00209           q= new Point(cell->xmin(),cell->ymin(),0); 
00210           std::cout<< "1.add ("<< *q <<") in "<< *cell<<std::endl;
00211           this->m_graph.push_vertex(q);
00212           ((Cell2dVoronoiSite2d*)c)->n_intersections<< q;
00213           return true;
00214         } else if ( ((Cell2dVoronoiSite2d*)c)->m_polynomial[(sz[0]-1)*st[0]]<EPSILON )
00215         {
00216           q= new Point(cell->xmax(),cell->ymax(),0);
00217           std::cout<< "1.add ("<< *q <<") in "<< *cell<<std::endl;
00218           this->m_graph.push_vertex(q);
00219           ((Cell2dVoronoiSite2d*)c)->s_intersections<< q;
00220           return true;
00221         } else if ( ((Cell2dVoronoiSite2d*)c)->m_polynomial[sz[0]*sz[1]-1]<EPSILON )
00222         {
00223           q= new Point(cell->xmin(),cell->ymax(),0);
00224           std::cout<< "1.add ("<< *q <<") in "<< *cell<<std::endl;
00225           this->m_graph.push_uedge(l[0],q);
00226           ((Cell2dVoronoiSite2d*)c)->w_intersections<< q;
00227           return true;
00228         } else if ( ((Cell2dVoronoiSite2d*)c)->m_polynomial[(sz[1]-1)*st[1]]<EPSILON )
00229         {
00230           q= new Point(cell->xmax(),cell->ymin(),0);
00231           std::cout<< "1.add ("<< *q <<") in "<< *cell<<std::endl;
00232           this->m_graph.push_vertex(q);
00233           this->m_graph.push_uedge(l[0],q);
00234           ((Cell2dVoronoiSite2d*)c)->e_intersections<< q;
00235           return true;
00236         }  
00237       }
00238   }
00239 
00240 //    std::cout<< "nb_in= "<<  ((VCell*)cell)->nb_intersect() <<std::endl;
00241     //std::cout<< "box  = "<< *this <<std::endl;
00242         //foreach(Point* q, this->intersections() ) 
00243         //std::cout<< " "<< *q <<std::endl;
00244 //    print((Cell2dAlgebraicCurve*)m_objects[0]);
00245     return true;
00246 
00247     };
00248 
00249 
00250 //   bool singularity(Cell * cell) 
00251 //     { 
00252 //       std::cout<< "Voronoi Singularity"<<std::endl;
00253 // return topology2d<C,V>::singularity(cell); };
00254 
00255   bool subdivide(Cell * cell) 
00256     { return topology2d<C,V>::subdivide(cell,NULL); };
00257 
00258 private:
00259 
00260 public:
00261 
00262   std::list<VoronoiSite2d *> m_sites ;
00263 
00264   std::list<VCell *> m_singular_cells;  
00265 
00266   Graph<Point*>       m_graph;  // topological graph
00267   
00268   Graph<Cell2d*>      m_leaves; // active leaves graph
00269   Graph<Cell2d*>      b_leaves; // border leaves CCW loop
00270 
00271   double            m_maxprec ;
00272   double            m_minprec ;
00273   
00274   BoundingBox       m_bbx;
00275   Seq<VSite*>       m_objects;
00276 
00277   Seq<Face *>         m_faces;
00278 };
00279   
00280 //--------------------------------------------------------------------
00281 
00282 TMPL void 
00283 SELF::push_back(VoronoiSite2d *v)
00284 {
00285   this->m_objects.push_back(v); 
00286   this->m_sites.push_back(v);
00287 
00288   //std::cout<<"added "<< v->coordinates() << std::endl;
00289 }
00290 
00291 TMPL void SELF::set_smoothness(double eps) {
00292   m_maxprec = eps;
00293 }
00294 
00295 TMPL void SELF::set_precision(double eps) {
00296   m_minprec = eps;
00297 }
00298 
00299 TMPL void 
00300 SELF::run() {
00301      // assume this->m_sites.size()>1
00302      //topology2d<C,V>::run();
00303      //std::cout<<"Topology run OK." <<std::endl;
00304 
00306 
00307   std::cout<<"Running, objs="<<this->m_objects.size() << std::endl;
00308 
00309   //Cell* cl = Cell2dFactory::instance()->create(this->m_objects,this->m_bbx);
00310   VCell * l = new VCell(this->m_bbx);
00311   //std::cout<<"voronoi diagram"<<std::endl;
00312   foreach( VSite * vcurve, this->m_objects) 
00313   {
00314     //VoronoiSite2d * vcurve = dynamic_cast<VoronoiSite2d *>(o);
00315     l->push_back( new Cell2dVoronoiSite2d(vcurve,this->m_bbx) );
00316   }
00317 
00318   std::cout<<"RUNing "<< l <<std::endl;
00319 
00320   // double maxsz = this->m_maxprec*m_tree->root()->get_cell()->size();
00321   // double minsz = this->m_minprec*m_tree->root()->get_cell()->size();
00322   double maxsz = this->m_maxprec;
00323   double minsz = this->m_minprec;
00324 
00325   
00326   std::stack<Cell *> cell_stack;
00327   cell_stack.push(l);
00328 
00329   while(!cell_stack.empty()  ) {   //   
00330 
00331 //    Node * node = this->m_nodes.front() ;
00332     Cell   * cl = cell_stack.top();
00333     cell_stack.pop();
00334     Cell2d * cl2= dynamic_cast<Cell2d*>(cl);
00335 
00336     //std::cout<<"node "<<cl <<std::endl;
00337 
00338     if(cl->is_active()) {
00339 
00340       //std::cout<<"active.. "<<std::endl;
00341 
00342       if(cl->size() > maxsz) 
00343         { 
00344           //this->subdivide(cl, node) ;
00345           Cell * left, * right;
00346             ((cell<C,V> *)cl)->subdivide(left, right) ;
00347           cell_stack.push(left);
00348           cell_stack.push(right);
00349         }
00350       else if(this->is_regular(cl) )// && cl->is_intersected())
00351       { 
00352         //std::cout<<"ins regular "<<std::endl;
00353         this->insert_regular(cl) ;
00354         //std::cout<<"ok "<<std::endl;
00355         cl2->m_gnode= 
00356           this->m_leaves.push_vertex(cl2);
00357         if (  cl2->is_border() )
00358           this->b_leaves.push_vertex(cl2);       
00359       }
00360       else if(cl->size() > minsz)
00361       { 
00362         //std::cout<<"subdivide "<<std::endl;
00363           Cell* left, * right;
00364           cl->subdivide(left, right) ;
00365           cell_stack.push(left);
00366           cell_stack.push(right);
00367       }
00368       else
00369       { 
00370         //std::cout<<"singularity "<<std::endl;
00371         //this->singularity(cl) ;
00372 //        std::cout<<"VD, Inserting singular"<<*cl2<<std::endl;  
00373         this->m_singular_cells<< (VCell*)cl2; // does not work with forwa
00374         ( (VCell*)cl2 )->process_singular() ;
00375 
00376         cl2->m_gnode= 
00377           this->m_leaves.push_vertex(cl2);
00378         if (  cl2->is_border() )
00379           this->b_leaves.push_vertex(cl2);       
00380       }
00381         }
00382     else    //inactive leaf -- end if
00383     {
00384         if (  cl2->is_border() )
00385             this->b_leaves.push_vertex(cl2);       
00386     }
00387   }
00388 
00389   /* add edges */
00390   Seq<Cell2d*> nlist;
00391 
00392   std::cout<<"border " << std::endl;
00393   // Border graph
00394   this->b_leaves.dfs(nlist);
00395 
00396   foreach(Cell2d* cl2, nlist)
00397   {
00398     if (cl2->s_neighbors.size()==0)
00399       foreach(Cell2d* nb, cl2->e_neighbors )
00400         if (nlist.member(nb) && nb->s_neighbors.size()==0)
00401           this->b_leaves.push_edge( cl2,nb ) ;
00402     if (cl2->e_neighbors.size()==0)
00403       foreach(Cell2d* nb, cl2->n_neighbors )
00404         if (nlist.member(nb) && nb->e_neighbors.size()==0)
00405           this->b_leaves.push_edge( cl2,nb ) ;
00406     if (cl2->n_neighbors.size()==0)
00407       foreach(Cell2d* nb, cl2->w_neighbors )
00408         if (nlist.member(nb)&& nb->n_neighbors.size()==0)
00409           this->b_leaves.push_edge( cl2,nb ) ;
00410     if (cl2->w_neighbors.size()==0)
00411              foreach(Cell2d* nb, cl2->s_neighbors )
00412                if (nlist.member(nb)&& nb->w_neighbors.size()==0)
00413                  this->b_leaves.push_edge( cl2,nb ) ;
00414   }
00415   nlist.clear();
00416 
00417 
00418 
00419 
00420 
00422 
00423      // Treating singular cells
00424      foreach( VCell* q, m_singular_cells )
00425      { q->compute_boundary();
00426        //m_singular_cells.erase(q);
00427      }
00428 
00429      //Computing Voronoi Cells:
00430      this->b_leaves.dfs(nlist);// remove empty border cells
00431      std::cout<<"Border size= "<< nlist.size() <<std::endl;
00432 
00433      Cell2d* pr;
00434      pr= nlist[nlist.size()-1];
00435 
00436      foreach(Cell2d* cl2, nlist)
00437       {
00438           if ( cl2->is_corner() )
00439               pr=cl2;
00440           else {
00441               if ( (cl2->s_neighbors.size()==0 && 
00442                     cl2->intersections(0).size()==0 ) ||
00443                    (cl2->e_neighbors.size()==0 && 
00444                     cl2->intersections(1).size()==0 ) ||
00445                    (cl2->n_neighbors.size()==0 && 
00446                     cl2->intersections(2).size()==0 ) ||
00447                    (cl2->w_neighbors.size()==0 && 
00448                     cl2->intersections(3).size()==0 )  )
00449               {
00450                   this->b_leaves.push_edge(pr, this->b_leaves.next(cl2) ) ;
00451                   this->b_leaves.delete_vertex( cl2 ) ;
00452               }
00453               else
00454                   pr=cl2;
00455           }
00456       }
00457  std::cout<<"Border Ok." <<std::endl;
00458 
00459       // Leaf graph
00460       nlist.clear();
00461       this->m_leaves.dfs(nlist);
00462       foreach(Cell2d* cl2, nlist)
00463       {
00464           //Cell * cl= dynamic_cast<Cell*>(cl);
00465           foreach(Cell2d* nb, cl2->neighbors() )
00466               this->m_leaves.push_edge( cl2,nb ) ;
00467       }
00468       //remove interior cells
00469       if (0)//done at subdivision time
00470       foreach(Cell2d* cl, nlist) {
00471         if (!cl->is_active() )//|| !cl->is_touching() ) 
00472         {  
00473           this->m_leaves.delete_vertex(cl);
00474         }
00475       }
00476       
00477      
00478  std::cout<<"Leaf graph Ok." <<std::endl;
00479 
00480 
00482 
00483  //Remove inactive cells OK ..
00484  // AND misleading edges 
00485  //Recover connected components .. ( for all regular cells and sign +,-)
00486  // FOR ALL CC's:
00487  //1. check if CC is actually SCC .. 
00488  //2. walk on boundry and output face
00489 
00490    //get boundary
00491 
00492 //   nlist.clear();
00493 //   this->m_leaves.dfs(nlist);
00494 
00495    Point *p= NULL;
00496    Face * f= NULL;
00497    int aux;
00498    int sgn(1);
00499    unsigned site;//the site whose cell is computed
00500 
00501    assert( nlist.size()>1);
00502 
00503    Cell2d *s= NULL,
00504           *t= NULL,
00505           *b= NULL;
00506    STACK stack;
00507 
00508    // Start exploration
00509    foreach(Cell2d* cl, nlist)
00510    {
00511      if ( cl->is_active()        &&
00512           (!this->b_leaves.member(cl))   &&
00513           ((VCell*)cl)->count() ==1 
00514         )
00515      { cl->m_gnode->aux(0);
00516        stack.push(cl);  }
00517    }
00518 
00519    std::cout<<"#stack: "<<nlist.size()<<std::endl;
00520 
00521 //   if (0) //Don't compute 2Dcells
00522 while ( !stack.empty() )
00523    {
00524    s= stack.top();
00525    aux=s->m_gnode->aux();
00526 
00527    //Every bisector box is visited twice
00528    switch (aux)
00529    {
00530    case 0:
00531      sgn=1 ;
00532    case -1 :
00533      sgn=1 ;
00534      break ;
00535    case  2 :
00536      sgn=-1;
00537    break   ;
00538    default :
00539      stack.pop();
00540      continue;
00541    }
00542    site=((VCell*)s)->site(sgn);//computing Voronoi Cell of "site"
00543 
00544 
00545    // Recovering site 
00546    f= new Face();
00547 
00548    // Get starting point (CCW)
00549    std::cout<<"Getting voronoi cell of "<<site <<"("<<(sgn==1 ? "+": "-")
00550             <<"), starting "<< *s<<  std::endl;
00551    p= s->starting_point(sgn);
00552 //   std::cout<<"starting at "<< *p <<std::endl;
00553    // Walking on CCW face
00554    p= s->pair(p,sgn);
00555 //   std::cout<<"p= "<< *p <<std::endl;
00556    f->insert(p);
00557    b=s;
00558    
00559 //int c(0); 
00560    do  {
00561 //if (++c>137) {while(!stack.empty()) stack.pop(); exit(0);break;}
00562      //std::cout<<"Next"<< *b <<" sites= "<< ((VCell*)b)->sites()<<std::endl;
00563      //std::cout<<"."<<std::endl;
00564      //if ( !b->is_corner())
00565 
00566 
00567       if( this->m_leaves.member(b) ) {
00568       aux=b->m_gnode->aux();
00569       b->m_gnode->aux(aux + (sgn==1 ? 2:-1) );
00570       //std::cout<<"aux="<<b->m_gnode->aux()<<std::endl; 
00571       }
00572       //else
00573       //  std::cout<<"Passed: "<< (*b) <<"\n";
00574 
00575 
00576       t= b->neighbor(p);
00577 
00578       //if ( t!=NULL)
00579       //  std::cout<<*t<<" is neighbor of "<<*b<<" for point "<<*p <<std::endl;
00580 
00581         // std::cout<<"Ints,b "<<b<<": "<<b->nb_intersect() <<std::endl;
00582         // foreach( Point* q, b->intersections() )
00583         //   std::cout<<"b: "<<": "<<*q  <<std::endl;
00584         // foreach( Cell2d* c, b->neighbors() )
00585         // {
00586         //   VCell* cc= dynamic_cast<VCell*>( c );
00587         //   std::cout<<"   Ints,t "<<"("<<cc->count() <<",sites="<<cc->sites()<<") "<<": "<<c->nb_intersect()<<", "<< *c <<", adr "<< cc <<std::endl;
00588         // foreach( Point* q, cc->intersections() )
00589         //   std::cout<<"   t: "<<": "<<*q  <<std::endl;
00590 
00591         //   foreach(Cell * m, cc->m_objects)        
00592         //     std::cout<<"   t-obj:"<< m <<std::endl;
00593 
00594 
00595         // }
00596 
00597       // if (b->m_singular.size() >0) 
00598       //  std::cout<<"Voronoi Vertex! "<< *b <<", " <<std::endl;
00599 
00600       //if (0)
00601       if ( t==NULL)
00602       { // border cell reached
00603 
00604 //        std::cout<<"Border Cell "<<*b <<", #="<< ((VCell*)b)->nb_intersect() <<std::endl;
00605         //foreach( Point* q, b->intersections() )
00606         //    std::cout<< *q<<"   adr  "<<q<<std::endl; 
00607 
00608      //check meeting corner
00609           if          (b->s_neighbors.size()==0 &&
00610                        b->e_neighbors.size()==0 && b->intersections(1).size()==0)
00611            f->insert(new Point(b->xmax(),b->ymin(),0.0) );
00612           if    (b->e_neighbors.size()==0 &&
00613                        b->n_neighbors.size()==0 && b->intersections(2).size()==0)
00614            f->insert(new Point(b->xmax(),b->ymax(),0.0) );
00615           if   (b->n_neighbors.size()==0 &&
00616                        b->w_neighbors.size()==0 && b->intersections(3).size()==0)
00617            f->insert(new Point(b->xmin(),b->ymax(),0.0) );
00618           if   (b->w_neighbors.size()==0 &&
00619                        b->s_neighbors.size()==0 && b->intersections(0).size()==0)
00620              f->insert(new Point(b->xmin(),b->ymin(),0.0) );
00621 
00622 //          std::cout<<"Moving on border. ("<< this->m_faces.size()<<")"<< std::endl;
00623           b=this->b_leaves.next(b);
00624 //          std::cout<<"Moved to "<<*b <<" sites="<<((VCell*)b)->sites()<<std::endl;
00625 
00626           //check leaving corner
00627           if          (b->s_neighbors.size()==0 &&
00628                        b->e_neighbors.size()==0 && b->intersections(0).size()==0 )
00629           { f->insert(new Point(b->xmax(),b->ymin(),0.0) );
00630           }
00631           else if   (b->e_neighbors.size()==0 &&
00632                        b->n_neighbors.size()==0 && b->intersections(1).size()==0)
00633           { f->insert(new Point(b->xmax(),b->ymax(),0.0) );
00634           }
00635 
00636           else if   (b->n_neighbors.size()==0 &&
00637                        b->w_neighbors.size()==0 && b->intersections(2).size()==0)
00638           { f->insert(new Point(b->xmin(),b->ymax(),0.0) );
00639           }
00640           else if   (b->w_neighbors.size()==0 &&
00641                        b->s_neighbors.size()==0 && b->intersections(3).size()==0)
00642           {   f->insert(new Point(b->xmin(),b->ymin(),0.0) );
00643           }//end check corner
00644 
00645           if (  this->m_leaves.member(b) ) 
00646           {   //entering point. Changing bisector
00647             sgn=((VCell*)b)->signof(site);
00648             p= b->starting_point(sgn);
00649             f->insert(p);
00650             //std::cout<<"Entering from "<<*b<<" ,sgn="<<sgn<<std::endl;
00651             //std::cout<<"insert "<<*p<<std::endl;
00652             p= b->pair(p,sgn);
00653             f->insert(p);
00654             //std::cout<<"insert "<<*p<<std::endl;
00655             //std::cout<<"To : "<< *(b->neighbor(p)) <<std::endl;
00656           }
00657       }
00658       else
00659       { // next normal cell
00660         //std::cout<<"next normal cell "<<std::endl;
00661           b=t;
00662           if ( b->m_singular.size() > 0 )
00663               f->insert(b->m_singular[0]);
00664           p= b->pair(p,sgn);
00665           f->insert(p);
00666           //std::cout<<"p="<<*p<<std::endl;
00667       }
00668 
00669    } while (b!=s); 
00670    //(b->m_gnode->aux()==1 || b->m_gnode->aux()==-1 || b->m_gnode->aux()==2) );
00671 
00672    std::cout<<"Face ADDED ("<< this->m_faces.size()+1<<")" << std::endl;
00673    f->set_index(site);
00674    this->m_faces<< f;
00675 
00676 //  if (this->m_faces.size()== 6)  break;
00677 
00678    }// End exploration
00679 
00680   std::cout<<" # faces= "<< this->m_faces.size() << std::endl;
00681 
00682 
00683 }
00684 
00685 TMPL Viewer&
00686 operator<<(Viewer& out, const SELF& tp) {
00687 
00688   foreach(Shape* vs, tp.m_objects)
00689   {
00690     out<<" <point color=\"255 127 0\"> "<<
00691       ((VoronoiSite2d *)vs)->x() << " "<<
00692       ((VoronoiSite2d *)vs)->y() << " "<<
00693       ((VoronoiSite2d *)vs)->z() << "</point>\n";
00694   }
00695 
00696   return out;
00697 }
00698 
00699 //====================================================================
00700 } // namespace shape
00701 } // namespace mmx
00702 //====================================================================
00703 # undef TMPL
00704 # undef AlgebraicCurve
00705 # undef VoronoiSite
00706 # undef VCell
00707 # undef Cell
00708 # undef Cell2dVoronoiBisector
00709 # undef Cell2dFactory
00710 # undef Curve
00711 # undef SELF 
00712 # undef VoronoiSite2d
00713 # undef VoronoiCurve
00714 # undef Viewer
00715 # undef STACK
00716 # undef Shape
00717 # endif