VecTypes.h

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 :: Framework                              *
00020 *                                                                             *
00021 * Authors: M. Adam, J. Allard, B. Andre, P-J. Bensoussan, S. Cotin, C. Duriez,*
00022 * H. Delingette, F. Falipou, F. Faure, S. Fonteneau, L. Heigeas, C. Mendoza,  *
00023 * M. Nesme, P. Neumann, J-P. de la Plata Alcade, F. Poyer and F. Roy          *
00024 *                                                                             *
00025 * Contact information: contact@sofa-framework.org                             *
00026 ******************************************************************************/
00027 #ifndef SOFA_DEFAULTTYPE_VECTYPES_H
00028 #define SOFA_DEFAULTTYPE_VECTYPES_H
00029 
00030 #include <sofa/defaulttype/Vec.h>
00031 #include <sofa/core/objectmodel/BaseContext.h>
00032 #include <sofa/helper/vector.h>
00033 #include <iostream>
00034 #include <algorithm>
00035 
00036 
00037 
00038 namespace sofa
00039 {
00040 
00041 namespace defaulttype
00042 {
00043 
00044 using helper::vector;
00045 
00046 template<class TCoord, class TDeriv, class TReal = typename TCoord::value_type>
00047 class StdVectorTypes
00048 {
00049 public:
00050     typedef TCoord Coord;
00051     typedef TDeriv Deriv;
00052     typedef TReal Real;
00053     typedef vector<Coord> VecCoord;
00054     typedef vector<Deriv> VecDeriv;
00055     typedef vector<Real> VecReal;
00056 
00057 
00058     template <class T>
00059     class SparseData
00060     {
00061     public:
00062         SparseData(unsigned int _index, const T& _data): index(_index), data(_data){};
00063         SparseData(){};
00064         unsigned int index;
00065         T data;
00066     };
00067 
00068     typedef SparseData<Coord> SparseCoord;
00069     typedef SparseData<Deriv> SparseDeriv;
00070 
00071     typedef vector<SparseCoord> SparseVecCoord;
00072     typedef vector<SparseDeriv> SparseVecDeriv;
00073 
00075     typedef vector<SparseVecDeriv> VecConst;
00076     
00077     template<typename T>
00078     static void set(Coord& c, T x, T y, T z)
00079     {
00080     
00081         if (c.size() > 0)
00082             c[0] = (Real)x;
00083         if (c.size() > 1)
00084             c[1] = (Real)y;
00085         if (c.size() > 2)
00086             c[2] = (Real)z;
00087     }
00088     
00089     template<typename T>
00090     static void get(T& x, T& y, T& z, const Coord& c)
00091     {
00092       x = (c.size() > 0) ? (T) c[0] : (T) 0.0;
00093       y = (c.size() > 1) ? (T) c[1] : (T) 0.0;
00094       z = (c.size() > 2) ? (T) c[2] : (T) 0.0;
00095     }
00096     
00097     template<typename T>
00098     static void add(Coord& c, T x, T y, T z)
00099     {
00100         if (c.size() > 0)
00101             c[0] += (Real)x;
00102         if (c.size() > 1)
00103             c[1] += (Real)y;
00104         if (c.size() > 2)
00105             c[2] += (Real)z;
00106     }
00107     
00108     static const char* Name();
00109 
00110     static Coord interpolate(const helper::vector< Coord > &ancestors, const helper::vector< Real > &coefs)
00111     {
00112         assert(ancestors.size() == coefs.size());
00113             
00114         Coord c;
00115         
00116         for (unsigned int i = 0; i < ancestors.size(); i++)
00117         {
00118             c += ancestors[i] * coefs[i];
00119         }
00120 
00121         return c;
00122     }
00123 };
00124 
00126 template<class T>
00127 class ExtVectorAllocator
00128 {
00129 public:
00130     typedef T              value_type;
00131     typedef unsigned int   size_type;
00132     virtual ~ExtVectorAllocator() {}
00133     virtual void resize(value_type*& data, size_type size, size_type& maxsize, size_type& cursize)=0;
00134     virtual void close(value_type* data)=0;
00135 };
00136 
00140 template<class T>
00141 class ExtVector
00142 {
00143 public:
00144     typedef T              value_type;
00145     typedef unsigned int   size_type;
00146 
00147 protected:
00148     value_type* data;
00149     size_type   maxsize;
00150     size_type   cursize;
00151     ExtVectorAllocator<T>* allocator;
00152 public:
00153     explicit ExtVector(ExtVectorAllocator<T>* alloc = NULL) : data(NULL), maxsize(0), cursize(0), allocator(alloc) {}
00154     ExtVector(int size, ExtVectorAllocator<T>* alloc) : data(NULL), maxsize(0), cursize(0), allocator(alloc) { resize(size); }
00155     ~ExtVector() { if (allocator) allocator->close(data); }
00156     void setAllocator(ExtVectorAllocator<T>* alloc)
00157     {
00158         if (alloc != allocator)
00159         {
00160             if (cursize)
00161             {
00162                 value_type* oldData = data;
00163                 size_type size = cursize;
00164                 data = NULL;
00165                 maxsize = 0;
00166                 cursize = 0;
00167                 alloc->resize(data, size, maxsize, cursize);
00168                 std::copy(oldData, oldData+size, data);
00169                 if (allocator)
00170                     allocator->close(oldData);
00171             }
00172             allocator = alloc;
00173         }
00174     }
00175     void setData(value_type* d, size_type s) { data=d; maxsize=s; cursize=s; }
00176     T* getData() { return this->data; }
00177     const T* getData() const { return this->data; }
00178 
00179     value_type& operator[](size_type i) { return data[i]; }
00180     const value_type& operator[](size_type i) const { return data[i]; }
00181     size_type size() const { return cursize; }
00182     bool empty() const { return cursize==0; }
00183     void reserve(size_type size)
00184     {
00185         if (size <= maxsize)
00186             return;
00187         size_type temp = cursize;
00188         if (allocator)
00189             allocator->resize(data, size, maxsize, temp);
00190         else
00191         {
00192             std::cerr << "Error: invalid reserve request ("<<size<<">"<<maxsize<<") on external vector without allocator.\n";
00193         }
00194     }
00195     void resize(size_type size)
00196     {
00197         if (size <= maxsize)
00198             cursize = size;
00199         else if (allocator)
00200             allocator->resize(data, size, maxsize, cursize);
00201         else
00202         {
00203             cursize = maxsize;
00204             std::cerr << "Error: invalid resize request ("<<size<<">"<<maxsize<<") on external vector without allocator.\n";
00205         }
00206     }
00207     void clear()
00208     {
00209         resize(0);
00210     }
00211     void push_back(const T& v)
00212     {
00213         int i = this->size();
00214         resize(i+1);
00215         (*this)[i] = v;
00216     }
00217     T* begin() { return getData(); }
00218     const T* begin() const { return getData(); }
00219     T* end() { return getData()+size(); }
00220     const T* end() const { return getData()+size(); }
00221 
00222 
00224   inline friend std::ostream& operator<< ( std::ostream& os, const ExtVector<T>& vec )
00225   {
00226       if( vec.size()>0 ){
00227           for( unsigned int i=0; i<vec.size()-1; ++i ) os<<vec[i]<<" ";
00228           os<<vec[vec.size()-1];
00229       }
00230       return os;
00231   }
00232 
00234   inline friend std::istream& operator>> ( std::istream& in, ExtVector<T>& vec )
00235   {
00236       T t;
00237       vec.clear();
00238       while(in>>t){
00239           vec.push_back(t);
00240       }
00241       if( in.rdstate() & std::ios_base::eofbit ) { in.clear(); }
00242       return in;
00243   }
00244 
00245 };
00246 
00247 template<class T>
00248 class DefaultAllocator : public ExtVectorAllocator<T>
00249 {
00250 public:
00251     typedef typename ExtVectorAllocator<T>::value_type value_type;
00252     typedef typename ExtVectorAllocator<T>::size_type size_type;
00253     virtual void close(value_type* data)
00254     {
00255             if (data!=NULL) delete[] data;
00256             delete this;
00257     }
00258     virtual void resize(value_type*& data, size_type size, size_type& maxsize, size_type& cursize)
00259     {
00260         if (size > maxsize)
00261         {
00262             T* oldData = data;
00263             maxsize = (size > 2*maxsize ? size : 2*maxsize);
00264             data = new T[maxsize];
00265             if (cursize)
00266                 std::copy(oldData, oldData+cursize, data);
00267             //for (size_type i = 0 ; i < cursize ; ++i)
00268             //    data[i] = oldData[i];
00269             if (oldData!=NULL) delete[] oldData;
00270         }
00271         cursize = size;
00272     }
00273 };
00274 
00276 template<class T>
00277 class ResizableExtVector : public ExtVector<T>
00278 {
00279 public:
00280     typedef typename ExtVector<T>::value_type value_type;
00281     typedef typename ExtVector<T>::size_type size_type;
00282     ResizableExtVector()
00283     : ExtVector<T>(new DefaultAllocator<T>)
00284     {
00285     }
00286 };
00287 
00288 template<class TCoord, class TDeriv, class TReal = typename TCoord::value_type>
00289 class ExtVectorTypes
00290 {
00291 public:
00292     typedef TCoord Coord;
00293     typedef TDeriv Deriv;
00294     typedef TReal Real;
00295     typedef ResizableExtVector<Coord> VecCoord;
00296     typedef ResizableExtVector<Deriv> VecDeriv;
00297     typedef ResizableExtVector<Real> VecReal;
00298 
00299     template <class T>
00300     class SparseData
00301     {
00302     public:
00303         SparseData(unsigned int _index, const T& _data): index(_index), data(_data){};
00304         unsigned int index;
00305         T data;
00306     };
00307 
00308     typedef SparseData<Coord> SparseCoord;
00309     typedef SparseData<Deriv> SparseDeriv;
00310 
00311     typedef vector<SparseCoord> SparseVecCoord;
00312     typedef vector<SparseDeriv> SparseVecDeriv;
00313 
00315     typedef vector<SparseVecDeriv> VecConst;
00316     
00317     template<typename T>
00318     static void set(Coord& c, T x, T y, T z)
00319     {
00320     
00321         if (c.size() > 0)
00322             c[0] = (Real)x;
00323         if (c.size() > 1)
00324             c[1] = (Real)y;
00325         if (c.size() > 2)
00326             c[2] = (Real)z;
00327     }
00328     
00329     template<typename T>
00330     static void get(T& x, T& y, T& z, const Coord& c)
00331     {
00332       x = (c.size() > 0) ? (T) c[0] : (T) 0.0;
00333       y = (c.size() > 1) ? (T) c[1] : (T) 0.0;
00334       z = (c.size() > 2) ? (T) c[2] : (T) 0.0;
00335     }
00336     
00337     template<typename T>
00338     static void add(Coord& c, T x, T y, T z)
00339     {
00340         if (c.size() > 0)
00341             c[0] += (Real)x;
00342         if (c.size() > 1)
00343             c[1] += (Real)y;
00344         if (c.size() > 2)
00345             c[2] += (Real)z;
00346     }
00347     
00348     static const char* Name();
00349 
00350     static Coord interpolate(const helper::vector< Coord > & ancestors, const helper::vector< Real > & coefs)
00351     {
00352         assert(ancestors.size() == coefs.size());
00353             
00354         Coord c;
00355         
00356         for (unsigned int i = 0; i < ancestors.size(); i++)
00357         {
00358             c += ancestors[i] * coefs[i];
00359         }
00360 
00361         return c;
00362     }
00363 };
00364 
00365 //
00366 // 3D
00367 //
00368 
00370 typedef StdVectorTypes<Vec3d,Vec3d,double> Vec3dTypes;
00372 typedef StdVectorTypes<Vec3f,Vec3f,float> Vec3fTypes;
00373 
00374 template<> inline const char* Vec3dTypes::Name() { return "Vec3d"; }
00375 template<> inline const char* Vec3fTypes::Name() { return "Vec3f"; }
00376 
00378 typedef ExtVectorTypes<Vec3d,Vec3d,double> ExtVec3dTypes;
00380 typedef ExtVectorTypes<Vec3f,Vec3f,float> ExtVec3fTypes;
00381 
00382 template<> inline const char* ExtVec3dTypes::Name() { return "ExtVec3d"; }
00383 template<> inline const char* ExtVec3fTypes::Name() { return "ExtVec3f"; }
00384 
00385 //
00386 // 2D
00387 //
00388 
00390 typedef StdVectorTypes<Vec2d,Vec2d,double> Vec2dTypes;
00392 typedef StdVectorTypes<Vec2f,Vec2f,float> Vec2fTypes;
00393 
00394 template<> inline const char* Vec2dTypes::Name() { return "Vec2d"; }
00395 template<> inline const char* Vec2fTypes::Name() { return "Vec2f"; }
00396 
00398 typedef ExtVectorTypes<Vec2d,Vec2d,double> ExtVec2dTypes;
00400 typedef ExtVectorTypes<Vec2f,Vec2f,float> ExtVec2fTypes;
00401 
00402 template<> inline const char* ExtVec2dTypes::Name() { return "ExtVec2d"; }
00403 template<> inline const char* ExtVec2fTypes::Name() { return "ExtVec2f"; }
00404 
00405 //
00406 // 1D
00407 //
00408 
00410 typedef StdVectorTypes<Vec1d,Vec1d,double> Vec1dTypes;
00412 typedef StdVectorTypes<Vec1f,Vec1f,float> Vec1fTypes;
00413 
00414 template<> inline const char* Vec1dTypes::Name() { return "Vec1d"; }
00415 template<> inline const char* Vec1fTypes::Name() { return "Vec1f"; }
00416 
00418 typedef ExtVectorTypes<Vec1d,Vec1d,double> ExtVec1dTypes;
00420 typedef ExtVectorTypes<Vec1f,Vec1f,float> ExtVec1fTypes;
00421 
00422 template<> inline const char* ExtVec1dTypes::Name() { return "ExtVec1d"; }
00423 template<> inline const char* ExtVec1fTypes::Name() { return "ExtVec1f"; }
00424 
00425 //
00426 // 6D (3 coordinates + 3 angles)
00427 //
00428 
00430 typedef StdVectorTypes<Vec6d,Vec6d,double> Vec6dTypes;
00432 typedef StdVectorTypes<Vec6f,Vec6f,float> Vec6fTypes;
00433 
00434 template<> inline const char* Vec6dTypes::Name() { return "Vec6d"; }
00435 template<> inline const char* Vec6fTypes::Name() { return "Vec6f"; }
00436 
00438 typedef ExtVectorTypes<Vec6d,Vec6d,double> ExtVec6dTypes;
00440 typedef ExtVectorTypes<Vec6f,Vec6f,float> ExtVec6fTypes;
00441 
00442 template<> inline const char* ExtVec6dTypes::Name() { return "ExtVec6d"; }
00443 template<> inline const char* ExtVec6fTypes::Name() { return "ExtVec6f"; }
00444 
00445 #ifdef SOFA_FLOAT
00447 typedef Vec6fTypes Vec6Types;
00449 typedef Vec3fTypes Vec3Types;
00451 typedef Vec2fTypes Vec2Types;
00453 typedef Vec1fTypes Vec1Types;
00455 typedef ExtVec6fTypes ExtVec6Types;
00457 typedef ExtVec3fTypes ExtVec3Types;
00459 typedef ExtVec2fTypes ExtVec2Types;
00461 typedef ExtVec1fTypes ExtVec1Types;
00462 #else
00464 typedef Vec6dTypes Vec6Types;
00466 typedef Vec3dTypes Vec3Types;
00468 typedef Vec2dTypes Vec2Types;
00470 typedef Vec1dTypes Vec1Types;
00472 typedef ExtVec6dTypes ExtVec6Types;
00474 typedef ExtVec3dTypes ExtVec3Types;
00476 typedef ExtVec2dTypes ExtVec2Types;
00478 typedef ExtVec1dTypes ExtVec1Types;
00479 #endif
00480 } // namespace defaulttype
00481 
00482 namespace core
00483 {
00484 namespace componentmodel
00485 {
00486 namespace behavior
00487 {
00488 
00497 template<class Coord, class Deriv, class Vec, class M, class SV>
00498 Deriv inertiaForce( const SV& /*sv*/, const Vec& /*a*/, const M& /*m*/, const Coord& /*x*/, const Deriv& /*v*/ );
00499 
00501 template <>
00502 inline defaulttype::Vec<3, double> inertiaForce<
00503     defaulttype::Vec<3, double>,
00504     defaulttype::Vec<3, double>,
00505     objectmodel::BaseContext::Vec3,
00506     double,
00507     objectmodel::BaseContext::SpatialVector
00508 >
00509 (
00510     const objectmodel::BaseContext::SpatialVector& sv,
00511     const objectmodel::BaseContext::Vec3& a,
00512     const double& m,
00513     const defaulttype::Vec<3, double>& x,
00514     const defaulttype::Vec<3, double>& v
00515 )
00516 {
00517     const objectmodel::BaseContext::Vec3& omega=sv.getAngularVelocity();
00518     //std::cerr<<"inertiaForce, sv = "<<sv<<", omega ="<<omega<<", a = "<<a<<", m= "<<m<<", x= "<<x<<", v= "<<v<<std::endl;
00519     return -( a + omega.cross( omega.cross(x) + v*2 ))*m;
00520 }
00521 
00523 template <>
00524 inline defaulttype::Vec<3, float> inertiaForce<
00525     defaulttype::Vec<3, float>,
00526     defaulttype::Vec<3, float>,
00527     objectmodel::BaseContext::Vec3,
00528     float,
00529     objectmodel::BaseContext::SpatialVector
00530 >
00531 (
00532     const objectmodel::BaseContext::SpatialVector& sv,
00533     const objectmodel::BaseContext::Vec3& a,
00534     const float& m,
00535     const defaulttype::Vec<3, float>& x,
00536     const defaulttype::Vec<3, float>& v
00537 )
00538 {
00539     const objectmodel::BaseContext::Vec3& omega=sv.getAngularVelocity();
00540     //std::cerr<<"inertiaForce, sv = "<<sv<<", omega ="<<omega<<", a = "<<a<<", m= "<<m<<", x= "<<x<<", v= "<<v<<std::endl;
00541     return -( a + omega.cross( omega.cross(x) + v*2 ))*m;
00542 }
00543 
00545 template <>
00546 inline defaulttype::Vec<2, double> inertiaForce<
00547     defaulttype::Vec<2, double>,
00548     defaulttype::Vec<2, double>,
00549     objectmodel::BaseContext::Vec3,
00550     double,
00551     objectmodel::BaseContext::SpatialVector
00552 >
00553 (
00554     const objectmodel::BaseContext::SpatialVector& sv,
00555     const objectmodel::BaseContext::Vec3& a,
00556     const double& m,
00557     const defaulttype::Vec<2, double>& x,
00558     const defaulttype::Vec<2, double>& v
00559 )
00560 {
00561     double omega=(double)sv.getAngularVelocity()[2]; // z direction
00562     defaulttype::Vec<2, double> a2( (double)a[0], (double)a[1] );
00563     return -( a2 -( x*omega + v*2 )*omega )*m;
00564 }
00565 
00567 template <>
00568 inline defaulttype::Vec<2, float> inertiaForce<
00569     defaulttype::Vec<2, float>,
00570     defaulttype::Vec<2, float>,
00571     objectmodel::BaseContext::Vec3,
00572     float,
00573     objectmodel::BaseContext::SpatialVector
00574 >
00575 (
00576     const objectmodel::BaseContext::SpatialVector& sv,
00577     const objectmodel::BaseContext::Vec3& a,
00578     const float& m,
00579     const defaulttype::Vec<2, float>& x,
00580     const defaulttype::Vec<2, float>& v
00581 )
00582 {
00583     float omega=(float)sv.getAngularVelocity()[2]; // z direction
00584     defaulttype::Vec<2, float> a2( (float)a[0], (float)a[1] );
00585     return -( a2 -( x*omega + v*2 )*omega )*m;
00586 }
00587 
00588 } // namespace behavoir
00589 
00590 } // namespace componentmodel
00591 
00592 
00593 
00594 namespace objectmodel
00595 {
00596 
00597 // Specialization of Field::getValueTypeString() method to display smaller aliases 
00598 // The next line hides all those methods from the doxygen documentation
00600 
00601 template<>
00602 inline std::string BaseData::typeName< defaulttype::Vec1f >(const defaulttype::Vec1f *) { return "Vec1f"; }
00603 
00604 template<>
00605 inline std::string BaseData::typeName< std::vector< defaulttype::Vec1f > >(const std::vector< defaulttype::Vec1f > *) { return "vector<Vec1f>"; }
00606 
00607 template<>
00608 inline std::string BaseData::typeName< helper::vector< defaulttype::Vec1f > >(const helper::vector< defaulttype::Vec1f > *) { return "vector<Vec1f>"; }
00609 
00610 template<>
00611 inline std::string BaseData::typeName< defaulttype::Vec1d >(const defaulttype::Vec1d *) { return "Vec1d"; }
00612 
00613 template<>
00614 inline std::string BaseData::typeName< std::vector< defaulttype::Vec1d > >(const std::vector< defaulttype::Vec1d > *) { return "vector<Vec1d>"; }
00615 
00616 template<>
00617 inline std::string BaseData::typeName< helper::vector< defaulttype::Vec1d > >(const helper::vector< defaulttype::Vec1d > *) { return "vector<Vec1d>"; }
00618 
00619 template<>
00620 inline std::string BaseData::typeName< defaulttype::Vec2d >(const defaulttype::Vec2d *) { return "Vec2d"; }
00621 
00622 template<>
00623 inline std::string BaseData::typeName< std::vector< defaulttype::Vec2d > >(const std::vector< defaulttype::Vec2d > *) { return "vector<Vec2d>"; }
00624 
00625 template<>
00626 inline std::string BaseData::typeName< helper::vector< defaulttype::Vec2d > >(const helper::vector< defaulttype::Vec2d > *) { return "vector<Vec2d>"; }
00627 
00628 template<>
00629 inline std::string BaseData::typeName< defaulttype::Vec3d >(const defaulttype::Vec3d *) { return "Vec3d"; }
00630 
00631 template<>
00632 inline std::string BaseData::typeName< std::vector< defaulttype::Vec3d > >(const std::vector< defaulttype::Vec3d > *) { return "vector<Vec3d>"; }
00633 
00634 template<>
00635 inline std::string BaseData::typeName< helper::vector< defaulttype::Vec3d > >(const helper::vector< defaulttype::Vec3d > *) { return "vector<Vec3d>"; }
00636 
00637 template<>
00638 inline std::string BaseData::typeName< defaulttype::Vec6d >(const defaulttype::Vec6d *) { return "Vec6d"; }
00639 
00640 template<>
00641 inline std::string BaseData::typeName< std::vector< defaulttype::Vec6d > >(const std::vector< defaulttype::Vec6d > *) { return "vector<Vec6d>"; }
00642 
00643 template<>
00644 inline std::string BaseData::typeName< helper::vector< defaulttype::Vec6d > >(const helper::vector< defaulttype::Vec6d > *) { return "vector<Vec6d>"; }
00645 
00647 
00648 } // namespace objectmodel
00649 
00650 } // namespace core
00651 
00652 } // namespace sofa
00653 
00654 #endif

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