SpringForceField.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 // Author: François Faure, INRIA-UJF, (C) 2006
00026 //
00027 // Copyright: See COPYING file that comes with this distribution
00028 #ifndef SOFA_COMPONENT_FORCEFIELD_SPRINGFORCEFIELD_INL
00029 #define SOFA_COMPONENT_FORCEFIELD_SPRINGFORCEFIELD_INL
00030 
00031 #include <sofa/component/forcefield/SpringForceField.h>
00032 #include <sofa/core/componentmodel/behavior/PairInteractionForceField.inl>
00033 #include <sofa/core/componentmodel/topology/BaseMeshTopology.h>
00034 #include <sofa/helper/io/MassSpringLoader.h>
00035 #include <sofa/helper/gl/template.h>
00036 #include <sofa/helper/system/config.h>
00037 #include <assert.h>
00038 #include <iostream>
00039 
00040 namespace sofa
00041 {
00042 
00043 namespace component
00044 {
00045 
00046 namespace forcefield
00047 {
00048 
00049 using std::cerr;
00050 using std::endl;
00051 
00052 template<class DataTypes>
00053 SpringForceField<DataTypes>::SpringForceField(MechanicalState* mstate1, MechanicalState* mstate2, SReal _ks, SReal _kd)
00054 : Inherit(mstate1, mstate2)
00055 , ks(initData(&ks,_ks,"stiffness","uniform stiffness for the all springs"))
00056 , kd(initData(&kd,_kd,"damping","uniform damping for the all springs"))
00057 , springs(initData(&springs,"spring","pairs of indices, stiffness, damping, rest length"))
00058 {
00059 }
00060 
00061 template<class DataTypes>
00062 SpringForceField<DataTypes>::SpringForceField(SReal _ks, SReal _kd)
00063 : ks(initData(&ks,_ks,"stiffness","uniform stiffness for the all springs"))
00064 , kd(initData(&kd,_kd,"damping","uniform damping for the all springs"))
00065 , springs(initData(&springs,"spring","pairs of indices, stiffness, damping, rest length"))
00066 {
00067 }
00068                   
00069                   
00070 template<class DataTypes>
00071 void SpringForceField<DataTypes>::parse(core::objectmodel::BaseObjectDescription* arg)
00072 {
00073     if (arg->getAttribute("filename"))
00074         this->load(arg->getAttribute("filename"));
00075     this->Inherit::parse(arg);
00076 }
00077 
00078 template <class DataTypes>
00079 class SpringForceField<DataTypes>::Loader : public helper::io::MassSpringLoader
00080 {
00081     public:
00082         SpringForceField<DataTypes>* dest;
00083         Loader(SpringForceField<DataTypes>* dest) : dest(dest) {}
00084         virtual void addSpring(int m1, int m2, SReal ks, SReal kd, SReal initpos)
00085         {
00086                   helper::vector<Spring>& springs = *dest->springs.beginEdit();
00087                   springs.push_back(Spring(m1,m2,ks,kd,initpos));
00088                   dest->springs.endEdit();
00089         }
00090 };
00091 
00092 template <class DataTypes>
00093 bool SpringForceField<DataTypes>::load(const char *filename)
00094 {
00095     bool ret = true;
00096     if (filename && filename[0])
00097     {
00098         Loader loader(this);
00099         ret &= loader.load(filename);
00100     }
00101     else ret = false;
00102     return ret;
00103 }
00104 
00105 template <class DataTypes>
00106 void SpringForceField<DataTypes>::init()
00107 {
00108     this->Inherit::init();
00109 }
00110 
00111 template<class DataTypes>
00112 void SpringForceField<DataTypes>::addSpringForce(SReal& ener, VecDeriv& f1, const VecCoord& p1, const VecDeriv& v1, VecDeriv& f2, const VecCoord& p2, const VecDeriv& v2, int /*i*/, const Spring& spring)
00113 {
00114     int a = spring.m1;
00115     int b = spring.m2;
00116     Coord u = p2[b]-p1[a];
00117     Real d = u.norm();
00118     Real inverseLength = 1.0f/d;
00119         if( d>1.0e-4 ) // null length => no force 
00120             return;
00121     u *= inverseLength;
00122     Real elongation = (Real)(d - spring.initpos);
00123         ener += elongation * elongation * spring.ks /2;
00124     Deriv relativeVelocity = v2[b]-v1[a];
00125     Real elongationVelocity = dot(u,relativeVelocity);
00126     Real forceIntensity = (Real)(spring.ks*elongation+spring.kd*elongationVelocity);
00127     Deriv force = u*forceIntensity;
00128     f1[a]+=force;
00129     f2[b]-=force;
00130 }
00131 
00132 template<class DataTypes>
00133 void SpringForceField<DataTypes>::addForce(VecDeriv& f1, VecDeriv& f2, const VecCoord& x1, const VecCoord& x2, const VecDeriv& v1, const VecDeriv& v2)
00134 {
00135     f1.resize(x1.size());
00136     f2.resize(x2.size());
00137     m_potentialEnergy = 0;
00138         for (unsigned int i=0; i<this->springs.getValue().size(); i++)
00139     {
00140           this->addSpringForce(m_potentialEnergy,f1,x1,v1,f2,x2,v2, i, this->springs.getValue()[i]);
00141     }
00142 }
00143 
00144 template<class DataTypes>
00145 void SpringForceField<DataTypes>::addDForce(VecDeriv&, VecDeriv&, const VecDeriv&, const VecDeriv&)
00146 {
00147     std::cerr << "SpringForceField does not support implicit integration. Use StiffSpringForceField instead.\n";
00148 }
00149 
00150 template<class DataTypes>
00151 void SpringForceField<DataTypes>::draw()
00152 {
00153     if (!((this->mstate1 == this->mstate2)?getContext()->getShowForceFields():getContext()->getShowInteractionForceFields())) return;
00154     const VecCoord& p1 = *this->mstate1->getX();
00155     const VecCoord& p2 = *this->mstate2->getX();
00156 /*        cerr<<"SpringForceField<DataTypes>::draw() "<<getName()<<endl;
00157         cerr<<"SpringForceField<DataTypes>::draw(), p1.size = "<<p1.size()<<endl;
00158         cerr<<"SpringForceField<DataTypes>::draw(), p1 = "<<p1<<endl;
00159         cerr<<"SpringForceField<DataTypes>::draw(), p2 = "<<p2<<endl;*/
00160         glDisable(GL_LIGHTING);
00161     bool external = (this->mstate1!=this->mstate2);
00162     //if (!external)
00163     //  glColor4f(1,1,1,1);
00164         const helper::vector<Spring>& springs = this->springs.getValue();
00165     glBegin(GL_LINES);
00166     for (unsigned int i=0; i<springs.size(); i++)
00167     {
00168         Real d = (p2[springs[i].m2]-p1[springs[i].m1]).norm();
00169         if (external)
00170         {
00171             if (d<springs[i].initpos*0.9999)
00172                 glColor4f(1,0,0,1);
00173             else
00174                 glColor4f(0,1,0,1);
00175         }
00176         else
00177         {
00178             if (d<springs[i].initpos*0.9999)
00179                 glColor4f(1,0.5f,0,1);
00180             else
00181                 glColor4f(0,1,0.5f,1);
00182         }
00183         helper::gl::glVertexT(p1[springs[i].m1]);
00184         helper::gl::glVertexT(p2[springs[i].m2]);
00185     }
00186     glEnd();
00187 }
00188 
00189 } // namespace forcefield
00190 
00191 } // namespace component
00192 
00193 } // namespace sofa
00194 
00195 #endif

Generated on Sun Nov 23 03:09:30 2008 for Sofa by  doxygen 1.5.7.1