38#ifndef PCL_SURFACE_IMPL_TEXTURE_MAPPING_HPP_
39#define PCL_SURFACE_IMPL_TEXTURE_MAPPING_HPP_
42#include <pcl/surface/texture_mapping.h>
43#include <unordered_set>
46template<
typename Po
intInT> std::vector<Eigen::Vector2f, Eigen::aligned_allocator<Eigen::Vector2f> >
48 const Eigen::Vector3f &p1,
49 const Eigen::Vector3f &p2,
50 const Eigen::Vector3f &p3)
52 std::vector<Eigen::Vector2f, Eigen::aligned_allocator<Eigen::Vector2f> > tex_coordinates;
54 Eigen::Vector3f
p1p2 (p2[0] - p1[0], p2[1] - p1[1], p2[2] - p1[2]);
55 Eigen::Vector3f
p1p3 (p3[0] - p1[0], p3[1] - p1[1], p3[2] - p1[2]);
56 Eigen::Vector3f
p2p3 (p3[0] - p2[0], p3[1] - p2[1], p3[2] - p2[2]);
79 double e1 = (p2 - p3).norm () / f_;
80 double e2 = (p1 - p3).norm () / f_;
81 double e3 = (p1 - p2).norm () / f_;
87 tp2[0] =
static_cast<float> (
e3);
99 r_tp2[0] =
static_cast<float> (
tp2[0] * std::cos (alpha) -
tp2[1] * std::sin (alpha));
100 r_tp2[1] =
static_cast<float> (
tp2[0] * std::sin (alpha) +
tp2[1] * std::cos (alpha));
102 r_tp3[0] =
static_cast<float> (
tp3[0] * std::cos (alpha) -
tp3[1] * std::sin (alpha));
103 r_tp3[1] =
static_cast<float> (
tp3[0] * std::sin (alpha) +
tp3[1] * std::cos (alpha));
137 tex_coordinates.push_back (
tp1);
138 tex_coordinates.push_back (
tp2);
139 tex_coordinates.push_back (
tp3);
140 return (tex_coordinates);
144template<
typename Po
intInT>
void
154 Eigen::Vector3f
facet[3];
157 std::vector<std::vector<Eigen::Vector2f, Eigen::aligned_allocator<Eigen::Vector2f> > >
texture_map;
162 std::vector<Eigen::Vector2f, Eigen::aligned_allocator<Eigen::Vector2f> >
texture_map_tmp;
165 for (std::size_t i = 0; i <
tex_mesh.tex_polygons[
m].
size (); ++i)
168 for (std::size_t j = 0; j <
tex_mesh.tex_polygons[
m][i].vertices.
size (); ++j)
170 std::size_t idx =
tex_mesh.tex_polygons[
m][i].vertices[j];
180 std::vector<Eigen::Vector2f, Eigen::aligned_allocator<Eigen::Vector2f> > tex_coordinates = mapTexture2Face (
facet[0],
facet[1],
facet[2]);
186 tex_material_.tex_name =
"material_" + std::to_string(
m);
187 tex_material_.tex_file = tex_files_[
m];
188 tex_mesh.tex_materials.push_back (tex_material_);
196template<
typename Po
intInT>
void
211 for (
int i = 0; i < nr_points; ++i)
244 std::vector<std::vector<Eigen::Vector2f, Eigen::aligned_allocator<Eigen::Vector2f> > >
texture_map;
249 std::vector<Eigen::Vector2f, Eigen::aligned_allocator<Eigen::Vector2f> >
texture_map_tmp;
252 for (std::size_t i = 0; i <
tex_mesh.tex_polygons[
m].
size (); ++i)
255 for (std::size_t j = 0; j <
tex_mesh.tex_polygons[
m][i].vertices.
size (); ++j)
257 std::size_t idx =
tex_mesh.tex_polygons[
m][i].vertices[j];
270 tex_material_.tex_name =
"material_" + std::to_string(
m);
271 tex_material_.tex_file = tex_files_[
m];
272 tex_mesh.tex_materials.push_back (tex_material_);
280template<
typename Po
intInT>
void
286 PCL_ERROR (
"The mesh should be divided into nbCamera+1 sub-meshes.\n");
287 PCL_ERROR (
"You provided %d cameras and a mesh containing %d sub-meshes.\n",
cams.
size (),
tex_mesh.tex_polygons.
size ());
291 PCL_INFO (
"You provided %d cameras and a mesh containing %d sub-meshes.\n",
cams.
size (),
tex_mesh.tex_polygons.
size ());
311 std::vector<Eigen::Vector2f, Eigen::aligned_allocator<Eigen::Vector2f> >
texture_map_tmp;
330 tex_material_.tex_name =
"material_" + std::to_string(
m);
332 tex_mesh.tex_materials.push_back (tex_material_);
339 std::vector<Eigen::Vector2f, Eigen::aligned_allocator<Eigen::Vector2f> >
texture_map_tmp;
352 tex_material_.tex_name =
"material_" + std::to_string(
cams.
size());
353 tex_material_.tex_file =
"occluded.jpg";
354 tex_mesh.tex_materials.push_back (tex_material_);
358template<
typename Po
intInT>
bool
361 Eigen::Vector3f direction;
362 direction (0) =
pt.x;
363 direction (1) =
pt.y;
364 direction (2) =
pt.z;
369 cloud = octree->getInputCloud();
374 octree->getIntersectedVoxelIndices(direction, -direction, indices);
376 int nbocc =
static_cast<int> (indices.
size ());
377 for (
const auto &index : indices)
380 if (
pt.z * (*cloud)[index].z < 0)
397template<
typename Po
intInT>
void
418 Eigen::Vector3f direction;
422 direction (0) = (*input_cloud)[i].x;
423 direction (1) = (*input_cloud)[i].y;
424 direction (2) = (*input_cloud)[i].z;
429 int nbocc =
static_cast<int> (indices.
size ());
430 for (
const auto &index : indices)
433 if ((*
input_cloud)[i].z * (*input_cloud)[index].z < 0)
461template<
typename Po
intInT>
void
478 for (std::size_t polygons = 0; polygons <
cleaned_mesh.tex_polygons.
size (); ++polygons)
483 for (std::size_t faces = 0; faces <
tex_mesh.tex_polygons[polygons].
size (); ++faces)
489 for (
const auto &
vertex :
tex_mesh.tex_polygons[polygons][faces].vertices)
514template<
typename Po
intInT>
void
529template<
typename Po
intInT>
int
536 PCL_ERROR (
"The mesh must contain only 1 sub-mesh!\n");
542 PCL_ERROR (
"Must provide at least one camera info!\n");
579 for (std::size_t faces = 0; faces <
tex_mesh.tex_polygons[0].
size (); ++faces)
584 tex_mesh.tex_polygons[0][faces].vertices.cend(),
587 if (occluded_set.find(vertex) != occluded_set.cend()) {
615template<
typename Po
intInT>
void
634 Eigen::Vector3f direction;
640 std::vector<double>
zDist;
641 std::vector<double>
ptDist;
645 direction =
pt.getVector3fMap() = point.getVector3fMap();
651 nbocc =
static_cast<int> (indices.
size ());
654 for (
const auto &index : indices)
676 (
nbocc == 0) ? (
pt.intensity = 0) : (
pt.intensity = 1);
689template<
typename Po
intInT>
void
701template<
typename Po
intInT>
void
712 std::vector<pcl::Vertices> faces;
731 nan_point.x = std::numeric_limits<float>::quiet_NaN ();
732 nan_point.y = std::numeric_limits<float>::quiet_NaN ();
765 u1.idx_face = idx_face;
u2.idx_face = idx_face;
u3.idx_face = idx_face;
869 std::vector<Eigen::Vector2f, Eigen::aligned_allocator<Eigen::Vector2f> >
dummy_container;
882 for (std::size_t idx_face = 0 ; idx_face <
visibility.
size () ; ++idx_face)
923 std::vector<Eigen::Vector2f, Eigen::aligned_allocator<Eigen::Vector2f> >
dummy_container;
928 for(std::size_t idx_face = 0 ; idx_face <
mesh.tex_polygons[
cameras.
size()].
size() ; ++idx_face)
931 UV1(0) = -1.0;
UV1(1) = -1.0;
932 UV2(0) = -1.0;
UV2(1) = -1.0;
933 UV3(0) = -1.0;
UV3(1) = -1.0;
942template<
typename Po
intInT>
inline void
975template<
typename Po
intInT>
inline void
986 radius = std::sqrt( std::max(
r1, std::max(
r2,
r3) )) ;
991template<
typename Po
intInT>
inline bool
1000 if (
cam.center_w > 0)
1004 if (
cam.center_h > 0)
1010 if (
cam.focal_length_w > 0)
1014 if (
cam.focal_length_h > 0)
1035template<
typename Po
intInT>
inline bool
1039 Eigen::Vector2d
v0,
v1,
v2;
1040 v0(0) = p3.
x - p1.
x;
v0(1) = p3.
y - p1.
y;
1041 v1(0) = p2.
x - p1.
x;
v1(1) = p2.
y - p1.
y;
1057 return ((u >= 0) && (v >= 0) && (u + v < 1));
1061template<
typename Po
intInT>
inline bool
1072#define PCL_INSTANTIATE_TextureMapping(T) \
1073 template class PCL_EXPORTS pcl::TextureMapping<T>;
Iterator class for point clouds with or without given indices.
ConstCloudIterator(const PointCloud< PointT > &cloud)
std::size_t size() const
Size of the range the iterator is going through.
shared_ptr< PointCloud< PointT > > Ptr
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.
float euclideanDistance(const PointType1 &p1, const PointType2 &p2)
Calculate the euclidean distance between the two given points.
void fromPCLPointCloud2(const pcl::PCLPointCloud2 &msg, pcl::PointCloud< PointT > &cloud, const MsgFieldMap &field_map)
Convert a PCLPointCloud2 binary data blob into a pcl::PointCloud<T> object using a field_map.
A 2D point structure representing Euclidean xy coordinates.
Structure to store camera pose and focal length.
Structure that links a uv coordinate to its 3D point and face.