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