LineSetSkinningMapping.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 
00026 #ifndef SOFA_COMPONENT_MAPPING_LINESETSKINNINGMAPPING_INL
00027 #define SOFA_COMPONENT_MAPPING_LINESETSKINNINGMAPPING_INL
00028 
00029 #include <sofa/component/mapping/LineSetSkinningMapping.h>
00030 
00031 namespace sofa
00032 {
00033 
00034 namespace component
00035 {
00036 
00037 namespace mapping
00038 {
00039 
00040 template <class BasicMapping>
00041 Vec<3,double> LineSetSkinningMapping<BasicMapping>::projectToSegment( Vec<3,Real>& first, Vec<3,Real>& last, OutCoord& vertice)
00042 {
00043     Vec3d segment,v_f,v_l;
00044 
00045     segment = last - first;
00046     v_f = vertice-first;
00047     v_l = vertice-last;
00048 
00049     if(v_f*segment>0.0 && -segment*v_l>0.0)
00050     {
00051         double prod = v_f*segment;
00052         return first + (segment * (prod/segment.norm2()));
00053     }
00054     else 
00055     {
00056         if (v_l.norm() > v_f.norm())
00057             return first;
00058         else
00059             return last;
00060     }
00061 }
00062 
00063 template <class BasicMapping>
00064 double LineSetSkinningMapping<BasicMapping>::convolutionSegment(Vec<3,Real>& first, Vec<3,Real>& last, OutCoord& vertice)
00065 {
00066     int steps = 1000;
00067     double sum = 0.0;
00068     Vec<3,Real> dist, line;
00069 
00070     line=last-first;
00071 
00072     // False integration
00073     for(int i=0; i<=steps; i++)
00074     {
00075         dist = ((line * i) / steps) + first - vertice;
00076         sum += pow(1/dist.norm(),weightCoef.getValue());
00077     }
00078 
00079     sum *= line.norm()/steps;
00080     return sum;
00081 }
00082 
00083 template <class BasicMapping>
00084 void LineSetSkinningMapping<BasicMapping>::init()
00085 {
00086     OutVecCoord& xto = *this->toModel->getX();
00087     InVecCoord& xfrom = *this->fromModel->getX();   
00088     t = this->fromModel->getContext()->getMeshTopology();
00089     linesInfluencedByVertice.resize(xto.size());
00090 
00091     verticesInfluencedByLine.resize(t->getNbLines());
00092 
00093     neighborhoodLinesSet.resize(t->getNbLines());
00094     neighborhood.resize(t->getNbLines());
00095 
00096     for(unsigned int line1Index=0; line1Index< (unsigned) t->getNbLines(); line1Index++)
00097     {
00098         const sofa::core::componentmodel::topology::BaseMeshTopology::Line& line1 = t->getLine(line1Index);
00099         for(unsigned int line2Index=0; line2Index< (unsigned) t->getNbLines(); line2Index++)
00100         {
00101             const sofa::core::componentmodel::topology::BaseMeshTopology::Line& line2 = t->getLine(line2Index);
00102             if ((line1[0] == line2[0]) || (line1[0] == line2[1]) || (line1[1] == line2[0]))
00103             {
00104                 neighborhoodLinesSet[line1Index].insert(line2Index);
00105             }
00106         }
00107     }
00108 
00109     for(unsigned int line1Index=0; line1Index< (unsigned) t->getNbLines(); line1Index++)
00110     {
00111         std::set<int> result;
00112         std::insert_iterator<std::set<int> > res_ins(result, result.begin());
00113 
00114         neighborhood[line1Index] = neighborhoodLinesSet[line1Index];
00115 
00116         for(unsigned int i=0; i<nvNeighborhood.getValue()-1; i++)
00117         {
00118             for (std::set<int>::const_iterator it = neighborhood[line1Index].begin(), itbegin = it, itend = neighborhood[line1Index].end(); it != itend; it++)
00119             {
00120                 set_union(itbegin, itend, neighborhoodLinesSet[(*it)].begin(), neighborhoodLinesSet[(*it)].end(), res_ins);
00121             }
00122 
00123             neighborhood[line1Index] = result;
00124         }
00125     }
00126 
00127     for(unsigned int verticeIndex=0; verticeIndex<xto.size(); verticeIndex++)
00128     {
00129         double  sumWeights = 0.0;
00130         vector<influencedLineType> lines;
00131         lines.resize(t->getNbLines());
00132 
00133         for(unsigned int lineIndex=0; lineIndex< (unsigned) t->getNbLines(); lineIndex++)
00134         {
00135             const sofa::core::componentmodel::topology::BaseMeshTopology::Line& line = t->getLine(lineIndex);
00136             double _weight = convolutionSegment(xfrom[line[0]].getCenter(), xfrom[line[1]].getCenter(), xto[verticeIndex]);
00137 
00138             for(unsigned int lineInfluencedIndex=0; lineInfluencedIndex<lines.size(); lineInfluencedIndex++)
00139             {
00140                 if(lines[lineInfluencedIndex].weight <= _weight)
00141                 {
00142                     for(unsigned int i=lines.size()-1; i > lineInfluencedIndex; i--)
00143                     {
00144                         lines[i].lineIndex = lines[i-1].lineIndex;
00145                         lines[i].weight = lines[i-1].weight;
00146                         lines[i].position = lines[i-1].position;
00147                     }
00148                     lines[lineInfluencedIndex].lineIndex = lineIndex;
00149                     lines[lineInfluencedIndex].weight = _weight;
00150                     lines[lineInfluencedIndex].position = xfrom[line[0]].getOrientation().inverseRotate(xto[verticeIndex] - xfrom[line[0]].getCenter());
00151                     break;
00152                 }
00153             }
00154         }
00155 
00156         unsigned int lineInfluencedIndex = 0;
00157         int max = lines[lineInfluencedIndex].lineIndex;
00158         sumWeights += lines[lineInfluencedIndex].weight;
00159         linesInfluencedByVertice[verticeIndex].push_back(lines[lineInfluencedIndex]);
00160         influencedVerticeType vertice;
00161         vertice.verticeIndex = verticeIndex;
00162         vertice.weight = lines[lineInfluencedIndex].weight;
00163         vertice.position = lines[lineInfluencedIndex].position;
00164         verticesInfluencedByLine[lineInfluencedIndex].push_back(vertice);
00165 
00166         lineInfluencedIndex++;
00167 
00168         while (linesInfluencedByVertice[verticeIndex].size() < numberInfluencedLines.getValue() && lineInfluencedIndex < lines.size())
00169         {
00170             if (neighborhood[max].count(lines[lineInfluencedIndex].lineIndex) != 0)
00171             {
00172                 sumWeights += lines[lineInfluencedIndex].weight;
00173                 linesInfluencedByVertice[verticeIndex].push_back(lines[lineInfluencedIndex]);
00174                 vertice.verticeIndex = verticeIndex;
00175                 vertice.weight = lines[lineInfluencedIndex].weight;
00176                 vertice.position = lines[lineInfluencedIndex].position;
00177                 verticesInfluencedByLine[lineInfluencedIndex].push_back(vertice);
00178             }
00179             lineInfluencedIndex++;
00180         }
00181 
00182         for (unsigned int influencedLineIndex=0; influencedLineIndex<linesInfluencedByVertice[verticeIndex].size(); influencedLineIndex++)
00183                 linesInfluencedByVertice[verticeIndex][influencedLineIndex].weight /= sumWeights;
00184     }
00185 }
00186 
00187 template <class BasicMapping>
00188 void LineSetSkinningMapping<BasicMapping>::reinit()
00189 {
00190     linesInfluencedByVertice.clear();
00191     verticesInfluencedByLine.clear();
00192     neighborhoodLinesSet.clear();
00193     neighborhood.clear();
00194 
00195     init();
00196 }
00197 
00198 template <class BasicMapping>
00199 void LineSetSkinningMapping<BasicMapping>::draw()
00200 {
00201     //if (!getShow(this)) return;
00202     //glDisable (GL_LIGHTING);
00203     //glLineWidth(1);
00204 
00205     //glBegin (GL_LINES);
00206 
00207     //OutVecCoord& xto = *this->toModel->getX();
00208     //InVecCoord& xfrom = *this->fromModel->getX(); 
00209 
00210     //for(unsigned int verticeIndex=0; verticeIndex<xto.size(); verticeIndex++)
00211     //{
00212     //  const sofa::core::componentmodel::topology::BaseMeshTopology::Line& line = t->getLine(linesInfluencedByVertice[verticeIndex][0].lineIndex);
00213     //  Vec<3,Real> v = projectToSegment(xfrom[line[0]].getCenter(), xfrom[line[1]].getCenter(), xto[verticeIndex]);
00214 
00215     //  glColor3f (1,0,0);
00216     //  helper::gl::glVertexT(xto[verticeIndex]);
00217     //  helper::gl::glVertexT(v);
00218 
00219     //  for(unsigned int i=1; i<linesInfluencedByVertice[verticeIndex].size(); i++)
00220     //  {
00221     //      const sofa::core::componentmodel::topology::BaseMeshTopology::Line& l = t->getLine(linesInfluencedByVertice[verticeIndex][i].lineIndex);
00222     //      Vec<3,Real> v = projectToSegment(xfrom[l[0]].getCenter(), xfrom[l[1]].getCenter(), xto[verticeIndex]);
00223 
00224     //      glColor3f (0,0,1);
00225     //      helper::gl::glVertexT(xto[verticeIndex]);
00226     //      helper::gl::glVertexT(v);
00227     //  }
00228     //}
00229     //glEnd();
00230 }
00231 
00232 template <class BasicMapping>
00233 void LineSetSkinningMapping<BasicMapping>::apply( typename Out::VecCoord& out, const typename In::VecCoord& in )
00234 {       
00235     for (unsigned int verticeIndex=0; verticeIndex<out.size(); verticeIndex++)
00236     {
00237         out[verticeIndex] = typename Out::Coord();
00238         for (unsigned int lineInfluencedIndex=0; lineInfluencedIndex<linesInfluencedByVertice[verticeIndex].size(); lineInfluencedIndex++)
00239         {
00240             influencedLineType iline = linesInfluencedByVertice[verticeIndex][lineInfluencedIndex];
00241             out[verticeIndex] += in[t->getLine(iline.lineIndex)[0]].getCenter()*iline.weight;
00242             out[verticeIndex] += in[t->getLine(iline.lineIndex)[0]].getOrientation().rotate(iline.position*iline.weight);
00243         }
00244     }       
00245 }
00246 
00247 template <class BasicMapping>
00248 void LineSetSkinningMapping<BasicMapping>::applyJ( typename Out::VecDeriv& out, const typename In::VecDeriv& in )
00249 {
00250     InVecCoord& xfrom = *this->fromModel->getX();
00251 
00252     for (unsigned int verticeIndex=0; verticeIndex<out.size(); verticeIndex++)
00253     {
00254         out[verticeIndex] = typename Out::Deriv();      
00255         for (unsigned int lineInfluencedIndex=0; lineInfluencedIndex<linesInfluencedByVertice[verticeIndex].size(); lineInfluencedIndex++)
00256         {
00257             influencedLineType iline = linesInfluencedByVertice[verticeIndex][lineInfluencedIndex];
00258             Vec<3,Real> IP = xfrom[t->getLine(iline.lineIndex)[0]].getOrientation().rotate(iline.position);
00259             out[verticeIndex] += (in[t->getLine(iline.lineIndex)[0]].getVCenter() - IP.cross(in[t->getLine(iline.lineIndex)[0]].getVOrientation())) * iline.weight;
00260         }
00261     }   
00262 }
00263 
00264 
00265 template <class BasicMapping>
00266 void LineSetSkinningMapping<BasicMapping>::applyJT( typename In::VecDeriv& out, const typename Out::VecDeriv& in )
00267 {
00268     InVecCoord& xfrom = *this->fromModel->getX();
00269 
00270     for(unsigned int lineIndex=0; lineIndex< (unsigned) t->getNbLines(); lineIndex++)
00271     {
00272         for (unsigned int verticeInfluencedIndex=0; verticeInfluencedIndex<verticesInfluencedByLine[lineIndex].size(); verticeInfluencedIndex++)
00273         {
00274             influencedVerticeType vertice = verticesInfluencedByLine[lineIndex][verticeInfluencedIndex];
00275             Vec<3,Real> IP = xfrom[t->getLine(lineIndex)[0]].getOrientation().rotate(vertice.position);
00276             out[vertice.verticeIndex].getVCenter() += in[vertice.verticeIndex] * vertice.weight;
00277             out[vertice.verticeIndex].getVOrientation() += IP.cross(in[vertice.verticeIndex]) * vertice.weight;
00278         }
00279     }
00280 }
00281 
00282 template <class BasicMapping>
00283 void LineSetSkinningMapping<BasicMapping>::applyJT( typename In::VecConst& out, const typename Out::VecConst& in )
00284 {
00285     out.clear();
00286     out.resize(in.size());
00287 
00288     InVecCoord& xfrom = *this->fromModel->getX();
00289 
00290     for(unsigned int i=0; i<in.size(); i++)
00291     {
00292         for (unsigned int j=0;j<in[i].size();j++)
00293         {
00294             const OutSparseDeriv cIn = in[i][j];
00295             int verticeIndex = cIn.index;
00296             const OutDeriv d = (OutDeriv) cIn.data;
00297             //printf(" normale : %f %f %f",d.x(), d.y(), d.z());
00298             for(unsigned int lineInfluencedIndex=0; lineInfluencedIndex<linesInfluencedByVertice[verticeIndex].size(); lineInfluencedIndex++)
00299             {
00300                 influencedLineType iline = linesInfluencedByVertice[verticeIndex][lineInfluencedIndex];
00301                 Vec<3,Real> IP = xfrom[t->getLine(iline.lineIndex)[0]].getOrientation().rotate(iline.position);
00302                 InDeriv direction;
00303                 direction.getVCenter() = d * iline.weight;
00304                 //printf("\n Weighted normale : %f %f %f",direction.getVCenter().x(), direction.getVCenter().y(), direction.getVCenter().z());
00305                 direction.getVOrientation() = IP.cross(d) * iline.weight;
00306                 out[i].push_back(InSparseDeriv(t->getLine(iline.lineIndex)[0], direction));
00307             }
00308         }
00309     }
00310 }
00311 
00312 } // namespace mapping
00313 
00314 } // namespace component
00315 
00316 } // namespace sofa
00317 
00318 #endif

Generated on Sun Nov 23 03:32:37 2008 for Sofa by  doxygen 1.5.7.1