00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #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
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
00101
00102 internalForces = f;
00103 externalForces = new VecDeriv;
00104
00105
00106
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
00116
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
00147
00148
00149
00150
00151
00152
00153
00154
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 , SReal , bool , bool )
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(""));
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
00204 if (arg->getAttribute("scale")!=NULL) {
00205 scale.setValue((SReal)atof(arg->getAttribute("scale")));
00206
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
00212
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
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
00228
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
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
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
00328
00329
00330
00331
00332
00333
00334
00335 if (v0 != NULL && (*v0).size() > maxIndex)
00336 (*v0)[outputIndex] = (*v0)[inputIndex];
00337
00338
00339
00340
00341
00342
00343
00344 if ((*externalForces).size() > maxIndex)
00345 (*externalForces)[outputIndex] = (*externalForces)[inputIndex];
00346
00347
00348 if (reset_position != NULL && (*reset_position).size() > maxIndex)
00349 (*reset_position)[outputIndex] = (*reset_position)[inputIndex];
00350
00351
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
00380
00381
00382
00383 Coord tmp;
00384 Deriv tmp2;
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399 if(v0 != NULL && (*v0).size() > maxIndex)
00400 {
00401 tmp2 = (*v0) [idx1];
00402 (*v0)[idx1] = (*v0)[idx2];
00403 (*v0)[idx2] = tmp2;
00404 }
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417 if ((*externalForces).size() > maxIndex)
00418 {
00419 tmp2 = (*externalForces)[idx1];
00420 (*externalForces)[idx1] = (*externalForces)[idx2];
00421 (*externalForces)[idx2] = tmp2;
00422 }
00423
00424
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
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
00478
00479
00480
00481
00482
00483
00484 renumber(v0, &dtmp, index);
00485
00486
00487
00488 renumber(externalForces, &dtmp, index);
00489
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
00516 if (reset_position!=NULL)
00517 (*reset_position).resize(size);
00518
00519
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
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
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
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
00675
00676 unsigned int j;
00677
00678
00679
00680
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
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
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 {
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
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
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
00948 *this->xfree = *x;
00949
00950
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
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
01005 if (reset_position == NULL) this->reset_position = new VecCoord;
01006 *this->reset_position = *x;
01007 }
01008
01009
01010
01011
01012
01013 template <class DataTypes>
01014 void MechanicalObject<DataTypes>::reset()
01015 {
01016 if (reset_position == NULL) return;
01017
01018 this->resize(reset_position->size());
01019
01020
01021 *this->getVecCoord(VecId::position().index) = *this->reset_position;
01022
01023
01024
01025 if (v0 == NULL) return;
01026 *this->getVecDeriv(VecId::velocity().index) = *this->v0;
01027
01028
01029
01030 *this->getVecCoord(VecId::freePosition().index) = *this->getVecCoord(VecId::position().index);
01031
01032
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
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
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 )
01131 {
01132 this->f = this->internalForces;
01133 }
01134
01135 template <class DataTypes>
01136 void MechanicalObject<DataTypes>::endIntegration(Real )
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
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
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
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
01333 std::cerr << "Invalid vOp operation ("<<v<<','<<a<<','<<b<<','<<f<<")\n";
01334 return;
01335 }
01336 if (v == b)
01337 {
01338
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
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
01379 std::cerr << "Invalid vOp operation ("<<v<<','<<a<<','<<b<<','<<f<<")\n";
01380 return;
01381 }
01382 if (b.isNull())
01383 {
01384
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
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
01438 std::cerr << "Invalid vOp operation ("<<v<<','<<a<<','<<b<<','<<f<<")\n";
01439 return;
01440 }
01441 }
01442 else
01443 {
01444
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
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
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
01513 std::cerr << "Invalid vOp operation ("<<v<<','<<a<<','<<b<<','<<f<<")\n";
01514 return;
01515 }
01516 }
01517 else
01518 {
01519
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
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
01588 std::cerr << "Invalid vOp operation ("<<v<<','<<a<<','<<b<<','<<f<<")\n";
01589 return;
01590 }
01591 }
01592 else
01593 {
01594
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
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
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)
01659 {
01660 if (f_v_a == 1.0)
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)
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
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
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
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
01929
01930
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
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
01992
01993
01994
01995 }
01996
01997 }
01998
01999 #endif
02000