BeamLinearMapping.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_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
00096
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
00121
00122
00123
00124 out.resize(points.size());
00125 for(unsigned int i=0;i<points.size();i++)
00126 {
00127
00128
00129
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
00149 for(unsigned int i=0;i<points.size();i++)
00150 {
00151
00152
00153
00154
00155
00156
00157
00158
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
00173
00174 }
00175
00176
00177
00178
00179
00180
00181
00182
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);
00189
00190 for(unsigned int i=0; i<in.size(); i++)
00191 {
00192
00193
00194 for (unsigned int j=0;j<in[i].size();j++)
00195 {
00196 int index = in[i][j].index;
00197
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;
00206
00207
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 }
00238
00239 }
00240
00241 }
00242
00243 #endif