Hexa2QuadTopologicalMapping.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/Hexa2QuadTopologicalMapping.h>
00026
00027 #include <sofa/core/ObjectFactory.h>
00028
00029 #include <sofa/component/topology/QuadSetTopologyContainer.h>
00030 #include <sofa/component/topology/QuadSetTopologyModifier.h>
00031 #include <sofa/component/topology/QuadSetTopologyChange.h>
00032
00033 #include <sofa/component/topology/HexahedronSetTopologyContainer.h>
00034 #include <sofa/component/topology/HexahedronSetTopologyModifier.h>
00035 #include <sofa/component/topology/HexahedronSetTopologyChange.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(Hexa2QuadTopologicalMapping)
00058
00059
00060 int Hexa2QuadTopologicalMappingClass = core::RegisterObject("Special case of mapping where HexahedronSetTopology is converted to QuadSetTopology")
00061 .add< Hexa2QuadTopologicalMapping >()
00062
00063 ;
00064
00065
00066
00067 Hexa2QuadTopologicalMapping::Hexa2QuadTopologicalMapping(In* from, Out* to)
00068 : TopologicalMapping(from, to),
00069 object1(initData(&object1, std::string("../.."), "object1", "First object to map")),
00070 object2(initData(&object2, std::string(".."), "object2", "Second object to map"))
00071 {
00072 }
00073
00074
00075 Hexa2QuadTopologicalMapping::~Hexa2QuadTopologicalMapping()
00076 {
00077 }
00078
00079 void Hexa2QuadTopologicalMapping::init()
00080 {
00081
00082
00083
00084
00085 if (fromModel) {
00086
00087 std::cout << "INFO_print : Hexa2QuadTopologicalMapping - from = hexa" << std::endl;
00088
00089 if (toModel) {
00090
00091 std::cout << "INFO_print : Hexa2QuadTopologicalMapping - to = quad" << std::endl;
00092
00093 QuadSetTopologyContainer *to_tstc;
00094 toModel->getContext()->get(to_tstc);
00095 to_tstc->clear();
00096
00097 toModel->setNbPoints(fromModel->getNbPoints());
00098
00099 QuadSetTopologyModifier *to_tstm;
00100 toModel->getContext()->get(to_tstm);
00101
00102 const sofa::helper::vector<Quad> &quadArray=fromModel->getQuads();
00103
00104 unsigned int nb_visible_quads = 0;
00105
00106 Loc2GlobVec.clear();
00107 Glob2LocMap.clear();
00108
00109 for (unsigned int i=0; i<quadArray.size(); ++i) {
00110
00111 if (fromModel->getHexaQuadShell(i).size()==1) {
00112
00113 to_tstm->addQuadProcess(quadArray[i]);
00114
00115 Loc2GlobVec.push_back(i);
00116 Glob2LocMap[i]=Loc2GlobVec.size()-1;
00117
00118 nb_visible_quads+=1;
00119 }
00120 }
00121
00122 to_tstm->notifyEndingEvent();
00123 }
00124
00125 }
00126 }
00127
00128 unsigned int Hexa2QuadTopologicalMapping::getFromIndex(unsigned int ind){
00129
00130 if(fromModel->getHexaQuadShell(ind).size()==1){
00131 return fromModel->getHexaQuadShell(ind)[0];
00132 }else{
00133 return 0;
00134 }
00135 }
00136
00137 void Hexa2QuadTopologicalMapping::updateTopologicalMapping(){
00138
00139
00140
00141 if (fromModel) {
00142
00143 QuadSetTopologyModifier *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::QUADSREMOVED:
00165 {
00166
00167
00168 int last;
00169 int ind_last;
00170
00171 last= fromModel->getNbQuads() - 1;
00172
00173 const sofa::helper::vector<unsigned int> &tab = ( static_cast< const QuadsRemoved *>( *itBegin ) )->getArray();
00174
00175 unsigned int ind_tmp;
00176
00177 unsigned int ind_real_last;
00178 ind_last=toModel->getNbQuads();
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 > quads_to_remove;
00230 quads_to_remove.push_back(ind_k);
00231
00232 to_tstm->removeQuads(quads_to_remove, true, false);
00233
00234 }else{
00235
00236 std::cout << "INFO_print : Hexa2QuadTopologicalMapping - Glob2LocMap should have the visible quad " << tab[i] << std::endl;
00237 std::cout << "INFO_print : Hexa2QuadTopologicalMapping - nb quads = " << ind_last << std::endl;
00238 }
00239
00240 --last;
00241 }
00242 break;
00243 }
00244
00245 case core::componentmodel::topology::HEXAHEDRAREMOVED:
00246 {
00247
00248
00249 if (fromModel) {
00250
00251 const sofa::helper::vector<Hexahedron> &hexahedronArray=fromModel->getHexas();
00252
00253 const sofa::helper::vector<unsigned int> &tab = ( static_cast< const HexahedraRemoved *>( *itBegin ) )->getArray();
00254
00255 sofa::helper::vector< Quad > quads_to_create;
00256 sofa::helper::vector< unsigned int > quadsIndexList;
00257 int nb_elems = toModel->getNbQuads();
00258
00259 for (unsigned int i = 0; i < tab.size(); ++i)
00260 {
00261
00262 for (unsigned int j = 0; j < 6; ++j)
00263 {
00264 unsigned int k = (fromModel->getQuadHexaShell(tab[i]))[j];
00265
00266 if (fromModel->getHexaQuadShell(k).size()==1) {
00267
00268
00269
00270 }else{
00271
00272 unsigned int ind_test;
00273 if(tab[i] == fromModel->getHexaQuadShell(k)[0]){
00274
00275 ind_test = fromModel->getHexaQuadShell(k)[1];
00276
00277 }else{
00278
00279 ind_test = fromModel->getHexaQuadShell(k)[0];
00280 }
00281
00282 bool is_present = false;
00283 unsigned int k0 = 0;
00284 while((!is_present) && k0 < i){
00285 is_present = (ind_test == tab[k0]);
00286 k0+=1;
00287 }
00288 if(!is_present){
00289
00290 Quad t;
00291
00292 const Hexahedron &te=hexahedronArray[ind_test];
00293 int h = fromModel->getQuadIndexInHexahedron(fromModel->getQuadHexaShell(ind_test),k);
00294
00295
00296
00297
00298 switch( h ) {
00299
00300 case 0:
00301 {
00302 t[0] = te[0];
00303 t[1] = te[3];
00304 t[2] = te[2];
00305 t[3] = te[1];
00306
00307 break;
00308 }
00309 case 1:
00310 {
00311 t[0] = te[4];
00312 t[1] = te[5];
00313 t[2] = te[6];
00314 t[3] = te[7];
00315
00316 break;
00317 }
00318 case 2:
00319 {
00320 t[0] = te[0];
00321 t[1] = te[1];
00322 t[2] = te[5];
00323 t[3] = te[4];
00324
00325 break;
00326 }
00327 case 3:
00328 {
00329 t[0] = te[1];
00330 t[1] = te[2];
00331 t[2] = te[6];
00332 t[3] = te[5];
00333
00334 break;
00335 }
00336 case 4:
00337 {
00338 t[0] = te[2];
00339 t[1] = te[3];
00340 t[2] = te[7];
00341 t[3] = te[6];
00342
00343 break;
00344 }
00345 case 5:
00346 {
00347 t[0] = te[3];
00348 t[1] = te[0];
00349 t[2] = te[4];
00350 t[3] = te[7];
00351
00352 break;
00353 }
00354
00355 default:
00356 break;
00357 };
00358
00359 quads_to_create.push_back(t);
00360 quadsIndexList.push_back(nb_elems);
00361 nb_elems+=1;
00362
00363 Loc2GlobVec.push_back(k);
00364 std::map<unsigned int, unsigned int>::iterator iter_1 = Glob2LocMap.find(k);
00365 if(iter_1 != Glob2LocMap.end() ) {
00366 std::cout << "INFO_print : Hexa2QuadTopologicalMapping - fail to add quad " << k << "which already exists" << std::endl;
00367 Glob2LocMap.erase(Glob2LocMap.find(k));
00368 }
00369 Glob2LocMap[k]=Loc2GlobVec.size()-1;
00370 }
00371 }
00372 }
00373 }
00374
00375 to_tstm->addQuadsProcess(quads_to_create) ;
00376 to_tstm->addQuadsWarning(quads_to_create.size(), quads_to_create, quadsIndexList) ;
00377
00378 }
00379
00380 break;
00381 }
00382
00383 case core::componentmodel::topology::POINTSREMOVED:
00384 {
00385
00386
00387 const sofa::helper::vector<unsigned int> tab = ( static_cast< const sofa::component::topology::PointsRemoved * >( *itBegin ) )->getArray();
00388
00389 sofa::helper::vector<unsigned int> indices;
00390
00391 for(unsigned int i = 0; i < tab.size(); ++i){
00392
00393
00394 indices.push_back(tab[i]);
00395 }
00396
00397 sofa::helper::vector<unsigned int>& tab_indices = indices;
00398
00399 to_tstm->removePointsWarning(tab_indices, false);
00400 to_tstm->propagateTopologicalChanges();
00401 to_tstm->removePointsProcess(tab_indices, false);
00402
00403 break;
00404 }
00405
00406 case core::componentmodel::topology::POINTSRENUMBERING:
00407 {
00408
00409
00410 const sofa::helper::vector<unsigned int> &tab = ( static_cast< const PointsRenumbering * >( *itBegin ) )->getIndexArray();
00411 const sofa::helper::vector<unsigned int> &inv_tab = ( static_cast< const PointsRenumbering * >( *itBegin ) )->getinv_IndexArray();
00412
00413 sofa::helper::vector<unsigned int> indices;
00414 sofa::helper::vector<unsigned int> inv_indices;
00415
00416 for(unsigned int i = 0; i < tab.size(); ++i){
00417
00418
00419 indices.push_back(tab[i]);
00420 inv_indices.push_back(inv_tab[i]);
00421 }
00422
00423 sofa::helper::vector<unsigned int>& tab_indices = indices;
00424 sofa::helper::vector<unsigned int>& inv_tab_indices = inv_indices;
00425
00426 to_tstm->renumberPointsWarning(tab_indices, inv_tab_indices, false);
00427 to_tstm->propagateTopologicalChanges();
00428 to_tstm->renumberPointsProcess(tab_indices, inv_tab_indices, false);
00429
00430 break;
00431 }
00432
00433 default:
00434
00435 break;
00436 };
00437
00438 ++itBegin;
00439 }
00440 to_tstm->propagateTopologicalChanges();
00441 }
00442 }
00443
00444 return;
00445 }
00446
00447 }
00448
00449 }
00450
00451 }
00452