grid_closest.h
Go to the documentation of this file.
00001 /****************************************************************************
00002 * VCGLib                                                            o o     *
00003 * Visual and Computer Graphics Library                            o     o   *
00004 *                                                                _   O  _   *
00005 * Copyright(C) 2005                                                \/)\/    *
00006 * Visual Computing Lab                                            /\/|      *
00007 * ISTI - Italian National Research Council                           |      *
00008 *                                                                    \      *
00009 * All rights reserved.                                                      *
00010 *                                                                           *
00011 * This program is free software; you can redistribute it and/or modify      *
00012 * it under the terms of the GNU General Public License as published by      *
00013 * the Free Software Foundation; either version 2 of the License, or         *
00014 * (at your option) any later version.                                       *
00015 *                                                                           *
00016 * This program is distributed in the hope that it will be useful,           *
00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of            *
00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             *
00019 * GNU General Public License (http://www.gnu.org/licenses/gpl.txt)          *
00020 * for more details.                                                         *
00021 *                                                                           *
00022 ****************************************************************************/
00023 /****************************************************************************
00024 History
00025 
00026 $Log: not supported by cvs2svn $
00027 Revision 1.16  2006/10/02 09:34:03  cignoni
00028 Re-added diff 1.12 by Pietroni (cancelled by previous rollback):
00029 in GridDoRay function the RayIterator must be initialized with maximum distance
00030 
00031 Revision 1.15  2006/10/02 09:28:45  cignoni
00032 Reverted to version 1.10 to nullify dangerous marfr960's changes
00033 
00034 Revision 1.10  2006/05/17 12:48:52  pietroni
00035 corrected bug in GridGetInBox function
00036 
00037 Revision 1.9  2006/01/27 09:58:47  corsini
00038 fix signed/unsigned mismatch
00039 
00040 Revision 1.8  2005/12/06 18:00:39  pietroni
00041 added deleted objects control for GridClosest() function call
00042 
00043 Revision 1.7  2005/12/02 00:30:27  cignoni
00044 Corrected typename usage and removed excess ';' from end of template functions, for gcc compiling
00045 
00046 Revision 1.6  2005/10/03 13:57:32  pietroni
00047 added GridGetInSphere and GridGetInBox functions
00048 
00049 Revision 1.5  2005/10/02 23:18:06  cignoni
00050 Small bug in the computation of the intersection between the todo box and the grid bbox that failed for extrema points.
00051 
00052 Revision 1.4  2005/09/30 15:12:16  cignoni
00053 Completely rewrote the GridClosest, now it:
00054 - works for point out of the grid
00055 - expands the box in a distance coherent way
00056 - does not re-visit already visited cells
00057 - shorter code!!
00058 ( still to be tested :) )
00059 
00060 Revision 1.3  2005/09/30 13:15:48  pietroni
00061 added functions:
00062 - GetKClosest
00063 - DoRay
00064 
00065 Revision 1.2  2005/09/28 08:27:11  cignoni
00066 Added a control to avoid multiple check of the same cells during radial expansion
00067 Still miss some code to properly initialize when point is out of the BBox of the grid.
00068 
00069 Revision 1.1  2005/09/27 15:09:38  cignoni
00070 First Version
00071 
00072 
00073 ****************************************************************************/
00074 
00076 //@param _p a 3d point
00077 //@param _maxDist maximum distance not to search beyond.
00078 //@param _getPointDistance (templated type) a functor object used to calculate distance from a grid object to the point _p.
00079 //@param _minDist the returned closest distance
00080 //@param _closestPt the returned closest point
00081 //@return The closest element
00082 //*/
00084 //      A DISTFUNCT object must implement an operator () with signature:
00085 //              bool operator () (const ObjType& obj, const CoordType & _p, ScalarType & min_dist, CoordType & _closestPt);
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     // Initialize min_dist with _maxDist to exploit early rejection test.
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))  // <-- NEW: use of distance functor
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       //boxtodo.Intersect(Si.bbox);
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] ||  // this test is to avoid to re-process already analyzed cells.
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   }//end namespace vcg
00307 #endif
00308 


shape_reconstruction
Author(s): Roberto Martín-Martín
autogenerated on Sat Jun 8 2019 18:31:29