MechanicalObject.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_MECHANICALOBJECT_INL
00026 #define SOFA_COMPONENT_MECHANICALOBJECT_INL
00027 
00028 #include <sofa/component/MechanicalObject.h>
00029 #include <sofa/core/componentmodel/topology/BaseMeshTopology.h>
00030 
00031 #include <sofa/component/topology/PointSetTopologyChange.h>
00032 
00033 #include <sofa/component/topology/RegularGridTopology.h>
00034 #include <sofa/helper/io/MassSpringLoader.h>
00035 
00036 #include <sofa/defaulttype/VecTypes.h>
00037 #include <sofa/defaulttype/RigidTypes.h>
00038 #include <sofa/defaulttype/DataTypeInfo.h>
00039 #include <sofa/helper/system/glut.h>
00040 
00041 #include <assert.h>
00042 #include <iostream>
00043 
00044 #include <sofa/component/MeshLoader.h>
00045 
00046 namespace sofa
00047 {
00048   
00049 
00050   namespace component
00051   {
00052 
00053     using namespace topology;
00054     using namespace sofa::core::componentmodel::topology;
00055 
00056     using namespace sofa::defaulttype;
00057     template <class DataTypes>
00058     MechanicalObject<DataTypes>::MechanicalObject()
00059       : x(new VecCoord), v(new VecDeriv), f(new VecDeriv), dx(new VecDeriv), x0(new VecCoord),reset_position(NULL), v0(NULL), xfree(new VecCoord), vfree(new VecDeriv), c(new VecConst), vsize(0), m_gnuplotFileX(NULL), m_gnuplotFileV(NULL)
00060       , f_X ( new XDataPtr<DataTypes>(&x,  "position coordinates of the degrees of freedom") )
00061       , f_V ( new VDataPtr<DataTypes>(&v,  "velocity coordinates of the degrees of freedom") )
00062       , f_F ( new VDataPtr<DataTypes>(&f,  "f vector of the degrees of freedom") )
00063       , f_Dx ( new VDataPtr<DataTypes>(&dx,  "dx vector of the degrees of freedom") )
00064       , f_Xfree ( new XDataPtr<DataTypes>(&xfree,  "free position coordinates of the degrees of freedom") )
00065       , f_Vfree ( new VDataPtr<DataTypes>(&vfree,  "free velocity coordinates of the degrees of freedom") )
00066       , f_X0( new XDataPtr<DataTypes>(&x0, "rest position coordinates of the degrees of freedom") )     
00067 
00068     {
00069       //HACK
00070       if (!restScale.isSet())
00071     restScale.setValue(1);
00072       initialized = false;
00073       this->addField(f_X, "position");
00074       this->addField(f_V, "velocity");
00075       this->addField(f_F, "force");
00076       this->addField(f_Dx, "derivX");
00077       this->addField(f_Xfree, "free_position");
00078       this->addField(f_Vfree, "free_velocity");
00079       this->addField(f_X0,"rest_position");
00080       
00081 
00082       f_X->init();
00083       f_V->init();
00084       f_F->init();
00085       f_Dx->init();
00086       f_Xfree->init();
00087       f_Vfree->init();
00088       f_X0->init();
00089 
00090 
00091 
00092       restScale = this->initData(&restScale, (SReal)1.0, "restScale","optional scaling of rest position coordinates (to simulated pre-existing internal tension)");
00093       translation=this->initData(&translation, Vector3(), "translation", "Translation of the DOFs");
00094       rotation=this->initData(&rotation, Vector3(), "rotation", "Rotation of the DOFs");
00095       scale=this->initData(&scale, (SReal)1.0, "scale", "Scale of the DOFs");
00096       filename=this->initData(&filename, std::string(""), "filename", "File corresponding to the Mechanical Object", false);
00097       debugViewIndices=this->initData(&debugViewIndices, (bool) false, "debugViewIndices", "Debug : view indices");
00098       debugViewIndicesScale=this->initData(&debugViewIndicesScale, (float) 0.0001, "debugViewIndicesScale", "Debug : scale for view indices");
00099       
00100       /*    x = new VecCoord;
00101         v = new VecDeriv;*/
00102       internalForces = f; // = new VecDeriv;
00103       externalForces = new VecDeriv;
00104       //dx = new VecDeriv;
00105 
00106       // default size is 1
00107       resize(1);
00108       setVecCoord(VecId::position().index, this->x);
00109       setVecDeriv(VecId::velocity().index, this->v);
00110       setVecDeriv(VecId::force().index, this->f);
00111       setVecDeriv(VecId::dx().index, this->dx);
00112       setVecCoord(VecId::restPosition().index, this->x0);
00113       setVecCoord(VecId::freePosition().index, this->xfree);
00114       setVecDeriv(VecId::freeVelocity().index, this->vfree);
00115       /*    cerr<<"MechanicalObject<DataTypes>::MechanicalObject, x.size() = "<<x->size()<<endl;
00116         cerr<<"MechanicalObject<DataTypes>::MechanicalObject, v.size() = "<<v->size()<<endl;*/
00117     }
00118 
00119     template <class DataTypes>
00120     void MechanicalObject<DataTypes>::initGnuplot(const std::string path)
00121     {
00122       if( !this->getName().empty() ){
00123         if (m_gnuplotFileX != NULL) delete m_gnuplotFileX;
00124         if (m_gnuplotFileV != NULL) delete m_gnuplotFileV;
00125     m_gnuplotFileX = new std::ofstream( (path + this->getName()+"_x.txt").c_str() );
00126     m_gnuplotFileV = new std::ofstream( (path + this->getName()+"_v.txt").c_str() );
00127       }
00128     }
00129 
00130     template <class DataTypes>
00131     void MechanicalObject<DataTypes>::exportGnuplot(Real time)
00132     {
00133       if( m_gnuplotFileX!=NULL ){
00134     (*m_gnuplotFileX) << time <<"\t"<< *getX() << std::endl;
00135       }
00136       if( m_gnuplotFileV!=NULL ){
00137     (*m_gnuplotFileV) << time <<"\t"<< *getV() << std::endl;
00138       }
00139     }
00140 
00141     template <class DataTypes>
00142     MechanicalObject<DataTypes>& 
00143     MechanicalObject<DataTypes>::operator = (const MechanicalObject& obj)
00144     {
00145       resize( obj.getSize() );
00146       /*    *getX() = *obj.getX();
00147         if( obj.x0 != NULL ){
00148         x0 = new VecCoord;
00149         *x0 = *obj.x0;
00150         }
00151         *getV() = *obj.getV();
00152         if( obj.v0 != NULL ){
00153         v0 = new VecDeriv;
00154         *v0 = *obj.v0;
00155         }*/
00156       return *this;
00157     }
00158 
00159     template<class DataTypes>
00160     class MechanicalObject<DataTypes>::Loader : public helper::io::MassSpringLoader
00161     {
00162     public:
00163       MechanicalObject<DataTypes>* dest;
00164       int index;
00165       Loader(MechanicalObject<DataTypes>* dest) : dest(dest), index(0) {}
00166 
00167       virtual void addMass(SReal px, SReal py, SReal pz, SReal vx, SReal vy, SReal vz, SReal /*mass*/, SReal /*elastic*/, bool /*fixed*/, bool /*surface*/)
00168       {
00169     dest->resize(index+1);
00170     DataTypes::set((*dest->getX())[index], px, py, pz);
00171     DataTypes::set((*dest->getV())[index], vx, vy, vz);
00172     ++index;
00173       }
00174     };
00175 
00176     template<class DataTypes>
00177     bool MechanicalObject<DataTypes>::load(const char* filename)
00178     {
00179       typename MechanicalObject<DataTypes>::Loader loader(this);
00180       return loader.load(filename);
00181     }
00182 
00183     template <class DataTypes>
00184     void MechanicalObject<DataTypes>::parse ( BaseObjectDescription* arg )
00185     {
00186       if (arg->getAttribute("filename")) {  
00187     filename.setValue(arg->getAttribute("filename"));        
00188       }
00189       if (!filename.getValue().empty()) 
00190       {
00191     load(filename.getValue().c_str());
00192     filename.setValue(std::string("")); //clear the field filename: When we save the scene, we don't need anymore the filename
00193       }
00194 
00195       unsigned int size0 = getX()->size();
00196       Inherited::parse(arg);
00197       if (arg->getAttribute("size")!=NULL) {
00198         resize( atoi(arg->getAttribute("size")) );
00199       }
00200       else if (getX()->size() != size0)
00201         resize( getX()->size() );
00202 
00203       //obj->parseTransform(arg);
00204       if (arg->getAttribute("scale")!=NULL) {
00205     scale.setValue((SReal)atof(arg->getAttribute("scale")));      
00206     //applyScale(scale.getValue());   
00207       }
00208       if (arg->getAttribute("rx")!=NULL || arg->getAttribute("ry")!=NULL || arg->getAttribute("rz")!=NULL) {
00209     rotation.setValue(Vector3((SReal)(atof(arg->getAttribute("rx","0.0"))),(SReal)(atof(arg->getAttribute("ry","0.0"))),(SReal)(atof(arg->getAttribute("rz","0.0")))));
00210 
00211     //Quaternion q=helper::Quater<SReal>::createQuaterFromEuler( Vec<3,SReal>(rotation.getValue()[0],rotation.getValue()[1],rotation.getValue()[2]));
00212     //applyRotation(q);
00213       }
00214       if (arg->getAttribute("dx")!=NULL || arg->getAttribute("dy")!=NULL || arg->getAttribute("dz")!=NULL) {        
00215     translation.setValue(Vector3((Real)atof(arg->getAttribute("dx","0.0")), (Real)atof(arg->getAttribute("dy","0.0")), (Real)atof(arg->getAttribute("dz","0.0"))));
00216     //applyTranslation(translation.getValue()[0],translation.getValue()[1],translation.getValue()[2]);
00217       }
00218 
00219     }
00220 
00221     template <class DataTypes>
00222     MechanicalObject<DataTypes>::~MechanicalObject()
00223     {
00224       delete externalForces;
00225       if (reset_position!=NULL)
00226         delete reset_position;
00227       //if (x0!=NULL)
00228       //  delete x0;
00229       if (v0!=NULL)
00230         delete v0;
00231       for (unsigned int i=0;i<vectorsCoord.size();i++)
00232         if (vectorsCoord[i]!=NULL)
00233       delete vectorsCoord[i];
00234       for (unsigned int i=0;i<vectorsDeriv.size();i++)
00235         if (vectorsDeriv[i]!=NULL)
00236       delete vectorsDeriv[i];
00237       if( m_gnuplotFileV!=NULL )
00238     delete m_gnuplotFileV;
00239       if( m_gnuplotFileX!=NULL )
00240     delete m_gnuplotFileX;
00241     }
00242 
00243 
00244     template <class DataTypes>
00245     void MechanicalObject<DataTypes>::handleStateChange()
00246     {                  
00247         std::list<const sofa::core::componentmodel::topology::TopologyChange *>::const_iterator itBegin=_topology->firstStateChange();
00248         std::list<const sofa::core::componentmodel::topology::TopologyChange *>::const_iterator itEnd=_topology->lastStateChange();     
00249 
00250         while( itBegin != itEnd )
00251         {
00252             TopologyChangeType changeType = (*itBegin)->getChangeType();
00253 
00254             switch( changeType ) 
00255             {
00256                 case core::componentmodel::topology::POINTSADDED:
00257                     {                       
00258                         unsigned int nbPoints = ( static_cast< const PointsAdded * >( *itBegin ) )->getNbAddedVertices();
00259                         sofa::helper::vector< sofa::helper::vector< unsigned int > > ancestors = ( static_cast< const PointsAdded * >( *itBegin ) )->ancestorsList;
00260                         sofa::helper::vector< sofa::helper::vector< double       > > coefs     = ( static_cast< const PointsAdded * >( *itBegin ) )->coefs;
00261 
00262                         if (!ancestors.empty() )
00263                         {
00264                             unsigned int prevSizeMechObj = getSize();
00265                             resize( prevSizeMechObj + nbPoints );
00266 
00267                             sofa::helper::vector< sofa::helper::vector< double > > coefs2;
00268                             coefs2.resize(ancestors.size());
00269 
00270                             for (unsigned int i = 0; i < ancestors.size(); ++i)
00271                               {                                       
00272                                 coefs2[i].resize(ancestors[i].size());
00273 
00274                                 for (unsigned int j = 0; j < ancestors[i].size(); ++j)
00275                                   {
00276                                     // constructng default coefs if none were defined
00277                                     if (coefs == (const sofa::helper::vector< sofa::helper::vector< double > >)0 || coefs[i].size() == 0)
00278                                       coefs2[i][j] = 1.0f / ancestors[i].size();
00279                                     else
00280                                       coefs2[i][j] = coefs[i][j];
00281                                   }
00282                              }
00283 
00284                             for (unsigned int i = 0; i < ancestors.size(); ++i)
00285                             {
00286                                 computeWeightedValue( prevSizeMechObj + i, ancestors[i], coefs2[i] );
00287                             }
00288                         }
00289                         break;
00290                     }
00291                 case core::componentmodel::topology::POINTSREMOVED:
00292                 {                   
00293                     const sofa::helper::vector<unsigned int> tab = ( static_cast< const PointsRemoved * >( *itBegin ) )->getArray();
00294 
00295                     unsigned int prevSizeMechObj   = getSize();
00296                     unsigned int lastIndexMech = prevSizeMechObj - 1;
00297                     for (unsigned int i = 0; i < tab.size(); ++i)
00298                     {                               
00299                         replaceValue(lastIndexMech, tab[i] ); 
00300 
00301                         --lastIndexMech;
00302                     }
00303                     resize( prevSizeMechObj - tab.size() );
00304                     break;
00305                 }
00306                 case core::componentmodel::topology::POINTSRENUMBERING:
00307                 {                               
00308                     const sofa::helper::vector<unsigned int> &tab = ( static_cast< const PointsRenumbering * >( *itBegin ) )->getIndexArray();
00309 
00310                     renumberValues( tab );
00311                     break;
00312                 }
00313                 default:
00314                     // Ignore events that are not Quad  related.
00315                     break;
00316                 };              
00317 
00318                 ++itBegin;
00319             }               
00320     }
00321 
00322     template <class DataTypes>
00323     void MechanicalObject<DataTypes>::replaceValue (const int inputIndex, const int outputIndex)
00324     {
00325         const unsigned int maxIndex = std::max(inputIndex, outputIndex);
00326 
00327         // standard state vectors
00328         // Note that the x,v,x0,f,dx,xfree,vfree and internalForces vectors (but
00329         // not v0, reset_position, and externalForces) are present in the
00330         // array of all vectors, so then don't need to be processed separatly.
00331         //(*x) [outputIndex] = (*x) [inputIndex];
00332         //if((*x0).size() > maxIndex)
00333         //    (*x0)[outputIndex] = (*x0)[inputIndex];
00334         //(*v) [outputIndex] = (*v) [inputIndex];
00335         if (v0 != NULL && (*v0).size() > maxIndex)
00336             (*v0)[outputIndex] = (*v0)[inputIndex];
00337         //if ((*f).size()>0)
00338         //    (*f) [outputIndex] = (*f) [inputIndex];
00339         //if ((*dx).size()>0)
00340         //    (*dx)[outputIndex] = (*dx)[inputIndex];
00341         // forces
00342         //if ((*internalForces).size()>0)
00343         //    (*internalForces)[outputIndex] = (*internalForces)[inputIndex];
00344         if ((*externalForces).size() > maxIndex)
00345             (*externalForces)[outputIndex] = (*externalForces)[inputIndex];
00346 
00347         // Note: the following assumes that topological changes won't be reset
00348         if (reset_position != NULL && (*reset_position).size() > maxIndex)
00349             (*reset_position)[outputIndex] = (*reset_position)[inputIndex];
00350 
00351         // temporary state vectors
00352         unsigned int i;
00353         for (i=0;i<vectorsCoord.size();i++)
00354         {
00355             if(vectorsCoord[i] != NULL)
00356             {
00357                 VecCoord& vector = *vectorsCoord[i];
00358                 if (vector.size() > maxIndex)
00359                     vector[outputIndex]=vector[inputIndex];
00360             }
00361         }
00362         for ( i=0;i<vectorsDeriv.size();i++)
00363         {
00364             if(vectorsDeriv[i] != NULL)
00365             {
00366                 VecDeriv& vector = *vectorsDeriv[i];
00367                 if (vector.size() > maxIndex)
00368                     vector[outputIndex]=vector[inputIndex];
00369             }
00370         }
00371 
00372     }
00373 
00374     template <class DataTypes>
00375     void MechanicalObject<DataTypes>::swapValues (const int idx1, const int idx2)
00376     {
00377         const unsigned int maxIndex = std::max(idx1, idx2);
00378 
00379         // standard state vectors
00380         // Note that the x,v,x0,f,dx,xfree,vfree and internalForces vectors (but
00381         // not v0, reset_position, and externalForces) are present in the
00382         // array of all vectors, so then don't need to be processed separatly.
00383         Coord tmp;
00384         Deriv tmp2;
00385         //tmp = (*x)[idx1];
00386         //(*x) [idx1] = (*x) [idx2];
00387         //(*x) [idx2] = tmp;
00388 
00389         //if((*x0).size() > maxIndex)
00390         //{
00391         //  tmp = (*x0)[idx1];
00392         //  (*x0)[idx1] = (*x0)[idx2];
00393         //  (*x0)[idx2] = tmp;
00394         //}
00395         //tmp2 = (*v)[idx1];
00396         //(*v) [idx1] = (*v) [idx2];
00397         //(*v) [idx2] = tmp2;
00398 
00399         if(v0 != NULL && (*v0).size() > maxIndex)
00400         {
00401             tmp2 = (*v0) [idx1];
00402             (*v0)[idx1] = (*v0)[idx2];
00403             (*v0)[idx2] = tmp2;
00404         }
00405         //tmp2 = (*f) [idx1];
00406         //(*f) [idx1] = (*f)[idx2];
00407         //(*f) [idx2] = tmp2;
00408 
00409         //tmp2 = (*dx) [idx1];
00410         //(*dx)[idx1] = (*dx)[idx2];
00411         //(*dx)[idx2] = tmp2;
00412 
00413         // forces
00414         //tmp2 = (*internalForces)[idx1];
00415         //(*internalForces)[idx1] = (*internalForces)[idx2];
00416         //(*internalForces)[idx2] = tmp2;
00417         if ((*externalForces).size() > maxIndex)
00418         {
00419             tmp2 = (*externalForces)[idx1];
00420             (*externalForces)[idx1] = (*externalForces)[idx2];
00421             (*externalForces)[idx2] = tmp2;
00422         }
00423 
00424         // Note: the following assumes that topological changes won't be reset
00425         if (reset_position != NULL && (*reset_position).size() > maxIndex)
00426         {
00427             tmp = (*reset_position)[idx1];
00428             (*reset_position)[idx1] = (*reset_position)[idx2];
00429             (*reset_position)[idx2] = tmp;
00430         }
00431 
00432         // temporary state vectors
00433         unsigned int i;
00434         for (i=0;i<vectorsCoord.size();i++)
00435         { 
00436             if(vectorsCoord[i] != NULL)
00437             {
00438                 VecCoord& vector = *vectorsCoord[i];
00439                 if(vector.size() > maxIndex)
00440                 {
00441                     tmp = vector[idx1];
00442                     vector[idx1] = vector[idx2];
00443                     vector[idx2] = tmp;
00444                 }
00445             }
00446         }
00447         for (i=0;i<vectorsDeriv.size();i++) 
00448         {
00449             if(vectorsDeriv[i] != NULL)
00450             {
00451                 VecDeriv& vector = *vectorsDeriv[i];
00452                 if(vector.size() > maxIndex)
00453                 {
00454                     tmp2 = vector[idx1];
00455                     vector[idx1] = vector[idx2];
00456                     vector[idx2] = tmp2;
00457                 }
00458             }
00459         }
00460     }
00461 
00462 template<class V>
00463 void renumber(V* v, V* tmp, const sofa::helper::vector< unsigned int > &index )
00464 {
00465     if (v==NULL) return;
00466     if (v->empty()) return;
00467     *tmp = *v;
00468     for (unsigned int i = 0; i < v->size(); ++i)
00469         (*v)[i] = (*tmp)[ index[i] ];
00470 }
00471 
00472     template <class DataTypes>
00473     void MechanicalObject<DataTypes>::renumberValues( const sofa::helper::vector< unsigned int > &index )
00474     {
00475         VecDeriv dtmp;
00476         VecCoord ctmp;
00477         // standard state vectors
00478         // Note that the x,v,x0,f,dx,xfree,vfree and internalForces vectors (but
00479         // not v0, reset_position, and externalForces) are present in the
00480         // array of all vectors, so then don't need to be processed separatly.
00481         //renumber(x, &ctmp, index);
00482         //renumber(x0, &ctmp, index);
00483         //renumber(v, &dtmp, index);
00484         renumber(v0, &dtmp, index);
00485         //renumber(f, &dtmp, index);
00486         //renumber(dx, &dtmp, index);
00487         //renumber(internalForces, &dtmp, index);
00488         renumber(externalForces, &dtmp, index);
00489         // Note: the following assumes that topological changes won't be reset
00490         renumber(reset_position, &ctmp, index);
00491         for (unsigned int i = 0; i < vectorsCoord.size(); ++i)
00492             renumber(vectorsCoord[i], &ctmp, index);
00493         for (unsigned int i = 0; i < vectorsDeriv.size(); ++i)
00494             renumber(vectorsDeriv[i], &dtmp, index);
00495     }
00496 
00497 
00498 
00499     template <class DataTypes>
00500     void MechanicalObject<DataTypes>::resize(const int size)
00501     {
00502         (*x).resize(size);
00503         if (initialized && x0!=NULL)
00504             (*x0).resize(size);
00505         (*v).resize(size);
00506         if (v0!=NULL)
00507             (*v0).resize(size);
00508         (*f).resize(size);
00509         (*dx).resize(size);
00510         (*xfree).resize(size);
00511         (*vfree).resize(size);
00512         if (externalForces->size()>0)
00513             externalForces->resize(size);
00514         internalForces->resize(size);
00515         // Note: the following assumes that topological changes won't be reset
00516         if (reset_position!=NULL)
00517             (*reset_position).resize(size);
00518     
00519         //if (size!=vsize)
00520         {
00521             vsize=size;
00522             for (unsigned int i=0;i<vectorsCoord.size();i++)
00523                 if (vectorsCoord[i]!=NULL && vectorsCoord[i]->size()!=0)
00524                 vectorsCoord[i]->resize(size);
00525             for (unsigned int i=0;i<vectorsDeriv.size();i++)
00526                 if (vectorsDeriv[i]!=NULL && vectorsDeriv[i]->size()!=0)
00527                 vectorsDeriv[i]->resize(size);
00528         }
00529     }
00530 
00531 
00532 
00533     template <class DataTypes>
00534     void MechanicalObject<DataTypes>::applyTranslation (const double dx,const double dy,const double dz)
00535     {      
00536       VecCoord& x = *this->getX();
00537       for (unsigned int i=0;i<x.size();i++)
00538     {
00539       DataTypes::add
00540             (x[i],dx,dy,dz);
00541     }
00542                
00543     }
00544 
00545     //Apply Rotation from Euler angles (in degree!)
00546     template <class DataTypes>
00547         void MechanicalObject<DataTypes>::applyRotation (const double rx, const double ry, const double rz)
00548     {          
00549         Quaternion q=helper::Quater<SReal>::createQuaterFromEuler( Vec<3,SReal>(rx,ry,rz)*M_PI/180.0);
00550         applyRotation(q);
00551     }
00552     
00553     template <class DataTypes>
00554     void MechanicalObject<DataTypes>::applyRotation (const defaulttype::Quat q)
00555     {            
00556       VecCoord& x = *this->getX();
00557       for (unsigned int i = 0; i < x.size(); i++)
00558       {
00559     Vec<3,Real> pos;
00560     DataTypes::get(pos[0],pos[1],pos[2],x[i]);
00561     Vec<3,Real> newposition = q.rotate(pos);
00562     DataTypes::set(x[i],newposition[0],newposition[1],newposition[2]);
00563       }           
00564     }
00565 
00566 #ifndef SOFA_FLOAT
00567     template<>
00568     void MechanicalObject<defaulttype::Rigid3dTypes>::applyRotation (const defaulttype::Quat q);
00569     template <>
00570     bool MechanicalObject<Vec1dTypes>::addBBox(double* minBBox, double* maxBBox);
00571 #endif
00572 #ifndef SOFA_Real
00573     template<>
00574     void MechanicalObject<defaulttype::Rigid3fTypes>::applyRotation (const defaulttype::Quat q);
00575     template <>
00576     bool MechanicalObject<Vec1fTypes>::addBBox(double* minBBox, double* maxBBox);
00577 #endif
00578     
00579     template <class DataTypes>
00580     void MechanicalObject<DataTypes>::applyScale(const double s)
00581     {
00582       std::cout << "MechanicalObject : applyScale " << this->getName() << " s=" << s << "\n";
00583       VecCoord& x = *this->getX();
00584       for (unsigned int i=0;i<x.size();i++)
00585     {
00586       x[i] *= (Real)s;
00587     }
00588     }
00589 
00590     template <class DataTypes>
00591     void MechanicalObject<DataTypes>::getIndicesInSpace(sofa::helper::vector<unsigned>& indices, Real xmin, Real xmax, Real ymin, Real ymax, Real zmin, Real zmax) const
00592     {
00593       const VecCoord& X = *getX();
00594       for( unsigned i=0; i<X.size(); ++i )
00595     {
00596       Real x=0.0,y=0.0,z=0.0;
00597       DataTypes::get(x,y,z,X[i]);
00598       if( x >= xmin && x <= xmax && y >= ymin && y <= ymax && z >= zmin && z <= zmax ){
00599             indices.push_back(i);
00600       }
00601     }
00602     }
00603 
00604     /*
00605     template <class DataTypes>
00606     void MechanicalObject<DataTypes>::computeWeightedValue( const unsigned int i, const sofa::helper::vector< unsigned int >& ancestors, const sofa::helper::vector< double >& coefs)
00607     {
00608         // HD interpolate position, speed,force,...
00609         // assume all coef sum to 1.0
00610         unsigned int j;
00611         
00612         // Note that the x,v,x0,f,dx,xfree,vfree and internalForces vectors (but
00613         // not v0, reset_position, and externalForces) are present in the
00614         // array of all vectors, so then don't need to be processed separatly.
00615         if (v0 != NULL)
00616         {
00617             (*v0)[i] = Deriv();
00618             for (j = 0; j < ancestors.size(); ++j)
00619             {
00620                 (*v0)[i] += (*v0)[ancestors[j]] * (Real)coefs[j];
00621             }
00622         }
00623 
00624         // Note: the following assumes that topological changes won't be reset
00625         if (reset_position != NULL)
00626         {
00627             (*reset_position)[i] = Coord();
00628             for (j = 0; j < ancestors.size(); ++j)
00629             {
00630                 (*reset_position)[i] += (*reset_position)[ancestors[j]] * (Real)coefs[j];
00631             }
00632         }
00633 
00634         if (externalForces->size() > 0)
00635         {
00636             (*externalForces)[i] = Deriv();
00637             for (j = 0; j < ancestors.size(); ++j)
00638             {
00639                 (*externalForces)[i] += (*externalForces)[ancestors[j]] * (Real)coefs[j];
00640             }
00641         }
00642         
00643 
00644         for (unsigned int k = 0; k < vectorsCoord.size(); k++) 
00645         {
00646             if (vectorsCoord[k]!=NULL && vectorsCoord[k]->size()!=0) 
00647             {
00648                 (*vectorsCoord[k])[i] = Coord();
00649                 for (j = 0; j < ancestors.size(); ++j) 
00650                 {
00651                     (*vectorsCoord[k])[i] += (*vectorsCoord[k])[ancestors[j]] * (Real)coefs[j];
00652                 }
00653             }
00654         }
00655 
00656         for (unsigned int k = 0; k < vectorsDeriv.size(); k++)
00657         {
00658             if (vectorsDeriv[k]!=NULL && vectorsDeriv[k]->size()!=0)
00659             {
00660                 (*vectorsDeriv[k])[i] = Deriv();
00661                 for (j = 0; j < ancestors.size(); ++j)
00662                 {
00663                     (*vectorsDeriv[k])[i] += (*vectorsDeriv[k])[ancestors[j]] * (Real)coefs[j];
00664                 }
00665             }
00666         }
00667     }
00668     */
00669 
00670     
00671     template <class DataTypes>
00672     void MechanicalObject<DataTypes>::computeWeightedValue( const unsigned int i, const sofa::helper::vector< unsigned int >& ancestors, const sofa::helper::vector< double >& coefs)
00673     {
00674         // HD interpolate position, speed,force,...
00675         // assume all coef sum to 1.0
00676         unsigned int j;
00677         
00678         // Note that the x,v,x0,f,dx,xfree,vfree and internalForces vectors (but
00679         // not v0, reset_position, and externalForces) are present in the
00680         // array of all vectors, so then don't need to be processed separatly.
00681         if (v0 != NULL)
00682         {   
00683             helper::vector< Deriv > ancestorsDeriv(ancestors.size());
00684             helper::vector< Real > ancestorsCoefs(ancestors.size());
00685 
00686             for (j = 0; j < ancestors.size(); ++j)
00687             {
00688                 ancestorsDeriv[j] = (*v0)[ancestors[j]];
00689                 ancestorsCoefs[j] = coefs[j];
00690             }
00691 
00692             (*v0)[i] = DataTypes::interpolate(ancestorsDeriv, ancestorsCoefs);
00693         }
00694 
00695         // Note: the following assumes that topological changes won't be reset
00696         if (reset_position != NULL)
00697         {   
00698             helper::vector< Coord > ancestorsCoord(ancestors.size());
00699             helper::vector< Real > ancestorsCoefs(ancestors.size());
00700 
00701             for (j = 0; j < ancestors.size(); ++j)
00702             {
00703                 ancestorsCoord[j] = (*reset_position)[ancestors[j]];
00704                 ancestorsCoefs[j] = coefs[j];
00705             }
00706 
00707             (*reset_position)[i] = DataTypes::interpolate(ancestorsCoord, ancestorsCoefs);
00708         }
00709 
00710         if (externalForces->size() > 0)
00711         {
00712             helper::vector< Deriv > ancestorsDeriv(ancestors.size());
00713             helper::vector< Real > ancestorsCoefs(ancestors.size());
00714 
00715             for (j = 0; j < ancestors.size(); ++j)
00716             {
00717                 ancestorsDeriv[j] = (*externalForces)[ancestors[j]];
00718                 ancestorsCoefs[j] = coefs[j];
00719             }
00720 
00721             (*externalForces)[i] = DataTypes::interpolate(ancestorsDeriv, ancestorsCoefs);
00722         }
00723         
00724 
00725         for (unsigned int k = 0; k < vectorsCoord.size(); k++) 
00726         {
00727             if ((vectorsCoord[k] != NULL) && (vectorsCoord[k]->size() != 0)) 
00728             {
00729                 helper::vector< Coord > ancestorsCoord(ancestors.size());
00730                 helper::vector< Real > ancestorsCoefs(ancestors.size());
00731 
00732                 for (j = 0; j < ancestors.size(); ++j) 
00733                 {
00734                     ancestorsCoord[j] = (*vectorsCoord[k])[ancestors[j]];
00735                     ancestorsCoefs[j] = coefs[j];
00736                 }
00737 
00738                 (*vectorsCoord[k])[i] = DataTypes::interpolate(ancestorsCoord, ancestorsCoefs);
00739             }
00740         }
00741 
00742         for (unsigned int k = 0; k < vectorsDeriv.size(); k++)
00743         {
00744             if ((vectorsDeriv[k] != NULL) && (vectorsDeriv[k]->size() != 0))
00745             {
00746                 helper::vector< Deriv > ancestorsDeriv(ancestors.size());
00747                 helper::vector< Real > ancestorsCoefs(ancestors.size());
00748 
00749                 for (j = 0; j < ancestors.size(); ++j) 
00750                 {
00751                     ancestorsDeriv[j] = (*vectorsDeriv[k])[ancestors[j]];
00752                     ancestorsCoefs[j] = coefs[j];
00753                 }
00754 
00755                 (*vectorsDeriv[k])[i] = DataTypes::interpolate(ancestorsDeriv, ancestorsCoefs);
00756             }
00757         }
00758     }
00759     
00760 
00761     template <class DataTypes>
00762     void MechanicalObject<DataTypes>::computeNewPoint( const unsigned int i, const sofa::helper::vector< double >& m_x) 
00763     {   
00764           this->resize(i+1);          
00765 
00766           Vec<3,Real> pos(m_x[0], m_x[1], m_x[2]);
00767           Vec<3,Real> restpos(pos);
00768           
00769           Quaternion q=helper::Quater<SReal>::createQuaterFromEuler( Vec<3,SReal>(rotation.getValue()[0],rotation.getValue()[1],rotation.getValue()[2]));
00770           pos = q.rotate(pos*scale.getValue());
00771           pos += translation.getValue();
00772                  
00773           restpos = q.rotate(restpos*restScale.getValue());
00774           restpos += translation.getValue();
00775           
00776           DataTypes::set((*getX())[i], pos[0], pos[1], pos[2]);
00777           DataTypes::set((*getXfree())[i], pos[0], pos[1], pos[2]);   
00778           DataTypes::set((*getX0())[i], restpos[0],restpos[1],restpos[2]);
00779           
00780           if (reset_position != NULL)
00781             DataTypes::set((*reset_position)[i], pos[0], pos[1], pos[2]);
00782     }
00783 
00784     // Force the position of a point (and force its velocity to zero value)
00785     template <class DataTypes>
00786     void MechanicalObject<DataTypes>::forcePointPosition( const unsigned int i, const sofa::helper::vector< double >& m_x) 
00787     {
00788           DataTypes::set((*getX())[i], m_x[0], m_x[1], m_x[2]);
00789           DataTypes::set((*getV())[i], (Real) 0.0, (Real) 0.0, (Real) 0.0);
00790     }
00791 
00792     template <class DataTypes>
00793     void MechanicalObject<DataTypes>::contributeToMatrixDimension(unsigned int * const nbRow, unsigned int * const nbCol)
00794     {
00795       if (v->size() != 0)
00796     {
00797       (*nbRow) += v->size() * DataTypeInfo<Deriv>::size();
00798       (*nbCol) = *nbRow;
00799     }
00800     }  
00801 
00802 
00803     template <class DataTypes>
00804     void MechanicalObject<DataTypes>::setOffset(unsigned int &offset)
00805     {
00806       if (v->size() != 0)
00807     {
00808       offset += v->size() * DataTypeInfo<Deriv>::size();
00809     }
00810     }
00811 
00812 
00813 template <class DataTypes>
00814 void MechanicalObject<DataTypes>::loadInBaseVector(defaulttype::BaseVector * dest, VecId src, unsigned int &offset)
00815 {
00816     if (src.type == VecId::V_COORD)
00817     {
00818         const VecCoord* vSrc = getVecCoord(src.index);
00819         const unsigned int coordDim = DataTypeInfo<Coord>::size();
00820 
00821         for (unsigned int i=0; i<vSrc->size(); i++)
00822             for (unsigned int j=0; j<coordDim; j++)
00823             {
00824                 Real tmp;
00825                 DataTypeInfo<Coord>::getValue((*vSrc)[i],j,tmp);
00826                 dest->set(offset + i * coordDim + j, tmp);
00827             }
00828         offset += vSrc->size() * coordDim;
00829     }
00830     else
00831     {
00832         const VecDeriv* vSrc = getVecDeriv(src.index);
00833         const unsigned int derivDim = DataTypeInfo<Deriv>::size();
00834 
00835         for (unsigned int i=0; i<vSrc->size(); i++)
00836             for (unsigned int j=0; j<derivDim; j++)
00837             {
00838                 Real tmp;
00839                 DataTypeInfo<Deriv>::getValue((*vSrc)[i],j,tmp);
00840                 dest->set(offset + i * derivDim + j, tmp);
00841             }
00842         offset += vSrc->size() * derivDim;
00843     }
00844 }
00845 
00846     template <class DataTypes>
00847     void MechanicalObject<DataTypes>::addBaseVectorToState(VecId dest, defaulttype::BaseVector *src, unsigned int &offset)
00848     {
00849       if (dest.type == VecId::V_COORD)
00850     {
00851       VecCoord* vDest = getVecCoord(dest.index);
00852       const unsigned int coordDim = DataTypeInfo<Coord>::size();
00853 
00854       for (unsigned int i=0; i<vDest->size(); i++)
00855         {
00856           for (unsigned int j=0; j<coordDim; j++)
00857         {
00858           Real tmp;
00859           DataTypeInfo<Coord>::getValue((*vDest)[i],j,tmp);
00860           DataTypeInfo<Coord>::setValue((*vDest)[i], j, tmp + src->element(offset + i * coordDim + j));
00861         }
00862         }
00863 
00864       offset += vDest->size() * coordDim;
00865     }
00866       else
00867     {
00868       VecDeriv* vDest = getVecDeriv(dest.index);
00869       const unsigned int derivDim = DataTypeInfo<Deriv>::size();
00870 
00871       for (unsigned int i=0; i<vDest->size(); i++)
00872         for (unsigned int j=0; j<derivDim; j++)
00873           {
00874         Real tmp;
00875         DataTypeInfo<Deriv>::getValue((*vDest)[i],j,tmp);
00876         DataTypeInfo<Deriv>::setValue((*vDest)[i], j, tmp + src->element(offset + i * derivDim + j));
00877           }
00878 
00879       offset += vDest->size() * derivDim;
00880     }
00881     }
00882 
00883     template <class DataTypes>
00884     void MechanicalObject<DataTypes>::addDxToCollisionModel()
00885     {      
00886       for (unsigned int i=0; i < this->xfree->size(); i++)
00887         (*this->x)[i] = (*this->xfree)[i] + (*this->dx)[i];
00888     }
00889 
00890 
00891     template <class DataTypes>
00892     void MechanicalObject<DataTypes>::init()
00893     {      
00894       _topology = this->getContext()->getMeshTopology();
00895 
00896       f_X->beginEdit();
00897       f_V->beginEdit();
00898       f_F->beginEdit();
00899       f_Dx->beginEdit();
00900       f_Xfree->beginEdit();
00901       f_Vfree->beginEdit();
00902       f_X0->beginEdit();
00903 
00904       if (getX()->size() != (std::size_t)vsize || getV()->size() != (std::size_t)vsize)
00905     { // X and/or V where user-specified
00906       resize(getX()->size()>getV()->size()?getX()->size():getV()->size());
00907     }
00908       else if (getX()->size() <= 1)
00909     {
00910         sofa::component::MeshLoader* m_loader;
00911         this->getContext()->get(m_loader);
00912                 
00913         if(m_loader){           
00914 
00915             int nbp = m_loader->getNbPoints();
00916 
00917               //std::cout<<"Setting "<<nbp<<" points from MeshLoader. " <<std::endl;            
00918               
00919               this->resize(nbp);
00920               for (int i=0;i<nbp;i++) 
00921               {               
00922                 (*getX())[i] = Coord();
00923                 DataTypes::set((*getX())[i], m_loader->getPX(i), m_loader->getPY(i), m_loader->getPZ(i));               
00924               }
00925 
00926         }else{
00927                 
00928            if (_topology!=NULL && _topology->hasPos() && _topology->getContext() == this->getContext())      
00929              {   
00930                int nbp = _topology->getNbPoints();   
00931                //std::cout<<"Setting "<<nbp<<" points from topology. " << this->getName() << " topo : " << _topology->getName() <<std::endl;     
00932                this->resize(nbp);    
00933                for (int i=0;i<nbp;i++)   
00934                {     
00935                  (*getX())[i] = Coord();     
00936                  DataTypes::set((*getX())[i], _topology->getPX(i), _topology->getPY(i), _topology->getPZ(i));    
00937                }     
00938      
00939              }
00940         }
00941     }
00942     
00943     reinit();
00944     
00945       if (v0 == NULL) this->v0 = new VecDeriv;
00946       *this->v0 = *v;
00947       // free position = position
00948       *this->xfree = *x;
00949 
00950       //Rest position
00951 
00952       if (x0->size() == 0)
00953       { 
00954       *x0 = *x;
00955       if (restScale.getValue() != (Real)1)
00956       {
00957           Real s = (Real)restScale.getValue();
00958           for (unsigned int i=0; i<x0->size(); i++)
00959           (*x0)[i] *= s;
00960       }
00961       }
00962 
00963       initialized = true;    
00964 
00965     }
00966 
00967     
00968     
00969     template <class DataTypes>
00970     void MechanicalObject<DataTypes>::reinit()
00971     {
00972       Vector3 p0;
00973       sofa::component::topology::RegularGridTopology *grid; this->getContext()->get(grid, BaseContext::Local);
00974       if (grid) p0 = grid->getP0();
00975       
00976       if (scale.getValue() != (SReal)1.0)
00977       {
00978     this->applyScale(scale.getValue());   
00979     p0 *= scale.getValue();   
00980       }
00981       
00982       if (rotation.getValue()[0]!=0.0 || rotation.getValue()[1]!=0.0 || rotation.getValue()[2]!=0.0)
00983       {
00984         this->applyRotation(rotation.getValue()[0],rotation.getValue()[1],rotation.getValue()[2]);  
00985 //      p0 = q.rotate(p0);  
00986       }
00987                 
00988       if (translation.getValue()[0]!=0.0 || translation.getValue()[1]!=0.0 || translation.getValue()[2]!=0.0)
00989       {
00990     this->applyTranslation( translation.getValue()[0],translation.getValue()[1],translation.getValue()[2]);
00991     p0 += translation.getValue();
00992       }
00993      
00994       
00995       if (grid) grid->setP0(p0);
00996                     
00997       translation.setValue(Vector3());
00998       rotation.setValue(Vector3());
00999       scale.setValue((SReal)1.0);
01000     }
01001     template <class DataTypes>
01002     void MechanicalObject<DataTypes>::storeResetState()
01003     {
01004       // Save initial state for reset button
01005       if (reset_position == NULL) this->reset_position = new VecCoord;
01006       *this->reset_position = *x;
01007     }
01008 
01009     //
01010     // Integration related methods
01011     //
01012 
01013     template <class DataTypes>
01014     void MechanicalObject<DataTypes>::reset()
01015     {
01016       if (reset_position == NULL)        return;
01017       // Back to initial state
01018       this->resize(reset_position->size());
01019       //std::cout << this->getName() << ": reset X"<<std::endl;
01020       //*this->x = *reset_position;
01021       *this->getVecCoord(VecId::position().index) = *this->reset_position;
01022       //std::cout << this->getName() << ": reset V"<<std::endl;
01023       //*this->v = *v0;
01024       
01025       if (v0 == NULL)   return;
01026       *this->getVecDeriv(VecId::velocity().index) = *this->v0;
01027 
01028       //std::cout << this->getName() << ": reset Xfree"<<std::endl;
01029       //*this->xfree = *x;
01030       *this->getVecCoord(VecId::freePosition().index) = *this->getVecCoord(VecId::position().index);
01031       //std::cout << this->getName() << ": reset Vfree"<<std::endl;
01032       //*this->vfree = *v;
01033       *this->getVecDeriv(VecId::freeVelocity().index) = *this->getVecDeriv(VecId::velocity().index);
01034     }
01035 
01036     template <class DataTypes>
01037     void MechanicalObject<DataTypes>::writeX(std::ostream &out)
01038     {
01039         out << *getX();
01040     }
01041     template <class DataTypes>
01042         void MechanicalObject<DataTypes>::readX(std::istream &in)
01043     {                 
01044                 //in >> *getX(); //Modified to handle a modification of the number of Dofs. Problem to resolve: how to modify the containers to handle this...
01045                  Coord pos;
01046                  int i=0;              
01047                  while (in >> pos)
01048                  {
01049                     if (i>= getSize()) resize(i+1);
01050                     (*x)[i++]=pos;                                  
01051                  }              
01052                  if (i<getSize()) resize(i);
01053     }
01054     
01055     template <class DataTypes>
01056     double MechanicalObject<DataTypes>::compareX(std::istream &in)
01057     {
01058       std::string ref,cur;
01059       getline(in, ref);
01060       
01061       std::ostringstream out;
01062       out << *getX();
01063       cur = out.str();
01064          
01065       double error=0;
01066       std::istringstream compareX_ref(ref);
01067       std::istringstream compareX_cur(cur);
01068       
01069       Real value_ref, value_cur;
01070       unsigned int count=0;
01071       while (compareX_ref >> value_ref && compareX_cur >> value_cur )
01072       {
01073     error += fabs(value_ref-value_cur); 
01074     count ++;
01075       }
01076       return error/count;
01077     }
01078     
01079     template <class DataTypes>
01080     void MechanicalObject<DataTypes>::writeV(std::ostream &out)
01081     {
01082         out << *getV();
01083     }
01084     template <class DataTypes>
01085         void MechanicalObject<DataTypes>::readV(std::istream &in)
01086     {
01087           //in >> *getV();       
01088           Deriv pos;
01089           int i=0;              
01090           while (in >> pos)
01091           {
01092             if (i>= getSize()) resize(i+1);
01093             (*v)[i++]=pos;                                  
01094           }              
01095           if (i<getSize()) resize(i);           
01096         
01097     }
01098 
01099     template <class DataTypes>
01100     double MechanicalObject<DataTypes>::compareV(std::istream &in)
01101     {
01102       std::string ref,cur;
01103       getline(in, ref);
01104       
01105       std::ostringstream out;
01106       out << *getV();
01107       cur = out.str();
01108          
01109       double error=0;
01110       std::istringstream compareV_ref(ref);
01111       std::istringstream compareV_cur(cur);
01112       
01113       Real value_ref, value_cur;
01114       unsigned int count=0;
01115       while (compareV_ref >> value_ref && compareV_cur >> value_cur )
01116       {
01117        error += fabs(value_ref-value_cur); 
01118        count ++;
01119       }
01120       return error/count;
01121     }
01122     
01123     template <class DataTypes>
01124     void MechanicalObject<DataTypes>::writeState( std::ostream& out )
01125     {
01126     writeX(out); out << " "; writeV(out);     
01127     }
01128 
01129     template <class DataTypes>
01130     void MechanicalObject<DataTypes>::beginIntegration(Real /*dt*/)
01131     {
01132       this->f = this->internalForces;
01133     }
01134 
01135     template <class DataTypes>
01136     void MechanicalObject<DataTypes>::endIntegration(Real /*dt*/)
01137     {
01138       this->f = this->externalForces;
01139       this->externalForces->clear();
01140     }
01141 
01142     template <class DataTypes>
01143     void MechanicalObject<DataTypes>::accumulateForce()
01144     {
01145       if (!this->externalForces->empty())
01146     {
01147       for (unsigned int i=0; i < this->externalForces->size(); i++)
01148             (*this->f)[i] += (*this->externalForces)[i];
01149     }
01150     }
01151 
01152     template <class DataTypes>
01153     void MechanicalObject<DataTypes>::setVecCoord(unsigned int index, VecCoord* v)
01154     {
01155       if (index>=vectorsCoord.size())
01156         vectorsCoord.resize(index+1);
01157       vectorsCoord[index] = v;
01158     }
01159 
01160     template <class DataTypes>
01161     void MechanicalObject<DataTypes>::setVecDeriv(unsigned int index, VecDeriv* v)
01162     {
01163       if (index>=vectorsDeriv.size())
01164         vectorsDeriv.resize(index+1);
01165       vectorsDeriv[index] = v;
01166     }
01167 
01168     template <class DataTypes>
01169     void MechanicalObject<DataTypes>::setVecConst(unsigned int index, VecConst* v)
01170     {
01171       if (index>=vectorsConst.size())
01172         vectorsConst.resize(index+1);
01173       vectorsConst[index] = v;
01174     }
01175 
01176 
01177     template<class DataTypes>
01178     typename MechanicalObject<DataTypes>::VecCoord* MechanicalObject<DataTypes>::getVecCoord(unsigned int index)
01179     {
01180       if (index>=vectorsCoord.size())
01181         vectorsCoord.resize(index+1);
01182       if (vectorsCoord[index]==NULL)
01183         vectorsCoord[index] = new VecCoord;
01184       return vectorsCoord[index];
01185     }
01186 
01187     template<class DataTypes>
01188     const typename MechanicalObject<DataTypes>::VecCoord* MechanicalObject<DataTypes>::getVecCoord(unsigned int index) const
01189     {
01190       if (index>=vectorsCoord.size())
01191         return NULL;
01192       if (vectorsCoord[index]==NULL)
01193         return NULL;
01194       return vectorsCoord[index];
01195     }
01196 
01197     template<class DataTypes>
01198     typename MechanicalObject<DataTypes>::VecDeriv* MechanicalObject<DataTypes>::getVecDeriv(unsigned int index)
01199     {
01200       if (index>=vectorsDeriv.size())
01201         vectorsDeriv.resize(index+1);
01202       if (vectorsDeriv[index]==NULL)
01203         vectorsDeriv[index] = new VecDeriv;
01204     
01205       return vectorsDeriv[index];
01206     }
01207 
01208     template<class DataTypes>
01209     const typename MechanicalObject<DataTypes>::VecDeriv* MechanicalObject<DataTypes>::getVecDeriv(unsigned int index) const
01210     {
01211       if (index>=vectorsDeriv.size())
01212         return NULL;
01213       if (vectorsDeriv[index]==NULL)
01214         return NULL;
01215     
01216       return vectorsDeriv[index];
01217     }
01218 
01219     template<class DataTypes>
01220     typename MechanicalObject<DataTypes>::VecConst* MechanicalObject<DataTypes>::getVecConst(unsigned int index)
01221     {
01222       if (index>=vectorsConst.size())
01223         vectorsConst.resize(index+1);
01224       if (vectorsConst[index]==NULL)
01225         vectorsConst[index] = new VecConst;
01226     
01227       return vectorsConst[index];
01228     }
01229 
01230     template<class DataTypes>
01231     const typename MechanicalObject<DataTypes>::VecConst* MechanicalObject<DataTypes>::getVecConst(unsigned int index) const
01232     {
01233       if (index>=vectorsConst.size())
01234         return NULL;
01235       if (vectorsConst[index]==NULL)
01236         return NULL;
01237     
01238       return vectorsConst[index];
01239     }
01240 
01241 template <class DataTypes>
01242 void MechanicalObject<DataTypes>::vAvail(VecId& v)
01243 {
01244     if (v.type == VecId::V_COORD)
01245     {
01246         for (unsigned int i=v.index; i < vectorsCoord.size(); ++i)
01247             if (vectorsCoord[i] && ! vectorsCoord[i]->empty())
01248                 v.index = i+1;
01249     }
01250     else if (v.type == VecId::V_DERIV)
01251     {
01252         for (unsigned int i=v.index; i < vectorsDeriv.size(); ++i)
01253             if (vectorsDeriv[i] != NULL && ! (*vectorsDeriv[i]).empty())
01254                 v.index = i+1;
01255     }
01256 }
01257 
01258     template <class DataTypes>
01259     void MechanicalObject<DataTypes>::vAlloc(VecId v)
01260     {
01261       if (v.type == VecId::V_COORD && v.index >= VecId::V_FIRST_DYNAMIC_INDEX)
01262     {
01263       VecCoord* vec = getVecCoord(v.index);
01264       vec->resize(vsize);
01265     }
01266       else if (v.type == VecId::V_DERIV && v.index >= VecId::V_FIRST_DYNAMIC_INDEX)
01267     {
01268       VecDeriv* vec = getVecDeriv(v.index);
01269       vec->resize(vsize);
01270     }
01271       else
01272     {
01273       std::cerr << "Invalid alloc operation ("<<v<<")\n";
01274       return;
01275     }
01276       //vOp(v); // clear vector
01277     }
01278 
01279     template <class DataTypes>
01280     void MechanicalObject<DataTypes>::vFree(VecId v)
01281     {
01282       if (v.type == VecId::V_COORD && v.index >= VecId::V_FIRST_DYNAMIC_INDEX)
01283     {
01284       VecCoord* vec = getVecCoord(v.index);
01285       vec->resize(0);
01286     }
01287       else if (v.type == VecId::V_DERIV && v.index >= VecId::V_FIRST_DYNAMIC_INDEX)
01288     {
01289       VecDeriv* vec = getVecDeriv(v.index);
01290       vec->resize(0);
01291     }
01292       else
01293     {
01294       std::cerr << "Invalid free operation ("<<v<<")\n";
01295       return;
01296     }
01297     }
01298 
01299     template <class DataTypes>
01300     void MechanicalObject<DataTypes>::vOp(VecId v, VecId a, VecId b, double f)
01301     {
01302       if(v.isNull())
01303     {
01304       // ERROR
01305       std::cerr << "Invalid vOp operation ("<<v<<','<<a<<','<<b<<','<<f<<")\n";
01306       return;
01307     }
01308       if (a.isNull())
01309     {
01310       if (b.isNull())
01311         {
01312           // v = 0
01313           if (v.type == VecId::V_COORD)
01314         {
01315           VecCoord* vv = getVecCoord(v.index);
01316           vv->resize(this->vsize);
01317           for (unsigned int i=0; i<vv->size(); i++)
01318                     (*vv)[i] = Coord();
01319         }
01320           else
01321         {
01322           VecDeriv* vv = getVecDeriv(v.index);
01323           vv->resize(this->vsize);
01324           for (unsigned int i=0; i<vv->size(); i++)
01325                     (*vv)[i] = Deriv();
01326         }
01327         }
01328       else
01329         {
01330           if (b.type != v.type)
01331         {
01332           // ERROR
01333           std::cerr << "Invalid vOp operation ("<<v<<','<<a<<','<<b<<','<<f<<")\n";
01334           return;
01335         }
01336           if (v == b)
01337         {
01338           // v *= f
01339           if (v.type == VecId::V_COORD)
01340             {
01341               VecCoord* vv = getVecCoord(v.index);
01342               for (unsigned int i=0; i<vv->size(); i++)
01343                         (*vv)[i] *= (Real)f;
01344             }
01345           else
01346             {
01347               VecDeriv* vv = getVecDeriv(v.index);
01348               for (unsigned int i=0; i<vv->size(); i++)
01349                         (*vv)[i] *= (Real)f;
01350             }
01351         }
01352           else
01353         {
01354           // v = b*f
01355           if (v.type == VecId::V_COORD)
01356             {
01357               VecCoord* vv = getVecCoord(v.index);
01358               VecCoord* vb = getVecCoord(b.index);
01359               vv->resize(vb->size());
01360               for (unsigned int i=0; i<vv->size(); i++)
01361                         (*vv)[i] = (*vb)[i] * (Real)f;
01362             }
01363           else
01364             {
01365               VecDeriv* vv = getVecDeriv(v.index);
01366               VecDeriv* vb = getVecDeriv(b.index);
01367               vv->resize(vb->size());
01368               for (unsigned int i=0; i<vv->size(); i++)
01369                         (*vv)[i] = (*vb)[i] * (Real)f;
01370             }
01371         }
01372         }
01373     }
01374       else
01375     {
01376       if (a.type != v.type)
01377         {
01378           // ERROR
01379           std::cerr << "Invalid vOp operation ("<<v<<','<<a<<','<<b<<','<<f<<")\n";
01380           return;
01381         }
01382       if (b.isNull())
01383         {
01384           // v = a
01385           if (v.type == VecId::V_COORD)
01386         {
01387           VecCoord* vv = getVecCoord(v.index);
01388           VecCoord* va = getVecCoord(a.index);
01389           vv->resize(va->size());
01390           for (unsigned int i=0; i<vv->size(); i++)
01391                     (*vv)[i] = (*va)[i];
01392         }
01393           else
01394         {
01395           VecDeriv* vv = getVecDeriv(v.index);
01396           VecDeriv* va = getVecDeriv(a.index);
01397           vv->resize(va->size());
01398           for (unsigned int i=0; i<vv->size(); i++)
01399                     (*vv)[i] = (*va)[i];
01400         }
01401         }
01402       else
01403         {
01404           if (v == a)
01405         {
01406           if (f==1.0)
01407             {
01408               // v += b
01409               if (v.type == VecId::V_COORD)
01410             {
01411               VecCoord* vv = getVecCoord(v.index);
01412               if (b.type == VecId::V_COORD)
01413                 {
01414                   VecCoord* vb = getVecCoord(b.index);
01415                   vv->resize(vb->size());
01416                   for (unsigned int i=0; i<vv->size(); i++)
01417                                 (*vv)[i] += (*vb)[i];
01418                 }
01419               else
01420                 {
01421                   VecDeriv* vb = getVecDeriv(b.index);
01422                   vv->resize(vb->size());
01423                   for (unsigned int i=0; i<vv->size(); i++)
01424                                 (*vv)[i] += (*vb)[i];
01425                 }
01426             }
01427               else if (b.type == VecId::V_DERIV)
01428             {
01429               VecDeriv* vv = getVecDeriv(v.index);
01430               VecDeriv* vb = getVecDeriv(b.index);
01431               vv->resize(vb->size());
01432               for (unsigned int i=0; i<vv->size(); i++)
01433                             (*vv)[i] += (*vb)[i];
01434             }
01435               else
01436             {
01437               // ERROR
01438               std::cerr << "Invalid vOp operation ("<<v<<','<<a<<','<<b<<','<<f<<")\n";
01439               return;
01440             }
01441             }
01442           else
01443             {
01444               // v += b*f
01445               if (v.type == VecId::V_COORD)
01446             {
01447               VecCoord* vv = getVecCoord(v.index);
01448               if (b.type == VecId::V_COORD)
01449                 {
01450                   VecCoord* vb = getVecCoord(b.index);
01451                   vv->resize(vb->size());
01452                   for (unsigned int i=0; i<vv->size(); i++)
01453                                 (*vv)[i] += (*vb)[i]*(Real)f;
01454                 }
01455               else
01456                 {
01457                   VecDeriv* vb = getVecDeriv(b.index);
01458                   vv->resize(vb->size());
01459                   for (unsigned int i=0; i<vv->size(); i++)
01460                                 (*vv)[i] += (*vb)[i]*(Real)f;
01461                 }
01462             }
01463               else if (b.type == VecId::V_DERIV)
01464             {
01465               VecDeriv* vv = getVecDeriv(v.index);
01466               VecDeriv* vb = getVecDeriv(b.index);
01467               vv->resize(vb->size());
01468               for (unsigned int i=0; i<vv->size(); i++)
01469                             (*vv)[i] += (*vb)[i]*(Real)f;
01470             }
01471               else
01472             {
01473               // ERROR
01474               std::cerr << "Invalid vOp operation ("<<v<<','<<a<<','<<b<<','<<f<<")\n";
01475               return;
01476             }
01477             }
01478         }
01479           else if (v == b)
01480         {
01481           if (f==1.0)
01482             {
01483               // v += a
01484               if (v.type == VecId::V_COORD)
01485             {
01486               VecCoord* vv = getVecCoord(v.index);
01487               if (a.type == VecId::V_COORD)
01488                 {
01489                   VecCoord* va = getVecCoord(a.index);
01490                   vv->resize(va->size());
01491                   for (unsigned int i=0; i<vv->size(); i++)
01492                                 (*vv)[i] += (*va)[i];
01493                 }
01494               else
01495                 {
01496                   VecDeriv* va = getVecDeriv(a.index);
01497                   vv->resize(va->size());
01498                   for (unsigned int i=0; i<vv->size(); i++)
01499                                 (*vv)[i] += (*va)[i];
01500                 }
01501             }
01502               else if (a.type == VecId::V_DERIV)
01503             {
01504               VecDeriv* vv = getVecDeriv(v.index);
01505               VecDeriv* va = getVecDeriv(a.index);
01506               vv->resize(va->size());
01507               for (unsigned int i=0; i<vv->size(); i++)
01508                             (*vv)[i] += (*va)[i];
01509             }
01510               else
01511             {
01512               // ERROR
01513               std::cerr << "Invalid vOp operation ("<<v<<','<<a<<','<<b<<','<<f<<")\n";
01514               return;
01515             }
01516             }
01517           else
01518             {
01519               // v = a+v*f
01520               if (v.type == VecId::V_COORD)
01521             {
01522               VecCoord* vv = getVecCoord(v.index);
01523               VecCoord* va = getVecCoord(a.index);
01524               vv->resize(va->size());
01525               for (unsigned int i=0; i<vv->size(); i++)
01526                 {
01527                   (*vv)[i] *= (Real)f;
01528                   (*vv)[i] += (*va)[i];
01529                 }
01530             }
01531               else
01532             {
01533               VecDeriv* vv = getVecDeriv(v.index);
01534               VecDeriv* va = getVecDeriv(a.index);
01535               vv->resize(va->size());
01536               for (unsigned int i=0; i<vv->size(); i++)
01537                 {
01538                   (*vv)[i] *= (Real)f;
01539                   (*vv)[i] += (*va)[i];
01540                 }
01541             }
01542             }
01543         }
01544           else
01545         {
01546           if (f==1.0)
01547             {
01548               // v = a+b
01549               if (v.type == VecId::V_COORD)
01550             {
01551               VecCoord* vv = getVecCoord(v.index);
01552               VecCoord* va = getVecCoord(a.index);
01553               vv->resize(va->size());
01554               if (b.type == VecId::V_COORD)
01555                 {
01556                   VecCoord* vb = getVecCoord(b.index);
01557                   for (unsigned int i=0; i<vv->size(); i++)
01558                 {
01559                   (*vv)[i] = (*va)[i];
01560                   (*vv)[i] += (*vb)[i];
01561                 }
01562                 }
01563               else
01564                 {
01565                   VecDeriv* vb = getVecDeriv(b.index);
01566                   for (unsigned int i=0; i<vv->size(); i++)
01567                 {
01568                   (*vv)[i] = (*va)[i];
01569                   (*vv)[i] += (*vb)[i];
01570                 }
01571                 }
01572             }
01573               else if (b.type == VecId::V_DERIV)
01574             {
01575               VecDeriv* vv = getVecDeriv(v.index);
01576               VecDeriv* va = getVecDeriv(a.index);
01577               VecDeriv* vb = getVecDeriv(b.index);
01578               vv->resize(va->size());
01579               for (unsigned int i=0; i<vv->size(); i++)
01580                 {
01581                   (*vv)[i] = (*va)[i];
01582                   (*vv)[i] += (*vb)[i];
01583                 }
01584             }
01585               else
01586             {
01587               // ERROR
01588               std::cerr << "Invalid vOp operation ("<<v<<','<<a<<','<<b<<','<<f<<")\n";
01589               return;
01590             }
01591             }
01592           else
01593             {
01594               // v = a+b*f
01595               if (v.type == VecId::V_COORD)
01596             {
01597               VecCoord* vv = getVecCoord(v.index);
01598               VecCoord* va = getVecCoord(a.index);
01599               vv->resize(va->size());
01600               if (b.type == VecId::V_COORD)
01601                 {
01602                   VecCoord* vb = getVecCoord(b.index);
01603                   for (unsigned int i=0; i<vv->size(); i++)
01604                 {
01605                   (*vv)[i] = (*va)[i];
01606                   (*vv)[i] += (*vb)[i]*(Real)f;
01607                 }
01608                 }
01609               else
01610                 {
01611                   VecDeriv* vb = getVecDeriv(b.index);
01612                   for (unsigned int i=0; i<vv->size(); i++)
01613                 {
01614                   (*vv)[i] = (*va)[i];
01615                   (*vv)[i] += (*vb)[i]*(Real)f;
01616                 }
01617                 }
01618             }
01619               else if (b.type == VecId::V_DERIV)
01620             {
01621               VecDeriv* vv = getVecDeriv(v.index);
01622               VecDeriv* va = getVecDeriv(a.index);
01623               VecDeriv* vb = getVecDeriv(b.index);
01624               vv->resize(va->size());
01625               for (unsigned int i=0; i<vv->size(); i++)
01626                 {
01627                   (*vv)[i] = (*va)[i];
01628                   (*vv)[i] += (*vb)[i]*(Real)f;
01629                 }
01630             }
01631               else
01632             {
01633               // ERROR
01634               std::cerr << "Invalid vOp operation ("<<v<<','<<a<<','<<b<<','<<f<<")\n";
01635               return;
01636             }
01637             }
01638         }
01639         }
01640     }
01641     }
01642 
01643     template <class DataTypes>
01644     void MechanicalObject<DataTypes>::vMultiOp(const VMultiOp& ops)
01645     {
01646     // optimize common integration case: v += a*dt, x += v*dt
01647     if (ops.size() == 2 && ops[0].second.size() == 2 && ops[0].first == ops[0].second[0].first && ops[0].first.type == VecId::V_DERIV && ops[0].second[1].first.type == VecId::V_DERIV
01648                             && ops[1].second.size() == 2 && ops[1].first == ops[1].second[0].first && ops[0].first == ops[1].second[1].first && ops[1].first.type == VecId::V_COORD)
01649     {
01650         const VecDeriv& va = *getVecDeriv(ops[0].second[1].first.index);
01651         VecDeriv& vv = *getVecDeriv(ops[0].first.index);
01652         VecCoord& vx = *getVecCoord(ops[1].first.index);
01653         const unsigned int n = vx.size();
01654         const Real f_v_v = (Real)(ops[0].second[0].second);
01655         const Real f_v_a = (Real)(ops[0].second[1].second);
01656         const Real f_x_x = (Real)(ops[1].second[0].second);
01657         const Real f_x_v = (Real)(ops[1].second[1].second);
01658         if (f_v_v == 1.0 && f_x_x == 1.0) // very common case
01659         {
01660         if (f_v_a == 1.0) // used by euler implicit and other integrators that directly computes a*dt
01661         {
01662             for (unsigned int i=0;i<n;++i)
01663             {
01664             vv[i] += va[i];
01665             vx[i] += vv[i]*f_x_v;
01666             }
01667         }
01668         else
01669         {
01670             for (unsigned int i=0;i<n;++i)
01671             {
01672             vv[i] += va[i]*f_v_a;
01673             vx[i] += vv[i]*f_x_v;
01674             }
01675         }
01676         }
01677         else if (f_x_x == 1.0) // some damping is applied to v
01678         {
01679         for (unsigned int i=0;i<n;++i)
01680         {
01681             vv[i] *= f_v_v;
01682             vv[i] += va[i];
01683             vx[i] += vv[i]*f_x_v;
01684         }
01685         }
01686         else // general case
01687         {
01688         for (unsigned int i=0;i<n;++i)
01689         {
01690             vv[i] *= f_v_v;
01691             vv[i] += va[i]*f_v_a;
01692             vx[i] *= f_x_x;
01693             vx[i] += vv[i]*f_x_v;
01694         }
01695         }
01696     }
01697     else // no optimization for now for other cases
01698         Inherited::vMultiOp(ops);
01699     }
01700 
01701     template <class T> inline void clear( T& t )
01702     {
01703       t.clear();
01704     }
01705     template<> inline void clear( float& t )
01706     {
01707       t=0;
01708     }
01709     template<> inline void clear( double& t )
01710     {
01711       t=0;
01712     }
01713 
01714 
01715     template <class DataTypes>
01716     void MechanicalObject<DataTypes>::vThreshold(VecId v, double t)
01717     {
01718       if( v.type==VecId::V_DERIV)
01719     {
01720       VecDeriv* vv = getVecDeriv(v.index);
01721       Real t2 = (Real)(t*t);
01722       for (unsigned int i=0; i<vv->size(); i++)
01723         {
01724           if( (*vv)[i]*(*vv)[i] < t2 )
01725         clear((*vv)[i]);
01726         }
01727     }
01728       else 
01729     {
01730       std::cerr<<"MechanicalObject<DataTypes>::vThreshold does not apply to coordinate vectors"<<std::endl;
01731     }
01732     }
01733 
01734     template <class DataTypes>
01735     double MechanicalObject<DataTypes>::vDot(VecId a, VecId b)
01736     {
01737       Real r = 0.0;
01738       if (a.type == VecId::V_COORD && b.type == VecId::V_COORD)
01739     {
01740       VecCoord* va = getVecCoord(a.index);
01741       VecCoord* vb = getVecCoord(b.index);
01742       for (unsigned int i=0; i<va->size(); i++)
01743             r += (*va)[i] * (*vb)[i];
01744     }
01745       else if (a.type == VecId::V_DERIV && b.type == VecId::V_DERIV)
01746     {
01747       VecDeriv* va = getVecDeriv(a.index);
01748       VecDeriv* vb = getVecDeriv(b.index);
01749       for (unsigned int i=0; i<va->size(); i++)
01750             r += (*va)[i] * (*vb)[i];
01751     }
01752       else
01753     {
01754       std::cerr << "Invalid dot operation ("<<a<<','<<b<<")\n";
01755     }
01756       return r;
01757     }
01758 
01759     template <class DataTypes>
01760     void MechanicalObject<DataTypes>::setX(VecId v)
01761     {
01762       if (v.type == VecId::V_COORD)
01763     {
01764       this->x = getVecCoord(v.index);
01765     }
01766       else
01767     {
01768       std::cerr << "Invalid setX operation ("<<v<<")\n";
01769     }
01770     }
01771 
01772     template <class DataTypes>
01773     void MechanicalObject<DataTypes>::setXfree(VecId v)
01774     {
01775       if (v.type == VecId::V_COORD)
01776     {
01777       this->xfree = getVecCoord(v.index);
01778     }
01779       else
01780     {
01781       std::cerr << "Invalid setXfree operation ("<<v<<")\n";
01782     }
01783     }
01784 
01785     template <class DataTypes>
01786     void MechanicalObject<DataTypes>::setVfree(VecId v)
01787     {
01788       if (v.type == VecId::V_DERIV)
01789     {
01790       this->vfree = getVecDeriv(v.index);
01791     }
01792       else
01793     {
01794       std::cerr << "Invalid setVfree operation ("<<v<<")\n";
01795     }
01796     }
01797 
01798     template <class DataTypes>
01799     void MechanicalObject<DataTypes>::setV(VecId v)
01800     {
01801       if (v.type == VecId::V_DERIV)
01802     {
01803       this->v = getVecDeriv(v.index);
01804     }
01805       else
01806     {
01807       std::cerr << "Invalid setV operation ("<<v<<")\n";
01808     }
01809     }
01810 
01811     template <class DataTypes>
01812     void MechanicalObject<DataTypes>::setF(VecId v)
01813     {
01814       if (v.type == VecId::V_DERIV)
01815     {
01816       this->f = getVecDeriv(v.index);
01817     }
01818       else
01819     {
01820       std::cerr << "Invalid setF operation ("<<v<<")\n";
01821     }
01822     }
01823 
01824     template <class DataTypes>
01825     void MechanicalObject<DataTypes>::setDx(VecId v)
01826     {
01827       if (v.type == VecId::V_DERIV)
01828     {
01829       this->dx = getVecDeriv(v.index);
01830     }
01831       else
01832     {
01833       std::cerr << "Invalid setDx operation ("<<v<<")\n";
01834     }
01835     }
01836 
01837 
01838     template <class DataTypes>
01839     void MechanicalObject<DataTypes>::setC(VecId v)
01840     {
01841       if (v.type == VecId::V_CONST)
01842     {
01843       this->c = getVecConst(v.index);
01844     }
01845       else
01846     {
01847       std::cerr << "Invalid setDx operation ("<<v<<")\n";
01848     }
01849     }
01850 
01851 
01852     template <class DataTypes>
01853     void MechanicalObject<DataTypes>::printDOF( VecId v, std::ostream& out)
01854     {
01855       if( v.type==VecId::V_COORD )
01856     {
01857       VecCoord& x= *getVecCoord(v.index);
01858       for( unsigned i=0; i<x.size(); ++i )
01859             out<<x[i]<<" ";
01860     }
01861       else if( v.type==VecId::V_DERIV )
01862     {
01863       VecDeriv& x= *getVecDeriv(v.index);
01864       for( unsigned i=0; i<x.size(); ++i )
01865             out<<x[i]<<" ";
01866     }
01867       else
01868         out<<"MechanicalObject<DataTypes>::printDOF, unknown v.type = "<<v.type<<std::endl;
01869     }
01870 
01871 
01872     template <class DataTypes>
01873     unsigned MechanicalObject<DataTypes>::printDOFWithElapsedTime( VecId v,unsigned count, unsigned time, std::ostream& out)
01874     {
01875 
01876       if( v.type==VecId::V_COORD )
01877     {
01878       VecCoord& x= *getVecCoord(v.index);
01879         
01880       for( unsigned i=0; i<x.size(); ++i )
01881         {
01882           out<<count+i<<"\t"<<time<<"\t"<<x[i]<<std::endl;
01883         }
01884       out<<std::endl<<std::endl;
01885       return x.size();
01886     }
01887       else if( v.type==VecId::V_DERIV )
01888     {
01889       VecDeriv& x= *getVecDeriv(v.index);
01890       for( unsigned i=0; i<x.size(); ++i )
01891         out<<count+i<<"\t"<<time<<"\t"<<x[i]<<std::endl;
01892       out<<std::endl<<std::endl;
01893             
01894       return x.size();
01895     }
01896       else
01897     out<<"MechanicalObject<DataTypes>::printDOFWithElapsedTime, unknown v.type = "<<v.type<<std::endl;
01898     
01899       return 0;
01900     }
01901 
01902 
01903     template <class DataTypes>
01904     void MechanicalObject<DataTypes>::resetForce()
01905     {
01906       VecDeriv& f= *getF();
01907       for( unsigned i=0; i<f.size(); ++i )
01908         f[i] = Deriv();
01909     }
01910 
01911 
01912     template <class DataTypes>
01913     void MechanicalObject<DataTypes>::resetConstraint()
01914     {
01915       //    std::cout << "resetConstraint()\n";
01916       VecConst& c= *getC();
01917       c.clear();
01918 
01919       constraintId.clear();
01920     }
01921 
01922 
01923     template <class DataTypes>
01924     void MechanicalObject<DataTypes>::setConstraintId(unsigned int i)
01925     { 
01926       constraintId.push_back(i);
01927 
01928       //for (int j=0; j<constraintId.size(); j++)
01929       //{
01930       //    std::cout << "constraintId[j] = " << constraintId[j] << std::endl;
01931       //}
01932     }
01933 
01934     template <class DataTypes>
01935     sofa::helper::vector<unsigned int>& MechanicalObject<DataTypes>::getConstraintId()
01936     {
01937       return constraintId;
01938     }
01939 
01940     
01941 template <class DataTypes>
01942     bool MechanicalObject<DataTypes>::addBBox(double* minBBox, double* maxBBox)
01943 {
01944     const VecCoord& x = *getX();
01945     if (x.size() <= 0) return false;
01946     Real p[3] = {0,0,0};
01947     for (unsigned int i=0; i<x.size(); i++)
01948     {
01949         DataTypes::get(p[0], p[1], p[2], x[i]);
01950         for (int c=0;c<3;c++)
01951         {
01952             if (p[c] > maxBBox[c]) maxBBox[c] = p[c];
01953             if (p[c] < minBBox[c]) minBBox[c] = p[c];
01954         }
01955     }
01956     return true;
01957 }
01958 
01959 template <class DataTypes>
01960 void MechanicalObject<DataTypes>::draw()
01961 {
01962     if (debugViewIndices.getValue())
01963     {
01964         glColor3f(1.0,1.0,1.0);
01965         glDisable(GL_LIGHTING);
01966         float scale = debugViewIndicesScale.getValue();
01967         for (int i=0 ; i< vsize ; i++)
01968         {
01969             std::ostringstream oss;
01970             oss << i;
01971             std::string tmp = oss.str();
01972             const char* s = tmp.c_str();
01973             //glVertex3f(getPX(i),getPY(i),getPZ(i) );
01974             glPushMatrix();
01975                 glTranslatef(getPX(i), getPY(i), getPZ(i));
01976             
01977             glScalef(scale,scale,scale);
01978                 while(*s){
01979                     glutStrokeCharacter(GLUT_STROKE_ROMAN, *s);
01980                 s++;
01981             }
01982                 glPopMatrix();
01983             
01984         }
01985     }
01986     
01987 }
01988 
01989 
01990     //
01991     // Template specializations
01992 
01993 
01994 
01995   } // namespace component
01996 
01997 } // namespace sofa
01998 
01999 #endif
02000 

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