PenalityContactForceField.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_PENALITYCONTACTFORCEFIELD_INL
00026 #define SOFA_COMPONENT_FORCEFIELD_PENALITYCONTACTFORCEFIELD_INL
00027 
00028 #include <sofa/core/componentmodel/behavior/ForceField.inl>
00029 #include <sofa/component/forcefield/PenalityContactForceField.h>
00030 #include <sofa/helper/system/config.h>
00031 #include <assert.h>
00032 #include <sofa/helper/gl/template.h>
00033 #include <iostream>
00034 using std::cerr;
00035 using std::endl;
00036 
00037 namespace sofa
00038 {
00039 
00040 namespace component
00041 {
00042 
00043 namespace forcefield
00044 {
00045 
00046 template<class DataTypes>
00047 void PenalityContactForceField<DataTypes>::clear(int reserve)
00048 {
00049     prevContacts.swap(*contacts.beginEdit()); // save old contacts in prevContacts
00050     contacts.beginEdit()->clear();
00051     if (reserve)
00052         contacts.beginEdit()->reserve(reserve);
00053     contacts.endEdit();
00054 }
00055 
00056 template<class DataTypes>
00057 void PenalityContactForceField<DataTypes>::addContact(int m1, int m2, int index1, int index2, const Deriv& norm, Real dist, Real ks, Real mu_s, Real mu_v, int oldIndex)
00058 {
00059     int i = contacts.getValue().size();
00060     contacts.beginEdit()->resize(i+1);
00061     Contact& c = (*contacts.beginEdit())[i];
00062     c.m1 = m1;
00063     c.m2 = m2;
00064     c.index1 = index1;
00065     c.index2 = index2;
00066     c.norm = norm;
00067     c.dist = dist;
00068     c.ks = ks;
00069     c.mu_s = mu_s;
00070     c.mu_v = mu_v;
00071     c.pen = 0;
00072     if (oldIndex > 0 && oldIndex <= (int)prevContacts.size())
00073     {
00074        c.age = prevContacts[oldIndex-1].age+1;
00075     }
00076     else
00077     {
00078        c.age = 0;
00079         }
00080     contacts.endEdit();
00081 }
00082 
00083 template<class DataTypes>
00084 void PenalityContactForceField<DataTypes>::addForce(VecDeriv& f1, VecDeriv& f2, const VecCoord& x1, const VecCoord& x2, const VecDeriv& /*v1*/, const VecDeriv& /*v2*/)
00085 {
00086     f1.resize(x1.size());
00087     f2.resize(x2.size());
00088     for (unsigned int i=0; i<contacts.getValue().size(); i++)
00089     {
00090         Contact& c = (*contacts.beginEdit())[i];
00091         Coord u = x2[c.m2]-x1[c.m1];
00092         c.pen = c.dist - u*c.norm;
00093         if (c.pen > 0)
00094         {
00095             Real fN = c.ks * c.pen;
00096             Deriv force = -c.norm*fN;
00097             f1[c.m1]+=force;
00098             f2[c.m2]-=force;
00099         }
00100     }
00101     contacts.endEdit();
00102 }
00103 
00104 template<class DataTypes>
00105 void PenalityContactForceField<DataTypes>::addDForce(VecDeriv& df1, VecDeriv& df2, const VecDeriv& dx1, const VecDeriv& dx2, double kFactor, double /*bFactor*/)
00106 {
00107     df1.resize(dx1.size());
00108     df2.resize(dx2.size());
00109     for (unsigned int i=0; i<contacts.getValue().size(); i++)
00110     {
00111         const Contact& c = contacts.getValue()[i];
00112         if (c.pen > 0) // + dpen > 0)
00113         {
00114             Coord du = dx2[c.m2]-dx1[c.m1];
00115             Real dpen = - du*c.norm;
00116             //if (c.pen < 0) dpen += c.pen; // start penality at distance 0
00117             Real dfN = c.ks * dpen * (Real)kFactor;
00118             Deriv dforce = -c.norm*dfN;
00119             df1[c.m1]+=dforce;
00120             df2[c.m2]-=dforce;
00121         }
00122     }
00123 }
00124 
00125 template <class DataTypes> 
00126     double PenalityContactForceField<DataTypes>::getPotentialEnergy(const VecCoord&, const VecCoord&)
00127 {
00128     cerr<<"PenalityContactForceField::getPotentialEnergy-not-implemented !!!"<<endl;
00129     return 0;
00130 }
00131 
00132 template<class DataTypes>
00133 void PenalityContactForceField<DataTypes>::draw()
00134 {
00135     if (!((this->mstate1 == this->mstate2)?getContext()->getShowForceFields():getContext()->getShowInteractionForceFields())) return;
00136     const VecCoord& p1 = *this->mstate1->getX();
00137     const VecCoord& p2 = *this->mstate2->getX();
00138     glDisable(GL_LIGHTING);
00139 
00140     glBegin(GL_LINES);
00141     for (unsigned int i=0; i<contacts.getValue().size(); i++)
00142     {
00143         const Contact& c = contacts.getValue()[i];
00144         Real d = c.dist - (p2[c.m2]-p1[c.m1])*c.norm;
00145         if (c.age > 10) //c.spen > c.mu_s * c.ks * 0.99)
00146             if (d > 0)
00147                 glColor4f(1,0,1,1);
00148             else
00149                 glColor4f(0,1,1,1);
00150         else
00151             if (d > 0)
00152                 glColor4f(1,0,0,1);
00153             else
00154                 glColor4f(0,1,0,1);
00155         helper::gl::glVertexT(p1[c.m1]);
00156         helper::gl::glVertexT(p2[c.m2]);
00157     }
00158     glEnd();
00159 
00160     if (getContext()->getShowNormals())
00161     {
00162         glColor4f(1,1,0,1);
00163         glBegin(GL_LINES);
00164         for (unsigned int i=0; i<contacts.getValue().size(); i++)
00165         {
00166             const Contact& c = contacts.getValue()[i];
00167             Coord p = p1[c.m1] - c.norm;
00168             helper::gl::glVertexT(p1[c.m1]);
00169             helper::gl::glVertexT(p);
00170             p = p2[c.m2] + c.norm;
00171             helper::gl::glVertexT(p2[c.m2]);
00172             helper::gl::glVertexT(p);
00173         }
00174         glEnd();
00175     }
00176 }
00177 
00178 
00179 template<class DataTypes>
00180     void PenalityContactForceField<DataTypes>::grabPoint( 
00181     const core::componentmodel::behavior::MechanicalState<defaulttype::Vec3Types> *tool, 
00182     const helper::vector< unsigned int > &index, 
00183     helper::vector< std::pair< core::objectmodel::BaseObject*, defaulttype::Vec3f> > &result, 
00184     helper::vector< unsigned int > &triangle,
00185     helper::vector< unsigned int > &index_point)  
00186 {
00187   if (static_cast< core::objectmodel::BaseObject *>(this->mstate1) == static_cast< const core::objectmodel::BaseObject *>(tool))
00188   {     
00189     for (unsigned int i=0;i<contacts.getValue().size();i++)
00190     {
00191       for (unsigned int j=0;j<index.size();j++)
00192       {
00193     if (contacts.getValue()[i].m1  == (int)index[j]) 
00194     {
00195       result.push_back(std::make_pair(static_cast< core::objectmodel::BaseObject *>(this), 
00196                (*this->mstate2->getX())[contacts.getValue()[i].m2])
00197               );
00198       triangle.push_back(contacts.getValue()[i].index2);
00199       index_point.push_back(index[j]);
00200     }
00201       }
00202     } 
00203   }   
00204   else if (static_cast< core::objectmodel::BaseObject *>(this->mstate2) == static_cast< const core::objectmodel::BaseObject *>(tool)) 
00205   {
00206         
00207     for (unsigned int i=0;i<contacts.getValue().size();i++)
00208     {
00209       for (unsigned int j=0;j<index.size();j++)
00210       {
00211     if (contacts.getValue()[i].m2  == (int)index[j])
00212     {
00213       result.push_back(std::make_pair(static_cast< core::objectmodel::BaseObject *>(this),
00214                (*this->mstate1->getX())[contacts.getValue()[i].m1])
00215               );
00216       
00217       triangle.push_back(contacts.getValue()[i].index1);
00218       index_point.push_back(index[j]);
00219     }
00220       }       
00221     }
00222   }
00223       
00224               
00225 }
00226     
00227 
00228 } // namespace forcefield
00229 
00230 } // namespace component
00231 
00232 } // namespace sofa
00233 
00234 #endif

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