shape_doc 0.1
/Users/mourrain/Devel/mmx/shape/include/shape/cell3d_surface_algebraic.hpp
Go to the documentation of this file.
00001 /*****************************************************************************
00002  * M a t h e m a  g i x
00003  *****************************************************************************
00004  * cell of algebraic surface
00005  * 2008-03-20
00006  * Bernard Mourrain & Julien Wintz
00007  *****************************************************************************
00008  *               Copyright (C) 2008 INRIA Sophia-Antipolis
00009  *****************************************************************************
00010  * Comments :
00011  ****************************************************************************/
00012 
00013 # ifndef shape_cell3d_surface_algebraic_hpp
00014 # define shape_cell3d_surface_algebraic_hpp
00015 
00016 # include <realroot/Interval.hpp>
00017 # include <realroot/polynomial_bernstein.hpp>
00018 # include <realroot/sign_variation.hpp>
00019 # include <realroot/Seq.hpp>
00020 # include <shape/bounding_box.hpp>
00021 # include <shape/surface_algebraic.hpp>
00022 # include <shape/cell3d.hpp>
00023 # include <shape/solver_implicit.hpp>
00024 # include <shape/marching_cube.hpp>
00025 
00026 # define TMPL template<class C, class V>
00027 # define TMPL1 template<class C>
00028 # define SELF cell3d_surface_algebraic<C,V>
00029 # undef Topology
00030 //====================================================================
00031 namespace mmx {
00032 namespace shape {
00033 
00034 
00035 TMPL struct topology;
00036 TMPL struct tpl3d;
00037 TMPL struct cell3d_surface_algebraic;
00038 
00039 //--------------------------------------------------------------------
00040 struct cell3d_surface_algebraic_def {}; 
00041 
00042 template<> struct use<cell3d_surface_algebraic_def>
00043 //   :public use<topology_def> 
00044 //   ,public use<surface_algebraic_def> 
00045 {
00046   typedef Interval< double >                    Scalar;
00047   typedef polynomial< double, with<Bernstein> > Polynomial;
00048   //  typedef use<cell3d_def>::Cell3d           Cell3d;
00049   //  typedef use<cell3d_def>::BoundingBox      BoundingBox;
00050   //  typedef cell3d_surface_algebraic<double,double> Cell3dAlgebraicSurface;
00051 }; 
00052 
00053 //--------------------------------------------------------------------
00054 template<class C, class V=default_env>
00055 struct cell3d_surface_algebraic : public cell3d<C,V> {
00056 public:
00057 
00058   typedef REF_OF(V)  Ref;
00059   typedef tpl3d<C,V>                          Topology3d;
00060   typedef topology<C,REF_OF(V)>               Topology;
00061 
00062   typedef typename Topology::Point         Point;  
00063   typedef typename Topology::Edge          Edge;
00064   typedef typename Topology::Face          Face;
00065 
00066   typedef cell3d<C,V>                      Cell;
00067   typedef cell3d<C,V>                      CellBase;
00068   typedef cell3d<C,V>                      Cell3d;
00069 
00070   typedef bounding_box<C,Ref>              BoundingBox;
00071   
00072   typedef surface_algebraic<C,Ref>         AlgebraicSurface;
00073   
00074   typedef typename use<cell3d_surface_algebraic_def,V>::Polynomial  Polynomial;
00075 
00076   //  typedef polynomial< Interval<C>, with<Bernstein> > Polynomial;
00077   //  typedef polynomial< Scalar, with<Bernstein> > Polynomial;
00078   
00079   typedef solver_implicit<C,V>             Solver;
00080   
00081   cell3d_surface_algebraic(const SELF&);
00082   cell3d_surface_algebraic(const Polynomial&, const BoundingBox& );
00083   cell3d_surface_algebraic(char*, const BoundingBox& );
00084   
00085   cell3d_surface_algebraic(const AlgebraicSurface&, const BoundingBox&);
00086   cell3d_surface_algebraic(AlgebraicSurface *, const BoundingBox&);
00087 
00088   virtual bool is_regular(void);
00089   virtual bool is_active (void) const;
00090 
00091   virtual bool is_intersected (void) {return true;}
00092 
00093   virtual bool insert_regular (Topology*) ;
00094   virtual bool insert_singular(Topology*) ;
00095 
00096   virtual void polygonise (Topology3d*) ;
00097 
00098   virtual bool topology_regular(Topology*) ;
00099   
00100   template<class CELL> 
00101           void split    (CELL*& left, CELL*& right, int v, double s);
00102   virtual void subdivide(Cell*& left, Cell*& right, int v, double s);
00103   
00104   int           mc_index(void)      const ;
00105   bool          edge_point(Point**, int ) const ;
00106 
00107   void          insert(Point* p) { m_points<< p; }
00108   void          insert(Face*  p) { m_faces<< p;  }
00109 
00110   double        vertex_eval(unsigned sx, unsigned sy, unsigned sz) const;
00111   const Polynomial&   equation() const {return m_polynomial;}
00112   Polynomial    get_polynomial() const {return m_polynomial;}
00113   
00114 public:
00115   Polynomial        m_polynomial;
00116   Point*            m_center;
00117   int               m_idx;
00118 
00119   Seq<Point*>       m_points;
00120   Seq<Face*>        m_faces;
00121 
00122 private:
00123   void resolve_conflict(Seq<Cell3d*> &neighb, double side, int cc);
00124 };
00125 
00126 //====================================================================
00127 TMPL
00128 SELF::cell3d_surface_algebraic(const SELF& s)
00129   : Cell3d((BoundingBox)s), m_polynomial(s.equation()), m_center(0)
00130 {
00131   
00132 }
00133 //--------------------------------------------------------------------
00134 TMPL
00135 SELF::cell3d_surface_algebraic(const Polynomial& pol, const BoundingBox& bx)
00136   : Cell3d(bx), m_polynomial(pol), m_center(0)
00137 {
00138 
00139 }
00140 //--------------------------------------------------------------------
00141 TMPL
00142 SELF::cell3d_surface_algebraic(char* pol, const BoundingBox& bx)
00143   : Cell3d(bx), m_polynomial(pol), m_center(0)
00144 {
00145 }
00146 //--------------------------------------------------------------------
00147 TMPL
00148 SELF::cell3d_surface_algebraic(const AlgebraicSurface& sf, const BoundingBox& b): Cell3d(b), m_center(0)
00149 {
00150   Seq<mmx::GMP::rational> bx;
00151   bx<<as<mmx::GMP::rational>(b.xmin());
00152   bx<<as<mmx::GMP::rational>(b.xmax());
00153   bx<<as<mmx::GMP::rational>(b.ymin());
00154   bx<<as<mmx::GMP::rational>(b.ymax());
00155   bx<<as<mmx::GMP::rational>(b.zmin());
00156   bx<<as<mmx::GMP::rational>(b.zmax());
00157   
00158   Polynomial tmp;
00159   tensor::bernstein<mmx::GMP::rational> polq(sf.equation().rep(),bx);
00160   let::assign(tmp.rep(),polq);
00161   m_polynomial=tmp;
00162 
00163 //     BoundingBox* bbx = sf->boundingBox();
00164 //     Polynomial ft, bk;
00165 //     tensor::face(ft,m_polynomial, 2, 1);
00166 //     solver_implicit::edge_point(n_intersections, ft, north_edge, bbx);
00167 //     solver_implicit::edge_point(s_intersections, ft, south_edge, bbx);
00168 //     solver_implicit::edge_point(w_intersections, ft, west_edge , bbx);
00169 //     solver_implicit::edge_point(e_intersections, ft, east_edge , bbx);
00170 
00171 //     tensor::face(bk, m_polynomial, 2, 0);
00172 //     solver_implicit::edge_point(n_intersections, bk, north_edge, bbx);
00173 //     solver_implicit::edge_point(s_intersections, bk, south_edge, bbx);
00174 //     solver_implicit::edge_point(w_intersections, bk, west_edge , bbx);
00175 //     solver_implicit::edge_point(e_intersections, bk, east_edge , bbx);
00176 
00177 //     tensor::face(ft, m_polynomial, 1, 1);
00178 //     solver_implicit::edge_point(w_intersections, ft, west_edge, bbx);
00179 //     solver_implicit::edge_point(e_intersections, ft, east_edge, bbx);
00180 
00181 //     tensor::face(bk, m_polynomial, 1, 0);
00182 //     solver_implicit::edge_point(w_intersections, bk, west_edge, bbx);
00183 //     solver_implicit::edge_point(e_intersections, bk, east_edge, bbx);
00184 
00185 //     foreach(Point* p, n_intersections) std::cout<<"n "<<p->x()<<" "<<p->y()<<" "<<p->z()<<std::endl;
00186 //     foreach(Point* p, s_intersections) std::cout<<"s "<<p->x()<<" "<<p->y()<<" "<<p->z()<<std::endl;
00187 //     foreach(Point* p, w_intersections) std::cout<<"w "<<p->x()<<" "<<p->y()<<" "<<p->z()<<std::endl;
00188 //     foreach(Point* p, e_intersections) std::cout<<"e "<<p->x()<<" "<<p->y()<<" "<<p->z()<<std::endl;
00189 
00190 }
00191 //--------------------------------------------------------------------
00192 TMPL bool 
00193 SELF::is_active()  const {
00194   //BoundingBox* bbx=(BoundingBox*)this;
00195   
00196   //    cout<<(BoundingBox*)this<<endl;
00197   //    cout<<m_polynomial.rep()<<endl;
00198   //    cout<<has_sign_variation(m_polynomial.begin(),m_polynomial.end())<<endl;
00199   
00200   //  Seq<Point*> lp;
00201   //  Polynomial ft, bk;
00202   //  tensor::face(ft,m_polynomial, 2, 1);
00203 
00204 //     solver_implicit::edge_point(lp, m_polynomial, north_front_edge, bbx);
00205 //     solver_implicit::edge_point(lp, m_polynomial, south_front_edge, bbx);
00206 //     solver_implicit::edge_point(lp, m_polynomial, west_front_edge , bbx);
00207 //     solver_implicit::edge_point(lp, m_polynomial, east_front_edge , bbx);
00208 
00209 //     tensor::face(bk, m_polynomial, 2, 0);
00210 //     solver_implicit::edge_point(lp, bk, north_back_edge, bbx);
00211 //     solver_implicit::edge_point(lp, bk, south_back_edge, bbx);
00212 //     solver_implicit::edge_point(lp, bk, west_back_edge , bbx);
00213 //     solver_implicit::edge_point(lp, bk, east_back_edge , bbx);
00214 
00215 //     tensor::face(m_polynomial, m_polynomial, 1, 1);
00216 //     solver_implicit::edge_point(lp, ft, west_edge, bbx);
00217 //     solver_implicit::edge_point(lp, ft, east_edge, bbx);
00218 
00219 //     tensor::face(bk, m_polynomial, 1, 0);
00220 //     solver_implicit::edge_point(lp, bk, west_edge, bbx);
00221 //     solver_implicit::edge_point(lp, bk, east_edge, bbx);
00222 
00223 //    foreach(Point* p, lp) std::cout<<" "<<p->x()<<" "<<p->y()<<" "<<p->z()<<std::endl;
00224 
00225   return has_sign_variation(m_polynomial.begin(),m_polynomial.end());
00226 }
00227 //--------------------------------------------------------------------
00228 TMPL bool 
00229 SELF::is_regular() { 
00230   Polynomial dxf, dyf, dzf;
00231   Polynomial fp0, fp1;
00232   Polynomial bk, ft;
00233 
00234 
00235   tensor::face(bk, m_polynomial, 2, 0);
00236   if(Solver::edge_sign_var(bk, Solver::north_back_edge) >1) return false; 
00237   if(Solver::edge_sign_var(bk, Solver::south_back_edge) >1) return false; 
00238   if(Solver::edge_sign_var(bk, Solver::east_back_edge ) >1) return false; 
00239   if(Solver::edge_sign_var(bk, Solver::west_back_edge ) >1) return false; 
00240 
00241 
00242   tensor::face(ft, m_polynomial, 2, 1);
00243   if(Solver::edge_sign_var(ft, Solver::north_front_edge) >1) return false; 
00244   if(Solver::edge_sign_var(ft, Solver::south_front_edge) >1) return false; 
00245   if(Solver::edge_sign_var(ft, Solver::east_front_edge ) >1) return false; 
00246   if(Solver::edge_sign_var(ft, Solver::west_front_edge ) >1) return false; 
00247 
00248   tensor::face(ft, equation(), 1, 1);
00249   if(Solver::edge_sign_var(ft, Solver::north_west_edge) >1) return false; 
00250   if(Solver::edge_sign_var(ft, Solver::north_east_edge) >1) return false; 
00251 
00252   tensor::face(bk, equation(), 1, 0);
00253   if(Solver::edge_sign_var(bk, Solver::south_west_edge) >1) return false; 
00254   if(Solver::edge_sign_var(bk, Solver::south_east_edge) >1) return false; 
00255 
00256   tensor::diff(dxf.rep(),m_polynomial.rep(),0);
00257   tensor::diff(dyf.rep(),m_polynomial.rep(),1);
00258   tensor::diff(dzf.rep(),m_polynomial.rep(),2);
00259 
00260   if(!has_sign_variation(dxf.begin(),dxf.end())) {
00261 
00262     this->m_idx=0;
00263     return true;
00264     
00265     tensor::face(fp0, dyf, 0, 0);
00266     tensor::face(fp1, dyf, 0, 1);
00267     if(!has_sign_variation(fp0.begin(),fp0.end()) &&
00268        !has_sign_variation(fp1.begin(),fp1.end()) ) return true;
00269 
00270     tensor::face(fp0, dzf, 0, 0);
00271     tensor::face(fp1, dzf, 0, 1);
00272     if(!has_sign_variation(fp0.begin(),fp0.end()) &&
00273        !has_sign_variation(fp1.begin(),fp1.end())) return true;
00274 
00275     return false;
00276   }
00277 
00278   //tensor::diff(dyf.rep(),m_polynomial.rep(),1);
00279   if(!has_sign_variation(dyf.begin(),dyf.end())) {
00280     this->m_idx=1;
00281     return true;
00282 
00283 //     tensor::face(fp0, dzf, 0, 0);
00284 //     tensor::face(fp1, dzf, 0, 1);
00285 //     if(!has_sign_variation(fp0.begin(),fp0.end()) &&
00286 //        !has_sign_variation(fp1.begin(),fp1.end())) return true;
00287 
00288 //     return false;
00289   }
00290 
00291   //tensor::diff(dzf.rep(),m_polynomial.rep(),2);
00292   if(!has_sign_variation(dzf.begin(),dzf.end())) {
00293     this->m_idx=2;
00294     return true;
00295   }
00296 
00297   return false;
00298 }
00299 //--------------------------------------------------------------------
00300 TMPL template<class CELL> void 
00301 SELF::split(CELL*& left, CELL*& right, int v, double c) {
00302   
00303   //  cout<<"Split begin"<<endl;
00304   if(v==0) {
00305     left = new CELL(m_polynomial, BoundingBox(this->xmin(),c, this->ymin(), this->ymax(), this->zmin(), this->zmax()));
00306     right= new CELL(m_polynomial, BoundingBox(c,this->xmax(), this->ymin(), this->ymax(), this->zmin(), this->zmax()));
00307     /*  Update neighbors  */
00308     this->connect0(left, right);
00309     left->join0(right);
00310   } else if (v==1) {
00311     left = new CELL(m_polynomial, BoundingBox(this->xmin(),this->xmax(), this->ymin(), c, this->zmin(), this->zmax()));
00312     right= new CELL(m_polynomial, BoundingBox(this->xmin(),this->xmax(), c, this->ymax(), this->zmin(), this->zmax()));
00313     /*  Update neighbors  */
00314     this->connect1(left, right);
00315     left->join1(right);
00316   } else {//v==2
00317     left = new CELL(m_polynomial, BoundingBox(this->xmin(),this->xmax(),this->ymin(),this->ymax(), this->zmin(), c));
00318     right= new CELL(m_polynomial, BoundingBox(this->xmin(),this->xmax(),this->ymin(),this->ymax(), c, this->zmax()));
00319     /*  Update neighbors  */
00320     this->connect2(left, right);
00321     left->join2(right);
00322   } 
00323   //cell3d_split(left,right,this,v,c);
00324   //  cout<<"Subdivide end "<<*left<<" "<<*right<<endl;
00325   tensor::split(left->m_polynomial, right->m_polynomial, v);
00326   //this->disconnect();
00327 }
00328 
00329 //--------------------------------------------------------------------
00330 TMPL void 
00331 SELF::subdivide(Cell*& Left, Cell*& Right, int v, double c) {
00332   SELF * left=0, * right=0;
00333   this->split(left,right,v,c);
00334   Left=left; Right=right;
00335 }
00336 
00337 //--------------------------------------------------------------------
00338 TMPL bool 
00339 SELF::insert_regular(Topology* t) {
00340   
00341   //  Topology3d* tpl3d= dynamic_cast<Topology3d*>(t);
00342   //  marching_cube::polygonise(*this, *this);
00343     
00344   //  if(this->m_idx == 0) 
00345   
00346   // marching_cube::polygonise(*t, *this); //NOT before topology_regular
00347   //  tpl3d->insert(F);
00348   
00349   
00350   //foreach(Point* p, F->points()) tpl3d->insert(p);
00351   return true;
00352 }
00353 //--------------------------------------------------------------------
00354 TMPL void
00355 SELF::polygonise(Topology3d* t) {
00356   marching_cube::polygonise(*t, *this); 
00357 }
00358 //--------------------------------------------------------------------
00359 TMPL bool 
00360 SELF::insert_singular(Topology* ) {
00361   return true;
00362 }
00363 //--------------------------------------------------------------------
00364 TMPL bool 
00365 SELF::topology_regular(Topology* t) {
00366   
00367   Topology3d* tpl3d= dynamic_cast<Topology3d*>(t);
00368 
00369    if(this->w_neighbors.size()>1)
00370      resolve_conflict(this->w_neighbors, this->xmin(),0 );
00371 
00372    if(this->e_neighbors.size()>1)
00373      resolve_conflict(this->e_neighbors, this->xmax(),0 );
00374 
00375     // foreach(Cell3d* cl, this->n_neighbors) 
00376     //   if(dynamic_cast<SELF*>(cl)->m_faces.size()>0)
00377     //     insert_bbx(tpl3d,cl,1,0);      
00378   
00379   if(this->n_neighbors.size()>1)
00380     resolve_conflict(this->n_neighbors, this->ymax(),1 );
00381 
00382    if(this->s_neighbors.size()>1)
00383      resolve_conflict(this->s_neighbors, this->ymin(),1 );
00384 
00385    if(this->f_neighbors.size()>1)
00386      resolve_conflict(this->f_neighbors, this->zmax(),2 );
00387 
00388    if(this->b_neighbors.size()>1)
00389      resolve_conflict(this->b_neighbors, this->zmin(),2 );
00390 
00391     //output topology
00392   foreach(Point* p, this->m_points)  tpl3d->insert(p);
00393   foreach(Face* f,  this->m_faces)   
00394   {
00395     tpl3d->insert(f);
00396     //if (f->size()>3) insert_bbx(tpl3d, (BoundingBox*)this);
00397   }
00398 
00399   return true;
00400 }
00401 
00402 //--------------------------------------------------------------------
00403 TMPL void
00404 SELF::resolve_conflict(Seq<Cell3d*> &neighb, double side, int cc)
00405 {
00406 
00407   typedef Cell3d Cell3dRef;
00408     Seq<Point*> tmp;
00409     Seq<Edge*> edges;
00410     bool ccw;
00411     
00412     //if (0)
00413     foreach(Face* f1, this->m_faces) 
00414     { // discover wrong egde
00415       ccw= f1->is_ccw();
00416       tmp.clear();
00417       foreach(Point *p, *f1)
00418         if ( (*p)[cc]==side )  //( p->y()==this->ymax() )
00419           tmp<<p;
00420       if ( tmp.size()==2 )
00421       {
00422         Edge * tt=new Edge(tmp[0],tmp[1]);
00423         edges.clear();
00424         foreach(Cell3dRef* cl, neighb) //traverse neighbors 
00425           if(dynamic_cast<SELF*>(cl)->m_faces.size()>0)
00426           {
00427             foreach(Face* f0,dynamic_cast<SELF*>(cl)->m_faces)
00428             {// discover right edges
00429               tmp.clear();
00430               foreach(Point *p, *f0)
00431                 //if ( p->y() == cl->ymin()  )
00432                 if ( (*p)[cc] == side )
00433                   tmp<<p;
00434               if ( tmp.size()==2 )
00435               { //gather edge
00436                 edges<< new Edge( tmp[0],tmp[1]);
00437               }
00438             }
00439           }
00440         if ( edges.size()>0 )
00441         {
00442           std::cout<<"Found big edge on plane "<<cc<<", "<<side<<std::endl;
00443           std::cout<<"adding "<<edges.size() << " edges." <<std::endl;
00444         }
00445         foreach( Edge* e, edges) // Split f1 by adding new edges
00446         {
00447           Face * ff=
00448             new Face( 
00449               e->destination(), 
00450               e->source(), 
00451               f1->not_on(tt) );
00452           if ( ff->is_ccw()!=ccw )
00453             ff->reverse();
00454           this->m_faces <<  ff;
00455         }
00456         m_faces.erase( m_faces.search(f1) );//delete old face
00457       }
00458     }
00459 }
00460 
00461 //--------------------------------------------------------------------
00462 TMPL double
00463 SELF::vertex_eval(unsigned sx, unsigned sy, unsigned sz) const {
00464   
00465   int s=0;
00466   s+= sx*(m_polynomial.rep().env.sz(0)-1)*m_polynomial.rep().env.st(0);
00467   s+= sy*(m_polynomial.rep().env.sz(1)-1)*m_polynomial.rep().env.st(1);
00468   s+= sz*(m_polynomial.rep().env.sz(2)-1)*m_polynomial.rep().env.st(2);
00469   return m_polynomial[s];
00470 }
00471 
00472 //--------------------------------------------------------------------
00473 TMPL int
00474 SELF::mc_index() const {
00475 
00476   double isolevel = 0;
00477   int CubeIndex=0;
00478   
00479   if (vertex_eval(0,1,0) <= isolevel) CubeIndex |= 1;
00480   if (vertex_eval(1,1,0) <= isolevel) CubeIndex |= 2;
00481   if (vertex_eval(1,0,0) <= isolevel) CubeIndex |= 4;
00482   if (vertex_eval(0,0,0) <= isolevel) CubeIndex |= 8;
00483   if (vertex_eval(0,1,1) <= isolevel) CubeIndex |= 16;
00484   if (vertex_eval(1,1,1) <= isolevel) CubeIndex |= 32;
00485   if (vertex_eval(1,0,1) <= isolevel) CubeIndex |= 64;
00486   if (vertex_eval(0,0,1) <= isolevel) CubeIndex |= 128;
00487   
00488   return CubeIndex;
00489 }
00490 //--------------------------------------------------------------------
00491 TMPL bool
00492 SELF::edge_point(Point** CELL, int cube_index) const {
00493   
00494   BoundingBox* bx = (BoundingBox*)this;
00495   Seq<Point*>  F;
00496   Polynomial bk, ft;
00497 
00498   tensor::face(bk, equation(), 2, 0);
00499   if (cube_index & 1) {
00500     Solver::edge_point(F, bk, Solver::north_back_edge, *bx);    
00501     if(F.size()==0) { 
00502       std::cout<<"Problem in MC0"<<std::endl;
00503       return false;
00504     } else
00505       CELL[0] = F[0]; 
00506     F.resize(0);
00507   }
00508   if (cube_index & 2) {
00509     Solver::edge_point(F, bk, Solver::east_back_edge , *bx);
00510     if(F.size()==0) {  
00511       std::cout<<"Problem in MC1"<<std::endl;
00512       return false;
00513     } else
00514       CELL[1] = F[0];  
00515     F.resize(0);
00516   }
00517   if (cube_index & 4) {
00518     Solver::edge_point(F, bk, Solver::south_back_edge, *bx);
00519     if(F.size()==0) {  
00520       std::cout<<"Problem in MC2"<<std::endl;
00521       return false;
00522     } else
00523       CELL[2] = F[0]; 
00524     F.resize(0);
00525   }
00526   if (cube_index & 8) {
00527     Solver::edge_point(F, bk, Solver::west_back_edge , *bx);
00528     if(F.size()==0) { 
00529       std::cout<<"Problem in MC3"<<std::endl;
00530     } else
00531       CELL[3] = F[0]; 
00532     F.resize(0);
00533   }
00534 
00535   tensor::face(ft,equation(), 2, 1);
00536 
00537   if (cube_index & 16) {
00538     Solver::edge_point(F, ft, Solver::north_front_edge, *bx);
00539     if(F.size()==0) { 
00540       std::cout<<"Problem in MC4 "<<std::endl;
00541       return false;
00542       } else
00543       CELL[4] = F[0]; 
00544     F.resize(0);
00545   }
00546   
00547   if (cube_index & 32) {
00548     Solver::edge_point(F, ft, Solver::east_front_edge , *bx);
00549     if(F.size()==0) { 
00550       std::cout<<"Problem in MC5"<<std::endl;
00551       return false;
00552     } else
00553       CELL[5] = F[0]; 
00554     F.resize(0);
00555   }
00556   
00557   if (cube_index & 64) {
00558     Solver::edge_point(F, ft, Solver::south_front_edge, *bx);
00559     if(F.size()==0) {
00560       std::cout<<"Problem in MC6"<<std::endl;
00561       return false;
00562     } else
00563       CELL[6] = F[0]; 
00564     F.resize(0);
00565   }
00566   
00567   if (cube_index & 128) {
00568     Solver::edge_point(F, ft, Solver::west_front_edge , *bx);
00569     if(F.size()==0)  {
00570       std::cout<<"Problem in MC7"<<std::endl;
00571       return false;
00572     } else
00573       CELL[7] = F[0]; 
00574     F.resize(0);
00575   }
00576   
00577   tensor::face(ft, equation(), 1, 1);
00578   if (cube_index & 256) {
00579     Solver::edge_point(F, ft, Solver::north_west_edge, *bx);
00580     if(F.size()==0)  {
00581       std::cout<<"Problem in MC8"<<std::endl;
00582       return false;
00583     } else
00584       CELL[8] = F[0]; 
00585     F.resize(0);
00586   } 
00587   
00588   if (cube_index & 512) {
00589     Solver::edge_point(F, ft, Solver::north_east_edge, *bx);
00590     if(F.size()==0)  {
00591       std::cout<<"Problem in MC9"<<std::endl;
00592       return false;
00593     } else
00594       CELL[9] =  F[0]; 
00595     F.resize(0);
00596   } 
00597   
00598   tensor::face(bk, equation(), 1, 0);
00599   
00600   if (cube_index & 1024) {
00601     Solver::edge_point(F, bk, Solver::south_east_edge, *bx);
00602     if(F.size()==0)  {
00603       std::cout<<"Problem in MC10"<<std::endl;
00604       return false;
00605     } else
00606       CELL[10] = F[0]; 
00607     F.resize(0);
00608     } 
00609   
00610   if (cube_index & 2048) {
00611     Solver::edge_point(F, bk, Solver::south_west_edge, *bx);
00612     if(F.size()==0)  {
00613       std::cout<<"Problem in MC11"<<std::endl;
00614       return false;
00615     } else
00616       CELL[11] = F[0]; 
00617     F.resize(0);
00618   } 
00619 
00620   return true;
00621 }
00622 
00623 //====================================================================
00624 } ; // namespace shape
00625 } ; // namespace mmx
00626 # undef TMPL
00627 # undef TMPL1
00628 # undef Point
00629 # undef Edge
00630 # undef AlgebraicSurface
00631 # undef SELF 
00632 # endif // SHAPE_IMPLICITCELL_H