Tetra2TriangleTopologicalMapping.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/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 // Register in the Factory
00060 int Tetra2TriangleTopologicalMappingClass = core::RegisterObject("Special case of mapping where TetrahedronSetTopology is converted to TriangleSetTopology")
00061 .add< Tetra2TriangleTopologicalMapping >()
00062 
00063 ;
00064 
00065 // Implementation
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     //std::cout << "INFO_print : init Tetra2TriangleTopologicalMapping" << std::endl;
00081 
00082     // INITIALISATION of TRIANGULAR mesh from TETRAHEDRAL mesh :
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     // INITIALISATION of TRIANGULAR mesh from TETRAHEDRAL mesh :
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                         //std::cout << "INFO_print : Tetra2TriangleTopologicalMapping - ENDING_EVENT" << std::endl;
00162                         to_tstm->notifyEndingEvent();
00163                         break;
00164                     }
00165 
00166                 case core::componentmodel::topology::TRIANGLESREMOVED:
00167                     {
00168                         //std::cout << "INFO_print : Tetra2TriangleTopologicalMapping - TRIANGLESREMOVED" << std::endl;
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                         //std::cout << "INFO_print : Tetra2TriangleTopologicalMapping - TETRAHEDRAREMOVED" << std::endl;
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) { // remove as visible the triangle indexed by k
00272 
00273                                         // do nothing
00274 
00275                                     }else{ // fromModel->getTetraTriangleShell(k).size()==2 // add as visible the triangle indexed by k
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{ // tab[i] == fromModel->getTetraTriangleShell(k)[1] 
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                                             // sort t such that t[0] is the smallest one 
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                         //std::cout << "INFO_print : Tetra2TriangleTopologicalMapping - POINTSREMOVED" << std::endl;
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                         //std::cout << "INFO_print : Hexa2QuadTopologicalMapping - POINTSREMOVED" << std::endl;
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                             //std::cout << "INFO_print : Hexa2QuadTopologicalMapping - point = " << tab[i] << std::endl;
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                     // Ignore events that are not Triangle  related.
00386                     break;
00387                 };              
00388 
00389                 ++itBegin;
00390             }
00391             to_tstm->propagateTopologicalChanges();
00392         }
00393     }
00394 
00395     return;
00396 }
00397 
00398 
00399 } // namespace topology
00400 
00401 } // namespace component
00402 
00403 } // namespace sofa
00404 

Generated on Sun Nov 23 03:45:50 2008 for Sofa by  doxygen 1.5.7.1