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 #ifndef __VCGLIB_GRID_UTIL
00066 #define __VCGLIB_GRID_UTIL
00067
00068 #include<vcg/space/index/base.h>
00069 #include<vcg/space/box3.h>
00070 #include <vcg/space/index/space_iterators.h>
00071
00072
00073 #ifndef WIN32
00074 #define __int64 long long
00075 #define __cdecl
00076 #endif
00077
00078 namespace vcg {
00079
00094 template <class SCALARTYPE>
00095 class BasicGrid
00096 {
00097 public:
00098
00099 typedef SCALARTYPE ScalarType;
00100 typedef Box3<ScalarType> Box3x;
00101 typedef Point3<ScalarType> CoordType;
00102 typedef BasicGrid<SCALARTYPE> GridType;
00103
00104 Box3x bbox;
00105
00106 CoordType dim;
00107 Point3i siz;
00108 CoordType voxel;
00109
00110
00111
00112
00113
00114 void ComputeDimAndVoxel()
00115 {
00116 this->dim = this->bbox.max - this->bbox.min;
00117 this->voxel[0] = this->dim[0]/this->siz[0];
00118 this->voxel[1] = this->dim[1]/this->siz[1];
00119 this->voxel[2] = this->dim[2]/this->siz[2];
00120 }
00121
00122
00123
00124
00125 inline Point3i GridP( const Point3<ScalarType> & p ) const
00126 {
00127 Point3i pi;
00128 PToIP(p, pi);
00129 return pi;
00130 }
00131
00132
00133
00134
00135
00136 inline void PToIP(const CoordType & p, Point3i &pi ) const
00137 {
00138 CoordType t = p - bbox.min;
00139 pi[0] = int( t[0] / voxel[0] );
00140 pi[1] = int( t[1] / voxel[1] );
00141 pi[2] = int( t[2] / voxel[2] );
00142 }
00143
00144
00145
00146
00147
00148 inline void IPiToPf(const Point3i & pi, CoordType &p ) const
00149 {
00150 p[0] = ((ScalarType)pi[0])*voxel[0];
00151 p[1] = ((ScalarType)pi[1])*voxel[1];
00152 p[2] = ((ScalarType)pi[2])*voxel[2];
00153 p += bbox.min;
00154 }
00155
00156
00157
00158
00159
00160 inline void IPiToBox(const Point3i & pi, Box3x & b ) const
00161 {
00162 CoordType p;
00163 p[0] = ((ScalarType)pi[0])*voxel[0];
00164 p[1] = ((ScalarType)pi[1])*voxel[1];
00165 p[2] = ((ScalarType)pi[2])*voxel[2];
00166 p += bbox.min;
00167 b.min = p;
00168 b.max = (p + voxel);
00169 }
00170
00171
00172
00173
00174 inline void IPiToBoxCenter(const Point3i & pi, CoordType & c ) const
00175 {
00176 CoordType p;
00177 IPiToPf(pi,p);
00178 c = p + voxel/ScalarType(2.0);
00179 }
00180
00181
00182
00183 inline void IPfToPf(const CoordType & pi, CoordType &p ) const
00184 {
00185 p[0] = ((ScalarType)pi[0])*voxel[0];
00186 p[1] = ((ScalarType)pi[1])*voxel[1];
00187 p[2] = ((ScalarType)pi[2])*voxel[2];
00188 p += bbox.min;
00189 }
00190
00191
00192
00193
00194
00195 void BoxToIBox( const Box3x & b, Box3i & ib ) const
00196 {
00197 PToIP(b.min, ib.min);
00198 PToIP(b.max, ib.max);
00199
00200 }
00201
00202
00203
00204
00205
00207 void IBoxToBox( const Box3i & ib, Box3x & b ) const
00208 {
00209 IPToP(ib.min,b.min);
00210 IPToP(ib.max,b.max);
00211 }
00212 };
00213
00214 template<class scalar_type>
00215 void BestDim( const Box3<scalar_type> box, const scalar_type voxel_size, Point3i & dim )
00216 {
00217 Point3<scalar_type> box_size = box.max-box.min;
00218 __int64 elem_num = (__int64)(box_size[0]/voxel_size +0.5) *( __int64)(box_size[1]/voxel_size +0.5) * (__int64)(box_size[2]/voxel_size +0.5);
00219 BestDim(elem_num,box_size,dim);
00220 }
00225 template<class scalar_type>
00226 void BestDim( const __int64 elems, const Point3<scalar_type> & size, Point3i & dim )
00227 {
00228 const __int64 mincells = 1;
00229 const double GFactor = 1;
00230 double diag = size.Norm();
00231 double eps = diag*1e-4;
00232
00233 assert(elems>0);
00234 assert(size[0]>=0.0);
00235 assert(size[1]>=0.0);
00236 assert(size[2]>=0.0);
00237
00238
00239 __int64 ncell = (__int64)(elems*GFactor);
00240 if(ncell<mincells)
00241 ncell = mincells;
00242
00243 dim[0] = 1;
00244 dim[1] = 1;
00245 dim[2] = 1;
00246
00247 if(size[0]>eps)
00248 {
00249 if(size[1]>eps)
00250 {
00251 if(size[2]>eps)
00252 {
00253 double k = pow((double)(ncell/(size[0]*size[1]*size[2])),double(1.0/3.f));
00254 dim[0] = int(size[0] * k);
00255 dim[1] = int(size[1] * k);
00256 dim[2] = int(size[2] * k);
00257 }
00258 else
00259 {
00260 dim[0] = int(::sqrt(ncell*size[0]/size[1]));
00261 dim[1] = int(::sqrt(ncell*size[1]/size[0]));
00262 }
00263 }
00264 else
00265 {
00266 if(size[2]>eps)
00267 {
00268 dim[0] = int(::sqrt(ncell*size[0]/size[2]));
00269 dim[2] = int(::sqrt(ncell*size[2]/size[0]));
00270 }
00271 else
00272 dim[0] = int(ncell);
00273 }
00274 }
00275 else
00276 {
00277 if(size[1]>eps)
00278 {
00279 if(size[2]>eps)
00280 {
00281 dim[1] = int(::sqrt(ncell*size[1]/size[2]));
00282 dim[2] = int(::sqrt(ncell*size[2]/size[1]));
00283 }
00284 else
00285 dim[1] = int(ncell);
00286 }
00287 else if(size[2]>eps)
00288 dim[2] = int(ncell);
00289 }
00290 dim[0] = math::Max(dim[0],1);
00291 dim[1] = math::Max(dim[1],1);
00292 dim[2] = math::Max(dim[2],1);
00293 }
00294 }
00295 #endif