ReUseX  0.0.1
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 friend void put(const plane_map &, key_type &p, const value_type &val) {
41 p(0) = static_cast<Scalar>(CGAL::to_double(val.a()));
42 p(1) = static_cast<Scalar>(CGAL::to_double(val.b()));
43 p(2) = static_cast<Scalar>(CGAL::to_double(val.c()));
44 p(3) = static_cast<Scalar>(CGAL::to_double(val.d()));
45 };
46};
47
48template <typename Kernel, typename PointT> struct point_map {
49
51 using value_type = typename Kernel::Point_3;
53 using category = boost::readable_property_map_tag;
54 value_type operator[](const key_type &pt) const {
55 return value_type(pt.x, pt.y, pt.z);
56 }
57
58 friend value_type get(const point_map &, const key_type &pt) {
59 return value_type(pt.x, pt.y, pt.z);
60 };
61
62 friend void put(const point_map &, key_type &pt, const value_type &val) {
63 pt.x = static_cast<typename PointT::ScalarType>(CGAL::to_double(val.x()));
64 pt.y = static_cast<typename PointT::ScalarType>(CGAL::to_double(val.y()));
65 pt.z = static_cast<typename PointT::ScalarType>(CGAL::to_double(val.z()));
66 };
67};
68
69namespace ReUseX::geometry {
70template <typename Scalar> using Plane = Eigen::Matrix<Scalar, 4, 1>;
71
72template <typename Scalar>
74 std::vector<Plane<Scalar>, Eigen::aligned_allocator<Plane<Scalar>>>;
75
76template <typename Scalar, typename PointT>
78 typename pcl::PointCloud<PointT>::ConstPtr points,
79 std::vector<pcl::IndicesPtr> &inliers,
80 double angle_threshold = 25.0,
81 double distance_threshold = 0.01) {
83 "Regularizing planes with threshold: {} degrees and {} distance",
84 angle_threshold, distance_threshold);
85
86 using Kernel = CGAL::Exact_predicates_inexact_constructions_kernel;
87 using FT = typename Kernel::FT;
88
89 std::vector<int> point_plane_index(points->size(), -1);
90 for (size_t i = 0; i < inliers.size(); ++i) {
91 for (const auto &idx : *(inliers[i])) {
92 point_plane_index[idx] = static_cast<int>(i);
93 }
94 }
95
96 CGAL::Shape_regularization::Planes::regularize_planes(
98 CGAL::Random_access_property_map(
99 point_plane_index), /* point index to plane index */
100 /*regularize_parallelism=*/true,
101 /*regularize_orthogonality=*/true,
102 /*regularize_coplanarity=*/true,
103 /*regularize_axis_symmetry=*/true,
104 /*tolerance_angle=*/FT(angle_threshold),
105 /*tolerance_coplanarity=*/FT(distance_threshold));
106
107 // CGAL::Shape_regularization::Planes::regularize_planes(
108 // planes, *points,
109 // CGAL::parameters::plane_map(plane_map<Kernel, Scalar>())
110 // .point_map(point_map<Kernel, PointT>())
111 // .plane_index_map(plane_index_map(inliers, points->size()))
112 // // CGAL::Random_access_property_map(point_plane_index))
113 // //.regularize_coplanarity(true)
114 // //.maximum_offset(FT(0.01))
115 // //.regularize_parallelism(true)
116 // //.regularize_orthogonality(true)
117 // //.regularize_axis_symmetry(true)
118 // //.symmetry_direction(Kernel::Vector_3(0, 0, 1))
119 // .maximum_angle(FT(threshold)));
120
121 return planes;
122}
123} // namespace ReUseX::geometry
ReUseX::PointT PointT
std::vector< Plane< Scalar >, Eigen::aligned_allocator< Plane< Scalar > > > PlaneVector
Eigen::Matrix< Scalar, 4, 1 > Plane
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)
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