synaps/topology/point_graph.h

00001 /*********************************************************************
00002 *      This file is part of the source code of SYNAPS library          *
00003 *   Author(s): G. Gatellier                                          *
00004 *              B. Mourrain, GALAAD, INRIA                            *
00005 **********************************************************************/
00006 #ifndef synaps_topology_point_graph_H
00007 #define synaps_topology_point_graph_H
00008 /*********************************************************************/
00009 #include <vector>
00010 #include <map>
00011 #include <synaps/base/Seq.h>
00012 #include <synaps/topology/point.h>
00013 #include <synaps/base/io/axel.h>
00014 #include <synaps/base/io/geomview.h>
00015 /*********************************************************************/
00016 __BEGIN_NAMESPACE_SYNAPS
00017 //--------------------------------------------------------------------
00018 namespace topology
00019 {
00020 
00022 
00026   template<class Pt>
00027   struct ltpts
00028   {
00032     inline bool operator()(const Pt & Pi, const Pt & Pj) 
00033       {return (ptcmp(Pi,Pj) < 0);}
00034   };
00035 
00037 
00053   template<class C, 
00054            class R = Seq<topology::point<C> >, 
00055            class S = Seq<std::vector<int> >
00056           >
00057   struct point_graph  {
00059     typedef S Vect;
00060 
00062     typedef R VectPt;
00063 
00065     typedef typename R::value_type point_t;
00066 
00068     typedef C coeff_t;
00069 
00075     std::map<point_t, int, ltpts<point_t> > Pts_Map;
00076 
00081     R Vertices;
00082 
00088     S Edges;
00089 
00091     int nb_edges;
00092 
00094     point_graph():Vertices(),Edges(),nb_edges() {}
00095 
00097     point_graph(const point_graph<C,R,S> & Graph)
00098       :Pts_Map(Graph.Pts_Map), Vertices(Graph.Vertices), Edges(Graph.Edges) {}
00099 
00107     int access(const point_t & Point) const
00108       {
00109         bool exist = false;
00110         int i;
00111         for( i = 0; i < Vertices.size(); ++i)
00112           {
00113             if ( ptcmp(Point,Vertices[i]) == 0)
00114               {
00115                 exist = true;
00116                 break;
00117               }
00118           }
00119         
00120         if ( exist )
00121           return i;
00122         else
00123           return -1;
00124       }
00125 
00133     int access(point_t * Point) const
00134       {
00135         bool exist = false;
00136         int i;
00137         for( i = 0; i < Vertices.size(); ++i)
00138           {
00139             if ( ptcmp((*Point),Vertices[i]) == 0)
00140               {
00141                 exist = true;
00142                 break;
00143               }
00144           }
00145         
00146         if ( exist )
00147           return i;
00148         else
00149           return -1;
00150       }
00151 
00152 
00160     point_graph(R & V,S & E): 
00161       Vertices(V),Edges(E),nb_edges(E.size()) {}
00162 
00169     inline void insertVertex(const point_t & Point)
00170       {
00171         Vertices.push_back(Point);
00172       }
00173 
00178     inline void createInEdge()
00179       {
00180         typedef typename Vect::value_type type;
00181         type V;
00182         Edges.push_back(V);
00183       }
00184 
00192     int insert(const point_t & Point)
00193       {
00194         int size = Vertices.size();
00195         if (size == 0)
00196           return push_back(Point);
00197         bool exist = false;
00198         int i;
00199         for( i = 0; i < size; ++i)
00200           {
00201             if (ptcmp(Point,Vertices[i]) == 0)
00202               {
00203                 exist = true;
00204                 break;
00205               }
00206           }
00207         if ( exist )
00208             return i;
00209         else
00210           return push_back(Point);
00211       }
00212 
00220     int push_back(const point_t & Point)
00221       {
00222         int indice = Vertices.size();
00223         Pts_Map[(Point)]=indice;
00224         insertVertex(Point);
00225         return indice;
00226       }
00227 
00237     void insert(int  nb_point_begin, 
00238                 int  nb_point_end)
00239       {
00240         int max = std::max(nb_point_end,nb_point_begin);
00241         if (max >= (int)(Edges.size()))
00242           {
00243             for(int i =(int)((Edges.size())-1); i < max; ++i)
00244               createInEdge();
00245           }
00246 
00247         if ( nb_point_begin < nb_point_end )
00248           {
00249             bool isAlready =false;
00250             for(int i = 0; i < (int)Edges[nb_point_begin].size(); ++i)
00251               if (Edges[nb_point_begin][i] == nb_point_end)
00252                 {
00253                   isAlready=true;
00254                   break;
00255                 }
00256             if ( !(isAlready) )
00257               {
00258                 Edges[nb_point_begin].push_back(nb_point_end);
00259                 ++nb_edges;
00260               }
00261           }
00262         else if ( nb_point_begin > nb_point_end )
00263           {
00264             bool isAlready =false;
00265             for(int i = 0; i < (int)Edges[nb_point_end].size(); ++i)
00266               if (Edges[nb_point_end][i] == nb_point_begin)
00267                 {
00268                   isAlready=true;
00269                   break;
00270                 }
00271             if ( !(isAlready) )
00272               {
00273                 Edges[nb_point_end].push_back(nb_point_begin);
00274                 ++nb_edges;
00275               }
00276           }
00277       }
00278 
00279     //----------------------------------------------------------------
00280     // Functions will be useful for the topology of one surface ??
00281     // (For the next developper)
00282     //----------------------------------------------------------------
00283 
00291     void graphAddCoord(const coeff_t & value, const int & ind)
00292       {
00293         std::map<point_t, int, ltpts<point_t> > auxiliar_map;
00294         if (Vertices.size() != 0)
00295           {
00296             int size = Vertices[0].size();
00297             assert( ind<(size+1) );
00298             int indice = Vertices.size();
00299             
00300             for(int i = 0; i < indice; ++i)
00301               {
00302                 if (size == ind)
00303                   {
00304                     Vertices[i].resize(size+1);
00305                     Vertices[i][size] = value;
00306                     auxiliar_map[(Vertices[i])] = i;
00307                   }
00308                 else
00309                   {
00310                     Vertices[i][ind] = value;
00311                     auxiliar_map[(Vertices[i])] = i;
00312                   }
00313               }
00314             Pts_Map.clear();
00315             Pts_Map = auxiliar_map;
00316           }
00317       }
00318 
00326     void graphSwap(const int & ind_i, const int & ind_j)
00327       {
00328         std::map<point_t, int, ltpts<point_t> > auxiliar_map;
00329         int indice = Vertices.size();
00330         for(int i = 0; i < indice; ++i)
00331           {
00332             coeff_t aux = Vertices[i][ind_i];
00333             Vertices[i][ind_i] = Vertices[i][ind_j];
00334             Vertices[i][ind_j] = aux;
00335             auxiliar_map[(Vertices[i])] = i;
00336           }
00337         Pts_Map.clear();
00338         Pts_Map = auxiliar_map;
00339       }
00340 
00341 
00350     void rotationGraph(const coeff_t & t)
00351       {
00352         std::map<point_t, int, ltpts<point_t> > auxiliar_map;
00353         if (Vertices.size() != 0)
00354           {
00355             int size = Vertices[0].size();
00356             int indice = Vertices.size();
00357             for(int i = 0; i < indice; ++i)
00358               {
00359                 point_t newPoint(size);
00360                 rotation3d(newPoint,Vertices[i],t);
00361                 Vertices[i] = newPoint;
00362                 auxiliar_map[(Vertices[i])] = i;
00363               }
00364             Pts_Map.clear();
00365             Pts_Map = auxiliar_map;
00366           }
00367       }
00368 
00375     void graphInsert(const point_graph<C,R,S> & Graph)
00376       {
00377         int indice = Graph.Edges.size();
00378         for(int i = 0; i < indice; ++i)
00379           {
00380             int begin = insert(Graph.Vertices[i]);
00381             for(int j = 0; j < (int)Graph.Edges[i].size(); ++j)
00382               {
00383                 int end = insert(Graph.Vertices[Graph.Edges[i][j]]);
00384                 push_back(begin,end);
00385               }
00386           }
00387       }
00388 
00389   };
00390   //--------------------------------------------------------------------
00391   template<class C, class R>
00392   std::ostream & operator<<(std::ostream& os, const point_graph<C,R>& g)
00393   {
00394     os <<"PointGraph("<<g.Vertices;
00395     for(unsigned i=0;i<g.Edges.size();i++)
00396       {
00397         if(g.Edges[i].size())
00398           {
00399             for(unsigned j=0; j<g.Edges[i].size();j++) 
00400               os <<"; ("<<i<<","<<g.Edges[i][j]<<")";
00401           }
00402       }
00403     os <<")";  return os;
00404   }
00405   
00406   template <class C, class R, class S>
00407   void print( char* file,
00408               const point_graph<C,R,S> & G,
00409               float r = 0.0, float g = 0.0,
00410               float b = 0.9, float a = 1.,
00411               float sz= 0.01)
00412   {
00413     typedef typename point_graph<C,R,S>::point_t point_t;
00414 
00415     std::vector< std::pair<int,int> > lines;
00416     for( unsigned  i = 0;  i <  G.Edges.size(); i++ )
00417       for( unsigned j = 0; j < G.Edges[i].size(); j++ )
00418         lines.push_back( std::pair<unsigned,unsigned>(i,G.Edges[i][j]) );
00419 
00420     point_t pt1, pt2;
00421     std::ofstream f;
00422     f.open (file, std::ofstream::out | std::ofstream::app);
00423 
00424     int size = (int)lines.size();
00425 
00426     // Number of Lines.
00427     f << size <<  " ";
00428 
00429     // Number of Points.
00430     f << (2*size) << " ";
00431 
00432     // For the colors.
00433     f << size <<  std::endl;
00434 
00435     for(int i = 1; i <= size; ++i)
00436       f<<"2 ";
00437 
00438     f<<std::endl;
00439 
00440     for(int i = 1; i <= size; ++i)
00441       f<<"1 ";
00442 
00443     f<<std::endl;
00444 
00445     for(int i = 0; i < size; ++i)
00446       {
00447         pt1=G.Vertices[lines[i].first];
00448         pt2=G.Vertices[lines[i].second];
00449         if(pt1.size()<3)
00450           f <<pt1[0]<<" "<<pt1[1]<<" "<<0<<" ";
00451         else
00452           f <<pt1[0]<<" "<<pt1[1]<<" "<<pt1[2]<<" ";
00453 
00454         if(pt2.size()<3)
00455           f <<pt2[0]<<" "<<pt2[1]<<" "<<0<<std::endl;
00456         else
00457           f <<pt2[0]<<" "<<pt2[1]<<" "<<pt2[2]<<std::endl;
00458       }
00459     f<<std::endl;
00460     for(int i = 0; i < size; ++i)
00461       f << r << " " << g << " " << b << " " << a  <<"\n";
00462 
00463 
00464     /*
00465     f << G.Vertices.size()  << " " << lines.size() << std::endl;
00466     for ( unsigned i = 0; i < G.Vertices.size(); i ++ )
00467       {
00468         unsigned m = std::min((unsigned)3,G.Vertices[i].size());
00469         for ( unsigned d = 0; d < m; d++ )
00470           f << G.Vertices[i][d] << " ";
00471         for ( unsigned d = m; d < 3; d++ )
00472           f << "0 ";
00473         f << std::endl;
00474       };
00475     
00476     f << 2 << " " << lines[0].first << " " << lines[0].second //<< std::endl;
00477       << " "<< r << " " << g << " " << b << " " << a << std::endl;
00478     for ( unsigned i = 1; i < lines.size(); i ++)
00479       f << 2 << " " << lines[i].first << " " << lines[i].second
00480         << " "<< r << " " << g << " " << b << " " << a << std::endl;
00481       for(unsigned i=0; i< G.Vertices.size(); i++) 
00482       { 
00483       print(f,G.Vertices[i],r,g,b,a,sz);
00484       }
00485     */
00486     f.close(); 
00487   }
00488 
00489   
00490   template <class C, class R, class S>
00491   geomview::ostream & operator<< (geomview::ostream & os, 
00492                                   const point_graph<C,R,S> & G)
00493   {
00494 
00495     os<<"{= VECT\n";
00496     print(os.file,G,os.color.r,os.color.g,os.color.b,1,os.width.sz); 
00497     os <<"}\n";
00498     return os;
00499   }
00500 
00501   template <class C, class R, class S>
00502   axel::ostream & operator<< (axel::ostream & os, 
00503                               const point_graph<C,R,S> & G)
00504   {
00505     os<<"<curve type=\"mesh\">\n<vect>\nVECT\n";
00506     print(os.file,G,os.color.r,os.color.g,os.color.b,1,os.width.sz); 
00507     os<<"</vect>\n</curve>\n";
00508     return os;
00509   }
00510 
00511 
00512 }
00513 
00514 //--------------------------------------------------------------------
00515 __END_NAMESPACE_SYNAPS
00516 /*********************************************************************/
00517 #endif // synaps_topology_point_graph_H

SYNAPS DOCUMENTATION
logo