Jafar
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
VoxelSpace.hpp
00001 /* $Id$ */
00002 
00003 #include <kernel/jafarMacro.hpp>
00004 #include <geom/Atom.hpp>
00005 #include <map>
00006 #include <climits>
00007 
00008 namespace jafar {
00009   namespace geom {
00015     template<int _dimension_, class _T_, int _level_ = _dimension_>
00016     class VoxelMultiDimensionStorage {
00017         typedef boost::numeric::ublas::bounded_vector<int, _dimension_> IndexVec;
00018         typedef std::map<int, VoxelMultiDimensionStorage<_dimension_, _T_, _level_ - 1> > MapVMD;
00019         typedef typename MapVMD::iterator MapVMD_it;
00020         typedef typename MapVMD::const_iterator MapVMD_cit;
00021       public:
00022         VoxelMultiDimensionStorage() : m_firstIndex( INT_MAX ), m_lastIndex( INT_MIN )
00023         {
00024         }
00025         inline _T_& operator[]( IndexVec index )
00026         {
00027           return m_storage[ index(_level_ - 1) ][ index ] ;
00028         }
00037         template<class _TFunctor_>
00038         inline void iterateCreateVoxels( IndexVec _firstIndex, IndexVec _lastIndex, _TFunctor_* _functor)
00039         {
00040           // Update the first index and last index
00041           int firstIndex_ = _firstIndex( _level_ - 1);
00042           int lastIndex_ = _lastIndex( _level_  - 1 );
00043           if( firstIndex_ < m_firstIndex ) m_firstIndex = firstIndex_;
00044           if( lastIndex_ > m_lastIndex ) m_lastIndex = lastIndex_;
00045           // Iterate and create voxels as needed
00046           for(int i = firstIndex_; i <= lastIndex_; ++i)
00047           {
00048             m_storage[i].iterateCreateVoxels(_firstIndex, _lastIndex, _functor);
00049           }
00050         }
00059         template<class _TFunctor_>
00060         inline void iterateVoxels( IndexVec _firstIndex, IndexVec _lastIndex, _TFunctor_* _functor) const
00061         {
00062           int firstIndex_ = _firstIndex(_level_ - 1);
00063           if( firstIndex_ < m_firstIndex ) firstIndex_ = m_firstIndex;
00064           int lastIndex_ = _lastIndex( _level_  - 1 );
00065           for(MapVMD_cit it = m_storage.find( firstIndex_ ); it->first <= lastIndex_ and it != m_storage.end(); ++it)
00066           {
00067             it->second.iterateVoxels<_TFunctor_>( _firstIndex, _lastIndex, _functor );
00068           }
00069         }
00070         template<class _TFunctor_>
00071         inline void iterateAllVoxels( _TFunctor_* _functor) const
00072         {
00073           for(MapVMD_cit it = m_storage.begin(); it != m_storage.end(); ++it)
00074           {
00075             it->second.iterateAllVoxels<_TFunctor_>( _functor );
00076           }
00077         }
00078         template<class _TFunctor_>
00079         inline void iterateAllVoxels( _TFunctor_* _functor)
00080         {
00081           for(MapVMD_it it = m_storage.begin(); it != m_storage.end(); ++it)
00082           {
00083             it->second.iterateAllVoxels<_TFunctor_>( _functor );
00084           }
00085         }
00086       private:
00087         int m_firstIndex;
00088         int m_lastIndex;
00089         MapVMD m_storage;
00090     };
00091     // Specialization of VoxelMultiDimensionStorage to stop recursions
00092     template< int _dimension_, class _T_>
00093     class VoxelMultiDimensionStorage<_dimension_, _T_, 1> {
00094         typedef boost::numeric::ublas::bounded_vector<int, _dimension_> IndexVec;
00095         typedef std::map<int, _T_ > MapObject;
00096         typedef typename MapObject::iterator MapObject_it;
00097         typedef typename MapObject::const_iterator MapObject_cit;
00098       public:
00099         VoxelMultiDimensionStorage<_dimension_, _T_, 1>() : m_firstIndex( INT_MAX ), m_lastIndex( INT_MIN )
00100         {
00101         }
00102         _T_& operator[]( IndexVec index ) { return storage(index(0)); }
00103         template<class _TFunctor_>
00104         inline void iterateCreateVoxels( IndexVec _firstIndex, IndexVec _lastIndex, _TFunctor_* _functor)
00105         {
00106           // Update the first index and last index
00107           int firstIndex_ = _firstIndex( 0);
00108           int lastIndex_ = _lastIndex( 0 );
00109           if( firstIndex_ < m_firstIndex ) m_firstIndex = firstIndex_;
00110           if( lastIndex_ > m_lastIndex ) m_lastIndex = lastIndex_;
00111           for(int i = firstIndex_; i <= lastIndex_; ++i)
00112           {
00113             _functor->apply( &storage[i] );
00114           }
00115         }
00116         template<class _TFunctor_>
00117         inline void iterateVoxels( IndexVec _firstIndex, IndexVec _lastIndex, _TFunctor_* _functor) const
00118         {
00119           int firstIndex_ = _firstIndex( 0 );
00120           if( firstIndex_ < m_firstIndex ) firstIndex_ = m_firstIndex;
00121           int lastIndex_ = _lastIndex( 0 );
00122           for(MapObject_cit it = storage.find(firstIndex_); it->first <= lastIndex_ and it != storage.end(); ++it)
00123           {
00124             _functor->apply( &it->second );
00125           }
00126         }
00127         template<class _TFunctor_>
00128         inline void iterateAllVoxels( _TFunctor_* functor)
00129         {
00130           for(MapObject_it it = storage.begin(); it != storage.end(); ++it)
00131           {
00132             functor->apply( &it->second );
00133           }
00134         }
00135         template<class _TFunctor_>
00136         inline void iterateAllVoxels( _TFunctor_* functor) const
00137         {
00138           for(MapObject_cit it = storage.begin(); it != storage.end(); ++it)
00139           {
00140             functor->apply( &it->second );
00141           }
00142         }
00143       private:
00144         int m_firstIndex;
00145         int m_lastIndex;
00146         MapObject storage;
00147     };
00153     template<int _dimension_, class _TObject_>
00154     struct AtomBoundingBoxGetter {
00155       public:
00156         inline static BoundingBox<_dimension_> boundingBox( const _TObject_* obj)
00157         {
00158           return obj->atom().boundingBox();
00159         }
00160     };
00161     template<int _dimension_, class _TObject_, class _BoundingBoxGetter_>
00162     class VoxelSpace;
00163     template<int _dimension_, class _TObject_, class _BoundingBoxGetter_>
00164     std::ostream& operator<<(std::ostream& s, const VoxelSpace<_dimension_, _TObject_, _BoundingBoxGetter_>&);
00175     template<int _dimension_, class _TObject_, class _BoundingBoxGetter_>
00176     class VoxelSpace {
00177       friend std::ostream& operator<<<>(std::ostream& s, const VoxelSpace<_dimension_, _TObject_, _BoundingBoxGetter_>&);
00178 
00179       typedef geom::BoundingBox<_dimension_> BoundingBoxD;
00180       typedef typename Atom<_dimension_>::HomogenousVecD HomogenousVecD;
00181       typedef boost::numeric::ublas::bounded_vector<int, _dimension_> IndexVec;
00182       typedef std::list<_TObject_*> ObjectsList;
00183       typedef typename ObjectsList::iterator ObjectsList_it;
00184       typedef typename ObjectsList::const_iterator ObjectsList_cit;
00185     private:
00186     struct InsertFunctor;
00187     struct RemoveFunctor;
00188       public:
00189         class Voxel {
00190           friend class VoxelSpace<_dimension_, _TObject_, _BoundingBoxGetter_>;
00191           friend struct VoxelSpace<_dimension_, _TObject_, _BoundingBoxGetter_>::InsertFunctor;
00192           friend struct VoxelSpace<_dimension_, _TObject_, _BoundingBoxGetter_>::RemoveFunctor;
00193           public:
00194             Voxel()
00195             {
00196             }
00197             const std::list<_TObject_*>& objects() const { return m_objects; }
00198           private:
00199             void insertObject(_TObject_* object) { m_objects.push_back( object); }
00200             void removeObject(_TObject_* object) { m_objects.remove( object); }
00201           private:
00202             ObjectsList m_objects;
00203         };
00204       public:
00208         VoxelSpace(double voxelSize_);
00209         ~VoxelSpace();
00210       public:
00215         void insertObject(_TObject_* object);
00219         void removeObject(_TObject_* object);
00223         std::list<const Voxel*> voxelsCountaining( const _TObject_* object) const;
00224         std::list<_TObject_*> objectsIn( const BoundingBoxD&) const;
00225       private:
00229         IndexVec indexFor(const HomogenousVecD& v ) const;
00230       private:
00234         JFR_DEFINE_PARAM_RO(double, voxelSize)
00235       private:
00236         VoxelMultiDimensionStorage<_dimension_, Voxel> m_voxels;
00237       private:
00238         // Functors
00239         struct RemoveFunctor {
00240           _TObject_* object;
00241           void apply( Voxel* v)
00242           {
00243             v->removeObject( object );
00244           }
00245         };
00249         struct InsertFunctor {
00250           _TObject_* object;
00251           void apply( Voxel* v)
00252           {
00253             v->insertObject( object );
00254           }
00255         };
00259         struct FindVoxelsFunctor {
00260           std::list< const Voxel*> voxels;
00261           void apply( const Voxel* v)
00262           {
00263             voxels.push_back( v);
00264           }
00265         };
00269         struct FindObjectsFunctor {
00270           std::list< _TObject_*> objects;
00271           BoundingBoxD boundingBox;
00272           void apply( const Voxel* v)
00273           {
00274             for( ObjectsList_cit it = v->objects().begin();
00275                  it != v->objects().end(); ++it)
00276             {
00277               if( std::find(objects.begin(), objects.end(), *it) == objects.end())
00278               {
00279                 if( _BoundingBoxGetter_::boundingBox( *it ).overlap( boundingBox ) )
00280                 {
00281                   objects.push_back( *it );
00282                 }
00283               }
00284             }
00285           }
00286         };
00287         struct StreamFunctor {
00288           StreamFunctor(std::ostream& _stream) : stream(_stream) {}
00289           std::ostream& stream;
00290           void apply( const Voxel* v)
00291           {
00292             stream << "Voxel : { ";
00293             for( ObjectsList_cit it = v->objects().begin();
00294                  it != v->objects().end(); ++it)
00295             {
00296               if( it != v->objects().begin()) stream << " , ";
00297               stream << "( " << *it << " " << _BoundingBoxGetter_::boundingBox( *it ) << " " << **it << " )";
00298             }
00299             stream << " } ";
00300           }
00301         };
00302     };
00303   }
00304 }
00305 
00306 #include "geom/VoxelSpaceImpl.hpp"
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on Wed Oct 15 2014 00:37:19 for Jafar by doxygen 1.7.6.1
LAAS-CNRS