AttachConstraint.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_CONSTRAINT_ATTACHCONSTRAINT_INL
00026 #define SOFA_COMPONENT_CONSTRAINT_ATTACHCONSTRAINT_INL
00027 
00028 #include <sofa/core/componentmodel/behavior/PairInteractionConstraint.inl>
00029 #include <sofa/component/constraint/AttachConstraint.h>
00030 #include <sofa/helper/gl/template.h>
00031 #include <sofa/defaulttype/RigidTypes.h>
00032 #include <iostream>
00033 
00034 #include <sofa/component/topology/PointSubset.h>
00035 
00036 using std::cerr;
00037 using std::endl;
00038 
00039 namespace sofa
00040 {
00041 
00042 namespace component
00043 {
00044 
00045 namespace constraint
00046 {
00047 
00048 using namespace core::componentmodel::topology;
00049 
00050 using namespace sofa::defaulttype;
00051 using namespace sofa::helper;
00052 using namespace sofa::core::componentmodel::behavior;
00053 
00054 template<>
00055 inline void AttachConstraint<defaulttype::Rigid3dTypes>::projectPosition(Coord& x1, Coord& x2, bool freeRotations, unsigned index)
00056 {
00057     x2.getCenter() = x1.getCenter();
00058     if (!freeRotations)
00059     {
00060     if (!restRotations.empty())
00061     {
00062         if (index+1 >= lastDist.size() || activeFlags[index+1])
00063         x2.getOrientation() = x1.getOrientation()*restRotations[index];
00064         else
00065         { // gradually set the velocity along the direction axis
00066         Real fact = -lastDist[index] / (lastDist[index+1]-lastDist[index]);
00067         Vector3 axis(restRotations[index][0], restRotations[index][1], restRotations[index][2]);
00068         Real angle = acos(restRotations[index][3])*2;
00069         //restRotations[index].toAngleAxis(angle,axis);
00070         x2.getOrientation() = x1.getOrientation()*Quat(axis,angle*fact);
00071         }
00072     }
00073     else
00074         x2.getOrientation() = x1.getOrientation();
00075     }
00076 }
00077 
00078 template<>
00079 inline void AttachConstraint<defaulttype::Rigid3fTypes>::projectPosition(Coord& x1, Coord& x2, bool freeRotations, unsigned /*index*/)
00080 {
00081     x2.getCenter() = x1.getCenter();
00082     if (!freeRotations)
00083         x2.getOrientation() = x1.getOrientation();
00084 }
00085 
00086 template<>
00087 inline void AttachConstraint<defaulttype::Rigid2dTypes>::projectPosition(Coord& x1, Coord& x2, bool freeRotations, unsigned /*index*/)
00088 {
00089     x2.getCenter() = x1.getCenter();
00090     if (!freeRotations)
00091         x2.getOrientation() = x1.getOrientation();
00092 }
00093 
00094 template<>
00095 inline void AttachConstraint<defaulttype::Rigid2fTypes>::projectPosition(Coord& x1, Coord& x2, bool freeRotations, unsigned /*index*/)
00096 {
00097     x2.getCenter() = x1.getCenter();
00098     if (!freeRotations)
00099         x2.getOrientation() = x1.getOrientation();
00100 }
00101 
00102 template<>
00103 inline void AttachConstraint<defaulttype::Rigid3dTypes>::projectVelocity(Deriv& x1, Deriv& x2, bool freeRotations, unsigned /*index*/)
00104 {
00105     x2.getVCenter() = x1.getVCenter();
00106     if (!freeRotations)
00107         x2.getVOrientation() = x1.getVOrientation();
00108     //x2 = Deriv();
00109 }
00110 
00111 template<>
00112 inline void AttachConstraint<defaulttype::Rigid3fTypes>::projectVelocity(Deriv& x1, Deriv& x2, bool freeRotations, unsigned /*index*/)
00113 {
00114     x2.getVCenter() = x1.getVCenter();
00115     if (!freeRotations)
00116         x2.getVOrientation() = x1.getVOrientation();
00117 }
00118 
00119 template<>
00120 inline void AttachConstraint<defaulttype::Rigid2dTypes>::projectVelocity(Deriv& x1, Deriv& x2, bool freeRotations, unsigned /*index*/)
00121 {
00122     x2.getVCenter() = x1.getVCenter();
00123     if (!freeRotations)
00124         x2.getVOrientation() = x1.getVOrientation();
00125 }
00126 
00127 template<>
00128 inline void AttachConstraint<defaulttype::Rigid2fTypes>::projectVelocity(Deriv& x1, Deriv& x2, bool freeRotations, unsigned /*index*/)
00129 {
00130     x2.getVCenter() = x1.getVCenter();
00131     if (!freeRotations)
00132         x2.getVOrientation() = x1.getVOrientation();
00133 }
00134 
00135 template<>
00136 inline void AttachConstraint<defaulttype::Rigid3dTypes>::projectResponse(Deriv& dx1, Deriv& dx2, bool freeRotations, bool twoway, unsigned /*index*/)
00137 {
00138     if (!twoway)
00139     {
00140         if (!freeRotations)
00141             dx2 = Deriv();
00142         else
00143             dx2.getVCenter().clear();
00144     }
00145     else
00146     {
00147         if (!freeRotations)
00148         {
00149             dx1 += dx2;
00150             dx2 = dx1;
00151         }
00152         else
00153         {
00154             dx1.getVCenter() += dx2.getVCenter();
00155             dx2.getVCenter() = dx1.getVCenter();
00156         }
00157     }
00158 }
00159 
00160 template<>
00161 inline void AttachConstraint<defaulttype::Rigid3fTypes>::projectResponse(Deriv& dx1, Deriv& dx2, bool freeRotations, bool twoway, unsigned /*index*/)
00162 {
00163     if (!twoway)
00164     {
00165         if (!freeRotations)
00166             dx2 = Deriv();
00167         else
00168             dx2.getVCenter().clear();
00169     }
00170     else
00171     {
00172         if (!freeRotations)
00173         {
00174             dx1 += dx2;
00175             dx2 = dx1;
00176         }
00177         else
00178         {
00179             dx1.getVCenter() += dx2.getVCenter();
00180             dx2.getVCenter() = dx1.getVCenter();
00181         }
00182     }
00183 }
00184 
00185 template<>
00186 inline void AttachConstraint<defaulttype::Rigid2dTypes>::projectResponse(Deriv& dx1, Deriv& dx2, bool freeRotations, bool twoway, unsigned /*index*/)
00187 {
00188     if (!twoway)
00189     {
00190         if (!freeRotations)
00191             dx2 = Deriv();
00192         else
00193             dx2.getVCenter().clear();
00194     }
00195     else
00196     {
00197         if (!freeRotations)
00198         {
00199             dx1 += dx2;
00200             dx2 = dx1;
00201         }
00202         else
00203         {
00204             dx1.getVCenter() += dx2.getVCenter();
00205             dx2.getVCenter() = dx1.getVCenter();
00206         }
00207     }
00208 }
00209 
00210 template<>
00211 inline void AttachConstraint<defaulttype::Rigid2fTypes>::projectResponse(Deriv& dx1, Deriv& dx2, bool freeRotations, bool twoway, unsigned /*index*/)
00212 {
00213     if (!twoway)
00214     {
00215         if (!freeRotations)
00216             dx2 = Deriv();
00217         else
00218             dx2.getVCenter().clear();
00219     }
00220     else
00221     {
00222         if (!freeRotations)
00223         {
00224             dx1 += dx2;
00225             dx2 = dx1;
00226         }
00227         else
00228         {
00229             dx1.getVCenter() += dx2.getVCenter();
00230             dx2.getVCenter() = dx1.getVCenter();
00231         }
00232     }
00233 }
00234 
00235 template<>
00236 inline unsigned int AttachConstraint<defaulttype::Rigid3dTypes>::DerivConstrainedSize(bool freeRotations)
00237 {
00238     if (freeRotations)
00239         return Deriv::static_size;
00240     else
00241         return Deriv::size();
00242 }
00243 
00244 template<>
00245 inline unsigned int AttachConstraint<defaulttype::Rigid3fTypes>::DerivConstrainedSize(bool freeRotations)
00246 {
00247     if (freeRotations)
00248         return Deriv::static_size;
00249     else
00250         return Deriv::size();
00251 }
00252 
00253 template<>
00254 inline unsigned int AttachConstraint<defaulttype::Rigid2dTypes>::DerivConstrainedSize(bool freeRotations)
00255 {
00256     if (freeRotations)
00257         return Deriv::static_size;
00258     else
00259         return Deriv::size();
00260 }
00261 
00262 template<>
00263 inline unsigned int AttachConstraint<defaulttype::Rigid2fTypes>::DerivConstrainedSize(bool freeRotations)
00264 {
00265     if (freeRotations)
00266         return Deriv::static_size;
00267     else
00268         return Deriv::size();
00269 }
00270 
00271 #if 0
00272 // Define TestNewPointFunction
00273 template< class DataTypes>
00274 bool AttachConstraint<DataTypes>::FCTestNewPointFunction(int /*nbPoints*/, void* param, const sofa::helper::vector< unsigned int > &, const sofa::helper::vector< double >& )
00275 {
00276     AttachConstraint<DataTypes> *fc= (AttachConstraint<DataTypes> *)param;
00277     if (fc) {
00278         return true;
00279     }else{
00280         return false;
00281     }
00282 }
00283 
00284 // Define RemovalFunction
00285 template< class DataTypes>
00286 void AttachConstraint<DataTypes>::FCRemovalFunction(int pointIndex, void* param)
00287 {
00288     AttachConstraint<DataTypes> *fc= (AttachConstraint<DataTypes> *)param;
00289     if (fc) {
00290         fc->removeConstraint((unsigned int) pointIndex);
00291     }
00292     return;
00293 } 
00294 #endif
00295 
00296 template <class DataTypes>
00297 AttachConstraint<DataTypes>::AttachConstraint()
00298 : f_indices1( initData(&f_indices1,"indices1","Indices of the source points on the first model") )
00299 , f_indices2( initData(&f_indices2,"indices2","Indices of the fixed points on the second model") )
00300 , f_radius( initData(&f_radius,(Real)-1,"radius", "Radius to search corresponding fixed point if no indices are given") )
00301 , f_twoWay( initData(&f_twoWay,false,"twoWay", "true if forces should be projected back from model2 to model1") )
00302 , f_freeRotations( initData(&f_freeRotations,false,"freeRotations", "true to keep rotations free (only used for Rigid DOFs)") )
00303 , f_lastFreeRotation( initData(&f_lastFreeRotation,false,"lastFreeRotation", "true to keep rotation of the last attached point free (only used for Rigid DOFs)") )
00304 , f_restRotations( initData(&f_restRotations,false,"restRotations", "true to use rest rotations local offsets (only used for Rigid DOFs)") )
00305 , f_lastPos( initData(&f_lastPos,"lastPos", "position at which the attach constraint should become inactive") )
00306 , f_lastDir( initData(&f_lastDir,"lastDir", "direction from lastPos at which the attach coustraint should become inactive") )
00307 , f_clamp( initData(&f_clamp, false,"clamp", "true to clamp particles at lastPos instead of freeing them.") )
00308 {
00309     // default to indice 0
00310 //     f_indices1.beginEdit()->push_back(0);
00311 //     f_indices1.endEdit();
00312 //     f_indices2.beginEdit()->push_back(0);
00313 //     f_indices2.endEdit();
00314 }
00315 
00316 #if 0
00317 // Handle topological changes
00318 template <class DataTypes> void AttachConstraint<DataTypes>::handleTopologyChange()
00319 {   
00320     std::list<const TopologyChange *>::const_iterator itBegin=topology->firstChange();
00321     std::list<const TopologyChange *>::const_iterator itEnd=topology->lastChange();
00322 
00323     f_indices.beginEdit()->handleTopologyEvents(itBegin,itEnd,this->getMState()->getSize());
00324 }
00325 #endif
00326 
00327 template <class DataTypes>
00328 AttachConstraint<DataTypes>::~AttachConstraint()
00329 {
00330 }
00331 
00332 template <class DataTypes>
00333 void AttachConstraint<DataTypes>::clearConstraints()
00334 {
00335     f_indices1.beginEdit()->clear();
00336     f_indices1.endEdit();
00337     f_indices2.beginEdit()->clear();
00338     f_indices2.endEdit();
00339 }
00340 
00341 template <class DataTypes>
00342 void AttachConstraint<DataTypes>::addConstraint(unsigned int index1, unsigned int index2)
00343 {
00344     f_indices1.beginEdit()->push_back(index1);
00345     f_indices1.endEdit();
00346     f_indices2.beginEdit()->push_back(index2);
00347     f_indices2.endEdit();
00348 }
00349 
00350 // -- Constraint interface
00351 
00352 
00353 template <class DataTypes>
00354 void AttachConstraint<DataTypes>::init()
00355 {
00356     this->core::componentmodel::behavior::PairInteractionConstraint<DataTypes>::init();
00357 
00358     topology = getContext()->getMeshTopology();
00359 
00360     if (f_radius.getValue() >= 0 && f_indices1.getValue().size()==0 && f_indices2.getValue().size()==0 && this->mstate1 && this->mstate2)
00361     {
00362         const Real maxR = f_radius.getValue();
00363         VecCoord& x1 = *this->mstate1->getX();
00364         VecCoord& x2 = *this->mstate2->getX();
00365         for (unsigned int i2=0; i2<x2.size(); ++i2)
00366         {
00367             int best = -1;
00368             Real bestR = maxR;
00369             for (unsigned int i1=0; i1<x1.size(); ++i1)
00370             {
00371                 Real r = (x2[i2]-x1[i1]).norm();
00372                 if (r <= bestR)
00373                 {
00374                     best = i1;
00375                     bestR = r;
00376                 }
00377             }
00378             if (best >= 0)
00379             {
00380                 addConstraint(best, i2);
00381             }
00382         }
00383     }
00384 #if 0
00385     // Initialize functions and parameters
00386     topology::PointSubset my_subset = f_indices.getValue();
00387 
00388     my_subset.setTestFunction(FCTestNewPointFunction);
00389     my_subset.setRemovalFunction(FCRemovalFunction);
00390 
00391     my_subset.setTestParameter( (void *) this );
00392     my_subset.setRemovalParameter( (void *) this );
00393 #endif
00394     activeFlags.resize(f_indices2.getValue().size());
00395     std::fill(activeFlags.begin(), activeFlags.end(), true);
00396     if (f_restRotations.getValue())
00397     calcRestRotations();
00398 }
00399 
00400 template <class DataTypes>
00401 void AttachConstraint<DataTypes>::calcRestRotations()
00402 {
00403 }
00404 
00405 template <>
00406 void AttachConstraint<Rigid3dTypes>::calcRestRotations()
00407 {
00408     const SetIndexArray & indices2 = f_indices2.getValue().getArray();
00409     const VecCoord& x0 = *this->mstate2->getX0();
00410     restRotations.resize(indices2.size());
00411     for (unsigned int i=0;i<indices2.size(); ++i)
00412     {
00413     Quat q(0,0,0,1);
00414     if (indices2[i] < x0.size()-1)
00415     {
00416         Vector3 dp0 = x0[indices2[i]].vectorToChild(x0[indices2[i]+1].getCenter()-x0[indices2[i]].getCenter());
00417         dp0.normalize();
00418         Vector3 y = cross(dp0, Vector3(1,0,0));
00419         y.normalize();
00420         double alpha = acos(dp0[0]);
00421         q = Quat(y,alpha);
00422         std::cout << "restRotations x2["<<indices2[i]<<"]="<<q<<" dp0="<<dp0<<" qx="<<q.rotate(Vector3(1,0,0))<<std::endl;
00423     }
00424     restRotations[i] = q;
00425     }
00426 }
00427 
00428 template <class DataTypes>
00429 void AttachConstraint<DataTypes>::projectPosition(VecCoord& res1, VecCoord& res2)
00430 {
00431     const SetIndexArray & indices1 = f_indices1.getValue().getArray();
00432     const SetIndexArray & indices2 = f_indices2.getValue().getArray();
00433     const bool freeRotations = f_freeRotations.getValue();
00434     const bool lastFreeRotation = f_lastFreeRotation.getValue();
00435     const bool last = (f_lastDir.isSet() && f_lastDir.getValue().norm() > 1.0e-10);
00436     const bool clamp = f_clamp.getValue();
00437     const bool log = this->f_printLog.getValue();
00438 
00439     // update active flags
00440     activeFlags.resize(indices2.size());
00441     if (last)
00442     lastDist.resize(indices2.size());
00443     //std::cout << "lastDir="<<f_lastDir.getValue()<<std::endl;
00444     //std::cout << "lastPos="<<f_lastPos.getValue()<<std::endl;
00445     for (unsigned int i=0;i<indices1.size() && i<indices2.size(); ++i)
00446     {
00447         bool active = true;
00448         if (last)
00449         {
00450         Coord p = res1[indices1[i]];
00451             Vec<3,Real> p3d;
00452             DataTypes::get(p3d[0],p3d[1],p3d[2],p);
00453         lastDist[i] = (Real)( (p3d-f_lastPos.getValue())*f_lastDir.getValue());
00454             if (lastDist[i] > 0.0)
00455             {
00456                 if (clamp)
00457                 {
00458                     if (activeFlags[i])
00459                         std::cout << "AttachConstraint: point "<<indices1[i]<<" stopped."<<std::endl;
00460                     //DataTypes::set(p,f_lastPos.getValue()[0],f_lastPos.getValue()[1],f_lastPos.getValue()[2]);
00461                     //p = f_lastPos.getValue();
00462                 }
00463                 else
00464                 {
00465                     if (activeFlags[i])
00466                         std::cout << "AttachConstraint: point "<<indices1[i]<<" is free."<<std::endl;
00467                 }
00468                 active = false;
00469             }
00470         }
00471         activeFlags[i] = active;
00472     }
00473     for (unsigned int i=0;i<indices1.size() && i<indices2.size(); ++i)
00474     {
00475         Coord p = res1[indices1[i]];
00476         if (activeFlags[i])
00477         {
00478             if (log) std::cout << "AttachConstraint: x2["<<indices2[i]<<"] = x1["<<indices1[i]<<"]\n";
00479             //res2[indices2[i]] = res1[indices1[i]];
00480             projectPosition(p, res2[indices2[i]], freeRotations || (lastFreeRotation && (i>=activeFlags.size() || !activeFlags[i+1])), i);
00481         }
00482     else if (clamp)
00483     {
00484         DataTypes::set(p,f_lastPos.getValue()[0],f_lastPos.getValue()[1],f_lastPos.getValue()[2]);
00485             if (log) std::cout << "AttachConstraint: x2["<<indices2[i]<<"] = lastPos\n";
00486             projectPosition(p, res2[indices2[i]], freeRotations, i);
00487     }
00488     }
00489 }
00490 
00491 template <class DataTypes>
00492 void AttachConstraint<DataTypes>::projectVelocity(VecDeriv& res1, VecDeriv& res2)
00493 {
00494     const SetIndexArray & indices1 = f_indices1.getValue().getArray();
00495     const SetIndexArray & indices2 = f_indices2.getValue().getArray();
00496     const bool freeRotations = f_freeRotations.getValue();
00497     const bool lastFreeRotation = f_lastFreeRotation.getValue();
00498     const bool clamp = f_clamp.getValue();
00499     const bool log = this->f_printLog.getValue();
00500     for (unsigned int i=0;i<indices1.size() && i<indices2.size(); ++i)
00501     {
00502         bool active = true;
00503         if (i < activeFlags.size()) active = activeFlags[i];
00504         //res2[indices2[i]] = res1[indices1[i]];
00505         if (active)
00506         {
00507             if (log) std::cout << "AttachConstraint: v2["<<indices2[i]<<"] = v1["<<indices1[i]<<"]\n";
00508             projectVelocity(res1[indices1[i]], res2[indices2[i]], freeRotations || (lastFreeRotation && (i>=activeFlags.size() || !activeFlags[i+1])), i);
00509         }
00510         else if (clamp)
00511         {
00512             if (log) std::cout << "AttachConstraint: v2["<<indices2[i]<<"] = 0\n";
00513             Deriv v = Deriv();
00514             projectVelocity(v, res2[indices2[i]], freeRotations, i);
00515         }
00516     }
00517 }
00518 
00519 template <class DataTypes>
00520 void AttachConstraint<DataTypes>::projectResponse(VecDeriv& res1, VecDeriv& res2)
00521 {
00522     const SetIndexArray & indices1 = f_indices1.getValue().getArray();
00523     const SetIndexArray & indices2 = f_indices2.getValue().getArray();
00524     const bool twoway = f_twoWay.getValue();
00525     const bool freeRotations = f_freeRotations.getValue();
00526     const bool lastFreeRotation = f_lastFreeRotation.getValue();
00527     const bool clamp = f_clamp.getValue();
00528     const bool log = this->f_printLog.getValue();
00529     for (unsigned int i=0;i<indices1.size() && i<indices2.size(); ++i)
00530     {
00531         bool active = true;
00532         if (i < activeFlags.size()) active = activeFlags[i];
00533         if (active)
00534         {
00535             if (log)
00536             {
00537                 if (twoway) std::cout << "AttachConstraint: r2["<<indices2[i]<<"] = r1["<<indices2[i]<<"] = (r2["<<indices2[i]<<"] + r2["<<indices2[i]<<"])\n";
00538                 else        std::cout << "AttachConstraint: r2["<<indices2[i]<<"] = 0\n";
00539             }
00540             projectResponse(res1[indices1[i]], res2[indices2[i]], freeRotations || (lastFreeRotation && (i>=activeFlags.size() || !activeFlags[i+1])), twoway, i);
00541             //res2[indices2[i]] = Deriv();
00542             if (log)
00543                 std::cout << "AttachConstraint: final r2["<<indices2[i]<<"] = "<<res2[indices2[i]]<<"\n";
00544         }
00545         else if (clamp)
00546         {
00547             if (log) std::cout << "AttachConstraint: r2["<<indices2[i]<<"] = 0\n";
00548             Deriv v = Deriv();
00549             projectResponse(v, res2[indices2[i]], freeRotations, false, i);
00550             if (log)
00551                 std::cout << "AttachConstraint: final r2["<<indices2[i]<<"] = "<<res2[indices2[i]]<<"\n";
00552         }
00553     }
00554 }
00555 
00556 // Matrix Integration interface
00557 template <class DataTypes>
00558 void AttachConstraint<DataTypes>::applyConstraint(defaulttype::BaseMatrix *mat, unsigned int &offset)
00559 {
00560     //std::cout << "applyConstraint in Matrix with offset = " << offset << std::endl;
00561     const SetIndexArray & indices = f_indices2.getValue().getArray();
00562     const unsigned int N = Deriv::size();
00563     const unsigned int NC = DerivConstrainedSize(f_freeRotations.getValue());
00564     const unsigned int NCLast = DerivConstrainedSize(f_lastFreeRotation.getValue());
00565     unsigned int i=0;
00566     const bool clamp = f_clamp.getValue();
00567     const bool log = this->f_printLog.getValue();
00568     for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it, ++i)
00569     {
00570         if (!clamp && i < activeFlags.size() && !activeFlags[i]) continue;
00571         if (log) std::cout << "AttachConstraint: apply in matrix column/row "<<(*it)<<"\n";
00572     if (NCLast != NC && (i>=activeFlags.size() || !activeFlags[i+1]))
00573     {
00574         // Reset Fixed Row and Col
00575         for (unsigned int c=0;c<NCLast;++c)
00576         mat->clearRowCol(offset + N * (*it) + c);
00577         // Set Fixed Vertex
00578         for (unsigned int c=0;c<NCLast;++c)
00579         mat->set(offset + N * (*it) + c, offset + N * (*it) + c, 1.0);
00580     }
00581     else
00582     {
00583         // Reset Fixed Row and Col
00584         for (unsigned int c=0;c<NC;++c)
00585         mat->clearRowCol(offset + N * (*it) + c);
00586         // Set Fixed Vertex
00587         for (unsigned int c=0;c<NC;++c)
00588         mat->set(offset + N * (*it) + c, offset + N * (*it) + c, 1.0);
00589     }
00590     }
00591 }
00592 
00593 template <class DataTypes>
00594 void AttachConstraint<DataTypes>::applyConstraint(defaulttype::BaseVector *vect, unsigned int &offset)
00595 {
00596     std::cout << "applyConstraint in Vector with offset = " << offset << std::endl;
00597 
00598     const SetIndexArray & indices = f_indices2.getValue().getArray();
00599     const unsigned int N = Deriv::size();
00600     const unsigned int NC = DerivConstrainedSize(f_freeRotations.getValue());
00601     const unsigned int NCLast = DerivConstrainedSize(f_lastFreeRotation.getValue());
00602     unsigned int i=0;
00603     const bool clamp = f_clamp.getValue();
00604     for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it, ++i)
00605     {
00606         if (!clamp && i < activeFlags.size() && !activeFlags[i]) continue;
00607     if (NCLast != NC && (i>=activeFlags.size() || !activeFlags[i+1]))
00608     {
00609         for (unsigned int c=0;c<NCLast;++c)
00610         vect->clear(offset + N * (*it) + c);
00611     }
00612     else
00613     {
00614         for (unsigned int c=0;c<NC;++c)
00615         vect->clear(offset + N * (*it) + c);
00616     }
00617     }
00618 }
00619 
00620 
00621 template <class DataTypes>
00622 void AttachConstraint<DataTypes>::draw()
00623 {
00624     if (!getContext()->
00625             getShowBehaviorModels()) return;
00626     const SetIndexArray & indices1 = f_indices1.getValue().getArray();
00627     const SetIndexArray & indices2 = f_indices2.getValue().getArray();
00628     VecCoord& x1 = *this->mstate1->getX();
00629     VecCoord& x2 = *this->mstate2->getX();
00630     glDisable (GL_LIGHTING);
00631     glPointSize(10);
00632     glColor4f (1,0.5,0.5,1);
00633     glBegin (GL_POINTS);
00634     for (unsigned int i=0;i<indices1.size() && i<indices2.size(); ++i)
00635     {
00636         if (activeFlags.size() > i && !activeFlags[i]) continue;
00637         gl::glVertexT(x2[indices2[i]]);
00638     }
00639     glEnd();
00640     glPointSize(1);
00641     glColor4f (1,0.5,0.5,1);
00642     glBegin (GL_LINES);
00643     for (unsigned int i=0;i<indices1.size() && i<indices2.size(); ++i)
00644     {
00645         if (activeFlags.size() > i && !activeFlags[i]) continue;
00646         gl::glVertexT(x1[indices1[i]]);
00647         gl::glVertexT(x2[indices2[i]]);
00648     }
00649     glEnd();
00650 }
00651 
00652 } // namespace constraint
00653 
00654 } // namespace component
00655 
00656 } // namespace sofa
00657 
00658 #endif

Generated on Sun Nov 23 02:38:09 2008 for Sofa by  doxygen 1.5.7.1