QuadularBendingSprings.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_QUADULARBENDINGSPRINGS_INL
00026 #define SOFA_COMPONENT_FORCEFIELD_QUADULARBENDINGSPRINGS_INL
00027 
00028 #include <sofa/component/forcefield/QuadularBendingSprings.h>
00029 #include <iostream>
00030 
00031 #include <sofa/helper/gl/template.h>
00032 
00033 #include <sofa/component/topology/QuadData.inl>
00034 #include <sofa/component/topology/EdgeData.inl>
00035 
00036 #include <sofa/component/topology/PointSetTopologyChange.h>
00037 
00038 namespace sofa
00039 {
00040 
00041 namespace component
00042 {
00043 
00044 namespace forcefield
00045 {
00046 
00047 using namespace sofa::defaulttype;
00048 using namespace sofa::component::topology;
00049 using namespace core::componentmodel::topology;
00050 
00051 using std::cerr;
00052 using std::cout;
00053 using std::endl;
00054 
00055 using namespace core::componentmodel::behavior;
00056 using core::componentmodel::topology::BaseMeshTopology;
00057 
00058 typedef BaseMeshTopology::Quad              Quad;
00059 typedef BaseMeshTopology::QuadEdges         QuadEdges;
00060 
00061 template< class DataTypes>
00062 void QuadularBendingSprings<DataTypes>::QuadularBSEdgeCreationFunction(int /*edgeIndex*/, void* param, EdgeInformation &ei,
00063                                                                                  const Edge& ,  const sofa::helper::vector< unsigned int > &,
00064                                                                                  const sofa::helper::vector< double >&)
00065 {
00066     QuadularBendingSprings<DataTypes> *ff= (QuadularBendingSprings<DataTypes> *)param;
00067     if (ff) {       
00068         
00069         unsigned int u,v;
00071         for (u=0;u<3;++u) {
00072             for (v=0;v<3;++v) {
00073                 ei.DfDx[u][v]=0;
00074             }
00075         }
00076 
00077         ei.is_activated=false;
00078         ei.is_initialized=false;
00079 
00080     }
00081 }
00082 
00083 template< class DataTypes>
00084 void QuadularBendingSprings<DataTypes>::QuadularBSQuadCreationFunction (const sofa::helper::vector<unsigned int> &quadAdded, 
00085                                                                                       void* param, vector<EdgeInformation> &edgeData)
00086 {
00087 
00088     QuadularBendingSprings<DataTypes> *ff= (QuadularBendingSprings<DataTypes> *)param;
00089     if (ff) {
00090         
00091         double m_ks=ff->getKs();
00092         double m_kd=ff->getKd();
00093 
00094         unsigned int u,v;
00095 
00096         unsigned int nb_activated = 0;
00097         
00098         const typename DataTypes::VecCoord *restPosition=ff->mstate->getX0();
00099 
00100         for (unsigned int i=0;i<quadAdded.size();++i) {         
00101 
00103             QuadEdges te2 = ff->_topology->getEdgeQuadShell(quadAdded[i]);
00105             Quad t2 = ff->_topology->getQuad(quadAdded[i]);
00106 
00107             for(unsigned int j=0;j<4;++j) {
00108 
00109                 EdgeInformation &ei = edgeData[te2[j]]; // ff->edgeInfo
00110                 if(!(ei.is_initialized)){
00111 
00112                     unsigned int edgeIndex = te2[j];
00113                     ei.is_activated=true;
00114 
00116                     for (u=0;u<3;++u) {
00117                         for (v=0;v<3;++v) {
00118                             ei.DfDx[u][v]=0;
00119                         }
00120                     }
00121                 
00122                     const sofa::helper::vector< unsigned int > shell = ff->_topology->getQuadEdgeShell(edgeIndex);
00123                     if (shell.size()==2) {
00124 
00125                         nb_activated+=1;
00126 
00127                         QuadEdges te1;
00128                         Quad t1;
00129 
00130                         if(shell[0] == quadAdded[i]){
00131                             
00132                             te1 = ff->_topology->getEdgeQuadShell(shell[1]);
00133                             t1 =  ff->_topology->getQuad(shell[1]);
00134 
00135                         }else{ // shell[1] == quadAdded[i]
00136                             
00137                             te1 = ff->_topology->getEdgeQuadShell(shell[0]);
00138                             t1 =  ff->_topology->getQuad(shell[0]);
00139                         }
00140 
00141                         int i1 = ff->_topology->getEdgeIndexInQuad(te1, edgeIndex); //edgeIndex //te1[j]
00142                         int i2 = ff->_topology->getEdgeIndexInQuad(te2, edgeIndex); // edgeIndex //te2[j]
00143 
00144                         ei.m1 = t1[i1]; // i1
00145                         ei.m2 = t2[(i2+3)%4]; // i2
00146 
00147                         ei.m3 = t1[(i1+3)%4]; // (i1+3)%4
00148                         ei.m4 = t2[i2]; // (i2+3)%4
00149 
00150                         //QuadularBendingSprings<DataTypes> *fftest= (QuadularBendingSprings<DataTypes> *)param;
00151                         ei.ks=m_ks; //(fftest->ks).getValue();
00152                         ei.kd=m_kd; //(fftest->kd).getValue();
00153 
00154                         Coord u1 = (*restPosition)[ei.m1] - (*restPosition)[ei.m2];
00155                         Real d1 = u1.norm();
00156                         ei.restlength1=(double) d1;
00157 
00158                         Coord u2 = (*restPosition)[ei.m3] - (*restPosition)[ei.m4];
00159                         Real d2 = u2.norm();
00160                         ei.restlength2=(double) d2;
00161 
00162                         ei.is_activated=true;
00163 
00164                     }else{
00165 
00166                         ei.is_activated=false;
00167 
00168                     }
00169 
00170                     ei.is_initialized = true;
00171                 }
00172             }
00173 
00174         }
00175 
00176     }
00177     
00178 }
00179 
00180 template< class DataTypes>
00181 void QuadularBendingSprings<DataTypes>::QuadularBSQuadDestructionFunction (const sofa::helper::vector<unsigned int> &quadRemoved, 
00182                                                                                       void* param, vector<EdgeInformation> &edgeData)
00183 {
00184     QuadularBendingSprings<DataTypes> *ff= (QuadularBendingSprings<DataTypes> *)param;
00185     if (ff) {               
00186 
00187         double m_ks=ff->getKs(); // typename DataTypes::
00188         double m_kd=ff->getKd(); // typename DataTypes::
00189 
00190         //unsigned int u,v;
00191 
00192         const typename DataTypes::VecCoord *restPosition=ff->mstate->getX0();
00193 
00194         for (unsigned int i=0;i<quadRemoved.size();++i) {           
00195 
00197             QuadEdges te = ff->_topology->getEdgeQuadShell(quadRemoved[i]);
00199             Quad t =  ff->_topology->getQuad(quadRemoved[i]);
00200 
00201 
00202             for(unsigned int j=0;j<4;++j) {
00203 
00204                 EdgeInformation &ei = edgeData[te[j]]; // ff->edgeInfo
00205                 if(ei.is_initialized){
00206 
00207                     unsigned int edgeIndex = te[j];
00208 
00209                     const sofa::helper::vector< unsigned int > shell = ff->_topology->getQuadEdgeShell(edgeIndex);
00210                     if (shell.size()==3) {
00211                         
00212                         QuadEdges te1;
00213                         Quad t1;
00214                         QuadEdges te2;
00215                         Quad t2;
00216 
00217                         if(shell[0] == quadRemoved[i]){
00218                             te1 = ff->_topology->getEdgeQuadShell(shell[1]);
00219                             t1 =  ff->_topology->getQuad(shell[1]);
00220                             te2 = ff->_topology->getEdgeQuadShell(shell[2]);
00221                             t2 =  ff->_topology->getQuad(shell[2]);
00222 
00223                         }else{
00224 
00225                             if(shell[1] == quadRemoved[i]){
00226 
00227                                 te1 = ff->_topology->getEdgeQuadShell(shell[2]);
00228                                 t1 =  ff->_topology->getQuad(shell[2]);
00229                                 te2 = ff->_topology->getEdgeQuadShell(shell[0]);
00230                                 t2 =  ff->_topology->getQuad(shell[0]);
00231 
00232                             }else{ // shell[2] == quadRemoved[i]
00233 
00234                                 te1 = ff->_topology->getEdgeQuadShell(shell[0]);
00235                                 t1 =  ff->_topology->getQuad(shell[0]);
00236                                 te2 = ff->_topology->getEdgeQuadShell(shell[1]);
00237                                 t2 =  ff->_topology->getQuad(shell[1]);
00238 
00239                             }
00240                         }
00241 
00242                         int i1 = ff->_topology->getEdgeIndexInQuad(te1, edgeIndex);
00243                         int i2 = ff->_topology->getEdgeIndexInQuad(te2, edgeIndex);
00244 
00245                         ei.m1 = t1[i1];
00246                         ei.m2 = t2[(i2+3)%4];
00247 
00248                         ei.m3 = t1[(i1+3)%4];
00249                         ei.m4 = t2[i2];
00250 
00251                         //QuadularBendingSprings<DataTypes> *fftest= (QuadularBendingSprings<DataTypes> *)param;
00252                         ei.ks=m_ks; //(fftest->ks).getValue();
00253                         ei.kd=m_kd; //(fftest->kd).getValue();
00254 
00255                         Coord u1 = (*restPosition)[ei.m1] - (*restPosition)[ei.m2];
00256                         Real d1 = u1.norm();
00257                         ei.restlength1=(double) d1;
00258 
00259                         Coord u2 = (*restPosition)[ei.m3] - (*restPosition)[ei.m4];
00260                         Real d2 = u2.norm();
00261                         ei.restlength2=(double) d2;
00262 
00263                         ei.is_activated=true;
00264 
00265                     }else{
00266 
00267                         ei.is_activated=false;
00268                         ei.is_initialized = false;
00269 
00270                     }
00271 
00272                 }else{
00273 
00274                     ei.is_activated=false;
00275                     ei.is_initialized = false;
00276 
00277                 }
00278             }
00279 
00280         }
00281 
00282     }
00283 }
00284 
00285 
00286 template<class DataTypes>
00287 QuadularBendingSprings<DataTypes>::QuadularBendingSprings()
00288 : updateMatrix(true)
00289 {
00290   f_ks = this->initData(&f_ks,(double) 100000.0,"stiffness","uniform stiffness for the all springs");
00291   f_kd = this->initData(&f_kd,(double) 1.0,"damping","uniform damping for the all springs");
00292 }
00293 
00294 
00295 template<class DataTypes>
00296 QuadularBendingSprings<DataTypes>::~QuadularBendingSprings()
00297 {}
00298 
00299 
00300 template <class DataTypes> void QuadularBendingSprings<DataTypes>::handleTopologyChange()
00301 {
00302     bool debug_mode = false;
00303 
00304     std::list<const TopologyChange *>::const_iterator itBegin=_topology->firstChange();
00305     std::list<const TopologyChange *>::const_iterator itEnd=_topology->lastChange();
00306 
00307     edgeInfo.handleTopologyEvents(itBegin,itEnd);
00308     //quadInfo.handleTopologyEvents(itBegin,itEnd);
00309 
00310     while( itBegin != itEnd )
00311     {
00312         core::componentmodel::topology::TopologyChangeType changeType = (*itBegin)->getChangeType();        
00313 
00314         if(changeType == core::componentmodel::topology::POINTSREMOVED){
00315             
00316             unsigned int last = _topology->getNbPoints() -1;
00317             unsigned int i,j;
00318 
00319             const sofa::helper::vector<unsigned int> tab = ( static_cast< const sofa::component::topology::PointsRemoved * >( *itBegin ) )->getArray();
00320 
00321             sofa::helper::vector<unsigned int> lastIndexVec;
00322             for(unsigned int i_init = 0; i_init < tab.size(); ++i_init){
00323 
00324                 lastIndexVec.push_back(last - i_init);
00325             }
00326 
00327             for ( i = 0; i < tab.size(); ++i)
00328             {
00329                 unsigned int i_next = i;
00330                 bool is_reached = false;
00331                 while( (!is_reached) && (i_next < lastIndexVec.size() - 1)){
00332 
00333                     i_next += 1 ;
00334                     is_reached = is_reached || (lastIndexVec[i_next] == tab[i]);
00335                 }
00336 
00337                 if(is_reached){
00338 
00339                     lastIndexVec[i_next] = lastIndexVec[i];
00340 
00341                 }
00342                 
00343                 const sofa::helper::vector<unsigned int> &shell= _topology->getQuadVertexShell(lastIndexVec[i]); 
00344                 for (j=0;j<shell.size();++j) {
00345 
00346                     Quad tj =  _topology->getQuad(shell[j]);
00347                     
00348                     unsigned int vertexIndex = _topology->getVertexIndexInQuad(tj, lastIndexVec[i]);
00349 
00350                     QuadEdges tej = _topology->getEdgeQuadShell(shell[j]);
00351 
00352                     for (unsigned int j_edge=vertexIndex; j_edge%4 !=(vertexIndex+2)%4; ++j_edge) {
00353 
00354                         unsigned int ind_j = tej[j_edge%4];
00355 
00356                         if (edgeInfo[ind_j].m1 == (int) last){
00357                                 edgeInfo[ind_j].m1=(int) tab[i];
00358                                 //std::cout << "INFO_print : OK m1 for ind_j =" << ind_j << std::endl; 
00359                         }else{
00360                             if (edgeInfo[ind_j].m2 == (int) last){
00361                                 edgeInfo[ind_j].m2=(int) tab[i];
00362                                 //std::cout << "INFO_print : OK m2 for ind_j =" << ind_j << std::endl; 
00363                             }
00364                         }
00365 
00366                         if (edgeInfo[ind_j].m3 == (int) last){
00367                                 edgeInfo[ind_j].m3=(int) tab[i];
00368                                 //std::cout << "INFO_print : OK m3 for ind_j =" << ind_j << std::endl; 
00369                         }else{
00370                             if (edgeInfo[ind_j].m4 == (int) last){
00371                                 edgeInfo[ind_j].m4=(int) tab[i];
00372                                 //std::cout << "INFO_print : OK m4 for ind_j =" << ind_j << std::endl; 
00373                             }
00374                         }
00375 
00376                     }
00377                 }
00378                 
00379                 if(debug_mode){
00380 
00381                     for (unsigned int j_loc=0;j_loc<edgeInfo.size();++j_loc) {
00382 
00383                         bool is_forgotten = false;
00384                         if (edgeInfo[j_loc].m1 == (int) last){
00385                             edgeInfo[j_loc].m1 =(int) tab[i];
00386                             is_forgotten=true;
00387                             //std::cout << "INFO_print : QuadularBendingSprings - MISS m1 for j_loc =" << j_loc << std::endl; 
00388 
00389                         }else{
00390                             if (edgeInfo[j_loc].m2 ==(int) last){
00391                                 edgeInfo[j_loc].m2 =(int) tab[i];
00392                                 is_forgotten=true;
00393                                 //std::cout << "INFO_print : QuadularBendingSprings - MISS m2 for j_loc =" << j_loc << std::endl; 
00394 
00395                             }
00396 
00397                         }
00398 
00399                         if (edgeInfo[j_loc].m3 == (int) last){
00400                             edgeInfo[j_loc].m3 =(int) tab[i];
00401                             is_forgotten=true;
00402                             //std::cout << "INFO_print : QuadularBendingSprings - MISS m3 for j_loc =" << j_loc << std::endl; 
00403 
00404                         }else{
00405                             if (edgeInfo[j_loc].m4 ==(int) last){
00406                                 edgeInfo[j_loc].m4 =(int) tab[i];
00407                                 is_forgotten=true;
00408                                 //std::cout << "INFO_print : QuadularBendingSprings - MISS m4 for j_loc =" << j_loc << std::endl; 
00409 
00410                             }
00411 
00412                         }                   
00413                     }
00414                 }
00415 
00416                 --last;
00417             }
00418             
00419         }else{
00420             if(changeType == core::componentmodel::topology::POINTSRENUMBERING){                                                
00421 
00422                 const sofa::helper::vector<unsigned int> tab = ( static_cast< const sofa::component::topology::PointsRenumbering * >( *itBegin ) )->getinv_IndexArray();
00423 
00424                 for ( int i = 0; i < _topology->getNbEdges(); ++i)
00425                 {   
00426                     if(edgeInfo[i].is_activated){
00427                         edgeInfo[i].m1  = tab[edgeInfo[i].m1];
00428                         edgeInfo[i].m2  = tab[edgeInfo[i].m2];  
00429                         edgeInfo[i].m3  = tab[edgeInfo[i].m3];
00430                         edgeInfo[i].m4  = tab[edgeInfo[i].m4];  
00431                     }
00432                 }   
00433             }
00434         }
00435         ++itBegin;
00436     }
00437 }
00438 
00439 
00440 template<class DataTypes>
00441 void QuadularBendingSprings<DataTypes>::init()
00442 {
00443     //std::cerr << "initializing QuadularBendingSprings" << std::endl;
00444     this->Inherited::init();
00445 
00446     _topology = this->getContext()->getMeshTopology();
00447 
00448     if (_topology->getNbQuads()==0)
00449     {
00450         std::cerr << "ERROR(QuadularBendingSprings): object must have a Quadular Set Topology.\n";
00451         return;
00452     }   
00453 
00455     edgeInfo.resize(_topology->getNbEdges());
00456 
00457     // set edge tensor to 0 
00458     for (int i=0;i<_topology->getNbEdges();++i) 
00459     {
00460         QuadularBSEdgeCreationFunction(i, (void*) this, edgeInfo[i],
00461             _topology->getEdge(i),  (const sofa::helper::vector< unsigned int > )0,
00462             (const sofa::helper::vector< double >)0);
00463     }
00464 
00465     // create edge tensor by calling the quad creation function
00466     sofa::helper::vector<unsigned int> quadAdded;
00467     for (int i=0;i<_topology->getNbQuads();++i)
00468     {
00469         quadAdded.push_back(i);
00470     }
00471     QuadularBSQuadCreationFunction(quadAdded,(void*) this,
00472         edgeInfo);
00473 
00474     edgeInfo.setCreateFunction(QuadularBSEdgeCreationFunction);
00475     edgeInfo.setCreateQuadFunction(QuadularBSQuadCreationFunction);
00476     edgeInfo.setDestroyQuadFunction(QuadularBSQuadDestructionFunction);
00477     edgeInfo.setCreateParameter( (void *) this );
00478     edgeInfo.setDestroyParameter( (void *) this );
00480 
00481     /*
00482     dof = dynamic_cast<MechanicalObject<DataTypes>*>( this->getContext()->getMechanicalState() );
00483     assert(dof);
00484     //std::cout<<"==================================QuadularBendingSprings<DataTypes>::init(), dof size = "<<dof->getX()->size()<<std::endl;
00485 
00486     // Set the bending springs
00487 
00488     std::map< IndexPair, IndexPair > edgeMap;
00489     std::set< IndexPair > springSet;
00490 
00491     sofa::core::componentmodel::topology::BaseMeshTopology* topology = this->getContext()->getMeshTopology();
00492     assert( topology );
00493 
00494     const topology::MeshTopology::SeqQuads& quads = topology->getQuads();
00495     //std::cout<<"==================================QuadularBendingSprings<DataTypes>::init(), quads size = "<<quads.size()<<std::endl;
00496     for( unsigned i= 0; i<quads.size(); ++i )
00497     {
00498         const topology::MeshTopology::Quad& face = quads[i];
00499         {
00500             registerEdge( std::make_pair(face[0], face[1]), std::make_pair(face[3], face[2]), edgeMap, springSet );
00501             registerEdge( std::make_pair(face[1], face[2]), std::make_pair(face[0], face[3]), edgeMap, springSet );
00502             registerEdge( std::make_pair(face[2], face[3]), std::make_pair(face[1], face[0]), edgeMap, springSet );
00503             registerEdge( std::make_pair(face[3], face[0]), std::make_pair(face[2], face[1]), edgeMap, springSet );
00504         }
00505     }
00506 
00507     // init the parent class
00508     StiffSpringForceField<DataTypes>::init();
00509     */
00510 }
00511 
00512 template <class DataTypes> 
00513     double QuadularBendingSprings<DataTypes>::getPotentialEnergy(const VecCoord& /*x*/)
00514 {
00515     std::cerr<<"QuadularBendingSprings::getPotentialEnergy-not-implemented !!!"<<endl;
00516     return 0;
00517 }
00518 
00519 template<class DataTypes>
00520 void QuadularBendingSprings<DataTypes>::addForce(VecDeriv& f, const VecCoord& x, const VecDeriv& v)
00521 {   
00522     int nbEdges=_topology->getNbEdges();
00523 
00524     EdgeInformation *einfo;
00525 
00526     //const helper::vector<Spring>& m_springs= this->springs.getValue();
00527     //this->dfdx.resize(nbEdges); //m_springs.size()
00528     f.resize(x.size());
00529     m_potentialEnergy = 0;
00530     /*        cerr<<"QuadularBendingSprings<DataTypes>::addForce()"<<endl;*/
00531 
00532     for(int i=0; i<nbEdges; i++ )
00533     {
00534         einfo=&edgeInfo[i];
00535 
00536         /*            cerr<<"QuadularBendingSprings<DataTypes>::addForce() between "<<springs[i].m1<<" and "<<springs[i].m2<<endl;*/
00537 
00538         if(einfo->is_activated){            
00539 
00540             //this->addSpringForce(m_potentialEnergy,f,x,v, i, einfo->spring);
00541 
00542             int a1 = einfo->m1;
00543             int b1 = einfo->m2;
00544             int a2 = einfo->m3;
00545             int b2 = einfo->m4;
00546             Coord u1 = x[b1]-x[a1];
00547             Real d1 = u1.norm();
00548             Coord u2 = x[b2]-x[a2];
00549             Real d2 = u2.norm();
00550             if( d1>1.0e-4 )
00551             {
00552                 Real inverseLength = 1.0f/d1;
00553                 u1 *= inverseLength;
00554                 Real elongation = (Real)(d1 - einfo->restlength1);
00555                 m_potentialEnergy += elongation * elongation * einfo->ks / 2;
00556         /*      cerr<<"QuadularBendingSprings<DataTypes>::addSpringForce, p = "<<p<<endl;
00557 
00558                 cerr<<"QuadularBendingSprings<DataTypes>::addSpringForce, new potential energy = "<<potentialEnergy<<endl;*/
00559                 Deriv relativeVelocity = v[b1]-v[a1];
00560                 Real elongationVelocity = dot(u1,relativeVelocity);
00561                 Real forceIntensity = (Real)(einfo->ks*elongation+einfo->kd*elongationVelocity);
00562                 Deriv force = u1*forceIntensity;
00563                 f[a1]+=force;
00564                 f[b1]-=force;
00565 
00566                 updateMatrix=true;
00567 
00568                 Mat3& m = einfo->DfDx; //Mat& m = this->dfdx[i];
00569                 Real tgt = forceIntensity * inverseLength;
00570                 for( int j=0; j<3; ++j )
00571                 {
00572                     for( int k=0; k<3; ++k )
00573                     {
00574                         m[j][k] = ((Real)einfo->ks-tgt) * u1[j] * u1[k];
00575                     }
00576                     m[j][j] += tgt;
00577                 }
00578             }
00579             else // null length, no force and no stiffness
00580             {
00581                 Mat3& m = einfo->DfDx; //Mat& m = this->dfdx[i];
00582                 for( int j=0; j<3; ++j )
00583                 {
00584                     for( int k=0; k<3; ++k )
00585                     {
00586                         m[j][k] = 0;
00587                     }
00588                 }
00589             }
00590 
00591             if( d2>1.0e-4 )
00592             {
00593                 Real inverseLength = 1.0f/d2;
00594                 u2 *= inverseLength;
00595                 Real elongation = (Real)(d2 - einfo->restlength2);
00596                 m_potentialEnergy += elongation * elongation * einfo->ks / 2;
00597         /*      cerr<<"QuadularBendingSprings<DataTypes>::addSpringForce, p = "<<p<<endl;
00598 
00599                 cerr<<"QuadularBendingSprings<DataTypes>::addSpringForce, new potential energy = "<<potentialEnergy<<endl;*/
00600                 Deriv relativeVelocity = v[b2]-v[a2];
00601                 Real elongationVelocity = dot(u2,relativeVelocity);
00602                 Real forceIntensity = (Real)(einfo->ks*elongation+einfo->kd*elongationVelocity);
00603                 Deriv force = u2*forceIntensity;
00604                 f[a2]+=force;
00605                 f[b2]-=force;
00606 
00607                 updateMatrix=true;
00608 
00609                 Mat3& m = einfo->DfDx; //Mat& m = this->dfdx[i];
00610                 Real tgt = forceIntensity * inverseLength;
00611                 for( int j=0; j<3; ++j )
00612                 {
00613                     for( int k=0; k<3; ++k )
00614                     {
00615                         m[j][k] = ((Real)einfo->ks-tgt) * u2[j] * u2[k];
00616                     }
00617                     m[j][j] += tgt;
00618                 }
00619             }
00620             else // null length, no force and no stiffness
00621             {
00622                 Mat3& m = einfo->DfDx; //Mat& m = this->dfdx[i];
00623                 for( int j=0; j<3; ++j )
00624                 {
00625                     for( int k=0; k<3; ++k )
00626                     {
00627                         m[j][k] = 0;
00628                     }
00629                 }
00630             }
00631 
00632         }
00633     }
00634 
00635     
00636     //for (unsigned int i=0; i<springs.size(); i++)
00637     //{
00638         /*            cerr<<"QuadularBendingSprings<DataTypes>::addForce() between "<<springs[i].m1<<" and "<<springs[i].m2<<endl;*/
00639     //    this->addSpringForce(m_potentialEnergy,f,x,v, i, springs[i]);
00640     //}
00641 }
00642 
00643 template<class DataTypes>
00644 void QuadularBendingSprings<DataTypes>::addDForce(VecDeriv& df, const VecDeriv& dx)
00645 {       
00646     int nbEdges=_topology->getNbEdges();
00647 
00648     EdgeInformation *einfo;
00649 
00650     df.resize(dx.size());
00651     //cerr<<"QuadularBendingSprings<DataTypes>::addDForce, dx1 = "<<dx1<<endl;
00652     //cerr<<"QuadularBendingSprings<DataTypes>::addDForce, df1 before = "<<f1<<endl;
00653     //const helper::vector<Spring>& springs = this->springs.getValue();
00654 
00655     for(int i=0; i<nbEdges; i++ )
00656     {
00657         einfo=&edgeInfo[i];
00658 
00659         /*            cerr<<"QuadularBendingSprings<DataTypes>::addForce() between "<<springs[i].m1<<" and "<<springs[i].m2<<endl;*/
00660 
00661         if(einfo->is_activated){
00662             //this->addSpringDForce(df,dx, i, einfo->spring);
00663 
00664             const int a1 = einfo->m1;
00665             const int b1 = einfo->m2;
00666             const Coord d1 = dx[b1]-dx[a1];
00667             const int a2 = einfo->m3;
00668             const int b2 = einfo->m4;
00669             const Coord d2 = dx[b2]-dx[a2];
00670             const Deriv dforce1 = einfo->DfDx*d1;
00671             const Deriv dforce2 = einfo->DfDx*d2;
00672             df[a1]+=dforce1;
00673             df[b1]-=dforce1;
00674             df[a2]+=dforce2;
00675             df[b2]-=dforce2;
00676             //cerr<<"QuadularBendingSprings<DataTypes>::addSpringDForce, a="<<a<<", b="<<b<<", dforce ="<<dforce<<endl;
00677         
00678             if(updateMatrix){
00679 
00680             }
00681             updateMatrix=false;
00682         }
00683     }
00684 
00685     //for (unsigned int i=0; i<springs.size(); i++)
00686     //{
00687     //    this->addSpringDForce(df,dx, i, springs[i]);
00688     //}
00689     //cerr<<"QuadularBendingSprings<DataTypes>::addDForce, df = "<<f<<endl;
00690 }
00691 
00692 
00693 /*
00694 template<class DataTypes>
00695 void QuadularBendingSprings<DataTypes>::updateLameCoefficients()
00696 {
00697     lambda= f_youngModulus.getValue()*f_poissonRatio.getValue()/(1-f_poissonRatio.getValue()*f_poissonRatio.getValue());
00698     mu = f_youngModulus.getValue()*(1-f_poissonRatio.getValue())/(1-f_poissonRatio.getValue()*f_poissonRatio.getValue());
00699 //  std::cerr << "initialized Lame coef : lambda=" <<lambda<< " mu="<<mu<<std::endl;
00700 }
00701 */
00702 
00703 
00704 template<class DataTypes>
00705 void QuadularBendingSprings<DataTypes>::draw()
00706 {
00707     if (!this->getContext()->getShowForceFields()) return;
00708     if (!this->mstate) return;
00709 
00710     if (this->getContext()->getShowWireFrame())
00711         glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
00712 
00713     VecCoord& x = *this->mstate->getX();
00714 
00715     glDisable(GL_LIGHTING);
00716 
00717     unsigned int nb_to_draw = 0;
00718 
00719     glBegin(GL_LINES);
00720     for(unsigned int i=0;i<edgeInfo.size(); ++i)
00721     {
00722         if(edgeInfo[i].is_activated){
00723         
00724             
00725             bool external=true;
00726             Real d1 = (x[edgeInfo[i].m2]-x[edgeInfo[i].m1]).norm();
00727             if (external)
00728             {
00729                 if (d1<edgeInfo[i].restlength1*0.9999)
00730                     glColor4f(1,0,0,1);
00731                 else
00732                     glColor4f(0,1,0,1);
00733             }
00734             else
00735             {
00736                 if (d1<edgeInfo[i].restlength1*0.9999)
00737                     glColor4f(1,0.5f,0,1);
00738                 else
00739                     glColor4f(0,1,0.5f,1);
00740             }
00741             
00742 
00743             nb_to_draw+=1;
00744 
00745             //glColor4f(0,1,0,1);
00746             helper::gl::glVertexT(x[edgeInfo[i].m1]);
00747             helper::gl::glVertexT(x[edgeInfo[i].m2]);
00748 
00749             Real d2 = (x[edgeInfo[i].m4]-x[edgeInfo[i].m3]).norm();
00750             if (external)
00751             {
00752                 if (d2<edgeInfo[i].restlength2*0.9999)
00753                     glColor4f(1,0,0,1);
00754                 else
00755                     glColor4f(0,1,0,1);
00756             }
00757             else
00758             {
00759                 if (d2<edgeInfo[i].restlength2*0.9999)
00760                     glColor4f(1,0.5f,0,1);
00761                 else
00762                     glColor4f(0,1,0.5f,1);
00763             }
00764             
00765 
00766             nb_to_draw+=1;
00767 
00768             //glColor4f(0,1,0,1);
00769             helper::gl::glVertexT(x[edgeInfo[i].m3]);
00770             helper::gl::glVertexT(x[edgeInfo[i].m4]);
00771 
00772         }
00773     }
00774     glEnd();
00775 
00776 
00777     if (this->getContext()->getShowWireFrame())
00778         glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
00779 
00780 
00782 
00783     glBegin(GL_QUADS);
00784     glColor4f(1,0,0,1);
00785     for(int i=0;i<_topology->getNbQuads(); ++i)
00786     {
00787         helper::gl::glVertexT(x[_topology->getQuad(i)[0]]);
00788         helper::gl::glVertexT(x[_topology->getQuad(i)[1]]);
00789         helper::gl::glVertexT(x[_topology->getQuad(i)[2]]);
00790         helper::gl::glVertexT(x[_topology->getQuad(i)[3]]);
00791     }
00792     glEnd();
00793 
00795 }
00796 
00797 
00798 
00799 } // namespace forcefield
00800 
00801 } // namespace component
00802 
00803 } // namespace sofa
00804 
00805 #endif

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