CarvingManager.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 "CarvingManager.h"
00026 #include <sofa/core/ObjectFactory.h>
00027 #include <sofa/core/componentmodel/collision/DetectionOutput.h>
00028 #include <sofa/core/objectmodel/KeypressedEvent.h>
00029 #include <sofa/core/objectmodel/KeyreleasedEvent.h>
00030 #include <sofa/simulation/common/AnimateBeginEvent.h>
00031 #include <sofa/simulation/common/AnimateEndEvent.h>
00032 #include <sofa/core/componentmodel/topology/TopologicalMapping.h>
00033 #include <sofa/helper/gl/template.h>
00034
00035 namespace sofa
00036 {
00037
00038 namespace component
00039 {
00040
00041 namespace collision
00042 {
00043
00044 SOFA_DECL_CLASS(CarvingManager)
00045
00046 int CarvingManagerClass = core::RegisterObject("Manager handling carving operations between a SphereModel and a TriangleSetModel relying on a TetrahedronSetTopology")
00047 .add< CarvingManager >()
00048 ;
00049
00050
00051 CarvingManager::CarvingManager()
00052 : f_modelTool( initData(&f_modelTool, "modelTool", "SharpLineModel path"))
00053 , f_modelSurface( initData(&f_modelSurface, "modelSurface", "TriangleSetModel path"))
00054 , active( initData(&active, false, "active", "Activate this object.\nNote that this can be dynamically controlled by using a key") )
00055 , keyEvent( initData(&keyEvent, '1', "key", "key to press to activate this object until the key is released") )
00056 , keySwitchEvent( initData(&keySwitchEvent, '4', "keySwitch", "key to activate this object until the key is pressed again") )
00057 , modelTool(NULL)
00058 , modelSurface(NULL)
00059 , topoMapping(NULL)
00060 , intersectionMethod(NULL)
00061 , detectionNP(NULL)
00062 {
00063 this->f_listening.setValue(true);
00064 }
00065
00066 CarvingManager::~CarvingManager()
00067 {
00068 }
00069
00070 void CarvingManager::init()
00071 {
00072 _topology = this->getContext()->getMeshTopology();
00073 this->getContext()->get(tetraMod);
00074
00075 if (f_modelTool.getValue().empty())
00076 modelTool = getContext()->get<ToolModel>(core::objectmodel::BaseContext::SearchDown);
00077 else
00078 modelTool = getContext()->get<ToolModel>(f_modelTool.getValue());
00079 if (f_modelSurface.getValue().empty())
00080 {
00081
00082
00083 std::vector<TriangleModel*> models;
00084 getContext()->get<TriangleModel>(&models, core::objectmodel::BaseContext::SearchRoot);
00085 for (unsigned int i=0;i<models.size();++i)
00086 {
00087 TriangleModel* m = models[i];
00088 m->getContext()->get(topoMapping);
00089 if (topoMapping == NULL) continue;
00090
00091 modelSurface = m;
00092 break;
00093 }
00094 }
00095 else
00096 {
00097 modelSurface = getContext()->get<TriangleModel>(f_modelSurface.getValue());
00098 modelSurface->getContext()->get(topoMapping);
00099 }
00100 intersectionMethod = getContext()->get<core::componentmodel::collision::Intersection>();
00101 detectionNP = getContext()->get<core::componentmodel::collision::NarrowPhaseDetection>();
00102 bool error = false;
00103 if (modelTool == NULL) { std::cerr << "CarvingManager: modelTool not found\n"; error = true; }
00104 if (modelSurface == NULL) { std::cerr << "CarvingManager: modelSurface not found\n"; error = true; }
00105 if (intersectionMethod == NULL) { std::cerr << "CarvingManager: intersectionMethod not found\n"; error = true; }
00106 if (detectionNP == NULL) { std::cerr << "CarvingManager: NarrowPhaseDetection not found\n"; error = true; }
00107 if (!error)
00108 std::cout << "CarvingManager: init OK." << std::endl;
00109 }
00110
00111 void CarvingManager::reset()
00112 {
00113 }
00114
00115 void CarvingManager::doCarve()
00116 {
00117 if (modelTool==NULL || modelSurface==NULL || intersectionMethod == NULL || detectionNP == NULL) return;
00118
00119 if (topoMapping == NULL){
00120 _topology = modelSurface->getContext()->getMeshTopology();
00121 modelSurface->getContext()->get(tetraMod);
00122 }else{
00123 _topology = topoMapping->getFrom()->getContext()->getMeshTopology();
00124 topoMapping->getFrom()->getContext()->get(tetraMod);
00125 }
00126
00127 if (tetraMod == NULL) return;
00128
00129
00130
00131 {
00132 const bool continuous = intersectionMethod->useContinuous();
00133 const double dt = getContext()->getDt();
00134 const int depth = 6;
00135
00136 if (continuous)
00137 modelTool->computeContinuousBoundingTree(dt, depth);
00138 else
00139 modelTool->computeBoundingTree(depth);
00140
00141 if (continuous)
00142 modelSurface->computeContinuousBoundingTree(dt, depth);
00143 else
00144 modelSurface->computeBoundingTree(depth);
00145 }
00146
00147 sofa::helper::vector<std::pair<core::CollisionModel*, core::CollisionModel*> > vectCMPair;
00148
00149
00150
00151 vectCMPair.push_back(std::make_pair(modelSurface->getFirst(),modelTool->getFirst()));
00152
00153
00154 detectionNP->setInstance(this);
00155 detectionNP->setIntersectionMethod(intersectionMethod);
00156 detectionNP->beginNarrowPhase();
00157 detectionNP->addCollisionPairs(vectCMPair);
00158 detectionNP->endNarrowPhase();
00159
00160 const core::componentmodel::collision::NarrowPhaseDetection::DetectionOutputMap& detectionOutputs = detectionNP->getDetectionOutputs();
00161
00162
00163
00164 const ContactVector* contacts = NULL;
00165 core::componentmodel::collision::NarrowPhaseDetection::DetectionOutputMap::const_iterator it = detectionOutputs.begin();
00166 if (it != detectionOutputs.end())
00167 {
00168 std::cout << "Contacts available..." << std::endl;
00169 contacts = dynamic_cast<const ContactVector*>(it->second);
00170 }
00171 unsigned int ncontacts = 0;
00172 if (contacts != NULL)
00173 {
00174 ncontacts = contacts->size();
00175 std::cout << contacts->size() << " contacts detected." << std::endl;
00176 }
00177 std::set<unsigned> elemsToRemove;
00178 for (unsigned int j=0; j < ncontacts; ++j)
00179 {
00180 const ContactVector::value_type& c = (*contacts)[j];
00181 int triangleIdx = (c.elem.first.getCollisionModel()==modelSurface ? c.elem.first.getIndex():c.elem.second.getIndex());
00182
00183 if (topoMapping)
00184 {
00185 triangleIdx = topoMapping->getGlobIndex(triangleIdx);
00186 }
00187 const sofa::helper::vector< unsigned int >& tetras = _topology->getTetraTriangleShell(triangleIdx);
00188 elemsToRemove.insert(tetras.begin(), tetras.end());
00189 }
00190 if (!elemsToRemove.empty())
00191 {
00192 std::cout << elemsToRemove.size() << " tetrahedra to remove"<<std::endl;
00193 sofa::helper::vector< unsigned int > tetrahedra;
00194 for (std::set<unsigned>::const_iterator it = elemsToRemove.begin(), itend = elemsToRemove.end(); it != itend; ++it)
00195 tetrahedra.push_back(*it);
00196 tetraMod->removeTetrahedra(tetrahedra);
00197 }
00198 detectionNP->setInstance(NULL);
00199
00200 }
00201
00202 void CarvingManager::handleEvent(sofa::core::objectmodel::Event* event)
00203 {
00204 if (sofa::core::objectmodel::KeypressedEvent* ev = dynamic_cast<sofa::core::objectmodel::KeypressedEvent*>(event))
00205 {
00206 std::cout << "GET KEY "<<ev->getKey()<<std::endl;
00207 if (ev->getKey() == keyEvent.getValue())
00208 {
00209 active.setValue(true);
00210 }
00211 else if (ev->getKey() == keySwitchEvent.getValue())
00212 {
00213 active.setValue(!active.getValue());
00214 }
00215 }
00216 else if (sofa::core::objectmodel::KeyreleasedEvent* ev = dynamic_cast<sofa::core::objectmodel::KeyreleasedEvent*>(event))
00217 {
00218 if (ev->getKey() == keyEvent.getValue())
00219 {
00220 active.setValue(false);
00221 }
00222 }
00223 else if ( dynamic_cast<simulation::AnimateEndEvent*>(event))
00224 {
00225 if (active.getValue())
00226 doCarve();
00227 }
00228 }
00229
00230 }
00231
00232 }
00233
00234 }