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

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