From 5aa30de1714fce6f31c91268b139e42dea8e4ac4 Mon Sep 17 00:00:00 2001 From: Louise Poubel Date: Thu, 2 Dec 2021 12:55:50 -0800 Subject: [PATCH 1/7] Grid config: set values from startup and improve layout Signed-off-by: Louise Poubel --- examples/config/grid_config.config | 36 ++++++++++ src/plugins/grid_config/GridConfig.cc | 78 +++++++++++---------- src/plugins/grid_config/GridConfig.hh | 19 +++++ src/plugins/grid_config/GridConfig.qml | 96 +++++++++++++++++--------- 4 files changed, 159 insertions(+), 70 deletions(-) create mode 100644 examples/config/grid_config.config diff --git a/examples/config/grid_config.config b/examples/config/grid_config.config new file mode 100644 index 000000000..bae1ef8b3 --- /dev/null +++ b/examples/config/grid_config.config @@ -0,0 +1,36 @@ + + + + + View 1 + docked + + ogre2 + scene + 1 1 1 + 0.8 0.8 0.8 + -6 3 6 0 0.5 0 + + + + + + + + false + 5 + 5 + floating + false + + + + + docked + + 3 + 2 + 2 + 1 2 3 0 0 0 + 1 0 0 1 + diff --git a/src/plugins/grid_config/GridConfig.cc b/src/plugins/grid_config/GridConfig.cc index 026d21037..8e5b6fb2d 100644 --- a/src/plugins/grid_config/GridConfig.cc +++ b/src/plugins/grid_config/GridConfig.cc @@ -17,6 +17,7 @@ #include #include +#include #include #include #include @@ -75,11 +76,49 @@ GridConfig::GridConfig() GridConfig::~GridConfig() = default; ///////////////////////////////////////////////// -void GridConfig::LoadConfig(const tinyxml2::XMLElement *) +void GridConfig::LoadConfig(const tinyxml2::XMLElement *_pluginElem) { if (this->title.empty()) this->title = "Grid config"; + // Configuration + if (_pluginElem) + { + // For grid to be configured at startup + if (auto cellCountElem = _pluginElem->FirstChildElement("cell_count")) + cellCountElem->QueryIntText(&this->dataPtr->gridParam.hCellCount); + + if (auto vElem = _pluginElem->FirstChildElement("vertical_cell_count")) + vElem->QueryIntText(&this->dataPtr->gridParam.vCellCount); + + if (auto lengthElem = _pluginElem->FirstChildElement("cell_length")) + lengthElem->QueryDoubleText(&this->dataPtr->gridParam.cellLength); + + auto elem = _pluginElem->FirstChildElement("pose"); + if (nullptr != elem && nullptr != elem->GetText()) + { + std::stringstream poseStr; + poseStr << std::string(elem->GetText()); + poseStr >> this->dataPtr->gridParam.pose; + } + + elem = _pluginElem->FirstChildElement("color"); + if (nullptr != elem && nullptr != elem->GetText()) + { + std::stringstream colorStr; + colorStr << std::string(elem->GetText()); + colorStr >> this->dataPtr->gridParam.color; + } + this->newParams( + this->dataPtr->gridParam.hCellCount, + this->dataPtr->gridParam.vCellCount, + this->dataPtr->gridParam.cellLength, + convert(this->dataPtr->gridParam.pose.Pos()), + convert(this->dataPtr->gridParam.pose.Rot().Euler()), + convert(this->dataPtr->gridParam.color)); + this->dataPtr->dirty = true; + } + ignition::gui::App()->findChild< ignition::gui::MainWindow *>()->installEventFilter(this); } @@ -149,43 +188,10 @@ void GridConfig::UpdateGrid() ///////////////////////////////////////////////// void GridConfig::LoadGrid() { - auto loadedEngNames = rendering::loadedEngines(); - if (loadedEngNames.empty()) + auto scene = rendering::sceneFromFirstRenderEngine(); + if (nullptr == scene) return; - // assume there is only one engine loaded - auto engineName = loadedEngNames[0]; - if (loadedEngNames.size() > 1) - { - igndbg << "More than one engine is available. " - << "Grid config plugin will use engine [" - << engineName << "]" << std::endl; - } - auto engine = rendering::engine(engineName); - if (!engine) - { - ignerr << "Internal error: failed to load engine [" << engineName - << "]. Grid plugin won't work." << std::endl; - return; - } - - if (engine->SceneCount() == 0) - return; - - // assume there is only one scene - // load scene - auto scene = engine->SceneByIndex(0); - if (!scene) - { - ignerr << "Internal error: scene is null." << std::endl; - return; - } - - if (!scene->IsInitialized() || nullptr == scene->RootVisual()) - { - return; - } - // load grid // if gridPtr found, load the existing gridPtr to class for (unsigned int i = 0; i < scene->VisualCount(); ++i) diff --git a/src/plugins/grid_config/GridConfig.hh b/src/plugins/grid_config/GridConfig.hh index 859e8f4a5..2fd8d263c 100644 --- a/src/plugins/grid_config/GridConfig.hh +++ b/src/plugins/grid_config/GridConfig.hh @@ -77,6 +77,25 @@ namespace gui /// \param[in] _checked indicates show or hide grid public slots: void OnShow(bool _checked); + /// \brief Notify QML that grid values have changed. + /// \param[in] _hCellCount Horizontal cell count + /// \param[in] _vCellCount Vertical cell count + /// \param[in] _cellLength Cell length + /// \param[in] _x X position + /// \param[in] _y Y position + /// \param[in] _z Z position + /// \param[in] _roll Orientation's roll + /// \param[in] _pitch Orientation's pitch + /// \param[in] _yaw Orientation's yaw + /// \param[in] _color Grid color + signals: void newParams( + int _hCellCount, + int _vCellCount, + double _cellLength, + QVector3D _pos, + QVector3D _rot, + QColor _color); + /// \internal /// \brief Pointer to private data. private: std::unique_ptr dataPtr; diff --git a/src/plugins/grid_config/GridConfig.qml b/src/plugins/grid_config/GridConfig.qml index d73efd47d..6c92ae16c 100644 --- a/src/plugins/grid_config/GridConfig.qml +++ b/src/plugins/grid_config/GridConfig.qml @@ -21,7 +21,7 @@ import QtQuick.Layouts 1.3 import "qrc:/qml" GridLayout { - columns: 6 + columns: 4 columnSpacing: 10 Layout.minimumWidth: 300 Layout.minimumHeight: 625 @@ -29,11 +29,33 @@ GridLayout { anchors.leftMargin: 10 anchors.rightMargin: 10 - // Left spacer - Item { - Layout.columnSpan: 1 - Layout.rowSpan: 15 - Layout.fillWidth: true + // Get number of decimal digits based on a widget's width + // TODO(chapulina) Move this to a common place so all widgets can use it + function getDecimals(_width) { + if (_width <= 80) + return 2; + else if (_width <= 100) + return 4; + return 6; + } + + Connections { + target: GridConfig + onNewParams: { + horizontalCellCount.value = _hCellCount; + verticalCellCount.value = _vCellCount; + cellLength.value = _cellLength; + x.value = _pos.x; + y.value = _pos.y; + z.value = _pos.z; + roll.value = _rot.x; + pitch.value = _rot.y; + yaw.value = _rot.z; + r.value = _color.r; + g.value = _color.g; + b.value = _color.b; + a.value = _color.a; + } } CheckBox { @@ -47,13 +69,6 @@ GridLayout { } } - // Right spacer - Item { - Layout.columnSpan: 1 - Layout.rowSpan: 15 - Layout.fillWidth: true - } - Text { Layout.columnSpan: 4 text: "Cell Count" @@ -70,8 +85,9 @@ GridLayout { IgnSpinBox { Layout.columnSpan: 2 + Layout.fillWidth: true id: verticalCellCount - maximumValue: 1000 + maximumValue: Number.MAX_VALUE minimumValue: 0 value: 0 onEditingFinished: GridConfig.UpdateVCellCount(verticalCellCount.value) @@ -86,8 +102,9 @@ GridLayout { IgnSpinBox { Layout.columnSpan: 2 + Layout.fillWidth: true id: horizontalCellCount - maximumValue: 1000 + maximumValue: Number.MAX_VALUE minimumValue: 1 value: 20 onEditingFinished: GridConfig.UpdateHCellCount(horizontalCellCount.value) @@ -109,11 +126,12 @@ GridLayout { } IgnSpinBox { Layout.columnSpan: 2 + Layout.fillWidth: true id: cellLength - maximumValue: 1000.00 - minimumValue: 0.01 + maximumValue: Number.MAX_VALUE + minimumValue: 0.0000001 value: 1.00 - decimals: 2 + decimals: getDecimals(cellLength.width) stepSize: 0.01 onEditingFinished: GridConfig.UpdateCellLength(cellLength.value) } @@ -140,11 +158,12 @@ GridLayout { } IgnSpinBox { + Layout.fillWidth: true id: x value: 0.00 - maximumValue: 1000.00 - minimumValue: -1000.00 - decimals: 2 + maximumValue: Number.MAX_VALUE + minimumValue: -Number.MAX_VALUE + decimals: getDecimals(x.width) stepSize: 0.01 onEditingFinished: GridConfig.SetPose(x.value, y.value, z.value, roll.value, pitch.value, yaw.value) } @@ -155,11 +174,12 @@ GridLayout { } IgnSpinBox { + Layout.fillWidth: true id: roll maximumValue: 6.28 minimumValue: 0.00 value: 0.00 - decimals: 2 + decimals: getDecimals(roll.width) stepSize: 0.01 onEditingFinished: GridConfig.SetPose(x.value, y.value, z.value, roll.value, pitch.value, yaw.value) } @@ -170,11 +190,12 @@ GridLayout { } IgnSpinBox { + Layout.fillWidth: true id: y value: 0.00 - maximumValue: 1000.00 - minimumValue: -1000.00 - decimals: 2 + maximumValue: Number.MAX_VALUE + minimumValue: -Number.MAX_VALUE + decimals: getDecimals(y.width) stepSize: 0.01 onEditingFinished: GridConfig.SetPose(x.value, y.value, z.value, roll.value, pitch.value, yaw.value) } @@ -185,11 +206,12 @@ GridLayout { } IgnSpinBox { + Layout.fillWidth: true id: pitch maximumValue: 6.28 minimumValue: 0.00 value: 0.00 - decimals: 2 + decimals: getDecimals(pitch.width) stepSize: 0.01 onEditingFinished: GridConfig.SetPose(x.value, y.value, z.value, roll.value, pitch.value, yaw.value) } @@ -200,11 +222,12 @@ GridLayout { } IgnSpinBox { + Layout.fillWidth: true id: z value: 0.00 - maximumValue: 1000.00 - minimumValue: -1000.00 - decimals: 2 + maximumValue: Number.MAX_VALUE + minimumValue: -Number.MAX_VALUE + decimals: getDecimals(z.width) stepSize: 0.01 onEditingFinished: GridConfig.SetPose(x.value, y.value, z.value, roll.value, pitch.value, yaw.value) } @@ -215,11 +238,12 @@ GridLayout { } IgnSpinBox { + Layout.fillWidth: true id: yaw maximumValue: 6.28 minimumValue: 0.00 value: 0.00 - decimals: 2 + decimals: getDecimals(yaw.width) stepSize: 0.01 onEditingFinished: GridConfig.SetPose(x.value, y.value, z.value, roll.value, pitch.value, yaw.value) } @@ -237,12 +261,13 @@ GridLayout { } IgnSpinBox { + Layout.fillWidth: true id: r maximumValue: 1.00 minimumValue: 0.00 value: 0.7 stepSize: 0.01 - decimals: 2 + decimals: getDecimals(r.width) onEditingFinished: GridConfig.SetColor(r.value, g.value, b.value, a.value) } @@ -252,12 +277,13 @@ GridLayout { } IgnSpinBox { + Layout.fillWidth: true id: g maximumValue: 1.00 minimumValue: 0.00 value: 0.7 stepSize: 0.01 - decimals: 2 + decimals: getDecimals(g.width) onEditingFinished: GridConfig.SetColor(r.value, g.value, b.value, a.value) } @@ -267,12 +293,13 @@ GridLayout { } IgnSpinBox { + Layout.fillWidth: true id: b maximumValue: 1.00 minimumValue: 0.00 value: 0.7 stepSize: 0.01 - decimals: 2 + decimals: getDecimals(b.width) onEditingFinished: GridConfig.SetColor(r.value, g.value, b.value, a.value) } @@ -282,12 +309,13 @@ GridLayout { } IgnSpinBox { + Layout.fillWidth: true id: a maximumValue: 1.00 minimumValue: 0.00 value: 1.0 stepSize: 0.01 - decimals: 2 + decimals: getDecimals(a.width) onEditingFinished: GridConfig.SetColor(r.value, g.value, b.value, a.value) } From c07881b3a1217a58a416282c841331c815c126f5 Mon Sep 17 00:00:00 2001 From: Louise Poubel Date: Thu, 2 Dec 2021 13:01:13 -0800 Subject: [PATCH 2/7] cppcheck Signed-off-by: Louise Poubel --- src/plugins/grid_config/GridConfig.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/plugins/grid_config/GridConfig.cc b/src/plugins/grid_config/GridConfig.cc index 8e5b6fb2d..e12d7bb4c 100644 --- a/src/plugins/grid_config/GridConfig.cc +++ b/src/plugins/grid_config/GridConfig.cc @@ -15,6 +15,8 @@ * */ +#include + #include #include #include From 134e1ca51e254878cc92f0716b601854e5d70eee Mon Sep 17 00:00:00 2001 From: Louise Poubel Date: Fri, 3 Dec 2021 10:14:29 -0800 Subject: [PATCH 3/7] doxy Signed-off-by: Louise Poubel --- src/plugins/grid_config/GridConfig.hh | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/plugins/grid_config/GridConfig.hh b/src/plugins/grid_config/GridConfig.hh index 2fd8d263c..cfb9841af 100644 --- a/src/plugins/grid_config/GridConfig.hh +++ b/src/plugins/grid_config/GridConfig.hh @@ -81,12 +81,8 @@ namespace gui /// \param[in] _hCellCount Horizontal cell count /// \param[in] _vCellCount Vertical cell count /// \param[in] _cellLength Cell length - /// \param[in] _x X position - /// \param[in] _y Y position - /// \param[in] _z Z position - /// \param[in] _roll Orientation's roll - /// \param[in] _pitch Orientation's pitch - /// \param[in] _yaw Orientation's yaw + /// \param[in] _pos XYZ Position + /// \param[in] _rot RPY orientation /// \param[in] _color Grid color signals: void newParams( int _hCellCount, From df99e28a660c046892bae1ac97ca88af217a12c5 Mon Sep 17 00:00:00 2001 From: Louise Poubel Date: Mon, 6 Dec 2021 21:44:20 -0800 Subject: [PATCH 4/7] Add features from Grid3d to GridConfig Signed-off-by: Louise Poubel --- examples/config/grid_config.config | 19 +- src/plugins/grid_config/GridConfig.cc | 287 +++++++++++++++++-------- src/plugins/grid_config/GridConfig.hh | 52 ++++- src/plugins/grid_config/GridConfig.qml | 34 ++- 4 files changed, 293 insertions(+), 99 deletions(-) diff --git a/examples/config/grid_config.config b/examples/config/grid_config.config index bae1ef8b3..037268656 100644 --- a/examples/config/grid_config.config +++ b/examples/config/grid_config.config @@ -28,9 +28,18 @@ docked - 3 - 2 - 2 - 1 2 3 0 0 0 - 1 0 0 1 + + 3 + 2 + 2 + 1 2 3 0 0 0 + 1 0 0 1 + + + 2 + 0 + 1 + 0 0 0 0.5 0 0 + 0 1 0 1 + diff --git a/src/plugins/grid_config/GridConfig.cc b/src/plugins/grid_config/GridConfig.cc index e12d7bb4c..fa502b48e 100644 --- a/src/plugins/grid_config/GridConfig.cc +++ b/src/plugins/grid_config/GridConfig.cc @@ -33,35 +33,50 @@ namespace ignition::gui { struct GridParam { - /// \brief Default horizontal cell count + /// \brief Horizontal cell count int hCellCount{20}; - /// \brief Default vertical cell count + /// \brief Vertical cell count int vCellCount{0}; - /// \brief Default cell length + /// \brief Cell length double cellLength{1.0}; - /// \brief Default pose of grid + /// \brief 3D pose math::Pose3d pose{math::Pose3d::Zero}; - /// \brief Default color of grid + /// \brief Grid color math::Color color{math::Color(0.7f, 0.7f, 0.7f, 1.0f)}; - - /// \brief Default visible state - bool visible{true}; }; class GridConfigPrivate { - /// \brief Assume only one gridptr in a scene - public: rendering::GridPtr grid; + /// \brief List of grid names. + public: QStringList nameList; + + /// \brief + std::string name; - /// \brief Default grid parameters + /// \brief Grid parameters public: GridParam gridParam; + /// \brief Grids to add at startup + public: std::vector startupGrids; + + /// \brief Pointer to selected grid + rendering::GridPtr grid{nullptr}; + + /// \brief Pointer to scene + rendering::ScenePtr scene{nullptr}; + /// \brief Flag that indicates whether there are new updates to be rendered. public: bool dirty{false}; + + /// \brief True if name list needs to be refreshed. + public: bool refreshList{true}; + + /// \brief Visible state + bool visible{true}; }; } @@ -86,39 +101,45 @@ void GridConfig::LoadConfig(const tinyxml2::XMLElement *_pluginElem) // Configuration if (_pluginElem) { - // For grid to be configured at startup - if (auto cellCountElem = _pluginElem->FirstChildElement("cell_count")) - cellCountElem->QueryIntText(&this->dataPtr->gridParam.hCellCount); + // For grids to be inserted at startup + for (auto insertElem = _pluginElem->FirstChildElement("insert"); + insertElem != nullptr; + insertElem = insertElem->NextSiblingElement("insert")) + { + GridParam gridParam; - if (auto vElem = _pluginElem->FirstChildElement("vertical_cell_count")) - vElem->QueryIntText(&this->dataPtr->gridParam.vCellCount); + // Both cell_count and horizontal_cell_count apply to horizontal for backwards + // compatibility + if (auto cellCountElem = insertElem->FirstChildElement("cell_count")) + cellCountElem->QueryIntText(&gridParam.hCellCount); - if (auto lengthElem = _pluginElem->FirstChildElement("cell_length")) - lengthElem->QueryDoubleText(&this->dataPtr->gridParam.cellLength); + if (auto cellCountElem = insertElem->FirstChildElement("horizontal_cell_count")) + cellCountElem->QueryIntText(&gridParam.hCellCount); - auto elem = _pluginElem->FirstChildElement("pose"); - if (nullptr != elem && nullptr != elem->GetText()) - { - std::stringstream poseStr; - poseStr << std::string(elem->GetText()); - poseStr >> this->dataPtr->gridParam.pose; - } + if (auto vElem = insertElem->FirstChildElement("vertical_cell_count")) + vElem->QueryIntText(&gridParam.vCellCount); - elem = _pluginElem->FirstChildElement("color"); - if (nullptr != elem && nullptr != elem->GetText()) - { - std::stringstream colorStr; - colorStr << std::string(elem->GetText()); - colorStr >> this->dataPtr->gridParam.color; + if (auto lengthElem = insertElem->FirstChildElement("cell_length")) + lengthElem->QueryDoubleText(&gridParam.cellLength); + + auto elem = insertElem->FirstChildElement("pose"); + if (nullptr != elem && nullptr != elem->GetText()) + { + std::stringstream poseStr; + poseStr << std::string(elem->GetText()); + poseStr >> gridParam.pose; + } + + elem = insertElem->FirstChildElement("color"); + if (nullptr != elem && nullptr != elem->GetText()) + { + std::stringstream colorStr; + colorStr << std::string(elem->GetText()); + colorStr >> gridParam.color; + } + + this->dataPtr->startupGrids.push_back(gridParam); } - this->newParams( - this->dataPtr->gridParam.hCellCount, - this->dataPtr->gridParam.vCellCount, - this->dataPtr->gridParam.cellLength, - convert(this->dataPtr->gridParam.pose.Pos()), - convert(this->dataPtr->gridParam.pose.Rot().Euler()), - convert(this->dataPtr->gridParam.color)); - this->dataPtr->dirty = true; } ignition::gui::App()->findChild< @@ -130,23 +151,65 @@ bool GridConfig::eventFilter(QObject *_obj, QEvent *_event) { if (_event->type() == ignition::gui::events::Render::kType) { - // This event is called in Scene3d's RenderThread, so it's safe to make - // rendering calls here - this->UpdateGrid(); + if (nullptr == this->dataPtr->scene) + this->dataPtr->scene = rendering::sceneFromFirstRenderEngine(); + + if (nullptr != this->dataPtr->scene) + { + // Create grid setup at startup + this->CreateGrids(); + + // Update combo box + this->RefreshList(); + + // Update selected grid + this->UpdateGrid(); + } } // Standard event processing return QObject::eventFilter(_obj, _event); } +///////////////////////////////////////////////// +void GridConfig::CreateGrids() +{ + if (this->dataPtr->startupGrids.empty()) + return; + + for (const auto &gridParam : this->dataPtr->startupGrids) + { + auto grid = this->dataPtr->scene->CreateGrid(); + grid->SetCellCount(gridParam.hCellCount); + grid->SetVerticalCellCount(gridParam.vCellCount); + grid->SetCellLength(gridParam.cellLength); + + auto gridVis = this->dataPtr->scene->CreateVisual(); + this->dataPtr->scene->RootVisual()->AddChild(gridVis); + gridVis->SetLocalPose(gridParam.pose); + gridVis->AddGeometry(grid); + + auto mat = this->dataPtr->scene->CreateMaterial(); + mat->SetAmbient(gridParam.color); + mat->SetDiffuse(gridParam.color); + mat->SetSpecular(gridParam.color); + gridVis->SetMaterial(mat); + + this->dataPtr->dirty = true; + + igndbg << "Created grid [" << grid->Name() << "]" << std::endl; + } + this->dataPtr->startupGrids.clear(); +} + ///////////////////////////////////////////////// void GridConfig::UpdateGrid() { - // Load grid if it doesn't already exist + // Connect to a grid if (!this->dataPtr->grid) - this->LoadGrid(); + this->ConnectToGrid(); - // If grid was not loaded successfully, don't update + // If not connected, don't update if (!this->dataPtr->grid) return; @@ -177,7 +240,7 @@ void GridConfig::UpdateGrid() ignerr << "Grid visual missing material" << std::endl; } - visual->SetVisible(this->dataPtr->gridParam.visible); + visual->SetVisible(this->dataPtr->visible); } else { @@ -188,69 +251,74 @@ void GridConfig::UpdateGrid() } ///////////////////////////////////////////////// -void GridConfig::LoadGrid() +void GridConfig::ConnectToGrid() { - auto scene = rendering::sceneFromFirstRenderEngine(); - if (nullptr == scene) + if (this->dataPtr->name.empty()) + return; + + if (this->dataPtr->grid) return; - // load grid - // if gridPtr found, load the existing gridPtr to class - for (unsigned int i = 0; i < scene->VisualCount(); ++i) + for (unsigned int i = 0; i < this->dataPtr->scene->VisualCount(); ++i) { - auto vis = scene->VisualByIndex(i); + auto vis = this->dataPtr->scene->VisualByIndex(i); if (!vis || vis->GeometryCount() == 0) continue; for (unsigned int j = 0; j < vis->GeometryCount(); ++j) { auto grid = std::dynamic_pointer_cast( vis->GeometryByIndex(j)); - if (grid) + if (grid && grid->Name() == this->dataPtr->name) { - igndbg << "Attaching to existing grid" << std::endl; this->dataPtr->grid = grid; - return; + + igndbg << "Connected to grid [" << grid->Name() << "]" << std::endl; + + // TODO(chapulina) Set to the grid's visible state when that's available + // through ign-rendering's API + this->dataPtr->visible = true; + grid->Parent()->SetVisible(true); + + this->dataPtr->gridParam.hCellCount = grid->CellCount(); + this->dataPtr->gridParam.vCellCount = grid->VerticalCellCount(); + this->dataPtr->gridParam.cellLength = grid->CellLength(); + this->dataPtr->gridParam.pose = grid->Parent()->LocalPose(); + this->dataPtr->gridParam.color = grid->Parent()->Material()->Ambient(); + this->newParams( + grid->CellCount(), + grid->VerticalCellCount(), + grid->CellLength(), + convert(grid->Parent()->LocalPose().Pos()), + convert(grid->Parent()->LocalPose().Rot().Euler()), + convert(grid->Parent()->Material()->Ambient())); } } } +} - if (this->dataPtr->grid) - return; - - // Create grid - igndbg << "Creating grid" << std::endl; - - auto root = scene->RootVisual(); - this->dataPtr->grid = scene->CreateGrid(); - if (!this->dataPtr->grid) - { - ignwarn << "Failed to create grid, grid config plugin won't work." - << std::endl; +///////////////////////////////////////////////// +void GridConfig::OnName(const QString &_name) +{ + this->dataPtr->name = _name.toStdString(); - // If we get here, most likely the render engine and scene are fully loaded, - // but they don't support grids. So stop trying. - ignition::gui::App()->findChild< - ignition::gui::MainWindow *>()->removeEventFilter(this); - return; - } + // Set it to null so we load the new grid + this->dataPtr->grid = nullptr; - this->dataPtr->grid->SetCellCount( - this->dataPtr->gridParam.hCellCount); - this->dataPtr->grid->SetVerticalCellCount( - this->dataPtr->gridParam.vCellCount); - this->dataPtr->grid->SetCellLength( - this->dataPtr->gridParam.cellLength); + // Don't change the grid we're about to connected to + this->dataPtr->dirty = false; +} - auto vis = scene->CreateVisual(); - root->AddChild(vis); - vis->SetLocalPose(this->dataPtr->gridParam.pose); - vis->AddGeometry(this->dataPtr->grid); +///////////////////////////////////////////////// +QStringList GridConfig::NameList() const +{ + return this->dataPtr->nameList; +} - auto mat = scene->CreateMaterial(); - mat->SetAmbient(this->dataPtr->gridParam.color); - mat->SetDiffuse(this->dataPtr->gridParam.color); - mat->SetSpecular(this->dataPtr->gridParam.color); - vis->SetMaterial(mat); +///////////////////////////////////////////////// +void GridConfig::SetNameList(const QStringList &_nameList) +{ + this->dataPtr->nameList = _nameList; + this->NameListChanged(); } ///////////////////////////////////////////////// @@ -293,10 +361,49 @@ void GridConfig::SetColor(double _r, double _g, double _b, double _a) ///////////////////////////////////////////////// void GridConfig::OnShow(bool _checked) { - this->dataPtr->gridParam.visible = _checked; + this->dataPtr->visible = _checked; this->dataPtr->dirty = true; } +///////////////////////////////////////////////// +void GridConfig::OnRefresh() +{ + this->dataPtr->refreshList = true; +} + +///////////////////////////////////////////////// +void GridConfig::RefreshList() +{ + if (!this->dataPtr->refreshList) + return; + this->dataPtr->refreshList = false; + + // Clear + this->dataPtr->nameList.clear(); + + // Get updated list + for (unsigned int i = 0; i < this->dataPtr->scene->VisualCount(); ++i) + { + auto vis = this->dataPtr->scene->VisualByIndex(i); + if (!vis || vis->GeometryCount() == 0) + continue; + for (unsigned int j = 0; j < vis->GeometryCount(); ++j) + { + auto grid = std::dynamic_pointer_cast( + vis->GeometryByIndex(j)); + if (grid) + { + this->dataPtr->nameList.push_back(QString::fromStdString(grid->Name())); + } + } + } + + // Select first one + if (this->dataPtr->nameList.count() > 0) + this->OnName(this->dataPtr->nameList.at(0)); + this->NameListChanged(); +} + // Register this plugin IGNITION_ADD_PLUGIN(ignition::gui::GridConfig, ignition::gui::Plugin) diff --git a/src/plugins/grid_config/GridConfig.hh b/src/plugins/grid_config/GridConfig.hh index cfb9841af..e825de7b8 100644 --- a/src/plugins/grid_config/GridConfig.hh +++ b/src/plugins/grid_config/GridConfig.hh @@ -29,10 +29,34 @@ namespace gui { class GridConfigPrivate; + /// \brief Manages grids in an Ignition Rendering scene. This plugin can be + /// used for: + /// * Introspecting grids + /// * Editing grids + /// + /// ## Configuration + /// + /// * \ : One grid will be inserted at startup for each \ + /// tag. + /// * \ : Number of cells in the horizontal + /// direction, defaults to 20. + /// * \ : Number of cells in the vertical direction, + /// defaults to 0; + /// * \ : Length of each cell, defaults to 1. + /// * \ : Grid pose, defaults to the origin. + /// * \ : Grid color, defaults to (0.7, 0.7, 0.7, 1.0) class GridConfig : public ignition::gui::Plugin { Q_OBJECT + /// \brief Name list + Q_PROPERTY( + QStringList nameList + READ NameList + WRITE SetNameList + NOTIFY NameListChanged + ) + /// \brief Constructor public: GridConfig(); @@ -45,11 +69,35 @@ namespace gui // Documentation inherited protected: bool eventFilter(QObject *_obj, QEvent *_event) override; + /// \brief Create grids defined at startup + public: void CreateGrids(); + /// \brief Update grid public: void UpdateGrid(); - /// \brief Callback to retrieve existing grid or create a new one. - public: void LoadGrid(); + /// \brief Callback to retrieve existing grid. + public: void ConnectToGrid(); + + /// \brief Refresh list of grids. This is called in the rendering thread. + public: void RefreshList(); + + /// \brief Callback when refresh button is pressed. + public slots: void OnRefresh(); + + /// \brief Callback when a new name is chosen on the combo box. + /// \param[in] _name Grid name + public slots: void OnName(const QString &_name); + + /// \brief Get the list of grid names + /// \return List of grids. + public slots: QStringList NameList() const; + + /// \brief Set the list of names + /// \param[in] _nameList List of names + public slots: void SetNameList(const QStringList &_nameList); + + /// \brief Notify that name list has changed + signals: void NameListChanged(); /// \brief Callback to update vertical cell count /// \param[in] _cellCount new vertical cell count diff --git a/src/plugins/grid_config/GridConfig.qml b/src/plugins/grid_config/GridConfig.qml index 6c92ae16c..e59fd4723 100644 --- a/src/plugins/grid_config/GridConfig.qml +++ b/src/plugins/grid_config/GridConfig.qml @@ -16,6 +16,7 @@ */ import QtQuick 2.9 import QtQuick.Controls 2.1 +import QtQuick.Controls.Material 2.1 import QtQuick.Dialogs 1.0 import QtQuick.Layouts 1.3 import "qrc:/qml" @@ -58,11 +59,40 @@ GridLayout { } } + ComboBox { + id: combo + Layout.columnSpan: 2 + Layout.fillWidth: true + model: GridConfig.nameList + onCurrentIndexChanged: { + if (currentIndex < 0) + return; + + GridConfig.OnName(textAt(currentIndex)); + } + popup.width: parent.width + ToolTip.visible: hovered + ToolTip.delay: Qt.styleHints.mousePressAndHoldInterval + ToolTip.text: qsTr("Grids in the scene") + } + + RoundButton { + text: "\u21bb" + Layout.columnSpan: 1 + Material.background: Material.primary + onClicked: { + GridConfig.OnRefresh(); + } + ToolTip.visible: hovered + ToolTip.delay: Qt.styleHints.mousePressAndHoldInterval + ToolTip.text: qsTr("Refresh list of grids") + } + CheckBox { Layout.alignment: Qt.AlignHCenter id: showgrid - Layout.columnSpan: 4 - text: qsTr("Show/Hide Grid") + Layout.columnSpan: 1 + text: qsTr("Show") checked: true onClicked: { GridConfig.OnShow(checked) From 770118daf13cf291f0e7fcd9f84376f7e3ace75b Mon Sep 17 00:00:00 2001 From: Louise Poubel Date: Mon, 6 Dec 2021 22:11:15 -0800 Subject: [PATCH 5/7] Deprecate Grid3D Signed-off-by: Louise Poubel --- Migration.md | 7 + src/plugins/CMakeLists.txt | 1 - src/plugins/grid_3d/CMakeLists.txt | 11 - src/plugins/grid_3d/Grid3D.cc | 525 ------------------------- src/plugins/grid_3d/Grid3D.hh | 94 ----- src/plugins/grid_3d/Grid3D.qml | 26 -- src/plugins/grid_3d/Grid3D.qrc | 5 - src/plugins/grid_3d/Grid3D_TEST.cc | 291 -------------- src/plugins/grid_config/CMakeLists.txt | 4 + 9 files changed, 11 insertions(+), 953 deletions(-) delete mode 100644 src/plugins/grid_3d/CMakeLists.txt delete mode 100644 src/plugins/grid_3d/Grid3D.cc delete mode 100644 src/plugins/grid_3d/Grid3D.hh delete mode 100644 src/plugins/grid_3d/Grid3D.qml delete mode 100644 src/plugins/grid_3d/Grid3D.qrc delete mode 100644 src/plugins/grid_3d/Grid3D_TEST.cc diff --git a/Migration.md b/Migration.md index a80f8fee2..b482ad451 100644 --- a/Migration.md +++ b/Migration.md @@ -5,6 +5,13 @@ Deprecated code produces compile-time warnings. These warning serve as notification to users that their code should be upgraded. The next major release will remove the deprecated code. +## Ignition GUI 6.1 to 6.2 + +* All features from `Grid3D` have been incorportated into `GridConfig`. The code + for the original `Grid3D` has been removed and now the installed library is + just a copy of `GridConfig`. Existing `Grid3D` users shouldn't be affected and + may continue to use `Grid3D` as before. + ## Ignition GUI 5.x to 6.x * The `Scene3D` plugin is deprecated, use `MinimalScene` with diff --git a/src/plugins/CMakeLists.txt b/src/plugins/CMakeLists.txt index dd1a1bccf..7666bb759 100644 --- a/src/plugins/CMakeLists.txt +++ b/src/plugins/CMakeLists.txt @@ -115,7 +115,6 @@ endfunction() # Plugins add_subdirectory(camera_tracking) -add_subdirectory(grid_3d) add_subdirectory(grid_config) add_subdirectory(image_display) add_subdirectory(interactive_view_control) diff --git a/src/plugins/grid_3d/CMakeLists.txt b/src/plugins/grid_3d/CMakeLists.txt deleted file mode 100644 index 444b3f566..000000000 --- a/src/plugins/grid_3d/CMakeLists.txt +++ /dev/null @@ -1,11 +0,0 @@ -ign_gui_add_plugin(Grid3D - SOURCES - Grid3D.cc - QT_HEADERS - Grid3D.hh - TEST_SOURCES - # Grid3D_TEST.cc - PUBLIC_LINK_LIBS - ignition-rendering${IGN_RENDERING_VER}::ignition-rendering${IGN_RENDERING_VER} -) - diff --git a/src/plugins/grid_3d/Grid3D.cc b/src/plugins/grid_3d/Grid3D.cc deleted file mode 100644 index d9072ae67..000000000 --- a/src/plugins/grid_3d/Grid3D.cc +++ /dev/null @@ -1,525 +0,0 @@ -/* - * Copyright (C) 2017 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 -#include -#include -#include - -#include -#include -#include -#include - -// TODO(louise) Remove these pragmas once ign-rendering is disabling the -// warnings -#ifdef _WIN32 -#pragma warning(push) -#pragma warning(disable: 4251) -#endif - -#include -#include -#include -#include -#include - -#ifdef _MSC_VER -#pragma warning(pop) -#endif - -#include "Grid3D.hh" - -// Default cell count -static const int kDefaultCellCount{20}; - -// Default vertical cell count -static const int kDefaultVertCellCount{0}; - -// Default cell length -static const double kDefaultCellLength{1.0}; - -// Default pose -static const ignition::math::Pose3d kDefaultPose{ignition::math::Pose3d::Zero}; - -// Default color -static const ignition::math::Color kDefaultColor{ - ignition::math::Color(0.7f, 0.7f, 0.7f, 1.0f)}; - -namespace ignition -{ -namespace gui -{ -namespace plugins -{ - /// \brief Holds configuration for a grid - struct GridInfo - { - /// \brief Number of cells in the horizontal - int cellCount{kDefaultCellCount}; - - /// \brief Number of cells in the vertical - int vertCellCount{kDefaultVertCellCount}; - - /// \brief Cell length, both horizontal and vertical - double cellLength{kDefaultCellLength}; - - /// \brief Grid pose in the world - math::Pose3d pose{kDefaultPose}; - - /// \brief Grid ambient color - math::Color color{kDefaultColor}; - }; - - class Grid3DPrivate - { - /// brief Parent window - public: QQuickWindow *quickWindow = nullptr; - - /// \brief We keep a pointer to the engine and rely on it not being - /// destroyed, since it is a singleton. - public: rendering::RenderEngine *engine = nullptr; - - /// \brief We keep the scene name rather than a shared pointer because we - /// don't want to share ownership. - public: std::string sceneName{""}; - - /// \brief Engine name received at startup - public: std::string engineName{""}; - - /// \brief Grids received from config file on startup - public: std::vector startupGrids; - - /// \brief Keep track of grids we currently found on the scene - public: std::vector grids; - }; -} -} -} - -using namespace ignition; -using namespace gui; -using namespace plugins; - -///////////////////////////////////////////////// -Grid3D::Grid3D() - : Plugin(), dataPtr(new Grid3DPrivate) -{ -} - -///////////////////////////////////////////////// -Grid3D::~Grid3D() -{ -} - -///////////////////////////////////////////////// -void Grid3D::LoadConfig(const tinyxml2::XMLElement *_pluginElem) -{ - if (this->title.empty()) - this->title = "3D Grid"; - - // Configuration - if (_pluginElem) - { - // All grids managed belong to the same engine and scene - auto elem = _pluginElem->FirstChildElement("engine"); - if (nullptr != elem && nullptr != elem->GetText()) - this->dataPtr->engineName = elem->GetText(); - - elem = _pluginElem->FirstChildElement("scene"); - if (nullptr != elem && nullptr != elem->GetText()) - this->dataPtr->sceneName = elem->GetText(); - - // For grids to be inserted at startup - for (auto insertElem = _pluginElem->FirstChildElement("insert"); - insertElem != nullptr; - insertElem = insertElem->NextSiblingElement("insert")) - { - GridInfo gridInfo; - - if (auto cellCountElem = insertElem->FirstChildElement("cell_count")) - cellCountElem->QueryIntText(&gridInfo.cellCount); - - if (auto vElem = insertElem->FirstChildElement("vertical_cell_count")) - vElem->QueryIntText(&gridInfo.vertCellCount); - - if (auto lengthElem = insertElem->FirstChildElement("cell_length")) - lengthElem->QueryDoubleText(&gridInfo.cellLength); - - elem = insertElem->FirstChildElement("pose"); - if (nullptr != elem && nullptr != elem->GetText()) - { - std::stringstream poseStr; - poseStr << std::string(elem->GetText()); - poseStr >> gridInfo.pose; - } - - elem = insertElem->FirstChildElement("color"); - if (nullptr != elem && nullptr != elem->GetText()) - { - std::stringstream colorStr; - colorStr << std::string(elem->GetText()); - colorStr >> gridInfo.color; - } - - this->dataPtr->startupGrids.push_back(gridInfo); - } - } - - // TODO(anyone): remove - just for testing when inserting plugin - GridInfo gridInfo; - this->dataPtr->startupGrids.push_back(gridInfo); - - this->connect(this->PluginItem(), &QQuickItem::windowChanged, - [=](QQuickWindow *_window) - { - if (!_window) - { - igndbg << "Changed to null window" << std::endl; - return; - } - - this->dataPtr->quickWindow = _window; - - // Initialize after Scene3D plugins - this->connect(this->dataPtr->quickWindow, &QQuickWindow::beforeRendering, - this, &Grid3D::Initialize, Qt::DirectConnection); - }); -} - -///////////////////////////////////////////////// -void Grid3D::Initialize() -{ - // Render engine - auto loadedEngNames = rendering::loadedEngines(); - if (loadedEngNames.empty()) - { - // Keep trying until an engine is loaded - return; - } - - if (this->dataPtr->engineName.empty()) - { - this->dataPtr->engineName = loadedEngNames[0]; - } - - if (this->dataPtr->engineName != loadedEngNames[0]) - { - ignwarn << "Trying to load engine [" + this->dataPtr->engineName - + "] but [" + loadedEngNames[0] - + "] is already loaded." << std::endl; - - this->disconnect(this->dataPtr->quickWindow, &QQuickWindow::beforeRendering, - this, &Grid3D::Initialize); - - return; - } - - if (nullptr == this->dataPtr->engine) - this->dataPtr->engine = rendering::engine(this->dataPtr->engineName); - - if (nullptr == this->dataPtr->engine) - { - ignwarn << "Failed to get engine [" + this->dataPtr->engineName - + "]" << std::endl; - - this->disconnect(this->dataPtr->quickWindow, &QQuickWindow::beforeRendering, - this, &Grid3D::Initialize); - - return; - } - - if (this->dataPtr->engine->SceneCount() == 0) - { - // Scene may not be loaded yet, keep trying - return; - } - - // Scene - rendering::ScenePtr scene; - if (!this->dataPtr->sceneName.empty()) - { - scene = this->dataPtr->engine->SceneByName(this->dataPtr->sceneName); - } - else - { - scene = this->dataPtr->engine->SceneByIndex(0); - } - if (!scene) - { - // Scene may not be loaded yet, keep trying - return; - } - - auto root = scene->RootVisual(); - - // Initial grids - for (const auto &g : this->dataPtr->startupGrids) - { - auto grid = scene->CreateGrid(); - grid->SetCellCount(g.cellCount); - grid->SetVerticalCellCount(g.vertCellCount); - grid->SetCellLength(g.cellLength); - - auto gridVis = scene->CreateVisual(); - root->AddChild(gridVis); - gridVis->SetLocalPose(g.pose); - gridVis->AddGeometry(grid); - - auto mat = scene->CreateMaterial(); - mat->SetAmbient(g.color); - gridVis->SetMaterial(mat); - - igndbg << "Created grid [" << grid->Name() << "]" << std::endl; - } - - this->disconnect(this->dataPtr->quickWindow, &QQuickWindow::beforeRendering, - this, &Grid3D::Initialize); - - this->Refresh(); -} - -///////////////////////////////////////////////// -void Grid3D::Refresh() -{ -// auto mainLayout = this->layout(); -// // Clear previous layout -// if (mainLayout) -// { -// while (mainLayout->count() != 1) -// { -// auto item = mainLayout->takeAt(1); -// if (qobject_cast(item->widget())) -// { -// delete item->widget(); -// delete item; -// } -// } -// } -// // Creating layout for the first time -// else -// { -// mainLayout = new QVBoxLayout(); -// mainLayout->setContentsMargins(0, 0, 0, 0); -// mainLayout->setSpacing(0); -// this->setLayout(mainLayout); -// -// auto addButton = new QPushButton("New grid"); -// addButton->setObjectName("addGridButton"); -// addButton->setToolTip("Add a new grid with default values"); -// this->connect(addButton, SIGNAL(clicked()), this, SLOT(OnAdd())); -// -// auto refreshButton = new QPushButton("Refresh"); -// refreshButton->setObjectName("refreshGridButton"); -// refreshButton->setToolTip("Refresh the list of grids"); -// this->connect(refreshButton, SIGNAL(clicked()), this, SLOT(Refresh())); -// -// auto buttonsLayout = new QHBoxLayout(); -// buttonsLayout->addWidget(addButton); -// buttonsLayout->addWidget(refreshButton); -// -// auto buttonsWidget = new QWidget(); -// buttonsWidget->setLayout(buttonsLayout); -// -// mainLayout->addWidget(buttonsWidget); -// } -// -// auto scene = this->dataPtr->engine->SceneByName(this->dataPtr->sceneName); -// // Scene has been destroyed -// if (!scene) -// { -// // Delete buttons -// auto item = mainLayout->takeAt(0); -// if (item) -// { -// delete item->widget(); -// delete item; -// } -// -// // Add message -// auto msg = new QLabel(QString::fromStdString( -// "Scene \"" + this->dataPtr->sceneName + "\" has been destroyed.\n" -// + "Create a new scene and then open a new Grid plugin.")); -// mainLayout->addWidget(msg); -// mainLayout->setAlignment(msg, Qt::AlignCenter); -// return; -// } -// -// -// // Search for all grids currently in the scene -// this->dataPtr->grids.clear(); -// for (unsigned int i = 0; i < scene->VisualCount(); ++i) -// { -// auto vis = scene->VisualByIndex(i); -// if (!vis || vis->GeometryCount() == 0) -// continue; -// -// rendering::GridPtr grid; -// for (unsigned int j = 0; j < vis->GeometryCount(); ++j) -// { -// grid = std::dynamic_pointer_cast( -// vis->GeometryByIndex(j)); -// if (grid) -// break; -// } -// if (!grid) -// continue; -// -// this->dataPtr->grids.push_back(grid); -// auto gridName = QString::fromStdString(grid->Name()); -// -// auto cellCountWidget = new NumberWidget("Horizontal cell count", -// NumberType::UINT); -// cellCountWidget->SetValue(QVariant::fromValue(grid->CellCount())); -// cellCountWidget->setProperty("gridName", gridName); -// cellCountWidget->setObjectName("cellCountWidget"); -// this->connect(cellCountWidget, SIGNAL(ValueChanged(QVariant)), this, -// SLOT(OnChange(QVariant))); -// -// auto vertCellCountWidget = new NumberWidget("Vertical cell count", -// NumberType::UINT); -// vertCellCountWidget->SetValue( -// QVariant::fromValue(grid->VerticalCellCount())); -// vertCellCountWidget->setProperty("gridName", gridName); -// vertCellCountWidget->setObjectName("vertCellCountWidget"); -// this->connect(vertCellCountWidget, SIGNAL(ValueChanged(QVariant)), this, -// SLOT(OnChange(QVariant))); -// -// auto cellLengthWidget = new NumberWidget("Cell length", -// NumberType::DOUBLE); -// cellLengthWidget->SetValue(QVariant::fromValue(grid->CellLength())); -// cellLengthWidget->setProperty("gridName", gridName); -// cellLengthWidget->setObjectName("cellLengthWidget"); -// this->connect(cellLengthWidget, SIGNAL(ValueChanged(QVariant)), this, -// SLOT(OnChange(QVariant))); -// -// auto poseWidget = new Pose3dWidget(); -// poseWidget->SetValue(QVariant::fromValue(grid->Parent()->WorldPose())); -// poseWidget->setProperty("gridName", gridName); -// poseWidget->setObjectName("poseWidget"); -// this->connect(poseWidget, SIGNAL(ValueChanged(QVariant)), this, -// SLOT(OnChange(QVariant))); -// -// auto colorWidget = new ColorWidget(); -// colorWidget->SetValue(QVariant::fromValue(grid->Material()->Ambient())); -// colorWidget->setProperty("gridName", gridName); -// colorWidget->setObjectName("colorWidget"); -// this->connect(colorWidget, SIGNAL(ValueChanged(QVariant)), this, -// SLOT(OnChange(QVariant))); -// -// auto deleteButton = new QPushButton("Delete grid"); -// deleteButton->setToolTip("Delete grid " + gridName); -// deleteButton->setProperty("gridName", gridName); -// deleteButton->setObjectName("deleteButton"); -// this->connect(deleteButton, SIGNAL(clicked()), this, SLOT(OnDelete())); -// -// auto collapsible = new CollapsibleWidget(grid->Name()); -// collapsible->AppendContent(cellCountWidget); -// collapsible->AppendContent(vertCellCountWidget); -// collapsible->AppendContent(cellLengthWidget); -// collapsible->AppendContent(poseWidget); -// collapsible->AppendContent(colorWidget); -// collapsible->AppendContent(deleteButton); -// -// mainLayout->addWidget(collapsible); -// } -// -// auto spacer = new QWidget(); -// spacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); -// mainLayout->addWidget(spacer); -} - -///////////////////////////////////////////////// -void Grid3D::OnChange(const QVariant & /*_value*/) -{ -// auto gridName = -// this->sender()->property("gridName").toString().toStdString(); -// auto type = this->sender()->objectName().toStdString(); -// -// for (auto grid : this->dataPtr->grids) -// { -// if (grid->Name() != gridName) -// continue; -// -// if (type == "cellCountWidget") -// grid->SetCellCount(_value.toInt()); -// else if (type == "vertCellCountWidget") -// grid->SetVerticalCellCount(_value.toInt()); -// else if (type == "cellLengthWidget") -// grid->SetCellLength(_value.toDouble()); -// else if (type == "poseWidget") -// grid->Parent()->SetWorldPose(_value.value()); -// else if (type == "colorWidget") -// grid->Material()->SetAmbient(_value.value()); -// -// break; -// } -} - -///////////////////////////////////////////////// -void Grid3D::OnDelete() -{ -// auto gridName = -// this->sender()->property("gridName").toString().toStdString(); -// -// for (auto grid : this->dataPtr->grids) -// { -// if (grid->Name() != gridName) -// continue; -// -// grid->Scene()->DestroyVisual(grid->Parent()); -// this->dataPtr->grids.erase(std::remove(this->dataPtr->grids.begin(), -// this->dataPtr->grids.end(), grid), -// this->dataPtr->grids.end()); -// -// this->Refresh(); -// break; -// } -} - -///////////////////////////////////////////////// -void Grid3D::OnAdd() -{ -// auto scene = this->dataPtr->engine->SceneByName(this->dataPtr->sceneName); -// if (!scene) -// { -// return; -// } -// -// auto root = scene->RootVisual(); -// -// auto grid = scene->CreateGrid(); -// grid->SetCellCount(kDefaultCellCount); -// grid->SetVerticalCellCount(kDefaultVertCellCount); -// grid->SetCellLength(kDefaultCellLength); -// -// auto gridVis = scene->CreateVisual(); -// root->AddChild(gridVis); -// gridVis->SetLocalPose(kDefaultPose); -// gridVis->AddGeometry(grid); -// -// auto mat = scene->CreateMaterial(); -// mat->SetAmbient(kDefaultColor); -// gridVis->SetMaterial(mat); -// -// this->Refresh(); -} - -// Register this plugin -IGNITION_ADD_PLUGIN(ignition::gui::plugins::Grid3D, - ignition::gui::Plugin) - diff --git a/src/plugins/grid_3d/Grid3D.hh b/src/plugins/grid_3d/Grid3D.hh deleted file mode 100644 index 41464dfc2..000000000 --- a/src/plugins/grid_3d/Grid3D.hh +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (C) 2017 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 IGNITION_GUI_PLUGINS_GRID3D_HH_ -#define IGNITION_GUI_PLUGINS_GRID3D_HH_ - -#include - -#include "ignition/gui/qt.h" -#include "ignition/gui/Plugin.hh" - -namespace ignition -{ -namespace gui -{ -namespace plugins -{ - class Grid3DPrivate; - - /// \brief Manages grids in an Ignition Rendering scene. This plugin can be - /// used for: - /// * Adding grids - /// * Introspecting grids - /// * Editing grids - /// * Deleting grids - /// - /// ## Configuration - /// - /// * \ : Optional render engine name, defaults to the first loaded - /// engine. - /// * \ : Optional scene name, defaults to the first loaded scene. - /// * \ : Set to true so the plugin closes after grids given by - /// \ tags are added to the scene. - /// * \ : One grid will be inserted at startup for each \ - /// tag. - /// * \ : Number of cells in the horizontal direction, defaults - /// to 20. - /// * \ : Number of cells in the vertical direction, - /// defaults to 0; - /// * \ : Length of each cell, defaults to 1. - /// * \ : Grid pose, defaults to the origin. - /// * \ : Grid color, defaults to (0.7, 0.7, 0.7, 1.0) - class Grid3D : public Plugin - { - Q_OBJECT - - /// \brief Constructor - public: Grid3D(); - - /// \brief Destructor - public: virtual ~Grid3D(); - - // Documentation inherited - public: virtual void LoadConfig(const tinyxml2::XMLElement *_pluginElem) - override; - - private slots: void Initialize(); - - /// \brief Called when a value changes on a widget - /// \param[in] _value New value - private slots: void OnChange(const QVariant &_value); - - /// \brief Callback when a delete button is pressed. - private slots: void OnDelete(); - - /// \brief Callback when the add button is pressed. - private slots: void OnAdd(); - - /// \brief Callback when the refresh button is pressed. - private slots: void Refresh(); - - /// \internal - /// \brief Pointer to private data. - private: std::unique_ptr dataPtr; - }; -} -} -} - -#endif diff --git a/src/plugins/grid_3d/Grid3D.qml b/src/plugins/grid_3d/Grid3D.qml deleted file mode 100644 index 1603eae1d..000000000 --- a/src/plugins/grid_3d/Grid3D.qml +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (C) 2018 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. - * -*/ -import QtQuick 2.0 -import QtQuick.Controls 2.0 -import QtQuick.Layouts 1.3 - -Rectangle { - Layout.minimumWidth: 100 - Layout.minimumHeight: 100 -} - - diff --git a/src/plugins/grid_3d/Grid3D.qrc b/src/plugins/grid_3d/Grid3D.qrc deleted file mode 100644 index be3a0d9c3..000000000 --- a/src/plugins/grid_3d/Grid3D.qrc +++ /dev/null @@ -1,5 +0,0 @@ - - - Grid3D.qml - - diff --git a/src/plugins/grid_3d/Grid3D_TEST.cc b/src/plugins/grid_3d/Grid3D_TEST.cc deleted file mode 100644 index 818bb35e3..000000000 --- a/src/plugins/grid_3d/Grid3D_TEST.cc +++ /dev/null @@ -1,291 +0,0 @@ -/* - * Copyright (C) 2017 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 -#include -#include - -#include "ignition/gui/CollapsibleWidget.hh" -#include "ignition/gui/ColorWidget.hh" -#include "ignition/gui/Helpers.hh" -#include "ignition/gui/Iface.hh" -#include "ignition/gui/MainWindow.hh" -#include "ignition/gui/NumberWidget.hh" -#include "ignition/gui/Pose3dWidget.hh" -#include "ignition/gui/Plugin.hh" -#include "ignition/gui/QtMetatypes.hh" - -using namespace ignition; -using namespace gui; - -///////////////////////////////////////////////// -TEST(Grid3DTest, WithoutScene) -{ - setVerbosity(4); - EXPECT_TRUE(initApp()); - - // Load Grid3D without Scene3D - EXPECT_TRUE(loadPlugin("Grid3D")); - - // Create main window - EXPECT_TRUE(createMainWindow()); - - // Check there is no scene - auto engine = rendering::engine("ogre"); - ASSERT_NE(nullptr, engine); - - EXPECT_EQ(0u, engine->SceneCount()); - - EXPECT_TRUE(stop()); -} - -///////////////////////////////////////////////// -TEST(Grid3DTest, CRUD) -{ - setVerbosity(4); - EXPECT_TRUE(initApp()); - - // Load Scene3D before Grid3D - EXPECT_TRUE(loadPlugin("Scene3D")); - - // Load plugin - const char *pluginStr = - "" - "ogre" - "scene" - "" - "5" - "3.5" - "3" - "1 0 0 0 0 0" - "0 0 1 1" - "" - ""; - - tinyxml2::XMLDocument pluginDoc; - pluginDoc.Parse(pluginStr); - EXPECT_TRUE(ignition::gui::loadPlugin("Grid3D", - pluginDoc.FirstChildElement("plugin"))); - - // Create main window - EXPECT_TRUE(createMainWindow()); - - // Check scene - auto engine = rendering::engine("ogre"); - ASSERT_NE(nullptr, engine); - - auto scene = engine->SceneByName("scene"); - ASSERT_NE(nullptr, scene); - - // 2 children: camera and grid - EXPECT_EQ(1u, scene->VisualCount()); - EXPECT_EQ(1u, scene->VisualByIndex(0)->GeometryCount()); - - // Check grid - auto grid = std::dynamic_pointer_cast( - scene->VisualByIndex(0)->GeometryByIndex(0)); - ASSERT_NE(nullptr, grid); - - EXPECT_EQ(5u, grid->CellCount()); - EXPECT_EQ(3u, grid->VerticalCellCount()); - EXPECT_DOUBLE_EQ(3.5, grid->CellLength()); - EXPECT_EQ(math::Pose3d(1, 0, 0, 0, 0, 0), grid->Parent()->WorldPose()); - EXPECT_EQ(math::Color::Blue, grid->Material()->Ambient()); - - // Edit grid - auto win = mainWindow(); - ASSERT_NE(nullptr, win); - - // Cell count - { - auto name = QString::fromStdString("cellCountWidget"); - auto w = win->findChild(name); - ASSERT_NE(nullptr, w); - EXPECT_EQ(5, w->Value().toInt()); - w->ValueChanged(10); - QCoreApplication::processEvents(); - EXPECT_EQ(10u, grid->CellCount()); - } - - // Vertical cell count - { - auto name = QString::fromStdString("vertCellCountWidget"); - auto w = win->findChild(name); - ASSERT_NE(nullptr, w); - EXPECT_EQ(3, w->Value().toInt()); - w->ValueChanged(8); - QCoreApplication::processEvents(); - EXPECT_EQ(8u, grid->VerticalCellCount()); - } - - // Cell length - { - auto name = QString::fromStdString("cellLengthWidget"); - auto w = win->findChild(name); - ASSERT_NE(nullptr, w); - EXPECT_DOUBLE_EQ(3.5, w->Value().toDouble()); - w->ValueChanged(0.2); - QCoreApplication::processEvents(); - EXPECT_DOUBLE_EQ(0.2, grid->CellLength()); - } - - // Pose - { - auto name = QString::fromStdString("poseWidget"); - auto w = win->findChild(name); - ASSERT_NE(nullptr, w); - EXPECT_EQ(math::Pose3d(1, 0, 0, 0, 0, 0), w->Value().value()); - w->ValueChanged(QVariant::fromValue(math::Pose3d(0, 0, 1, 0, 0, 0))); - QCoreApplication::processEvents(); - EXPECT_EQ(math::Pose3d(0, 0, 1, 0, 0, 0), grid->Parent()->WorldPose()); - } - - // Color - { - auto name = QString::fromStdString("colorWidget"); - auto w = win->findChild(name); - ASSERT_NE(nullptr, w); - EXPECT_EQ(math::Color::Blue, w->Value().value()); - w->ValueChanged(QVariant::fromValue(math::Color::Cyan)); - QCoreApplication::processEvents(); - EXPECT_EQ(math::Color::Cyan, grid->Material()->Ambient()); - } - - // Add a new grid via GUI - { - // Click button - auto addButton = win->findChild("addGridButton"); - ASSERT_NE(nullptr, addButton); - addButton->click(); - - // Check there is a new grid - EXPECT_EQ(2u, scene->VisualCount()); - - // Check the old grid was moved to index 1 - EXPECT_EQ(grid, scene->VisualByIndex(1)->GeometryByIndex(0)); - - // Check new grid has the default values - EXPECT_EQ(1u, scene->VisualByIndex(0)->GeometryCount()); - auto grid2 = std::dynamic_pointer_cast( - scene->VisualByIndex(0)->GeometryByIndex(0)); - ASSERT_NE(nullptr, grid2); - - EXPECT_EQ(20u, grid2->CellCount()); - EXPECT_EQ(0u, grid2->VerticalCellCount()); - EXPECT_DOUBLE_EQ(1.0, grid2->CellLength()); - EXPECT_EQ(math::Pose3d::Zero, grid2->Parent()->WorldPose()); - EXPECT_EQ(math::Color(0.7, 0.7, 0.7, 1.0), grid2->Material()->Ambient()); - } - - // Add a new grid programmatically and refresh - { - // Add grid - auto grid3 = scene->CreateGrid(); - grid3->SetCellCount(66); - grid3->SetVerticalCellCount(8); - grid3->SetCellLength(2.6); - - auto grid3Vis = scene->CreateVisual(); - scene->RootVisual()->AddChild(grid3Vis); - grid3Vis->SetLocalPose(math::Pose3d(1, 2, 3, 0, 0, 0)); - grid3Vis->AddGeometry(grid3); - - auto mat = scene->CreateMaterial(); - mat->SetAmbient(math::Color(0.1, 0.2, 0.3)); - grid3Vis->SetMaterial(mat); - - EXPECT_EQ(3u, scene->VisualCount()); - - // Click button - auto refreshButton = win->findChild("refreshGridButton"); - ASSERT_NE(nullptr, refreshButton); - refreshButton->click(); - - // Check we now have 3 collapsibles - auto collapsibles = win->findChildren(); - EXPECT_EQ(3, collapsibles.size()); - - auto gridName = QVariant(QString::fromStdString(grid3->Name())); - - // Cell count - { - auto name = QString::fromStdString("cellCountWidget"); - auto w = findFirstByProperty(win->findChildren(name), - "gridName", gridName); - ASSERT_NE(nullptr, w); - EXPECT_EQ(66, w->Value().toInt()); - } - - // Vertical cell count - { - auto name = QString::fromStdString( - "vertCellCountWidget"); - auto w = findFirstByProperty(win->findChildren(name), - "gridName", gridName); - ASSERT_NE(nullptr, w); - EXPECT_EQ(8, w->Value().toInt()); - } - - // Cell length - { - auto name = QString::fromStdString("cellLengthWidget"); - auto w = findFirstByProperty(win->findChildren(name), - "gridName", gridName); - ASSERT_NE(nullptr, w); - EXPECT_DOUBLE_EQ(2.6, w->Value().toDouble()); - } - - // Pose - { - auto name = QString::fromStdString("poseWidget"); - auto w = findFirstByProperty(win->findChildren(name), - "gridName", gridName); - ASSERT_NE(nullptr, w); - EXPECT_EQ(math::Pose3d(1, 2, 3, 0, 0, 0), - w->Value().value()); - } - - // Color - { - auto name = QString::fromStdString("colorWidget"); - auto w = findFirstByProperty(win->findChildren(name), - "gridName", gridName); - ASSERT_NE(nullptr, w); - EXPECT_EQ(math::Color(0.1, 0.2, 0.3), w->Value().value()); - } - } - - // Delete a grid - { - auto gridName = QVariant(QString::fromStdString(grid->Name())); - auto name = QString::fromStdString("deleteButton"); - auto w = findFirstByProperty(win->findChildren(name), - "gridName", gridName); - ASSERT_NE(nullptr, w); - - w->click(); - - // Check scene - EXPECT_EQ(2u, scene->VisualCount()); - - // Check widgets - EXPECT_EQ(2, win->findChildren().size()); - } - - EXPECT_TRUE(stop()); -} - diff --git a/src/plugins/grid_config/CMakeLists.txt b/src/plugins/grid_config/CMakeLists.txt index f52674fd0..ed0dbd97e 100644 --- a/src/plugins/grid_config/CMakeLists.txt +++ b/src/plugins/grid_config/CMakeLists.txt @@ -6,3 +6,7 @@ ign_gui_add_plugin(GridConfig PUBLIC_LINK_LIBS ${IGNITION-RENDERING_LIBRARIES} ) + +# Also install as Grid3D, which was a legacy plugin with a subset of features +set_target_properties(GridConfig PROPERTIES OUTPUT_NAME Grid3D) +install (TARGETS GridConfig DESTINATION ${IGNITION_GUI_PLUGIN_INSTALL_DIR}) From 51d59df25edd4e5e50e60dfa4c24f0f171e5345a Mon Sep 17 00:00:00 2001 From: Louise Poubel Date: Mon, 6 Dec 2021 22:18:23 -0800 Subject: [PATCH 6/7] codecheck Signed-off-by: Louise Poubel --- src/plugins/grid_config/GridConfig.cc | 10 +++++++--- src/plugins/marker_manager/MarkerManager.cc | 2 +- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/plugins/grid_config/GridConfig.cc b/src/plugins/grid_config/GridConfig.cc index fa502b48e..42e7142b2 100644 --- a/src/plugins/grid_config/GridConfig.cc +++ b/src/plugins/grid_config/GridConfig.cc @@ -16,6 +16,7 @@ */ #include +#include #include #include @@ -108,13 +109,16 @@ void GridConfig::LoadConfig(const tinyxml2::XMLElement *_pluginElem) { GridParam gridParam; - // Both cell_count and horizontal_cell_count apply to horizontal for backwards - // compatibility + // Both cell_count and horizontal_cell_count apply to horizontal for + // backwards compatibility if (auto cellCountElem = insertElem->FirstChildElement("cell_count")) cellCountElem->QueryIntText(&gridParam.hCellCount); - if (auto cellCountElem = insertElem->FirstChildElement("horizontal_cell_count")) + if (auto cellCountElem = insertElem->FirstChildElement( + "horizontal_cell_count")) + { cellCountElem->QueryIntText(&gridParam.hCellCount); + } if (auto vElem = insertElem->FirstChildElement("vertical_cell_count")) vElem->QueryIntText(&gridParam.vCellCount); diff --git a/src/plugins/marker_manager/MarkerManager.cc b/src/plugins/marker_manager/MarkerManager.cc index 638860364..615e915c9 100644 --- a/src/plugins/marker_manager/MarkerManager.cc +++ b/src/plugins/marker_manager/MarkerManager.cc @@ -412,7 +412,7 @@ bool MarkerManagerPrivate::ProcessMarkerMsg(const ignition::msgs::Marker &_msg) { if (this->warnOnActionFailure) { - ignwarn << "Unable to delete all markers in namespace[" << ns + ignwarn << "Unable to delete all markers in namespace[" << ns << "], namespace can't be found." << std::endl; } return false; From e144763162f0edca11b60a2c41125b1dae2d9d57 Mon Sep 17 00:00:00 2001 From: Louise Poubel Date: Tue, 7 Dec 2021 15:27:05 -0800 Subject: [PATCH 7/7] fix install Signed-off-by: Louise Poubel --- src/plugins/grid_config/CMakeLists.txt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/plugins/grid_config/CMakeLists.txt b/src/plugins/grid_config/CMakeLists.txt index ed0dbd97e..a17616363 100644 --- a/src/plugins/grid_config/CMakeLists.txt +++ b/src/plugins/grid_config/CMakeLists.txt @@ -8,5 +8,7 @@ ign_gui_add_plugin(GridConfig ) # Also install as Grid3D, which was a legacy plugin with a subset of features -set_target_properties(GridConfig PROPERTIES OUTPUT_NAME Grid3D) -install (TARGETS GridConfig DESTINATION ${IGNITION_GUI_PLUGIN_INSTALL_DIR}) +install ( + FILES $ + RENAME ${CMAKE_SHARED_LIBRARY_PREFIX}Grid3D${CMAKE_SHARED_LIBRARY_SUFFIX} + DESTINATION ${IGNITION_GUI_PLUGIN_INSTALL_DIR})