RigidRigidMapping.inl
Go to the documentation of this file.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_RIGIDRIGIDMAPPING_INL
00026 #define SOFA_COMPONENT_MAPPING_RIGIDRIGIDMAPPING_INL
00027
00028 #include <sofa/component/mapping/RigidRigidMapping.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/helper/gl/Axis.h>
00038 #include <string.h>
00039 #include <iostream>
00040
00041 using std::cerr;
00042 using std::endl;
00043
00044
00045
00046 namespace sofa
00047 {
00048
00049 namespace component
00050 {
00051
00052 namespace mapping
00053 {
00054
00055 using namespace sofa::defaulttype;
00056
00057 template <class BasicMapping>
00058 class RigidRigidMapping<BasicMapping>::Loader : public helper::io::MassSpringLoader, public helper::io::SphereLoader
00059 {
00060 public:
00061 RigidRigidMapping<BasicMapping>* dest;
00062 Loader(RigidRigidMapping<BasicMapping>* dest) : dest(dest) {}
00063 virtual void addMass(SReal px, SReal py, SReal pz, SReal, SReal, SReal, SReal, SReal, bool, bool)
00064 {
00065 Coord c;
00066 Out::DataTypes::set(c,px,py,pz);
00067 dest->points.beginEdit()->push_back(c);
00068 }
00069 virtual void addSphere(SReal px, SReal py, SReal pz, SReal)
00070 {
00071 Coord c;
00072 Out::DataTypes::set(c,px,py,pz);
00073 dest->points.beginEdit()->push_back(c);
00074 }
00075 };
00076
00077 template <class BasicMapping>
00078 void RigidRigidMapping<BasicMapping>::load(const char *filename)
00079 {
00080 points.beginEdit()->resize(0);
00081
00082 if (strlen(filename)>4 && !strcmp(filename+strlen(filename)-4,".xs3"))
00083 {
00084 Loader loader(this);
00085 loader.helper::io::MassSpringLoader::load(filename);
00086 }
00087 else
00088 if (strlen(filename)>4 && !strcmp(filename+strlen(filename)-4,".sph"))
00089 {
00090 Loader loader(this);
00091 loader.helper::io::SphereLoader::load(filename);
00092 }
00093 else if (strlen(filename)>0)
00094 {
00095 helper::io::Mesh* mesh = helper::io::Mesh::Create(filename);
00096 if (mesh!=NULL)
00097 {
00098 points.beginEdit()->resize(mesh->getVertices().size());
00099 for (unsigned int i=0;i<mesh->getVertices().size();i++)
00100 {
00101 Out::DataTypes::set((*points.beginEdit())[i], mesh->getVertices()[i][0], mesh->getVertices()[i][1], mesh->getVertices()[i][2]);
00102 }
00103 delete mesh;
00104 }
00105 }
00106 }
00107
00108 template <class BasicMapping>
00109 void RigidRigidMapping<BasicMapping>::init()
00110 {
00111 if (this->points.getValue().empty() && this->toModel!=NULL)
00112 {
00113 VecCoord& x = *this->toModel->getX();
00114 points.beginEdit()->resize(x.size());
00115 for (unsigned int i=0;i<x.size();i++)
00116 (*points.beginEdit())[i] = x[i];
00117 }
00118 this->BasicMapping::init();
00119 }
00120
00121 template <class BasicMapping>
00122 void RigidRigidMapping<BasicMapping>::clear()
00123 {
00124 (*this->points.beginEdit()).clear();
00125 }
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141 template <class BasicMapping>
00142 void RigidRigidMapping<BasicMapping>::setRepartition(unsigned int value)
00143 {
00144 vector<unsigned int>& rep = *this->repartition.beginEdit();
00145 rep.clear();
00146 rep.push_back(value);
00147 this->repartition.endEdit();
00148 }
00149
00150 template <class BasicMapping>
00151 void RigidRigidMapping<BasicMapping>::setRepartition(sofa::helper::vector<unsigned int> values)
00152 {
00153 vector<unsigned int>& rep = *this->repartition.beginEdit();
00154 rep.clear();
00155 rep.reserve(values.size());
00156
00157 sofa::helper::vector<unsigned int>::iterator it = values.begin();
00158 while (it != values.end()){
00159 rep.push_back(*it);
00160 it++;
00161 }
00162 this->repartition.endEdit();
00163 }
00164
00165 template <class BasicMapping>
00166 void RigidRigidMapping<BasicMapping>::apply( typename Out::VecCoord& out, const typename In::VecCoord& in )
00167 {
00168 unsigned int cptOut;
00169 unsigned int val;
00170
00171 out.resize(points.getValue().size());
00172 pointsR0.resize(points.getValue().size());
00173
00174 switch (repartition.getValue().size())
00175 {
00176 case 0 :
00177 in[index.getValue()].writeRotationMatrix(rotation);
00178 for(unsigned int i=0;i<points.getValue().size();i++){
00179 pointsR0[i].getCenter() = rotation*(points.getValue()[i]).getCenter();
00180 out[i] = in[index.getValue()].mult(points.getValue()[i]);
00181 }
00182 break;
00183
00184 case 1 :
00185 val = repartition.getValue()[0];
00186 cptOut=0;
00187
00188 for (unsigned int ifrom=0 ; ifrom<in.size() ; ifrom++){
00189 in[ifrom].writeRotationMatrix(rotation);
00190 for(unsigned int ito=0; ito<val; ito++){
00191 pointsR0[cptOut].getCenter() = rotation*(points.getValue()[cptOut]).getCenter();
00192 out[cptOut] = in[ifrom].mult(points.getValue()[cptOut]);
00193 cptOut++;
00194 }
00195 }
00196 break;
00197
00198 default:
00199 if (repartition.getValue().size() != in.size()){
00200 std::cerr<<"Error : mapping dofs repartition.getValue() is not correct"<<std::endl;
00201 return;
00202 }
00203 cptOut=0;
00204
00205 for (unsigned int ifrom=0 ; ifrom<in.size() ; ifrom++){
00206 in[ifrom].writeRotationMatrix(rotation);
00207 for(unsigned int ito=0; ito<repartition.getValue()[ifrom]; ito++){
00208 pointsR0[cptOut].getCenter() = rotation*(points.getValue()[cptOut]).getCenter();
00209 out[cptOut] = in[ifrom].mult(points.getValue()[cptOut]);
00210 cptOut++;
00211 }
00212 }
00213 break;
00214 }
00215 }
00216
00217 template <class BasicMapping>
00218 void RigidRigidMapping<BasicMapping>::applyJ( typename Out::VecDeriv& childForces, const typename In::VecDeriv& parentForces )
00219 {
00220 Vector v,omega;
00221 childForces.resize(points.getValue().size());
00222 unsigned int cptchildForces;
00223 unsigned int val;
00224
00225 switch (repartition.getValue().size())
00226 {
00227 case 0:
00228 v = parentForces[index.getValue()].getVCenter();
00229 omega = parentForces[index.getValue()].getVOrientation();
00230 for(unsigned int i=0;i<points.getValue().size();i++){
00231 childForces[i].getVCenter() = v + cross(omega,pointsR0[i].getCenter());
00232 childForces[i].getVOrientation() = omega;
00233 }
00234 break;
00235
00236 case 1:
00237 val = repartition.getValue()[0];
00238 cptchildForces=0;
00239 for (unsigned int ifrom=0 ; ifrom<parentForces.size() ; ifrom++){
00240 v = parentForces[ifrom].getVCenter();
00241 omega = parentForces[ifrom].getVOrientation();
00242
00243 for(unsigned int ito=0; ito<val; ito++){
00244 childForces[cptchildForces].getVCenter() = v + cross(omega,(pointsR0[cptchildForces]).getCenter());
00245 childForces[cptchildForces].getVOrientation() = omega;
00246 cptchildForces++;
00247 }
00248 }
00249 break;
00250
00251 default:
00252 if (repartition.getValue().size() != parentForces.size()){
00253 std::cerr<<"Error : mapping dofs repartition.getValue() is not correct"<<std::endl;
00254 return;
00255 }
00256 cptchildForces=0;
00257 for (unsigned int ifrom=0 ; ifrom<parentForces.size() ; ifrom++){
00258 v = parentForces[ifrom].getVCenter();
00259 omega = parentForces[ifrom].getVOrientation();
00260
00261 for(unsigned int ito=0; ito<repartition.getValue()[ifrom]; ito++){
00262 childForces[cptchildForces].getVCenter() = v + cross(omega,(pointsR0[cptchildForces]).getCenter());
00263 childForces[cptchildForces].getVOrientation() = omega;
00264 cptchildForces++;
00265 }
00266 }
00267 break;
00268 }
00269
00270 }
00271
00272
00273 template <class BasicMapping>
00274 void RigidRigidMapping<BasicMapping>::applyJT( typename In::VecDeriv& parentForces, const typename Out::VecDeriv& childForces )
00275 {
00276 Vector v,omega;
00277 unsigned int val;
00278 unsigned int cpt;
00279 switch(repartition.getValue().size())
00280 {
00281 case 0 :
00282 for(unsigned int i=0;i<points.getValue().size();i++){
00283
00284
00285
00286
00287
00288 Vector f = childForces[i].getVCenter();
00289 v += f;
00290 omega += childForces[i].getVOrientation() + cross(f,-pointsR0[i].getCenter());
00291 }
00292 parentForces[index.getValue()].getVCenter() += v;
00293 parentForces[index.getValue()].getVOrientation() += omega;
00294 break;
00295 case 1 :
00296 val = repartition.getValue()[0];
00297 cpt=0;
00298 for(unsigned int ito=0;ito<parentForces.size();ito++){
00299 v=Vector();
00300 omega=Vector();
00301 for(unsigned int i=0;i<val;i++){
00302 Vector f = childForces[cpt].getVCenter();
00303 v += f;
00304 omega += childForces[cpt].getVOrientation() + cross(f,-pointsR0[cpt].getCenter());
00305 cpt++;
00306 }
00307 parentForces[ito].getVCenter() += v;
00308 parentForces[ito].getVOrientation() += omega;
00309 }
00310 break;
00311 default :
00312 if (repartition.getValue().size() != parentForces.size()){
00313 std::cerr<<"Error : mapping dofs repartition.getValue() is not correct"<<std::endl;
00314 return;
00315 }
00316 cpt=0;
00317 for(unsigned int ito=0;ito<parentForces.size();ito++){
00318 v=Vector();
00319 omega=Vector();
00320 for(unsigned int i=0;i<repartition.getValue()[ito];i++){
00321 Vector f = childForces[cpt].getVCenter();
00322 v += f;
00323 omega += childForces[cpt].getVOrientation() + cross(f,-pointsR0[cpt].getCenter());
00324 cpt++;
00325 }
00326 parentForces[ito].getVCenter() += v;
00327 parentForces[ito].getVOrientation() += omega;
00328
00329 }
00330 break;
00331 }
00332
00333 }
00334
00335
00336 template <class BasicMapping>
00337 void RigidRigidMapping<BasicMapping>::draw()
00338 {
00339 if (!getShow(this)) return;
00340 const typename Out::VecCoord& x = *this->toModel->getX();
00341 for (unsigned int i=0; i<x.size(); i++)
00342 {
00343 helper::gl::Axis::draw(x[i].getCenter(), x[i].getOrientation(), axisLength.getValue());
00344 }
00345 glEnd();
00346 }
00347
00348 }
00349
00350 }
00351
00352 }
00353
00354 #endif