Quad2TriangleTopologicalMapping.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/Quad2TriangleTopologicalMapping.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/QuadSetTopologyContainer.h>
00034 #include <sofa/component/topology/QuadSetTopologyModifier.h>
00035 #include <sofa/component/topology/QuadSetTopologyChange.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
00044 namespace sofa
00045 {
00046
00047 namespace component
00048 {
00049
00050 namespace topology
00051 {
00052
00053 using namespace sofa::defaulttype;
00054
00055 using namespace sofa::component::topology;
00056 using namespace sofa::core::componentmodel::topology;
00057
00059 typedef BaseMeshTopology In;
00061 typedef BaseMeshTopology Out;
00062
00063 SOFA_DECL_CLASS(Quad2TriangleTopologicalMapping)
00064
00065
00066 int Quad2TriangleTopologicalMappingClass = core::RegisterObject("Special case of mapping where QuadSetTopology is converted to TriangleSetTopology")
00067 .add< Quad2TriangleTopologicalMapping >()
00068
00069 ;
00070
00071
00072
00073 Quad2TriangleTopologicalMapping::Quad2TriangleTopologicalMapping(In* from, Out* to)
00074 : TopologicalMapping(from, to),
00075 object1(initData(&object1, std::string("../.."), "object1", "First object to map")),
00076 object2(initData(&object2, std::string(".."), "object2", "Second object to map"))
00077 {
00078 }
00079
00080
00081 Quad2TriangleTopologicalMapping::~Quad2TriangleTopologicalMapping()
00082 {
00083 }
00084
00085 void Quad2TriangleTopologicalMapping::init()
00086 {
00087
00088
00089
00090
00091 if (fromModel) {
00092
00093 std::cout << "INFO_print : Quad2TriangleTopologicalMapping - from = quad" << std::endl;
00094
00095 if (toModel) {
00096
00097 std::cout << "INFO_print : Quad2TriangleTopologicalMapping - to = triangle" << std::endl;
00098
00099 TriangleSetTopologyContainer *to_tstc;
00100 toModel->getContext()->get(to_tstc);
00101 to_tstc->clear();
00102
00103 toModel->setNbPoints(fromModel->getNbPoints());
00104
00105 TriangleSetTopologyModifier *to_tstm;
00106 toModel->getContext()->get(to_tstm);
00107
00108 const sofa::helper::vector<Quad> &quadArray=fromModel->getQuads();
00109
00110 Loc2GlobVec.clear();
00111 In2OutMap.clear();
00112
00113 for (unsigned int i=0; i<quadArray.size(); ++i) {
00114
00115
00116
00117
00118 unsigned int p0 = quadArray[i][0];
00119 unsigned int p1 = quadArray[i][1];
00120 unsigned int p2 = quadArray[i][2];
00121 unsigned int p3 = quadArray[i][3];
00122 to_tstm->addTriangleProcess(Triangle(helper::make_array<unsigned int>((unsigned int) p0, (unsigned int) p1, (unsigned int) p2)));
00123 to_tstm->addTriangleProcess(Triangle(helper::make_array<unsigned int>((unsigned int) p0, (unsigned int) p2, (unsigned int) p3)));
00124
00125 Loc2GlobVec.push_back(i);
00126 Loc2GlobVec.push_back(i);
00127 sofa::helper::vector<unsigned int> out_info;
00128 out_info.push_back(Loc2GlobVec.size()-2);
00129 out_info.push_back(Loc2GlobVec.size()-1);
00130 In2OutMap[i]=out_info;
00131
00132 }
00133
00134 to_tstm->notifyEndingEvent();
00135 }
00136
00137 }
00138 }
00139
00140 unsigned int Quad2TriangleTopologicalMapping::getFromIndex(unsigned int ind){
00141 return ind;
00142 }
00143
00144 void Quad2TriangleTopologicalMapping::updateTopologicalMapping(){
00145
00146
00147
00148
00149 if (fromModel) {
00150
00151 TriangleSetTopologyModifier *to_tstm;
00152 toModel->getContext()->get(to_tstm);
00153
00154 if (toModel) {
00155
00156 std::list<const TopologyChange *>::const_iterator itBegin=fromModel->firstChange();
00157 std::list<const TopologyChange *>::const_iterator itEnd=fromModel->lastChange();
00158
00159 while( itBegin != itEnd )
00160 {
00161 TopologyChangeType changeType = (*itBegin)->getChangeType();
00162
00163 switch( changeType ) {
00164
00165 case core::componentmodel::topology::ENDING_EVENT:
00166 {
00167
00168 to_tstm->notifyEndingEvent();
00169 break;
00170 }
00171
00172 case core::componentmodel::topology::QUADSADDED:
00173 {
00174
00175 if (fromModel) {
00176
00177 const sofa::helper::vector<Quad> &quadArray=fromModel->getQuads();
00178
00179 const sofa::helper::vector<unsigned int> &tab = ( static_cast< const QuadsAdded *>( *itBegin ) )->getArray();
00180
00181 sofa::helper::vector< Triangle > triangles_to_create;
00182 sofa::helper::vector< unsigned int > trianglesIndexList;
00183 int nb_elems = toModel->getNbTriangles();
00184
00185 for (unsigned int i = 0; i < tab.size(); ++i)
00186 {
00187 unsigned int k = tab[i];
00188
00189 unsigned int p0 = quadArray[k][0];
00190 unsigned int p1 = quadArray[k][1];
00191 unsigned int p2 = quadArray[k][2];
00192 unsigned int p3 = quadArray[k][3];
00193 Triangle t1 = Triangle(helper::make_array<unsigned int>((unsigned int) p0, (unsigned int) p1, (unsigned int) p2));
00194 Triangle t2 = Triangle(helper::make_array<unsigned int>((unsigned int) p0, (unsigned int) p2, (unsigned int) p3));
00195
00196 triangles_to_create.push_back(t1);
00197 trianglesIndexList.push_back(nb_elems);
00198 triangles_to_create.push_back(t2);
00199 trianglesIndexList.push_back(nb_elems+1);
00200 nb_elems+=2;
00201
00202 Loc2GlobVec.push_back(k);
00203 Loc2GlobVec.push_back(k);
00204 sofa::helper::vector<unsigned int> out_info;
00205 out_info.push_back(Loc2GlobVec.size()-2);
00206 out_info.push_back(Loc2GlobVec.size()-1);
00207 In2OutMap[k]=out_info;
00208
00209 }
00210
00211 to_tstm->addTrianglesProcess(triangles_to_create) ;
00212 to_tstm->addTrianglesWarning(triangles_to_create.size(), triangles_to_create, trianglesIndexList) ;
00213 to_tstm->propagateTopologicalChanges();
00214 }
00215 break;
00216 }
00217 case core::componentmodel::topology::QUADSREMOVED:
00218 {
00219
00220
00221 if (fromModel) {
00222
00223 const sofa::helper::vector<unsigned int> &tab = ( static_cast< const QuadsRemoved *>( *itBegin ) )->getArray();
00224
00225 int last= fromModel->getNbQuads() - 1;
00226
00227 int ind_tmp;
00228
00229 sofa::helper::vector<unsigned int> ind_real_last;
00230 int ind_last=toModel->getNbTriangles();
00231
00232 for (unsigned int i = 0; i < tab.size(); ++i)
00233 {
00234
00235
00236 unsigned int k = tab[i];
00237 sofa::helper::vector<unsigned int> ind_k;
00238
00239 std::map<unsigned int, sofa::helper::vector<unsigned int> >::iterator iter_1 = In2OutMap.find(k);
00240 if(iter_1 != In2OutMap.end()) {
00241
00242 unsigned int t1 = In2OutMap[k][0];
00243 unsigned int t2 = In2OutMap[k][1];
00244
00245 ind_last = ind_last - 1;
00246
00247 ind_k = In2OutMap[k];
00248 ind_real_last = ind_k;
00249
00250 std::map<unsigned int, sofa::helper::vector<unsigned int> >::iterator iter_2 = In2OutMap.find(last);
00251 if(iter_2 != In2OutMap.end()) {
00252
00253 ind_real_last = In2OutMap[last];
00254
00255 if((int) k != last){
00256
00257 In2OutMap.erase(In2OutMap.find(k));
00258 In2OutMap[k] = ind_real_last;
00259
00260 In2OutMap.erase(In2OutMap.find(last));
00261 In2OutMap[last] = ind_k;
00262
00263 ind_tmp = Loc2GlobVec[ind_real_last[0]];
00264 Loc2GlobVec[ind_real_last[0]] = Loc2GlobVec[ind_k[0]];
00265 Loc2GlobVec[ind_k[0]] = ind_tmp;
00266
00267 ind_tmp = Loc2GlobVec[ind_real_last[1]];
00268 Loc2GlobVec[ind_real_last[1]] = Loc2GlobVec[ind_k[1]];
00269 Loc2GlobVec[ind_k[1]] = ind_tmp;
00270 }
00271 }else{
00272 std::cout << "INFO_print : Quad2TriangleTopologicalMapping - In2OutMap should have the quad " << last << std::endl;
00273 }
00274
00275 if((int) ind_k[1] != ind_last){
00276
00277 In2OutMap.erase(In2OutMap.find(Loc2GlobVec[ind_last]));
00278 In2OutMap[Loc2GlobVec[ind_last]] = ind_k;
00279
00280 sofa::helper::vector<unsigned int> out_info;
00281 out_info.push_back(ind_last);
00282 out_info.push_back(ind_last-1);
00283
00284 In2OutMap.erase(In2OutMap.find(Loc2GlobVec[ind_k[1]]));
00285 In2OutMap[Loc2GlobVec[ind_k[1]]] = out_info;
00286
00287 ind_tmp = Loc2GlobVec[ind_k[1]];
00288 Loc2GlobVec[ind_k[1]] = Loc2GlobVec[ind_last];
00289 Loc2GlobVec[ind_last] = ind_tmp;
00290
00291 }
00292
00293 ind_last = ind_last-1;
00294
00295 if((int) ind_k[0] != ind_last){
00296
00297 ind_tmp = Loc2GlobVec[ind_k[0]];
00298 Loc2GlobVec[ind_k[0]] = Loc2GlobVec[ind_last];
00299 Loc2GlobVec[ind_last] = ind_tmp;
00300
00301 }
00302
00303 In2OutMap.erase(In2OutMap.find(Loc2GlobVec[Loc2GlobVec.size() - 1]));
00304
00305 Loc2GlobVec.resize( Loc2GlobVec.size() - 2 );
00306
00307 sofa::helper::vector< unsigned int > triangles_to_remove;
00308 triangles_to_remove.push_back(t1);
00309 triangles_to_remove.push_back(t2);
00310
00311 to_tstm->removeTriangles(triangles_to_remove, true, false);
00312
00313 }else{
00314 std::cout << "INFO_print : Quad2TriangleTopologicalMapping - In2OutMap should have the quad " << k << std::endl;
00315 }
00316
00317 --last;
00318 }
00319 }
00320
00321 break;
00322 }
00323
00324 case core::componentmodel::topology::POINTSREMOVED:
00325 {
00326
00327
00328 const sofa::helper::vector<unsigned int> tab = ( static_cast< const sofa::component::topology::PointsRemoved * >( *itBegin ) )->getArray();
00329
00330 sofa::helper::vector<unsigned int> indices;
00331
00332 for(unsigned int i = 0; i < tab.size(); ++i){
00333
00334
00335 indices.push_back(tab[i]);
00336 }
00337
00338 sofa::helper::vector<unsigned int>& tab_indices = indices;
00339
00340 to_tstm->removePointsWarning(tab_indices, false);
00341 to_tstm->propagateTopologicalChanges();
00342 to_tstm->removePointsProcess(tab_indices, false);
00343
00344 break;
00345 }
00346
00347
00348 case core::componentmodel::topology::POINTSRENUMBERING:
00349 {
00350
00351
00352 const sofa::helper::vector<unsigned int> &tab = ( static_cast< const PointsRenumbering * >( *itBegin ) )->getIndexArray();
00353 const sofa::helper::vector<unsigned int> &inv_tab = ( static_cast< const PointsRenumbering * >( *itBegin ) )->getinv_IndexArray();
00354
00355 sofa::helper::vector<unsigned int> indices;
00356 sofa::helper::vector<unsigned int> inv_indices;
00357
00358 for(unsigned int i = 0; i < tab.size(); ++i){
00359
00360
00361 indices.push_back(tab[i]);
00362 inv_indices.push_back(inv_tab[i]);
00363 }
00364
00365 sofa::helper::vector<unsigned int>& tab_indices = indices;
00366 sofa::helper::vector<unsigned int>& inv_tab_indices = inv_indices;
00367
00368 to_tstm->renumberPointsWarning(tab_indices, inv_tab_indices, false);
00369 to_tstm->propagateTopologicalChanges();
00370 to_tstm->renumberPointsProcess(tab_indices, inv_tab_indices, false);
00371
00372 break;
00373 }
00374
00375
00376 case core::componentmodel::topology::POINTSADDED:
00377 {
00378
00379
00380 const sofa::component::topology::PointsAdded *ta=static_cast< const sofa::component::topology::PointsAdded * >( *itBegin );
00381
00382 to_tstm->addPointsProcess(ta->getNbAddedVertices());
00383 to_tstm->addPointsWarning(ta->getNbAddedVertices(), ta->ancestorsList, ta->coefs, false);
00384 to_tstm->propagateTopologicalChanges();
00385
00386 break;
00387 }
00388
00389
00390
00391 default:
00392
00393 break;
00394 };
00395
00396 ++itBegin;
00397 }
00398 to_tstm->propagateTopologicalChanges();
00399 }
00400 }
00401
00402 return;
00403 }
00404
00405
00406 }
00407
00408 }
00409
00410 }
00411