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