LinearMovementConstraint.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_LINEARMOVEMENTCONSTRAINT_INL
00026 #define SOFA_COMPONENT_CONSTRAINT_LINEARMOVEMENTCONSTRAINT_INL
00027 
00028 #include <sofa/core/componentmodel/topology/BaseMeshTopology.h>
00029 #include <sofa/core/componentmodel/behavior/Constraint.inl>
00030 #include <sofa/core/componentmodel/topology/BaseMeshTopology.h>
00031 #include <sofa/component/constraint/LinearMovementConstraint.h>
00032 #include <sofa/helper/gl/template.h>
00033 #include <sofa/defaulttype/RigidTypes.h>
00034 #include <iostream>
00035 
00036 #include <sofa/component/topology/PointSubset.h>
00037 
00038 using std::cerr;
00039 using std::endl;
00040 
00041 namespace sofa
00042 {
00043 
00044 namespace component
00045 {
00046 
00047 namespace constraint
00048 {
00049 
00050 using namespace core::componentmodel::topology;
00051 
00052 using namespace sofa::defaulttype;
00053 using namespace sofa::helper;
00054 using namespace sofa::core::componentmodel::behavior;
00055 
00056 
00057 // Define TestNewPointFunction
00058 template< class DataTypes>
00059 bool LinearMovementConstraint<DataTypes>::FCTestNewPointFunction(int /*nbPoints*/, void* param, const sofa::helper::vector< unsigned int > &, const sofa::helper::vector< double >& )
00060 {
00061     LinearMovementConstraint<DataTypes> *fc= (LinearMovementConstraint<DataTypes> *)param;
00062     if (fc) {
00063         return true;
00064     }else{
00065         return false;
00066     }
00067 }
00068 
00069 // Define RemovalFunction
00070 template< class DataTypes>
00071 void LinearMovementConstraint<DataTypes>::FCRemovalFunction(int pointIndex, void* param)
00072 {
00073     LinearMovementConstraint<DataTypes> *fc= (LinearMovementConstraint<DataTypes> *)param;
00074     if (fc) {
00075         fc->removeIndex((unsigned int) pointIndex);
00076     }
00077     return;
00078 } 
00079 
00080 template <class DataTypes>
00081 LinearMovementConstraint<DataTypes>::LinearMovementConstraint()
00082 : core::componentmodel::behavior::Constraint<DataTypes>(NULL)
00083 , m_indices( initData(&m_indices,"indices","Indices of the constrained points") )
00084 , m_keyTimes(  initData(&m_keyTimes,"keyTimes","key times for the movements") )
00085 , m_keyMovements(  initData(&m_keyMovements,"movements","movements corresponding to the key times") )
00086 {
00087     // default to indice 0
00088     m_indices.beginEdit()->push_back(0);
00089     m_indices.endEdit();
00090 
00091     //default valueEvent to 0
00092     m_keyTimes.beginEdit()->push_back( 0.0 );
00093     m_keyTimes.endEdit();
00094     m_keyMovements.beginEdit()->push_back( Deriv() );
00095     m_keyMovements.endEdit();
00096 }
00097 
00098 
00099 // Handle topological changes
00100 template <class DataTypes> void LinearMovementConstraint<DataTypes>::handleTopologyChange()
00101 {   
00102     std::list<const TopologyChange *>::const_iterator itBegin=topology->firstChange();
00103     std::list<const TopologyChange *>::const_iterator itEnd=topology->lastChange();
00104 
00105     m_indices.beginEdit()->handleTopologyEvents(itBegin,itEnd,this->getMState()->getSize());
00106 
00107 }
00108 
00109 template <class DataTypes>
00110 LinearMovementConstraint<DataTypes>::~LinearMovementConstraint()
00111 {
00112 }
00113 
00114 template <class DataTypes>
00115 void LinearMovementConstraint<DataTypes>::clearIndices()
00116 {
00117     m_indices.beginEdit()->clear();
00118     m_indices.endEdit();
00119 }
00120 
00121 template <class DataTypes>
00122 void LinearMovementConstraint<DataTypes>::addIndex(unsigned int index)
00123 {
00124     m_indices.beginEdit()->push_back(index);
00125     m_indices.endEdit();
00126 }
00127 
00128 template <class DataTypes>
00129 void LinearMovementConstraint<DataTypes>::removeIndex(unsigned int index)
00130 {
00131     removeValue(*m_indices.beginEdit(),index);
00132     m_indices.endEdit();
00133 }
00134 
00135 template <class DataTypes>
00136 void LinearMovementConstraint<DataTypes>::clearKeyMovements()
00137 {
00138     m_keyTimes.beginEdit()->clear();
00139     m_keyTimes.endEdit();
00140     m_keyMovements.beginEdit()->clear();
00141     m_keyMovements.endEdit();
00142 }
00143 
00144 template <class DataTypes>
00145 void LinearMovementConstraint<DataTypes>::addKeyMovement(Real time, Deriv movement)
00146 {
00147     m_keyTimes.beginEdit()->push_back( time );
00148     m_keyTimes.endEdit();
00149     m_keyMovements.beginEdit()->push_back( movement );
00150     m_keyMovements.endEdit();
00151 }
00152 
00153 // -- Constraint interface
00154 
00155 
00156 template <class DataTypes>
00157 void LinearMovementConstraint<DataTypes>::init()
00158 {
00159     this->core::componentmodel::behavior::Constraint<DataTypes>::init();
00160 
00161     topology = getContext()->getMeshTopology();
00162 
00163     // Initialize functions and parameters
00164     topology::PointSubset my_subset = m_indices.getValue();
00165 
00166     my_subset.setTestFunction(FCTestNewPointFunction);
00167     my_subset.setRemovalFunction(FCRemovalFunction);
00168 
00169     my_subset.setTestParameter( (void *) this );
00170     my_subset.setRemovalParameter( (void *) this );
00171 
00172     x0.resize(0);
00173     nextM = prevM = Deriv();
00174 
00175 }
00176 
00177 
00178 template <class DataTypes>
00179 void LinearMovementConstraint<DataTypes>::projectResponse(VecDeriv& )
00180 {
00181 
00182 }
00183 
00184 template <class DataTypes>
00185 void LinearMovementConstraint<DataTypes>::projectVelocity(VecDeriv& dx)
00186 {
00187     Real cT = (Real) this->getContext()->getTime(); 
00188     if(cT >= *m_keyTimes.getValue().begin() && cT <= *m_keyTimes.getValue().rbegin()){
00189         const SetIndexArray & indices = m_indices.getValue().getArray();
00190 
00191         bool finished=false;
00192 
00193         typename helper::vector<Real>::const_iterator it_t = m_keyTimes.getValue().begin();
00194         typename VecDeriv::const_iterator it_m = m_keyMovements.getValue().begin();
00195  
00196         //WARNING : we consider that the key-events are in chronological order
00197         //here we search between which keyTimes we are, to know which are the motion to interpolate
00198         while( it_t != m_keyTimes.getValue().end() && !finished)
00199         {
00200             if( *it_t <= cT) {
00201                 prevT = *it_t;
00202                 prevM = *it_m;
00203             }
00204             else {
00205                 nextT = *it_t;
00206                 nextM = *it_m;
00207                 finished = true;
00208             }
00209             it_t++;
00210             it_m++;
00211         }
00212 
00213         //if we found 2 keyTimes, we have to interpolate a velocity (linear interpolation)
00214         if(finished){
00215             Real dTsimu = (Real) this->getContext()->getDt();
00216             Real dt = (cT - prevT) / (nextT - prevT);
00217             Deriv m= (nextM-prevM)*dt;
00218             Deriv mPrev= (nextM-prevM)*(((cT-dTsimu) - prevT) / (nextT - prevT));
00219 
00220             //set the motion to the Dofs 
00221             for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it)
00222             {
00223                 dx[*it] = (m - mPrev) * (1/dTsimu);
00224             }   
00225         }
00226     }
00227 }
00228 
00229 
00230 template <class DataTypes>
00231 void LinearMovementConstraint<DataTypes>::projectPosition(VecCoord& x)
00232 {
00233     Real cT = (Real) this->getContext()->getTime(); 
00234 
00235     //initialize initial Dofs positions, if it's not done
00236     if (x0.size() == 0){
00237         const SetIndexArray & indices = m_indices.getValue().getArray();
00238         x0.resize( x.size() );
00239         for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it)
00240             x0[*it] = x[*it];
00241     }
00242 
00243     //if we found 2 keyTimes, we have to interpolate a position (linear interpolation)
00244     if(cT >= *m_keyTimes.getValue().begin() && cT <= *m_keyTimes.getValue().rbegin() && nextT!=prevT){
00245         const SetIndexArray & indices = m_indices.getValue().getArray();
00246 
00247         Real dt = (cT - prevT) / (nextT - prevT);
00248         Deriv m = prevM + (nextM-prevM)*dt;
00249 
00250         //set the motion to the Dofs 
00251         for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it)
00252         {
00253             x[*it] = x0[*it] + m ;
00254         }
00255     }
00256 }
00257 
00258 //display the path the constrained dofs will go through
00259 template <class DataTypes>
00260 void LinearMovementConstraint<DataTypes>::draw()
00261 {
00262     if (!getContext()->
00263             getShowBehaviorModels()) return;
00264     glDisable (GL_LIGHTING);
00265     glPointSize(10);
00266     glColor4f (1,0.5,0.5,1);
00267     glBegin (GL_LINES);
00268     const SetIndexArray & indices = m_indices.getValue().getArray();
00269     for (unsigned int i=0 ; i<m_keyMovements.getValue().size()-1 ; i++) {
00270         for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it)
00271         {
00272             gl::glVertexT(x0[*it]+m_keyMovements.getValue()[i]);
00273             gl::glVertexT(x0[*it]+m_keyMovements.getValue()[i+1]);
00274         }
00275     }
00276     glEnd();
00277 }
00278 
00279 // Specialization for rigids
00280 template <>
00281 void LinearMovementConstraint<Rigid3dTypes >::draw();
00282 template <>
00283 void LinearMovementConstraint<Rigid3fTypes >::draw();
00284 
00285 } // namespace constraint
00286 
00287 } // namespace component
00288 
00289 } // namespace sofa
00290 
00291 #endif
00292 

Generated on Sun Nov 23 02:41:55 2008 for Sofa by  doxygen 1.5.7.1