DiagonalMass.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_MASS_DIAGONALMASS_INL
00026 #define SOFA_COMPONENT_MASS_DIAGONALMASS_INL
00027 
00028 #include <sofa/component/mass/DiagonalMass.h>
00029 #include <sofa/helper/io/MassSpringLoader.h>
00030 #include <sofa/helper/gl/template.h>
00031 #include <sofa/defaulttype/RigidTypes.h>
00032 #include <sofa/defaulttype/DataTypeInfo.h>
00033 #include <sofa/component/topology/TopologyChangedEvent.h>
00034 #include <sofa/component/topology/PointData.inl>
00035 #include <sofa/component/topology/RegularGridTopology.h>
00036 #include <sofa/component/mass/AddMToMatrixFunctor.h>
00037 
00038 namespace sofa
00039 {
00040 
00041 namespace component
00042 {
00043 
00044 namespace mass
00045 {
00046 
00047 
00048 using namespace sofa::component::topology;
00049 using namespace core::componentmodel::topology;
00050     
00051 template<class MassType>
00052 void MassPointCreationFunction(int , 
00053                    void* , MassType & t, 
00054                    const sofa::helper::vector< unsigned int > &,
00055                    const sofa::helper::vector< double >&)
00056 {
00057     t=0;
00058 }
00059 
00060 template< class DataTypes, class MassType>
00061 inline void MassEdgeCreationFunction(const sofa::helper::vector<unsigned int> &edgeAdded, 
00062                               void* param, vector<MassType> &masses) 
00063 {
00064     DiagonalMass<DataTypes, MassType> *dm= (DiagonalMass<DataTypes, MassType> *)param;
00065     if (dm->getMassTopologyType()==DiagonalMass<DataTypes, MassType>::TOPOLOGY_EDGESET) {       
00066         
00067         typename DataTypes::Real md=dm->getMassDensity();
00068         typename DataTypes::Real mass=typename DataTypes::Real();
00069         unsigned int i;
00070 
00071         for (i=0;i<edgeAdded.size();++i) {
00073             const Edge &e=dm->_topology->getEdge(edgeAdded[i]);
00074             // compute its mass based on the mass density and the edge length
00075             if(dm->edgeGeo){
00076                 mass=(md*dm->edgeGeo->computeRestEdgeLength(edgeAdded[i]))/(typename DataTypes::Real)2.0;
00077             }
00078             // added mass on its two vertices
00079             masses[e[0]]+=mass;
00080             masses[e[1]]+=mass;
00081         }
00082 
00083     }
00084 }
00085 
00086 template< class DataTypes, class MassType>
00087 inline void MassEdgeDestroyFunction(const sofa::helper::vector<unsigned int> &edgeRemoved, 
00088                               void* param, vector<MassType> &masses) 
00089 {
00090     DiagonalMass<DataTypes, MassType> *dm= (DiagonalMass<DataTypes, MassType> *)param;
00091     if (dm->getMassTopologyType()==DiagonalMass<DataTypes, MassType>::TOPOLOGY_EDGESET) {
00092                 
00093         typename DataTypes::Real md=dm->getMassDensity();
00094         typename DataTypes::Real mass=typename DataTypes::Real();
00095         unsigned int i;
00096 
00097         for (i=0;i<edgeRemoved.size();++i) {
00099             const Edge &e=dm->_topology->getEdge(edgeRemoved[i]);
00100             // compute its mass based on the mass density and the edge length
00101             if(dm->edgeGeo){
00102                 mass=(md*dm->edgeGeo->computeRestEdgeLength(edgeRemoved[i]))/(typename DataTypes::Real)2.0;
00103             }
00104             // added mass on its two vertices
00105             masses[e[0]]-=mass;
00106             masses[e[1]]-=mass;
00107         }
00108 
00109     }
00110 }
00111 
00112 template< class DataTypes, class MassType>
00113 inline void MassTriangleCreationFunction(const sofa::helper::vector<unsigned int> &triangleAdded, 
00114                               void* param, vector<MassType> &masses) 
00115 {
00116     DiagonalMass<DataTypes, MassType> *dm= (DiagonalMass<DataTypes, MassType> *)param;
00117     if (dm->getMassTopologyType()==DiagonalMass<DataTypes, MassType>::TOPOLOGY_TRIANGLESET) {
00118                 
00119         typename DataTypes::Real md=dm->getMassDensity();
00120         typename DataTypes::Real mass=typename DataTypes::Real();
00121         unsigned int i;
00122 
00123         for (i=0;i<triangleAdded.size();++i) {
00125             const Triangle &t=dm->_topology->getTriangle(triangleAdded[i]);
00126             // compute its mass based on the mass density and the triangle area
00127             if(dm->triangleGeo){
00128                 mass=(md*dm->triangleGeo->computeRestTriangleArea(triangleAdded[i]))/(typename DataTypes::Real)3.0;
00129             }
00130             // removed  mass on its three vertices
00131             masses[t[0]]+=mass;
00132             masses[t[1]]+=mass;
00133             masses[t[2]]+=mass;
00134         }
00135 
00136     }
00137 }
00138 
00139 template< class DataTypes, class MassType>
00140 inline void MassTriangleDestroyFunction(const sofa::helper::vector<unsigned int> &triangleRemoved, 
00141                               void* param, vector<MassType> &masses) 
00142 {
00143     DiagonalMass<DataTypes, MassType> *dm= (DiagonalMass<DataTypes, MassType> *)param;
00144     if (dm->getMassTopologyType()==DiagonalMass<DataTypes, MassType>::TOPOLOGY_TRIANGLESET) {
00145 
00146         typename DataTypes::Real md=dm->getMassDensity();
00147         typename DataTypes::Real mass=typename DataTypes::Real();
00148         unsigned int i;
00149 
00150         for (i=0;i<triangleRemoved.size();++i) {
00152             const Triangle &t=dm->_topology->getTriangle(triangleRemoved[i]);
00153             // compute its mass based on the mass density and the triangle area
00154             if(dm->triangleGeo){
00155                 mass=(md*dm->triangleGeo->computeRestTriangleArea(triangleRemoved[i]))/(typename DataTypes::Real)3.0;
00156             }
00157             // removed  mass on its three vertices
00158             masses[t[0]]-=mass;
00159             masses[t[1]]-=mass;
00160             masses[t[2]]-=mass;
00161             // Commented to prevent from printing in case of triangle removal
00162             //std::cerr<< "mass vertex " << t[0]<< " = " << masses[t[0]]<<std::endl;
00163             //std::cerr<< "mass vertex " << t[1]<< " = " << masses[t[1]]<<std::endl;
00164             //std::cerr<< "mass vertex " << t[2]<< " = " << masses[t[2]]<<std::endl;
00165         }
00166 
00167     }
00168 }
00169 
00170 template< class DataTypes, class MassType>
00171 inline void MassTetrahedronCreationFunction(const sofa::helper::vector<unsigned int> &tetrahedronAdded, 
00172                               void* param, vector<MassType> &masses) 
00173 {
00174     DiagonalMass<DataTypes, MassType> *dm= (DiagonalMass<DataTypes, MassType> *)param;
00175     if (dm->getMassTopologyType()==DiagonalMass<DataTypes, MassType>::TOPOLOGY_TETRAHEDRONSET) {
00176         
00177         typename DataTypes::Real md=dm->getMassDensity();
00178         typename DataTypes::Real mass=typename DataTypes::Real();
00179         unsigned int i;
00180 
00181         for (i=0;i<tetrahedronAdded.size();++i) {
00183             const Tetrahedron &t=dm->_topology->getTetra(tetrahedronAdded[i]);
00184             // compute its mass based on the mass density and the tetrahedron volume
00185             if(dm->tetraGeo){
00186                 mass=(md*dm->tetraGeo->computeRestTetrahedronVolume(tetrahedronAdded[i]))/(typename DataTypes::Real)4.0;
00187             }
00188             // removed  mass on its four vertices
00189             masses[t[0]]+=mass;
00190             masses[t[1]]+=mass;
00191             masses[t[2]]+=mass;
00192             masses[t[3]]+=mass;
00193 
00194         }
00195 
00196     }
00197 }
00198 
00199 template< class DataTypes, class MassType>
00200 inline void MassTetrahedronDestroyFunction(const sofa::helper::vector<unsigned int> &tetrahedronRemoved, 
00201                               void* param, vector<MassType> &masses) 
00202 {
00203     DiagonalMass<DataTypes, MassType> *dm= (DiagonalMass<DataTypes, MassType> *)param;
00204     if (dm->getMassTopologyType()==DiagonalMass<DataTypes, MassType>::TOPOLOGY_TETRAHEDRONSET) {
00205         
00206         typename DataTypes::Real md=dm->getMassDensity();
00207         typename DataTypes::Real mass=typename DataTypes::Real();
00208         unsigned int i;
00209 
00210         for (i=0;i<tetrahedronRemoved.size();++i) {
00212             const Tetrahedron &t=dm->_topology->getTetra(tetrahedronRemoved[i]);
00213             if(dm->tetraGeo){
00214                 // compute its mass based on the mass density and the tetrahedron volume
00215                 mass=(md*dm->tetraGeo->computeRestTetrahedronVolume(tetrahedronRemoved[i]))/(typename DataTypes::Real)4.0;
00216             }
00217             // removed  mass on its four vertices
00218             masses[t[0]]-=mass;
00219             masses[t[1]]-=mass;
00220             masses[t[2]]-=mass;
00221             masses[t[3]]-=mass;
00222         }
00223 
00224     }
00225 }
00226 
00227 
00228 using namespace sofa::defaulttype;
00229 using namespace sofa::core::componentmodel::behavior;
00230 
00231 
00232 template <class DataTypes, class MassType>
00233 DiagonalMass<DataTypes, MassType>::DiagonalMass()
00234 : f_mass( initData(&f_mass, "mass", "values of the particles masses") )
00235 , m_massDensity( initData(&m_massDensity, (Real)1.0,"massDensity", "mass density that allows to compute the  particles masses from a mesh topology and geometry.\nOnly used if > 0") )
00236 , showCenterOfGravity( initData(&showCenterOfGravity, false, "showGravityCenter", "display the center of gravity of the system" ) )
00237 , showAxisSize( initData(&showAxisSize, 1.0f, "showAxisSizeFactor", "factor length of the axis displayed (only used for rigids)" ) )
00238 , topologyType(TOPOLOGY_UNKNOWN)
00239 {
00240 
00241 }
00242 
00243 
00244 
00245 
00246 template <class DataTypes, class MassType>
00247 DiagonalMass<DataTypes, MassType>::~DiagonalMass()
00248 {
00249 }
00250 
00251 template <class DataTypes, class MassType>
00252 void DiagonalMass<DataTypes, MassType>::clear()
00253 {
00254     VecMass& masses = *f_mass.beginEdit();
00255     masses.clear();
00256     f_mass.endEdit();
00257 }
00258 
00259 template <class DataTypes, class MassType>
00260 void DiagonalMass<DataTypes, MassType>::addMass(const MassType& m)
00261 {
00262     VecMass& masses = *f_mass.beginEdit();
00263     masses.push_back(m);
00264     f_mass.endEdit();
00265 }
00266 
00267 template <class DataTypes, class MassType>
00268 void DiagonalMass<DataTypes, MassType>::resize(int vsize)
00269 {
00270     VecMass& masses = *f_mass.beginEdit();
00271     masses.resize(vsize);
00272     f_mass.endEdit();
00273 }
00274 
00275 // -- Mass interface
00276 template <class DataTypes, class MassType>
00277 void DiagonalMass<DataTypes, MassType>::addMDx(VecDeriv& res, const VecDeriv& dx, double factor)
00278 {
00279 
00280     const MassVector &masses= f_mass.getValue();
00281     if (factor == 1.0)
00282     {
00283         for (unsigned int i=0;i<dx.size();i++)
00284         {
00285             res[i] += dx[i] * masses[i];
00286         }
00287     }
00288     else
00289     {
00290         for (unsigned int i=0;i<dx.size();i++)
00291         {
00292             res[i] += (dx[i] * masses[i]) * (Real)factor;
00293         }
00294     }
00295 }
00296 
00297 template <class DataTypes, class MassType>
00298 void DiagonalMass<DataTypes, MassType>::accFromF(VecDeriv& a, const VecDeriv& f)
00299 {
00300 
00301     const MassVector &masses= f_mass.getValue();
00302     for (unsigned int i=0;i<f.size();i++)
00303     {
00304         a[i] = f[i] / masses[i];
00305     }
00306 }
00307 
00308 template <class DataTypes, class MassType>
00309     double DiagonalMass<DataTypes, MassType>::getKineticEnergy( const VecDeriv& v )
00310 {
00311 
00312     const MassVector &masses= f_mass.getValue();
00313     double e = 0;
00314     for (unsigned int i=0;i<masses.size();i++)
00315     {
00316         e += v[i]*masses[i]*v[i]; // v[i]*v[i]*masses[i] would be more efficient but less generic
00317     }
00318     return e/2;
00319 }
00320 
00321 template <class DataTypes, class MassType>
00322     double DiagonalMass<DataTypes, MassType>::getPotentialEnergy( const VecCoord& x )
00323 {
00324 
00325     const MassVector &masses= f_mass.getValue();
00326     SReal e = 0;
00327     // gravity
00328     Vec3d g ( this->getContext()->getLocalGravity() );
00329     Deriv theGravity;
00330     DataTypes::set ( theGravity, g[0], g[1], g[2]);
00331     for (unsigned int i=0;i<masses.size();i++)
00332     {
00333         e -= theGravity*masses[i]*x[i];
00334     }
00335     return e;
00336 }
00337 
00338 template <class DataTypes, class MassType>
00339 void DiagonalMass<DataTypes, MassType>::addMToMatrix(defaulttype::BaseMatrix * mat, double mFact, unsigned int &offset)
00340 {
00341     const MassVector &masses= f_mass.getValue();
00342     const int N = defaulttype::DataTypeInfo<Deriv>::size();
00343     AddMToMatrixFunctor<Deriv,MassType> calc;
00344     for (unsigned int i=0;i<masses.size();i++)
00345         calc(mat, masses[i], offset + N*i, mFact);
00346 }
00347 
00348 
00349 template <class DataTypes, class MassType>
00350     double DiagonalMass<DataTypes, MassType>::getElementMass(unsigned int index)
00351 {
00352     return (SReal)(f_mass.getValue()[index]);
00353 }
00354 
00355 
00356 template <class DataTypes, class MassType>
00357 void DiagonalMass<DataTypes, MassType>::handleTopologyChange()
00358 {
00359     std::list<const TopologyChange *>::const_iterator itBegin=_topology->firstChange();
00360     std::list<const TopologyChange *>::const_iterator itEnd=_topology->lastChange();
00361     std::list<const TopologyChange *>::const_iterator it;
00362 
00363     VecMass& masses = *f_mass.beginEdit();
00364     masses.handleTopologyEvents(itBegin,itEnd);
00365     f_mass.endEdit();
00366 }
00367 
00368 
00369   template <class DataTypes, class MassType>
00370   void DiagonalMass<DataTypes, MassType>::reinit()
00371   {
00372     if (_topology && (m_massDensity.getValue() > 0 || f_mass.getValue().size() == 0))
00373       {
00374     if (_topology->getNbTetras()>0) {
00375 
00376       VecMass& masses = *f_mass.beginEdit();
00377       topologyType=TOPOLOGY_TETRAHEDRONSET;                   
00378                         
00379       // resize array
00380       clear();
00381       masses.resize(this->mstate->getSize());
00382                         
00383       for(unsigned int i=0;i<masses.size();++i)
00384         masses[i]=(Real)0;
00385 
00386       Real md=m_massDensity.getValue();
00387       Real mass=Real();
00388 
00389       for (int i=0;i<_topology->getNbTetras();++i) {          
00390 
00391         const Tetrahedron &t=_topology->getTetra(i);
00392         if(tetraGeo){
00393           mass=(md*tetraGeo->computeRestTetrahedronVolume(i))/(Real)4.0;
00394         }
00395         masses[t[0]]+=mass;
00396         masses[t[1]]+=mass;
00397         masses[t[2]]+=mass;
00398         masses[t[3]]+=mass;
00399       }
00400       f_mass.endEdit();
00401     }
00402     else if (_topology->getNbTriangles()>0) {
00403       VecMass& masses = *f_mass.beginEdit();
00404       topologyType=TOPOLOGY_TRIANGLESET;
00405 
00406       // resize array
00407       clear();
00408       masses.resize(this->mstate->getSize());
00409 
00410       for(unsigned int i=0;i<masses.size();++i)
00411         masses[i]=(Real)0;
00412 
00413       Real md=m_massDensity.getValue();
00414       Real mass=Real();
00415 
00416       for (int i=0;i<_topology->getNbTriangles();++i) {
00417         const Triangle &t=_topology->getTriangle(i);
00418         if(triangleGeo){
00419           mass=(md*triangleGeo->computeRestTriangleArea(i))/(Real)3.0;
00420         }
00421         masses[t[0]]+=mass;
00422         masses[t[1]]+=mass;
00423         masses[t[2]]+=mass;
00424       }
00425       f_mass.endEdit();
00426     }
00427     /*
00428       else if (_topology->getNbHexas()>0) {
00429 
00430       // TODO : Hexas
00431       topologyType=TOPOLOGY_HEXAHEDRONSET;
00432       }
00433       else if (_topology->getNbQuads()>0) {
00434 
00435       // TODO : Quads
00436       topologyType=TOPOLOGY_QUADSET;
00437       }
00438     */
00439     else if (_topology->getNbEdges()>0) {
00440 
00441       VecMass& masses = *f_mass.beginEdit();
00442       topologyType=TOPOLOGY_EDGESET;
00443                         
00444       // resize array
00445       clear();
00446       masses.resize(this->mstate->getSize());
00447                         
00448       for(unsigned int i=0;i<masses.size();++i)
00449         masses[i]=(Real)0;
00450 
00451       Real md=m_massDensity.getValue();
00452       Real mass=Real();
00453 
00454       for (int i=0;i<_topology->getNbEdges();++i) {
00455         const Edge &e=_topology->getEdge(i);
00456         if(edgeGeo){
00457           mass=(md*edgeGeo->computeEdgeLength(i))/(Real)2.0;
00458         }
00459         masses[e[0]]+=mass;
00460         masses[e[1]]+=mass;
00461       }
00462       f_mass.endEdit();
00463     } 
00464       }
00465   }
00466 
00467 template <class DataTypes, class MassType>
00468 void DiagonalMass<DataTypes, MassType>::init()
00469 {
00470 /*  using sofa::component::topology::RegularGridTopology;
00471   RegularGridTopology* reg = dynamic_cast<RegularGridTopology*>( getContext()->getMeshTopology() );
00472   if( reg != NULL )
00473   {
00474     Real weight = reg->getDx().norm() * reg->getDy().norm() * reg->getDz().norm() * m_massDensity.getValue()/8;
00475     VecMass& m = *f_mass.beginEdit();
00476     for( int i=0; i<reg->getNx()-1; i++ )
00477     {
00478       for( int j=0; j<reg->getNy()-1; j++ )
00479       {
00480         for( int k=0; k<reg->getNz()-1; k++ )
00481         {
00482           m[reg->point(i,j,k)] += weight;
00483           m[reg->point(i,j,k+1)] += weight;
00484           m[reg->point(i,j+1,k)] += weight;
00485           m[reg->point(i,j+1,k+1)] += weight;
00486           m[reg->point(i+1,j,k)] += weight;
00487           m[reg->point(i+1,j,k+1)] += weight;
00488           m[reg->point(i+1,j+1,k)] += weight;
00489           m[reg->point(i+1,j+1,k+1)] += weight;
00490         }
00491       }
00492     }
00493     f_mass.endEdit();
00494   }*/   
00495 
00496     _topology = this->getContext()->getMeshTopology();  
00497 
00498     this->getContext()->get(edgeGeo);
00499     this->getContext()->get(triangleGeo);
00500     this->getContext()->get(quadGeo);
00501     this->getContext()->get(tetraGeo);
00502     this->getContext()->get(hexaGeo);
00503 
00504     Inherited::init();
00505 
00506     // add the functions to handle topology changes.
00507 
00508     VecMass& masses = *f_mass.beginEdit();
00509         masses.setCreateFunction(MassPointCreationFunction<MassType>);
00510     masses.setCreateEdgeFunction(MassEdgeCreationFunction<DataTypes,MassType>);
00511     masses.setDestroyEdgeFunction(MassEdgeDestroyFunction<DataTypes,MassType>);
00512     masses.setCreateTriangleFunction(MassTriangleCreationFunction<DataTypes,MassType>);
00513     masses.setDestroyTriangleFunction(MassTriangleDestroyFunction<DataTypes,MassType>);
00514     masses.setCreateTetrahedronFunction(MassTetrahedronCreationFunction<DataTypes,MassType>);
00515     masses.setDestroyTetrahedronFunction(MassTetrahedronDestroyFunction<DataTypes,MassType>);
00516 
00517     masses.setCreateParameter( (void *) this );
00518     masses.setDestroyParameter( (void *) this );
00519     f_mass.endEdit();
00520 
00521     if ((f_mass.getValue().size()==0) && (_topology!=0)) {      
00522           reinit();       
00523         }
00524 }
00525 
00526 template <class DataTypes, class MassType>
00527 void DiagonalMass<DataTypes, MassType>::addGravityToV(double dt)
00528 {
00529     if(this->mstate){
00530         VecDeriv& v = *this->mstate->getV();
00531 
00532         // gravity
00533         Vec3d g ( this->getContext()->getLocalGravity() );
00534         Deriv theGravity;
00535         DataTypes::set ( theGravity, g[0], g[1], g[2]);
00536         Deriv hg = theGravity * (typename DataTypes::Real)dt;
00537 
00538         for (unsigned int i=0;i<v.size();i++) {
00539             v[i] += hg;
00540         }
00541     }
00542 }
00543 
00544 template <class DataTypes, class MassType>
00545 void DiagonalMass<DataTypes, MassType>::addForce(VecDeriv& f, const VecCoord& x, const VecDeriv& v)
00546 {
00547     //if gravity was added separately (in solver's "solve" method), then nothing to do here
00548     if(this->m_separateGravity.getValue())
00549         return;
00550 
00551     const MassVector &masses= f_mass.getValue();
00552 
00553     // gravity
00554     Vec3d g ( this->getContext()->getLocalGravity() );
00555     Deriv theGravity;
00556     DataTypes::set ( theGravity, g[0], g[1], g[2]);
00557     
00558     // velocity-based stuff
00559     core::objectmodel::BaseContext::SpatialVector vframe = getContext()->getVelocityInWorld();
00560     core::objectmodel::BaseContext::Vec3 aframe = getContext()->getVelocityBasedLinearAccelerationInWorld() ;
00561 
00562     // project back to local frame
00563     vframe = getContext()->getPositionInWorld() / vframe;
00564     aframe = getContext()->getPositionInWorld().backProjectVector( aframe );
00565     
00566     // add weight and inertia force
00567     for (unsigned int i=0;i<masses.size();i++) {
00568         f[i] += theGravity*masses[i] + core::componentmodel::behavior::inertiaForce(vframe,aframe,masses[i],x[i],v[i]);
00569     }
00570 }
00571 
00572 template <class DataTypes, class MassType>
00573     void DiagonalMass<DataTypes, MassType>::draw()
00574 {
00575   if (!getContext()->getShowBehaviorModels()) return;
00576   const MassVector &masses= f_mass.getValue();
00577   const VecCoord& x = *this->mstate->getX();
00578   Coord gravityCenter;
00579   Real totalMass=0.0;
00580   glDisable (GL_LIGHTING);
00581   glPointSize(2);
00582   glColor4f (1,1,1,1);
00583   glBegin (GL_POINTS);
00584   for (unsigned int i=0; i<x.size(); i++)
00585   {
00586     helper::gl::glVertexT(x[i]);
00587     gravityCenter += x[i]*masses[i];
00588     totalMass += masses[i];
00589   }
00590   glEnd();
00591   if(showCenterOfGravity.getValue()){
00592     glBegin (GL_LINES);
00593     glColor4f (1,1,0,1);
00594     glPointSize(5);
00595     gravityCenter /= totalMass;
00596     for(unsigned int i=0 ; i<Coord::static_size ; i++){
00597       Coord v;
00598       v[i] = showAxisSize.getValue();
00599       helper::gl::glVertexT(gravityCenter-v);
00600       helper::gl::glVertexT(gravityCenter+v);
00601     }
00602     glEnd();
00603   }
00604 }
00605 
00606 template <class DataTypes, class MassType>
00607     bool DiagonalMass<DataTypes, MassType>::addBBox(double* minBBox, double* maxBBox)
00608 {
00609     const VecCoord& x = *this->mstate->getX();
00610     for (unsigned int i=0; i<x.size(); i++)
00611     {
00612         //const Coord& p = x[i];
00613         Real p[3] = {0.0, 0.0, 0.0};
00614         DataTypes::get(p[0],p[1],p[2],x[i]);
00615         for (int c=0;c<3;c++)
00616         {
00617             if (p[c] > maxBBox[c]) maxBBox[c] = p[c];
00618             if (p[c] < minBBox[c]) minBBox[c] = p[c];
00619         }
00620     }
00621     return true;
00622 }
00623 
00624 template <class DataTypes, class MassType>
00625 class DiagonalMass<DataTypes, MassType>::Loader : public helper::io::MassSpringLoader
00626 {
00627 public:
00628     DiagonalMass<DataTypes, MassType>* dest;
00629     Loader(DiagonalMass<DataTypes, MassType>* dest) : dest(dest) {}
00630     virtual void addMass(SReal /*px*/, SReal /*py*/, SReal /*pz*/, SReal /*vx*/, SReal /*vy*/, SReal /*vz*/, SReal mass, SReal /*elastic*/, bool /*fixed*/, bool /*surface*/)
00631     {
00632         dest->addMass(MassType((Real)mass));
00633     }
00634 };
00635 
00636 template <class DataTypes, class MassType>
00637 bool DiagonalMass<DataTypes, MassType>::load(const char *filename)
00638 {
00639     clear();
00640     if (filename!=NULL && filename[0]!='\0')
00641     {
00642         Loader loader(this);
00643         return loader.load(filename);
00644     }
00645     else return false;
00646 }
00647 
00648 // Specialization for rigids
00649 #ifndef SOFA_FLOAT
00650 /*template <>
00651     inline void MassEdgeDestroyFunction<Rigid3dTypes, Rigid3dMass>(const sofa::helper::vector<unsigned int> &, 
00652     void* , vector<Rigid3dMass> &); 
00653 
00654 template <>
00655     inline void MassEdgeCreationFunction<Rigid3dTypes, Rigid3dMass>(const sofa::helper::vector<unsigned int> &, 
00656     void* , vector<Rigid3dMass> &);*/
00657 
00658 template <>
00659     double DiagonalMass<Rigid3dTypes, Rigid3dMass>::getPotentialEnergy( const VecCoord& x );
00660 template <>
00661     double DiagonalMass<Rigid2dTypes, Rigid2dMass>::getPotentialEnergy( const VecCoord& x );
00662 template <>
00663     void DiagonalMass<Rigid3dTypes, Rigid3dMass>::draw();
00664 template <>
00665     void DiagonalMass<Rigid2dTypes, Rigid2dMass>::draw();
00666 #endif
00667 #ifndef SOFA_DOUBLE
00668 template <>
00669     double DiagonalMass<Rigid3fTypes, Rigid3fMass>::getPotentialEnergy( const VecCoord& x );
00670 template <>
00671     double DiagonalMass<Rigid2fTypes, Rigid2fMass>::getPotentialEnergy( const VecCoord& x );
00672 
00673 template <>
00674     void DiagonalMass<Rigid3fTypes, Rigid3fMass>::draw();
00675 template <>
00676     void DiagonalMass<Rigid2fTypes, Rigid2fMass>::draw();
00677 #endif
00678 
00679 
00680 template<class DataTypes, class MassType>
00681 void DiagonalMass<DataTypes, MassType>::parse(core::objectmodel::BaseObjectDescription* arg)
00682 {
00683    
00684     if (arg->getAttribute("filename"))
00685     {
00686         this->load(arg->getAttribute("filename"));
00687         arg->removeAttribute("filename");
00688     }
00689      this->Inherited::parse(arg);  
00690 }
00691 
00692 
00693 
00694 } // namespace mass
00695 
00696 } // namespace component
00697 
00698 } // namespace sofa
00699 
00700 #endif

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