ReUseX  0.0.5
3D Point Cloud Processing for Building Reuse
Loading...
Searching...
No Matches
visual_observer.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// PCL/Eigen-typed visualization observer payloads. This header carries the
8// heavy point-cloud/geometry types that the visualization side needs, and is
9// deliberately kept OUT of the core interface (core/processing_observer.hpp):
10// core headers stay PCL-free (STANDARDS ยง1) and only see IVisualObserver as an
11// opaque forward-declared pointer through the observer registry. Only
12// geometry/vision/visualize consumers that actually emit visualization events
13// include this header.
14
15#include "reusex/core/logging.hpp"
16#include "reusex/core/processing_observer.hpp"
17#include "reusex/core/stages.hpp"
18#include "reusex/types.hpp"
19
20#include <pcl/Vertices.h>
21#include <pcl/correspondence.h>
22
23#include <Eigen/Geometry>
24#include <fmt/format.h>
25#include <memory>
26#include <string_view>
27#include <type_traits>
28#include <typeinfo>
29#include <utility>
30#include <vector>
31
32// Forward declaration to avoid circular dependency
34class CellComplex;
35} // namespace reusex::geometry
36
37namespace reusex::core {
38
40
41 public:
42 virtual ~IVisualObserver() = default;
43 using Pair = std::pair<Eigen::Vector4d, Eigen::Vector3d>;
44 using PlanePair = std::pair<Pair, Pair>;
45
46 // Viewer callbacks
47 template <typename T>
48 void viewer_add_geometry(std::string_view name,
49 [[maybe_unused]] const T &geometry, Stage stage,
50 int idx = 0) {
51 // Special case: if T is Eigen::Vector4d, use virtual dispatch
52 if constexpr (std::is_same_v<T, Eigen::Vector4d>) {
53 viewer_add_plane(name, geometry, stage, idx);
54 } else if constexpr (std::is_same_v<
55 T, std::pair<Eigen::Vector4d, Eigen::Vector3d>>) {
56 viewer_add_plane(name, geometry, stage, idx);
57 } else if constexpr (std::is_same_v<T, PlanePair>) {
58 viewer_add_plane_pair(name, geometry, stage, idx);
59 } else if constexpr (std::is_same_v<
60 T, std::shared_ptr<geometry::CellComplex>>) {
61 viewer_add_cell_complex(name, geometry, stage, idx);
62 } else if constexpr (std::is_same_v<T, CloudConstPtr>) {
63 viewer_add_cloud(name, geometry, stage, idx);
64 } else {
65 // Default implementation: log that geometry type is not handled
66 // This prevents linker errors while providing runtime visibility
67 core::debug("viewer_add_geometry<{}> called for '{}' at stage '{}' "
68 "(no handler registered)",
69 typeid(T).name(), name, to_string(stage));
70 }
71 }
72
73 template <typename T>
74 void viewer_add_geometries(std::string_view name, const T &geometries,
75 Stage stage) {
76 for (size_t i = 0; i < geometries.size(); ++i) {
77 viewer_add_geometry(fmt::format("{}_{}", name, i), geometries[i], stage,
78 i);
79 }
80 }
81
82 // Virtual method for specific geometry types (can be overridden)
83 virtual void viewer_add_plane(std::string_view name,
84 [[maybe_unused]] const Eigen::Vector4d &plane,
85 Stage stage, int /*idx*/ = 0) {
86 // Default: log that geometry type is not handled
87 core::debug("viewer_add_plane called for '{}' at stage '{}' "
88 "(no handler registered)",
89 name, to_string(stage));
90 }
91
92 virtual void viewer_add_plane(
93 std::string_view name,
94 [[maybe_unused]] const std::pair<Eigen::Vector4d, Eigen::Vector3d> &plane,
95 Stage stage, int /*idx*/ = 0) {
96 // Default: log that geometry type is not handled
97 core::debug("viewer_add_plane (with origin) called for '{}' at stage '{}' "
98 "(no handler registered)",
99 name, to_string(stage));
100 }
101
102 virtual void viewer_add_plane_pair(std::string_view name,
103 [[maybe_unused]] const PlanePair &pair,
104 Stage stage, int /*idx*/ = 0) {
105 // Default: log that geometry type is not handled
106 core::debug("viewer_add_plane_pair called for '{}' at stage '{}' "
107 "(no handler registered)",
108 name, to_string(stage));
109 }
110
112 std::string_view name,
113 [[maybe_unused]] const std::shared_ptr<reusex::geometry::CellComplex> &cc,
114 Stage stage, int /*idx*/ = 0) {
115 // Default: log that geometry type is not handled
116 core::debug("viewer_add_cell_complex called for '{}' at stage '{}' "
117 "(no handler registered)",
118 name, to_string(stage));
119 }
120
121 virtual void viewer_add_cloud(std::string_view name,
122 [[maybe_unused]] const CloudConstPtr &cloud,
123 Stage stage, int /*idx*/ = 0) {
124 // Default: log that geometry type is not handled
125 core::debug("viewer_add_cloud called for '{}' at stage '{}' "
126 "(no handler registered)",
127 name, to_string(stage));
128 }
129
131 std::string_view name, [[maybe_unused]] double focal_x,
132 [[maybe_unused]] double focal_y, [[maybe_unused]] int image_width,
133 [[maybe_unused]] int image_height,
134 [[maybe_unused]] const Eigen::Affine3f &pose, Stage stage,
135 int /*idx*/ = 0) {
136 core::debug("viewer_add_camera_frustum called for '{}' at stage '{}' "
137 "(no handler registered)",
138 name, to_string(stage));
139 }
140
142 std::string_view name, [[maybe_unused]] const CloudLocPtr &disc_points,
143 [[maybe_unused]] const std::shared_ptr<std::vector<pcl::Vertices>>
144 &disc_outlines,
145 [[maybe_unused]] const pcl::CorrespondencesPtr &edges, Stage stage,
146 int /*idx*/ = 0) {
147 core::debug("viewer_add_visibility_graph called for '{}' at stage '{}' "
148 "(no handler registered)",
149 name, to_string(stage));
150 }
151
152 virtual void
153 viewer_add_labeled_cloud(std::string_view name,
154 [[maybe_unused]] const CloudConstPtr &cloud,
155 [[maybe_unused]] const CloudLConstPtr &labels,
156 Stage stage, int /*idx*/ = 0) {
157 core::debug("viewer_add_labeled_cloud called for '{}' at stage '{}' "
158 "(no handler registered)",
159 name, to_string(stage));
160 }
161};
162
163} // namespace reusex::core
virtual void viewer_add_plane(std::string_view name, const std::pair< Eigen::Vector4d, Eigen::Vector3d > &plane, Stage stage, int=0)
virtual ~IVisualObserver()=default
virtual void viewer_add_cloud(std::string_view name, const CloudConstPtr &cloud, Stage stage, int=0)
std::pair< Eigen::Vector4d, Eigen::Vector3d > Pair
virtual void viewer_add_plane_pair(std::string_view name, const PlanePair &pair, Stage stage, int=0)
virtual void viewer_add_camera_frustum(std::string_view name, double focal_x, double focal_y, int image_width, int image_height, const Eigen::Affine3f &pose, Stage stage, int=0)
virtual void viewer_add_cell_complex(std::string_view name, const std::shared_ptr< reusex::geometry::CellComplex > &cc, Stage stage, int=0)
virtual void viewer_add_visibility_graph(std::string_view name, const CloudLocPtr &disc_points, const std::shared_ptr< std::vector< pcl::Vertices > > &disc_outlines, const pcl::CorrespondencesPtr &edges, Stage stage, int=0)
std::pair< Pair, Pair > PlanePair
virtual void viewer_add_labeled_cloud(std::string_view name, const CloudConstPtr &cloud, const CloudLConstPtr &labels, Stage stage, int=0)
void viewer_add_geometry(std::string_view name, const T &geometry, Stage stage, int idx=0)
virtual void viewer_add_plane(std::string_view name, const Eigen::Vector4d &plane, Stage stage, int=0)
void viewer_add_geometries(std::string_view name, const T &geometries, Stage stage)
auto to_string(Material value) -> std::string_view
Convert Material enum to its string identifier.
typename CloudL::ConstPtr CloudLConstPtr
typename Cloud::ConstPtr CloudConstPtr
typename CloudLoc::Ptr CloudLocPtr