ReUseX  0.0.5
3D Point Cloud Processing for Building Reuse
Loading...
Searching...
No Matches
regularization.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/core/logging.hpp"
7
8#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
9#include <CGAL/Shape_regularization/regularize_planes.h>
10#include <CGAL/property_map.h>
11#include <Eigen/Dense>
12#include <pcl/common/common.h>
13#include <pcl/point_cloud.h>
14#include <pcl/point_types.h>
15#include <range/v3/to_container.hpp>
16#include <range/v3/view/transform.hpp>
17
18#include <vector>
19
20template <typename Kernel, typename Scalar> struct plane_map {
21
22 using key_type =
23 Eigen::Matrix<Scalar, 4, 1>; // The iterator's value type is an index
24 using value_type = typename Kernel::Plane_3; // The object manipulated by the
25 // algorithm is a Plane
26 using reference = value_type; // The object does not exist in memory, so
27 // there's no reference
28 using category =
29 boost::readable_property_map_tag; // The property map is used both
30
31 using FT = typename Kernel::FT;
32
33 value_type operator[](const key_type &p) const {
34 return value_type(FT(p(0)), FT(p(1)), FT(p(2)), FT(p(3)));
35 }
36 friend value_type get(const plane_map &, const key_type &p) {
37 return value_type(FT(p(0)), FT(p(1)), FT(p(2)), FT(p(3)));
38 };
39
40 // cppcheck-suppress constParameterReference
41 friend void put(const plane_map &, key_type &p, const value_type &val) {
42 p(0) = static_cast<Scalar>(CGAL::to_double(val.a()));
43 p(1) = static_cast<Scalar>(CGAL::to_double(val.b()));
44 p(2) = static_cast<Scalar>(CGAL::to_double(val.c()));
45 p(3) = static_cast<Scalar>(CGAL::to_double(val.d()));
46 };
47};
48
49template <typename Kernel, typename PointT> struct point_map {
50
52 using value_type = typename Kernel::Point_3;
54 using category = boost::readable_property_map_tag;
55 value_type operator[](const key_type &pt) const {
56 return value_type(pt.x, pt.y, pt.z);
57 }
58
59 friend value_type get(const point_map &, const key_type &pt) {
60 return value_type(pt.x, pt.y, pt.z);
61 };
62
63 friend void put(const point_map &, key_type &pt, const value_type &val) {
64 pt.x = static_cast<typename PointT::ScalarType>(CGAL::to_double(val.x()));
65 pt.y = static_cast<typename PointT::ScalarType>(CGAL::to_double(val.y()));
66 pt.z = static_cast<typename PointT::ScalarType>(CGAL::to_double(val.z()));
67 };
68};
69
70namespace reusex::geometry {
71template <typename Scalar> using Plane = Eigen::Matrix<Scalar, 4, 1>;
72
73template <typename Scalar>
75 std::vector<Plane<Scalar>, Eigen::aligned_allocator<Plane<Scalar>>>;
76
77template <typename Scalar, typename PointT>
79 typename pcl::PointCloud<PointT>::ConstPtr points,
80 std::vector<pcl::IndicesPtr> &inliers,
81 double angle_threshold = 25.0,
82 double distance_threshold = 0.01) {
84 "Regularizing planes with threshold: {} degrees and {} distance",
85 angle_threshold, distance_threshold);
86
87 using Kernel = CGAL::Exact_predicates_inexact_constructions_kernel;
88 using FT = typename Kernel::FT;
89
90 std::vector<int> point_plane_index(points->size(), -1);
91 for (size_t i = 0; i < inliers.size(); ++i) {
92 for (const auto &idx : *(inliers[i])) {
93 point_plane_index[idx] = static_cast<int>(i);
94 }
95 }
96
97 CGAL::Shape_regularization::Planes::regularize_planes(
99 CGAL::Random_access_property_map(
100 point_plane_index), /* point index to plane index */
101 /*regularize_parallelism=*/true,
102 /*regularize_orthogonality=*/true,
103 /*regularize_coplanarity=*/true,
104 /*regularize_axis_symmetry=*/true,
105 /*tolerance_angle=*/FT(angle_threshold),
106 /*tolerance_coplanarity=*/FT(distance_threshold));
107
108 // CGAL::Shape_regularization::Planes::regularize_planes(
109 // planes, *points,
110 // CGAL::parameters::plane_map(plane_map<Kernel, Scalar>())
111 // .point_map(point_map<Kernel, PointT>())
112 // .plane_index_map(plane_index_map(inliers, points->size()))
113 // // CGAL::Random_access_property_map(point_plane_index))
114 // //.regularize_coplanarity(true)
115 // //.maximum_offset(FT(0.01))
116 // //.regularize_parallelism(true)
117 // //.regularize_orthogonality(true)
118 // //.regularize_axis_symmetry(true)
119 // //.symmetry_direction(Kernel::Vector_3(0, 0, 1))
120 // .maximum_angle(FT(threshold)));
121
122 return planes;
123}
124} // namespace reusex::geometry
reusex::PointT PointT
auto regularizePlanes(PlaneVector< Scalar > &planes, typename pcl::PointCloud< PointT >::ConstPtr points, std::vector< pcl::IndicesPtr > &inliers, double angle_threshold=25.0, double distance_threshold=0.01)
std::vector< Plane< Scalar >, Eigen::aligned_allocator< Plane< Scalar > > > PlaneVector
Eigen::Matrix< Scalar, 4, 1 > Plane
void trace(fmt::format_string< Args... > format, Args &&...args)
Definition logging.hpp:72
Eigen::Matrix< Scalar, 4, 1 > key_type
typename Kernel::Plane_3 value_type
value_type reference
friend value_type get(const plane_map &, const key_type &p)
friend void put(const plane_map &, key_type &p, const value_type &val)
typename Kernel::FT FT
value_type operator[](const key_type &p) const
boost::readable_property_map_tag category
friend void put(const point_map &, key_type &pt, const value_type &val)
boost::readable_property_map_tag category
friend value_type get(const point_map &, const key_type &pt)
typename Kernel::Point_3 value_type
value_type reference
value_type operator[](const key_type &pt) const