00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00076
00077
00078
00079
00080
00081
00082
00084
00085
00086
00087 #ifndef __VCGLIB_GRID_CLOSEST
00088 #define __VCGLIB_GRID_CLOSEST
00089
00090 #include <vcg/space/index/space_iterators.h>
00091
00092 namespace vcg{
00093
00094 template <class SPATIAL_INDEX, class OBJPOINTDISTFUNCTOR, class OBJMARKER>
00095 typename SPATIAL_INDEX::ObjPtr GridClosest(SPATIAL_INDEX &Si,
00096 OBJPOINTDISTFUNCTOR _getPointDistance,
00097 OBJMARKER & _marker,
00098 const typename OBJPOINTDISTFUNCTOR::QueryType & _p_obj,
00099 const typename SPATIAL_INDEX::ScalarType & _maxDist,
00100 typename SPATIAL_INDEX::ScalarType & _minDist,
00101 typename SPATIAL_INDEX:: CoordType &_closestPt)
00102 {
00103 typedef typename SPATIAL_INDEX::ObjPtr ObjPtr;
00104 typedef typename SPATIAL_INDEX::CoordType CoordType;
00105 typedef typename SPATIAL_INDEX::ScalarType ScalarType;
00106 typedef typename SPATIAL_INDEX::Box3x Box3x;
00107
00108 Point3<ScalarType> _p = OBJPOINTDISTFUNCTOR::Pos(_p_obj);
00109
00110 _minDist = _maxDist;
00111
00112 ObjPtr winner=NULL;
00113 _marker.UnMarkAll();
00114 ScalarType newradius = Si.voxel.Norm();
00115 ScalarType radius;
00116 Box3i iboxdone,iboxtodo;
00117 CoordType t_res;
00118 typename SPATIAL_INDEX::CellIterator first,last,l;
00119 if(Si.bbox.IsInEx(_p))
00120 {
00121 Point3i _ip;
00122 Si.PToIP(_p,_ip);
00123 Si.Grid( _ip[0],_ip[1],_ip[2], first, last );
00124 for(l=first;l!=last;++l)
00125 {
00126 ObjPtr elem=&(**l);
00127 if (!elem->IsD())
00128 {
00129 if (_getPointDistance((**l), _p_obj,_minDist, t_res))
00130 {
00131 winner=elem;
00132 _closestPt=t_res;
00133 newradius=_minDist;
00134 }
00135 _marker.Mark(elem);
00136 }
00137 }
00138 iboxdone=Box3i(_ip,_ip);
00139 }
00140
00141 int ix,iy,iz;
00142 Box3i ibox(Point3i(0,0,0),Si.siz-Point3i(1,1,1));
00143 do
00144 {
00145 radius=newradius;
00146 Box3x boxtodo=Box3x(_p,radius);
00147
00148 Si.BoxToIBox(boxtodo, iboxtodo);
00149 iboxtodo.Intersect(ibox);
00150 if(!boxtodo.IsNull())
00151 {
00152 for (ix=iboxtodo.min[0]; ix<=iboxtodo.max[0]; ix++)
00153 for (iy=iboxtodo.min[1]; iy<=iboxtodo.max[1]; iy++)
00154 for (iz=iboxtodo.min[2]; iz<=iboxtodo.max[2]; iz++)
00155 if(ix<iboxdone.min[0] || ix>iboxdone.max[0] ||
00156 iy<iboxdone.min[1] || iy>iboxdone.max[1] ||
00157 iz<iboxdone.min[2] || iz>iboxdone.max[2] )
00158 {
00159 Si.Grid( ix, iy, iz, first, last );
00160 for(l=first;l!=last;++l) if (!(**l).IsD())
00161 {
00162 ObjPtr elem=&(**l);
00163 if (!elem->IsD())
00164 {
00165 if( ! _marker.IsMarked(elem))
00166 {
00167 if (_getPointDistance((**l), _p_obj, _minDist, t_res))
00168 {
00169 winner=elem;
00170 _closestPt=t_res;
00171 };
00172 _marker.Mark(elem);
00173 }
00174 }
00175 }
00176 }
00177 }
00178 if(!winner) newradius=radius+Si.voxel.Norm();
00179 else newradius = _minDist;
00180 iboxdone=iboxtodo;
00181 }
00182 while (_minDist>radius);
00183
00184 return winner;
00185 }
00186
00187 template <class SPATIALINDEXING,class OBJPOINTDISTFUNCTOR, class OBJMARKER,
00188 class OBJPTRCONTAINER, class DISTCONTAINER, class POINTCONTAINER>
00189 unsigned int GridGetKClosest(SPATIALINDEXING &_Si,
00190 OBJPOINTDISTFUNCTOR & _getPointDistance,
00191 OBJMARKER & _marker,
00192 const unsigned int _k,
00193 const typename SPATIALINDEXING::CoordType & _p,
00194 const typename SPATIALINDEXING::ScalarType & _maxDist,
00195 OBJPTRCONTAINER & _objectPtrs,
00196 DISTCONTAINER & _distances,
00197 POINTCONTAINER & _points)
00198 {
00199 typedef vcg::ClosestIterator<SPATIALINDEXING,OBJPOINTDISTFUNCTOR,OBJMARKER> ClosestIteratorType;
00200 ClosestIteratorType Cli=ClosestIteratorType(_Si,_getPointDistance);
00201 Cli.SetMarker(_marker);
00202 Cli.Init(_p,_maxDist);
00203 unsigned int i=0;
00204 _objectPtrs.clear();
00205 _distances.clear();
00206 _points.clear();
00207 while ((!Cli.End())&&(i<_k))
00208 {
00209 _objectPtrs.push_back(&(*Cli));
00210 _distances.push_back(Cli.Dist());
00211 _points.push_back(Cli.NearestPoint());
00212 ++Cli;
00213 i++;
00214 }
00215 return (i);
00216 }
00217
00218 template <class SPATIALINDEXING,class OBJRAYISECTFUNCTOR, class OBJMARKER>
00219 typename SPATIALINDEXING::ObjPtr GridDoRay(SPATIALINDEXING &_Si,
00220 OBJRAYISECTFUNCTOR &_rayIntersector,
00221 OBJMARKER &_marker,
00222 const Ray3<typename SPATIALINDEXING::ScalarType> & _ray,
00223 const typename SPATIALINDEXING::ScalarType & _maxDist,
00224 typename SPATIALINDEXING::ScalarType & _t)
00225 {
00226 typedef vcg::RayIterator<SPATIALINDEXING,OBJRAYISECTFUNCTOR,OBJMARKER> RayIteratorType;
00227 RayIteratorType RayIte=RayIteratorType(_Si,_rayIntersector,_maxDist);
00228 RayIte.SetMarker(_marker);
00229 RayIte.Init(_ray);
00230
00231 if (!RayIte.End())
00232 {
00233 _t=RayIte.Dist();
00234 return(&(*RayIte));
00235 }
00236 return 0;
00237 }
00238
00239
00240 template <class SPATIALINDEXING, class OBJPOINTDISTFUNCTOR, class OBJMARKER, class OBJPTRCONTAINER, class DISTCONTAINER, class POINTCONTAINER>
00241 unsigned int GridGetInSphere(SPATIALINDEXING &_Si,
00242 OBJPOINTDISTFUNCTOR & _getPointDistance,
00243 OBJMARKER & _marker,
00244 const typename SPATIALINDEXING::CoordType & _p,
00245 const typename SPATIALINDEXING::ScalarType & _r,
00246 OBJPTRCONTAINER & _objectPtrs,
00247 DISTCONTAINER & _distances,
00248 POINTCONTAINER & _points)
00249 {
00250 typedef vcg::ClosestIterator<SPATIALINDEXING,OBJPOINTDISTFUNCTOR,OBJMARKER> ClosestIteratorType;
00251 ClosestIteratorType Cli=ClosestIteratorType(_Si,_getPointDistance);
00252 Cli.SetMarker(_marker);
00253 Cli.Init(_p,_r);
00254 _objectPtrs.clear();
00255 _distances.clear();
00256 _points.clear();
00257 while (!Cli.End())
00258 {
00259 _objectPtrs.push_back(&(*Cli));
00260 _distances.push_back(Cli.Dist());
00261 _points.push_back(Cli.NearestPoint());
00262 ++Cli;
00263 }
00264 return ((int)_objectPtrs.size());
00265 }
00266
00267 template <class SPATIALINDEXING,class OBJMARKER, class OBJPTRCONTAINER>
00268 unsigned int GridGetInBox(SPATIALINDEXING &_Si,
00269 OBJMARKER & _marker,
00270 const vcg::Box3<typename SPATIALINDEXING::ScalarType> &_bbox,
00271 OBJPTRCONTAINER & _objectPtrs)
00272 {
00273 typename SPATIALINDEXING::CellIterator first,last,l;
00274 _objectPtrs.clear();
00275 vcg::Box3i ibbox;
00276 Box3i Si_ibox(Point3i(0,0,0),_Si.siz-Point3i(1,1,1));
00277 _Si.BoxToIBox(_bbox, ibbox);
00278 ibbox.Intersect(Si_ibox);
00279 _marker.UnMarkAll();
00280 if (ibbox.IsNull())
00281 return 0;
00282 else
00283 {
00284 int ix,iy,iz;
00285 for (ix=ibbox.min[0]; ix<=ibbox.max[0]; ix++)
00286 for (iy=ibbox.min[1]; iy<=ibbox.max[1]; iy++)
00287 for (iz=ibbox.min[2]; iz<=ibbox.max[2]; iz++)
00288 {
00289 _Si.Grid( ix, iy, iz, first, last );
00290 for(l=first;l!=last;++l)
00291 if (!(**l).IsD())
00292 {
00293 typename SPATIALINDEXING::ObjPtr elem=&(**l);
00294 vcg::Box3<typename SPATIALINDEXING::ScalarType> box_elem;
00295 elem->GetBBox(box_elem);
00296 if(( ! _marker.IsMarked(elem))&&(box_elem.Collide(_bbox))){
00297 _objectPtrs.push_back(elem);
00298 _marker.Mark(elem);
00299 }
00300 }
00301 }
00302 return (static_cast<unsigned int>(_objectPtrs.size()));
00303 }
00304 }
00305
00306 }
00307 #endif
00308