RigidRigidMapping.inl

Go to the documentation of this file.
00001 /******************************************************************************
00002 *       SOFA, Simulation Open-Framework Architecture, version 1.0 beta 3      *
00003 *                (c) 2006-2008 MGH, INRIA, USTL, UJF, CNRS                    *
00004 *                                                                             *
00005 * This library is free software; you can redistribute it and/or modify it     *
00006 * under the terms of the GNU Lesser General Public License as published by    *
00007 * the Free Software Foundation; either version 2.1 of the License, or (at     *
00008 * your option) any later version.                                             *
00009 *                                                                             *
00010 * This library is distributed in the hope that it will be useful, but WITHOUT *
00011 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       *
00012 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
00013 * for more details.                                                           *
00014 *                                                                             *
00015 * You should have received a copy of the GNU Lesser General Public License    *
00016 * along with this library; if not, write to the Free Software Foundation,     *
00017 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.          *
00018 *******************************************************************************
00019 *                               SOFA :: Modules                               *
00020 *                                                                             *
00021 * Authors: The SOFA Team and external contributors (see Authors.txt)          *
00022 *                                                                             *
00023 * Contact information: contact@sofa-framework.org                             *
00024 ******************************************************************************/
00025 #ifndef SOFA_COMPONENT_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); //Coord((Real)px,(Real)py,(Real)pz));
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); //Coord((Real)px,(Real)py,(Real)pz));
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     { // Default to mesh loader
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 template <class BasicMapping>
00129 void RigidRigidMapping<BasicMapping>::disable()
00130 {
00131     if (!this->points.getValue().empty() && this->toModel!=NULL)
00132     {
00133         VecCoord& x = *this->toModel->getX();
00134         x.resize(points.getValue().size());
00135         for (unsigned int i=0;i<points.getValue().size();i++)
00136             x[i] = points.getValue()[i];
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     //repartition.setValue(values);
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 : //no value specified : simple rigid mapping
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 : //one value specified : uniform repartition.getValue() mapping on the input dofs
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: //n values are specified : heterogen repartition.getValue() mapping on the input dofs
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             // out = Jt in
00284             // Jt = [ I     ]
00285             //      [ -OM^t ]
00286             // -OM^t = OM^
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 } // namespace mapping
00349 
00350 } // namespace component
00351 
00352 } // namespace sofa
00353 
00354 #endif

Generated on Sun Nov 23 03:33:53 2008 for Sofa by  doxygen 1.5.7.1