12#include "../objects/Project.hpp"
13#include "../objects/Sensor.hpp"
21 const Project*
const initial_project
23 panel_name(
std::string(
"Sensor Geometry") + get_imgui_stable_name()),
24 active_project(initial_project),
31 return panel_name.c_str();
36 if (ImGui::Begin(panel_name.c_str())) {
37 if (active_project ==
nullptr)
38 ImGui::Text(
"No project is loaded.");
39 else if (active_project->get_sensors_count() == 0u)
40 ImGui::Text(
"No sensors are loaded.");
42 recache_sensor_colours();
43 draw_geometry_summary();
52 const Project*
const new_project
55 active_project = new_project;
56 sensor_colours.clear();
59const char* SensorGeometryPanel::get_imgui_stable_name() noexcept
61 return "###SensorGeometryPanel";
64void SensorGeometryPanel::recache_sensor_colours() noexcept
70 for (
auto [src, dst] : std::views::zip(active_project->
observe_sensors(), sensor_colours))
72 static_cast<int>(src.colour.r * 255.0f),
73 static_cast<int>(src.colour.g * 255.0f),
74 static_cast<int>(src.colour.b * 255.0f),
75 static_cast<int>(src.colour.a * 255.0f)
77 }
catch (
const std::exception& exception) {
78 LOG_F_ERROR(
"Could not store the sensor colouring: {}", exception.
what());
79 plotting_spec_3d.MarkerFillColors =
nullptr;
80 plotting_spec_3d.MarkerLineColors =
nullptr;
81 plotting_spec_3d.MarkerFillColor = ImVec4(255.0f, 255.0f, 255.0f, 255.0f);
82 plotting_spec_3d.MarkerLineColor = IMPLOT_AUTO_COL;
87 plotting_spec_3d.MarkerFillColors = &*sensor_colours.begin();
88 plotting_spec_3d.MarkerLineColors = plotting_spec_3d.MarkerFillColors;
92void SensorGeometryPanel::draw_geometry_summary() noexcept
94 ImGui::SeparatorText(
"Geometry Summary");
95 if (ImGui::BeginTable(
"##GeometrySummary", 5, table_flags)) {
96 ImGui::TableSetupColumn(
"##SensorColourColumn", ImGuiTableColumnFlags_WidthFixed);
97 ImGui::TableSetupColumn(
"Sensor", ImGuiTableColumnFlags_WidthFixed);
98 ImGui::TableSetupColumn(
"X Position", ImGuiTableColumnFlags_WidthStretch);
99 ImGui::TableSetupColumn(
"Y Position", ImGuiTableColumnFlags_WidthStretch);
100 ImGui::TableSetupColumn(
"Z Position", ImGuiTableColumnFlags_WidthStretch);
101 ImGui::TableHeadersRow();
103 std::size_t row_idx = 0;
105 for (
const auto& sensor : active_project->observe_sensors()) {
106 ImGui::PushID(
static_cast<int>(sensor.get_id()));
108 ImGui::TableNextRow();
109 ImGui::TableNextColumn();
111 const ImVec4 colour = ImGui::ColorConvertU32ToFloat4(sensor_colours[row_idx]);
112 std::array<float, 4> new_colour = {colour.x, colour.y, colour.z, colour.w};
113 if (ImGui::ColorEdit4(
"##colour", new_colour.
data(), ImGuiColorEditFlags_NoInputs)) {
114 app->notify(ModifySensorColourNotification(
115 active_project->get_id(),
125 sensor_colours[row_idx] = IM_COL32(
126 static_cast<int>(new_colour[0] * 255.0f),
127 static_cast<int>(new_colour[1] * 255.0f),
128 static_cast<int>(new_colour[2] * 255.0f),
129 static_cast<int>(new_colour[3] * 255.0f)
133 ImGui::TableNextColumn();
135 ImGui::TextUnformatted(sensor.get_imgui_name());
137 Position new_position = sensor.position;
138 bool position_changed =
false;
140 ImGui::TableNextColumn();
142 position_changed = ImGui::InputFloat(
"##x", &new_position.x, 0.01f, 1.0f);
144 ImGui::TableNextColumn();
146 position_changed = ImGui::InputFloat(
"##y", &new_position.y, 0.01f, 1.0f) || position_changed;
148 ImGui::TableNextColumn();
150 position_changed = ImGui::InputFloat(
"##z", &new_position.z, 0.01f, 1.0f) || position_changed;
155 if (position_changed)
156 app->notify(ModifySensorPositionNotification(active_project->get_id(), sensor.get_id(), new_position));
163void SensorGeometryPanel::draw_geometry_plot() const noexcept
165 ImGui::SeparatorText(
"Geometry Plot");
166 ImPlot3D::PushStyleColor(ImPlot3DCol_FrameBg, ImVec4(0.0f, 0.0f, 0.0f, 0.0f));
168 const auto avail_size = ImGui::GetContentRegionAvail();
169 const float aspect_ratio = avail_size.x / avail_size.y;
172 ImPlot3D::SetupBoxScale(aspect_ratio, 1.0f, 1.0f);
173 ImPlot3D::SetupAxes(
"X",
"Y",
"Z");
174 ImPlot3D::PlotScatterG(
176 Project::get_sensor_point,
178 static_cast<int>(active_project->get_sensors_count()),
185 ImPlot3D::PopStyleColor();
AllNotifications specification.
EchoMap class specification.
EchoMap portable logger specification.
#define LOG_F_ERROR(msg,...)
Logs a formatted error-level message using echomap::Logger::log_f.
EchoMap sensor geometry panel specification.
The EchoMap maintains state for the application including WebGPU and Dear ImGui context,...
auto observe_sensors() const noexcept
Provides a transformed view for stored Sensor objects in the Project.
size_t get_sensors_count() const noexcept
Checks if any Sensor objects are owned by the Project.
SensorGeometryPanel(EchoMap *app, const Project *initial_project=nullptr)
Create a new SensorGeometryPanel to plot and control Sensor information.
const char * get_imgui_name() const noexcept override
Retrieves the name of the IPanel for Dear ImGui API functions.
void change_active_project(const Project *new_project) override
Updates the active Project being described by the IPanel.
void draw() noexcept override
Draw the panel to the active rendering context.
The main EchoMap outermost namespace for all non-exported symbols.