38 #ifndef PCL_SURFACE_IMPL_TEXTURE_MAPPING_HPP_
39 #define PCL_SURFACE_IMPL_TEXTURE_MAPPING_HPP_
42 #include <pcl/kdtree/kdtree_flann.h>
43 #include <pcl/surface/texture_mapping.h>
44 #include <unordered_set>
47 template<
typename Po
intInT> std::vector<Eigen::Vector2f, Eigen::aligned_allocator<Eigen::Vector2f> >
49 const Eigen::Vector3f &p1,
50 const Eigen::Vector3f &p2,
51 const Eigen::Vector3f &p3)
53 std::vector<Eigen::Vector2f, Eigen::aligned_allocator<Eigen::Vector2f> > tex_coordinates;
55 Eigen::Vector3f p1p2 (p2[0] - p1[0], p2[1] - p1[1], p2[2] - p1[2]);
56 Eigen::Vector3f p1p3 (p3[0] - p1[0], p3[1] - p1[1], p3[2] - p1[2]);
57 Eigen::Vector3f p2p3 (p3[0] - p2[0], p3[1] - p2[1], p3[2] - p2[2]);
60 p1p2 /= std::sqrt (p1p2.dot (p1p2));
61 p1p3 /= std::sqrt (p1p3.dot (p1p3));
62 p2p3 /= std::sqrt (p2p3.dot (p2p3));
65 Eigen::Vector3f f_normal = p1p2.cross (p1p3);
66 f_normal /= std::sqrt (f_normal.dot (f_normal));
69 Eigen::Vector3f f_vector_field = vector_field_ - vector_field_.dot (f_normal) * f_normal;
72 f_vector_field /= std::sqrt (f_vector_field.dot (f_vector_field));
75 Eigen::Vector2f tp1, tp2, tp3;
77 double alpha = std::acos (f_vector_field.dot (p1p2));
80 double e1 = (p2 - p3).norm () / f_;
81 double e2 = (p1 - p3).norm () / f_;
82 double e3 = (p1 - p2).norm () / f_;
88 tp2[0] =
static_cast<float> (e3);
92 double cos_p1 = (e2 * e2 + e3 * e3 - e1 * e1) / (2 * e2 * e3);
93 double sin_p1 = sqrt (1 - (cos_p1 * cos_p1));
95 tp3[0] =
static_cast<float> (cos_p1 * e2);
96 tp3[1] =
static_cast<float> (sin_p1 * e2);
99 Eigen::Vector2f r_tp2, r_tp3;
100 r_tp2[0] =
static_cast<float> (tp2[0] * std::cos (alpha) - tp2[1] * std::sin (alpha));
101 r_tp2[1] =
static_cast<float> (tp2[0] * std::sin (alpha) + tp2[1] * std::cos (alpha));
103 r_tp3[0] =
static_cast<float> (tp3[0] * std::cos (alpha) - tp3[1] * std::sin (alpha));
104 r_tp3[1] =
static_cast<float> (tp3[0] * std::sin (alpha) + tp3[1] * std::cos (alpha));
114 float min_x = tp1[0];
115 float min_y = tp1[1];
138 tex_coordinates.push_back (tp1);
139 tex_coordinates.push_back (tp2);
140 tex_coordinates.push_back (tp3);
141 return (tex_coordinates);
145 template<
typename Po
intInT>
void
150 int point_size =
static_cast<int> (tex_mesh.
cloud.
data.size ()) / nr_points;
155 Eigen::Vector3f facet[3];
158 std::vector<std::vector<Eigen::Vector2f, Eigen::aligned_allocator<Eigen::Vector2f> > >texture_map;
160 for (std::size_t m = 0; m < tex_mesh.
tex_polygons.size (); ++m)
163 std::vector<Eigen::Vector2f, Eigen::aligned_allocator<Eigen::Vector2f> > texture_map_tmp;
166 for (std::size_t i = 0; i < tex_mesh.
tex_polygons[m].size (); ++i)
169 for (std::size_t j = 0; j < tex_mesh.
tex_polygons[m][i].vertices.size (); ++j)
171 std::size_t idx = tex_mesh.
tex_polygons[m][i].vertices[j];
172 memcpy (&x, &tex_mesh.
cloud.
data[idx * point_size + tex_mesh.
cloud.
fields[0].offset],
sizeof(
float));
173 memcpy (&y, &tex_mesh.
cloud.
data[idx * point_size + tex_mesh.
cloud.
fields[1].offset],
sizeof(
float));
174 memcpy (&z, &tex_mesh.
cloud.
data[idx * point_size + tex_mesh.
cloud.
fields[2].offset],
sizeof(
float));
181 std::vector<Eigen::Vector2f, Eigen::aligned_allocator<Eigen::Vector2f> > tex_coordinates = mapTexture2Face (facet[0], facet[1], facet[2]);
182 for (
const auto &tex_coordinate : tex_coordinates)
183 texture_map_tmp.push_back (tex_coordinate);
187 tex_material_.tex_name =
"material_" + std::to_string(m);
188 tex_material_.tex_file = tex_files_[m];
197 template<
typename Po
intInT>
void
202 int point_size =
static_cast<int> (tex_mesh.
cloud.
data.size ()) / nr_points;
204 float x_lowest = 100000;
206 float y_lowest = 100000;
208 float z_lowest = 100000;
212 for (
int i = 0; i < nr_points; ++i)
214 memcpy (&x_, &tex_mesh.
cloud.
data[i * point_size + tex_mesh.
cloud.
fields[0].offset],
sizeof(
float));
215 memcpy (&y_, &tex_mesh.
cloud.
data[i * point_size + tex_mesh.
cloud.
fields[1].offset],
sizeof(
float));
216 memcpy (&z_, &tex_mesh.
cloud.
data[i * point_size + tex_mesh.
cloud.
fields[2].offset],
sizeof(
float));
235 float x_range = (x_lowest - x_highest) * -1;
236 float x_offset = 0 - x_lowest;
241 float z_range = (z_lowest - z_highest) * -1;
242 float z_offset = 0 - z_lowest;
245 std::vector<std::vector<Eigen::Vector2f, Eigen::aligned_allocator<Eigen::Vector2f> > >texture_map;
247 for (std::size_t m = 0; m < tex_mesh.
tex_polygons.size (); ++m)
250 std::vector<Eigen::Vector2f, Eigen::aligned_allocator<Eigen::Vector2f> > texture_map_tmp;
253 for (std::size_t i = 0; i < tex_mesh.
tex_polygons[m].size (); ++i)
255 Eigen::Vector2f tmp_VT;
256 for (std::size_t j = 0; j < tex_mesh.
tex_polygons[m][i].vertices.size (); ++j)
258 std::size_t idx = tex_mesh.
tex_polygons[m][i].vertices[j];
259 memcpy (&x_, &tex_mesh.
cloud.
data[idx * point_size + tex_mesh.
cloud.
fields[0].offset],
sizeof(
float));
260 memcpy (&y_, &tex_mesh.
cloud.
data[idx * point_size + tex_mesh.
cloud.
fields[1].offset],
sizeof(
float));
261 memcpy (&z_, &tex_mesh.
cloud.
data[idx * point_size + tex_mesh.
cloud.
fields[2].offset],
sizeof(
float));
264 tmp_VT[0] = (x_ + x_offset) / x_range;
265 tmp_VT[1] = (z_ + z_offset) / z_range;
266 texture_map_tmp.push_back (tmp_VT);
271 tex_material_.tex_name =
"material_" + std::to_string(m);
272 tex_material_.tex_file = tex_files_[m];
281 template<
typename Po
intInT>
void
287 PCL_ERROR (
"The mesh should be divided into nbCamera+1 sub-meshes.\n");
288 PCL_ERROR (
"You provided %d cameras and a mesh containing %d sub-meshes.\n", cams.size (), tex_mesh.
tex_polygons.size ());
292 PCL_INFO (
"You provided %d cameras and a mesh containing %d sub-meshes.\n", cams.size (), tex_mesh.
tex_polygons.size ());
300 for (std::size_t m = 0; m < cams.size (); ++m)
303 Camera current_cam = cams[m];
306 Eigen::Affine3f cam_trans = current_cam.
pose;
312 std::vector<Eigen::Vector2f, Eigen::aligned_allocator<Eigen::Vector2f> > texture_map_tmp;
315 for (
const auto &tex_polygon : tex_mesh.
tex_polygons[m])
317 Eigen::Vector2f tmp_VT;
319 for (
const auto &vertex : tex_polygon.vertices)
322 PointInT pt = (*camera_transformed_cloud)[vertex];
325 getPointUVCoordinates (pt, current_cam, tmp_VT);
326 texture_map_tmp.push_back (tmp_VT);
331 tex_material_.tex_name =
"material_" + std::to_string(m);
340 std::vector<Eigen::Vector2f, Eigen::aligned_allocator<Eigen::Vector2f> > texture_map_tmp;
341 for (
const auto &tex_polygon : tex_mesh.
tex_polygons[cams.size ()])
342 for (std::size_t j = 0; j < tex_polygon.vertices.size (); ++j)
344 Eigen::Vector2f tmp_VT;
347 texture_map_tmp.push_back (tmp_VT);
353 tex_material_.tex_name =
"material_" + std::to_string(cams.size());
354 tex_material_.tex_file =
"occluded.jpg";
359 template<
typename Po
intInT>
bool
362 Eigen::Vector3f direction;
363 direction (0) = pt.x;
364 direction (1) = pt.y;
365 direction (2) = pt.z;
370 cloud = octree->getInputCloud();
372 double distance_threshold = octree->getResolution();
375 octree->getIntersectedVoxelIndices(direction, -direction, indices);
377 int nbocc =
static_cast<int> (indices.size ());
378 for (
const auto &index : indices)
381 if (pt.z * (*cloud)[index].z < 0)
387 if (std::fabs ((*cloud)[index].z - pt.z) <= distance_threshold)
398 template<
typename Po
intInT>
void
401 const double octree_voxel_size,
pcl::Indices &visible_indices,
405 double maxDeltaZ = octree_voxel_size;
408 Octree octree (octree_voxel_size);
416 visible_indices.clear ();
419 Eigen::Vector3f direction;
421 for (std::size_t i = 0; i < input_cloud->size (); ++i)
423 direction (0) = (*input_cloud)[i].x;
424 direction (1) = (*input_cloud)[i].y;
425 direction (2) = (*input_cloud)[i].z;
430 int nbocc =
static_cast<int> (indices.size ());
431 for (
const auto &index : indices)
434 if ((*input_cloud)[i].z * (*input_cloud)[index].z < 0)
440 if (std::fabs ((*input_cloud)[index].z - (*input_cloud)[i].z) <= maxDeltaZ)
450 filtered_cloud->points.push_back ((*input_cloud)[i]);
451 visible_indices.push_back (
static_cast<pcl::index_t> (i));
455 occluded_indices.push_back (
static_cast<pcl::index_t> (i));
462 template<
typename Po
intInT>
void
466 cleaned_mesh = tex_mesh;
475 removeOccludedPoints (cloud, filtered_cloud, octree_voxel_size, visible, occluded);
479 for (std::size_t polygons = 0; polygons < cleaned_mesh.
tex_polygons.size (); ++polygons)
484 for (std::size_t faces = 0; faces < tex_mesh.
tex_polygons[polygons].size (); ++faces)
487 bool faceIsVisible =
true;
490 for (
const auto &vertex : tex_mesh.
tex_polygons[polygons][faces].vertices)
492 if (find (occluded.begin (), occluded.end (), vertex) == occluded.end ())
501 faceIsVisible =
false;
515 template<
typename Po
intInT>
void
517 const double octree_voxel_size)
525 removeOccludedPoints (cloud, filtered_cloud, octree_voxel_size, visible, occluded);
530 template<
typename Po
intInT>
int
537 PCL_ERROR (
"The mesh must contain only 1 sub-mesh!\n");
541 if (cameras.empty ())
543 PCL_ERROR (
"Must provide at least one camera info!\n");
548 sorted_mesh = tex_mesh;
560 for (
const auto &camera : cameras)
563 Eigen::Affine3f cam_trans = camera.pose;
570 removeOccludedPoints (transformed_cloud, filtered_cloud, octree_voxel_size, visible, occluded);
571 visible_pts = *filtered_cloud;
574 std::unordered_set<index_t> occluded_set(occluded.cbegin(), occluded.cend());
578 std::vector<pcl::Vertices> visibleFaces_currentCam;
580 for (std::size_t faces = 0; faces < tex_mesh.
tex_polygons[0].size (); ++faces)
584 const auto faceIsVisible = std::all_of(tex_mesh.
tex_polygons[0][faces].vertices.cbegin(),
586 [&](
const auto& vertex)
588 if (occluded_set.find(vertex) != occluded_set.cend()) {
592 Eigen::Vector2f dummy_UV;
593 return this->getPointUVCoordinates ((*transformed_cloud)[vertex], camera, dummy_UV);
599 visibleFaces_currentCam.push_back (tex_mesh.
tex_polygons[0][faces]);
606 sorted_mesh.
tex_polygons.push_back (visibleFaces_currentCam);
611 sorted_mesh.tex_polygons.push_back (tex_mesh.tex_polygons[0]);
616 template<
typename Po
intInT>
void
619 const double octree_voxel_size,
const bool show_nb_occlusions,
620 const int max_occlusions)
623 double maxDeltaZ = octree_voxel_size * 2.0;
626 Octree octree (octree_voxel_size);
635 Eigen::Vector3f direction;
641 std::vector<double> zDist;
642 std::vector<double> ptDist;
644 for (
const auto& point: *input_cloud)
646 direction = pt.getVector3fMap() = point.getVector3fMap();
652 nbocc =
static_cast<int> (indices.size ());
655 for (
const auto &index : indices)
658 if (pt.z * (*input_cloud)[index].z < 0)
662 else if (std::fabs ((*input_cloud)[index].z - pt.z) <= maxDeltaZ)
669 zDist.push_back (std::fabs ((*input_cloud)[index].z - pt.z));
674 if (show_nb_occlusions)
675 (nbocc <= max_occlusions) ? (pt.
intensity =
static_cast<float> (nbocc)) : (pt.
intensity =
static_cast<float> (max_occlusions));
679 colored_cloud->
points.push_back (pt);
682 if (zDist.size () >= 2)
684 std::sort (zDist.begin (), zDist.end ());
685 std::sort (ptDist.begin (), ptDist.end ());
690 template<
typename Po
intInT>
void
692 double octree_voxel_size,
bool show_nb_occlusions,
int max_occlusions)
698 showOcclusions (cloud, colored_cloud, octree_voxel_size, show_nb_occlusions, max_occlusions);
702 template<
typename Po
intInT>
void
713 std::vector<pcl::Vertices> faces;
715 for (
int current_cam = 0; current_cam < static_cast<int> (cameras.size ()); ++current_cam)
717 PCL_INFO (
"Processing camera %d of %d.\n", current_cam+1, cameras.size ());
725 std::vector<bool> visibility;
726 visibility.resize (mesh.
tex_polygons[current_cam].size ());
727 std::vector<UvIndex> indexes_uv_to_points;
732 nan_point.
x = std::numeric_limits<float>::quiet_NaN ();
733 nan_point.
y = std::numeric_limits<float>::quiet_NaN ();
739 for (
int idx_face = 0; idx_face < static_cast<int> (mesh.
tex_polygons[current_cam].size ()); ++idx_face)
746 if (isFaceProjected (cameras[current_cam],
747 (*camera_cloud)[mesh.
tex_polygons[current_cam][idx_face].vertices[0]],
748 (*camera_cloud)[mesh.
tex_polygons[current_cam][idx_face].vertices[1]],
749 (*camera_cloud)[mesh.
tex_polygons[current_cam][idx_face].vertices[2]],
757 projections->
points.push_back (uv_coord1);
758 projections->
points.push_back (uv_coord2);
759 projections->
points.push_back (uv_coord3);
767 indexes_uv_to_points.push_back (u1);
768 indexes_uv_to_points.push_back (u2);
769 indexes_uv_to_points.push_back (u3);
772 visibility[idx_face] =
true;
776 projections->
points.push_back (nan_point);
777 projections->
points.push_back (nan_point);
778 projections->
points.push_back (nan_point);
779 indexes_uv_to_points.push_back (u_null);
780 indexes_uv_to_points.push_back (u_null);
781 indexes_uv_to_points.push_back (u_null);
783 visibility[idx_face] =
false;
793 if (visibility.size () - cpt_invisible !=0)
800 std::vector<float> neighborsSquaredDistance;
804 for (
int idx_pcam = 0 ; idx_pcam <= current_cam ; ++idx_pcam)
807 for (
int idx_face = 0; idx_face < static_cast<int> (mesh.
tex_polygons[idx_pcam].size ()); ++idx_face)
810 if (idx_pcam == current_cam && !visibility[idx_face])
823 if (isFaceProjected (cameras[current_cam],
824 (*camera_cloud)[mesh.
tex_polygons[idx_pcam][idx_face].vertices[0]],
825 (*camera_cloud)[mesh.
tex_polygons[idx_pcam][idx_face].vertices[1]],
826 (*camera_cloud)[mesh.
tex_polygons[idx_pcam][idx_face].vertices[2]],
836 getTriangleCircumcscribedCircleCentroid(uv_coord1, uv_coord2, uv_coord3, center, radius);
839 if (kdtree.
radiusSearch (center, radius, idxNeighbors, neighborsSquaredDistance) > 0 )
842 for (
const auto &idxNeighbor : idxNeighbors)
844 if (std::max ((*camera_cloud)[mesh.
tex_polygons[idx_pcam][idx_face].vertices[0]].z,
845 std::max ((*camera_cloud)[mesh.
tex_polygons[idx_pcam][idx_face].vertices[1]].z,
846 (*camera_cloud)[mesh.
tex_polygons[idx_pcam][idx_face].vertices[2]].z))
847 < (*camera_cloud)[indexes_uv_to_points[idxNeighbor].idx_cloud].z)
850 if (checkPointInsideTriangle(uv_coord1, uv_coord2, uv_coord3, (*projections)[idxNeighbor]))
853 visibility[indexes_uv_to_points[idxNeighbor].idx_face] =
false;
870 std::vector<Eigen::Vector2f, Eigen::aligned_allocator<Eigen::Vector2f> > dummy_container;
875 std::vector<pcl::Vertices> occluded_faces;
876 occluded_faces.resize (visibility.size ());
877 std::vector<pcl::Vertices> visible_faces;
878 visible_faces.resize (visibility.size ());
880 int cpt_occluded_faces = 0;
881 int cpt_visible_faces = 0;
883 for (std::size_t idx_face = 0 ; idx_face < visibility.size () ; ++idx_face)
885 if (visibility[idx_face])
888 mesh.
tex_coordinates[current_cam][cpt_visible_faces * 3](0) = (*projections)[idx_face*3].x;
889 mesh.
tex_coordinates[current_cam][cpt_visible_faces * 3](1) = (*projections)[idx_face*3].y;
891 mesh.
tex_coordinates[current_cam][cpt_visible_faces * 3 + 1](0) = (*projections)[idx_face*3 + 1].x;
892 mesh.
tex_coordinates[current_cam][cpt_visible_faces * 3 + 1](1) = (*projections)[idx_face*3 + 1].y;
894 mesh.
tex_coordinates[current_cam][cpt_visible_faces * 3 + 2](0) = (*projections)[idx_face*3 + 2].x;
895 mesh.
tex_coordinates[current_cam][cpt_visible_faces * 3 + 2](1) = (*projections)[idx_face*3 + 2].y;
897 visible_faces[cpt_visible_faces] = mesh.
tex_polygons[current_cam][idx_face];
904 occluded_faces[cpt_occluded_faces] = mesh.
tex_polygons[current_cam][idx_face];
905 cpt_occluded_faces++;
910 occluded_faces.resize (cpt_occluded_faces);
913 visible_faces.resize (cpt_visible_faces);
924 std::vector<Eigen::Vector2f, Eigen::aligned_allocator<Eigen::Vector2f> > dummy_container;
929 for(std::size_t idx_face = 0 ; idx_face < mesh.
tex_polygons[cameras.size()].size() ; ++idx_face)
931 Eigen::Vector2f UV1, UV2, UV3;
932 UV1(0) = -1.0; UV1(1) = -1.0;
933 UV2(0) = -1.0; UV2(1) = -1.0;
934 UV3(0) = -1.0; UV3(1) = -1.0;
943 template<
typename Po
intInT>
inline void
948 ptB.
x = p2.
x - p1.
x; ptB.
y = p2.
y - p1.
y;
949 ptC.
x = p3.
x - p1.
x; ptC.
y = p3.
y - p1.
y;
951 double D = 2.0*(ptB.
x*ptC.
y - ptB.
y*ptC.
x);
956 circomcenter.
x = p1.
x;
957 circomcenter.
y = p1.
y;
962 double bx2 = ptB.
x * ptB.
x;
963 double by2 = ptB.
y * ptB.
y;
964 double cx2 = ptC.
x * ptC.
x;
965 double cy2 = ptC.
y * ptC.
y;
968 circomcenter.
x =
static_cast<float> (p1.
x + (ptC.
y*(bx2 + by2) - ptB.
y*(cx2 + cy2)) / D);
969 circomcenter.
y =
static_cast<float> (p1.
y + (ptB.
x*(cx2 + cy2) - ptC.
x*(bx2 + by2)) / D);
972 radius = std::sqrt( (circomcenter.
x - p1.
x)*(circomcenter.
x - p1.
x) + (circomcenter.
y - p1.
y)*(circomcenter.
y - p1.
y));
976 template<
typename Po
intInT>
inline void
980 circumcenter.
x =
static_cast<float> (p1.
x + p2.
x + p3.
x ) / 3;
981 circumcenter.
y =
static_cast<float> (p1.
y + p2.
y + p3.
y ) / 3;
982 double r1 = (circumcenter.
x - p1.
x) * (circumcenter.
x - p1.
x) + (circumcenter.
y - p1.
y) * (circumcenter.
y - p1.
y) ;
983 double r2 = (circumcenter.
x - p2.
x) * (circumcenter.
x - p2.
x) + (circumcenter.
y - p2.
y) * (circumcenter.
y - p2.
y) ;
984 double r3 = (circumcenter.
x - p3.
x) * (circumcenter.
x - p3.
x) + (circumcenter.
y - p3.
y) * (circumcenter.
y - p3.
y) ;
987 radius = std::sqrt( std::max( r1, std::max( r2, r3) )) ;
992 template<
typename Po
intInT>
inline bool
998 double sizeX = cam.
width;
999 double sizeY = cam.
height;
1010 double focal_x, focal_y;
1021 UV_coordinates.
x =
static_cast<float> ((focal_x * (pt.x / pt.z) + cx) / sizeX);
1022 UV_coordinates.
y = 1.0f -
static_cast<float> ((focal_y * (pt.y / pt.z) + cy) / sizeY);
1025 if (UV_coordinates.
x >= 0.0 && UV_coordinates.
x <= 1.0 && UV_coordinates.
y >= 0.0 && UV_coordinates.
y <= 1.0)
1030 UV_coordinates.
x = -1.0f;
1031 UV_coordinates.
y = -1.0f;
1036 template<
typename Po
intInT>
inline bool
1040 Eigen::Vector2d v0, v1, v2;
1041 v0(0) = p3.
x - p1.
x; v0(1) = p3.
y - p1.
y;
1042 v1(0) = p2.
x - p1.
x; v1(1) = p2.
y - p1.
y;
1043 v2(0) = pt.
x - p1.
x; v2(1) = pt.
y - p1.
y;
1046 double dot00 = v0.dot(v0);
1047 double dot01 = v0.dot(v1);
1048 double dot02 = v0.dot(v2);
1049 double dot11 = v1.dot(v1);
1050 double dot12 = v1.dot(v2);
1053 double invDenom = 1.0 / (dot00*dot11 - dot01*dot01);
1054 double u = (dot11*dot02 - dot01*dot12) * invDenom;
1055 double v = (dot00*dot12 - dot01*dot02) * invDenom;
1058 return ((u >= 0) && (v >= 0) && (u + v < 1));
1062 template<
typename Po
intInT>
inline bool
1065 return (getPointUVCoordinates(p1, camera, proj1)
1067 getPointUVCoordinates(p2, camera, proj2)
1069 getPointUVCoordinates(p3, camera, proj3)
1073 #define PCL_INSTANTIATE_TextureMapping(T) \
1074 template class PCL_EXPORTS pcl::TextureMapping<T>;
KdTreeFLANN is a generic type of 3D spatial locator using kD-tree structures.
int radiusSearch(const PointT &point, double radius, Indices &k_indices, std::vector< float > &k_sqr_distances, unsigned int max_nn=0) const override
Search for all the nearest neighbors of the query point in a given radius.
void setInputCloud(const PointCloudConstPtr &cloud, const IndicesConstPtr &indices=IndicesConstPtr()) override
Provide a pointer to the input dataset.
shared_ptr< PointCloud< PointT > > Ptr
std::vector< PointT, Eigen::aligned_allocator< PointT > > points
The point data.
bool getPointUVCoordinates(const PointInT &pt, const Camera &cam, Eigen::Vector2f &UV_coordinates)
computes UV coordinates of point, observed by one particular camera
void mapTexture2MeshUV(pcl::TextureMesh &tex_mesh)
Map texture to a mesh UV mapping.
void mapTexture2Mesh(pcl::TextureMesh &tex_mesh)
Map texture to a mesh synthesis algorithm.
void getTriangleCircumcscribedCircleCentroid(const pcl::PointXY &p1, const pcl::PointXY &p2, const pcl::PointXY &p3, pcl::PointXY &circumcenter, double &radius)
Returns the centroid of a triangle and the corresponding circumscribed circle's radius.
typename PointCloud::Ptr PointCloudPtr
typename Octree::Ptr OctreePtr
bool isPointOccluded(const PointInT &pt, const OctreePtr octree)
Check if a point is occluded using raycasting on octree.
bool checkPointInsideTriangle(const pcl::PointXY &p1, const pcl::PointXY &p2, const pcl::PointXY &p3, const pcl::PointXY &pt)
Returns True if a point lays within a triangle.
bool isFaceProjected(const Camera &camera, const PointInT &p1, const PointInT &p2, const PointInT &p3, pcl::PointXY &proj1, pcl::PointXY &proj2, pcl::PointXY &proj3)
Returns true if all the vertices of one face are projected on the camera's image plane.
void removeOccludedPoints(const PointCloudPtr &input_cloud, PointCloudPtr &filtered_cloud, const double octree_voxel_size, pcl::Indices &visible_indices, pcl::Indices &occluded_indices)
Remove occluded points from a point cloud.
std::vector< Eigen::Vector2f, Eigen::aligned_allocator< Eigen::Vector2f > > mapTexture2Face(const Eigen::Vector3f &p1, const Eigen::Vector3f &p2, const Eigen::Vector3f &p3)
Map texture to a face.
int sortFacesByCamera(pcl::TextureMesh &tex_mesh, pcl::TextureMesh &sorted_mesh, const pcl::texture_mapping::CameraVector &cameras, const double octree_voxel_size, PointCloud &visible_pts)
Segment faces by camera visibility.
void getTriangleCircumcenterAndSize(const pcl::PointXY &p1, const pcl::PointXY &p2, const pcl::PointXY &p3, pcl::PointXY &circumcenter, double &radius)
Returns the circumcenter of a triangle and the circle's radius.
void showOcclusions(const PointCloudPtr &input_cloud, pcl::PointCloud< pcl::PointXYZI >::Ptr &colored_cloud, const double octree_voxel_size, const bool show_nb_occlusions=true, const int max_occlusions=4)
Colors a point cloud, depending on its occlusions.
typename PointCloud::ConstPtr PointCloudConstPtr
void mapMultipleTexturesToMeshUV(pcl::TextureMesh &tex_mesh, pcl::texture_mapping::CameraVector &cams)
Map textures acquired from a set of cameras onto a mesh.
void textureMeshwithMultipleCameras(pcl::TextureMesh &mesh, const pcl::texture_mapping::CameraVector &cameras)
Segment and texture faces by camera visibility.
void defineBoundingBox()
Investigate dimensions of pointcloud data set and define corresponding bounding box for octree.
void setInputCloud(const PointCloudConstPtr &cloud_arg, const IndicesConstPtr &indices_arg=IndicesConstPtr())
Provide a pointer to the input data set.
void addPointsFromInputCloud()
Add points from input point cloud to octree.
Octree pointcloud search class
uindex_t getIntersectedVoxelIndices(Eigen::Vector3f origin, Eigen::Vector3f direction, Indices &k_indices, uindex_t max_voxel_count=0) const
Get indices of all voxels that are intersected by a ray (origin, direction).
Define standard C methods to do distance calculations.
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.
std::vector< Camera, Eigen::aligned_allocator< Camera > > CameraVector
detail::int_type_t< detail::index_type_size, detail::index_type_signed > index_t
Type used for an index in PCL.
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.
float euclideanDistance(const PointType1 &p1, const PointType2 &p2)
Calculate the euclidean distance between the two given points.
IndicesAllocator<> Indices
Type used for indices in PCL.
std::vector<::pcl::PCLPointField > fields
std::vector< std::uint8_t > data
A 2D point structure representing Euclidean xy coordinates.
std::vector< std::vector< pcl::Vertices > > tex_polygons
polygon which is mapped with specific texture defined in TexMaterial
std::vector< std::vector< Eigen::Vector2f, Eigen::aligned_allocator< Eigen::Vector2f > > > tex_coordinates
UV coordinates.
std::vector< pcl::TexMaterial > tex_materials
define texture material
pcl::PCLPointCloud2 cloud
Structure to store camera pose and focal length.
Structure that links a uv coordinate to its 3D point and face.