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