00001 #include "bsol_point_index_3d.h"
00002
00003
00004 #include <vsol/vsol_point_3d.h>
00005 #include <vsol/vsol_box_3d.h>
00006 #include "bsol_algs.h"
00007 #ifdef DEBUG
00008 #include <vcl_iostream.h>
00009 #endif
00010
00011 static void clear_flag(vsol_point_3d_sptr& p)
00012 {
00013 p->unset_user_flag(VSOL_FLAG1);
00014 }
00015
00016 static void set_flag(vsol_point_3d_sptr & p)
00017 {
00018 p->set_user_flag(VSOL_FLAG1);
00019 }
00020
00021 static bool flag(vsol_point_3d_sptr const& p)
00022 {
00023 return p->get_user_flag(VSOL_FLAG1);
00024 }
00025
00026
00027
00028
00029
00030 bsol_point_index_3d::bsol_point_index_3d()
00031 {
00032 nrows_ = 0;
00033 ncols_ = 0;
00034 nslabs_ = 0;
00035 b_box_ = (vsol_box_3d*)0;
00036 }
00037
00038 bsol_point_index_3d::bsol_point_index_3d(int nrows, int ncols, int nslabs,
00039 vsol_box_3d_sptr const& bb)
00040 {
00041 nrows_ = nrows;
00042 ncols_ = ncols;
00043 nslabs_ = nslabs;
00044
00045 point_array_.resize(nrows, ncols);
00046 for (int r = 0; r<nrows; r++)
00047 for (int c = 0; c<ncols; c++)
00048 {
00049 vcl_vector<vcl_vector<vsol_point_3d_sptr> >* v =
00050 new vcl_vector<vcl_vector<vsol_point_3d_sptr> >(nslabs);
00051 point_array_[r][c] = v;
00052
00053 }
00054 b_box_ = bb;
00055 double w = b_box_->width(), h = b_box_->height(), d = b_box_->depth();
00056 row_spacing_ = 1;
00057 col_spacing_ = 1;
00058 slab_spacing_ = 1;
00059 if (nrows)
00060 row_spacing_ = h/nrows;
00061 if (ncols)
00062 col_spacing_ = w/ncols;
00063 if (nslabs)
00064 slab_spacing_ = d/nslabs;
00065 }
00066
00067 bsol_point_index_3d::
00068 bsol_point_index_3d(int nrows, int ncols, int nslabs,
00069 vcl_vector<vsol_point_3d_sptr> const& points)
00070 {
00071 nrows_ = nrows;
00072 ncols_ = ncols;
00073 nslabs_ = nslabs;
00074
00075 point_array_.resize(nrows, ncols);
00076 for (int r = 0; r<nrows; r++)
00077 for (int c = 0; c<ncols; c++)
00078 {
00079 vcl_vector<vcl_vector<vsol_point_3d_sptr> >* v =
00080 new vcl_vector<vcl_vector<vsol_point_3d_sptr> >(nslabs);
00081 point_array_[r][c] = v;
00082
00083 }
00084 vbl_bounding_box<double,3> box = bsol_algs::bounding_box(points);
00085 b_box_ = new vsol_box_3d(box);
00086 double w = b_box_->width(), h = b_box_->height(), d = b_box_->depth();
00087 row_spacing_ = 1;
00088 col_spacing_ = 1;
00089 slab_spacing_ = 1;
00090 if (nrows)
00091 row_spacing_ = h/nrows;
00092 if (ncols)
00093 col_spacing_ = w/ncols;
00094 if (nslabs)
00095 slab_spacing_ = d/nslabs;
00096
00097 this->add_points(points);
00098 }
00099
00100
00101 bsol_point_index_3d::~bsol_point_index_3d()
00102 {
00103 for (int r = 0; r<nrows_; r++)
00104 for (int c = 0; c<ncols_; c++)
00105 delete point_array_[r][c];
00106 }
00107
00108 void bsol_point_index_3d::origin(double& x0, double& y0, double& z0)
00109 {
00110 if (!b_box_) { x0 = y0 = z0 = 0; return; }
00111 x0 = b_box_->get_min_x();
00112 y0 = b_box_->get_min_y();
00113 z0 = b_box_->get_min_z();
00114 }
00115
00116 int
00117 bsol_point_index_3d::n_points(const int row, const int col, const int slab)
00118 {
00119 if (row<0||row>=nrows_||col<0||col>=ncols_||slab<0||slab>=nslabs_)
00120 return 0;
00121 int n = (*(point_array_[row][col]))[slab].size();
00122 return n;
00123 }
00124
00125 int
00126 bsol_point_index_3d::n_points(const double x, const double y, const double z)
00127 {
00128 int row=0, col=0, slab=0;
00129 if (!trans(x, y, z, row, col, slab))
00130 return 0;
00131 if (row<0||row>=nrows_||col<0||col>=ncols_||slab<0||slab>=nslabs_)
00132 return 0;
00133 return (*(point_array_[row][col]))[slab].size();
00134 }
00135
00136 int bsol_point_index_3d::n_points()
00137 {
00138 int n = 0;
00139 for (int r=0; r<nrows_; r++)
00140 for (int c=0; c<ncols_; c++)
00141 for (int s=0; s<nslabs_; s++)
00142 n += n_points(r, c, s);
00143 return n;
00144 }
00145
00146 vcl_vector<vsol_point_3d_sptr> bsol_point_index_3d::points(const int row, const int col,
00147 const int slab)
00148 {
00149 vcl_vector<vsol_point_3d_sptr> out;
00150 if (row<0||row>=nrows_||col<0||col>=ncols_||slab<0||slab>=nslabs_)
00151 return out;
00152 return (*(point_array_[row][col]))[slab];
00153 }
00154
00155
00156 bool bsol_point_index_3d::trans(const double x, const double y,
00157 const double z,
00158 int& row, int& col, int& slab)
00159 {
00160 if (!bsol_algs::in(b_box_, x, y, z))
00161 return false;
00162 col = (int)((x-b_box_->get_min_x())/col_spacing_);
00163 row = (int)((y-b_box_->get_min_y())/row_spacing_);
00164 slab = (int)((z-b_box_->get_min_z())/slab_spacing_);
00165 return true;
00166 }
00167
00168
00169
00170
00171
00172 bool bsol_point_index_3d::add_point(vsol_point_3d_sptr const& p)
00173 {
00174 double x = p->x(), y = p->y(), z = p->z();
00175 int row=0, col=0, slab=0;
00176 if (!trans(x, y, z, row, col, slab))
00177 return false;
00178 if (row<0||row>=nrows_||col<0||col>=ncols_||slab<0||slab>=nslabs_)
00179 return false;
00180 vcl_vector<vcl_vector<vsol_point_3d_sptr> >* v = point_array_[row][col];
00181 (*v)[slab].push_back(p);
00182 return true;
00183 }
00184
00185 bool bsol_point_index_3d::add_points(vcl_vector<vsol_point_3d_sptr> const& points)
00186 {
00187 bool ok = true;
00188 for (vcl_vector<vsol_point_3d_sptr>::const_iterator pit = points.begin();
00189 pit != points.end(); pit++)
00190 if (!this->add_point(*pit))
00191 ok = false;
00192 return ok;
00193 }
00194
00195 bool bsol_point_index_3d::find_point(vsol_point_3d_sptr const& p)
00196 {
00197 int row=0, col=0, slab = 0;
00198 if (!this->trans(p->x(), p->y(), p->z(),row, col, slab))
00199 return false;
00200 if (row<0||row>=nrows_||col<0||col>=ncols_||slab<0||slab>=nslabs_)
00201 return false;
00202 vcl_vector<vsol_point_3d_sptr>& points = (*(point_array_[row][col]))[slab];
00203 for (vcl_vector<vsol_point_3d_sptr>::iterator pit = points.begin();
00204 pit!=points.end(); pit++)
00205 if ((*pit)==p)
00206 return true;
00207 return false;
00208 }
00209
00210
00211 bool bsol_point_index_3d::in_box(vsol_box_3d_sptr const& box,
00212 vcl_vector<vsol_point_3d_sptr>& points)
00213 {
00214 if (!box)
00215 return false;
00216 double xmin = box->get_min_x(),
00217 ymin = box->get_min_y(), zmin = box->get_min_z();
00218 double xmax = box->get_max_x(),
00219 ymax = box->get_max_y(), zmax = box->get_max_z();
00220 int row_min = 0, col_min = 0, slab_min = 0;
00221 int row_max = 0, col_max = 0, slab_max = 0;
00222 trans(xmin, ymin, zmin, row_min, col_min, slab_min);
00223 trans(xmax, ymax, zmax, row_max, col_max, slab_max);
00224 if (row_min<0)
00225 row_min = 0;
00226 if (col_min<0)
00227 col_min = 0;
00228 if (slab_min<0)
00229 slab_min = 0;
00230 if (row_max>nrows_)
00231 row_max = nrows_-1;
00232 if (col_max>=ncols_)
00233 col_max = ncols_-1;
00234 if (slab_max>=nslabs_)
00235 slab_max = nslabs_-1;
00236 for (int r=row_min; r<row_max; r++)
00237 for (int c=col_min; c<col_max; c++)
00238 for (int s=slab_min; s<slab_max; s++)
00239 {
00240 vcl_vector<vsol_point_3d_sptr>& pts = (*(point_array_[r][c]))[s];
00241 for (vcl_vector<vsol_point_3d_sptr>::iterator pit = pts.begin();
00242 pit != pts.end(); pit++)
00243 points.push_back(*pit);
00244 }
00245 return true;
00246 }
00247
00248
00249 bool bsol_point_index_3d::in_radius(const double radius,
00250 vsol_point_3d_sptr const& p,
00251 vcl_vector<vsol_point_3d_sptr>& points)
00252 {
00253 if (!p)
00254 return false;
00255 bool found_points = false;
00256
00257 double x = p->x(), y = p->y(), z = p->z();
00258 int row = 0, col = 0, slab = 0;
00259 this->trans(x, y, z, row, col, slab);
00260
00261 int row_radius = int(radius/row_spacing_),
00262 col_radius = int(radius/col_spacing_),
00263 slab_radius = int(radius/slab_spacing_);
00264
00265 row_radius++; col_radius++;
00266 for (int ro = -row_radius; ro<=row_radius; ro++)
00267 for (int co = -col_radius; co<=col_radius; co++)
00268 for (int so = -slab_radius; so<=slab_radius; so++)
00269 {
00270 int r = row+ro, c = col+co, s = slab + so;
00271 if (r<0||r>=nrows_||c<0||c>=ncols_||s<0||s>=nslabs_)
00272 continue;
00273 vcl_vector<vsol_point_3d_sptr>& points_in_cell =
00274 (*(point_array_[r][c]))[s];
00275 int n = points_in_cell.size();
00276 if (!n)
00277 continue;
00278 for (int i=0; i<n; i++)
00279 if (!flag(points_in_cell[i]))
00280 {
00281 points.push_back(points_in_cell[i]);
00282 found_points = true;
00283 }
00284 }
00285 return found_points;
00286 }
00287
00288
00289 bool bsol_point_index_3d::closest_in_radius(const double radius,
00290 vsol_point_3d_sptr const& p,
00291 vsol_point_3d_sptr& point)
00292 {
00293 vcl_vector<vsol_point_3d_sptr> points;
00294 this->in_radius(radius, p, points);
00295 double d = 0;
00296 point = bsol_algs::closest_point(p, points, d);
00297 if (!point||d>radius)
00298 return false;
00299 #ifdef DEBUG
00300 vcl_cout << "p("<< p->x() << ' ' << p->y()<< "):P(" << point->x() << ' ' << point->y() << "):" << d << vcl_endl;
00301 #endif
00302 return true;
00303 }
00304
00305 void bsol_point_index_3d::clear()
00306 {
00307 for (int r =0; r<nrows_; r++)
00308 for (int c = 0; c<ncols_; c++)
00309 for (int s = 0; c<nslabs_; c++)
00310 (*(point_array_[r][c]))[s].clear();
00311 }
00312
00313 bool bsol_point_index_3d::mark_point(vsol_point_3d_sptr& p)
00314 {
00315 if (!p||!this->find_point(p))
00316 return false;
00317 set_flag(p);
00318 return true;
00319 }
00320
00321 bool bsol_point_index_3d::unmark_point(vsol_point_3d_sptr& p)
00322 {
00323 if (!p||!this->find_point(p))
00324 return false;
00325 clear_flag(p);
00326 return true;
00327 }
00328
00329 bool bsol_point_index_3d::marked(vsol_point_3d_sptr const& p)
00330 {
00331 if (!p||!this->find_point(p))
00332 return false;
00333 return flag(p);
00334 }
00335
00336 vcl_vector<vsol_point_3d_sptr> bsol_point_index_3d::points()
00337 {
00338 vcl_vector<vsol_point_3d_sptr> out;
00339 for (int r=0; r<nrows_; r++)
00340 for (int c=0; c<ncols_; c++)
00341 for (int s=0; s<nslabs_; s++)
00342 {
00343 vcl_vector<vsol_point_3d_sptr>& points = (*(point_array_[r][c]))[s];
00344 for (vcl_vector<vsol_point_3d_sptr>::iterator pit = points.begin();
00345 pit!= points.end(); pit++)
00346 out.push_back(*pit);
00347 }
00348 return out;
00349 }
00350
00351 void bsol_point_index_3d::clear_marks()
00352 {
00353 for (int r=0; r<nrows_; ++r)
00354 for (int c=0; c<ncols_; ++c)
00355 for (int s=0; s<nslabs_; ++s)
00356 for (vcl_vector<vsol_point_3d_sptr>::iterator pit = (*(point_array_[r][c]))[s].begin();
00357 pit != (*(point_array_[r][c]))[s].end(); ++pit)
00358 clear_flag(*pit);
00359 }
00360
00361 vsol_box_3d_sptr bsol_point_index_3d::
00362 index_cell(const int row, const int col, const int slab)
00363 {
00364 vsol_box_3d_sptr box = new vsol_box_3d;
00365 if (row<0||row>=nrows_||col<0||col>=ncols_||slab<0||slab>=nslabs_)
00366 return box;
00367
00368 double x0, y0, z0;
00369 this->origin(x0, y0, z0);
00370 double xmin = col_spacing_*col + x0;
00371 double ymin = row_spacing_*row + y0;
00372 double zmin = slab_spacing_*slab + z0;
00373 box->add_point(xmin, ymin, zmin);
00374 box->add_point(xmin+col_spacing_, ymin+row_spacing_, zmin+slab_spacing_);
00375 return box;
00376 }
00377
00378 vsol_box_3d_sptr bsol_point_index_3d::
00379 index_cell(const double x, const double y, const double z)
00380 {
00381 vsol_box_3d_sptr null;
00382 int row=0, col=0, slab=0;
00383 if (!trans(x, y, z, row, col, slab))
00384 return null;
00385 if (row<0||row>=nrows_||col<0||col>=ncols_||slab<0||slab>=nslabs_)
00386 return null;
00387 return this->index_cell(row, col, slab);
00388 }
00389
00390 vsol_box_3d_sptr bsol_point_index_3d::point_bounds()
00391 {
00392 vsol_box_3d_sptr box = new vsol_box_3d();
00393 for (int r=0; r<nrows_; r++)
00394 for (int c=0; c<ncols_; c++)
00395 for (int s=0; s<nslabs_; s++)
00396 {
00397 vcl_vector<vsol_point_3d_sptr>& points = (*(point_array_[r][c]))[s];
00398 for (vcl_vector<vsol_point_3d_sptr>::iterator pit = points.begin();
00399 pit!= points.end(); pit++)
00400 box->add_point((*pit)->x(), (*pit)->y(), (*pit)->z());
00401 }
00402 return box;
00403 }