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 #include <sofa/component/mass/UniformMass.inl>
00026 #include <sofa/defaulttype/VecTypes.h>
00027 #include <sofa/defaulttype/RigidTypes.h>
00028 #include <sofa/helper/gl/Axis.h>
00029 #include <sofa/core/ObjectFactory.h>
00030 #include <sofa/helper/system/FileRepository.h>
00031
00032 namespace sofa
00033 {
00034
00035 namespace component
00036 {
00037
00038 namespace mass
00039 {
00040
00041
00042
00043 using namespace sofa::defaulttype;
00044
00045
00046 static void skipToEOL(FILE* f)
00047 {
00048 int ch;
00049 while ((ch = fgetc(f)) != EOF && ch != '\n')
00050 ;
00051 }
00052
00053
00054 Mat3x3d MatrixFromEulerXYZ(double thetaX, double thetaY, double thetaZ)
00055 {
00056 double cosX = cos(thetaX);
00057 double sinX = sin(thetaX);
00058 double cosY = cos(thetaY);
00059 double sinY = sin(thetaY);
00060 double cosZ = cos(thetaZ);
00061 double sinZ = sin(thetaZ);
00062 return
00063 Mat3x3d(Vec3d( cosZ, -sinZ, 0),
00064 Vec3d( sinZ, cosZ, 0),
00065 Vec3d( 0, 0, 1)) *
00066 Mat3x3d(Vec3d( cosY, 0, sinY),
00067 Vec3d( 0, 1, 0),
00068 Vec3d(-sinY, 0, cosY)) *
00069 Mat3x3d(Vec3d( 1, 0, 0),
00070 Vec3d( 0, cosX, -sinX),
00071 Vec3d( 0, sinX, cosX)) ;
00072 }
00073
00074
00075
00076
00077 #ifndef SOFA_FLOAT
00078 template<>
00079 void UniformMass<Rigid3dTypes, Rigid3dMass>::parse(core::objectmodel::BaseObjectDescription* arg)
00080 {
00081 Inherited::parse(arg);
00082 Rigid3dMass m = this->getMass();
00083 if (arg->getAttribute("filename"))
00084 {
00085 std::string filename = arg->getAttribute("filename");
00086 if (!sofa::helper::system::DataRepository.findFile(filename))
00087 {
00088 std::cerr << "ERROR: cannot find file '" << filename << "'." << std::endl;
00089 }
00090 else
00091 {
00092 char cmd[64];
00093 FILE* file;
00094 if ((file = fopen(filename.c_str(), "r")) == NULL)
00095 {
00096 std::cerr << "ERROR: cannot read file '" << filename << "'." << std::endl;
00097 }
00098 else
00099 {
00100
00101
00102
00103 {
00104 skipToEOL(file);
00105
00106 while (fscanf(file, "%s", cmd) != EOF)
00107 {
00108 if (!strcmp(cmd,"inrt"))
00109 {
00110 for (int i = 0; i < 9; i++)
00111 {
00112 fscanf(file, "%lf", &(m.inertiaMatrix.ptr()[i]));
00113 }
00114 }
00115 else if (!strcmp(cmd,"cntr"))
00116 {
00117 Vec3d center;
00118 for (int i = 0; i < 3; ++i)
00119 {
00120 fscanf(file, "%lf", &(center[i]));
00121 }
00122 }
00123 else if (!strcmp(cmd,"mass"))
00124 {
00125 double mass;
00126 fscanf(file, "%lf", &mass);
00127 if (!arg->getAttribute("mass"))
00128 m.mass = mass;
00129 }
00130 else if (!strcmp(cmd,"volm"))
00131 {
00132 fscanf(file, "%lf", &(m.volume));
00133 }
00134 else if (!strcmp(cmd,"frme"))
00135 {
00136 Quatd orient;
00137 for (int i = 0; i < 4; ++i)
00138 {
00139 fscanf(file, "%lf", &(orient[i]));
00140 }
00141 orient.normalize();
00142 }
00143 else if (!strcmp(cmd,"grav"))
00144 {
00145 Vec3d gravity;
00146 fscanf(file, "%lf %lf %lf\n", &(gravity.x()),
00147 &(gravity.y()), &(gravity.z()));
00148 }
00149 else if (!strcmp(cmd,"visc"))
00150 {
00151 double viscosity = 0;
00152 fscanf(file, "%lf", &viscosity);
00153 }
00154 else if (!strcmp(cmd,"stck"))
00155 {
00156 double tmp;
00157 fscanf(file, "%lf", &tmp);
00158 }
00159 else if (!strcmp(cmd,"step"))
00160 {
00161 double tmp;
00162 fscanf(file, "%lf", &tmp);
00163 }
00164 else if (!strcmp(cmd,"prec"))
00165 {
00166 double tmp;
00167 fscanf(file, "%lf", &tmp);
00168 }
00169 else if (cmd[0] == '#')
00170 {
00171 skipToEOL(file);
00172 }
00173 else
00174 {
00175 printf("%s: Unknown RigidMass keyword: %s\n", filename.c_str(), cmd);
00176 skipToEOL(file);
00177 }
00178 }
00179 }
00180 fclose(file);
00181 }
00182 }
00183 }
00184 m.recalc();
00185 this->setMass(m);
00186 }
00187
00188
00189 template <>
00190 void UniformMass<Rigid3dTypes, Rigid3dMass>::draw()
00191 {
00192 if (!getContext()->getShowBehaviorModels())
00193 return;
00194 const VecCoord& x = *mstate->getX();
00195 RigidTypes::Vec3 gravityCenter;
00196 defaulttype::Vec3d len;
00197
00198
00199
00200
00201
00202
00203
00204
00205 double m00 = mass.getValue().inertiaMatrix[0][0];
00206 double m11 = mass.getValue().inertiaMatrix[1][1];
00207 double m22 = mass.getValue().inertiaMatrix[2][2];
00208 len[0] = sqrt(m11+m22-m00);
00209 len[1] = sqrt(m00+m22-m11);
00210 len[2] = sqrt(m00+m11-m22);
00211
00212 for (unsigned int i=0; i<x.size(); i++)
00213 {
00214 helper::gl::Axis::draw(x[i].getCenter(), x[i].getOrientation(), len*showAxisSize.getValue());
00215 gravityCenter += (x[i].getCenter());
00216 }
00217
00218 if(showCenterOfGravity.getValue()){
00219 gravityCenter /= x.size();
00220 glColor3f (1,1,0);
00221 glBegin (GL_LINES);
00222 helper::gl::glVertexT(gravityCenter - RigidTypes::Vec3(showAxisSize.getValue(),0,0) );
00223 helper::gl::glVertexT(gravityCenter + RigidTypes::Vec3(showAxisSize.getValue(),0,0) );
00224 helper::gl::glVertexT(gravityCenter - RigidTypes::Vec3(0,showAxisSize.getValue(),0) );
00225 helper::gl::glVertexT(gravityCenter + RigidTypes::Vec3(0,showAxisSize.getValue(),0) );
00226 helper::gl::glVertexT(gravityCenter - RigidTypes::Vec3(0,0,showAxisSize.getValue()) );
00227 helper::gl::glVertexT(gravityCenter + RigidTypes::Vec3(0,0,showAxisSize.getValue()) );
00228 glEnd();
00229 }
00230 }
00231
00232
00233
00234 template <>
00235 void UniformMass<Rigid2dTypes, Rigid2dMass>::draw()
00236 {
00237 if (!getContext()->getShowBehaviorModels())
00238 return;
00239 const VecCoord& x = *mstate->getX();
00240 defaulttype::Vec3d len;
00241
00242 len[0] = len[1] = sqrt(mass.getValue().inertiaMatrix);
00243 len[2] = 0;
00244
00245 for (unsigned int i=0; i<x.size(); i++)
00246 {
00247 Quat orient(Vec3d(0,0,1), x[i].getOrientation());
00248 Vec3d center; center = x[i].getCenter();
00249 helper::gl::Axis::draw(center, orient, len);
00250 }
00251 }
00252
00253 template <>
00254 double UniformMass<Rigid3dTypes,Rigid3dMass>::getPotentialEnergy( const Rigid3dTypes::VecCoord& x )
00255 {
00256 double e = 0;
00257
00258 Vec3d g ( this->getContext()->getLocalGravity() );
00259 for (unsigned int i=0;i<x.size();i++)
00260 {
00261 e -= g*mass.getValue().mass*x[i].getCenter();
00262 }
00263 return e;
00264 }
00265
00266
00267 template <>
00268 double UniformMass<Rigid2dTypes,Rigid2dMass>::getPotentialEnergy( const Rigid2dTypes::VecCoord& x )
00269 {
00270 double e = 0;
00271
00272 Vec2d g; g = this->getContext()->getLocalGravity();
00273 for (unsigned int i=0;i<x.size();i++)
00274 {
00275 e -= g*mass.getValue().mass*x[i].getCenter();
00276 }
00277 return e;
00278 }
00279
00280 template <>
00281 double UniformMass<Rigid3dTypes,Rigid3dMass>::getElementMass(unsigned int )
00282 {
00283 return (mass.getValue().mass);
00284 }
00285
00286 template <>
00287 sofa::defaulttype::Vector3::value_type UniformMass<Rigid2dTypes,Rigid2dMass>::getElementMass(unsigned int )
00288 {
00289 return (mass.getValue().mass);
00290 }
00291
00292
00293 template <>
00294 void UniformMass<Vec6dTypes, double>::draw()
00295 {
00296 if (!getContext()->getShowBehaviorModels())
00297 return;
00298 const VecCoord& x = *mstate->getX();
00299 const VecCoord& x0 = *mstate->getX0();
00300
00301 Mat3x3d R; R.identity();
00302 glBegin(GL_LINES);
00303 for (unsigned int i=0; i<x.size(); i++)
00304 {
00305 defaulttype::Vec3d len(1,1,1);
00306 int a = (i<x.size()-1)?i : i-1;
00307 int b = a+1;
00308 defaulttype::Vec3d dp; dp = x0[b]-x0[a];
00309 defaulttype::Vec3d p; p = x[i];
00310 len[0] = dp.norm();
00311 len[1] = len[0];
00312 len[2] = len[0];
00313 R = R * MatrixFromEulerXYZ(x[i][3], x[i][4], x[i][5]);
00314 glColor3f(1,0,0);
00315 helper::gl::glVertexT(p);
00316 helper::gl::glVertexT(p + R.col(0)*len[0]);
00317 glColor3f(0,1,0);
00318 helper::gl::glVertexT(p);
00319 helper::gl::glVertexT(p + R.col(1)*len[1]);
00320 glColor3f(0,0,1);
00321 helper::gl::glVertexT(p);
00322 helper::gl::glVertexT(p + R.col(2)*len[2]);
00323 }
00324 glEnd();
00325 }
00326
00327 template <>
00328 void UniformMass<Vec3dTypes, double>::addMDxToVector(defaulttype::BaseVector *resVect, const VecDeriv* dx, double mFact, unsigned int& offset)
00329 {
00330 unsigned int derivDim = Deriv::size();
00331 double m = mass.getValue();
00332
00333 unsigned int vecDim = mstate->getX()->size();
00334
00335 const double* g = this->getContext()->getLocalGravity().ptr();
00336
00337 for (unsigned int i=0; i<vecDim; i++)
00338 for (unsigned int j=0; j<derivDim; j++)
00339 {
00340 if (dx != NULL)
00341 resVect->add(offset + i * derivDim + j, mFact * m * g[j] * (*dx)[i][0]);
00342 else
00343 resVect->add(offset + i * derivDim + j, mFact * m * g[j]);
00344 }
00345 }
00346
00347 #endif
00348
00349 #ifndef SOFA_DOUBLE
00350 template<>
00351 void UniformMass<Rigid3fTypes, Rigid3fMass>::parse(core::objectmodel::BaseObjectDescription* arg)
00352 {
00353 Inherited::parse(arg);
00354 Rigid3fMass m = this->getMass();
00355 if (arg->getAttribute("filename"))
00356 {
00357 std::string filename = arg->getAttribute("filename");
00358 if (!sofa::helper::system::DataRepository.findFile(filename))
00359 {
00360 std::cerr << "ERROR: cannot find file '" << filename << "'." << std::endl;
00361 }
00362 else
00363 {
00364 char cmd[64];
00365 FILE* file;
00366 if ((file = fopen(filename.c_str(), "r")) == NULL)
00367 {
00368 std::cerr << "ERROR: cannot read file '" << filename << "'." << std::endl;
00369 }
00370 else
00371 {
00372
00373
00374
00375 {
00376 skipToEOL(file);
00377
00378 while (fscanf(file, "%s", cmd) != EOF)
00379 {
00380 if (!strcmp(cmd,"inrt"))
00381 {
00382 for (int i = 0; i < 9; i++)
00383 {
00384 fscanf(file, "%f", &(m.inertiaMatrix.ptr()[i]));
00385 }
00386 }
00387 else if (!strcmp(cmd,"cntr"))
00388 {
00389 Vec3d center;
00390 for (int i = 0; i < 3; ++i)
00391 {
00392 fscanf(file, "%lf", &(center[i]));
00393 }
00394 }
00395 else if (!strcmp(cmd,"mass"))
00396 {
00397 float mass;
00398 fscanf(file, "%f", &mass);
00399 if (!arg->getAttribute("mass"))
00400 m.mass = mass;
00401 }
00402 else if (!strcmp(cmd,"volm"))
00403 {
00404 fscanf(file, "%f", &(m.volume));
00405 }
00406 else if (!strcmp(cmd,"frme"))
00407 {
00408 Quatd orient;
00409 for (int i = 0; i < 4; ++i)
00410 {
00411 fscanf(file, "%lf", &(orient[i]));
00412 }
00413 orient.normalize();
00414 }
00415 else if (!strcmp(cmd,"grav"))
00416 {
00417 Vec3d gravity;
00418 fscanf(file, "%lf %lf %lf\n", &(gravity.x()),
00419 &(gravity.y()), &(gravity.z()));
00420 }
00421 else if (!strcmp(cmd,"visc"))
00422 {
00423 double viscosity = 0;
00424 fscanf(file, "%lf", &viscosity);
00425 }
00426 else if (!strcmp(cmd,"stck"))
00427 {
00428 double tmp;
00429 fscanf(file, "%lf", &tmp);
00430 }
00431 else if (!strcmp(cmd,"step"))
00432 {
00433 double tmp;
00434 fscanf(file, "%lf", &tmp);
00435 }
00436 else if (!strcmp(cmd,"prec"))
00437 {
00438 double tmp;
00439 fscanf(file, "%lf", &tmp);
00440 }
00441 else if (cmd[0] == '#')
00442 {
00443 skipToEOL(file);
00444 }
00445 else
00446 {
00447 printf("%s: Unknown RigidMass keyword: %s\n", filename.c_str(), cmd);
00448 skipToEOL(file);
00449 }
00450 }
00451 }
00452 fclose(file);
00453 }
00454 }
00455 }
00456 m.recalc();
00457 this->setMass(m);
00458 }
00459
00460
00461 template <>
00462 void UniformMass<Rigid3fTypes, Rigid3fMass>::draw()
00463 {
00464 if (!getContext()->getShowBehaviorModels())
00465 return;
00466 const VecCoord& x = *mstate->getX();
00467 RigidTypes::Vec3 gravityCenter;
00468 defaulttype::Vec3d len;
00469
00470
00471
00472
00473
00474
00475
00476
00477 double m00 = mass.getValue().inertiaMatrix[0][0];
00478 double m11 = mass.getValue().inertiaMatrix[1][1];
00479 double m22 = mass.getValue().inertiaMatrix[2][2];
00480 len[0] = sqrt(m11+m22-m00);
00481 len[1] = sqrt(m00+m22-m11);
00482 len[2] = sqrt(m00+m11-m22);
00483
00484 for (unsigned int i=0; i<x.size(); i++)
00485 {
00486 helper::gl::Axis::draw(x[i].getCenter(), x[i].getOrientation(), len*showAxisSize.getValue());
00487 gravityCenter += (x[i].getCenter());
00488 }
00489
00490 if(showCenterOfGravity.getValue()){
00491 gravityCenter /= x.size();
00492 glColor3f (1,1,0);
00493 glBegin (GL_LINES);
00494 helper::gl::glVertexT(gravityCenter - RigidTypes::Vec3(showAxisSize.getValue(),0,0) );
00495 helper::gl::glVertexT(gravityCenter + RigidTypes::Vec3(showAxisSize.getValue(),0,0) );
00496 helper::gl::glVertexT(gravityCenter - RigidTypes::Vec3(0,showAxisSize.getValue(),0) );
00497 helper::gl::glVertexT(gravityCenter + RigidTypes::Vec3(0,showAxisSize.getValue(),0) );
00498 helper::gl::glVertexT(gravityCenter - RigidTypes::Vec3(0,0,showAxisSize.getValue()) );
00499 helper::gl::glVertexT(gravityCenter + RigidTypes::Vec3(0,0,showAxisSize.getValue()) );
00500 glEnd();
00501 }
00502 }
00503
00504 template <>
00505 void UniformMass<Rigid2fTypes, Rigid2fMass>::draw()
00506 {
00507 if (!getContext()->getShowBehaviorModels())
00508 return;
00509 const VecCoord& x = *mstate->getX();
00510 defaulttype::Vec3d len;
00511
00512 len[0] = len[1] = sqrt(mass.getValue().inertiaMatrix);
00513 len[2] = 0;
00514
00515 for (unsigned int i=0; i<x.size(); i++)
00516 {
00517 Quat orient(Vec3d(0,0,1), x[i].getOrientation());
00518 Vec3d center; center = x[i].getCenter();
00519 helper::gl::Axis::draw(center, orient, len);
00520 }
00521 }
00522
00523 template <>
00524 double UniformMass<Rigid3fTypes,Rigid3fMass>::getPotentialEnergy( const Rigid3fTypes::VecCoord& x )
00525 {
00526 double e = 0;
00527
00528 Vec3d g ( this->getContext()->getLocalGravity() );
00529 for (unsigned int i=0;i<x.size();i++)
00530 {
00531 e -= g*mass.getValue().mass*x[i].getCenter();
00532 }
00533 return e;
00534 }
00535
00536 template <>
00537 double UniformMass<Rigid2fTypes,Rigid2fMass>::getPotentialEnergy( const Rigid2fTypes::VecCoord& x )
00538 {
00539 double e = 0;
00540
00541 Vec2d g; g = this->getContext()->getLocalGravity();
00542 for (unsigned int i=0;i<x.size();i++)
00543 {
00544 e -= g*mass.getValue().mass*x[i].getCenter();
00545 }
00546 return e;
00547 }
00548
00549 template <>
00550 double UniformMass<Rigid3fTypes,Rigid3fMass>::getElementMass(unsigned int )
00551 {
00552 return (double)(mass.getValue().mass);
00553 }
00554
00555
00556 template <>
00557 double UniformMass<Rigid2fTypes,Rigid2fMass>::getElementMass(unsigned int )
00558 {
00559 return (double)(mass.getValue().mass);
00560 }
00561
00562 template <>
00563 void UniformMass<Vec6fTypes, float>::draw()
00564 {
00565 if (!getContext()->getShowBehaviorModels())
00566 return;
00567 const VecCoord& x = *mstate->getX();
00568 const VecCoord& x0 = *mstate->getX0();
00569
00570 Mat3x3d R;
00571 glBegin(GL_LINES);
00572 for (unsigned int i=0; i<x.size(); i++)
00573 {
00574 defaulttype::Vec3d len(1,1,1);
00575 int a = (i<x.size()-1)?i : i-1;
00576 int b = a+1;
00577 defaulttype::Vec3d dp; dp = x0[b]-x0[a];
00578 defaulttype::Vec3d p; p = x[i];
00579 len[0] = dp.norm();
00580 len[1] = len[0];
00581 len[2] = len[0];
00582 R = R * MatrixFromEulerXYZ(x[i][3], x[i][4], x[i][5]);
00583 glColor3f(1,0,0);
00584 helper::gl::glVertexT(p);
00585 helper::gl::glVertexT(p + R.col(0)*len[0]);
00586 glColor3f(0,1,0);
00587 helper::gl::glVertexT(p);
00588 helper::gl::glVertexT(p + R.col(1)*len[1]);
00589 glColor3f(0,0,1);
00590 helper::gl::glVertexT(p);
00591 helper::gl::glVertexT(p + R.col(2)*len[2]);
00592 }
00593 glEnd();
00594 }
00595
00596
00597 template <>
00598 void UniformMass<Vec3fTypes, float>::addMDxToVector(defaulttype::BaseVector *resVect, const VecDeriv* dx, SReal mFact, unsigned int& offset)
00599 {
00600 unsigned int derivDim = Deriv::size();
00601 float m = mass.getValue();
00602
00603 unsigned int vecDim = mstate->getX()->size();
00604
00605 const SReal* g = this->getContext()->getLocalGravity().ptr();
00606
00607 for (unsigned int i=0; i<vecDim; i++)
00608 for (unsigned int j=0; j<derivDim; j++)
00609 {
00610 if (dx != NULL)
00611 resVect->add(offset + i * derivDim + j, mFact * m * g[j] * (*dx)[i][0]);
00612 else
00613 resVect->add(offset + i * derivDim + j, mFact * m * g[j]);
00614 }
00615 }
00616
00617 #endif
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632 SOFA_DECL_CLASS(UniformMass)
00633
00634
00635 int UniformMassClass = core::RegisterObject("Define the same mass for all the particles")
00636
00637 #ifndef SOFA_FLOAT
00638 .add< UniformMass<Vec3dTypes,double> >()
00639 .add< UniformMass<Vec2dTypes,double> >()
00640 .add< UniformMass<Vec1dTypes,double> >()
00641 .add< UniformMass<Vec6dTypes,double> >()
00642 .add< UniformMass<Rigid3dTypes,Rigid3dMass> >()
00643 .add< UniformMass<Rigid2dTypes,Rigid2dMass> >()
00644 #endif
00645 #ifndef SOFA_DOUBLE
00646 .add< UniformMass<Vec3fTypes,float> >()
00647 .add< UniformMass<Vec2fTypes,float> >()
00648 .add< UniformMass<Vec1fTypes,float> >()
00649 .add< UniformMass<Vec6fTypes,float> >()
00650 .add< UniformMass<Rigid3fTypes,Rigid3fMass> >()
00651 .add< UniformMass<Rigid2fTypes,Rigid2fMass> >()
00652 #endif
00653 ;
00654
00655 #ifndef SOFA_FLOAT
00656 template class UniformMass<Vec3dTypes,double>;
00657 template class UniformMass<Vec2dTypes,double>;
00658 template class UniformMass<Vec1dTypes,double>;
00659 template class UniformMass<Vec6dTypes,double>;
00660 template class UniformMass<Rigid3dTypes,Rigid3dMass>;
00661 template class UniformMass<Rigid2dTypes,Rigid2dMass>;
00662 #endif
00663 #ifndef SOFA_DOUBLE
00664 template class UniformMass<Vec3fTypes,float>;
00665 template class UniformMass<Vec2fTypes,float>;
00666 template class UniformMass<Vec1fTypes,float>;
00667 template class UniformMass<Vec6fTypes,float>;
00668 template class UniformMass<Rigid3fTypes,Rigid3fMass>;
00669 template class UniformMass<Rigid2fTypes,Rigid2fMass>;
00670 #endif
00671
00672 }
00673
00674 }
00675
00676 }