RoomEditor.h
Go to the documentation of this file.
1/**
2 * This file is part of ArmarX.
3 *
4 * ArmarX is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * ArmarX is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * @package navigation::ArmarXObjects::room_editor
17 * @author Fabian Reister ( fabian dot reister at kit dot edu )
18 * @date 2026
19 * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
20 * GNU General Public License
21 */
22
23#pragma once
24
25#include <cstddef>
26#include <functional>
27#include <map>
28#include <optional>
29#include <string>
30#include <vector>
31
32#include <Eigen/Core>
33
37
39
41{
42
43 /// A room together with the provider segment (i.e. the navigation graph) it belongs to.
49
50 /**
51 * @brief Interactive ArViz front-end for the room polygons stored in the navigation memory.
52 *
53 * Each polygon vertex is visualized as a draggable handle which is restricted to the
54 * XY plane. Additionally, a handle is placed on the midpoint of every edge. Dragging
55 * such an edge handle (or using its context menu) cuts the edge, i.e. inserts a new
56 * vertex in between the two adjacent ones.
57 *
58 * The editor is purely concerned with visualization and interaction. Whenever a room
59 * has been modified, the callback registered via `setRoomChangedCallback()` is invoked,
60 * which is where the change is persisted (e.g. written back to the memory).
61 */
63 {
64 public:
66 {
67 /// Prefix of the ArViz layers created by the editor.
68 std::string layerPrefix = "RoomEditor";
69
70 /// Radius of the (spherical) vertex handles [mm].
71 float vertexHandleRadius = 75.F;
72
73 /// Edge length of the (cubic) edge handles [mm].
74 float edgeHandleSize = 90.F;
75
76 /// Width of the polygon outline [mm].
77 float lineWidth = 10.F;
78
79 /// Handles are drawn slightly above the polygon to avoid z-fighting [mm].
80 float handleZOffset = 20.F;
81
82 /// Radius of the (cylindrical) whole-room move handle [mm].
83 float moveHandleRadius = 120.F;
84
85 /// Height of the (cylindrical) whole-room move handle [mm].
86 float moveHandleHeight = 40.F;
87
88 /// Scale of the room name labels.
89 float labelScale = 4.F;
90 };
91
92 /// Called whenever a room was modified by the user.
93 using RoomChangedCallback = std::function<void(const EditableRoom&)>;
94
95 RoomEditor(viz::Client arviz, const Parameters& parameters);
96
97 /**
98 * @brief Replaces the edited rooms, e.g. after (re-)reading them from the memory.
99 *
100 * Any interaction that is currently in progress is discarded.
101 */
102 void setRooms(const std::vector<EditableRoom>& rooms);
103
104 const std::vector<EditableRoom>& rooms() const;
105
107
108 /// True while the user is dragging a handle. Reloading should be paused meanwhile.
109 bool isInteracting() const;
110
111 /**
112 * @brief Processes the interaction feedback of the previous commit and stages
113 * everything that has to be (re-)drawn.
114 *
115 * Must be called once per cycle, right after `stage` has been reset.
116 */
117 void update(const viz::CommitResult& result, viz::StagedCommit& stage);
118
119 /// Stages a full redraw of all layers (rooms and handles).
120 void redrawAll(viz::StagedCommit& stage);
121
122 private:
123 struct Handle
124 {
125 enum class Type
126 {
127 /// The handle represents the polygon vertex at `pointIndex`.
128 Vertex,
129 /// The handle sits on the edge from `pointIndex` to `pointIndex + 1`.
130 Edge,
131 /// The handle moves/rotates the whole room. `pointIndex` is unused.
132 Move
133 };
134
135 Type type = Type::Vertex;
136 std::size_t roomIndex = 0;
137 std::size_t pointIndex = 0;
138 };
139
140 /// The transformation the user is currently applying to a handle.
141 struct PendingTransform
142 {
143 std::string element;
144 Handle handle;
145
146 /// For Vertex/Edge handles: the absolute new position of the (inserted) vertex.
147 Eigen::Vector2f position = Eigen::Vector2f::Zero();
148
149 /// For Move handles: the delta rotation about Z [rad] applied to the whole room.
150 float rotation = 0.F;
151
152 /// For Move handles: the delta translation in world XY [mm] applied to the whole room.
153 Eigen::Vector2f translation = Eigen::Vector2f::Zero();
154 };
155
156 enum class ContextMenuEntry
157 {
158 InsertPointAfter = 0,
159 InsertPointBefore = 1,
160 DeletePoint = 2
161 };
162
163 void handleInteraction(const viz::InteractionFeedback& interaction,
164 viz::StagedCommit& stage);
165
166 void handleContextMenu(const Handle& handle, int entry, viz::StagedCommit& stage);
167
168 /// Applies the pending transformation to the room polygon and notifies the callback.
169 void applyPendingTransform(viz::StagedCommit& stage);
170
171 /// Stages a redraw of the room polygons only (used for the live drag preview).
172 void redrawRooms(viz::StagedCommit& stage);
173
174 /// The polygon of the given room, with a pending drag preview applied.
175 std::vector<Eigen::Vector2f> previewPolygon(std::size_t roomIndex) const;
176
177 /// The (untransformed) position a handle is drawn at.
178 Eigen::Vector2f handlePosition(const Handle& handle) const;
179
180 std::string elementName(const Handle& handle) const;
181
182 void notifyRoomChanged(std::size_t roomIndex) const;
183
184 viz::Client arviz;
185 Parameters parameters;
186
187 RoomChangedCallback roomChangedCallback;
188
189 std::vector<EditableRoom> rooms_;
190
191 viz::Layer roomLayer;
192 viz::Layer handleLayer;
193
194 /// Maps ArViz element names to the handle they represent.
195 std::map<std::string, Handle> handleByElement;
196
197 std::optional<PendingTransform> pendingTransform;
198 };
199
200} // namespace armarx::navigation::components::room_editor
bool isInteracting() const
True while the user is dragging a handle. Reloading should be paused meanwhile.
void update(const viz::CommitResult &result, viz::StagedCommit &stage)
Processes the interaction feedback of the previous commit and stages everything that has to be (re-)d...
const std::vector< EditableRoom > & rooms() const
void setRooms(const std::vector< EditableRoom > &rooms)
Replaces the edited rooms, e.g.
void setRoomChangedCallback(RoomChangedCallback callback)
std::function< void(const EditableRoom &)> RoomChangedCallback
Called whenever a room was modified by the user.
Definition RoomEditor.h:93
RoomEditor(viz::Client arviz, const Parameters &parameters)
void redrawAll(viz::StagedCommit &stage)
Stages a full redraw of all layers (rooms and handles).
A room together with the provider segment (i.e. the navigation graph) it belongs to.
Definition RoomEditor.h:45
float moveHandleRadius
Radius of the (cylindrical) whole-room move handle [mm].
Definition RoomEditor.h:83
float edgeHandleSize
Edge length of the (cubic) edge handles [mm].
Definition RoomEditor.h:74
float moveHandleHeight
Height of the (cylindrical) whole-room move handle [mm].
Definition RoomEditor.h:86
float vertexHandleRadius
Radius of the (spherical) vertex handles [mm].
Definition RoomEditor.h:71
std::string layerPrefix
Prefix of the ArViz layers created by the editor.
Definition RoomEditor.h:68
float handleZOffset
Handles are drawn slightly above the polygon to avoid z-fighting [mm].
Definition RoomEditor.h:80
A staged commit prepares multiple layers to be committed.
Definition Client.h:30