00001
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
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
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
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
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
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"