QuadSetTopologyContainer.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
00026 #include <sofa/component/topology/QuadSetTopologyContainer.h>
00027
00028 #include <sofa/core/ObjectFactory.h>
00029
00030 #include <sofa/component/MeshLoader.h>
00031
00032 namespace sofa
00033 {
00034 namespace component
00035 {
00036 namespace topology
00037 {
00038 using namespace std;
00039 using namespace sofa::defaulttype;
00040
00041 SOFA_DECL_CLASS(QuadSetTopologyContainer)
00042 int QuadSetTopologyContainerClass = core::RegisterObject("Quad set topology container")
00043 .add< QuadSetTopologyContainer >()
00044 ;
00045
00046 QuadSetTopologyContainer::QuadSetTopologyContainer()
00047 : EdgeSetTopologyContainer()
00048 {}
00049
00050 QuadSetTopologyContainer::QuadSetTopologyContainer(const sofa::helper::vector< Quad >& quads )
00051 : EdgeSetTopologyContainer()
00052 , m_quad( quads )
00053 {
00054 for (unsigned int i=0; i<m_quad.size(); ++i)
00055 {
00056 for(unsigned int j=0; j<4; ++j)
00057 {
00058 int a = m_quad[i][j];
00059 if (a >= (int)nbPoints) nbPoints = a+1;
00060 }
00061 }
00062 }
00063
00064 void QuadSetTopologyContainer::addQuad( int a, int b, int c, int d )
00065 {
00066 m_quad.push_back(Quad(a,b,c,d));
00067 if (a >= (int)nbPoints) nbPoints = a+1;
00068 if (b >= (int)nbPoints) nbPoints = b+1;
00069 if (c >= (int)nbPoints) nbPoints = c+1;
00070 if (d >= (int)nbPoints) nbPoints = d+1;
00071 }
00072
00073 void QuadSetTopologyContainer::init()
00074 {
00075 EdgeSetTopologyContainer::init();
00076 }
00077
00078 void QuadSetTopologyContainer::loadFromMeshLoader(sofa::component::MeshLoader* loader)
00079 {
00080
00081 PointSetTopologyContainer::loadFromMeshLoader(loader);
00082 m_quad = loader->getQuads();
00083 }
00084
00085 void QuadSetTopologyContainer::createQuadSetArray()
00086 {
00087 #ifndef NDEBUG
00088 cout << "Error. [QuadSetTopologyContainer::createQuadSetArray] This method must be implemented by a child topology." << endl;
00089 #endif
00090 }
00091
00092 void QuadSetTopologyContainer::createQuadVertexShellArray()
00093 {
00094 if(!hasQuads())
00095 {
00096 #ifndef NDEBUG
00097 cout << "Warning. [QuadSetTopologyContainer::createQuadVertexShellArray] quad array is empty." << endl;
00098 #endif
00099 createQuadSetArray();
00100 }
00101
00102 if(hasQuadVertexShell())
00103 {
00104 clearQuadVertexShell();
00105 }
00106
00107 m_quadVertexShell.resize( getNbPoints() );
00108
00109 for (unsigned int i=0; i<m_quad.size(); ++i)
00110 {
00111
00112 for (unsigned int j=0; j<4; ++j)
00113 {
00114 m_quadVertexShell[ m_quad[i][j] ].push_back( i );
00115 }
00116 }
00117 }
00118
00119 void QuadSetTopologyContainer::createQuadEdgeShellArray()
00120 {
00121 if(!hasQuads())
00122 {
00123 #ifndef NDEBUG
00124 cout << "Warning. [QuadSetTopologyContainer::createQuadEdgeShellArray] quad array is empty." << endl;
00125 #endif
00126 createQuadSetArray();
00127 }
00128
00129 if(!hasEdges())
00130 {
00131 #ifndef NDEBUG
00132 cout << "Warning. [QuadSetTopologyContainer::createQuadEdgeShellArray] edge array is empty." << endl;
00133 #endif
00134 createEdgeSetArray();
00135 }
00136
00137 if(!hasQuadEdges())
00138 createQuadEdgeArray();
00139
00140 const unsigned int numQuads = getNumberOfQuads();
00141 const unsigned int numEdges = getNumberOfEdges();
00142
00143 if(hasQuadEdgeShell())
00144 {
00145 clearQuadEdgeShell();
00146 }
00147
00148 m_quadEdgeShell.resize(numEdges);
00149
00150 for (unsigned int i=0; i<numQuads; ++i)
00151 {
00152
00153 for (unsigned int j=0; j<4; ++j)
00154 {
00155 m_quadEdgeShell[ m_quadEdge[i][j] ].push_back( i );
00156 }
00157 }
00158 }
00159
00160 void QuadSetTopologyContainer::createEdgeSetArray()
00161 {
00162 if(!hasQuads())
00163 {
00164 #ifndef NDEBUG
00165 cout << "Warning. [QuadSetTopologyContainer::createEdgeSetArray] quad array is empty." << endl;
00166 #endif
00167 createQuadSetArray();
00168 }
00169
00170 if(hasEdges())
00171 {
00172 #ifndef NDEBUG
00173 cout << "Warning. [QuadSetTopologyContainer::createEdgeSetArray] edge array is not empty." << endl;
00174 #endif
00175
00176
00177 EdgeSetTopologyContainer::clear();
00178
00179 if(hasQuadEdges())
00180 clearQuadEdges();
00181
00182 if(hasQuadEdgeShell())
00183 clearQuadEdgeShell();
00184 }
00185
00186
00187 std::map<Edge, unsigned int> edgeMap;
00188
00189 for (unsigned int i=0; i<m_quad.size(); ++i)
00190 {
00191 const Quad &t = m_quad[i];
00192 for(unsigned int j=0; j<4; ++j)
00193 {
00194 const unsigned int v1 = t[(j+1)%4];
00195 const unsigned int v2 = t[(j+2)%4];
00196
00197
00198 const Edge e = ((v1<v2) ? Edge(v1,v2) : Edge(v2,v1));
00199
00200 if(edgeMap.find(e) == edgeMap.end())
00201 {
00202
00203 const int edgeIndex = edgeMap.size();
00204 edgeMap[e] = edgeIndex;
00205 m_edge.push_back(e);
00206 }
00207 }
00208 }
00209 }
00210
00211 void QuadSetTopologyContainer::createQuadEdgeArray()
00212 {
00213 if(!hasQuads())
00214 {
00215 #ifndef NDEBUG
00216 cout << "Warning. [QuadSetTopologyContainer::createQuadEdgeArray] quad array is empty." << endl;
00217 #endif
00218 createQuadSetArray();
00219 }
00220
00221 if(!hasEdges())
00222 {
00223 #ifndef NDEBUG
00224 cout << "Warning. [QuadSetTopologyContainer::createQuadEdgeArray] edge array is empty." << endl;
00225 #endif
00226 createEdgeSetArray();
00227 }
00228
00229 if(hasQuadEdges())
00230 clearQuadEdges();
00231
00232 const unsigned int numQuads = getNumberOfQuads();
00233
00234 m_quadEdge.resize( numQuads );
00235
00236 for(unsigned int i=0; i<numQuads; ++i)
00237 {
00238 Quad &t = m_quad[i];
00239
00240 for (unsigned int j=0; j<4; ++j)
00241 {
00242 const int edgeIndex = getEdgeIndex(t[(j+1)%4],t[(j+2)%4]);
00243 m_quadEdge[i][j]=edgeIndex;
00244 }
00245 }
00246 }
00247
00248 const sofa::helper::vector<Quad> &QuadSetTopologyContainer::getQuadArray()
00249 {
00250 if(!hasQuads() && getNbPoints()>0)
00251 {
00252 #ifndef NDEBUG
00253 cout << "Warning. [QuadSetTopologyContainer::getQuadArray] creating quad array." << endl;
00254 #endif
00255 createQuadSetArray();
00256 }
00257
00258 return m_quad;
00259 }
00260
00261 int QuadSetTopologyContainer::getQuadIndex(PointID v1, PointID v2, PointID v3, PointID v4)
00262 {
00263 if(!hasQuadVertexShell())
00264 createQuadVertexShellArray();
00265
00266 sofa::helper::vector<unsigned int> set1 = getQuadVertexShell(v1);
00267 sofa::helper::vector<unsigned int> set2 = getQuadVertexShell(v2);
00268 sofa::helper::vector<unsigned int> set3 = getQuadVertexShell(v3);
00269 sofa::helper::vector<unsigned int> set4 = getQuadVertexShell(v4);
00270
00271 sort(set1.begin(), set1.end());
00272 sort(set2.begin(), set2.end());
00273 sort(set3.begin(), set3.end());
00274 sort(set4.begin(), set4.end());
00275
00276
00277 sofa::helper::vector<unsigned int> out1(set1.size()+set2.size());
00278 sofa::helper::vector<unsigned int>::iterator result1;
00279 result1 = std::set_intersection(set1.begin(),set1.end(),set2.begin(),set2.end(),out1.begin());
00280 out1.erase(result1,out1.end());
00281
00282 sofa::helper::vector<unsigned int> out2(set3.size()+out1.size());
00283 sofa::helper::vector<unsigned int>::iterator result2;
00284 result2 = std::set_intersection(set3.begin(),set3.end(),out1.begin(),out1.end(),out2.begin());
00285 out2.erase(result2,out2.end());
00286
00287 sofa::helper::vector<unsigned int> out3(set4.size()+out2.size());
00288 sofa::helper::vector<unsigned int>::iterator result3;
00289 result3 = std::set_intersection(set4.begin(),set4.end(),out2.begin(),out2.end(),out3.begin());
00290 out3.erase(result3,out3.end());
00291
00292 #ifndef NDEBUG
00293 if(out3.size() > 1)
00294 cout << "Warning. [QuadSetTopologyContainer::getQuadIndex] more than one quad found" << endl;
00295 #endif
00296
00297 if(out3.size()==1)
00298 return (int) (out3[0]);
00299 else
00300 return -1;
00301 }
00302
00303 unsigned int QuadSetTopologyContainer::getNumberOfQuads() const
00304 {
00305 return m_quad.size();
00306 }
00307
00308 const sofa::helper::vector< sofa::helper::vector<unsigned int> > &QuadSetTopologyContainer::getQuadVertexShellArray()
00309 {
00310 if(!hasQuadVertexShell())
00311 {
00312 #ifndef NDEBUG
00313 cout << "Warning. [QuadSetTopologyContainer::getQuadVertexShellArray] quad vertex shell array is empty." << endl;
00314 #endif
00315 createQuadVertexShellArray();
00316 }
00317
00318 return m_quadVertexShell;
00319 }
00320
00321 const sofa::helper::vector< sofa::helper::vector<unsigned int> > &QuadSetTopologyContainer::getQuadEdgeShellArray()
00322 {
00323 if(!hasQuadEdgeShell())
00324 {
00325 #ifndef NDEBUG
00326 cout << "Warning. [QuadSetTopologyContainer::getQuadEdgeShellArray] quad edge shell array is empty." << endl;
00327 #endif
00328 createQuadEdgeShellArray();
00329 }
00330
00331 return m_quadEdgeShell;
00332 }
00333
00334 const sofa::helper::vector< QuadEdges> &QuadSetTopologyContainer::getQuadEdgeArray()
00335 {
00336 if(m_quadEdge.empty())
00337 createQuadEdgeArray();
00338
00339 return m_quadEdge;
00340 }
00341
00342 const VertexQuads& QuadSetTopologyContainer::getQuadVertexShell(PointID i)
00343 {
00344 if(!hasQuadVertexShell())
00345 {
00346 #ifndef NDEBUG
00347 cout << "Warning. [QuadSetTopologyContainer::getQuadVertexShell] quad vertex shell array is empty." << endl;
00348 #endif
00349 createQuadVertexShellArray();
00350 }
00351 else if( i >= m_quadVertexShell.size())
00352 {
00353 #ifndef NDEBUG
00354 cout << "Error. [QuadSetTopologyContainer::getQuadVertexShell] index out of bounds." << endl;
00355 #endif
00356 createQuadVertexShellArray();
00357 }
00358
00359 return m_quadVertexShell[i];
00360 }
00361
00362 const EdgeQuads& QuadSetTopologyContainer::getQuadEdgeShell(EdgeID i)
00363 {
00364 if(!hasQuadEdgeShell())
00365 {
00366 #ifndef NDEBUG
00367 cout << "Warning. [QuadSetTopologyContainer::getQuadEdgeShell] quad edge shell array is empty." << endl;
00368 #endif
00369 createQuadEdgeShellArray();
00370 }
00371 else if( i >= m_quadEdgeShell.size())
00372 {
00373 #ifndef NDEBUG
00374 cout << "Error. [QuadSetTopologyContainer::getQuadEdgeShell] index out of bounds." << endl;
00375 #endif
00376 createQuadEdgeShellArray();
00377 }
00378
00379 return m_quadEdgeShell[i];
00380 }
00381
00382 const QuadEdges &QuadSetTopologyContainer::getQuadEdge(const unsigned int i)
00383 {
00384 if(m_quadEdge.empty())
00385 createQuadEdgeArray();
00386
00387 if( i >= m_quadEdge.size())
00388 {
00389 #ifndef NDEBUG
00390 cout << "Error. [QuadSetTopologyContainer::getQuadEdge] index out of bounds." << endl;
00391 #endif
00392 createQuadEdgeArray();
00393 }
00394
00395 return m_quadEdge[i];
00396 }
00397
00398 int QuadSetTopologyContainer::getVertexIndexInQuad(Quad &t, unsigned int vertexIndex) const
00399 {
00400 if(t[0]==vertexIndex)
00401 return 0;
00402 else if(t[1]==vertexIndex)
00403 return 1;
00404 else if(t[2]==vertexIndex)
00405 return 2;
00406 else if(t[3]==vertexIndex)
00407 return 3;
00408 else
00409 return -1;
00410 }
00411
00412 int QuadSetTopologyContainer::getEdgeIndexInQuad(QuadEdges &t, unsigned int edgeIndex) const
00413 {
00414 if(t[0]==edgeIndex)
00415 return 0;
00416 else if(t[1]==edgeIndex)
00417 return 1;
00418 else if(t[2]==edgeIndex)
00419 return 2;
00420 else if(t[3]==edgeIndex)
00421 return 3;
00422 else
00423 return -1;
00424 }
00425
00426 sofa::helper::vector< unsigned int > &QuadSetTopologyContainer::getQuadEdgeShellForModification(const unsigned int i)
00427 {
00428 if(!hasQuadEdgeShell())
00429 {
00430 #ifndef NDEBUG
00431 cout << "Warning. [QuadSetTopologyContainer::getQuadEdgeShellForModification] quad edge shell array is empty." << endl;
00432 #endif
00433 createQuadEdgeShellArray();
00434 }
00435
00436 if( i >= m_quadEdgeShell.size())
00437 {
00438 #ifndef NDEBUG
00439 cout << "Error. [QuadSetTopologyContainer::getQuadEdgeShellForModification] index out of bounds." << endl;
00440 #endif
00441 createQuadEdgeShellArray();
00442 }
00443
00444 return m_quadEdgeShell[i];
00445 }
00446
00447 sofa::helper::vector< unsigned int > &QuadSetTopologyContainer::getQuadVertexShellForModification(const unsigned int i)
00448 {
00449 if(!hasQuadVertexShell())
00450 {
00451 #ifndef NDEBUG
00452 cout << "Warning. [QuadSetTopologyContainer::getQuadVertexShellForModification] quad vertex shell array is empty." << endl;
00453 #endif
00454 createQuadVertexShellArray();
00455 }
00456
00457 if( i >= m_quadVertexShell.size())
00458 {
00459 #ifndef NDEBUG
00460 cout << "Error. [QuadSetTopologyContainer::getQuadVertexShellForModification] index out of bounds." << endl;
00461 #endif
00462 createQuadVertexShellArray();
00463 }
00464
00465 return m_quadVertexShell[i];
00466 }
00467
00468
00469 bool QuadSetTopologyContainer::checkTopology() const
00470 {
00471 #ifndef NDEBUG
00472 bool ret = true;
00473
00474 if(hasQuadVertexShell())
00475 {
00476 for (unsigned int i=0; i<m_quadVertexShell.size(); ++i)
00477 {
00478 const sofa::helper::vector<unsigned int> &tvs = m_quadVertexShell[i];
00479 for (unsigned int j=0; j<tvs.size(); ++j)
00480 {
00481 if((m_quad[tvs[j]][0]!=i)
00482 && (m_quad[tvs[j]][1]!=i)
00483 && (m_quad[tvs[j]][2]!=i)
00484 && (m_quad[tvs[j]][3]!=i))
00485 {
00486 ret = false;
00487 std::cout << "*** CHECK FAILED : check_quad_vertex_shell, i = " << i << " , j = " << j << std::endl;
00488 }
00489 }
00490 }
00491 }
00492
00493 if(hasQuadEdgeShell())
00494 {
00495 for (unsigned int i=0; i<m_quadEdgeShell.size(); ++i)
00496 {
00497 const sofa::helper::vector<unsigned int> &tes = m_quadEdgeShell[i];
00498 for (unsigned int j=0; j<tes.size(); ++j)
00499 {
00500 if((m_quadEdge[tes[j]][0]!=i)
00501 && (m_quadEdge[tes[j]][1]!=i)
00502 && (m_quadEdge[tes[j]][2]!=i)
00503 && (m_quadEdge[tes[j]][3]!=i))
00504 {
00505 ret = false;
00506 std::cout << "*** CHECK FAILED : check_quad_edge_shell, i = " << i << " , j = " << j << std::endl;
00507 }
00508 }
00509 }
00510 }
00511
00512 return ret && EdgeSetTopologyContainer::checkTopology();
00513 #else
00514 return true;
00515 #endif
00516 }
00517
00518 bool QuadSetTopologyContainer::hasQuads() const
00519 {
00520 return !m_quad.empty();
00521 }
00522
00523 bool QuadSetTopologyContainer::hasQuadEdges() const
00524 {
00525 return !m_quadEdge.empty();
00526 }
00527
00528 bool QuadSetTopologyContainer::hasQuadVertexShell() const
00529 {
00530 return !m_quadVertexShell.empty();
00531 }
00532
00533 bool QuadSetTopologyContainer::hasQuadEdgeShell() const
00534 {
00535 return !m_quadEdgeShell.empty();
00536 }
00537
00538 void QuadSetTopologyContainer::clearQuadVertexShell()
00539 {
00540 for(unsigned int i=0; i<m_quadVertexShell.size(); ++i)
00541 m_quadVertexShell[i].clear();
00542
00543 m_quadVertexShell.clear();
00544 }
00545
00546 void QuadSetTopologyContainer::clearQuadEdgeShell()
00547 {
00548 for(unsigned int i=0; i<m_quadEdgeShell.size(); ++i)
00549 m_quadEdgeShell[i].clear();
00550
00551 m_quadEdgeShell.clear();
00552 }
00553
00554 void QuadSetTopologyContainer::clearQuadEdges()
00555 {
00556 m_quadEdge.clear();
00557 }
00558
00559 void QuadSetTopologyContainer::clearQuads()
00560 {
00561 m_quad.clear();
00562 }
00563
00564 void QuadSetTopologyContainer::clear()
00565 {
00566 clearQuadVertexShell();
00567 clearQuadEdgeShell();
00568 clearQuadEdges();
00569 clearQuads();
00570
00571 EdgeSetTopologyContainer::clear();
00572 }
00573
00574 }
00575
00576 }
00577
00578 }
00579