EdgeSetTopologyContainer.cpp

Go to the documentation of this file.
00001 /******************************************************************************
00002 *       SOFA, Simulation Open-Framework Architecture, version 1.0 beta 3      *
00003 *                (c) 2006-2008 MGH, INRIA, USTL, UJF, CNRS                    *
00004 *                                                                             *
00005 * This library is free software; you can redistribute it and/or modify it     *
00006 * under the terms of the GNU Lesser General Public License as published by    *
00007 * the Free Software Foundation; either version 2.1 of the License, or (at     *
00008 * your option) any later version.                                             *
00009 *                                                                             *
00010 * This library is distributed in the hope that it will be useful, but WITHOUT *
00011 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       *
00012 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
00013 * for more details.                                                           *
00014 *                                                                             *
00015 * You should have received a copy of the GNU Lesser General Public License    *
00016 * along with this library; if not, write to the Free Software Foundation,     *
00017 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.          *
00018 *******************************************************************************
00019 *                               SOFA :: Modules                               *
00020 *                                                                             *
00021 * Authors: The SOFA Team and external contributors (see Authors.txt)          *
00022 *                                                                             *
00023 * Contact information: contact@sofa-framework.org                             *
00024 ******************************************************************************/
00025 #include <sofa/component/topology/EdgeSetTopologyContainer.h>
00026 
00027 #include <sofa/core/ObjectFactory.h>
00028 // Use BOOST GRAPH LIBRARY : 
00029 
00030 #include <boost/config.hpp>
00031 #include <iostream>
00032 #include <vector>
00033 #include <utility>
00034 
00035 #include <boost/graph/adjacency_list.hpp>
00036 #include <boost/graph/connected_components.hpp>
00037 
00038 #include <boost/graph/cuthill_mckee_ordering.hpp>
00039 #include <boost/graph/bandwidth.hpp>
00040 
00041 #include <sofa/component/MeshLoader.h>
00042 
00043 namespace sofa
00044 {
00045 
00046 namespace component
00047 {
00048 
00049 namespace topology
00050 {
00051 
00052     using namespace std;
00053     using namespace sofa::defaulttype;
00054         SOFA_DECL_CLASS(EdgeSetTopologyContainer)
00055         int EdgeSetTopologyContainerClass = core::RegisterObject("Edge set topology container")
00056       .add< EdgeSetTopologyContainer >()
00057       ;
00058 
00059     EdgeSetTopologyContainer::EdgeSetTopologyContainer()
00060     : PointSetTopologyContainer( )
00061     {}
00062 
00063 EdgeSetTopologyContainer::EdgeSetTopologyContainer(const sofa::helper::vector< Edge > &edges )
00064 : PointSetTopologyContainer( )
00065 , m_edge( edges )
00066 {
00067     for (unsigned int i=0; i<m_edge.size(); ++i)
00068     {
00069         for(unsigned int j=0; j<2; ++j)
00070         {
00071             int a = m_edge[i][j];
00072             if (a >= (int)nbPoints) nbPoints = a+1;
00073         }
00074     }
00075 }
00076 
00077     void EdgeSetTopologyContainer::init()
00078     {
00079         PointSetTopologyContainer::init();
00080     }
00081 
00082     void EdgeSetTopologyContainer::loadFromMeshLoader(sofa::component::MeshLoader* loader)
00083     {
00084         // load points
00085         PointSetTopologyContainer::loadFromMeshLoader(loader);
00086         m_edge = loader->getEdges();
00087     }
00088 
00089     void EdgeSetTopologyContainer::addEdge(int a, int b)
00090     {
00091         m_edge.push_back(Edge(a,b));
00092         if (a >= (int)nbPoints) nbPoints = a+1;
00093         if (b >= (int)nbPoints) nbPoints = b+1;
00094     }
00095 
00096     void EdgeSetTopologyContainer::createEdgeVertexShellArray()
00097     {
00098         if(!hasEdges()) // this method should only be called when edges exist
00099         {
00100     #ifndef NDEBUG
00101             cout << "Warning. [EdgeSetTopologyContainer::createEdgeVertexShellArray] edge array is empty." << endl;
00102     #endif
00103             createEdgeSetArray();
00104         }
00105 
00106         if(hasEdgeVertexShell())
00107         {
00108             clearEdgeVertexShell();
00109         }
00110 
00111         m_edgeVertexShell.resize( getNbPoints() );
00112 
00113         for (unsigned int edge=0; edge<m_edge.size(); ++edge)
00114         {
00115             // adding edge in the edge shell of both points
00116             m_edgeVertexShell[ m_edge[edge][0] ].push_back(edge);
00117             m_edgeVertexShell[ m_edge[edge][1] ].push_back(edge);
00118         }
00119     }
00120 
00121     void EdgeSetTopologyContainer::createEdgeSetArray()
00122     {
00123     #ifndef NDEBUG
00124         cout << "Error. [EdgeSetTopologyContainer::createEdgeSetArray] This method must be implemented by a child topology." << endl;
00125     #endif
00126     }
00127 
00128     const sofa::helper::vector<Edge> &EdgeSetTopologyContainer::getEdgeArray()
00129     {
00130         if(!hasEdges() && getNbPoints()>0)
00131         {
00132     #ifndef NDEBUG
00133             cout << "Warning. [EdgeSetTopologyContainer::getEdgeArray] creating edge array." << endl;
00134     #endif
00135             createEdgeSetArray();
00136         }
00137 
00138         return m_edge;
00139     }
00140 
00141     int EdgeSetTopologyContainer::getEdgeIndex(PointID v1, PointID v2)
00142     {
00143         if(!hasEdges()) // this method should only be called when edges exist
00144         {
00145     #ifndef NDEBUG
00146             cout << "Warning. [EdgeSetTopologyContainer::getEdgeIndex] edge array is empty." << endl;
00147     #endif
00148             createEdgeSetArray();
00149         }
00150 
00151         if(!hasEdgeVertexShell())
00152             createEdgeVertexShellArray();
00153 
00154         const sofa::helper::vector< unsigned int > &es1 = getEdgeVertexShell(v1) ;
00155         
00156         int result = -1;
00157         for(unsigned int i=0; (i < es1.size()) && (result == -1); ++i) 
00158         {
00159             const Edge &e = m_edge[ es1[i] ];
00160             if ((e[0] == v2) || (e[1] == v2))
00161                 result = (int) es1[i];
00162         }
00163         return result;
00164     }
00165 
00166     // Return the number of connected components from the graph containing all edges and give, for each vertex, which component it belongs to  (use BOOST GRAPH LIBRAIRY)
00167     int EdgeSetTopologyContainer::getNumberConnectedComponents(sofa::helper::vector<unsigned int>& components)
00168     {
00169         using namespace boost;
00170 
00171         typedef adjacency_list <vecS, vecS, undirectedS> Graph;
00172 
00173         Graph G;
00174 
00175         for (unsigned int k=0; k<m_edge.size(); ++k) 
00176         {
00177             add_edge(m_edge[k][0], m_edge[k][1], G);
00178         }
00179 
00180         components.resize(num_vertices(G));
00181         int num = (int) connected_components(G, &components[0]);
00182 
00183         return num;
00184     }
00185 
00186     bool EdgeSetTopologyContainer::checkTopology() const
00187     {
00188     #ifndef NDEBUG
00189         bool ret = true;
00190         
00191         if(hasEdgeVertexShell()) 
00192         {
00193             for (unsigned int i=0; i<m_edgeVertexShell.size(); ++i) 
00194             {
00195                 const sofa::helper::vector<unsigned int> &es = m_edgeVertexShell[i];
00196 
00197                 for (unsigned int j=0; j<es.size(); ++j)
00198                 {
00199                     bool check_edge_vertex_shell = (m_edge[ es[j] ][0] == i) ||  (m_edge[ es[j] ][1] == i);
00200                     if(! check_edge_vertex_shell)
00201                     {
00202                         std::cout << "*** CHECK FAILED : check_edge_vertex_shell, i = " << i << " , j = " << j << std::endl;
00203                         ret = false;
00204                     }
00205                 }
00206             }
00207         }
00208 
00209         return ret &&  PointSetTopologyContainer::checkTopology();
00210     #else
00211         return true;
00212     #endif
00213     }
00214 
00215     unsigned int EdgeSetTopologyContainer::getNumberOfEdges() const
00216     {
00217         return m_edge.size();
00218     }
00219 
00220     const sofa::helper::vector< sofa::helper::vector<unsigned int> > &EdgeSetTopologyContainer::getEdgeVertexShellArray() 
00221     {
00222         if(!hasEdgeVertexShell())
00223         {
00224     #ifndef NDEBUG
00225             cout << "Warning. [EdgeSetTopologyContainer::getEdgeVertexShellArray] edge vertex shell array is empty." << endl;
00226     #endif
00227             createEdgeVertexShellArray();
00228         }
00229 
00230         return m_edgeVertexShell;
00231     }
00232 
00233     const VertexEdges& EdgeSetTopologyContainer::getEdgeVertexShell(PointID i)
00234     {
00235         if(!hasEdgeVertexShell())   // this method should only be called when the shell array exists
00236         {
00237     #ifndef NDEBUG
00238             cout << "Warning. [EdgeSetTopologyContainer::getEdgeVertexShell] edge vertex shell array is empty." << endl;
00239     #endif
00240             createEdgeVertexShellArray();
00241         }
00242 
00243     #ifndef NDEBUG
00244         if(m_edgeVertexShell.size() <= i)
00245             cout << "Error. [EdgeSetTopologyContainer::getEdgeVertexShell] edge vertex shell array out of bounds: "
00246                  << i << " >= " << m_edgeVertexShell.size() << endl;
00247     #endif
00248 
00249         return m_edgeVertexShell[i];
00250     }
00251 
00252     sofa::helper::vector< unsigned int > &EdgeSetTopologyContainer::getEdgeVertexShellForModification(const unsigned int i)
00253     {
00254         if(!hasEdgeVertexShell())   // this method should only be called when the shell array exists
00255         {
00256     #ifndef NDEBUG
00257             cout << "Warning. [EdgeSetTopologyContainer::getEdgeVertexShellForModification] edge vertex shell array is empty." << endl;
00258     #endif
00259             createEdgeVertexShellArray();
00260         }
00261 
00262         return m_edgeVertexShell[i];
00263     }
00264 
00265     bool EdgeSetTopologyContainer::hasEdges() const 
00266     {
00267         return !m_edge.empty();
00268     }
00269 
00270     bool EdgeSetTopologyContainer::hasEdgeVertexShell() const 
00271     {
00272         return !m_edgeVertexShell.empty();
00273     }
00274 
00275     void EdgeSetTopologyContainer::clearEdges()
00276     {
00277         m_edge.clear();
00278     }
00279 
00280     void EdgeSetTopologyContainer::clearEdgeVertexShell()
00281     {
00282         m_edgeVertexShell.clear();
00283     }
00284 
00285     void EdgeSetTopologyContainer::clear()
00286     {
00287         clearEdges();
00288         clearEdgeVertexShell();
00289 
00290         PointSetTopologyContainer::clear();
00291     }
00292 
00293 } // namespace topology
00294 
00295 } // namespace component
00296 
00297 } // namespace sofa
00298 

Generated on Sun Nov 23 03:43:31 2008 for Sofa by  doxygen 1.5.7.1