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_GRID_CLOSEST_2D
00025 #define __VCGLIB_GRID_CLOSEST_2D
00026
00027 #include <vcg/space/index/space_iterators2d.h>
00028 #include <vcg/space/intersection2.h>
00029
00030 namespace vcg{
00031
00032
00033 template <class SPATIALINDEXING,class OBJMARKER, class OBJPTRCONTAINER>
00034 unsigned int GridGetInBox2D(SPATIALINDEXING &_Si,
00035 OBJMARKER & _marker,
00036 const vcg::Box2<typename SPATIALINDEXING::ScalarType> &_bbox,
00037 OBJPTRCONTAINER & _objectPtrs,
00038 bool update_global_mark=true)
00039 {
00040 typename SPATIALINDEXING::CellIterator first,last,l;
00041
00042 vcg::Box2i ibbox;
00043 Box2i Si_ibox(Point2i(0,0),_Si.siz-Point2i(1,1));
00044 _Si.BoxToIBox(_bbox, ibbox);
00045 ibbox.Intersect(Si_ibox);
00046
00047 if (update_global_mark)
00048 _marker.UnMarkAll();
00049
00050 if (ibbox.IsNull())
00051 return 0;
00052 else
00053 {
00054 int ix,iy;
00055 for (ix=ibbox.min[0]; ix<=ibbox.max[0]; ix++)
00056 for (iy=ibbox.min[1]; iy<=ibbox.max[1]; iy++)
00057 {
00058 _Si.Grid( ix, iy, first, last );
00059 for(l=first;l!=last;++l)
00060 if (!(**l).IsD())
00061 {
00062 typename SPATIALINDEXING::ObjPtr elem=&(**l);
00063 vcg::Box2<typename SPATIALINDEXING::ScalarType> box_elem;
00064 elem->GetBBox(box_elem);
00065 if (update_global_mark)
00066 {
00067 if(( ! _marker.IsMarked(elem))&&(box_elem.Collide(_bbox)))
00068 {
00069 _objectPtrs.push_back(elem);
00070 _marker.Mark(elem);
00071 }
00072 }else
00073 {
00074 if(box_elem.Collide(_bbox))
00075 _objectPtrs.push_back(elem);
00076 }
00077 }
00078 }
00079 return (static_cast<unsigned int>(_objectPtrs.size()));
00080 }
00081 }
00082
00083 template <class SPATIAL_INDEX, class OBJPOINTDISTFUNCTOR, class OBJMARKER>
00084 typename SPATIAL_INDEX::ObjPtr GridClosest2D(SPATIAL_INDEX &Si,
00085 OBJPOINTDISTFUNCTOR _getPointDistance,
00086 OBJMARKER & _marker,
00087 const typename OBJPOINTDISTFUNCTOR::QueryType & _p_obj,
00088 const typename SPATIAL_INDEX::ScalarType & _maxDist,
00089 typename SPATIAL_INDEX::ScalarType & _minDist,
00090 typename SPATIAL_INDEX:: CoordType &_closestPt)
00091 {
00092 typedef typename SPATIAL_INDEX::ObjPtr ObjPtr;
00093 typedef SPATIAL_INDEX SpatialIndex;
00094 typedef typename SPATIAL_INDEX::CoordType CoordType;
00095 typedef typename SPATIAL_INDEX::ScalarType ScalarType;
00096 typedef typename SPATIAL_INDEX::Box2x Box2x;
00097
00098 Point2<ScalarType> _p = OBJPOINTDISTFUNCTOR::Pos(_p_obj);
00099
00100
00101 _minDist = _maxDist;
00102
00103 ObjPtr winner=NULL;
00104 _marker.UnMarkAll();
00105 ScalarType newradius = Si.voxel.Norm();
00106 ScalarType radius;
00107 Box2i iboxdone,iboxtodo;
00108 CoordType t_res;
00109 typename SPATIAL_INDEX::CellIterator first,last,l;
00110 if(Si.bbox.IsInEx(_p))
00111 {
00112 Point2i _ip;
00113 Si.PToIP(_p,_ip);
00114 Si.Grid( _ip[0],_ip[1], first, last );
00115 for(l=first;l!=last;++l)
00116 {
00117 ObjPtr elem=&(**l);
00118 if (!elem->IsD())
00119 {
00120 if (_getPointDistance((**l), _p_obj,_minDist, t_res))
00121 {
00122 winner=elem;
00123 _closestPt=t_res;
00124 newradius=_minDist;
00125 }
00126 _marker.Mark(elem);
00127 }
00128 }
00129 iboxdone=Box2i(_ip,_ip);
00130 }
00131
00132 int ix,iy;
00133 Box2i ibox(Point2i(0,0),Si.siz-Point2i(1,1));
00134
00135 do
00136 {
00137 radius=newradius;
00138 Box2x boxtodo=Box2x(_p,radius);
00139
00140 Si.BoxToIBox(boxtodo, iboxtodo);
00141 iboxtodo.Intersect(ibox);
00142 if(!boxtodo.IsNull())
00143 {
00144 for (ix=iboxtodo.min[0]; ix<=iboxtodo.max[0]; ix++)
00145 for (iy=iboxtodo.min[1]; iy<=iboxtodo.max[1]; iy++)
00146 if(ix<iboxdone.min[0] || ix>iboxdone.max[0] ||
00147 iy<iboxdone.min[1] || iy>iboxdone.max[1] )
00148 {
00149 Si.Grid( ix, iy, first, last );
00150 for(l=first;l!=last;++l) if (!(**l).IsD())
00151 {
00152 ObjPtr elem=&(**l);
00153 if (!elem->IsD())
00154 {
00155 if( ! _marker.IsMarked(elem))
00156 {
00157 if (_getPointDistance((**l), _p_obj, _minDist, t_res))
00158 {
00159 winner=elem;
00160 _closestPt=t_res;
00161 };
00162 _marker.Mark(elem);
00163 }
00164 }
00165 }
00166 }
00167 }
00168 if(!winner) newradius=radius+Si.voxel.Norm();
00169 else newradius = _minDist;
00170 iboxdone=iboxtodo;
00171 }
00172 while (_minDist>radius);
00173
00174 return winner;
00175 }
00176
00177 template <class SPATIALINDEXING,class OBJRAYISECTFUNCTOR, class OBJMARKER>
00178 typename SPATIALINDEXING::ObjPtr GridDoRay2D(SPATIALINDEXING &_Si,
00179 OBJRAYISECTFUNCTOR &_rayIntersector,
00180 OBJMARKER &_marker,
00181 const Ray2<typename SPATIALINDEXING::ScalarType> & _ray,
00182 const typename SPATIALINDEXING::ScalarType & _maxDist,
00183 typename SPATIALINDEXING::ScalarType & _t)
00184 {
00185 typedef vcg::RayIterator2D<SPATIALINDEXING,OBJRAYISECTFUNCTOR,OBJMARKER> RayIteratorType;
00186 RayIteratorType RayIte=RayIteratorType(_Si,_rayIntersector,_maxDist,_marker);
00187 RayIte.Init(_ray);
00188
00189 if (!RayIte.End())
00190 {
00191 _t=RayIte.Dist();
00192 return(&(*RayIte));
00193 }
00194 return NULL;
00195 }
00196
00197
00198 }
00199 #endif
00200