diff --git a/vcg/space/index/index2D/grid_closest_2D.h b/vcg/space/index/index2D/grid_closest_2D.h index 92159311..afdfb7ed 100644 --- a/vcg/space/index/index2D/grid_closest_2D.h +++ b/vcg/space/index/index2D/grid_closest_2D.h @@ -24,114 +24,177 @@ #ifndef __VCGLIB_GRID_CLOSEST #define __VCGLIB_GRID_CLOSEST -#include +#include +#include namespace vcg{ - template - unsigned int GridGetInBox2D(SPATIALINDEXING &_Si, - OBJMARKER & _marker, - const vcg::Box2 &_bbox, - OBJPTRCONTAINER & _objectPtrs, - bool update_global_mark=true) - { - typename SPATIALINDEXING::CellIterator first,last,l; - //_objectPtrs.clear(); - vcg::Box2i ibbox; - Box2i Si_ibox(Point2i(0,0),_Si.siz-Point2i(1,1)); - _Si.BoxToIBox(_bbox, ibbox); - ibbox.Intersect(Si_ibox); +template +unsigned int GridGetInBox2D(SPATIALINDEXING &_Si, + OBJMARKER & _marker, + const vcg::Box2 &_bbox, + OBJPTRCONTAINER & _objectPtrs, + bool update_global_mark=true) +{ + typename SPATIALINDEXING::CellIterator first,last,l; + //_objectPtrs.clear(); + vcg::Box2i ibbox; + Box2i Si_ibox(Point2i(0,0),_Si.siz-Point2i(1,1)); + _Si.BoxToIBox(_bbox, ibbox); + ibbox.Intersect(Si_ibox); - if (update_global_mark) - _marker.UnMarkAll(); + if (update_global_mark) + _marker.UnMarkAll(); - if (ibbox.IsNull()) - return 0; - else - { - int ix,iy; - for (ix=ibbox.min[0]; ix<=ibbox.max[0]; ix++) - for (iy=ibbox.min[1]; iy<=ibbox.max[1]; iy++) - { - _Si.Grid( ix, iy, first, last ); - for(l=first;l!=last;++l) - if (!(**l).IsD()) - { - typename SPATIALINDEXING::ObjPtr elem=&(**l); - vcg::Box2 box_elem; - elem->GetBBox(box_elem); - if(( ! _marker.IsMarked(elem))&&(box_elem.Collide(_bbox))){ - _objectPtrs.push_back(elem); - _marker.Mark(elem); - } - } - } - return (static_cast(_objectPtrs.size())); - } - } - - /*template - unsigned int GridGetInBoxes2D(SPATIALINDEXING &_Si, - OBJMARKER & _marker, - const std::vector > &_bbox, - OBJPTRCONTAINER & _objectPtrs) - { - typename SPATIALINDEXING::CellIterator first,last,l; - _objectPtrs.clear(); - _marker.UnMarkAll(); - for (int i=0;i<_bbox.size();i++) - GridGetInBox2D(_Si,_marker,_bbox[i],_objectPtrs,false); - return (static_cast(_objectPtrs.size())); - }*/ - - template - unsigned int GridGetInBoxes2D(SPATIALINDEXING &_Si, - OBJMARKER & _marker, - const std::vector > &_bbox, - OBJPTRCONTAINER & _objectPtrs) - { - typename SPATIALINDEXING::CellIterator first,last,l; - _objectPtrs.clear(); - _marker.UnMarkAll(); - std::vector cells; - - for (int i=0;i<_bbox.size();i++) + if (ibbox.IsNull()) + return 0; + else + { + int ix,iy; + for (ix=ibbox.min[0]; ix<=ibbox.max[0]; ix++) + for (iy=ibbox.min[1]; iy<=ibbox.max[1]; iy++) { - vcg::Box2i ibbox; - Box2i Si_ibox(Point2i(0,0),_Si.siz-Point2i(1,1)); - _Si.BoxToIBox(_bbox[i], ibbox); - ibbox.Intersect(Si_ibox); - - if (ibbox.IsNull())continue; - int ix,iy; - - for (ix=ibbox.min[0]; ix<=ibbox.max[0]; ix++) - for (iy=ibbox.min[1]; iy<=ibbox.max[1]; iy++) - cells.push_back(vcg::Point2i(ix,iy)); - } - //printf("%d \n",cells.size()); - std::sort(cells.begin(),cells.end()); - std::vector::iterator it=std::unique(cells.begin(),cells.end()); - cells.resize( it - cells.begin() ); - - for (int i=0;i box_elem; + box_elem=elem->BBox(); + if (update_global_mark) + { + if(( ! _marker.IsMarked(elem))&&(box_elem.Collide(_bbox))) + { + _objectPtrs.push_back(elem); + _marker.Mark(elem); + } + }else + { + if(box_elem.Collide(_bbox)) + _objectPtrs.push_back(elem); + } } - } } - return (static_cast(_objectPtrs.size())); - } + return (static_cast(_objectPtrs.size())); + } +} - }//end namespace vcg +template +typename SPATIAL_INDEX::ObjPtr GridClosest2D(SPATIAL_INDEX &Si, + OBJPOINTDISTFUNCTOR _getPointDistance, + OBJMARKER & _marker, + const typename OBJPOINTDISTFUNCTOR::QueryType & _p_obj, + const typename SPATIAL_INDEX::ScalarType & _maxDist, + typename SPATIAL_INDEX::ScalarType & _minDist, + typename SPATIAL_INDEX:: CoordType &_closestPt) +{ + typedef typename SPATIAL_INDEX::ObjPtr ObjPtr; + typedef SPATIAL_INDEX SpatialIndex; + typedef typename SPATIAL_INDEX::CoordType CoordType; + typedef typename SPATIAL_INDEX::ScalarType ScalarType; + typedef typename SPATIAL_INDEX::Box2x Box2x; + + Point2 _p = OBJPOINTDISTFUNCTOR::Pos(_p_obj); + + // Initialize min_dist with _maxDist to exploit early rejection test. + _minDist = _maxDist; + + ObjPtr winner=NULL; + _marker.UnMarkAll(); + ScalarType newradius = Si.voxel.Norm(); + ScalarType radius; + Box2i iboxdone,iboxtodo; + CoordType t_res; + typename SPATIAL_INDEX::CellIterator first,last,l; + if(Si.bbox.IsInEx(_p)) + { + Point2i _ip; + Si.PToIP(_p,_ip); + Si.Grid( _ip[0],_ip[1], first, last ); + for(l=first;l!=last;++l) + { + ObjPtr elem=&(**l); + if (!elem->IsD()) + { + if (_getPointDistance((**l), _p_obj,_minDist, t_res)) + { + winner=elem; + _closestPt=t_res; + newradius=_minDist; // + } + _marker.Mark(elem); + } + } + iboxdone=Box2i(_ip,_ip); + } + + int ix,iy; + Box2i ibox(Point2i(0,0),Si.siz-Point2i(1,1)); + + do + { + radius=newradius; + Box2x boxtodo=Box2x(_p,radius); + //boxtodo.Intersect(Si.bbox); + Si.BoxToIBox(boxtodo, iboxtodo); + iboxtodo.Intersect(ibox); + if(!boxtodo.IsNull()) + { + for (ix=iboxtodo.min[0]; ix<=iboxtodo.max[0]; ix++) + for (iy=iboxtodo.min[1]; iy<=iboxtodo.max[1]; iy++) + if(ixiboxdone.max[0] || // this test is to avoid to re-process already analyzed cells. + iyiboxdone.max[1] ) + { + Si.Grid( ix, iy, first, last ); + for(l=first;l!=last;++l) if (!(**l).IsD()) + { + ObjPtr elem=&(**l); + if (!elem->IsD()) + { + if( ! _marker.IsMarked(elem)) + { + if (_getPointDistance((**l), _p_obj, _minDist, t_res)) + { + winner=elem; + _closestPt=t_res; + }; + _marker.Mark(elem); + } + } + } + } + } + if(!winner) newradius=radius+Si.voxel.Norm(); + else newradius = _minDist; + iboxdone=iboxtodo; + } + while (_minDist>radius); + + return winner; +} + +template +typename SPATIALINDEXING::ObjPtr GridDoRay(SPATIALINDEXING &_Si, + OBJRAYISECTFUNCTOR &_rayIntersector, + OBJMARKER &_marker, + const Ray2 & _ray, + const typename SPATIALINDEXING::ScalarType & _maxDist, + typename SPATIALINDEXING::ScalarType & _t) +{ + typedef vcg::RayIterator2D RayIteratorType; + RayIteratorType RayIte=RayIteratorType(_Si,_rayIntersector,_maxDist,_marker); + RayIte.Init(_ray); + + if (!RayIte.End()) + { + _t=RayIte.Dist(); + return(&(*RayIte)); + } + return NULL; +} + + +}//end namespace vcg #endif