Triangle2EdgeTopologicalMapping.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/Triangle2EdgeTopologicalMapping.h>
00026
00027 #include <sofa/core/ObjectFactory.h>
00028
00029 #include <sofa/component/topology/EdgeSetTopologyContainer.h>
00030 #include <sofa/component/topology/EdgeSetTopologyModifier.h>
00031 #include <sofa/component/topology/EdgeSetTopologyChange.h>
00032
00033 #include <sofa/component/topology/TriangleSetTopologyContainer.h>
00034 #include <sofa/component/topology/TriangleSetTopologyModifier.h>
00035 #include <sofa/component/topology/TriangleSetTopologyChange.h>
00036
00037 #include <sofa/component/topology/PointSetTopologyChange.h>
00038
00039 #include <sofa/defaulttype/Vec.h>
00040 #include <map>
00041 #include <sofa/defaulttype/VecTypes.h>
00042
00043 namespace sofa
00044 {
00045
00046 namespace component
00047 {
00048
00049 namespace topology
00050 {
00051
00052 using namespace sofa::defaulttype;
00053
00054 using namespace sofa::component::topology;
00055 using namespace sofa::core::componentmodel::topology;
00056
00057 SOFA_DECL_CLASS(Triangle2EdgeTopologicalMapping)
00058
00059
00060 int Triangle2EdgeTopologicalMappingClass = core::RegisterObject("Special case of mapping where TriangleSetTopology is converted to EdgeSetTopology")
00061 .add< Triangle2EdgeTopologicalMapping >()
00062
00063 ;
00064
00065 Triangle2EdgeTopologicalMapping::Triangle2EdgeTopologicalMapping(In* from, Out* to)
00066 : TopologicalMapping(from, to),
00067 object1(initData(&object1, std::string("../.."), "object1", "First object to map")),
00068 object2(initData(&object2, std::string(".."), "object2", "Second object to map"))
00069 {
00070 }
00071
00072
00073 Triangle2EdgeTopologicalMapping::~Triangle2EdgeTopologicalMapping()
00074 {
00075 }
00076
00077 void Triangle2EdgeTopologicalMapping::init()
00078 {
00079 std::cout << "INFO_print : init Triangle2EdgeTopologicalMapping" << std::endl;
00080
00081
00082
00083 if (fromModel) {
00084
00085 std::cout << "INFO_print : Triangle2EdgeTopologicalMapping - from = triangle" << std::endl;
00086
00087 if (toModel) {
00088
00089 std::cout << "INFO_print : Triangle2EdgeTopologicalMapping - to = edge" << std::endl;
00090
00091 EdgeSetTopologyContainer *to_tstc;
00092 toModel->getContext()->get(to_tstc);
00093 to_tstc->clear();
00094
00095 toModel->setNbPoints(fromModel->getNbPoints());
00096
00097
00098 EdgeSetTopologyModifier *to_tstm;
00099 toModel->getContext()->get(to_tstm);
00100
00101 const sofa::helper::vector<Edge> &edgeArray=fromModel->getEdges();
00102
00103 unsigned int nb_visible_edges = 0;
00104
00105 Loc2GlobVec.clear();
00106 Glob2LocMap.clear();
00107
00108 for (unsigned int i=0; i<edgeArray.size(); ++i) {
00109
00110 if (fromModel->getTriangleEdgeShell(i).size()==1) {
00111
00112 to_tstm->addEdgeProcess(edgeArray[i]);
00113
00114 Loc2GlobVec.push_back(i);
00115 Glob2LocMap[i]=Loc2GlobVec.size()-1;
00116
00117 nb_visible_edges+=1;
00118 }
00119 }
00120
00121 to_tstm->notifyEndingEvent();
00122 }
00123
00124 }
00125
00126 }
00127
00128 unsigned int Triangle2EdgeTopologicalMapping::getFromIndex(unsigned int ind){
00129
00130 if(fromModel->getTriangleEdgeShell(ind).size()==1){
00131 return fromModel->getTriangleEdgeShell(ind)[0];
00132 }else{
00133 return 0;
00134 }
00135 }
00136
00137 void Triangle2EdgeTopologicalMapping::updateTopologicalMapping(){
00138
00139
00140
00141 if (fromModel) {
00142
00143 EdgeSetTopologyModifier *to_tstm;
00144 toModel->getContext()->get(to_tstm);
00145
00146 if (toModel) {
00147
00148 std::list<const TopologyChange *>::const_iterator itBegin=fromModel->firstChange();
00149 std::list<const TopologyChange *>::const_iterator itEnd=fromModel->lastChange();
00150
00151 while( itBegin != itEnd )
00152 {
00153 TopologyChangeType changeType = (*itBegin)->getChangeType();
00154
00155 switch( changeType ) {
00156
00157 case core::componentmodel::topology::ENDING_EVENT:
00158 {
00159
00160 to_tstm->notifyEndingEvent();
00161 break;
00162 }
00163
00164 case core::componentmodel::topology::EDGESREMOVED:
00165 {
00166
00167
00168 int last;
00169 int ind_last;
00170
00171 last= fromModel->getNbEdges() - 1;
00172
00173 const sofa::helper::vector<unsigned int> &tab = ( static_cast< const EdgesRemoved *>( *itBegin ) )->getArray();
00174
00175 unsigned int ind_tmp;
00176
00177 unsigned int ind_real_last;
00178 ind_last=toModel->getNbEdges();
00179
00180 for (unsigned int i = 0; i <tab.size(); ++i)
00181 {
00182 unsigned int k = tab[i];
00183 unsigned int ind_k;
00184
00185 std::map<unsigned int, unsigned int>::iterator iter_1 = Glob2LocMap.find(k);
00186 if(iter_1 != Glob2LocMap.end()) {
00187
00188 ind_last = ind_last - 1;
00189
00190 ind_k = Glob2LocMap[k];
00191 ind_real_last = ind_k;
00192
00193 std::map<unsigned int, unsigned int>::iterator iter_2 = Glob2LocMap.find(last);
00194 if(iter_2 != Glob2LocMap.end()) {
00195
00196 ind_real_last = Glob2LocMap[last];
00197
00198 if((int) k != last){
00199
00200 Glob2LocMap.erase(Glob2LocMap.find(k));
00201 Glob2LocMap[k] = ind_real_last;
00202
00203 Glob2LocMap.erase(Glob2LocMap.find(last));
00204 Glob2LocMap[last] = ind_k;
00205
00206 ind_tmp = Loc2GlobVec[ind_real_last];
00207 Loc2GlobVec[ind_real_last] = Loc2GlobVec[ind_k];
00208 Loc2GlobVec[ind_k] = ind_tmp;
00209 }
00210 }
00211
00212 if((int) ind_k != ind_last){
00213
00214 Glob2LocMap.erase(Glob2LocMap.find(Loc2GlobVec[ind_last]));
00215 Glob2LocMap[Loc2GlobVec[ind_last]] = ind_k;
00216
00217 Glob2LocMap.erase(Glob2LocMap.find(Loc2GlobVec[ind_k]));
00218 Glob2LocMap[Loc2GlobVec[ind_k]] = ind_last;
00219
00220 ind_tmp = Loc2GlobVec[ind_k];
00221 Loc2GlobVec[ind_k] = Loc2GlobVec[ind_last];
00222 Loc2GlobVec[ind_last] = ind_tmp;
00223
00224 }
00225
00226 Glob2LocMap.erase(Glob2LocMap.find(Loc2GlobVec[Loc2GlobVec.size() - 1]));
00227 Loc2GlobVec.resize( Loc2GlobVec.size() - 1 );
00228
00229 sofa::helper::vector< unsigned int > edges_to_remove;
00230 edges_to_remove.push_back(ind_k);
00231 to_tstm->removeEdges(edges_to_remove, false);
00232
00233 }else{
00234
00235 std::cout << "INFO_print : Triangle2EdgeTopologicalMapping - Glob2LocMap should have the visible edge " << tab[i] << std::endl;
00236 std::cout << "INFO_print : Triangle2EdgeTopologicalMapping - nb edges = " << ind_last << std::endl;
00237 }
00238
00239 --last;
00240 }
00241
00242
00243
00244 break;
00245 }
00246
00247 case core::componentmodel::topology::TRIANGLESREMOVED:
00248 {
00249
00250
00251
00252 if (fromModel) {
00253
00254 const sofa::helper::vector<Triangle> &triangleArray=fromModel->getTriangles();
00255
00256 const sofa::helper::vector<unsigned int> &tab = ( static_cast< const TrianglesRemoved *>( *itBegin ) )->getArray();
00257
00258 sofa::helper::vector< Edge > edges_to_create;
00259 sofa::helper::vector< unsigned int > edgesIndexList;
00260 int nb_elems = toModel->getNbEdges();
00261
00262 for (unsigned int i = 0; i < tab.size(); ++i)
00263 {
00264 for (unsigned int j = 0; j < 3; ++j)
00265 {
00266 unsigned int k = (fromModel->getEdgeTriangleShell(tab[i]))[j];
00267
00268 if (fromModel->getTriangleEdgeShell(k).size()!= 2) {
00269
00270
00271
00272 }else{
00273
00274 unsigned int ind_test;
00275 if(tab[i] == fromModel->getTriangleEdgeShell(k)[0]){
00276
00277 ind_test = fromModel->getTriangleEdgeShell(k)[1];
00278
00279 }else{
00280
00281 ind_test = fromModel->getTriangleEdgeShell(k)[0];
00282 }
00283
00284 bool is_present = false;
00285 unsigned int k0 = 0;
00286 while((!is_present) && k0 < i){
00287 is_present = (ind_test == tab[k0]);
00288 k0+=1;
00289 }
00290 if(!is_present){
00291
00292 Edge t;
00293
00294 const Triangle &te=triangleArray[ind_test];
00295 int h = fromModel->getEdgeIndexInTriangle(fromModel->getEdgeTriangleShell(ind_test),k);
00296
00297 t[0]=(int)(te[(h+1)%3]); t[1]=(int)(te[(h+2)%3]);
00298
00299
00300 if ((t[0]>t[1])) {
00301 int val=t[0]; t[0]=t[1]; t[1]=val;
00302 }
00303
00304 edges_to_create.push_back(t);
00305 edgesIndexList.push_back(nb_elems);
00306 nb_elems+=1;
00307
00308 Loc2GlobVec.push_back(k);
00309 std::map<unsigned int, unsigned int>::iterator iter_1 = Glob2LocMap.find(k);
00310 if(iter_1 != Glob2LocMap.end() ) {
00311 std::cout << "INFO_print : Triangle2EdgeTopologicalMapping - fail to add edge " << k << "which already exists" << std::endl;
00312 Glob2LocMap.erase(Glob2LocMap.find(k));
00313 }
00314 Glob2LocMap[k]=Loc2GlobVec.size()-1;
00315 }
00316 }
00317 }
00318 }
00319
00320 to_tstm->addEdgesProcess(edges_to_create) ;
00321 to_tstm->addEdgesWarning(edges_to_create.size(), edges_to_create, edgesIndexList) ;
00322
00323
00324 }
00325
00326 break;
00327 }
00328
00329 case core::componentmodel::topology::POINTSREMOVED:
00330 {
00331
00332
00333 const sofa::helper::vector<unsigned int> tab = ( static_cast< const sofa::component::topology::PointsRemoved * >( *itBegin ) )->getArray();
00334
00335 sofa::helper::vector<unsigned int> indices;
00336
00337 for(unsigned int i = 0; i < tab.size(); ++i){
00338
00339 indices.push_back(tab[i]);
00340 }
00341
00342 sofa::helper::vector<unsigned int>& tab_indices = indices;
00343
00344 to_tstm->removePointsWarning(tab_indices, false);
00345 to_tstm->propagateTopologicalChanges();
00346 to_tstm->removePointsProcess(tab_indices, false);
00347
00348 break;
00349 }
00350
00351 case core::componentmodel::topology::POINTSRENUMBERING:
00352 {
00353
00354
00355 const sofa::helper::vector<unsigned int> &tab = ( static_cast< const PointsRenumbering * >( *itBegin ) )->getIndexArray();
00356 const sofa::helper::vector<unsigned int> &inv_tab = ( static_cast< const PointsRenumbering * >( *itBegin ) )->getinv_IndexArray();
00357
00358 sofa::helper::vector<unsigned int> indices;
00359 sofa::helper::vector<unsigned int> inv_indices;
00360
00361 for(unsigned int i = 0; i < tab.size(); ++i){
00362
00363
00364 indices.push_back(tab[i]);
00365 inv_indices.push_back(inv_tab[i]);
00366 }
00367
00368 sofa::helper::vector<unsigned int>& tab_indices = indices;
00369 sofa::helper::vector<unsigned int>& inv_tab_indices = inv_indices;
00370
00371 to_tstm->renumberPointsWarning(tab_indices, inv_tab_indices, false);
00372 to_tstm->propagateTopologicalChanges();
00373 to_tstm->renumberPointsProcess(tab_indices, inv_tab_indices, false);
00374
00375 break;
00376 }
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423 case core::componentmodel::topology::TRIANGLESADDED:
00424 {
00425
00426
00427
00428 if (fromModel) {
00429
00430
00431
00432 const sofa::component::topology::TrianglesAdded *ta=static_cast< const sofa::component::topology::TrianglesAdded * >( *itBegin );
00433
00434 sofa::helper::vector< Edge > edges_to_create;
00435 sofa::helper::vector< unsigned int > edgesIndexList;
00436
00437 for (unsigned int i=0;i<ta->getNbAddedTriangles();++i)
00438 {
00439 unsigned int ind_elem = ta->triangleIndexArray[i];
00440 for (unsigned int j = 0; j < 3; ++j)
00441 {
00442 unsigned int k = (fromModel->getEdgeTriangleShell(ind_elem))[j];
00443
00444 std::map<unsigned int, unsigned int>::iterator iter_1 = Glob2LocMap.find(k);
00445 bool is_present = (iter_1 != Glob2LocMap.end()) && fromModel->getTriangleEdgeShell(k).size()>1;
00446
00447 if (is_present) {
00448
00449 unsigned int ind_k = Glob2LocMap[k];
00450 unsigned int ind_last = Loc2GlobVec.size() - 1;
00451 unsigned int ind_real_last = Loc2GlobVec[ind_last];
00452
00453 Glob2LocMap.erase(Glob2LocMap.find(ind_real_last));
00454 Glob2LocMap[ind_real_last] = ind_k;
00455
00456 Loc2GlobVec[ind_k] = ind_real_last;
00457
00458 Glob2LocMap.erase(Glob2LocMap.find(k));
00459 Loc2GlobVec.resize(Loc2GlobVec.size() - 1);
00460
00461 sofa::helper::vector< unsigned int > edges_to_remove;
00462 edges_to_remove.push_back(ind_k);
00463 to_tstm->removeEdges(edges_to_remove, false);
00464
00465 }else{
00466
00467 if((iter_1 == Glob2LocMap.end()) && (fromModel->getTriangleEdgeShell(k).size()==1)){
00468
00469
00470
00471
00472 Edge t = fromModel->getEdge(k);
00473
00474
00475
00476
00477
00478
00479 edges_to_create.push_back(t);
00480 edgesIndexList.push_back(Loc2GlobVec.size());
00481
00482 Loc2GlobVec.push_back(k);
00483 std::map<unsigned int, unsigned int>::iterator iter_1 = Glob2LocMap.find(k);
00484 if(iter_1 != Glob2LocMap.end() ) {
00485 std::cout << "INFO_print : Triangle2EdgeTopologicalMapping - fail to add edge " << k << "which already exists" << std::endl;
00486 Glob2LocMap.erase(Glob2LocMap.find(k));
00487 }
00488 Glob2LocMap[k]=Loc2GlobVec.size()-1;
00489
00490
00491
00492
00493 }
00494
00495 }
00496 }
00497 }
00498
00499 to_tstm->addEdgesProcess(edges_to_create) ;
00500 to_tstm->addEdgesWarning(edges_to_create.size(), edges_to_create, edgesIndexList) ;
00501 to_tstm->propagateTopologicalChanges();
00502
00503 }
00504
00505 break;
00506 }
00507
00508
00509 case core::componentmodel::topology::POINTSADDED:
00510 {
00511
00512
00513 const sofa::component::topology::PointsAdded *ta=static_cast< const sofa::component::topology::PointsAdded * >( *itBegin );
00514 to_tstm->addPointsProcess(ta->getNbAddedVertices());
00515 to_tstm->addPointsWarning(ta->getNbAddedVertices(), ta->ancestorsList, ta->coefs, false);
00516 to_tstm->propagateTopologicalChanges();
00517
00518 break;
00519 }
00520
00521
00522 default:
00523
00524 break;
00525 };
00526
00527 ++itBegin;
00528 }
00529 to_tstm->propagateTopologicalChanges();
00530
00531 }
00532 }
00533
00534 return;
00535 }
00536
00537 }
00538
00539 }
00540
00541 }
00542