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_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