FrameSpringForceField.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 SOFA_COMPONENT_FORCEFIELD_FRAMESPRINGFORCEFIELD_INL
00026 #define SOFA_COMPONENT_FORCEFIELD_FRAMESPRINGFORCEFIELD_INL
00027 
00028 #include <sofa/component/forcefield/FrameSpringForceField.h>
00029 #include <sofa/core/componentmodel/topology/BaseMeshTopology.h>
00030 #include <sofa/helper/io/MassSpringLoader.h>
00031 #include <sofa/helper/gl/template.h>
00032 #include <sofa/helper/gl/Cylinder.h>
00033 #include <sofa/helper/gl/Axis.h>
00034 #include <sofa/helper/system/config.h>
00035 #include <assert.h>
00036 #include <iostream>
00037 
00038 using std::cerr;
00039 using std::endl;
00040 
00041 namespace sofa
00042 {
00043 
00044   namespace component
00045   {
00046 
00047     namespace forcefield
00048     {
00049 
00050 
00051       template<class DataTypes>
00052       FrameSpringForceField<DataTypes>::FrameSpringForceField ( MechanicalState* object1, MechanicalState* object2 )
00053           : Inherit ( object1, object2 )
00054           , springs ( initData ( &springs,"spring","pairs of indices, stiffness, damping, rest length" ) )
00055           , showLawfulTorsion ( initData ( &showLawfulTorsion, false, "show lawful Torsion", "dislpay the lawful part of the joint rotation" ) )
00056           , showExtraTorsion ( initData ( &showExtraTorsion, false, "show illicit Torsion", "dislpay the illicit part of the joint rotation" ) )
00057       {
00058       }
00059 
00060       template<class DataTypes>
00061       FrameSpringForceField<DataTypes>::FrameSpringForceField()
00062           : springs ( initData ( &springs,"spring","pairs of indices, stiffness, damping, rest length" ) )
00063           , showLawfulTorsion ( initData ( &showLawfulTorsion, false, "show lawful Torsion", "dislpay the lawful part of the joint rotation" ) )
00064           , showExtraTorsion ( initData ( &showExtraTorsion, false, "show illicit Torsion", "dislpay the illicit part of the joint rotation" ) )
00065       {
00066       }
00067 
00068 
00069       template <class DataTypes>
00070       void FrameSpringForceField<DataTypes>::init()
00071       {
00072         this->Inherit::init();
00073       }
00074 
00075       template<class DataTypes>
00076       void FrameSpringForceField<DataTypes>::addSpringForce ( double& /*potentialEnergy*/, VecDeriv& f1, const VecCoord& p1, const VecDeriv& v1, VecDeriv& f2, const VecCoord& p2, const VecDeriv& v2, int , /*const*/ Spring& spring )
00077       {
00078         int a = spring.m1;
00079         int b = spring.m2;
00080 
00081         Mat Mr01, Mr10, Mr02, Mr20;
00082         p1[a].writeRotationMatrix ( Mr01 );
00083         invertMatrix ( Mr10, Mr01 );
00084         p2[b].writeRotationMatrix ( Mr02 );
00085         invertMatrix ( Mr20, Mr02 );
00086 
00087         Deriv Vp1p2 = v2[b] - v1[a];
00088 
00089         VecN damping ( spring.kd, spring.kd, spring.kd );
00090         VecN kst ( spring.stiffnessTrans, spring.stiffnessTrans, spring.stiffnessTrans );
00091         VecN ksr ( spring.stiffnessRot, spring.stiffnessRot, spring.stiffnessRot );
00092 
00093         //store the referential of the spring (p1) to use it in addSpringDForce()
00094         springRef[a] = p1[a];
00095 
00096         VecN fT = kst.linearProduct( ( p2[b].getCenter() + Mr02 * ( spring.vec2)) - ( p1[a].getCenter() + Mr01 * ( spring.vec1))) + damping.linearProduct ( Vp1p2.getVCenter());
00097         VecN fR = ksr.linearProduct( ( p1[a].getOrientation().inverse() * p2[b].getOrientation()).toEulerVector());
00098 
00099         VecN C1 = fR + cross( Mr01 * ( spring.vec1), fT) + damping.linearProduct ( Vp1p2.getVOrientation() );
00100         VecN C2 = fR + cross( Mr02 * ( spring.vec2), fT) + damping.linearProduct ( -Vp1p2.getVOrientation() );
00101 
00102         f1[a] += Deriv ( fT, C1);
00103         f2[b] -= Deriv ( fT, C2);
00104 
00105 /*cerr << "f1: " << fT1 << ", " << fR1 << endl;
00106 cerr << "f2: " << fT2 << ", " << fR2 << endl;
00107 cerr << "sum: " << fT2 + fT1 << ", " << fR2 + fR1 << endl;
00108 cerr << "diff: " << fT2 - fT1 << ", " << fR2 - fR1 << endl;*/
00109       }
00110 
00111       template<class DataTypes>
00112       void FrameSpringForceField<DataTypes>::addSpringDForce ( VecDeriv& f1, const VecDeriv& dx1, VecDeriv& f2, const VecDeriv& dx2, int , /*const*/ Spring& spring )
00113       {
00114         const int a = spring.m1;
00115         const int b = spring.m2;
00116         const Deriv Mdx1dx2 = dx2[b] - dx1[a];
00117 
00118         Mat Mr01, Mr10;
00119         springRef[a].writeRotationMatrix ( Mr01 );
00120         invertMatrix ( Mr10, Mr01 );
00121 
00122         VecN kst ( spring.stiffnessTrans, spring.stiffnessTrans, spring.stiffnessTrans );
00123         VecN ksr ( spring.stiffnessRot, spring.stiffnessRot, spring.stiffnessRot );
00124 
00125         //compute directional force
00126         VecN df0 = Mr01 * ( kst.linearProduct ( Mr10*Mdx1dx2.getVCenter() ) );
00127         //compute rotational force
00128         VecN dR0 = Mr01 * ( ksr.linearProduct ( Mr10* Mdx1dx2.getVOrientation() ) );
00129 
00130         const Deriv dforce ( df0,dR0);
00131 
00132         f1[a] += dforce;
00133         f2[b] -= dforce;
00134       }
00135 
00136       template<class DataTypes>
00137       void FrameSpringForceField<DataTypes>::addForce ( VecDeriv& f1, VecDeriv& f2, const VecCoord& x1, const VecCoord& x2, const VecDeriv& v1, const VecDeriv& v2 )
00138       {
00139         helper::vector<Spring>& springs = *this->springs.beginEdit();
00140 
00141         springRef.resize ( x1.size() );
00142 
00143         f1.resize ( x1.size() );
00144         f2.resize ( x2.size() );
00145         m_potentialEnergy = 0;
00146         for ( unsigned int i=0; i<springs.size(); i++ )
00147         {
00148           this->addSpringForce ( m_potentialEnergy,f1,x1,v1,f2,x2,v2, i, springs[i] );
00149         }
00150         this->springs.endEdit();
00151       }
00152 
00153       template<class DataTypes>
00154       void FrameSpringForceField<DataTypes>::addDForce ( VecDeriv& df1, VecDeriv& df2, const VecDeriv& dx1, const VecDeriv& dx2 )
00155       {
00156         df1.resize ( dx1.size() );
00157         df2.resize ( dx2.size() );
00158 
00159         //const helper::vector<Spring>& springs = this->springs.getValue();
00160         helper::vector<Spring>& springs = *this->springs.beginEdit();
00161         for ( unsigned int i=0; i<springs.size(); i++ )
00162         {
00163           this->addSpringDForce ( df1,dx1,df2,dx2, i, springs[i] );
00164         }
00165         this->springs.endEdit();
00166       }
00167 
00168       template<class DataTypes>
00169       void FrameSpringForceField<DataTypes>::draw()
00170       {
00171         if ( ! ( ( this->mstate1 == this->mstate2 ) ?getContext()->getShowForceFields() :getContext()->getShowInteractionForceFields() ) ) return;
00172         const VecCoord& p1 = *this->mstate1->getX();
00173         const VecCoord& p2 = *this->mstate2->getX();
00174 
00175         glDisable ( GL_LIGHTING );
00176         bool external = ( this->mstate1!=this->mstate2 );
00177         const helper::vector<Spring>& springs = this->springs.getValue();
00178 
00179         for ( unsigned int i=0; i<springs.size(); i++ )
00180         {
00181           double restLength = (springs[i].vec1.norm() + springs[i].vec2.norm());
00182           Real d = ( p2[springs[i].m2].getCenter()-p1[springs[i].m1].getCenter()).norm();
00183           if ( external )
00184           {
00185             if ( d < restLength *0.9999 )
00186               glColor4f ( 1,0,0,1 );
00187             else
00188               glColor4f ( 0,1,0,1 );
00189           }
00190           else
00191           {
00192             if ( d < restLength *0.9999 )
00193               glColor4f ( 1,0.5f,0,1 );
00194             else
00195               glColor4f ( 0,1,0.5f,1 );
00196           }
00197           glBegin ( GL_LINES );
00198           helper::gl::glVertexT ( p1[springs[i].m1].getCenter() );
00199           helper::gl::glVertexT ( p2[springs[i].m2].getCenter() );
00200 
00201           //Debug: display fT: the virtual displacement of the spring( see the model on top of FrameSpringForceField.h
00202           /*
00203           glColor4f ( 1,1,1,1 );
00204           helper::gl::glVertexT ( p1[springs[i].m1].getCenter() + p1[springs[i].m1].getOrientation().rotate ( springs[i].initRot1.rotate ( VecN ( springs[i].initLength/2, 0, 0 ) ) ) );
00205           helper::gl::glVertexT ( p2[springs[i].m2].getCenter() + p2[springs[i].m2].getOrientation().rotate ( springs[i].initRot2.rotate ( VecN ( -springs[i].initLength/2, 0, 0 ) ) ) );
00206           //*/
00207           glEnd();
00208         }
00209       }
00210 
00211 
00212       template<class DataTypes>
00213       void FrameSpringForceField<DataTypes>::clear ( int reserve )
00214       {
00215         helper::vector<Spring>& springs = *this->springs.beginEdit();
00216         springs.clear();
00217         if ( reserve ) springs.reserve ( reserve );
00218         this->springs.endEdit();
00219       }
00220 
00221       template<class DataTypes>
00222       void FrameSpringForceField<DataTypes>::addSpring ( const Spring& s )
00223       {
00224         springs.beginEdit()->push_back ( s );
00225         springs.endEdit();
00226       }
00227 
00228 
00229       template<class DataTypes>
00230       void FrameSpringForceField<DataTypes>::addSpring ( int m1, int m2, Real softKst, Real softKsr, Real kd )
00231       {
00232         Spring s ( m1,m2,softKst,softKsr, kd );
00233         //TODO// Init vec1 et vec2. Encore mieux a la creation du ressort mais il manque les positions des DOFs...
00234 
00235         springs.beginEdit()->push_back ( s );
00236         springs.endEdit();
00237       }
00238 
00239     } // namespace forcefield
00240 
00241   } // namespace component
00242 
00243 } // namespace sofa
00244 
00245 #endif
00246 

Generated on Sun Nov 23 02:56:58 2008 for Sofa by  doxygen 1.5.7.1