LMLForce.inl

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 #ifndef LMLFORCE_INL
00026 #define LMLFORCE_INL
00027 
00028 //#include "sofa/core/ForceField.inl"
00029 #include "LMLForce.h"
00030 #include "sofa/helper/gl/template.h"
00031 using namespace sofa::helper::gl;
00032 
00033 
00034 namespace sofa
00035 {
00036 
00037 namespace filemanager
00038 {
00039 
00040 namespace pml
00041 {
00042 
00043 
00044 template<class DataTypes>
00045 LMLForce<DataTypes>::LMLForce(Loads* loadsList, const map<unsigned int, unsigned int> &atomIndexToDOFIndex, MechanicalState<DataTypes> *mm)
00046 : ForceField<DataTypes>(mm), atomToDOFIndexes(atomIndexToDOFIndex)
00047 {
00048     mmodel = mm;
00049     loads = new Loads();
00050     Load * load;
00051     SReal dirX, dirY, dirZ;
00052     Deriv ve;
00053     this->setName("loads");
00054 
00055     //for each load, we search which ones are forces applied on the body nodes
00056     for (unsigned int i=0 ; i<loadsList->numberOfLoads() ; i++) {
00057         load = loadsList->getLoad(i);
00058         if (load->getType() == "Force") {
00059             //set the direction
00060             if (load->getDirection().isToward()) {
00061                 std::map<unsigned int, unsigned int>::const_iterator titi = atomIndexToDOFIndex.find(load->getDirection().getToward());
00062                 if (titi != atomIndexToDOFIndex.end()){
00063                     unsigned int dofInd = titi->second;
00064                     dirX = (*mm->getX())[dofInd].x();
00065                     dirY = (*mm->getX())[dofInd].y();
00066                     dirZ = (*mm->getX())[dofInd].z();
00067                 }
00068             }
00069             else
00070                 load->getDirection(dirX, dirY, dirZ);
00071 
00072             //set the target
00073             unsigned int cpt=0;
00074             for (unsigned int j=0 ; j<load->numberOfTargets(); j++) {
00075                 std::map<unsigned int, unsigned int>::const_iterator result = atomIndexToDOFIndex.find(load->getTarget(j));
00076                 if (result != atomIndexToDOFIndex.end()) {
00077                     cpt++;
00078                     if (load->getDirection().isToward())
00079                         ve = Deriv(dirX-(*mm->getX())[result->second].x(), dirY-(*mm->getX())[result->second].y(), dirZ - (*mm->getX())[result->second].z());
00080                     else
00081                         ve = Deriv(dirX, dirY, dirZ);
00082                     ve.normalize();
00083                     forces.push_back(ve);
00084                     targets.push_back(result->second);
00085                 }
00086             } 
00087 
00088             if (cpt > 0)
00089                 loads->addLoad(load);
00090         }
00091     }
00092 }
00093 
00094 template<class DataTypes>
00095 void LMLForce<DataTypes>::addForce (VecDeriv& f, const VecCoord& x, const VecDeriv& /*v*/)
00096 {
00097     //for each points, update the force vector f
00098     SReal time = getContext()->getTime();
00099     f.resize(x.size());
00100     Load * load;
00101     std::vector<unsigned int>::iterator it1 = targets.begin();
00102     VecDerivIterator it2 = forces.begin();
00103     SReal dirX, dirY, dirZ;
00104 
00105     for (unsigned int i=0 ; i<loads->numberOfLoads() ; i++) {
00106         load = loads->getLoad(i);
00107         SReal val = load->getValue(time);
00108         for (unsigned int j=0 ; j<load->numberOfTargets() ; j++) {
00109             if ( atomToDOFIndexes.find(load->getTarget(j)) != atomToDOFIndexes.end() ) {
00110                 // if force value == 0, then there's no force !
00111                 if (val == 0)
00112                     (*it2) = Deriv(0,0,0);
00113                 else {
00114                     //if force direction is defined by a toward index, then it must be updated each step time
00115                     if (load->getDirection().isToward()) {
00116                         std::map<unsigned int, unsigned int>::const_iterator titi = atomToDOFIndexes.find(load->getDirection().getToward());
00117                         if (titi != atomToDOFIndexes.end()){
00118                             unsigned int dofInd = titi->second;
00119                             (*it2) = (*mmodel->getX())[dofInd] - (*mmodel->getX())[*it1];
00120                             (*it2).normalize();
00121                         }
00122                     }
00123                     else {
00124                         // if there is new force, then update the direction
00125                         if( (*it2)[0]==0 && (*it2)[1]==0 && (*it2)[2]==0 ){
00126                             load->getDirection(dirX, dirY, dirZ);
00127                             (*it2) = Deriv(dirX, dirY, dirZ);
00128                             (*it2).normalize();
00129                         }
00130                     }
00131 
00132                     //put the force in f
00133                     f[*it1] += (*it2) * val;
00134                 }
00135                 it1++;
00136                 it2++;
00137             }
00138         }
00139     }
00140 }
00141     
00142 
00143 // -- VisualModel interface
00144 template<class DataTypes>   
00145 void LMLForce<DataTypes>::draw()
00146 {
00147     //display a little green segment with force direction
00148     if (!getContext()->getShowForceFields()) return;
00149     VecCoord& x = *mmodel->getX();
00150     glDisable (GL_LIGHTING);
00151     glPointSize(10);
00152     glColor4f (0.5,1,0.5,1);
00153     glBegin (GL_LINES);
00154     VecDerivIterator it2 = forces.begin();
00155     for (std::vector<unsigned int>::const_iterator it = this->targets.begin(); it != this->targets.end(); ++it)
00156     {
00157         glVertexT(x[*it]);
00158         glVertexT(x[*it]+(*it2));
00159         it2++;
00160     }
00161     glEnd();
00162 }
00163 
00164 }
00165 }
00166 }
00167 
00168 #endif

Generated on Sun Nov 23 03:56:12 2008 for Sofa by  doxygen 1.5.7.1