Triangle2EdgeTopologicalMapping.cpp

Go to the documentation of this file.
00001 /******************************************************************************
00002 *       SOFA, Simulation Open-Framework Architecture, version 1.0 beta 3      *
00003 *                (c) 2006-2008 MGH, INRIA, USTL, UJF, CNRS                    *
00004 *                                                                             *
00005 * This library is free software; you can redistribute it and/or modify it     *
00006 * under the terms of the GNU Lesser General Public License as published by    *
00007 * the Free Software Foundation; either version 2.1 of the License, or (at     *
00008 * your option) any later version.                                             *
00009 *                                                                             *
00010 * This library is distributed in the hope that it will be useful, but WITHOUT *
00011 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       *
00012 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
00013 * for more details.                                                           *
00014 *                                                                             *
00015 * You should have received a copy of the GNU Lesser General Public License    *
00016 * along with this library; if not, write to the Free Software Foundation,     *
00017 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.          *
00018 *******************************************************************************
00019 *                               SOFA :: Modules                               *
00020 *                                                                             *
00021 * Authors: The SOFA Team and external contributors (see Authors.txt)          *
00022 *                                                                             *
00023 * Contact information: contact@sofa-framework.org                             *
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 // Register in the Factory
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     // INITIALISATION of EDGE mesh from TRIANGULAR mesh :
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     // INITIALISATION of EDGE mesh from TRIANGULAR mesh :
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                         //std::cout << "INFO_print : Triangle2EdgeTopologicalMapping - ENDING_EVENT" << std::endl;
00160                         to_tstm->notifyEndingEvent();
00161                         break;
00162                     }
00163 
00164                 case core::componentmodel::topology::EDGESREMOVED:
00165                     {                                           
00166                         //std::cout << "INFO_print : Triangle2EdgeTopologicalMapping - EDGESREMOVED" << std::endl;
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                         //to_tstm->propagateTopologicalChanges();                                               
00243 
00244                         break;
00245                     }
00246 
00247                 case core::componentmodel::topology::TRIANGLESREMOVED:
00248                     {                       
00249 
00250                         //std::cout << "INFO_print : Triangle2EdgeTopologicalMapping - TRIANGLESREMOVED" << std::endl;
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) { // remove as visible the edge indexed by k // ==1
00269 
00270                                         // do nothing
00271 
00272                                     }else{ // fromModel->getTriangleEdgeShell(k).size()==2 // add as visible the edge indexed by k                                      
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{ // tab[i] == fromModel->getTriangleEdgeShell(k)[1] 
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                                             // sort t such that t[0] is the smallest one 
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                             //to_tstm->propagateTopologicalChanges();                           
00323 
00324                         }                               
00325 
00326                         break;
00327                     }               
00328 
00329                     case core::componentmodel::topology::POINTSREMOVED:
00330                     {
00331                         //std::cout << "INFO_print : Triangle2EdgeTopologicalMapping - POINTSREMOVED" << std::endl;
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                         //std::cout << "INFO_print : Hexa2TriangleTopologicalMapping - POINTSREMOVED" << std::endl;
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                             //std::cout << "INFO_print : Hexa2TriangleTopologicalMapping - point = " << tab[i] << std::endl;
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                     case core::componentmodel::topology::EDGESADDED:
00380                     {                       
00381 
00382                         //std::cout << "INFO_print : Triangle2EdgeTopologicalMapping - EDGESADDED" << std::endl;
00383 
00384                         if (fromModel) {                            
00385 
00386                             const sofa::component::topology::EdgesAdded *ta=static_cast< const sofa::component::topology::EdgesAdded * >( *itBegin );                           
00387 
00388                             sofa::helper::vector< Edge > edges_to_create;
00389                             sofa::helper::vector< unsigned int > edgesIndexList;
00390                             int nb_elems = toModel->getNbEdges();
00391 
00392                             for (unsigned int i=0;i<ta->getNbAddedEdges();++i)
00393                             {                                       
00394                                 Edge t = ta->edgeArray[i];  
00395                                 if ((t[0]>t[1])) {
00396                                     int val=t[0]; t[0]=t[1]; t[1]=val;
00397                                 }
00398                                 unsigned int k = ta->edgeIndexArray[i];                                 
00399                                                                             
00400                                 edges_to_create.push_back(t);   
00401                                 edgesIndexList.push_back(Loc2GlobVec.size());   
00402                                 nb_elems+=1;
00403                                 
00404                                 Loc2GlobVec.push_back(k);
00405                                 std::map<unsigned int, unsigned int>::iterator iter_1 = Glob2LocMap.find(k);
00406                                 if(iter_1 != Glob2LocMap.end() ) {
00407                                     std::cout << "INFO_print : Triangle2EdgeTopologicalMapping - fail to add edge " << k << "which already exists" << std::endl;
00408                                     Glob2LocMap.erase(Glob2LocMap.find(k));
00409                                 }
00410                                 Glob2LocMap[k]=Loc2GlobVec.size()-1;                                            
00411                             }
00412                             
00413                             to_tstm->addEdgesProcess(edges_to_create) ;                             
00414                             to_tstm->addEdgesWarning(edges_to_create.size(), edges_to_create, edgesIndexList) ;                         
00415                             //toModel->propagateTopologicalChanges();                           
00416 
00417                         }                               
00418 
00419                         break;
00420                     }
00421                     */                  
00422 
00423                     case core::componentmodel::topology::TRIANGLESADDED:
00424                     {                       
00425 
00426                         //std::cout << "INFO_print : Triangle2EdgeTopologicalMapping - TRIANGLESADDED" << std::endl;
00427 
00428                         if (fromModel) {
00429 
00430                             //const sofa::helper::vector<Triangle> &triangleArray=fromModel->getTriangles();
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) { // remove as visible the edge indexed by k                                        
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{ // add as visible the edge indexed by k
00466                                         
00467                                         if((iter_1 == Glob2LocMap.end()) && (fromModel->getTriangleEdgeShell(k).size()==1)){
00468                                         
00469                                             //sofa::helper::vector< Edge > edges_to_create;
00470                                             //sofa::helper::vector< unsigned int > edgesIndexList;                                      
00471 
00472                                             Edge t = fromModel->getEdge(k); 
00473                                             /*
00474                                             if ((t[0]>t[1])) {
00475                                                 int val=t[0]; t[0]=t[1]; t[1]=val;
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                                             //to_tstm->addEdgesProcess(edges_to_create) ;                               
00491                                             //to_tstm->addEdgesWarning(edges_to_create.size(), edges_to_create, edgesIndexList) ;           
00492                                             //toModel->propagateTopologicalChanges();                                           
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                         //std::cout << "INFO_print : Triangle2EdgeTopologicalMapping - POINTSADDED" << std::endl;                   
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                     // Ignore events that are not Edge  related.
00524                     break;
00525                 };              
00526 
00527                 ++itBegin;
00528             }
00529             to_tstm->propagateTopologicalChanges();
00530             
00531         }
00532     }
00533 
00534     return;
00535 }
00536 
00537 } // namespace topology
00538 
00539 } // namespace component
00540 
00541 } // namespace sofa
00542 

Generated on Sun Nov 23 03:46:36 2008 for Sofa by  doxygen 1.5.7.1