ReUseX  0.0.5
3D Point Cloud Processing for Building Reuse
Loading...
Searching...
No Matches
segment_rooms.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#include "reusex/core/processing_observer.hpp"
8#include "reusex/types/point_types.hpp"
9#include "reusex/utils/fmt_formatter.hpp"
10
11#include <pcl/community_clustering.hpp>
12
13#include <fmt/format.h>
14
15#include <pcl/common/pca.h>
16#include <pcl/correspondence.h>
17#include <pcl/filters/filter.h>
18#include <pcl/filters/uniform_sampling.h>
19#include <pcl/io/auto_io.h>
20#include <pcl/io/pcd_io.h>
21#include <pcl/point_types.h>
22#include <pcl/search/kdtree.h>
23
24#include <atomic>
25
26namespace reusex::geometry {
28 IndicesConstPtr filter = nullptr; // Optional filter to limit processing
29
30 float grid_size = 0.5F;
31 float resolution = 1.0F;
32 float beta = 0.01F;
33 // Finite Leiden iteration bound. STANDARDS ยง5 forbids unbounded loops in
34 // long-running stages; the previous -1 ("until convergence") could spin
35 // indefinitely on pathological graphs. 100 iterations is well past the
36 // point where Leiden modularity plateaus for room-scale graphs.
37 int max_iter = 100;
38
39 // --- Label propagation to non-sampled points (distance-bounded k-NN) ---
40 // Room clustering runs on a uniformly sampled subset; the remaining points
41 // inherit a room label from their sampled neighbours. A distance-bounded
42 // k-NN majority vote replaces the old unchecked 1-NN so that a single
43 // misclassified seed cannot smear across a whole region, and points with no
44 // labelled neighbour inside the radius stay kUnlabeled (0) instead of
45 // silently copying a far-away label.
46 int propagate_k = 5;
47 float propagate_max_radius = 0.5F;
49
50 // Optional cancellation flag. Caller retains ownership and must keep this
51 // alive for the full duration of the segment_rooms(...) call.
52 const std::atomic_bool *cancel_token = nullptr;
53};
54
74 IndicesConstPtr sampled_indices,
75 IndicesConstPtr missing_indices, int k,
76 float max_radius) -> size_t;
77
79 CloudLConstPtr planes,
80 const SegmentRoomsOptions &options) -> CloudLPtr;
82 CloudLConstPtr planes,
84 -> CloudLPtr;
85
86} // namespace reusex::geometry
auto propagate_room_labels(CloudConstPtr cloud, CloudLPtr labels, IndicesConstPtr sampled_indices, IndicesConstPtr missing_indices, int k, float max_radius) -> size_t
Propagate room labels from a labelled subset to a set of missing points using a distance-bounded k-NN...
auto segment_rooms_impl(CloudConstPtr cloud, CloudNConstPtr normals, CloudLConstPtr planes, const SegmentRoomsOptions &options) -> CloudLPtr
auto segment_rooms(CloudConstPtr cloud, CloudNConstPtr normals, CloudLConstPtr planes, const SegmentRoomsOptions &options=SegmentRoomsOptions{}) -> CloudLPtr
pcl::IndicesConstPtr IndicesConstPtr
typename CloudL::Ptr CloudLPtr
typename CloudL::ConstPtr CloudLConstPtr
typename Cloud::ConstPtr CloudConstPtr
typename CloudN::ConstPtr CloudNConstPtr
float propagate_max_radius
Max search radius (meters); no label beyond this stays unlabeled.
const std::atomic_bool * cancel_token
int propagate_k
Neighbours polled per missing point.