ReUseX  0.0.5
3D Point Cloud Processing for Building Reuse
Loading...
Searching...
No Matches
label_renderer.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
7#include "processing_observer.hpp"
9
10#include <fmt/format.h>
11#include <spdlog/spdlog.h>
12
13#include <memory>
14#include <string>
15#include <vector>
16
17namespace rux::view {
18
19// ============================================================================
20// TRAITS FOR TEMPLATE-BASED CALLBACK REGISTRATION
21// ============================================================================
22
25template <typename T> struct ItemTraits;
26
28template <> struct ItemTraits<LoadedCloud> {
29 static constexpr const char *type_name = "Cloud";
30 static constexpr const char *key_prefix = "c";
31
33 const LoadedCloud &item, int viewport) {
34 viewer->addPointCloud<PointT>(item.cloud, item.name, viewport);
35 }
36
37 static void
39 const std::string &name) {
40 viewer->removePointCloud(name);
41 }
42};
43
45template <> struct ItemTraits<LoadedMesh> {
46 static constexpr const char *type_name = "Mesh";
47 static constexpr const char *key_prefix = "m";
48
50 const LoadedMesh &item, int viewport) {
51 if (item.is_textured()) {
52 viewer->removePolygonMesh(item.name);
53 auto textured = std::get<pcl::TextureMesh::Ptr>(item.mesh);
54 viewer->addTextureMesh(*textured, item.name, viewport);
55 } else {
56 auto regular = std::get<pcl::PolygonMesh::Ptr>(item.mesh);
57 viewer->addPolygonMesh(*regular, item.name, viewport);
58 }
59 }
60
61 static void
63 const std::string &name) {
64 viewer->removePolygonMesh(name);
65 }
66};
67
68// ============================================================================
69// KEYBOARD CALLBACK REGISTRATION (TEMPLATE-BASED)
70// ============================================================================
71
77template <typename LoadedItem>
78void register_individual_toggles(std::vector<LoadedItem> &items,
80 using Traits = ItemTraits<LoadedItem>;
81
82 if (items.empty())
83 return;
84
85 observer.viewer_enqueue_task(
86 [&items, &observer](const rux::VizualizationObserver::ViewerPtr &viewer,
87 const std::vector<int> &) {
88 viewer->registerKeyboardCallback(
89 [&items,
90 &observer](const pcl::visualization::KeyboardEvent &event) {
91 for (size_t i = 0; i < items.size() && i < 10; ++i) {
92 if (event.getKeySym() ==
93 fmt::format("{}_{}", Traits::key_prefix, i) &&
94 event.keyDown()) {
95 items[i].visible = !items[i].visible;
96 if (items[i].visible) {
97 observer.viewer_enqueue_task(
98 [i, &items](
100 const std::vector<int> &viewports) {
101 Traits::add_to_viewer(viewer, items[i], viewports[0]);
102 });
103 spdlog::info("{} {} shown", Traits::type_name, i);
104 } else {
105 observer.viewer_enqueue_task(
106 [i, &items](
108 const std::vector<int> &) {
109 Traits::remove_from_viewer(viewer, items[i].name);
110 });
111 spdlog::info("{} {} hidden", Traits::type_name, i);
112 }
113 }
114 }
115 });
116 });
117}
118
124template <typename LoadedItem>
125void register_toggle_all_callback(std::vector<LoadedItem> &items,
126 rux::VizualizationObserver &observer) {
127 using Traits = ItemTraits<LoadedItem>;
128
129 if (items.empty())
130 return;
131
132 observer.viewer_enqueue_task(
133 [&items, &observer](const rux::VizualizationObserver::ViewerPtr &viewer,
134 const std::vector<int> &) {
135 viewer->registerKeyboardCallback(
136 [&items,
137 &observer](const pcl::visualization::KeyboardEvent &event) {
138 if (event.getKeySym() == Traits::key_prefix && event.keyDown()) {
139 // Check if all are currently visible
140 bool all_visible = true;
141 for (const auto &item : items) {
142 if (!item.visible) {
143 all_visible = false;
144 break;
145 }
146 }
147
148 // Toggle all items
149 for (size_t i = 0; i < items.size(); ++i) {
150 if (all_visible) {
151 observer.viewer_enqueue_task(
152 [i, &items](
154 const std::vector<int> &) {
155 Traits::remove_from_viewer(viewer, items[i].name);
156 items[i].visible = false;
157 });
158 } else {
159 observer.viewer_enqueue_task(
160 [i, &items](
162 const std::vector<int> &viewports) {
163 Traits::add_to_viewer(viewer, items[i], viewports[0]);
164 items[i].visible = true;
165 });
166 }
167 }
168 spdlog::info("All {}s {}", Traits::type_name,
169 all_visible ? "hidden" : "shown");
170 }
171 });
172 });
173}
174
175// ============================================================================
176// LABEL OVERLAY / LEGEND
177// ============================================================================
178
180void remove_label_legend(std::shared_ptr<ViewerState> state,
182
185 std::shared_ptr<ViewerState> state,
187
189void register_legend_toggle(const std::vector<LabelCloudInfo> &label_clouds,
190 std::shared_ptr<ViewerState> state,
192
198void register_label_toggles(const std::vector<LabelCloudInfo> &label_clouds,
199 std::shared_ptr<ViewerState> state,
201
202} // namespace rux::view
void viewer_enqueue_task(VizTask task)
std::shared_ptr< pcl::visualization::PCLVisualizer > ViewerPtr
reusex::PointT PointT
void remove_label_legend(std::shared_ptr< ViewerState > state, rux::VizualizationObserver &observer)
Remove the label legend overlay from the viewer.
void add_label_legend(const LabelCloudInfo &info, std::shared_ptr< ViewerState > state, rux::VizualizationObserver &observer)
Add a label legend overlay to the viewer for the given label cloud info.
void register_legend_toggle(const std::vector< LabelCloudInfo > &label_clouds, std::shared_ptr< ViewerState > state, rux::VizualizationObserver &observer)
Register keyboard callback for toggling label legend (key 'l').
void register_toggle_all_callback(std::vector< LoadedItem > &items, rux::VizualizationObserver &observer)
Register keyboard callback for toggling all items at once (key 'c' or 'm').
void register_individual_toggles(std::vector< LoadedItem > &items, rux::VizualizationObserver &observer)
Register keyboard callbacks for toggling individual items (e.g., c_0, m_0).
void register_label_toggles(const std::vector< LabelCloudInfo > &label_clouds, std::shared_ptr< ViewerState > state, rux::VizualizationObserver &observer)
Register keyboard callbacks for toggling label overlays (keys '1'-'9').
static constexpr const char * key_prefix
static void remove_from_viewer(const rux::VizualizationObserver::ViewerPtr &viewer, const std::string &name)
static constexpr const char * type_name
static void add_to_viewer(const rux::VizualizationObserver::ViewerPtr &viewer, const LoadedCloud &item, int viewport)
static constexpr const char * key_prefix
static constexpr const char * type_name
static void remove_from_viewer(const rux::VizualizationObserver::ViewerPtr &viewer, const std::string &name)
static void add_to_viewer(const rux::VizualizationObserver::ViewerPtr &viewer, const LoadedMesh &item, int viewport)
Traits class template for viewer item operations.
A label cloud with its associated metadata for legend display.
A point cloud loaded for visualization with associated metadata.
std::string name
Display name in viewer.
CloudPtr cloud
The point cloud data.
A polygon mesh loaded for visualization with associated metadata.
std::string name
Display name in viewer.
std::variant< pcl::PolygonMesh::Ptr, pcl::TextureMesh::Ptr > mesh
The mesh data (regular or textured).