00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef SOFA_COMPONENT_FORCEFIELD_FRAMESPRINGFORCEFIELD_H
00027 #define SOFA_COMPONENT_FORCEFIELD_FRAMESPRINGFORCEFIELD_H
00028
00029 #include <sofa/core/componentmodel/behavior/PairInteractionForceField.h>
00030 #include <sofa/core/componentmodel/behavior/MechanicalState.h>
00031 #include <sofa/defaulttype/Vec.h>
00032 #include <vector>
00033 #include <sofa/defaulttype/Mat.h>
00034 using namespace sofa::defaulttype;
00035
00036 namespace sofa
00037 {
00038
00039 namespace component
00040 {
00041
00042 namespace forcefield
00043 {
00044
00045 template<class DataTypes>
00046 class FrameSpringForceFieldInternalData
00047 {
00048 public:
00049 };
00050
00055 template<class DataTypes>
00056 class FrameSpringForceField : public core::componentmodel::behavior::PairInteractionForceField<DataTypes>, public virtual core::objectmodel::BaseObject
00057 {
00058 public:
00059 typedef typename core::componentmodel::behavior::PairInteractionForceField<DataTypes> Inherit;
00060 typedef typename DataTypes::VecCoord VecCoord;
00061 typedef typename DataTypes::VecDeriv VecDeriv;
00062 typedef typename DataTypes::Coord Coord;
00063 typedef typename DataTypes::Deriv Deriv;
00064 typedef typename Coord::value_type Real;
00065 typedef core::componentmodel::behavior::MechanicalState<DataTypes> MechanicalState;
00066 enum { N=Coord::static_size };
00067 typedef defaulttype::Mat<N,N,Real> Mat;
00068 typedef Vec<N,Real> VecN;
00069
00070
00071 class Spring
00072 {
00073 public:
00074 int m1, m2;
00075 VecN vec1, vec2;
00076 Real kd;
00077
00078 Real stiffnessTrans;
00079 Real stiffnessRot;
00080
00082 Spring ( int m1=0, int m2=0, Real softKst=0, Real softKsr=0, Real kd=0 )
00083 : m1 ( m1 ), m2 ( m2 ), kd ( kd ), stiffnessTrans ( softKst ), stiffnessRot ( softKsr )
00084 {
00085 }
00086
00087
00088 Real getStiffnessRotation() {return stiffnessRot;}
00089 Real getStiffnessTranslation() {return stiffnessTrans;}
00090 VecN getInitVec1() {return vec1;}
00091
00092
00093 void setStiffnessRotation ( Real ksr ) { stiffnessRot = ksr; }
00094 void setStiffnessTranslation ( Real kst ) { stiffnessTrans = kst; }
00095 void setInitVec1 ( const VecN& l ) { vec1=l; }
00096 void setInitVec2 ( const VecN& l ) { vec2=l; }
00097 void setDamping ( Real _kd ) { kd = _kd; }
00098
00099
00100 inline friend std::istream& operator >> ( std::istream& in, Spring& s )
00101 {
00102
00103
00104 std::string str;
00105 in>>str;
00106 if ( str == "BEGIN_SPRING" )
00107 {
00108 in>>s.m1>>s.m2;
00109 in>>str;
00110 while ( str != "END_SPRING" )
00111 {
00112 if ( str == "KS_T" )
00113 in>>s.stiffnessTrans;
00114 else if ( str == "KS_R" )
00115 in>>s.stiffnessRot;
00116 else if ( str == "KD" )
00117 in>>s.kd;
00118 else if ( str == "VEC1" )
00119 in>>s.vec1;
00120 else if ( str == "VEC2" )
00121 in>>s.vec2;
00122 else
00123 {
00124 std::cerr<<"Error parsing Spring : Unknown Attribute "<<str<<std::endl;
00125 return in;
00126 }
00127
00128 in>>str;
00129 }
00130 }
00131
00132 return in;
00133 }
00134
00135 friend std::ostream& operator << ( std::ostream& out, const Spring& s )
00136 {
00137 out<<"BEGIN_SPRING "<<s.m1<<" "<<s.m2<<" ";
00138
00139 if ( s.stiffnessTrans != 0.0 )
00140 out<<"KS_T "<<s.stiffnessTrans<<" ";
00141 if ( s.stiffnessRot != 0.0 )
00142 out<<"KS_R "<<s.stiffnessRot<<" ";
00143 if ( s.kd != 0.0 )
00144 out<<"KD "<<s.kd<<" ";
00145 if ( s.vec1!= VecN ( 0, 0, 0 ) )
00146 out<<"VEC1 "<<s.vec1<<" ";
00147 if ( s.vec2!= VecN ( 0, 0, 0 ) )
00148 out<<"VEC2 "<<s.vec2<<" ";
00149
00150 out<<"END_SPRING"<<std::endl;
00151 return out;
00152 }
00153
00154 };
00155
00156
00157
00158
00159 protected:
00160
00161 double m_potentialEnergy;
00163 Data<sofa::helper::vector<Spring> > springs;
00165 VecCoord springRef;
00167 Data<bool> showLawfulTorsion;
00168 Data<bool> showExtraTorsion;
00169
00170 FrameSpringForceFieldInternalData<DataTypes> data;
00171
00172
00174 void addSpringForce ( double& potentialEnergy, VecDeriv& f1, const VecCoord& p1, const VecDeriv& v1, VecDeriv& f2, const VecCoord& p2, const VecDeriv& v2, int i, Spring& spring );
00176 void addSpringDForce ( VecDeriv& df1, const VecDeriv& dx1, VecDeriv& df2, const VecDeriv& dx2, int i, Spring& spring );
00177
00178
00179
00180 public:
00181 FrameSpringForceField ( MechanicalState* object1, MechanicalState* object2 );
00182 FrameSpringForceField();
00183
00184 core::componentmodel::behavior::MechanicalState<DataTypes>* getObject1() { return this->mstate1; }
00185 core::componentmodel::behavior::MechanicalState<DataTypes>* getObject2() { return this->mstate2; }
00186
00187 virtual void init();
00188
00189 virtual void addForce ( VecDeriv& f1, VecDeriv& f2, const VecCoord& x1, const VecCoord& x2, const VecDeriv& v1, const VecDeriv& v2 );
00190
00191 virtual void addDForce ( VecDeriv& df1, VecDeriv& df2, const VecDeriv& dx1, const VecDeriv& dx2 );
00192
00193 virtual double getPotentialEnergy ( const VecCoord&, const VecCoord& ) { return m_potentialEnergy; }
00194
00195 sofa::helper::vector<Spring> * getSprings() { return springs.beginEdit(); }
00196
00197 void draw();
00198
00199
00200
00201 void clear ( int reserve=0 );
00202
00203 void addSpring ( const Spring& s );
00204
00205 void addSpring ( int m1, int m2, Real softKst, Real softKsr, Real kd );
00206
00207 };
00208
00209 }
00210
00211 }
00212
00213 }
00214
00215 #endif