ReUseX  0.0.1
3D Point Cloud Processing for Building Reuse
Loading...
Searching...
No Matches
utils.hpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2025 Povl Filip Sonne-Frederiksen
2//
3// SPDX-License-Identifier: GPL-3.0-or-later
4
5#pragma once
6#include <ReUseX/types.hpp>
7
8#include <Eigen/Core>
9#include <boost/functional/hash.hpp>
10#include <pcl/ModelCoefficients.h>
11#include <pcl/PolygonMesh.h>
12#include <pcl/common/pca.h>
13#include <range/v3/view/iota.hpp>
14#include <range/v3/view/zip.hpp>
15#include <spdlog/spdlog.h>
16
17#include <stdexcept>
18
19namespace ReUseX::geometry {
20
27auto dist_plane_point(const Eigen::Vector4d &plane,
28 const Eigen::Vector3d &point) -> double;
29
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>>;
49
62 EigenVectorContainer<double, 4> &planes, const double threshold = 0.1,
63 const Eigen::Matrix<double, 3, 1> &up = Eigen::Matrix<double, 3, 1>(
65
75 Eigen::Vector4d const &plane,
76 IndicesConstPtr indices,
77 const float threshold = 0.2) -> size_t;
78
92 std::vector<IndicesPtr> const &inliers_,
93 EigenVectorContainer<double, 3> const &centroids_,
94 CloudConstPtr cloud, const double angle_threshold = 0.1,
95 const double distance_threshold = 0.5,
96 const double min_overlap = 0.8)
97 -> std::tuple<EigenVectorContainer<double, 4>, std::vector<IndicesPtr>,
99
109 const Eigen::Vector3d &up = Eigen::Vector3d(0, 0, 1),
110 const double epsilon = 0.1)
111 -> std::tuple<std::vector<size_t>, std::vector<size_t>>;
112
127template <typename CloudPtr>
128auto compute_polygon_normal(const pcl::Vertices &poly,
129 const CloudPtr &cloud) -> Eigen::Vector3f {
130 if (poly.vertices.size() < 3) {
131 throw std::invalid_argument(
132 "Polygon must have at least 3 vertices to compute a normal");
133 }
134
135 Eigen::Vector3f normal = Eigen::Vector3f::Zero();
136 for (size_t i = 0; i < poly.vertices.size(); ++i) {
137 const auto idx_c = poly.vertices[i];
138 const auto idx_n = poly.vertices[(i + 1) % poly.vertices.size()];
139 const auto &v_c = cloud->points[idx_c].getVector3fMap();
140 const auto &v_n = cloud->points[idx_n].getVector3fMap();
141 normal += v_c.cross(v_n);
142 }
143
144 const float magnitude = normal.norm();
145 if (magnitude < 1e-10f) {
146 throw std::runtime_error(
147 "Cannot compute normal for degenerate polygon (zero magnitude)");
148 }
149
150 normal.normalize();
151 return normal;
152}
153
154} // namespace ReUseX::geometry
auto make_pairs(EigenVectorContainer< double, 4 > &planes, std::vector< IndicesPtr > &inliers, EigenVectorContainer< double, 3 > &centroids, 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.
Definition utils.hpp:128
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 &centroids_, 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
Definition types.hpp:38
typename Cloud::Ptr CloudPtr
Definition types.hpp:22
pcl::IndicesConstPtr IndicesConstPtr
Definition types.hpp:19
typename Cloud::ConstPtr CloudConstPtr
Definition types.hpp:23