shape_doc 0.1
|
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