BeamLinearMapping.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_BEAMLINEARMAPPING_INL
00026 #define SOFA_COMPONENT_MAPPING_BEAMLINEARMAPPING_INL
00027 
00028 #include <sofa/component/mapping/BeamLinearMapping.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 <string>
00038 
00039 
00040 
00041 namespace sofa
00042 {
00043 
00044 namespace component
00045 {
00046 
00047 namespace mapping
00048 {
00049 
00050 using namespace sofa::defaulttype;
00051 
00052 template <class BasicMapping>
00053 void BeamLinearMapping<BasicMapping>::init()
00054 {
00055     bool local = localCoord.getValue();
00056     if (this->points.empty() && this->toModel!=NULL)
00057     {
00058         typename In::VecCoord& xfrom = *this->fromModel->getX();
00059         beamLength.resize(xfrom.size());
00060         for (unsigned int i=0;i<xfrom.size()-1;i++)
00061                 beamLength[i] = (Real)((xfrom[i]-xfrom[i+1]).norm());
00062         if (xfrom.size()>=2)
00063             beamLength[xfrom.size()-1] = beamLength[xfrom.size()-2];
00064         VecCoord& x = *this->toModel->getX();
00065         std::cout << "BeamLinearMapping: init "<<x.size()<<" points."<<std::endl;
00066         points.resize(x.size());
00067         if (local)
00068         {
00069             for (unsigned int i=0;i<x.size();i++)
00070                 points[i] = x[i];
00071         }
00072         else
00073         {
00074             for (unsigned int i=0;i<x.size();i++)
00075             {
00076                 Coord p = xfrom[0].getOrientation().inverseRotate(x[i]-xfrom[0].getCenter());
00077                 unsigned int j=0;
00078                 while(j<beamLength.size() && p[0]>=beamLength[j])
00079                 {
00080                     p[0] -= beamLength[j];
00081                     ++j;
00082                 }
00083                 p/=beamLength[j];
00084                 p[0]+=j;
00085                 points[i] = p;
00086             }
00087         }
00088     }
00089     this->BasicMapping::init();
00090 }
00091 
00092 template <class BasicMapping>
00093 void BeamLinearMapping<BasicMapping>::apply( typename Out::VecCoord& out, const typename In::VecCoord& in )
00094 {
00095     //translation = in[index.getValue()].getCenter();
00096     //in[index.getValue()].writeRotationMatrix(rotation);
00097     rotatedPoints0.resize(points.size());
00098     rotatedPoints1.resize(points.size());
00099     out.resize(points.size());
00100     for(unsigned int i=0;i<points.size();i++)
00101     {
00102         Coord inpos = points[i];
00103         int in0 = helper::rfloor(inpos[0]);
00104         if (in0<0) in0 = 0; else if (in0 > (int)in.size()-2) in0 = in.size()-2;
00105         inpos[0] -= in0;
00106         rotatedPoints0[i] = in[in0].getOrientation().rotate(inpos) * beamLength[in0];
00107         Coord out0 = in[in0].getCenter() + rotatedPoints0[i];
00108         Coord inpos1 = inpos; inpos1[0] -= 1;
00109     rotatedPoints1[i] = in[in0+1].getOrientation().rotate(inpos1) * beamLength[in0];
00110         Coord out1 = in[in0+1].getCenter() + rotatedPoints1[i];
00111         Real fact = (Real)inpos[0];
00112         fact = 3*(fact*fact)-2*(fact*fact*fact);
00113         out[i] = out0 * (1-fact) + out1 * (fact);
00114     }
00115 }
00116 
00117 template <class BasicMapping>
00118 void BeamLinearMapping<BasicMapping>::applyJ( typename Out::VecDeriv& out, const typename In::VecDeriv& in )
00119 {
00120     //const typename In::VecCoord& x = *this->fromModel->getX(); 
00121     //Deriv v,omega;
00122     //v = in[index.getValue()].getVCenter();
00123     //omega = in[index.getValue()].getVOrientation();
00124     out.resize(points.size());
00125     for(unsigned int i=0;i<points.size();i++)
00126     {
00127         // out = J in
00128         // J = [ I -OM^ ]
00129         //out[i] =  v - cross(rotatedPoints[i],omega);
00130         
00131         defaulttype::Vec<N, typename In::Real> inpos = points[i];
00132         int in0 = helper::rfloor(inpos[0]);
00133         if (in0<0) in0 = 0; else if (in0 > (int)in.size()-2) in0 = in.size()-2;
00134         inpos[0] -= in0;
00135         Deriv omega0 = in[in0].getVOrientation();
00136         Deriv out0 = in[in0].getVCenter() - cross(rotatedPoints0[i], omega0);
00137         Deriv omega1 = in[in0+1].getVOrientation();
00138         Deriv out1 = in[in0+1].getVCenter() - cross(rotatedPoints1[i], omega1);
00139         Real fact = (Real)inpos[0];
00140         fact = 3*(fact*fact)-2*(fact*fact*fact);
00141         out[i] = out0 * (1-fact) + out1 * (fact);
00142     }
00143 }
00144 
00145 template <class BasicMapping>
00146 void BeamLinearMapping<BasicMapping>::applyJT( typename In::VecDeriv& out, const typename Out::VecDeriv& in )
00147 {
00148     //Deriv v,omega;
00149     for(unsigned int i=0;i<points.size();i++)
00150     {
00151         // out = Jt in
00152         // Jt = [ I     ]
00153         //      [ -OM^t ]
00154         // -OM^t = OM^
00155         
00156         //Deriv f = in[i];
00157         //v += f;
00158         //omega += cross(rotatedPoints[i],f);
00159     
00160         defaulttype::Vec<N, typename In::Real> inpos = points[i];
00161         int in0 = helper::rfloor(inpos[0]);
00162         if (in0<0) in0 = 0; else if (in0 > (int)out.size()-2) in0 = out.size()-2;
00163         inpos[0] -= in0;
00164         Deriv f = in[i];
00165         Real fact = (Real)inpos[0];
00166         fact = 3*(fact*fact)-2*(fact*fact*fact);
00167         out[in0].getVCenter() += f * (1-fact);
00168         out[in0].getVOrientation() += cross(rotatedPoints0[i], f) * (1-fact);
00169         out[in0+1].getVCenter() += f * (fact);
00170         out[in0+1].getVOrientation() += cross(rotatedPoints1[i], f) * (fact);
00171     }
00172     //out[index.getValue()].getVCenter() += v;
00173     //out[index.getValue()].getVOrientation() += omega;
00174 }
00175 
00176 
00177 // BeamLinearMapping::applyJT( typename In::VecConst& out, const typename Out::VecConst& in ) //
00178 // this function propagate the constraint through the rigid mapping :
00179 // if one constraint along (vector n) with a value (v) is applied on the childModel (like collision model)
00180 // then this constraint is transformed by (Jt.n) with value (v) for the rigid model
00181 // There is a specificity of this propagateConstraint: we have to find the application point on the childModel
00182 // in order to compute the right constaint on the rigidModel.
00183 template <class BasicMapping>
00184 void BeamLinearMapping<BasicMapping>::applyJT( typename In::VecConst& out, const typename Out::VecConst& in )
00185 {
00186     const typename In::VecCoord& x = *this->fromModel->getX(); 
00187     int outSize = out.size();
00188     out.resize(in.size() + outSize); // we can accumulate in "out" constraints from several mappings
00189 
00190     for(unsigned int i=0; i<in.size(); i++)
00191     {
00192         // computation of (Jt.n) //
00193         // in[i].size() = num node involved in the constraint
00194         for (unsigned int j=0;j<in[i].size();j++)
00195         {
00196             int index = in[i][j].index; // index of the node
00197             // interpolation//////////
00198             defaulttype::Vec<N, typename In::Real> inpos = points[index];
00199             int in0 = helper::rfloor(inpos[0]);
00200             if (in0<0) in0 = 0; else if (in0 > (int)x.size()-2) in0 = x.size()-2;
00201             inpos[0] -= in0;
00202         Real fact = (Real)inpos[0];
00203         fact = 3*(fact*fact)-2*(fact*fact*fact);
00205             Deriv w_n = (Deriv) in[i][j].data;  // weighted value of the constraint direction
00206 
00207             // Compute the mapped Constraint on the beam nodes ///
00208             InDeriv direction0;
00209             direction0.getVCenter() = w_n * (1-fact);
00210             direction0.getVOrientation() = cross(rotatedPoints0[index], w_n) * (1-fact);
00211             InDeriv direction1;
00212             direction1.getVCenter() = w_n * (fact);
00213             direction1.getVOrientation() = cross(rotatedPoints1[index], w_n) * (fact);
00214             out[outSize+i].push_back(InSparseDeriv(in0, direction0));
00215             out[outSize+i].push_back(InSparseDeriv(in0+1, direction1));
00216         }
00217         
00218     }
00219 }
00220 
00221 template <class BasicMapping>
00222 void BeamLinearMapping<BasicMapping>::draw()
00223 {
00224     if (!this->getShow()) return;
00225     glDisable (GL_LIGHTING);
00226     glPointSize(7);
00227     glColor4f (1,1,0,1);
00228     glBegin (GL_POINTS);
00229     const typename Out::VecCoord& x = *this->toModel->getX();
00230     for (unsigned int i=0; i<x.size(); i++)
00231     {
00232         helper::gl::glVertexT(x[i]);
00233     }
00234     glEnd();
00235 }
00236 
00237 } // namespace mapping
00238 
00239 } // namespace component
00240 
00241 } // namespace sofa
00242 
00243 #endif

Generated on Sun Nov 23 03:31:51 2008 for Sofa by  doxygen 1.5.7.1