EdgeSetTopologyContainer.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <sofa/component/topology/EdgeSetTopologyContainer.h>
00026
00027 #include <sofa/core/ObjectFactory.h>
00028
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
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())
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
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())
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
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())
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())
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 }
00294
00295 }
00296
00297 }
00298