Tetra2TriangleTopologicalMapping.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/Tetra2TriangleTopologicalMapping.h>
00026
00027 #include <sofa/core/ObjectFactory.h>
00028
00029 #include <sofa/component/topology/TriangleSetTopologyContainer.h>
00030 #include <sofa/component/topology/TriangleSetTopologyModifier.h>
00031 #include <sofa/component/topology/TriangleSetTopologyChange.h>
00032
00033 #include <sofa/component/topology/TetrahedronSetTopologyContainer.h>
00034 #include <sofa/component/topology/TetrahedronSetTopologyModifier.h>
00035 #include <sofa/component/topology/TetrahedronSetTopologyChange.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(Tetra2TriangleTopologicalMapping)
00058
00059
00060 int Tetra2TriangleTopologicalMappingClass = core::RegisterObject("Special case of mapping where TetrahedronSetTopology is converted to TriangleSetTopology")
00061 .add< Tetra2TriangleTopologicalMapping >()
00062
00063 ;
00064
00065
00066
00067 Tetra2TriangleTopologicalMapping::Tetra2TriangleTopologicalMapping(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 Tetra2TriangleTopologicalMapping::~Tetra2TriangleTopologicalMapping()
00075 {
00076 }
00077
00078 void Tetra2TriangleTopologicalMapping::init()
00079 {
00080
00081
00082
00083
00084
00085 if (fromModel) {
00086
00087 std::cout << "INFO_print : Tetra2TriangleTopologicalMapping - from = tetra" << std::endl;
00088
00089 if (toModel) {
00090
00091 std::cout << "INFO_print : Tetra2TriangleTopologicalMapping - to = triangle" << std::endl;
00092
00093 TriangleSetTopologyContainer *to_tstc;
00094 toModel->getContext()->get(to_tstc);
00095 to_tstc->clear();
00096
00097 toModel->setNbPoints(fromModel->getNbPoints());
00098
00099 TriangleSetTopologyModifier *to_tstm;
00100 toModel->getContext()->get(to_tstm);
00101
00102 const sofa::helper::vector<Triangle> &triangleArray=fromModel->getTriangles();
00103
00104
00105 unsigned int nb_visible_triangles = 0;
00106
00107 Loc2GlobVec.clear();
00108 Glob2LocMap.clear();
00109
00110 for (unsigned int i=0; i<triangleArray.size(); ++i) {
00111
00112 if (fromModel->getTetraTriangleShell(i).size()==1) {
00113
00114 to_tstm->addTriangleProcess(triangleArray[i]);
00115
00116 Loc2GlobVec.push_back(i);
00117 Glob2LocMap[i]=Loc2GlobVec.size()-1;
00118
00119 nb_visible_triangles+=1;
00120 }
00121 }
00122
00123 to_tstm->notifyEndingEvent();
00124
00125 }
00126
00127 }
00128 }
00129
00130 unsigned int Tetra2TriangleTopologicalMapping::getFromIndex(unsigned int ind){
00131
00132 if(fromModel->getTetraTriangleShell(ind).size()==1){
00133 return fromModel->getTetraTriangleShell(ind)[0];
00134 }else{
00135 return 0;
00136 }
00137 }
00138
00139 void Tetra2TriangleTopologicalMapping::updateTopologicalMapping(){
00140
00141
00142
00143 if (fromModel) {
00144
00145 TriangleSetTopologyModifier *to_tstm;
00146 toModel->getContext()->get(to_tstm);
00147
00148 if (toModel) {
00149
00150 std::list<const TopologyChange *>::const_iterator itBegin=fromModel->firstChange();
00151 std::list<const TopologyChange *>::const_iterator itEnd=fromModel->lastChange();
00152
00153 while( itBegin != itEnd )
00154 {
00155 TopologyChangeType changeType = (*itBegin)->getChangeType();
00156
00157 switch( changeType ) {
00158
00159 case core::componentmodel::topology::ENDING_EVENT:
00160 {
00161
00162 to_tstm->notifyEndingEvent();
00163 break;
00164 }
00165
00166 case core::componentmodel::topology::TRIANGLESREMOVED:
00167 {
00168
00169
00170 int last;
00171 int ind_last;
00172
00173 last= fromModel->getNbTriangles() - 1;
00174
00175 const sofa::helper::vector<unsigned int> &tab = ( static_cast< const TrianglesRemoved *>( *itBegin ) )->getArray();
00176
00177 unsigned int ind_tmp;
00178
00179 unsigned int ind_real_last;
00180 ind_last=toModel->getNbTriangles();
00181
00182 for (unsigned int i = 0; i <tab.size(); ++i)
00183 {
00184 unsigned int k = tab[i];
00185 unsigned int ind_k;
00186
00187 std::map<unsigned int, unsigned int>::iterator iter_1 = Glob2LocMap.find(k);
00188 if(iter_1 != Glob2LocMap.end()) {
00189
00190 ind_last = ind_last - 1;
00191
00192 ind_k = Glob2LocMap[k];
00193 ind_real_last = ind_k;
00194
00195 std::map<unsigned int, unsigned int>::iterator iter_2 = Glob2LocMap.find(last);
00196 if(iter_2 != Glob2LocMap.end()) {
00197
00198 ind_real_last = Glob2LocMap[last];
00199
00200 if((int) k != last){
00201
00202 Glob2LocMap.erase(Glob2LocMap.find(k));
00203 Glob2LocMap[k] = ind_real_last;
00204
00205 Glob2LocMap.erase(Glob2LocMap.find(last));
00206 Glob2LocMap[last] = ind_k;
00207
00208 ind_tmp = Loc2GlobVec[ind_real_last];
00209 Loc2GlobVec[ind_real_last] = Loc2GlobVec[ind_k];
00210 Loc2GlobVec[ind_k] = ind_tmp;
00211 }
00212 }
00213
00214 if((int) ind_k != ind_last){
00215
00216 Glob2LocMap.erase(Glob2LocMap.find(Loc2GlobVec[ind_last]));
00217 Glob2LocMap[Loc2GlobVec[ind_last]] = ind_k;
00218
00219 Glob2LocMap.erase(Glob2LocMap.find(Loc2GlobVec[ind_k]));
00220 Glob2LocMap[Loc2GlobVec[ind_k]] = ind_last;
00221
00222 ind_tmp = Loc2GlobVec[ind_k];
00223 Loc2GlobVec[ind_k] = Loc2GlobVec[ind_last];
00224 Loc2GlobVec[ind_last] = ind_tmp;
00225
00226 }
00227
00228 Glob2LocMap.erase(Glob2LocMap.find(Loc2GlobVec[Loc2GlobVec.size() - 1]));
00229 Loc2GlobVec.resize( Loc2GlobVec.size() - 1 );
00230
00231 sofa::helper::vector< unsigned int > triangles_to_remove;
00232 triangles_to_remove.push_back(ind_k);
00233
00234 TriangleSetTopologyModifier *triangleMod;
00235 toModel->getContext()->get(triangleMod);
00236 triangleMod->removeTriangles(triangles_to_remove, true, false);
00237
00238 }else{
00239
00240 std::cout << "INFO_print : Tetra2TriangleTopologicalMapping - Glob2LocMap should have the visible triangle " << tab[i] << std::endl;
00241 std::cout << "INFO_print : Tetra2TriangleTopologicalMapping - nb triangles = " << ind_last << std::endl;
00242 }
00243
00244 --last;
00245 }
00246
00247 break;
00248 }
00249
00250 case core::componentmodel::topology::TETRAHEDRAREMOVED:
00251 {
00252
00253
00254 if (fromModel) {
00255
00256 const sofa::helper::vector<Tetrahedron> &tetrahedronArray=fromModel->getTetras();
00257
00258 const sofa::helper::vector<unsigned int> &tab = ( static_cast< const TetrahedraRemoved *>( *itBegin ) )->getArray();
00259
00260 sofa::helper::vector< Triangle > triangles_to_create;
00261 sofa::helper::vector< unsigned int > trianglesIndexList;
00262 int nb_elems = toModel->getNbTriangles();
00263
00264 for (unsigned int i = 0; i < tab.size(); ++i)
00265 {
00266
00267 for (unsigned int j = 0; j < 4; ++j)
00268 {
00269 unsigned int k = (fromModel->getTriangleTetraShell(tab[i]))[j];
00270
00271 if (fromModel->getTetraTriangleShell(k).size()==1) {
00272
00273
00274
00275 }else{
00276
00277 unsigned int ind_test;
00278 if(tab[i] == fromModel->getTetraTriangleShell(k)[0]){
00279
00280 ind_test = fromModel->getTetraTriangleShell(k)[1];
00281
00282 }else{
00283
00284 ind_test = fromModel->getTetraTriangleShell(k)[0];
00285 }
00286
00287 bool is_present = false;
00288 unsigned int k0 = 0;
00289 while((!is_present) && k0 < i){
00290 is_present = (ind_test == tab[k0]);
00291 k0+=1;
00292 }
00293 if(!is_present){
00294
00295 Triangle t;
00296
00297 const Tetrahedron &te=tetrahedronArray[ind_test];
00298 int h = fromModel->getTriangleIndexInTetrahedron(fromModel->getTriangleTetraShell(ind_test),k);
00299
00300 if (h%2) {
00301 t[0]=(int)(te[(h+1)%4]); t[1]=(int)(te[(h+2)%4]); t[2]=(int)(te[(h+3)%4]);
00302 } else {
00303 t[0]=(int)(te[(h+1)%4]); t[2]=(int)(te[(h+2)%4]); t[1]=(int)(te[(h+3)%4]);
00304 }
00305
00306
00307 while ((t[0]>t[1]) || (t[0]>t[2])) {
00308 int val=t[0]; t[0]=t[1];t[1]=t[2];t[2]=val;
00309 }
00310
00311 triangles_to_create.push_back(t);
00312 trianglesIndexList.push_back(nb_elems);
00313 nb_elems+=1;
00314
00315 Loc2GlobVec.push_back(k);
00316 std::map<unsigned int, unsigned int>::iterator iter_1 = Glob2LocMap.find(k);
00317 if(iter_1 != Glob2LocMap.end() ) {
00318 std::cout << "INFO_print : Tetra2TriangleTopologicalMapping - fail to add triangle " << k << "which already exists" << std::endl;
00319 Glob2LocMap.erase(Glob2LocMap.find(k));
00320 }
00321 Glob2LocMap[k]=Loc2GlobVec.size()-1;
00322 }
00323 }
00324 }
00325 }
00326
00327 to_tstm->addTrianglesProcess(triangles_to_create) ;
00328 to_tstm->addTrianglesWarning(triangles_to_create.size(), triangles_to_create, trianglesIndexList) ;
00329
00330 }
00331
00332 break;
00333 }
00334
00335 case core::componentmodel::topology::POINTSREMOVED:
00336 {
00337
00338
00339 const sofa::helper::vector<unsigned int> tab = ( static_cast< const sofa::component::topology::PointsRemoved * >( *itBegin ) )->getArray();
00340
00341 sofa::helper::vector<unsigned int> indices;
00342
00343 for(unsigned int i = 0; i < tab.size(); ++i){
00344
00345 indices.push_back(tab[i]);
00346 }
00347
00348 sofa::helper::vector<unsigned int>& tab_indices = indices;
00349
00350 to_tstm->removePointsWarning(tab_indices, false);
00351
00352 to_tstm->propagateTopologicalChanges();
00353 to_tstm->removePointsProcess(tab_indices, false);
00354
00355 break;
00356 }
00357
00358 case core::componentmodel::topology::POINTSRENUMBERING:
00359 {
00360
00361
00362 const sofa::helper::vector<unsigned int> &tab = ( static_cast< const PointsRenumbering * >( *itBegin ) )->getIndexArray();
00363 const sofa::helper::vector<unsigned int> &inv_tab = ( static_cast< const PointsRenumbering * >( *itBegin ) )->getinv_IndexArray();
00364
00365 sofa::helper::vector<unsigned int> indices;
00366 sofa::helper::vector<unsigned int> inv_indices;
00367
00368 for(unsigned int i = 0; i < tab.size(); ++i){
00369
00370
00371 indices.push_back(tab[i]);
00372 inv_indices.push_back(inv_tab[i]);
00373 }
00374
00375 sofa::helper::vector<unsigned int>& tab_indices = indices;
00376 sofa::helper::vector<unsigned int>& inv_tab_indices = inv_indices;
00377
00378 to_tstm->renumberPointsWarning(tab_indices, inv_tab_indices, false);
00379 to_tstm->propagateTopologicalChanges();
00380 to_tstm->renumberPointsProcess(tab_indices, inv_tab_indices, false);
00381
00382 break;
00383 }
00384 default:
00385
00386 break;
00387 };
00388
00389 ++itBegin;
00390 }
00391 to_tstm->propagateTopologicalChanges();
00392 }
00393 }
00394
00395 return;
00396 }
00397
00398
00399 }
00400
00401 }
00402
00403 }
00404