shape_doc 0.1
/Users/mourrain/Devel/mmx/shape/include/shape/dualize.hpp
Go to the documentation of this file.
00001 /*****************************************************************************
00002  * M a t h e m a g i x
00003  *****************************************************************************
00004  * 2011-04-26
00005  * Bernard Mourrain
00006  *****************************************************************************
00007  *               Copyright (C) 2011 INRIA Sophia-Antipolis
00008  *****************************************************************************
00009  * Comments :
00010  ****************************************************************************/
00011 # ifndef shape_dualize_hpp
00012 # define shape_dualize_hpp
00013 
00014 # include <shape/list.hpp>
00015 # include <shape/kdtree_cell.hpp>
00016 
00017 # define TMPL   template<class C,class V, class Shape, class Cell>
00018 # define TMPL1  template<class V>
00019 # define SELF   dualize<C,V,Shape,Cell> 
00020 //====================================================================
00021 namespace mmx { namespace shape {
00022 //====================================================================
00023 template<class Shape, class Cell>
00024 struct graph_dual {
00025 
00026   typedef node<Shape*,Cell*>         Node;
00027 
00028 public:
00029   Seq<Node*>      m_edges;
00030   Seq<Node*>      m_faces;
00031 };
00032 
00033 
00034 template<class C,class V=default_env, class Shape=typename SHAPE_OF(V), class Cell=cell<C,V> >
00035 struct dualize: public PROCESS_OF(V)
00036 {
00037 
00038   typedef node<Shape*,Cell*>                  Node;
00039   typedef kdtree_cell<Shape,Cell>               Input;
00040   typedef graph_dual<Shape,Cell>              Output;
00041 
00042   dualize(void);
00043  ~dualize(void) ;
00044 
00045   void    set_input (Input* i) { m_input = i; }
00046 
00047   Input*  input  (void)     { return m_input; }
00048   Output* output (void)     { return m_output; }
00049 
00050   void run();
00051 
00052   void get_dual_vertex(Node*);
00053   void get_dual_edge(Node*, Node*);
00054   void get_dual_face(Node*, Node*, Node*);
00055   void get_dual_face(Node*, Node*, Node*, Node*);
00056 
00057   void clear(void);
00058 
00059 private:
00060   Input*       m_input;
00061   Output*      m_output;
00062 };
00063 //--------------------------------------------------------------------
00064 TMPL SELF::dualize() {
00065   m_output = new Output;
00066 }
00067 //--------------------------------------------------------------------
00068 TMPL SELF::~dualize(void) {
00069   delete m_output;
00070 }
00071 //--------------------------------------------------------------------
00072 TMPL void SELF::get_dual_vertex(Node* n) {
00073   if(!n->get_cell()->is_active()) return;
00074   if(!n->is_leaf()) {
00075     this->get_dual_vertex(n->left()); 
00076     this->get_dual_vertex(n->right()); 
00077     this->get_dual_edge(n->left(),n->right()); 
00078   }
00079   return;
00080 }
00081 
00082 //--------------------------------------------------------------------
00083 TMPL void SELF::get_dual_edge(Node* n1, Node* n2) {
00084   if(!n1->get_cell()->is_active()) return;
00085   if(!n2->get_cell()->is_active()) return;
00086   if(!is_adjacentpl3d(n1->get_cell(),n2->get_cell())) return;
00087 
00088   if(!n1->is_leaf()) { 
00089     get_dual_edge(n1->left(),  n2);
00090     get_dual_edge(n1->right(), n2);
00091     get_dual_face(n1->left(), n1->right(), n2);
00092     return;
00093   } 
00094 
00095   if(!n2->is_leaf()){
00096     get_dual_edge(n1,  n2->left());
00097     get_dual_edge(n1,  n2->right());
00098     get_dual_face(n1,  n2->left(), n2->right());
00099     return;
00100   }
00101 
00102   this->output()->m_edges<<n1<<n2;
00103   return;
00104 }
00105 
00106 //--------------------------------------------------------------------
00107 TMPL void SELF::get_dual_face(Node* n1, Node* n2, Node* n3) {
00108   if(!n1->get_cell()->is_active()) return;
00109   if(!n2->get_cell()->is_active()) return;
00110   if(!n3->get_cell()->is_active()) return;
00111   if(!is_adjacentpl3d(n1->get_cell(),n2->get_cell()) ||
00112      !is_adjacentpl3d(n2->get_cell(),n3->get_cell()) ||
00113      !is_adjacentpl3d(n3->get_cell(),n1->get_cell()) ) return;
00114 
00115   if(!n1->is_leaf()){
00116     if(is_adjacentpl3d(n1->left()->get_cell(),n2->get_cell())) {
00117       if(is_adjacentpl3d(n1->left()->get_cell(),n3->get_cell()))
00118         get_dual_face(n1->left(),n2,n3);
00119       else
00120       if(is_adjacentpl3d(n1->right()->get_cell(),n3->get_cell()))
00121         get_dual_face(n1->right(),n1->left(),n2,n3);
00122     } 
00123 
00124     if(is_adjacentpl3d(n1->right()->get_cell(),n2->get_cell())) {
00125       if(is_adjacentpl3d(n1->right()->get_cell(),n3->get_cell()))
00126         get_dual_face(n1->right(),n2,n3);
00127       else
00128       if(is_adjacentpl3d(n1->left()->get_cell(),n3->get_cell()))
00129         get_dual_face(n1->left(),n1->right(),n2,n3);
00130     }
00131     return;
00132   } 
00133 
00134   if(!n2->is_leaf()){
00135     if(is_adjacentpl3d(n2->left()->get_cell(),n3->get_cell())) {
00136       if(is_adjacentpl3d(n2->left()->get_cell(),n1->get_cell()))
00137         get_dual_face(n1, n2->left(),n3);
00138       else
00139       if(is_adjacentpl3d(n2->right()->get_cell(),n1->get_cell()))
00140         get_dual_face(n1, n2->right(),n2->left(),n3);
00141     } 
00142 
00143     if(is_adjacentpl3d(n2->right()->get_cell(),n3->get_cell())) {
00144       if(is_adjacentpl3d(n2->right()->get_cell(),n1->get_cell()))
00145         get_dual_face(n1, n2->right(),n3);
00146        else
00147       if(is_adjacentpl3d(n2->left()->get_cell(),n1->get_cell()))
00148         get_dual_face(n1,n2->left(),n2->right(),n3);
00149     }
00150     return;
00151   } 
00152 
00153   if(!n3->is_leaf()){
00154     if(is_adjacentpl3d(n3->left()->get_cell(),n1->get_cell())) {
00155       if(is_adjacentpl3d(n3->left()->get_cell(),n2->get_cell()))
00156         get_dual_face(n1,n2,n3->left());
00157       else
00158       if(is_adjacentpl3d(n3->right()->get_cell(),n2->get_cell()))
00159         get_dual_face(n1,n2,n3->right(),n3->left());
00160     } 
00161 
00162     if(is_adjacentpl3d(n3->right()->get_cell(),n1->get_cell())) {
00163       if(is_adjacentpl3d(n3->right()->get_cell(),n2->get_cell()))
00164         get_dual_face(n1,n2,n3->right());
00165       else
00166       if(is_adjacentpl3d(n3->left()->get_cell(),n2->get_cell()))
00167         get_dual_face(n1,n2,n3->left(),n3->right());
00168     }
00169     return;
00170   } 
00171 
00172   this->output()->m_faces<<n1<<n2<<n3;
00173   return;
00174 }
00175 
00176 //--------------------------------------------------------------------
00177 TMPL void SELF::get_dual_face(Node* n1, Node* n2, Node* n3, Node* n4) {
00178   if(!n1->get_cell()->is_active()) return;
00179   if(!n2->get_cell()->is_active()) return;
00180   if(!n3->get_cell()->is_active()) return;
00181   if(!n4->get_cell()->is_active()) return;
00182   if(!is_adjacentpl3d(n1->get_cell(),n2->get_cell()) ||
00183      !is_adjacentpl3d(n2->get_cell(),n3->get_cell()) ||
00184      !is_adjacentpl3d(n3->get_cell(),n4->get_cell()) ||
00185      !is_adjacentpl3d(n4->get_cell(),n1->get_cell()) ) return;
00186 
00187   if(!n1->is_leaf()){
00188     get_dual_face(n1->left(), n2,n3,n4);
00189     get_dual_face(n1->right(),n2,n3,n4);
00190     return;
00191   }
00192 
00193   if(!n2->is_leaf()){
00194     get_dual_face(n1,n2->left(), n3,n4);
00195     get_dual_face(n1,n2->right(),n3,n4);
00196     return;
00197   }
00198 
00199   if(!n3->is_leaf()){
00200     get_dual_face(n1,n2,n3->left(), n4);
00201     get_dual_face(n1,n2,n3->right(),n4);
00202     return;
00203   }
00204 
00205   if(!n4->is_leaf()){
00206     get_dual_face(n1,n2,n3,n4->left());
00207     get_dual_face(n1,n2,n3,n4->right());
00208     return;
00209   }
00210         
00211   this->output()->m_faces<<n1<<n2<<n3;
00212   this->output()->m_faces<<n1<<n4<<n3;
00213   return;
00214 }
00215 //--------------------------------------------------------------------
00216 TMPL void SELF::run() {
00217   this->get_dual_vertex(m_input->root());
00218 }
00219 //--------------------------------------------------------------------
00220 TMPL void SELF::clear(void) {
00221   
00222 }
00223 
00224 //====================================================================
00225 } ; // namespace shape
00226 } ; // namespace mmx
00227 //====================================================================
00228 # undef TMPL
00229 # undef TMPL1
00230 # undef SELF 
00231 # endif