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_MAPPING_RIGIDMAPPING_INL
00026 #define SOFA_COMPONENT_MAPPING_RIGIDMAPPING_INL
00027
00028 #include <sofa/component/mapping/RigidMapping.h>
00029 #include <sofa/defaulttype/VecTypes.h>
00030 #include <sofa/defaulttype/RigidTypes.h>
00031 #include <sofa/helper/io/MassSpringLoader.h>
00032 #include <sofa/helper/io/SphereLoader.h>
00033 #include <sofa/helper/io/Mesh.h>
00034 #include <sofa/helper/gl/template.h>
00035 #include <sofa/core/componentmodel/behavior/MechanicalMapping.inl>
00036 #include <sofa/core/componentmodel/behavior/MechanicalState.h>
00037 #include <sofa/core/Mapping.h>
00038 #include <sofa/core/componentmodel/behavior/MappedModel.h>
00039 #include <string.h>
00040 #include <iostream>
00041
00042 using std::cerr;
00043 using std::endl;
00044
00045
00046
00047 namespace sofa
00048 {
00049
00050 namespace component
00051 {
00052
00053 namespace mapping
00054 {
00055
00056 using namespace sofa::defaulttype;
00057
00058 template <class BasicMapping>
00059 class RigidMapping<BasicMapping>::Loader : public helper::io::MassSpringLoader, public helper::io::SphereLoader
00060 {
00061 public:
00062
00063 RigidMapping<BasicMapping>* dest;
00064 Loader(RigidMapping<BasicMapping>* dest) : dest(dest) {}
00065 virtual void addMass(SReal px, SReal py, SReal pz, SReal, SReal, SReal, SReal, SReal, bool, bool)
00066 {
00067 Coord c;
00068 Out::DataTypes::set(c,px,py,pz);
00069 dest->points.beginEdit()->push_back(c);
00070 }
00071 virtual void addSphere(SReal px, SReal py, SReal pz, SReal)
00072 {
00073 Coord c;
00074 Out::DataTypes::set(c,px,py,pz);
00075 dest->points.beginEdit()->push_back(c);
00076 }
00077 };
00078
00079 template <class BasicMapping>
00080 void RigidMapping<BasicMapping>::load(const char *filename)
00081 {
00082 points.beginEdit()->resize(0);
00083
00084 if (strlen(filename)>4 && !strcmp(filename+strlen(filename)-4,".xs3"))
00085 {
00086 Loader loader(this);
00087 loader.helper::io::MassSpringLoader::load(filename);
00088 }
00089 else
00090 if (strlen(filename)>4 && !strcmp(filename+strlen(filename)-4,".sph"))
00091 {
00092 Loader loader(this);
00093 loader.helper::io::SphereLoader::load(filename);
00094 }
00095 else if (strlen(filename)>0)
00096 {
00097 helper::io::Mesh* mesh = helper::io::Mesh::Create(filename);
00098 if (mesh!=NULL)
00099 {
00100 points.beginEdit()->resize(mesh->getVertices().size());
00101 for (unsigned int i=0;i<mesh->getVertices().size();i++)
00102 {
00103 Out::DataTypes::set((*points.beginEdit())[i], mesh->getVertices()[i][0], mesh->getVertices()[i][1], mesh->getVertices()[i][2]);
00104 }
00105 delete mesh;
00106 }
00107 }
00108 }
00109
00110 template <class BasicMapping>
00111 int RigidMapping<BasicMapping>::addPoint(const Coord& c)
00112 {
00113 int i = points.getValue().size();
00114 points.beginEdit()->push_back(c);
00115 return i;
00116 }
00117
00118 template <class BasicMapping>
00119 int RigidMapping<BasicMapping>::addPoint(const Coord& c, int indexFrom)
00120 {
00121 int i = points.getValue().size();
00122 points.beginEdit()->push_back(c);
00123 if (!repartition.getValue().empty())
00124 {
00125 repartition.beginEdit()->push_back(indexFrom);
00126 repartition.endEdit();
00127 }
00128 else if (!i)
00129 {
00130 index.setValue(indexFrom);
00131 }
00132 else if ((int)index.getValue() != indexFrom)
00133 {
00134 sofa::helper::vector<unsigned int>& rep = *repartition.beginEdit();
00135 rep.clear();
00136 rep.reserve(i+1);
00137 rep.insert(rep.end(),index.getValue(),i);
00138 rep.push_back(indexFrom);
00139 repartition.endEdit();
00140 }
00141 return i;
00142 }
00143
00144 template <class BasicMapping>
00145 void RigidMapping<BasicMapping>::init()
00146 {
00147
00148 if (this->points.getValue().empty() && this->toModel!=NULL && !useX0.getValue())
00149 {
00150 VecCoord& x = *this->toModel->getX();
00151
00152 points.beginEdit()->resize(x.size());
00153 for (unsigned int i=0;i<x.size();i++)
00154 (*points.beginEdit())[i] = x[i];
00155 }
00156
00157 this->BasicMapping::init();
00158
00159 }
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174 template <class BasicMapping>
00175 void RigidMapping<BasicMapping>::clear(int reserve)
00176 {
00177 this->points.beginEdit()->clear();
00178 if (reserve) this->points.beginEdit()->reserve(reserve);
00179 this->repartition.beginEdit()->clear();
00180 this->repartition.endEdit();
00181 }
00182
00183 template <class BasicMapping>
00184 void RigidMapping<BasicMapping>::setRepartition(unsigned int value)
00185 {
00186 vector<unsigned int>& rep = *this->repartition.beginEdit();
00187 rep.clear();
00188 rep.push_back(value);
00189 this->repartition.endEdit();
00190 }
00191
00192 template <class BasicMapping>
00193 void RigidMapping<BasicMapping>::setRepartition(sofa::helper::vector<unsigned int> values)
00194 {
00195 vector<unsigned int>& rep = *this->repartition.beginEdit();
00196 rep.clear();
00197 rep.reserve(values.size());
00198
00199 sofa::helper::vector<unsigned int>::iterator it = values.begin();
00200 while (it != values.end()){
00201 rep.push_back(*it);
00202 it++;
00203 }
00204 this->repartition.endEdit();
00205 }
00206
00207 template<class DataTypes>
00208 const typename DataTypes::VecCoord* M_getX0(core::componentmodel::behavior::MechanicalState<DataTypes>* model)
00209 {
00210 return model->getX0();
00211 }
00212
00213 template<class DataTypes>
00214 const typename DataTypes::VecCoord* M_getX0(core::componentmodel::behavior::MappedModel<DataTypes>* )
00215 {
00216 return NULL;
00217 }
00218
00219 template <class BasicMapping>
00220 const typename RigidMapping<BasicMapping>::VecCoord & RigidMapping<BasicMapping>::getPoints()
00221 {
00222 if(useX0.getValue())
00223 {
00224 const VecCoord* v = M_getX0(this->toModel);
00225 if (v) return *v;
00226 else std::cerr << "RigidMapping: ERROR useX0 can only be used in MechanicalMappings." << std::endl;
00227 }
00228 return points.getValue();
00229 }
00230
00231 template <class BasicMapping>
00232 void RigidMapping<BasicMapping>::apply( typename Out::VecCoord& out, const typename In::VecCoord& in )
00233 {
00234
00235 unsigned int cptOut;
00236 unsigned int val;
00237 Coord translation;
00238 Mat rotation;
00239
00240 const VecCoord& pts = this->getPoints();
00241
00242 rotatedPoints.resize(pts.size());
00243 out.resize(pts.size());
00244
00245 switch (repartition.getValue().size())
00246 {
00247 case 0 :
00248 translation = in[index.getValue()].getCenter();
00249 in[index.getValue()].writeRotationMatrix(rotation);
00250
00251 for(unsigned int i=0;i<pts.size();i++)
00252 {
00253 rotatedPoints[i] = rotation*pts[i];
00254 out[i] = rotatedPoints[i];
00255 out[i] += translation;
00256 }
00257 break;
00258
00259 case 1 :
00260 val = repartition.getValue()[0];
00261
00262 cptOut=0;
00263
00264 for (unsigned int ifrom=0 ; ifrom<in.size() ; ifrom++){
00265 translation = in[ifrom].getCenter();
00266 in[ifrom].writeRotationMatrix(rotation);
00267
00268 for(unsigned int ito=0; ito<val; ito++){
00269 rotatedPoints[cptOut] = rotation* pts[cptOut];
00270 out[cptOut] = rotatedPoints[cptOut];
00271 out[cptOut] += translation;
00272 cptOut++;
00273 }
00274 }
00275 break;
00276
00277 default:
00278 if (repartition.getValue().size() != in.size()){
00279 std::cerr<<"Error : mapping dofs repartition is not correct"<<std::endl;
00280 return;
00281 }
00282 cptOut=0;
00283
00284 for (unsigned int ifrom=0 ; ifrom<in.size() ; ifrom++){
00285 translation = in[ifrom].getCenter();
00286 in[ifrom].writeRotationMatrix(rotation);
00287
00288 for(unsigned int ito=0; ito<repartition.getValue()[ifrom]; ito++){
00289 rotatedPoints[cptOut] = rotation* pts[cptOut];
00290 out[cptOut] = rotatedPoints[cptOut];
00291 out[cptOut] += translation;
00292 cptOut++;
00293 }
00294 }
00295 break;
00296 }
00297 }
00298
00299 template <class BasicMapping>
00300 void RigidMapping<BasicMapping>::applyJ( typename Out::VecDeriv& out, const typename In::VecDeriv& in )
00301 {
00302 Deriv v,omega;
00303 const VecCoord& pts = this->getPoints();
00304 out.resize(pts.size());
00305 unsigned int cptOut;
00306 unsigned int val;
00307
00308 switch (repartition.getValue().size())
00309 {
00310 case 0:
00311 v = in[index.getValue()].getVCenter();
00312 omega = in[index.getValue()].getVOrientation();
00313 for(unsigned int i=0;i<pts.size();i++)
00314 {
00315
00316
00317 out[i] = v - cross(rotatedPoints[i],omega);
00318 }
00319 break;
00320 case 1:
00321 val = repartition.getValue()[0];
00322 cptOut=0;
00323
00324 for (unsigned int ifrom=0 ; ifrom<in.size() ; ifrom++){
00325 v = in[ifrom].getVCenter();
00326 omega = in[ifrom].getVOrientation();
00327
00328 for(unsigned int ito=0; ito<val; ito++){
00329
00330
00331 out[cptOut] = v - cross(rotatedPoints[cptOut],omega);
00332 cptOut++;
00333 }
00334 }
00335 break;
00336 default:
00337 if (repartition.getValue().size() != in.size()){
00338 std::cerr<<"Error : mapping dofs repartition is not correct"<<std::endl;
00339 return;
00340 }
00341
00342 cptOut=0;
00343
00344 for (unsigned int ifrom=0 ; ifrom<in.size() ; ifrom++){
00345 v = in[ifrom].getVCenter();
00346 omega = in[ifrom].getVOrientation();
00347
00348 for(unsigned int ito=0; ito<repartition.getValue()[ifrom]; ito++){
00349
00350
00351 out[cptOut] = v - cross(rotatedPoints[cptOut],omega);
00352 cptOut++;
00353 }
00354 }
00355 break;
00356 }
00357
00358 }
00359
00360 template <class BasicMapping>
00361 void RigidMapping<BasicMapping>::applyJT( typename In::VecDeriv& out, const typename Out::VecDeriv& in )
00362 {
00363 Deriv v,omega;
00364 unsigned int val;
00365 unsigned int cpt;
00366 const VecCoord& pts = this->getPoints();
00367 switch(repartition.getValue().size())
00368 {
00369 case 0 :
00370 for(unsigned int i=0;i<pts.size();i++){
00371
00372
00373
00374
00375
00376 Deriv f = in[i];
00377
00378 v += f;
00379 omega += cross(rotatedPoints[i],f);
00380
00381
00382 }
00383 out[index.getValue()].getVCenter() += v;
00384 out[index.getValue()].getVOrientation() += omega;
00385 break;
00386 case 1 :
00387 val = repartition.getValue()[0];
00388 cpt=0;
00389 for(unsigned int ito=0;ito<out.size();ito++){
00390 v=Deriv();
00391 omega=Deriv();
00392 for(unsigned int i=0;i<val;i++){
00393 Deriv f = in[cpt];
00394 v += f;
00395 omega += cross(rotatedPoints[cpt],f);
00396 cpt++;
00397 }
00398 out[ito].getVCenter() += v;
00399 out[ito].getVOrientation() += omega;
00400 }
00401 break;
00402 default :
00403 if (repartition.getValue().size() != out.size()){
00404 std::cerr<<"Error : mapping dofs repartition is not correct"<<std::endl;
00405 return;
00406 }
00407
00408 cpt=0;
00409 for(unsigned int ito=0;ito<out.size();ito++){
00410 v=Deriv();
00411 omega=Deriv();
00412 for(unsigned int i=0;i<repartition.getValue()[ito];i++){
00413 Deriv f = in[cpt];
00414 v += f;
00415 omega += cross(rotatedPoints[cpt],f);
00416 cpt++;
00417 }
00418 out[ito].getVCenter() += v;
00419 out[ito].getVOrientation() += omega;
00420 }
00421 break;
00422 }
00423
00424 }
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434 template <class BaseMapping>
00435 void RigidMapping<BaseMapping>::applyJT( typename In::VecConst& out, const typename Out::VecConst& in ){
00436
00437
00438
00439 int outSize = out.size();
00440 out.resize(in.size() + outSize);
00441
00442 for(unsigned int i=0; i<in.size(); i++)
00443 {
00444
00445
00446 typename Out::Coord ApplicationPoint;
00447
00448
00449 typename Out::Deriv n;
00450
00451 typename Out::Deriv w_n;
00452
00453
00454 for (unsigned int j=0;j<in[i].size();j++)
00455 {
00456 int index = in[i][j].index;
00457 w_n = (Deriv) in[i][j].data;
00458 double w = w_n.norm();
00459
00460 ApplicationPoint += rotatedPoints[index]*w;
00461
00462 n += w_n ;
00463 }
00464
00465 if (n.norm() < 0.9999 || n.norm() > 1.00001)
00466 printf("\n WARNING : constraint direction is not normalized !!!");
00467
00468
00469
00470
00471 typename Out::Deriv omega_n = cross(ApplicationPoint,n);
00472
00473 InDeriv direction;
00474
00475 direction.getVCenter() = n;
00476 direction.getVOrientation() = omega_n;
00477
00478
00479 out[outSize+i].push_back(InSparseDeriv(index.getValue(), direction));
00480 }
00481 }
00482
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497 #ifndef SOFA_FLOAT
00498 template<>
00499 void RigidMapping< core::componentmodel::behavior::MechanicalMapping< core::componentmodel::behavior::MechanicalState< defaulttype::Rigid2dTypes >, core::componentmodel::behavior::MechanicalState< defaulttype::Vec2dTypes > > >::applyJ( Out::VecDeriv& out, const In::VecDeriv& in );
00500 template<>
00501 void RigidMapping< core::componentmodel::behavior::MechanicalMapping< core::componentmodel::behavior::MechanicalState< defaulttype::Rigid2dTypes >, core::componentmodel::behavior::MechanicalState< defaulttype::Vec2dTypes > > >::applyJT( In::VecDeriv& out, const Out::VecDeriv& in );
00502 template<>
00503 void RigidMapping< core::componentmodel::behavior::MechanicalMapping< core::componentmodel::behavior::MechanicalState< defaulttype::Rigid2dTypes >, core::componentmodel::behavior::MechanicalState< defaulttype::Vec2dTypes > > >::applyJT( In::VecConst& out, const Out::VecConst& in );
00504 #endif
00505 #ifndef SOFA_DOUBLE
00506 template<>
00507 void RigidMapping< core::componentmodel::behavior::MechanicalMapping< core::componentmodel::behavior::MechanicalState< defaulttype::Rigid2fTypes >, core::componentmodel::behavior::MechanicalState< defaulttype::Vec2fTypes > > >::applyJ( Out::VecDeriv& out, const In::VecDeriv& in );
00508 template<>
00509 void RigidMapping< core::componentmodel::behavior::MechanicalMapping< core::componentmodel::behavior::MechanicalState< defaulttype::Rigid2fTypes >, core::componentmodel::behavior::MechanicalState< defaulttype::Vec2fTypes > > >::applyJT( In::VecDeriv& out, const Out::VecDeriv& in );
00510 template<>
00511 void RigidMapping< core::componentmodel::behavior::MechanicalMapping< core::componentmodel::behavior::MechanicalState< defaulttype::Rigid2fTypes >, core::componentmodel::behavior::MechanicalState< defaulttype::Vec2fTypes > > >::applyJT( In::VecConst& out, const Out::VecConst& in );
00512 #endif
00513
00514 #ifndef SOFA_FLOAT
00515 #ifndef SOFA_DOUBLE
00516 template<>
00517 void RigidMapping< core::componentmodel::behavior::MechanicalMapping< core::componentmodel::behavior::MechanicalState< defaulttype::Rigid2fTypes >, core::componentmodel::behavior::MechanicalState< defaulttype::Vec2dTypes > > >::applyJ( Out::VecDeriv& out, const In::VecDeriv& in );
00518 template<>
00519 void RigidMapping< core::componentmodel::behavior::MechanicalMapping< core::componentmodel::behavior::MechanicalState< defaulttype::Rigid2dTypes >, core::componentmodel::behavior::MechanicalState< defaulttype::Vec2fTypes > > >::applyJ( Out::VecDeriv& out, const In::VecDeriv& in );
00520 template<>
00521 void RigidMapping< core::componentmodel::behavior::MechanicalMapping< core::componentmodel::behavior::MechanicalState< defaulttype::Rigid2fTypes >, core::componentmodel::behavior::MechanicalState< defaulttype::Vec2dTypes > > >::applyJT( In::VecDeriv& out, const Out::VecDeriv& in );
00522 template<>
00523 void RigidMapping< core::componentmodel::behavior::MechanicalMapping< core::componentmodel::behavior::MechanicalState< defaulttype::Rigid2dTypes >, core::componentmodel::behavior::MechanicalState< defaulttype::Vec2fTypes > > >::applyJT( In::VecDeriv& out, const Out::VecDeriv& in );
00524 template<>
00525 void RigidMapping< core::componentmodel::behavior::MechanicalMapping< core::componentmodel::behavior::MechanicalState< defaulttype::Rigid2fTypes >, core::componentmodel::behavior::MechanicalState< defaulttype::Vec2dTypes > > >::applyJT( In::VecConst& out, const Out::VecConst& in );
00526 template<>
00527 void RigidMapping< core::componentmodel::behavior::MechanicalMapping< core::componentmodel::behavior::MechanicalState< defaulttype::Rigid2dTypes >, core::componentmodel::behavior::MechanicalState< defaulttype::Vec2fTypes > > >::applyJT( In::VecConst& out, const Out::VecConst& in );
00528 #endif
00529 #endif
00531 // template<typename real1, typename real2>
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548 template <class BasicMapping>
00549 void RigidMapping<BasicMapping>::draw()
00550 {
00551 if (!this->getShow()) return;
00552 glDisable (GL_LIGHTING);
00553 glPointSize(7);
00554 glColor4f (1,1,0,1);
00555 glBegin (GL_POINTS);
00556 const typename Out::VecCoord& x = *this->toModel->getX();
00557 for (unsigned int i=0; i<x.size(); i++)
00558 {
00559 helper::gl::glVertexT(x[i]);
00560 }
00561 glEnd();
00562 }
00563
00564 }
00565
00566 }
00567
00568 }
00569
00570 #endif