6#include "reusex/core/logging.hpp"
7#include "reusex/types.hpp"
10#include <boost/functional/hash.hpp>
11#include <pcl/ModelCoefficients.h>
12#include <pcl/PolygonMesh.h>
13#include <pcl/common/pca.h>
14#include <range/v3/view/iota.hpp>
15#include <range/v3/view/zip.hpp>
28 const Eigen::Vector3d &point) -> double;
44 std::vector<IndicesPtr> &inliers,
46 const double threshold = 0.6,
47 const double new_plane_offset = 0.5)
48 -> std::vector<std::pair<size_t, size_t>>;
62 const double threshold = 0.1,
63 const Eigen::Matrix<double, 3, 1> &up =
64 Eigen::Matrix<double, 3, 1>(0, 0, 1))
76 Eigen::Vector4d
const &plane,
78 const float threshold = 0.2) -> size_t;
93 std::vector<IndicesPtr>
const &inliers_,
96 const double distance_threshold = 0.5,
97 const double min_overlap = 0.8)
98 -> std::tuple<EigenVectorContainer<double, 4>, std::vector<IndicesPtr>,
110 const Eigen::Vector3d &up = Eigen::Vector3d(0, 0, 1),
111 const double epsilon = 0.1)
112 -> std::tuple<std::vector<size_t>, std::vector<size_t>>;
128template <
typename CloudPtr>
131 if (poly.vertices.size() < 3) {
132 throw std::invalid_argument(
133 "Polygon must have at least 3 vertices to compute a normal");
136 Eigen::Vector3f normal = Eigen::Vector3f::Zero();
137 for (
size_t i = 0; i < poly.vertices.size(); ++i) {
138 const auto idx_c = poly.vertices[i];
139 const auto idx_n = poly.vertices[(i + 1) % poly.vertices.size()];
140 const auto &v_c = cloud->points[idx_c].getVector3fMap();
141 const auto &v_n = cloud->points[idx_n].getVector3fMap();
142 normal += v_c.cross(v_n);
145 const float magnitude = normal.norm();
146 if (magnitude < 1e-10f) {
147 throw std::runtime_error(
148 "Cannot compute normal for degenerate polygon (zero magnitude)");
auto make_pairs(EigenVectorContainer< double, 4 > &planes, std::vector< IndicesPtr > &inliers, EigenVectorContainer< double, 3 > ¢roids, const double threshold=0.6, const double new_plane_offset=0.5) -> std::vector< std::pair< size_t, size_t > >
Create pairs of opposite parallel planes.
auto compute_polygon_normal(const pcl::Vertices &poly, const CloudPtr &cloud) -> Eigen::Vector3f
Compute the normal vector of a polygon.
auto dist_plane_point(const Eigen::Vector4d &plane, const Eigen::Vector3d &point) -> double
Calculate distance from a point to a plane.
auto compute_number_of_inliers(CloudConstPtr cloud, Eigen::Vector4d const &plane, IndicesConstPtr indices, const float threshold=0.2) -> size_t
Count number of inliers for a plane.
auto merge_planes(EigenVectorContainer< double, 4 > const &planes_, std::vector< IndicesPtr > const &inliers_, EigenVectorContainer< double, 3 > const ¢roids_, CloudConstPtr cloud, const double angle_threshold=0.1, const double distance_threshold=0.5, const double min_overlap=0.8) -> std::tuple< EigenVectorContainer< double, 4 >, std::vector< IndicesPtr >, EigenVectorContainer< double, 3 > >
Merge similar planes based on angle, distance, and overlap.
auto separate_planes(const EigenVectorContainer< double, 4 > &planes, const Eigen::Vector3d &up=Eigen::Vector3d(0, 0, 1), const double epsilon=0.1) -> std::tuple< std::vector< size_t >, std::vector< size_t > >
Separate planes into horizontal and vertical based on up vector.
auto force_orthogonal_planes(EigenVectorContainer< double, 4 > &planes, const double threshold=0.1, const Eigen::Matrix< double, 3, 1 > &up=Eigen::Matrix< double, 3, 1 >(0, 0, 1)) -> EigenVectorContainer< double, 4 >
Force planes to be orthogonal to a reference direction.
std::vector< Eigen::Matrix< Scalar, Rows, 1 >, Eigen::aligned_allocator< Eigen::Matrix< Scalar, Rows, 1 > > > EigenVectorContainer
typename Cloud::Ptr CloudPtr
pcl::IndicesConstPtr IndicesConstPtr
typename Cloud::ConstPtr CloudConstPtr