Skip to content

Commit

Permalink
Allowing deletion of lift cabin vertices (#518)
Browse files Browse the repository at this point in the history
Signed-off-by: tanjunkiat <tanjunkiat@outlook.sg>
  • Loading branch information
TanJunKiat authored Dec 19, 2024
1 parent 53928fa commit 5ed7be2
Show file tree
Hide file tree
Showing 12 changed files with 299 additions and 7 deletions.
1 change: 1 addition & 0 deletions rmf_traffic_editor/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ set(gui_sources
gui/building_dialog.cpp
gui/constraint.cpp
gui/coordinate_system.cpp
gui/delete_dialog.cpp
gui/feature.cpp
gui/edge.cpp
gui/editor.cpp
Expand Down
8 changes: 8 additions & 0 deletions rmf_traffic_editor/gui/building.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -810,6 +810,14 @@ Lift Building::get_lift(const std::string& name) const
return Lift();
}

void Building::purge_lift_cabin_vertices(std::string lift_name)
{
for (auto& level : levels)
{
level.delete_lift_vertex(lift_name);
}
}

void Building::add_constraint(
const int level_idx,
const QUuid& a,
Expand Down
2 changes: 2 additions & 0 deletions rmf_traffic_editor/gui/building.h
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,8 @@ class Building

Lift get_lift(const std::string& name) const;

void purge_lift_cabin_vertices(std::string lift_name);

private:
std::string filename;
};
Expand Down
119 changes: 119 additions & 0 deletions rmf_traffic_editor/gui/delete_dialog.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
/*
* Copyright (C) 2024 Open Source Robotics Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

#include "delete_dialog.h"
#include <QtWidgets>

DeleteDialog::DeleteDialog(
QWidget* parent,
const Building& building,
int level_idx,
int selected_vertex_idx)
: QDialog(parent)
{

setWindowTitle("Warning");
QVBoxLayout* warning_message_vbox_layout = new QVBoxLayout;

// check if vertex is a lift cabin
std::vector<std::string> lift_levels;
const auto& level = building.levels[level_idx];
const auto& v = level.vertices[selected_vertex_idx];
auto it = v.params.find("lift_cabin");
if ((it != v.params.end()))
{
auto lift = building.get_lift(v.lift_cabin());

for (const auto& level_door : lift.level_doors)
{
lift_levels.push_back(level_door.first);
}

std::string s;
for (uint i = 0; i < lift_levels.size(); i++)
{
s = s + lift_levels[i];
if (i < lift_levels.size() - 1)
{
s = s + ", ";
}
}
warning_message_vbox_layout->addWidget(new QLabel(
QString("This item is a lift cabin and is used in %1.\n "
"Are you sure you want to delete this item?")
.arg(QString::fromStdString(s))));
}
else
{
std::string s;
std::map<std::string, int> edge_types;
for (const auto& edge : level.edges_with_vertex(selected_vertex_idx))
{
edge_types[edge.type_to_string()]++;
}
for (const auto& edge_type : edge_types)
{
s = s + " - " + std::to_string(edge_type.second) + " " + edge_type.first +
" edge(s) \n";
}

std::map<std::string, int> polygon_types;
for (const auto& polygon : level.polygons_with_vertex(selected_vertex_idx))
{
polygon_types[polygon.type_to_string()]++;
}
for (const auto& polygon_type : polygon_types)
{
s = s + " - " + std::to_string(polygon_type.second) + " " +
polygon_type.first + " polygon(s) \n";
}

warning_message_vbox_layout->addWidget(new QLabel(
QString("This item is linked to: \n%1"
"Are you sure you want to delete this item?")
.arg(QString::fromStdString(s))));

}

QHBoxLayout* bottom_buttons_layout = new QHBoxLayout;
_ok_button = new QPushButton("OK", this); // first button = [enter] button
bottom_buttons_layout->addWidget(_ok_button);
connect(
_ok_button, &QAbstractButton::clicked,
this, &DeleteDialog::ok_button_clicked);

_cancel_button = new QPushButton("Cancel", this);
bottom_buttons_layout->addWidget(_cancel_button);
connect(
_cancel_button, &QAbstractButton::clicked,
this, &QDialog::reject);

QVBoxLayout* vbox_layout = new QVBoxLayout;
vbox_layout->addLayout(warning_message_vbox_layout);
vbox_layout->addLayout(bottom_buttons_layout);

setLayout(vbox_layout);
}

DeleteDialog::~DeleteDialog()
{
}

void DeleteDialog::ok_button_clicked()
{
accept();
}
44 changes: 44 additions & 0 deletions rmf_traffic_editor/gui/delete_dialog.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* Copyright (C) 2024 Open Source Robotics Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

#ifndef DELETE_DIALOG_H
#define DELETE_DIALOG_H

#include <QDialog>
#include <map>
#include "building.h"

class DeleteDialog : public QDialog
{
Q_OBJECT

public:
DeleteDialog(
QWidget* parent,
const Building& building,
int level_idx,
int selected_vertex_idx);
~DeleteDialog();

private:
QPushButton* _ok_button, * _cancel_button;

private slots:
void ok_button_clicked();
};

#endif
5 changes: 5 additions & 0 deletions rmf_traffic_editor/gui/edge.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -202,3 +202,8 @@ double Edge::get_width() const
return -1.0;// shouldn't get here
return it->second.value_double;
}

bool Edge::contains(const int idx) const
{
return start_idx == idx || end_idx == idx;
}
1 change: 1 addition & 0 deletions rmf_traffic_editor/gui/edge.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ class Edge
int get_graph_idx() const;

double get_width() const;
bool contains(const int idx) const;
};

#endif
50 changes: 43 additions & 7 deletions rmf_traffic_editor/gui/editor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@

#include "add_param_dialog.h"
#include "building_dialog.h"
#include "delete_dialog.h"
#include "editor.h"
#include "layer_dialog.h"
#include "layer_table.h"
Expand Down Expand Up @@ -978,14 +979,49 @@ void Editor::keyPressEvent(QKeyEvent* e)
}
else
{
QMessageBox::critical(
this,
"Could not delete item",
"If deleting a vertex, it must not be in any edges or polygons "
"or lifts. "
"If deleting a feature, it must not be in any constraints.");
// Get the selected vertex index
int selected_vertex_idx = -1;
for (int i = 0;
i < static_cast<int>(building.levels[level_idx].vertices.size());
i++)
{
if (building.levels[level_idx].vertices[i].selected)
{
selected_vertex_idx = i;
break;
}
}

building.clear_selection(level_idx);
if (selected_vertex_idx != -1)
{
DeleteDialog dialog(this, building, level_idx, selected_vertex_idx);
if (dialog.exec() == QDialog::Accepted)
{
// Get the selected vertex
const auto v =
building.levels[level_idx].vertices[selected_vertex_idx];
auto it = v.params.find("lift_cabin");
if ((it != v.params.end()))
{
// Remove all vertices with a lift cabin property that matches the selected vertex
building.purge_lift_cabin_vertices(v.lift_cabin());
}

building.levels[level_idx].delete_used_entities(
selected_vertex_idx);
undo_stack.push(new DeleteCommand(&building, level_idx));
clear_current_tool_buffer();
update_property_editor();
create_scene();
}
else
{
building.clear_selection(level_idx);
clear_current_tool_buffer();
update_property_editor();
create_scene();
}
}
}
break;
case Qt::Key_S:
Expand Down
51 changes: 51 additions & 0 deletions rmf_traffic_editor/gui/level.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -498,6 +498,35 @@ bool Level::delete_selected()
return true;
}

bool Level::delete_used_entities(int selected_vertex_idx)
{
if (selected_vertex_idx >= 0)
{
edges.erase(
std::remove_if(
edges.begin(),
edges.end(),
[selected_vertex_idx](const Edge& edge)
{
return edge.contains(selected_vertex_idx);
}),
edges.end());

polygons.erase(
std::remove_if(
polygons.begin(),
polygons.end(),
[selected_vertex_idx](const Polygon& polygon)
{
return polygon.contains_vertex(selected_vertex_idx);
}),
polygons.end());

return true;
}
return false;
}

bool Level::delete_lift_vertex(std::string lift_name)
{
std::vector<int> selected_vertex_idxes;
Expand Down Expand Up @@ -542,6 +571,28 @@ bool Level::delete_lift_vertex(std::string lift_name)
return true;
}

std::vector<Edge> Level::edges_with_vertex(int vertex_idx) const
{
std::vector<Edge> result;
for (const auto& edge : edges)
{
if (edge.contains(vertex_idx))
result.push_back(edge);
}
return result;
}

std::vector<Polygon> Level::polygons_with_vertex(int vertex_idx) const
{
std::vector<Polygon> result;
for (const auto& polygon : polygons)
{
if (polygon.contains_vertex(vertex_idx))
result.push_back(polygon);
}
return result;
}

void Level::get_selected_items(
std::vector<Level::SelectedItem>& items)
{
Expand Down
3 changes: 3 additions & 0 deletions rmf_traffic_editor/gui/level.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,10 @@ class Level

bool can_delete_current_selection();
bool delete_selected();
bool delete_used_entities(int selected_vertex_idx);
bool delete_lift_vertex(std::string lift_name);
std::vector<Edge> edges_with_vertex(int vertex_idx) const;
std::vector<Polygon> polygons_with_vertex(int vertex_idx) const;
void calculate_scale(const CoordinateSystem& coordinate_system);
void clear_selection();

Expand Down
19 changes: 19 additions & 0 deletions rmf_traffic_editor/gui/polygon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,3 +138,22 @@ void Polygon::create_param_if_needed(
if (it == params.end() || it->second.type != param_type)
params[name] = param_value;
}

bool Polygon::contains_vertex(const int vertex_idx) const
{
return std::find(vertices.begin(), vertices.end(),
vertex_idx) != vertices.end();
}

std::string Polygon::type_to_string() const
{
if (type == FLOOR)
return string("floor");
else if (type == ZONE)
return string("zone");
else if (type == ROI)
return string("roi");
else if (type == HOLE)
return string("hole");
return string("undefined");
}
3 changes: 3 additions & 0 deletions rmf_traffic_editor/gui/polygon.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,9 @@ class Polygon
const std::string& name,
const Param::Type& param_type,
const T& param_value);

bool contains_vertex(const int vertex_idx) const;
std::string type_to_string() const;
};

#endif

0 comments on commit 5ed7be2

Please sign in to comment.