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 #ifndef MOVEIT_DISTANCE_FIELD_VOXEL_GRID_
00038 #define MOVEIT_DISTANCE_FIELD_VOXEL_GRID_
00039
00040 #include <algorithm>
00041 #include <cmath>
00042 #include <Eigen/Core>
00043
00044 namespace distance_field
00045 {
00046
00048 enum Dimension {
00049 DIM_X = 0,
00050 DIM_Y = 1,
00051 DIM_Z = 2
00052 };
00053
00060 template <typename T>
00061 class VoxelGrid
00062 {
00063 public:
00089 VoxelGrid(double size_x, double size_y, double size_z, double resolution,
00090 double origin_x, double origin_y, double origin_z, T default_object);
00091 virtual ~VoxelGrid();
00092
00099 VoxelGrid();
00100
00118 void resize(double size_x, double size_y, double size_z, double resolution,
00119 double origin_x, double origin_y, double origin_z, T default_object);
00120
00134 const T& operator()(double x, double y, double z) const;
00135 const T& operator()(const Eigen::Vector3d& pos) const;
00136
00154 T& getCell(int x, int y, int z);
00155 T& getCell(const Eigen::Vector3i& pos);
00156 const T& getCell(int x, int y, int z) const;
00157 const T& getCell(const Eigen::Vector3i& pos) const;
00158
00177 void setCell(int x, int y, int z, const T& obj);
00178 void setCell(const Eigen::Vector3i& pos, const T& obj);
00179
00185 void reset(const T& initial);
00186
00194 double getSize(Dimension dim) const;
00195
00201 double getResolution() const;
00202
00204 double getResolution(Dimension dim) const;
00205
00213 double getOrigin(Dimension dim) const;
00214
00222 int getNumCells(Dimension dim) const;
00223
00242 void gridToWorld(int x, int y, int z, double& world_x, double& world_y, double& world_z) const;
00243 void gridToWorld(const Eigen::Vector3i& grid, Eigen::Vector3i& world) const;
00244
00261 bool worldToGrid(double world_x, double world_y, double world_z, int& x, int& y, int& z) const;
00262 bool worldToGrid(const Eigen::Vector3i& world, Eigen::Vector3i& grid) const;
00263
00273 bool isCellValid(int x, int y, int z) const;
00274 bool isCellValid(const Eigen::Vector3i& pos) const;
00275
00284 bool isCellValid(Dimension dim, int cell) const;
00285
00286 protected:
00287 T* data_;
00288 T default_object_;
00289 T*** data_ptrs_;
00290 double size_[3];
00291 double resolution_;
00292 double oo_resolution_;
00293 double origin_[3];
00294 double origin_minus_[3];
00295 int num_cells_[3];
00296 int num_cells_total_;
00297 int stride1_;
00298 int stride2_;
00309 int ref(int x, int y, int z) const;
00310
00323 int getCellFromLocation(Dimension dim, double loc) const;
00324
00334 double getLocationFromCell(Dimension dim, int cell) const;
00335
00336 };
00337
00339
00340 template<typename T>
00341 VoxelGrid<T>::VoxelGrid(double size_x, double size_y, double size_z, double resolution,
00342 double origin_x, double origin_y, double origin_z, T default_object)
00343 : data_(NULL)
00344 {
00345 resize(size_x, size_y, size_z, resolution, origin_x, origin_y, origin_z, default_object);
00346 }
00347
00348 template<typename T>
00349 VoxelGrid<T>::VoxelGrid()
00350 : data_(NULL)
00351 {
00352 for (int i=DIM_X; i<=DIM_Z; ++i)
00353 {
00354 size_[i] = 0;
00355 origin_[i] = 0;
00356 origin_minus_[i] = 0;
00357 num_cells_[i] = 0;
00358 }
00359 resolution_ = 1.0;
00360 oo_resolution_ = 1.0 / resolution_;
00361 num_cells_total_ = 0;
00362 stride1_ = 0;
00363 stride2_ = 0;
00364 }
00365
00366 template<typename T>
00367 void VoxelGrid<T>::resize(double size_x, double size_y, double size_z, double resolution,
00368 double origin_x, double origin_y, double origin_z, T default_object)
00369 {
00370 delete[] data_;
00371 data_ = NULL;
00372
00373 size_[DIM_X] = size_x;
00374 size_[DIM_Y] = size_y;
00375 size_[DIM_Z] = size_z;
00376 origin_[DIM_X] = origin_x;
00377 origin_[DIM_Y] = origin_y;
00378 origin_[DIM_Z] = origin_z;
00379 origin_minus_[DIM_X] = origin_x - 0.5 * resolution;
00380 origin_minus_[DIM_Y] = origin_y - 0.5 * resolution;
00381 origin_minus_[DIM_Z] = origin_z - 0.5 * resolution;
00382 num_cells_total_ = 1;
00383 resolution_ = resolution;
00384 oo_resolution_ = 1.0 / resolution_;
00385 for (int i=DIM_X; i<=DIM_Z; ++i)
00386 {
00387 num_cells_[i] = size_[i] * oo_resolution_;
00388 num_cells_total_ *= num_cells_[i];
00389 }
00390
00391 default_object_ = default_object;
00392
00393 stride1_ = num_cells_[DIM_Y]*num_cells_[DIM_Z];
00394 stride2_ = num_cells_[DIM_Z];
00395
00396
00397 if (num_cells_total_ > 0)
00398 data_ = new T[num_cells_total_];
00399 }
00400
00401 template<typename T>
00402 VoxelGrid<T>::~VoxelGrid()
00403 {
00404 delete[] data_;
00405 }
00406
00407 template<typename T>
00408 inline bool VoxelGrid<T>::isCellValid(int x, int y, int z) const
00409 {
00410 return (
00411 x>=0 && x<num_cells_[DIM_X] &&
00412 y>=0 && y<num_cells_[DIM_Y] &&
00413 z>=0 && z<num_cells_[DIM_Z]);
00414 }
00415
00416 template<typename T>
00417 inline bool VoxelGrid<T>::isCellValid(const Eigen::Vector3i& pos) const
00418 {
00419 return isCellValid(pos.x(), pos.y(), pos.z());
00420 }
00421
00422 template<typename T>
00423 inline bool VoxelGrid<T>::isCellValid(Dimension dim, int cell) const
00424 {
00425 return cell>=0 && cell<num_cells_[dim];
00426 }
00427
00428 template<typename T>
00429 inline int VoxelGrid<T>::ref(int x, int y, int z) const
00430 {
00431 return x*stride1_ + y*stride2_ + z;
00432 }
00433
00434 template<typename T>
00435 inline double VoxelGrid<T>::getSize(Dimension dim) const
00436 {
00437 return size_[dim];
00438 }
00439
00440 template<typename T>
00441 inline double VoxelGrid<T>::getResolution() const
00442 {
00443 return resolution_;
00444 }
00445
00446 template<typename T>
00447 inline double VoxelGrid<T>::getResolution(Dimension dim) const
00448 {
00449 return resolution_;
00450 }
00451
00452 template<typename T>
00453 inline double VoxelGrid<T>::getOrigin(Dimension dim) const
00454 {
00455 return origin_[dim];
00456 }
00457
00458 template<typename T>
00459 inline int VoxelGrid<T>::getNumCells(Dimension dim) const
00460 {
00461 return num_cells_[dim];
00462 }
00463
00464 template<typename T>
00465 inline const T& VoxelGrid<T>::operator()(double x, double y, double z) const
00466 {
00467 int cellX = getCellFromLocation(DIM_X, x);
00468 int cellY = getCellFromLocation(DIM_Y, y);
00469 int cellZ = getCellFromLocation(DIM_Z, z);
00470 if (!isCellValid(cellX, cellY, cellZ))
00471 return default_object_;
00472 return getCell(cellX, cellY, cellZ);
00473 }
00474
00475 template<typename T>
00476 inline const T& VoxelGrid<T>::operator()(const Eigen::Vector3d& pos) const
00477 {
00478 this->operator()(pos.x(), pos.y(), pos.z());
00479 }
00480
00481 template<typename T>
00482 inline T& VoxelGrid<T>::getCell(int x, int y, int z)
00483 {
00484 return data_[ref(x,y,z)];
00485 }
00486
00487 template<typename T>
00488 inline const T& VoxelGrid<T>::getCell(int x, int y, int z) const
00489 {
00490 return data_[ref(x,y,z)];
00491 }
00492
00493 template<typename T>
00494 inline T& VoxelGrid<T>::getCell(const Eigen::Vector3i& pos)
00495 {
00496 return data_[ref(pos.x(), pos.y(), pos.z())];
00497 }
00498
00499 template<typename T>
00500 inline const T& VoxelGrid<T>::getCell(const Eigen::Vector3i& pos) const
00501 {
00502 return data_[ref(pos.x(), pos.y(), pos.z())];
00503 }
00504
00505 template<typename T>
00506 inline void VoxelGrid<T>::setCell(int x, int y, int z, const T& obj)
00507 {
00508 data_[ref(x,y,z)] = obj;
00509 }
00510
00511 template<typename T>
00512 inline void VoxelGrid<T>::setCell(const Eigen::Vector3i& pos, const T& obj)
00513 {
00514 data_[ref(pos.x(), pos.y(), pos.z())] = obj;
00515 }
00516
00517 template<typename T>
00518 inline int VoxelGrid<T>::getCellFromLocation(Dimension dim, double loc) const
00519 {
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534 return int(floor((loc - origin_minus_[dim]) * oo_resolution_));
00535 }
00536
00537 template<typename T>
00538 inline double VoxelGrid<T>::getLocationFromCell(Dimension dim, int cell) const
00539 {
00540 return origin_[dim] + resolution_ * (double(cell));
00541 }
00542
00543
00544 template<typename T>
00545 inline void VoxelGrid<T>::reset(const T& initial)
00546 {
00547 std::fill(data_, data_ + num_cells_total_, initial);
00548 }
00549
00550 template<typename T>
00551 inline void VoxelGrid<T>::gridToWorld(int x, int y, int z, double& world_x, double& world_y, double& world_z) const
00552 {
00553 world_x = getLocationFromCell(DIM_X, x);
00554 world_y = getLocationFromCell(DIM_Y, y);
00555 world_z = getLocationFromCell(DIM_Z, z);
00556 }
00557
00558 template<typename T>
00559 inline void VoxelGrid<T>::gridToWorld(const Eigen::Vector3i& grid, Eigen::Vector3i& world) const
00560 {
00561 world.x() = getLocationFromCell(DIM_X, grid.x());
00562 world.y() = getLocationFromCell(DIM_Y, grid.y());
00563 world.z() = getLocationFromCell(DIM_Z, grid.z());
00564 }
00565
00566 template<typename T>
00567 inline bool VoxelGrid<T>::worldToGrid(double world_x, double world_y, double world_z, int& x, int& y, int& z) const
00568 {
00569 x = getCellFromLocation(DIM_X, world_x);
00570 y = getCellFromLocation(DIM_Y, world_y);
00571 z = getCellFromLocation(DIM_Z, world_z);
00572 return isCellValid(x,y,z);
00573 }
00574
00575 template<typename T>
00576 inline bool VoxelGrid<T>::worldToGrid(const Eigen::Vector3i& world, Eigen::Vector3i& grid) const
00577 {
00578 grid.x() = getCellFromLocation(DIM_X, world.x());
00579 grid.y() = getCellFromLocation(DIM_Y, world.y());
00580 grid.z() = getCellFromLocation(DIM_Z, world.z());
00581 return isCellValid(grid.x(), grid.y(), grid.z());
00582 }
00583
00584 }
00585 #endif