TopologicalChangeManager.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 "TopologicalChangeManager.h"
00026 
00027 #include <sofa/component/collision/TriangleModel.h>
00028 
00029 #include <sofa/component/MechanicalObject.h>
00030 #include <sofa/simulation/tree/GNode.h>
00031 
00032 #include <sofa/core/componentmodel/topology/TopologicalMapping.h>
00033 
00034 #include <sofa/component/topology/EdgeSetTopologyContainer.h>
00035 #include <sofa/component/topology/TriangleSetTopologyContainer.h>
00036 #include <sofa/component/topology/TriangleSetTopologyModifier.h>
00037 #include <sofa/component/topology/TriangleSetTopologyAlgorithms.h>
00038 #include <sofa/component/topology/TetrahedronSetTopologyContainer.h>
00039 #include <sofa/component/topology/QuadSetTopologyContainer.h>
00040 #include <sofa/component/topology/HexahedronSetTopologyContainer.h>
00041 
00042 #include <sofa/defaulttype/VecTypes.h>
00043 
00044 namespace sofa
00045 {
00046 
00047 namespace component
00048 {
00049 
00050 namespace collision
00051 {
00052 
00053 using namespace sofa::defaulttype;
00054 using namespace sofa::component::topology;
00055 
00056 TopologicalChangeManager::TopologicalChangeManager()
00057 {
00058 }
00059 
00060 TopologicalChangeManager::~TopologicalChangeManager()
00061 {
00062 }
00063 
00064 void TopologicalChangeManager::removeItemsFromTriangleModel(sofa::core::CollisionElementIterator elem2) const
00065 {
00066     TriangleModel* my_triangle_model = (dynamic_cast<TriangleModel*>(elem2.getCollisionModel()));
00067     if (my_triangle_model) 
00068     {
00069         sofa::core::componentmodel::topology::BaseMeshTopology* topo_curr;
00070         topo_curr = elem2.getCollisionModel()->getContext()->getMeshTopology(); 
00071         
00072         unsigned int ind_curr = elem2.getIndex();
00073 
00074         simulation::tree::GNode *node_curr = dynamic_cast<simulation::tree::GNode*>(topo_curr->getContext());
00075 
00076         std::set< unsigned int > items;
00077         items.insert(ind_curr);
00078 
00079         bool is_topoMap = true;
00080 
00081         while(is_topoMap)
00082         {
00083 
00084                 is_topoMap = false;
00085                 for(simulation::tree::GNode::ObjectIterator it = node_curr->object.begin(); it != node_curr->object.end(); ++it){                                                                                                                        
00086 
00087                         sofa::core::componentmodel::topology::TopologicalMapping *topoMap = dynamic_cast<sofa::core::componentmodel::topology::TopologicalMapping *>(*it);
00088                         if(topoMap != NULL){
00089                                 
00090                                 is_topoMap = true;
00091                                 //unsigned int ind_glob = topoMap->getGlobIndex(ind_curr);
00092                                 //ind_curr = topoMap->getFromIndex(ind_glob);
00093                                 std::set< unsigned int > loc_items = items;
00094                                 items.clear();
00095                                 for (std::set< unsigned int >::const_iterator it=loc_items.begin(); it != loc_items.end(); ++it)
00096                                 {
00097                                     unsigned int ind_glob = topoMap->getGlobIndex(*it);
00098                                     unsigned int ind = topoMap->getFromIndex(ind_glob);
00099                                     //std::cout << *it << " -> "<<ind_glob << " -> "<<ind<<std::endl;
00100                                     items.insert(ind);
00101                                 }
00102 
00103                                 topo_curr = topoMap->getFrom()->getContext()->getMeshTopology();
00104                                 node_curr = dynamic_cast<simulation::tree::GNode*>(topo_curr->getContext());
00105                                 
00106                                 break;
00107                         }
00108                 }
00109         }
00110         sofa::helper::vector<unsigned int> vitems;
00111         vitems.reserve(items.size());
00112         vitems.insert(vitems.end(), items.rbegin(), items.rend());
00113 
00114         sofa::core::componentmodel::topology::TopologyModifier* topoMod; 
00115         topo_curr->getContext()->get(topoMod);
00116 
00117         topoMod->removeItems(vitems);
00118 
00119         topoMod->notifyEndingEvent();
00120 
00121         
00122         topoMod->propagateTopologicalChanges();
00123         
00124 
00125         /*
00127 
00128         sofa::helper::vector<int> init_inverse_permutation;
00129         sofa::helper::vector<int>& inverse_permutation = init_inverse_permutation;
00130 
00131         sofa::component::topology::EdgeSetTopologyModifier* edgeMod; 
00132         topo_curr->getContext()->get(edgeMod);
00133         
00134         edgeMod->resortCuthillMckee(inverse_permutation);
00135 
00136         //std::cout << "inverse_permutation : " << std::endl;
00137         sofa::helper::vector<int> permutation;
00138         permutation.resize(inverse_permutation.size());
00139         for (unsigned int i=0; i<inverse_permutation.size(); ++i){
00140             permutation[inverse_permutation[i]]=i;
00141             //std::cout << i << " -> " << inverse_permutation[i] << std::endl;
00142         }
00143 
00144         //std::cout << "permutation : " << std::endl;
00145         //for (unsigned int i=0; i<permutation.size(); ++i){
00146             //std::cout << i << " -> " << permutation[i] << std::endl;
00147         //}         
00148             
00149         sofa::core::componentmodel::topology::TopologyModifier* topoMod; 
00150         topo_curr->getContext()->get(topoMod);
00151         topoMod->renumberPoints((const sofa::helper::vector<unsigned int> &) inverse_permutation, (const sofa::helper::vector<unsigned int> &) permutation);                
00152 
00153         */
00154     }
00155 }
00156 
00157 // Handle Removing of topological element (from any type of topology)
00158 void TopologicalChangeManager::removeItemsFromCollisionModel(sofa::core::CollisionElementIterator elem2) const
00159 {
00160     if(dynamic_cast<TriangleModel*>(elem2.getCollisionModel())!= NULL)
00161     {
00162         removeItemsFromTriangleModel(elem2);
00163     }
00164 }
00165 
00166 
00167 // Intermediate method to handle cutting
00168 bool TopologicalChangeManager::incisionTriangleSetTopology(sofa::core::componentmodel::topology::BaseMeshTopology* _topology)
00169 {
00170     const Vec<3,double>& a= (const Vec<3,double>) incision.a_init;
00171     const Vec<3,double>& b= (const Vec<3,double>) incision.b_init;
00172 
00173     const unsigned int &ind_ta = (const unsigned int) incision.ind_ta_init;
00174     const unsigned int &ind_tb = (const unsigned int) incision.ind_tb_init;
00175 
00176     unsigned int& a_last = incision.a_last_init;
00177     sofa::helper::vector< unsigned int >& a_p12_last = incision.a_p12_last_init;
00178     sofa::helper::vector< unsigned int >& a_i123_last = incision.a_i123_last_init;
00179 
00180     unsigned int& b_last = incision.b_last_init;
00181     sofa::helper::vector< unsigned int >& b_p12_last = incision.b_p12_last_init;
00182     sofa::helper::vector< unsigned int >& b_i123_last = incision.b_i123_last_init;
00183 
00184     bool is_prepared=!((a[0]==b[0] && a[1]==b[1] && a[2]==b[2]) || (incision.ind_ta_init == incision.ind_tb_init));
00185 
00186     if(is_prepared)
00187     {
00188         sofa::helper::vector< sofa::helper::vector<unsigned int> > new_points_init;
00189         sofa::helper::vector< sofa::helper::vector<unsigned int> > closest_vertices_init;
00190         sofa::helper::vector< sofa::helper::vector<unsigned int> > &new_points = new_points_init;
00191         sofa::helper::vector< sofa::helper::vector<unsigned int> > &closest_vertices = closest_vertices_init;
00192 
00193         sofa::component::topology::TriangleSetTopologyModifier* triangleMod; 
00194         _topology->getContext()->get(triangleMod);
00195 
00196         sofa::component::topology::TriangleSetTopologyAlgorithms<Vec3Types>* triangleAlg; 
00197         _topology->getContext()->get(triangleAlg);
00198 
00199         bool is_fully_cut = triangleAlg->InciseAlongPointsList(incision.is_first_cut, a, b, ind_ta, ind_tb, a_last, a_p12_last, a_i123_last, b_last, b_p12_last, b_i123_last, new_points, closest_vertices);
00200 
00201         // notify the end for the current sequence of topological change events
00202         triangleMod->notifyEndingEvent();
00203 
00204         triangleMod->propagateTopologicalChanges();
00205 
00206         incision.is_first_cut = false;
00207 
00208         return is_fully_cut;
00209     }
00210     else
00211     {
00212         return false;
00213     }
00214 }
00215 
00216 // Handle Cutting (activated only for a triangular topology), using global variables to register the two last input points
00217 bool TopologicalChangeManager::incisionCollisionModel(sofa::core::CollisionElementIterator elem2, Vector3& pos,
00218                             const bool firstInput, const bool isCut)
00219 {
00220     if(dynamic_cast<TriangleModel*>(elem2.getCollisionModel())!= NULL)
00221     {
00222         return incisionTriangleModel(elem2, pos, firstInput, isCut);
00223     }
00224 
00225     return false;
00226 }
00227 
00228 bool TopologicalChangeManager::incisionTriangleModel(sofa::core::CollisionElementIterator elem2, Vector3& pos,
00229                             const bool firstInput, const bool isCut)
00230 {
00231     Triangle triangle(elem2);
00232     TriangleModel* model2 = triangle.getCollisionModel();
00233 
00234     // Test if a TopologicalMapping (by default from TetrahedronSetTopology to TriangleSetTopology) exists :
00235 
00236     bool is_TopologicalMapping = false;
00237     
00238     sofa::core::componentmodel::topology::BaseMeshTopology* topo_curr;
00239     topo_curr = elem2.getCollisionModel()->getContext()->getMeshTopology(); 
00240 
00241     simulation::tree::GNode* parent2 = dynamic_cast<simulation::tree::GNode*>(model2->getContext());
00242 
00243     for (simulation::tree::GNode::ObjectIterator it = parent2->object.begin(); it != parent2->object.end(); ++it)
00244     {
00245         //std::cout << "INFO : name of GNode = " << (*it)->getName() <<  std::endl;
00246 
00247         if (dynamic_cast<sofa::core::componentmodel::topology::TopologicalMapping *>(*it)!= NULL)
00248         {
00249             is_TopologicalMapping=true;             
00250         }
00251 
00252     }
00253 
00254     // try to catch the topology associated to the detected object (a TriangleSetTopology is expected)
00255 
00256     sofa::component::topology::TriangleSetTopologyContainer* triangleCont; 
00257     topo_curr->getContext()->get(triangleCont);
00258 
00259     if(!is_TopologicalMapping)
00260     { // no TopologicalMapping
00261 
00262         if (triangleCont) // TriangleSetTopologyContainer
00263         {
00264             if (firstInput)
00265             {  
00266                 incision.a_init[0] = pos[0]; 
00267                 incision.a_init[1] = pos[1];
00268                 incision.a_init[2] = pos[2];
00269                 incision.ind_ta_init = elem2.getIndex();
00270 
00271                 incision.is_first_cut = true;
00272             }
00273             else if (isCut)
00274             {
00275                 incision.b_init[0] = pos[0];
00276                 incision.b_init[1] = pos[1];
00277                 incision.b_init[2] = pos[2];
00278 
00279                 incision.ind_tb_init = elem2.getIndex();
00280 
00281                 if(incisionTriangleSetTopology(topo_curr))
00282                 {
00283                     // full cut
00284                     incision.a_init[0] = pos[0]; 
00285                     incision.a_init[1] = pos[1];
00286                     incision.a_init[2] = pos[2];
00287                     incision.ind_ta_init = elem2.getIndex();
00288 
00289                     sofa::helper::vector<unsigned int> components_init;
00290                     sofa::helper::vector<unsigned int>& components = components_init;
00291 
00292                     sofa::component::topology::EdgeSetTopologyContainer* edgeCont; 
00293                     topo_curr->getContext()->get(edgeCont);
00294 
00295                     int num = edgeCont->getNumberConnectedComponents(components);
00296                     std::cout << "Number of connected components : " << num << endl;
00297                     //sofa::helper::vector<int>::size_type i;
00298                     //for (i = 0; i != components.size(); ++i)
00299                     //  std::cout << "Vertex " << i <<" is in component " << components[i] << endl;
00300                 }
00301                 else
00302                 {
00303                     sofa::helper::vector<unsigned int> components_init;
00304                     sofa::helper::vector<unsigned int>& components = components_init;
00305 
00306                     sofa::component::topology::EdgeSetTopologyContainer* edgeCont; 
00307                     topo_curr->getContext()->get(edgeCont);
00308 
00309                     int num = edgeCont->getNumberConnectedComponents(components);
00310                     std::cout << "Number of connected components : " << num << endl;
00311                     //sofa::helper::vector<int>::size_type i;
00312                     //for (i = 0; i != components.size(); ++i)
00313                     //  std::cout << "Vertex " << i <<" is in component " << components[i] << endl;
00314                     return true; // change state to ATTACHED;
00315                 }
00316             }
00317         }
00318     }else
00319     { // there may be a TetrahedronSetTopology over the TriangleSetTopology     
00320         
00321     }
00322 
00323     return false;
00324 }
00325 
00326 
00327 } // namespace collision
00328 
00329 } // namespace component
00330 
00331 } // namespace sofa

Generated on Sun Nov 23 02:36:39 2008 for Sofa by  doxygen 1.5.7.1