TopologicalChangeManager.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 "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
00092
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
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
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154 }
00155 }
00156
00157
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
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
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
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
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
00246
00247 if (dynamic_cast<sofa::core::componentmodel::topology::TopologicalMapping *>(*it)!= NULL)
00248 {
00249 is_TopologicalMapping=true;
00250 }
00251
00252 }
00253
00254
00255
00256 sofa::component::topology::TriangleSetTopologyContainer* triangleCont;
00257 topo_curr->getContext()->get(triangleCont);
00258
00259 if(!is_TopologicalMapping)
00260 {
00261
00262 if (triangleCont)
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
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
00298
00299
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
00312
00313
00314 return true;
00315 }
00316 }
00317 }
00318 }else
00319 {
00320
00321 }
00322
00323 return false;
00324 }
00325
00326
00327 }
00328
00329 }
00330
00331 }