shape_doc 0.1
/Users/mourrain/Devel/mmx/shape/include/shape/arrangement2d.hpp
Go to the documentation of this file.
00001 /*****************************************************************************
00002  * M a t h e m a g i x
00003  *****************************************************************************
00004  * TopologyCurve
00005  * 2008-05-16
00006  * Julien Wintz
00007  *****************************************************************************
00008  *               Copyright (C) 2006 INRIA Sophia-Antipolis
00009  *****************************************************************************
00010  * Comments :
00011  ****************************************************************************/
00012 # ifndef shape_arrangement2d_hpp
00013 # define shape_arrangement2d_hpp
00014 
00015 # include <shape/topology2d.hpp>
00016 
00017 # include <stack>
00018 # define  STACK std::stack<Cell2d*>
00019 
00020 # define TMPL template<class C, class V>
00021 # define Shape SHAPE_OF(V)
00022 # define AlgebraicCurve algebraic_curve<C,REF>
00023 # define ArrangementCurve arrangement_curve<C,REF>
00024 # define ParametricCurve parametric_curve<C,REF>
00025 # define Cell2dAlgebraicCurve cell2d_algebraic_curve<C,REF>
00026 # define Cell2dParametricCurve cell2d_parametric_curve<C,REF>
00027 # define Cell2dArrangementCurve cell2d_arrangement_curve<C,REF>
00028 # define Cell2dInter cell2d_intersection<C,REF>
00029 # define SELF arrangement2d<C,V>
00030 # undef Cell
00031 //====================================================================
00032 namespace mmx {
00033 namespace shape {
00034 
00035 
00036 
00037 template<class C, class V=default_env>
00038 class arrangement2d: public topology2d<C,V> {
00039 
00040   public:
00041 
00042   typedef typename topology2d<C,V>::Point       Point;  
00043   typedef typename topology2d<C,V>::Edge        Edge;
00044   typedef typename topology2d<C,V>::Face              Face;
00045   
00046   typedef typename topology2d<C,V>::BoundingBox BoundingBox;
00047   
00048   typedef typename topology2d<C,V>::Cell         Cell;
00049   typedef typename topology2d<C,V>::Cell2d     Cell2d;
00050   typedef typename topology2d<C,V>::Curve       Curve;
00051   
00052   typedef node<Curve*, Cell*>               Node;
00053   typedef kdtree<Curve*, Cell*>             Kdtree;
00054   typedef topology<C,V> Topology;
00055 
00056 public:
00057 
00058   arrangement2d(const BoundingBox& bx): topology2d<C,V>(bx){ };
00059   arrangement2d(Curve * curve) ;
00060   ~arrangement2d(void) {   delete this->m_tree ;  };
00061 
00062     void run(void)  ;
00063     
00064 //    virtual void insert(Point*);
00065 //    virtual void insert(Edge *);
00066 //    virtual void insert(Point * p1, Point * p2);
00067 
00068 
00069     virtual void insert_singular(Point*);
00070 
00071   protected:
00072     bool is_regular (Cell * cell) ;
00073     bool insert_regular(Cell * cell) ;
00074     bool singularity(Cell * cell) ;
00075     bool   subdivide(Cell * cell, Node * node) ;
00076 
00077 
00078   private:
00079     Kdtree         *  m_tree ;
00080     std::list<Node *> m_nodes ;
00081 
00082     // // Aux graph functions
00083     // static bool active_cell(gNode<Cell2d*>* v)
00084     //     {
00085     //         return (v->get_aux()>0 );
00086     //     }
00087 
00088     // static void ccw_walk(gNode<Cell2d*>* v)
00089     //     {
00090     //         //
00091     //     }
00092 
00093   };
00094 
00095 //--------------------------------------------------------------------
00096 
00097 TMPL void 
00098 SELF::run() {
00099 //
00100     topology2d<C,V>::run();
00101 
00102 
00103     std::cout<<"Computing arrangement." <<std::endl;
00104 
00105     Seq<Cell2d*> nlist;
00106     this->b_leaves.dfs(nlist);// remove empty border cells
00107     Cell2d* pr;
00108     pr= nlist[nlist.size()-1];
00109     //if (0)
00110     foreach(Cell2d* cl2, nlist)
00111      {
00112          if ( cl2->is_corner() )
00113              pr=cl2;
00114          else {
00115              if ( (cl2->s_neighbors.size()==0 && 
00116                    cl2->intersections(0).size()==0 ) ||
00117                   (cl2->e_neighbors.size()==0 && 
00118                    cl2->intersections(1).size()==0 ) ||
00119                   (cl2->n_neighbors.size()==0 && 
00120                    cl2->intersections(2).size()==0 ) ||
00121                   (cl2->w_neighbors.size()==0 && 
00122                    cl2->intersections(3).size()==0 )  )
00123              {
00124                  this->b_leaves.push_edge(pr, this->b_leaves.next(cl2) ) ;
00125                  this->b_leaves.delete_vertex( cl2 ) ;
00126              }
00127              else
00128                  pr=cl2;
00129          }
00130      }
00131 
00132 std::cout<<"Border Ok." <<std::endl;
00133 
00134       // Leaf graph
00135       nlist.clear();
00136       this->m_leaves.dfs(nlist);
00137       foreach(Cell2d* cl2, nlist)
00138       {
00139           //Cell * cl= dynamic_cast<Cell*>(cl);
00140           foreach(Cell2d* nb, cl2->neighbors() )
00141               this->m_leaves.push_edge( cl2,nb ) ;
00142       }
00143       //remove interior cells
00144       if (0)//done at subdivision time
00145       foreach(Cell2d* cl, nlist) {
00146         if (!cl->is_active() )//|| !cl->is_touching() ) 
00147         {  
00148           this->m_leaves.delete_vertex(cl);
00149         }
00150       }
00151       
00152       
00153  std::cout<<"Leaf graph Ok." <<std::endl;
00154 
00156 
00157 //Remove inactive cells OK ..
00158 // AND misleading edges 
00159 //Recover connected components .. ( for all regular cells and sign +,-)
00160 // FOR ALL CC's:
00161 //1. check if CC is actually SCC .. 
00162 //2. walk on boundry and output face
00163 
00164    Point *p= NULL;
00165    Face * f= NULL;
00166    int aux;
00167    int sgn(1);
00168    assert( nlist.size()>1);
00169 
00170    Cell2d *s= NULL,
00171           *t= NULL,
00172           *b= NULL;
00173    STACK stack;
00174 
00175    // Start exploration
00176   foreach(Cell2d* cl, nlist)
00177     if ( 
00178         cl->is_regular() && 
00179         cl->nb_intersect()==2 && 
00180         !cl->is_border() )
00181       stack.push(cl);  
00182 
00183 //if (0)
00184 while ( !stack.empty() )
00185    {
00186    s= stack.top();
00187    aux=s->m_gnode->aux();
00188    //std::cout<<"-Aux="<<aux<<std::endl;
00189 
00190    //-- all faces --
00191    switch ( aux )
00192    { 
00193    case (0): sgn=1; //+ face
00194    break;
00195    case (2): sgn=-1;//- face
00196    break;
00197    case (-1):sgn=1;//+ face
00198    break;
00199    default:  stack.pop();
00200    continue;
00201    }
00202 
00203 
00204    //Recovering face (s,sgn)
00205    f= new Face();
00206 
00207    // Get starting point (CCW)
00208    p= s->starting_point(sgn);
00209    std::cout<<"Getting ("<<(sgn==1 ? "+": "-")
00210      <<") face starting at "<< *s<<  std::endl;
00211 
00212    // Walking on CCW face
00213    p= s->pair(p,sgn);
00214    f->insert(p);
00215    b=s;
00216 
00217    
00218 //int c(0); 
00219    do  {
00220 //if (++c>120) {while(!stack.empty()) stack.pop(); exit(0);break;}
00221 //     std::cout<<"Next "<< *b <<std::endl;
00222 //       if ( !b->is_corner())
00223 //         std::cout<< *b<<", aux="<<b->m_gnode->aux()<<std::endl;
00224 
00225       if( this->m_leaves.member(b) ) {
00226       aux=b->m_gnode->aux();
00227       b->m_gnode->aux(aux + (sgn==1 ? 2:-1) );}
00228 
00229       t= b->neighbor(p);
00230 
00231       if ( t==NULL)
00232       { // border cell reached
00233 
00234           //check meeting corner
00235           if          (b->s_neighbors.size()==0 &&
00236                        b->e_neighbors.size()==0 && b->intersections(1).size()==0)
00237            f->insert(new Point(b->xmax(),b->ymin(),0.0) );
00238            else if    (b->e_neighbors.size()==0 &&
00239                        b->n_neighbors.size()==0 && b->intersections(2).size()==0)
00240            f->insert(new Point(b->xmax(),b->ymax(),0.0) );
00241            else if   (b->n_neighbors.size()==0 &&
00242                        b->w_neighbors.size()==0 && b->intersections(3).size()==0)
00243            f->insert(new Point(b->xmin(),b->ymax(),0.0) );
00244            else if   (b->w_neighbors.size()==0 &&
00245                        b->s_neighbors.size()==0 && b->intersections(0).size()==0)
00246              f->insert(new Point(b->xmin(),b->ymin(),0.0) );
00247 
00248           b=this->b_leaves.next(b);
00249 
00250           //check leaving corner
00251           if          (b->s_neighbors.size()==0 &&
00252                        b->e_neighbors.size()==0 && b->intersections(0).size()==0 )
00253           { f->insert(new Point(b->xmax(),b->ymin(),0.0) );
00254           } else if   (b->e_neighbors.size()==0 &&
00255                        b->n_neighbors.size()==0 && b->intersections(1).size()==0)
00256           { f->insert(new Point(b->xmax(),b->ymax(),0.0) );
00257           } else if   (b->n_neighbors.size()==0 &&
00258                        b->w_neighbors.size()==0 && b->intersections(2).size()==0)
00259           { f->insert(new Point(b->xmin(),b->ymax(),0.0) );
00260           } else if   (b->w_neighbors.size()==0 &&
00261                        b->s_neighbors.size()==0 && b->intersections(3).size()==0)
00262           {   f->insert(new Point(b->xmin(),b->ymin(),0.0) );
00263           }//end check corner
00264 
00265           if (  this->m_leaves.member(b) ) 
00266           {   //entering point
00267               p= b->starting_point(sgn);
00268               f->insert(p);
00269               p= b->pair(p,sgn);
00270               f->insert(p);
00271           }
00272       }
00273       else
00274       { // next normal cell
00275           b=t;
00276           if ( b->m_singular.size()==1 )
00277               f->insert(b->m_singular[0]);
00278           p= b->pair(p,sgn);
00279           f->insert(p);
00280       }
00281 
00282    } while (b!=s); 
00283    //(b->m_gnode->aux()==1 || b->m_gnode->aux()==-1 || b->m_gnode->aux()==2) );
00284 
00285   //std::cout<<"Face Added" << std::endl;
00286   this->m_faces<< f;
00287 
00288   //if (this->m_faces.size()==2)  break;
00289 
00290    }// End exploration
00291 
00292   std::cout<<" # faces= "<< this->m_faces.size() << std::endl;
00293 
00294 }
00295 
00296 TMPL bool 
00297 SELF::is_regular(Cell * cl) {
00298   return cl->is_regular();
00299 }
00300 
00301 TMPL bool 
00302 SELF::insert_regular(Cell * cl) {
00303   return cl->insert_regular(this);
00304 }
00305 
00306 TMPL bool 
00307 SELF::singularity(Cell * cl) {
00308   return cl->insert_singular(this) ;
00309 }
00310 
00311 TMPL void 
00312 SELF::insert_singular(Point * p) {
00313   this->m_specials<<p;
00314 }
00315 
00316 TMPL bool 
00317 SELF::subdivide(Cell * cl, Node * node) {
00318   int v=0;
00319   
00320   Cell* left, * right;
00321   v = cl->subdivide(left, right) ;
00322   
00323   node->m_left  = new Node(node, left,  Node::LEFT,  v); 
00324   m_nodes << node->m_left ;
00325   node->m_right = new Node(node, right, Node::RIGHT, v); 
00326   m_nodes << node->m_right;
00327 
00328   return true ;
00329 }
00330 
00331 
00332 //====================================================================
00333 } // namespace shape
00334 } // namespace mmx
00335 //====================================================================
00336 # undef TMPL
00337 # undef AlgebraicCurve
00338 # undef ArrangementCurve
00339 # undef Cell
00340 # undef Cell2dAlgebraicCurve
00341 # undef Cell2dParametricCurve
00342 # undef Cell2dArrangementCurve
00343 # undef Cell2dInter
00344 # undef Cell2dFactory
00345 # undef ParametricCurve
00346 # undef Curve
00347 # undef SELF 
00348 # undef Shape
00349 # undef STACK
00350 # endif