00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef __VCGLIB_UGRID_2D
00025 #define __VCGLIB_UGRID_2D
00026
00027 #include <vector>
00028 #include <algorithm>
00029 #include <stdio.h>
00030
00031 #include <vcg/space/box2.h>
00032 #include <vcg/space/line2.h>
00033 #include <vcg/space/index/grid_util2d.h>
00034 #include <vcg/space/index/grid_closest2d.h>
00035
00036 namespace vcg {
00037
00038 template < class OBJTYPE, class FLT=float >
00039 class GridStaticPtr2D: public BasicGrid2D<FLT>, SpatialIndex2D<OBJTYPE,FLT>
00040 {
00041 public:
00042 typedef OBJTYPE ObjType;
00043 typedef ObjType* ObjPtr;
00044 typedef typename ObjType::ScalarType ScalarType;
00045 typedef Point2<ScalarType> CoordType;
00046 typedef Box2<ScalarType> Box2x;
00047 typedef GridStaticPtr2D<OBJTYPE,FLT> MyGridType;
00048 typedef typename std::vector<OBJTYPE*>::iterator CellIterator;
00049 std::vector<std::vector<std::vector<OBJTYPE*> > > data;
00050
00051 private:
00052
00053
00054
00055 void Add( const int x,
00056 const int y,
00057 ObjType *elem)
00058 {
00059 assert((x>=0)&&(x<(int)data.size()));
00060 assert((y>=0)&&(y<(int)data[x].size()));
00061 data[x][y].push_back(elem);
00062 }
00063
00064 template <class OBJITER>
00065 inline void Set(const OBJITER & _oBegin,
00066 const OBJITER & _oEnd,
00067 const Box2x &_bbox,
00068 Point2i _siz)
00069 {
00070 this->bbox=_bbox;
00071 this->siz=_siz;
00072
00073
00074
00075 this->dim = this->bbox.max - this->bbox.min;
00076 this->voxel.X() = (this->dim.X()/(ScalarType)this->siz.X());
00077 this->voxel.Y() = (this->dim.Y()/(ScalarType)this->siz.Y());
00078
00080 data.resize(this->siz.X());
00081 for (size_t x=0;x<data.size();x++)
00082 data[x].resize(this->siz.Y());
00083
00084
00085 OBJITER IteObj;
00086 for (IteObj=_oBegin;IteObj!=_oEnd;IteObj++)
00087 {
00088 Box2<ScalarType> Box2D=(*IteObj).BBox();
00089
00090
00091 Point2i minIndex=this->GridP(Box2D.min);
00092 Point2i maxIndex=this->GridP(Box2D.max);
00093
00094 for (int x=minIndex.X();x<=maxIndex.X();x++)
00095 for (int y=minIndex.Y();y<=maxIndex.Y();y++)
00096 Add(x,y,&(*IteObj));
00097 }
00098 }
00099
00100 template <class OBJITER>
00101 inline void Set(const OBJITER & _oBegin,
00102 const OBJITER & _oEnd,
00103 const Box2x &_bbox)
00104 {
00105 int _size=(int)std::distance<OBJITER>(_oBegin,_oEnd);
00106
00107 Point2<FLT> _dim = _bbox.max - _bbox.min;
00108
00109 Point2i _siz;
00110
00111 BestDim2D( _size, _dim, _siz );
00112
00113 Set(_oBegin,_oEnd,_bbox,_siz);
00114 }
00115
00116 public:
00117
00118 void Grid( const int x, const int y,
00119 CellIterator & first,
00120 CellIterator & last )
00121 {
00122 first = data[x][y].begin();
00123 last = data[x][y].end();
00124 }
00125
00126 void Grid( const Point2i pi,
00127 CellIterator & first,
00128 CellIterator & last )
00129 {
00130 return Grid(pi.X(),pi.Y(),first,last);
00131 }
00132
00133 template <class OBJITER>
00134 inline void Set(const OBJITER & _oBegin,
00135 const OBJITER & _oEnd)
00136 {
00137 Box2x bbox;
00138
00139 OBJITER IteObj;
00140 for (IteObj=_oBegin;IteObj!=_oEnd;IteObj++)
00141 bbox.Add((*IteObj).BBox());
00142
00143 ScalarType diag=bbox.Diag();
00144 bbox.Offset(diag*0.01);
00145 Set<OBJITER>(_oBegin,_oEnd,bbox);
00146 }
00147
00148 template <class OBJPOINTDISTFUNCTOR, class OBJMARKER>
00149 ObjPtr GetClosest(OBJPOINTDISTFUNCTOR & _getPointDistance,
00150 OBJMARKER & _marker,
00151 const typename OBJPOINTDISTFUNCTOR::QueryType & _p,
00152 const ScalarType & _maxDist,
00153 ScalarType & _minDist,
00154 CoordType & _closestPt)
00155 {
00156 return (vcg::GridClosest2D<MyGridType,OBJPOINTDISTFUNCTOR,OBJMARKER>(*this,_getPointDistance,_marker, _p,_maxDist,_minDist,_closestPt));
00157 }
00158
00159 template <class OBJMARKER, class OBJPTRCONTAINER>
00160 unsigned int GetInBox(OBJMARKER & _marker,
00161 const vcg::Box2<ScalarType> _bbox,
00162 OBJPTRCONTAINER & _objectPtrs)
00163 {
00164 return(vcg::GridGetInBox2D<MyGridType,OBJMARKER,OBJPTRCONTAINER>
00165 (*this,_marker,_bbox,_objectPtrs));
00166 }
00167
00168
00169 template <class OBJRAYISECTFUNCTOR, class OBJMARKER>
00170 ObjPtr DoRay(OBJRAYISECTFUNCTOR & _rayIntersector, OBJMARKER & _marker,
00171 const Ray2<ScalarType> & _ray, const ScalarType & _maxDist,
00172 ScalarType & _t)
00173 {
00174 return(vcg::GridDoRay2D<MyGridType,OBJRAYISECTFUNCTOR,OBJMARKER>(*this,_rayIntersector,_marker,_ray,_maxDist,_t));
00175 }
00176
00177
00178 };
00179
00180 }
00181
00182 #endif