SpatialGridContainer.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 :: Modules                               *
00020 *                                                                             *
00021 * Authors: The SOFA Team and external contributors (see Authors.txt)          *
00022 *                                                                             *
00023 * Contact information: contact@sofa-framework.org                             *
00024 ******************************************************************************/
00025 //
00026 // C++ Interface: SpatialGridContainer
00027 //
00028 // Description: 
00029 //
00030 //
00031 // Author: The SOFA team <http://www.sofa-framework.org>, (C) 2006
00032 //
00033 // Copyright: See COPYING file that comes with this distribution
00034 //
00035 //
00036 
00037 #ifndef SOFA_COMPONENT_CONTAINER_SPATIALGRIDCONTAINER_H
00038 #define SOFA_COMPONENT_CONTAINER_SPATIALGRIDCONTAINER_H
00039 
00040 #include <sofa/helper/system/config.h>
00041 #include <sofa/defaulttype/Vec3Types.h>
00042 #include <sofa/core/objectmodel/BaseObject.h>
00043 #include <sofa/core/objectmodel/Event.h>
00044 #include <sofa/core/componentmodel/behavior/MechanicalState.h>
00045 #include <sofa/helper/rmath.h>
00046 #include <list>
00047 
00048 
00049 // I need C++0x !!!
00050 #ifndef HASH_NAMESPACE
00051 #  ifdef _MSC_VER
00052 #    if _MSC_VER >= 1300
00053 #      include <hash_map>
00054 //#      if _MSC_VER >= 1400
00055 #        define HASH_NAMESPACE stdext
00056 //#      else
00057 //#        define HASH_NAMESPACE std
00058 //#      endif
00059 #    else
00060 #      include <map>
00061 #      define HASH_NAMESPACE std
00062 #    endif
00063 #  else
00064 #    if __GNUC__ > 4 || (__GNUC__ == 4 && (__GNUC_MINOR__ >= 3 ))
00065 #      include <tr1/unordered_map>
00066 #      define HASH_NAMESPACE std::tr1
00067 #    else
00068 #      include <ext/hash_map>
00069 #      define HASH_NAMESPACE __gnu_cxx
00070 #    endif
00071 #  endif
00072 #endif
00073 
00074 namespace sofa
00075 {
00076 
00077 namespace component
00078 {
00079 
00080 namespace container
00081 {
00082 
00083 using namespace sofa::defaulttype;
00084 
00085 class EmptyClass
00086 {
00087 public:
00088     void clear() {}
00089 };
00090 
00091 template<class TDataTypes>
00092 class SpatialGridTypes
00093 {
00094 public:
00095     typedef TDataTypes DataTypes;
00096     typedef typename DataTypes::VecCoord VecCoord;
00097     typedef typename DataTypes::Coord Coord;
00098     typedef typename DataTypes::Real Real;
00099     //typedef EmptyClass                 CellData;
00100     typedef EmptyClass                 GridData;
00101     typedef EmptyClass                 ParticleField;
00102     class CellData
00103     {
00104     public:
00105         void clear()
00106         {
00107         }
00108         void add(ParticleField* /*field*/, int /*i*/, Real /*r2*/, Real /*h2*/)
00109         {
00110         }
00111     };
00112 
00113 //  class NeighborListener
00114 //  {
00115 //      public:
00116 //          void addNeighbor(int /*i1*/, int /*i2*/, Real /*r2*/, Real /*h2*/)
00117 //          {
00118 //          }
00119 //  };
00120 
00121     enum { GRIDDIM_LOG2 = 3 };
00122 };
00123 
00124 template<class DataTypes>
00125 class SpatialGrid
00126 {
00127 public:
00128     typedef typename DataTypes::Real Real;
00129     typedef typename DataTypes::Coord Coord;
00130     typedef typename DataTypes::VecCoord VecCoord;
00131     typedef typename DataTypes::CellData CellData;
00132     typedef typename DataTypes::GridData GridData;
00133     //typedef typename DataTypes::NeighborListener NeighborListener;
00134     typedef typename DataTypes::ParticleField ParticleField;
00135 
00136 public:
00137     SpatialGrid(Real cellWidth);
00138 
00139     void begin();
00140 
00141     void add(int i, const Coord& pos, bool allNeighbors = false);
00142 
00143     void end();
00144 
00145     void update(const VecCoord& x)
00146     {
00147     begin();
00148     for (unsigned int i=0;i<x.size();i++)
00149     {
00150         add(i, x[i]);
00151     }
00152     end();
00153     }
00154     
00155     void draw();
00156 
00157     template<class NeighborListener>
00158     void findNeighbors(NeighborListener* dest, Real dist);
00159 
00160     void computeField(ParticleField* field, Real dist);
00161 
00165     void reorderIndices(helper::vector<unsigned int>* old2new, helper::vector<unsigned int>* new2old);
00166 
00167     enum { GRIDDIM_LOG2 = DataTypes::GRIDDIM_LOG2, GRIDDIM = 1<<GRIDDIM_LOG2 };
00168     enum { NCELL = GRIDDIM*GRIDDIM*GRIDDIM };
00169     enum { DX = 1, DY = GRIDDIM, DZ = GRIDDIM*GRIDDIM };
00170     
00171     class Entry
00172     {
00173     public:
00174         int index;
00175         Coord pos;
00176         Entry(int i, const Coord& p) : index(i), pos(p) {}
00177     };
00178     
00179     class Cell
00180     {
00181     public:
00182         std::list<Entry> plist;
00183         CellData data;
00184         void clear()
00185         {
00186             plist.clear();
00187             data.clear();
00188         }
00189     };
00190 
00191     class Grid
00192     {
00193     public:
00194         Cell cell[NCELL];
00195         const Grid* neighbors[6];
00196         bool empty;
00197         GridData data;
00198         Grid() : empty(true) { std::fill(neighbors,neighbors+6, this); }
00199         void clear()
00200         {
00201             empty = true;
00202             for (unsigned int i=0; i<NCELL; i++)
00203                 cell[i].clear();
00204             data.clear();
00205         }
00206     };
00207 
00208     static Grid emptyGrid;
00209 
00210     class Key : public helper::fixed_array<int, 3>
00211     {
00212     public:
00213         Key() {}
00214         Key(int i1, int i2, int i3) { (*this)[0] = i1; (*this)[1] = i2; (*this)[2] = i3; };
00215         bool operator==(const Key& a) const
00216         {
00217             return (*this)[0] == a[0] && (*this)[1] == a[1] && (*this)[2] == a[2];
00218         }
00219     };
00220 
00221     static std::size_t hash(const Key& x)
00222     {
00223 //      return x[0]^x[1]^x[2];
00224         const unsigned int p0 = 73856093; // large prime numbers
00225         const unsigned int p1 = 19349663;
00226         const unsigned int p2 = 83492791;
00227         return (p0*x[0])^(p1*x[1])^(p2*x[2]);
00228     }
00229 
00230     class key_hash_fun
00231 #ifdef _MSC_VER
00232     : public HASH_NAMESPACE::hash_compare<Key>
00233     {
00234     public:
00235         //enum
00236         //{ // parameters for hash table
00237         //  bucket_size = 4, // 0 < bucket_size
00238         //  min_buckets = 8
00239         //}; // min_buckets = 2 ^^ N, 0 < N
00240         inline bool operator()(const Key& s1, const Key& s2) const
00241         {
00242             for (unsigned int i=0;i<s1.size();++i)
00243                 if (s1[i] < s2[i]) return true;
00244                 else if (s1[i] > s2[i]) return false;
00245             return false; // s1 == s2
00246         }
00247 #else
00248     {
00249     public:
00250 #endif
00251         inline std::size_t operator()(const Key &s) const
00252         {
00253             return hash(s);
00254         }
00255     };
00256 
00257 
00258 #ifndef _MSC_VER     
00259 #    if __GNUC__ > 4 || (__GNUC__ == 4 && (__GNUC_MINOR__ >= 3 ))        //hash_map is deprecated since gcc-4.3
00260         typedef HASH_NAMESPACE::unordered_map<Key, Grid*, key_hash_fun> Map;          
00261 #    else       
00262         typedef HASH_NAMESPACE::hash_map<Key, Grid*, key_hash_fun> Map;  
00263 #    endif       
00264 #else               
00265         typedef HASH_NAMESPACE::hash_map<Key, Grid*, key_hash_fun> Map;       
00266 #endif
00267        
00268        
00269     
00270     typedef typename Map::const_iterator const_iterator;
00271     typedef typename Map::iterator iterator;
00272     
00273     const_iterator gridBegin() const { return map.begin(); }
00274     const_iterator gridEnd() const { return map.end(); }
00275     
00276     iterator gridBegin() { return map.begin(); }
00277     iterator gridEnd() { return map.end(); }
00278     
00279     Real getCellWidth() const { return cellWidth; }
00280     Real getInvCellWidth() const { return invCellWidth; }
00281 
00282 protected:
00283     Map map;
00284     const Real cellWidth;
00285     const Real invCellWidth;
00286 
00287     const Grid* findGrid(const Key& k) const;
00288 
00289     Grid* getGrid(const Key& k);
00290 
00291     Cell* getCell(const Coord& x);
00292 
00293     const Cell* getCell(const Grid* g, int x, int y, int z);
00294 
00295     template<class NeighborListener>
00296     void findNeighbors(NeighborListener* dest, const Real dist2, const Cell** cellsBegin, const Cell** cellsEnd);
00297 
00298 };
00299 
00300 template<class DataTypes>
00301 class SpatialGridContainer : public virtual core::objectmodel::BaseObject
00302 {
00303 public:
00304     typedef typename DataTypes::Real Real;
00305     typedef typename DataTypes::Coord Coord;
00306     typedef typename DataTypes::VecCoord VecCoord;
00307     typedef SpatialGridTypes<DataTypes> GridTypes;
00308     typedef SpatialGrid< GridTypes > Grid;
00309     Grid* grid;
00310     Data<Real> d_cellWidth;
00311     Data<bool> d_showGrid;
00312     Data<bool> d_autoUpdate;
00313     Data<bool> d_sortPoints;
00314 
00317     template<class T>
00318     static bool canCreate(T*& obj, core::objectmodel::BaseContext* context, core::objectmodel::BaseObjectDescription* arg)
00319     {
00320         if (dynamic_cast<core::componentmodel::behavior::MechanicalState<DataTypes>*>(context->getMechanicalState()) == NULL)
00321             return false;
00322         return core::objectmodel::BaseObject::canCreate(obj, context, arg);
00323     }
00324 
00325     SpatialGridContainer();
00326     virtual ~SpatialGridContainer();
00327 
00328     virtual void init();
00329     virtual void reinit();
00330     virtual void draw();
00331     virtual void handleEvent(sofa::core::objectmodel::Event* event);
00332 
00333     Grid* getGrid() { return grid; }
00334     void updateGrid(const VecCoord& x)
00335     {
00336         grid->update(x);
00337     //grid->begin();
00338     //for (unsigned int i=0;i<x.size();i++)
00339     //{
00340     //    grid->add(i, x[i]);
00341     //}
00342     //grid->end();
00343     }
00344     template<class NeighborListener>
00345     void findNeighbors(NeighborListener* listener, Real r)
00346     {
00347     grid->findNeighbors(listener, r);
00348     }
00349     bool sortPoints();
00350 
00351     virtual std::string getTemplateName() const
00352     {
00353       return templateName(this);
00354     }
00355 
00356     static std::string templateName(const SpatialGridContainer<DataTypes>* = NULL)
00357     {
00358       return DataTypes::Name();
00359     }
00360 protected:
00361     core::componentmodel::behavior::MechanicalState<DataTypes>* mstate;
00362 };
00363 
00364 } // namespace container
00365 
00366 } // namespace component
00367 
00368 } // namespace sofa
00369 
00370 #endif

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