38 #ifndef PCL_STANDALONE_MARCHING_CUBES_IMPL_HPP_
39 #define PCL_STANDALONE_MARCHING_CUBES_IMPL_HPP_
41 #include <pcl/gpu/kinfu_large_scale/standalone_marching_cubes.h>
45 template <
typename Po
intT>
48 voxels_x_ = new_voxels_x;
49 voxels_y_ = new_voxels_y;
50 voxels_z_ = new_voxels_z;
51 volume_size_ = new_volume_size;
54 const Eigen::Vector3f volume_size = Eigen::Vector3f::Constant (volume_size_);
56 const Eigen::Vector3i volume_resolution (voxels_x_, voxels_y_, voxels_z_);
58 tsdf_volume_gpu_->setSize (volume_size);
61 int tsdf_total_size = voxels_x_ * voxels_y_ * voxels_z_;
62 tsdf_volume_cpu_= std::vector<int> (tsdf_total_size,0);
74 std::cout <<
"VOLUME SIZE IS " << volume_size_ << std::endl;
77 tsdf_volume_gpu_->reset ();
80 fill (tsdf_volume_cpu_.begin (), tsdf_volume_cpu_.end (), 0);
83 loadTsdfCloudToGPU (cloud);
86 return ( runMarchingCubes () );
93 template <
typename Po
intT>
void
96 std::vector< MeshPtr > meshes_vector;
98 int max_iterations = std::min( tsdf_clouds.size (), tsdf_offsets.size () );
99 PCL_INFO (
"There are %d cubes to be processed \n", max_iterations);
100 float cell_size = volume_size_ / voxels_x_;
102 int mesh_counter = 0;
104 for(
int i = 0; i < max_iterations; ++i)
106 PCL_INFO (
"Processing cube number %d\n", i);
109 Eigen::Affine3f cloud_transform;
111 float originX = (tsdf_offsets[i]).x();
112 float originY = (tsdf_offsets[i]).y();
113 float originZ = (tsdf_offsets[i]).z();
115 cloud_transform.linear ().setIdentity ();
116 cloud_transform.translation ()[0] = -originX;
117 cloud_transform.translation ()[1] = -originY;
118 cloud_transform.translation ()[2] = -originZ;
123 MeshPtr tmp = getMeshFromTSDFCloud (*tsdf_clouds[i]);
127 meshes_vector.push_back (tmp);
132 PCL_INFO (
"This cloud returned no faces, we skip it!\n");
137 cloud_transform.translation ()[0] = originX * cell_size;
138 cloud_transform.translation ()[1] = originY * cell_size;
139 cloud_transform.translation ()[2] = originZ * cell_size;
148 std::stringstream name;
149 name <<
"mesh_" << mesh_counter <<
".ply";
150 PCL_INFO (
"Saving mesh...%d \n", mesh_counter);
162 return (tsdf_volume_gpu_);
167 template <
typename Po
intT> std::vector<int>&
170 return (tsdf_volume_cpu_);
175 template <
typename Po
intT>
void
179 convertTsdfVectors (cloud, tsdf_volume_cpu_);
182 int cubeColumns = voxels_x_;
183 tsdf_volume_gpu_->data ().upload (tsdf_volume_cpu_, cubeColumns);
188 template <
typename Po
intT>
void
191 constexpr
int DIVISOR = std::numeric_limits<short>::max();
194 #pragma omp parallel for \
196 shared(cloud, output)
197 for(
int i = 0; i < (int) cloud.
size (); ++i)
203 if(x > 0 && x < voxels_x_ && y > 0 && y < voxels_y_ && z > 0 && z < voxels_z_)
206 int dst_index = x + voxels_x_ * y + voxels_y_ * voxels_x_ * z;
208 short2& elem = *
reinterpret_cast<short2*
> (&output[dst_index]);
209 elem.x =
static_cast<short> (cloud[i].intensity * DIVISOR);
210 elem.y =
static_cast<short> (1);
220 if (triangles.
empty () )
234 mesh_ptr->polygons.resize (triangles.
size () / 3);
235 for (std::size_t i = 0; i < mesh_ptr->polygons.size (); ++i)
241 mesh_ptr->polygons[i] = v;
264 if(mesh_ptr_ !=
nullptr)
PointCloud represents the base class in PCL for storing collections of 3D points.
std::uint32_t width
The point cloud width (if organized as an image-structure).
std::uint32_t height
The point cloud height (if organized as an image-structure).
shared_ptr< PointCloud< PointT > > Ptr
std::vector< PointT, Eigen::aligned_allocator< PointT > > points
The point data.
std::size_t size() const
Returns size in elements.
void download(T *host_ptr) const
Downloads data from internal buffer to CPU memory.
bool empty() const
Returns true if unallocated otherwise false.
MarchingCubes implements MarchingCubes functionality for TSDF volume on GPU.
shared_ptr< MarchingCubes > Ptr
Smart pointer.
StandaloneMarchingCubes(int voxels_x=512, int voxels_y=512, int voxels_z=512, float volume_size=3.0f)
Constructor
pcl::PolygonMesh::Ptr MeshPtr
MeshPtr getMeshFromTSDFCloud(const PointCloud &cloud)
Run marching cubes in a TSDF cloud and returns a PolygonMesh.
MeshPtr convertTrianglesToMesh(const pcl::gpu::DeviceArray< pcl::PointXYZ > &triangles)
Converts the triangles buffer device to a PolygonMesh.
void getMeshesFromTSDFVector(const std::vector< PointCloudPtr > &tsdf_clouds, const std::vector< Eigen::Vector3f, Eigen::aligned_allocator< Eigen::Vector3f > > &tsdf_offsets)
Runs marching cubes on every pointcloud in the vector.
void convertTsdfVectors(const PointCloud &cloud, std::vector< int > &output)
Read the data in the point cloud.
std::vector< int > & tsdfVolumeCPU()
Returns the associated Tsdf Volume buffer in CPU.
void loadTsdfCloudToGPU(const PointCloud &cloud)
Loads a TSDF Cloud to the TSDF Volume in GPU.
MeshPtr runMarchingCubes()
Runs marching cubes on the data that is contained in the TSDF Volume in GPU.
TsdfVolume::Ptr tsdfVolumeGPU()
Returns the associated Tsdf Volume buffer in GPU.
shared_ptr< TsdfVolume > Ptr
void transformPointCloud(const pcl::PointCloud< PointT > &cloud_in, pcl::PointCloud< PointT > &cloud_out, const Eigen::Matrix< Scalar, 4, 4 > &transform, bool copy_all_fields)
Apply a rigid transform defined by a 4x4 matrix.
int savePLYFile(const std::string &file_name, const pcl::PCLPointCloud2 &cloud, const Eigen::Vector4f &origin=Eigen::Vector4f::Zero(), const Eigen::Quaternionf &orientation=Eigen::Quaternionf::Identity(), bool binary_mode=false, bool use_camera=true)
Save point cloud data to a PLY file containing n-D points.
Defines functions, macros and traits for allocating and using memory.
void fromPCLPointCloud2(const pcl::PCLPointCloud2 &msg, pcl::PointCloud< PointT > &cloud, const MsgFieldMap &field_map, const std::uint8_t *msg_data)
Convert a PCLPointCloud2 binary data blob into a pcl::PointCloud<T> object using a field_map.
void toPCLPointCloud2(const pcl::PointCloud< PointT > &cloud, pcl::PCLPointCloud2 &msg, bool padding)
Convert a pcl::PointCloud<T> object to a PCLPointCloud2 binary data blob.
shared_ptr< ::pcl::PolygonMesh > Ptr
Describes a set of vertices in a polygon mesh, by basically storing an array of indices.