36 #ifndef PCL_SURFACE_IMPL_MARCHING_CUBES_H_
37 #define PCL_SURFACE_IMPL_MARCHING_CUBES_H_
46 template <
typename Po
intNT>
48 : min_p_ (), max_p_ (), percentage_extend_grid_ (), iso_level_ ()
53 template <
typename Po
intNT>
59 template <
typename Po
intNT>
void
64 min_p_ -= (max_p_ - min_p_) * percentage_extend_grid_/2;
65 max_p_ += (max_p_ - min_p_) * percentage_extend_grid_/2;
67 Eigen::Vector4f bounding_box_size = max_p_ - min_p_;
69 bounding_box_size = max_p_ - min_p_;
70 PCL_DEBUG (
"[pcl::MarchingCubesHoppe::getBoundingBox] Size of Bounding Box is [%f, %f, %f]\n",
71 bounding_box_size.x (), bounding_box_size.y (), bounding_box_size.z ());
73 (std::max) ((std::max)(bounding_box_size.x (), bounding_box_size.y ()),
74 bounding_box_size.z ());
77 PCL_DEBUG (
"[pcl::MarchingCubesHoppe::getBoundingBox] Lower left point is [%f, %f, %f]\n",
78 min_p_.x (), min_p_.y (), min_p_.z ());
79 PCL_DEBUG (
"[pcl::MarchingCubesHoppe::getBoundingBox] Upper left point is [%f, %f, %f]\n",
80 max_p_.x (), max_p_.y (), max_p_.z ());
85 template <
typename Po
intNT>
void
90 Eigen::Vector3f &output)
92 float mu = (iso_level_ - val_p1) / (val_p2-val_p1);
93 output = p1 + mu * (p2 - p1);
98 template <
typename Po
intNT>
void
100 Eigen::Vector3i &index_3d,
104 Eigen::Vector3f vertex_list[12];
105 if (leaf_node[0] < iso_level_) cubeindex |= 1;
106 if (leaf_node[1] < iso_level_) cubeindex |= 2;
107 if (leaf_node[2] < iso_level_) cubeindex |= 4;
108 if (leaf_node[3] < iso_level_) cubeindex |= 8;
109 if (leaf_node[4] < iso_level_) cubeindex |= 16;
110 if (leaf_node[5] < iso_level_) cubeindex |= 32;
111 if (leaf_node[6] < iso_level_) cubeindex |= 64;
112 if (leaf_node[7] < iso_level_) cubeindex |= 128;
119 Eigen::Vector3f center;
120 center[0] = min_p_[0] + (max_p_[0] - min_p_[0]) * index_3d[0] / res_x_;
121 center[1] = min_p_[1] + (max_p_[1] - min_p_[1]) * index_3d[1] / res_y_;
122 center[2] = min_p_[2] + (max_p_[2] - min_p_[2]) * index_3d[2] / res_z_;
124 std::vector<Eigen::Vector3f> p;
126 for (
int i = 0; i < 8; ++i)
128 Eigen::Vector3f point = center;
130 point[1] =
static_cast<float> (center[1] + (max_p_[1] - min_p_[1]) /
float (res_y_));
133 point[2] =
static_cast<float> (center[2] + (max_p_[2] - min_p_[2]) /
float (res_z_));
135 if((i & 0x1) ^ ((i >> 1) & 0x1))
136 point[0] = static_cast<float> (center[0] + (max_p_[0] - min_p_[0]) / float (res_x_));
144 interpolateEdge (p[0], p[1], leaf_node[0], leaf_node[1], vertex_list[0]);
146 interpolateEdge (p[1], p[2], leaf_node[1], leaf_node[2], vertex_list[1]);
148 interpolateEdge (p[2], p[3], leaf_node[2], leaf_node[3], vertex_list[2]);
150 interpolateEdge (p[3], p[0], leaf_node[3], leaf_node[0], vertex_list[3]);
152 interpolateEdge (p[4], p[5], leaf_node[4], leaf_node[5], vertex_list[4]);
154 interpolateEdge (p[5], p[6], leaf_node[5], leaf_node[6], vertex_list[5]);
156 interpolateEdge (p[6], p[7], leaf_node[6], leaf_node[7], vertex_list[6]);
158 interpolateEdge (p[7], p[4], leaf_node[7], leaf_node[4], vertex_list[7]);
160 interpolateEdge (p[0], p[4], leaf_node[0], leaf_node[4], vertex_list[8]);
162 interpolateEdge (p[1], p[5], leaf_node[1], leaf_node[5], vertex_list[9]);
164 interpolateEdge (p[2], p[6], leaf_node[2], leaf_node[6], vertex_list[10]);
166 interpolateEdge (p[3], p[7], leaf_node[3], leaf_node[7], vertex_list[11]);
169 for (
int i = 0;
triTable[cubeindex][i] != -1; i+=3)
172 p1.x = vertex_list[
triTable[cubeindex][i ]][0];
173 p1.y = vertex_list[triTable[cubeindex][i ]][1];
174 p1.z = vertex_list[triTable[cubeindex][i ]][2];
176 p2.x = vertex_list[triTable[cubeindex][i+1]][0];
177 p2.y = vertex_list[triTable[cubeindex][i+1]][1];
178 p2.z = vertex_list[triTable[cubeindex][i+1]][2];
180 p3.x = vertex_list[triTable[cubeindex][i+2]][0];
181 p3.y = vertex_list[triTable[cubeindex][i+2]][1];
182 p3.z = vertex_list[triTable[cubeindex][i+2]][2];
189 template <
typename Po
intNT>
void
191 Eigen::Vector3i &index3d)
193 leaf = std::vector<float> (8, 0.0f);
195 leaf[0] = getGridValue (index3d);
196 leaf[1] = getGridValue (index3d + Eigen::Vector3i (1, 0, 0));
197 leaf[2] = getGridValue (index3d + Eigen::Vector3i (1, 0, 1));
198 leaf[3] = getGridValue (index3d + Eigen::Vector3i (0, 0, 1));
199 leaf[4] = getGridValue (index3d + Eigen::Vector3i (0, 1, 0));
200 leaf[5] = getGridValue (index3d + Eigen::Vector3i (1, 1, 0));
201 leaf[6] = getGridValue (index3d + Eigen::Vector3i (1, 1, 1));
202 leaf[7] = getGridValue (index3d + Eigen::Vector3i (0, 1, 1));
207 template <
typename Po
intNT>
float
211 if (pos[0] < 0 || pos[0] >= res_x_)
213 if (pos[1] < 0 || pos[1] >= res_y_)
215 if (pos[2] < 0 || pos[2] >= res_z_)
218 return grid_[pos[0]*res_y_*res_z_ + pos[1]*res_z_ + pos[2]];
223 template <
typename Po
intNT>
void
226 if (!(iso_level_ >= 0 && iso_level_ < 1))
228 PCL_ERROR (
"[pcl::%s::performReconstruction] Invalid iso level %f! Please use a number between 0 and 1.\n", getClassName ().c_str (), iso_level_);
236 grid_ = std::vector<float> (res_x_*res_y_*res_z_, 0.0f);
239 tree_->setInputCloud (input_);
253 for (
int x = 1; x < res_x_-1; ++x)
254 for (
int y = 1; y < res_y_-1; ++y)
255 for (
int z = 1; z < res_z_-1; ++z)
257 Eigen::Vector3i index_3d (x, y, z);
258 std::vector<float> leaf_node;
259 getNeighborList1D (leaf_node, index_3d);
260 createSurface (leaf_node, index_3d, cloud);
265 for (
size_t i = 0; i < output.
polygons.size (); ++i)
269 for (
int j = 0; j < 3; ++j)
270 v.
vertices[j] = static_cast<int> (i) * 3 + j;
277 template <
typename Po
intNT>
void
279 std::vector<pcl::Vertices> &polygons)
281 if (!(iso_level_ >= 0 && iso_level_ < 1))
283 PCL_ERROR (
"[pcl::%s::performReconstruction] Invalid iso level %f! Please use a number between 0 and 1.\n", getClassName ().c_str (), iso_level_);
291 grid_ = std::vector<float> (res_x_*res_y_*res_z_, 0.0f);
294 tree_->setInputCloud (input_);
305 for (
int x = 1; x < res_x_-1; ++x)
306 for (
int y = 1; y < res_y_-1; ++y)
307 for (
int z = 1; z < res_z_-1; ++z)
309 Eigen::Vector3i index_3d (x, y, z);
310 std::vector<float> leaf_node;
311 getNeighborList1D (leaf_node, index_3d);
312 createSurface (leaf_node, index_3d, points);
315 polygons.resize (points.
size () / 3);
316 for (
size_t i = 0; i < polygons.size (); ++i)
320 for (
int j = 0; j < 3; ++j)
321 v.
vertices[j] = static_cast<int> (i) * 3 + j;
328 #define PCL_INSTANTIATE_MarchingCubes(T) template class PCL_EXPORTS pcl::MarchingCubes<T>;
330 #endif // PCL_SURFACE_IMPL_MARCHING_CUBES_H_