From 51d36a04516f94f865a4e04ba1b1417d46784bc1 Mon Sep 17 00:00:00 2001 From: ganovelli Date: Mon, 10 May 2004 14:57:23 +0000 Subject: [PATCH] created --- vcg/space/index/ugrid.h | 655 ---------------------------------------- 1 file changed, 655 deletions(-) delete mode 100644 vcg/space/index/ugrid.h diff --git a/vcg/space/index/ugrid.h b/vcg/space/index/ugrid.h deleted file mode 100644 index 10ee97a9..00000000 --- a/vcg/space/index/ugrid.h +++ /dev/null @@ -1,655 +0,0 @@ -/**************************************************************************** -* VCGLib o o * -* Visual and Computer Graphics Library o o * -* _ O _ * -* Copyright(C) 2004 \/)\/ * -* Visual Computing Lab /\/| * -* ISTI - Italian National Research Council | * -* \ * -* All rights reserved. * -* * -* This program is free software; you can redistribute it and/or modify * -* it under the terms of the GNU General Public License as published by * -* the Free Software Foundation; either version 2 of the License, or * -* (at your option) any later version. * -* * -* This program is distributed in the hope that it will be useful, * -* but WITHOUT ANY WARRANTY; without even the implied warranty of * -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) * -* for more details. * -* * -****************************************************************************/ -/**************************************************************************** - History - -$Log: not supported by cvs2svn $ -****************************************************************************/ - -#ifndef __VCGLIB_UGRID -#define __VCGLIB_UGRID - -namespace vcg { - - /** Static Uniform Grid - A spatial search structure for a accessing a container of objects. It is based on a uniform grid overlayed over a protion of space. - The grid partion the space into cells. Cells contains just pointers to the object that are stored elsewhere. - The set of object is meant to be static and pointer stable. - Useful for situation were many space related query are issued over the same dataset (ray tracing, measuring distances between meshes, re-detailing ecc.). Works well for distribution that ar reasonably uniform. - How to use it: - - */ -template < class ContainerType > -class UGrid -{ -public: - - /** Internal class for keeping the first pointer of object. - Definizione Link dentro la griglia. Classe di supporto per UGrid. - */ - class Link - { - public: - /// Costruttore di default - inline Link(){}; - /// Costruttore con inizializzatori - inline Link( ContainerType::iterator const nt, const int ni ){ - assert(ni>=0); - t = nt; - i = ni; - }; - - - inline bool operator < ( const Link & l ) const{ return i < l.i; } - inline bool operator <= ( const Link & l ) const{ return i <= l.i; } - inline bool operator > ( const Link & l ) const{ return i > l.i; } - inline bool operator >= ( const Link & l ) const{ return i >= l.i; } - inline bool operator == ( const Link & l ) const{ return i == l.i; } - inline bool operator != ( const Link & l ) const{ return i != l.i; } - - inline ContainerType::iterator & Elem() { - return t; - } - inline int & Index() { - return i; - } - - private: - /// Puntatore all'elemento T - ContainerType::iterator t; - /// Indirizzo del voxel dentro la griglia - int i; - - - };//end class Link - - typedef ContainerType::value_type ObjType; - typedef ObjType::ScalarType ScalarType; - typedef Point3 Point3x; - typedef Box3 Box3x; - typedef Line3 Line3x; - - Box3x bbox; - Point3x dim; /// Dimensione spaziale (lunghezza lati) del bbox - Point3i siz; /// Dimensioni griglia in celle - Point3x voxel; /// Dimensioni di una cella - - /// Insieme di tutti i links - vector links; - /// Griglia vera e propria - vector grid; - - /// Dato un punto, ritorna la cella che lo contiene - inline Link ** Grid( const Point3d & p ) - { - int x = int( (p[0]-bbox.min[0])/voxel[0] ); - int y = int( (p[1]-bbox.min[1])/voxel[1] ); - int z = int( (p[2]-bbox.min[2])/voxel[2] ); - -#ifndef NDEBUG - if ( x<0 || x>=siz[0] || y<0 || y>=siz[1] || z<0 || z>=siz[2] ) - return NULL; - else -#endif - - return grid.begin() + ( x+siz[0]*(y+siz[1]*z) ); - } - /// Date le coordinate ritorna la cella - inline Link ** Grid( const int x, const int y, const int z ) - { -#ifndef NDEBUG - if ( x<0 || x>=siz[0] || y<0 || y>=siz[1] || z<0 || z>=siz[2] ) - assert(0); - //return NULL; - else -#endif - assert(x+siz[0]*(y+siz[1]*z0) { - printf("\n%d rays (%f faces in %f voxel per ray)\n", - n_rays, - double(n_traversed_elem)/n_rays, - double(n_traversed_voxel)/n_rays); - printf("HIT: %d rays (%d%%) (%f faces in %f voxel per ray)\n", - n_rays_hit, - (n_rays_hit*100)/n_rays, - double(n_traversed_elem_hit)/n_rays_hit, - double(n_traversed_voxel_hit)/n_rays_hit); - } - } -#endif - - void ShowStats(FILE *fp) - { - // Conto le entry - int nentry = 0; - Hist H; - H.SetRange(0,1000,1000); - int pg; - for(pg=0;pg0.5) radius=(1.0-radius); radius*=voxel[0]; - - /*ScalarType radio_if[6]; - radio_if[0]= (dx-double(ix) )*voxel[0] ; - radio_if[1]= (dy-double(iy) )*voxel[1] ; - radio_if[2]= (dz-double(iz) )*voxel[2] ; - radio_if[3]= (1.0+double(ix)-dx)*voxel[0] ; - radio_if[4]= (1.0+double(iy)-dy)*voxel[1] ; - radio_if[5]= (1.0+double(iz)-dz)*voxel[2] ;*/ - - ScalarType - tmp=dy-ScalarType(iy); if (tmp>0.5) tmp=1.0-tmp; tmp*=voxel[1]; if (radius>tmp) radius=tmp; - tmp=dz-ScalarType(iz); if (tmp>0.5) tmp=1.0-tmp; tmp*=voxel[2]; if (radius>tmp) radius=tmp; - - Point3x t_res; - //ScalarType min_dist=1e10; - T* winner=NULL; - - Link *first, *last, *l; - if ((ix>=0) && (iy>=0) && (iz>=0) && (ixElem()->Dist(p,min_dist,t_res)) { - winner=&*(l->Elem()); - res=t_res; - - } - }; - }; - - //return winner; - - Point3i done_min=Point3i(ix,iy,iz), done_max=Point3i(ix,iy,iz); - - //printf("."); - - while (min_dist>radius) { - //if (dy-ScalarType(iy)) - done_min[0]--; if (done_min[0]<0) done_min[0]=0; - done_min[1]--; if (done_min[1]<0) done_min[1]=0; - done_min[2]--; if (done_min[2]<0) done_min[2]=0; - done_max[0]++; if (done_max[0]>=siz[0]-1) done_max[0]=siz[0]-1; - done_max[1]++; if (done_max[1]>=siz[1]-1) done_max[1]=siz[1]-1; - done_max[2]++; if (done_max[2]>=siz[2]-1) done_max[2]=siz[2]-1; - radius+=voxel_min; - //printf("+"); - for (ix=done_min[0]; ix<=done_max[0]; ix++) - for (iy=done_min[1]; iy<=done_max[1]; iy++) - for (iz=done_min[2]; iz<=done_max[2]; iz++) - { - Grid( ix, iy, iz, first, last ); - for(l=first;l!=last;++l) - { - if (l->Elem()->Dist(p,min_dist,t_res)) { - winner=&*(l->Elem()); - res=t_res; - }; - }; - } - }; - return winner; - }; - - T * DoRay( Line3x & ray, double & dist , double &p_a, double &p_b) - { - int ix,iy,iz; - double gx,gy,gz; - - if(!bbox.IsIn(ray.orig)) - { - //printf("."); - - Point3x ip; - if(Intersection(bbox,ray,ip)) - { - ix = int( (ip.x() - bbox.min.x())/voxel.x() ); - iy = int( (ip.y() - bbox.min.y())/voxel.y() ); - iz = int( (ip.z() - bbox.min.z())/voxel.z() ); - if(ix<0) ix = 0; - if(iy<0) iy = 0; - if(iz<0) iz = 0; - if(ix>=siz[0]) ix = siz[0]-1; - if(iy>=siz[1]) iy = siz[1]-1; - if(iz>=siz[2]) iz = siz[2]-1; - } - else - return 0; - } - else - { - /* Indici di voxel */ - ix = int( (ray.orig.x() - bbox.min.x())/voxel.x() ); - iy = int( (ray.orig.y() - bbox.min.y())/voxel.y() ); - iz = int( (ray.orig.z() - bbox.min.z())/voxel.z() ); - } - - /* Punti goal */ - if(ray.dire.x()>0.0) gx=double(ix+1)*voxel.x()+bbox.min.x(); - else gx=double(ix )*voxel.x()+bbox.min.x(); - if(ray.dire.y()>0.0) gy=double(iy+1)*voxel.y()+bbox.min.y(); - else gy=double(iy )*voxel.y()+bbox.min.y(); - if(ray.dire.z()>0.0) gz=double(iz+1)*voxel.z()+bbox.min.z(); - else gz=double( iz )*voxel.z()+bbox.min.z(); - - const ScalarType MAXFLOAT = 1e50; - const ScalarType EPSILON = 1e-50; - - /* Parametri della linea */ - double tx,ty,tz; - if( fabs(ray.dire.x())>EPSILON ) tx = (gx-ray.orig.x())/ray.dire.x(); - else tx = MAXFLOAT; - if( fabs(ray.dire.y())>EPSILON ) ty = (gy-ray.orig.y())/ray.dire.y(); - else ty = MAXFLOAT; - if( fabs(ray.dire.z())>EPSILON ) tz = (gz-ray.orig.z())/ray.dire.z(); - else tz = MAXFLOAT; - - T * bestf = NULL; - -#ifdef MONITOR_GRID - int n_traversed_voxel0=0,n_traversed_elem0=0; - n_rays++; -#endif - for(;;) - { - Link *first, *last, *l; - Grid( ix, iy, iz, first, last ); -#ifdef MONITOR_GRID - n_traversed_voxel++;n_traversed_voxel0++; -#endif - for(l=first;l!=last;++l) - { -#ifdef MONITOR_GRID - n_traversed_elem++;n_traversed_elem0++; -#endif - //return &(*(l->Elem())); - if(l->Elem()->Intersect(ray,dist, p_a, p_b)) { -#ifdef MONITOR_GRID - n_traversed_voxel_hit+=n_traversed_voxel0; - n_traversed_elem_hit+=n_traversed_elem0; - n_rays_hit++; -#endif - - return &(*(l->Elem())); - //{ - // bestf = &(*(l->Elem())); break; - //} - } - //if(bestf) break; - } - - if( tx=siz[0]) break; } - tx = (gx-ray.orig.x())/ray.dire.x(); - } else if( ty=siz[1]) break; } - ty = (gy-ray.orig.y())/ray.dire.y(); - } else { - if(ray.dire.z()<0.0) { gz -= voxel.z(); --iz; if(iz<0 ) break; } - else { gz += voxel.z(); ++iz; if(iz>=siz[2]) break; } - tz = (gz-ray.orig.z())/ray.dire.z(); - } - } - return bestf; - } - - - /// Inserisce una mesh nella griglia. Nota: prima bisogna - /// chiamare SetBBox che setta dim in maniera corretta - void Set( S & s ) - { - Set(s,s.size()); - } - - - /// Inserisce una mesh nella griglia. Nota: prima bisogna - /// chiamare SetBBox che setta dim in maniera corretta - void Set( S & s,int _size ) - { - Point3i _siz; - - BestDim( _size, dim, _siz ); - Set(s,_siz); - } - void Set(S & s, Point3i _siz) - { - siz=_siz; - // Calcola la dimensione della griglia - voxel[0] = dim[0]/siz[0]; - voxel[1] = dim[1]/siz[1]; - voxel[2] = dim[2]/siz[2]; - - // "Alloca" la griglia: +1 per la sentinella - grid.resize( siz[0]*siz[1]*siz[2]+1 ); - - // Ciclo inserimento dei tetraedri: creazione link - links.clear(); - S::iterator pt; - for(pt=s.begin(); pt!=s.end(); ++pt) - { - Box3x bb; // Boundig box del tetraedro corrente - (*pt).GetBBox(bb); - bb.Intersect(bbox); - if(! bb.IsNull() ) - { - Box3i ib; // Boundig box in voxels - BoxToIBox( bb,ib ); - /*ib.min-=Point3i(1,1,1); - ib.max+=Point3i(1,1,1); - if (ib.min[0]<0) ib.min[0]=0; - if (ib.min[1]<0) ib.min[1]=0; - if (ib.min[2]<0) ib.min[2]=0; - if (ib.max[0]>siz[0]) ib.max[0]=siz[0]; - if (ib.max[1]>siz[1]) ib.max[1]=siz[1]; - if (ib.max[2]>siz[2]) ib.max[2]=siz[2];*/ - - int x,y,z; - for(z=ib.min[2];z<=ib.max[2];++z) - { - int bz = z*siz[1]; - for(y=ib.min[1];y<=ib.max[1];++y) - { - int by = (y+bz)*siz[0]; - for(x=ib.min[0];x<=ib.max[0];++x) - // Inserire calcolo cella corrente - // if( pt->Intersect( ... ) - links.push_back( Link(pt,by+x) ); - } - } - } - } - // Push della sentinella - links.push_back( Link(NULL,grid.size()-1) ); - - // Ordinamento dei links - sort( links.begin(), links.end() ); - - // Creazione puntatori ai links - vector::iterator pl; - int pg; - pl = links.begin(); - for(pg=0;pgIndex() ) // Trovato inizio - { - ++pl; // Ricerca prossimo blocco - if(pl==links.end()) - break; - } - } - - } - - /** Calcolo dimensioni griglia. - Calcola la dimensione della griglia in funzione - della ratio del bounding box e del numero di elementi - */ - static void BestDim( const int elems, const Point3x & size, Point3i & dim ) - { - const int mincells = 27; // Numero minimo di celle - const double GFactor = 1.0; // GridEntry = NumElem*GFactor - double diag = size.Norm(); // Diagonale del box - double eps = diag*1e-4; // Fattore di tolleranza - - assert(elems>0); - assert(size[0]>=0.0); - assert(size[1]>=0.0); - assert(size[2]>=0.0); - - int ncell = int(elems*GFactor); // Calcolo numero di voxel - if(ncelleps) - { - if(size[1]>eps) - { - if(size[2]>eps) - { - double k = pow(ncell/(size[0]*size[1]*size[2]),1.0/3.0); - dim[0] = int(size[0] * k); - dim[1] = int(size[1] * k); - dim[2] = int(size[2] * k); - } - else - { - dim[0] = int(::sqrt(ncell*size[0]/size[1])); - dim[1] = int(::sqrt(ncell*size[1]/size[0])); - } - } - else - { - if(size[2]>eps) - { - dim[0] = int(::sqrt(ncell*size[0]/size[2])); - dim[2] = int(::sqrt(ncell*size[2]/size[0])); - } - else - dim[0] = int(ncell); - } - } - else - { - if(size[1]>eps) - { - if(size[2]>eps) - { - dim[1] = int(::sqrt(ncell*size[1]/size[2])); - dim[2] = int(::sqrt(ncell*size[2]/size[1])); - } - else - dim[1] = int(ncell); - } - else if(size[2]>eps) - dim[2] = int(ncell); - } - } - - - int MemUsed() - { - return sizeof(UGrid)+ sizeof(Link)*links.size() + sizeof(Link *) * grid.size(); - } -}; //end class UGrid - -} // end namespace - -#endif