CarvingManager.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 "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         // we look for a TriangleSetModel relying on a TetrahedronSetTopology.
00082         //modelSurface = getContext()->get<TriangleSetModel>(core::objectmodel::BaseContext::SearchDown);
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; // we found a good object
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     // do collision detection
00130     //std::cout << "CarvingManager: build bounding trees" << std::endl;
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     //vectCMPair = broadPhaseDetection->getCollisionModelPairs();
00149 
00150     //vectCMPair.push_back(std::make_pair(modelSurface,modelTool));
00151     vectCMPair.push_back(std::make_pair(modelSurface->getFirst(),modelTool->getFirst()));
00152     
00153     //std::cout << "CarvingManager: narrow phase" << std::endl;
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     //std::cout << "CarvingManager: process contacts" << std::endl;
00163 
00164     const ContactVector* contacts = NULL;
00165     core::componentmodel::collision::NarrowPhaseDetection::DetectionOutputMap::const_iterator it = detectionOutputs.begin(); //find(std::make_pair(modelSurface,modelTool));
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         // convert from local collision model indices to global topology ones
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     //std::cout << "CarvingManager: carve done" << std::endl;
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 (/* simulation::AnimateEndEvent* ev = */ dynamic_cast<simulation::AnimateEndEvent*>(event))
00224     {
00225         if (active.getValue())
00226             doCarve();
00227     }
00228 }
00229 
00230 } // namespace collision
00231 
00232 } // namespace component
00233 
00234 } // namespace sofa

Generated on Sun Nov 23 02:33:03 2008 for Sofa by  doxygen 1.5.7.1