From d4dbf98dedc29b177207ecdd245f93135d77e844 Mon Sep 17 00:00:00 2001 From: Steve Peters Date: Fri, 11 Feb 2022 12:28:54 -0800 Subject: [PATCH 1/3] Scene: support deletion of Heightmap Visuals (#3171) A Heightmap visual still appears in gzclient even when its corresponding Visual is removed using Scene::RemoveVisual, as reported in Issue #3159. This change stores the visual Id associated with the Ogre terrain object, and deletes the terrain when that visual Id is passed to Scene::RemoveVisual. The Scene::ProcessVisualMsg method was refactored to use a more consistent code path for visuals with heightmaps and avoid duplicate code. Signed-off-by: Steve Peters --- gazebo/rendering/Scene.cc | 117 ++++++++++++++++++------------- gazebo/rendering/ScenePrivate.hh | 4 ++ 2 files changed, 72 insertions(+), 49 deletions(-) diff --git a/gazebo/rendering/Scene.cc b/gazebo/rendering/Scene.cc index 552d33e102..27bf38ff1e 100644 --- a/gazebo/rendering/Scene.cc +++ b/gazebo/rendering/Scene.cc @@ -300,6 +300,7 @@ void Scene::Clear() delete this->dataPtr->terrain; this->dataPtr->terrain = NULL; + this->dataPtr->terrainVisualId.reset(); while (!this->dataPtr->visuals.empty()) this->RemoveVisual(this->dataPtr->visuals.begin()->first); @@ -2825,54 +2826,6 @@ bool Scene::ProcessVisualMsg(ConstVisualPtr &_msg, Visual::VisualType _type) return true; } - // Creating heightmap - // FIXME: A bit of a hack. - if (_msg->has_geometry() && - _msg->geometry().type() == msgs::Geometry::HEIGHTMAP && - _type != Visual::VT_COLLISION) - { - if (this->dataPtr->terrain) - { - // Only one Heightmap can be created per Scene - return true; - } - else - { - if (!this->dataPtr->terrain) - { - // create a dummy visual for loading heightmap visual plugin - // TODO make heightmap a visual to avoid special treatment here? - VisualPtr visual(new Visual(_msg->name(), this->dataPtr->worldVisual)); - auto m = *_msg.get(); - m.clear_material(); - visual->Load(msgs::VisualToSDF(m)); - - this->dataPtr->terrain = new Heightmap(shared_from_this()); - // check the material fields and set material if it is specified - if (_msg->has_material()) - { - auto matMsg = _msg->material(); - if (matMsg.has_script()) - { - auto scriptMsg = matMsg.script(); - for (auto const &uri : scriptMsg.uri()) - { - if (!uri.empty()) - RenderEngine::Instance()->AddResourcePath(uri); - } - std::string matName = scriptMsg.name(); - this->dataPtr->terrain->SetMaterial(matName); - } - } - this->dataPtr->terrain->SetLOD(this->dataPtr->heightmapLOD); - const double skirtLen = this->dataPtr->heightmapSkirtLength; - this->dataPtr->terrain->SetSkirtLength(skirtLen); - this->dataPtr->terrain->LoadFromMsg(_msg); - } - } - return true; - } - // Creating collision if (_type == Visual::VT_COLLISION) { @@ -2897,6 +2850,20 @@ bool Scene::ProcessVisualMsg(ConstVisualPtr &_msg, Visual::VisualType _type) return true; } + // Exit early if a heightmap already exists + bool hasHeightmap = false; + if (_msg->has_geometry() && + _msg->geometry().type() == msgs::Geometry::HEIGHTMAP) + { + hasHeightmap = true; + if (this->dataPtr->terrain) + { + // Only one Heightmap can be created per Scene + return true; + } + } + + // All other visuals VisualPtr visual; @@ -2924,7 +2891,51 @@ bool Scene::ProcessVisualMsg(ConstVisualPtr &_msg, Visual::VisualType _type) if (_msg->has_id()) visual->SetId(_msg->id()); - visual->LoadFromMsg(_msg); + if (!hasHeightmap) + { + visual->LoadFromMsg(_msg); + } + else + // Creating heightmap + // FIXME: A bit of a hack. + { + { + // Copy the const _msg so that we can clear materials before + // loading from message + msgs::Visual *msgMutable = new msgs::Visual(*_msg.get()); + msgMutable->clear_material(); + + // assign ownership of the copy to a const shared_ptr so it will be + // deleted when exiting this scope + ConstVisualPtr msgShared(static_cast(msgMutable)); + visual->LoadFromMsg(msgShared); + } + + // Store VisualId corresponding to terrain + this->dataPtr->terrainVisualId.emplace(visual->GetId()); + + this->dataPtr->terrain = new Heightmap(shared_from_this()); + // check the material fields and set material if it is specified + if (_msg->has_material()) + { + auto matMsg = _msg->material(); + if (matMsg.has_script()) + { + auto scriptMsg = matMsg.script(); + for (auto const &uri : scriptMsg.uri()) + { + if (!uri.empty()) + RenderEngine::Instance()->AddResourcePath(uri); + } + std::string matName = scriptMsg.name(); + this->dataPtr->terrain->SetMaterial(matName); + } + } + this->dataPtr->terrain->SetLOD(this->dataPtr->heightmapLOD); + const double skirtLen = this->dataPtr->heightmapSkirtLength; + this->dataPtr->terrain->SetSkirtLength(skirtLen); + this->dataPtr->terrain->LoadFromMsg(_msg); + } visual->SetType(_type); this->dataPtr->visuals[visual->GetId()] = visual; @@ -3407,6 +3418,14 @@ void Scene::RemoveVisual(uint32_t _id) if (iter != this->dataPtr->visuals.end()) { VisualPtr vis = iter->second; + // Remove the terrain object if this is the heightmap visual + if (this->dataPtr->terrainVisualId && + *this->dataPtr->terrainVisualId == _id) + { + delete this->dataPtr->terrain; + this->dataPtr->terrain = NULL; + this->dataPtr->terrainVisualId.reset(); + } // Remove all projectors attached to the visual auto piter = this->dataPtr->projectors.begin(); while (piter != this->dataPtr->projectors.end()) diff --git a/gazebo/rendering/ScenePrivate.hh b/gazebo/rendering/ScenePrivate.hh index 7ed79b5c7b..7aa31ee9d5 100644 --- a/gazebo/rendering/ScenePrivate.hh +++ b/gazebo/rendering/ScenePrivate.hh @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -309,6 +310,9 @@ namespace gazebo /// \brief True if this scene is running on the server. public: bool isServer; + /// \brief Terrain Visual Id. + public: std::optional terrainVisualId; + /// \brief The heightmap, if any. public: Heightmap *terrain = nullptr; From 5d924049050190486d0181bbb4b674dc421d0d0e Mon Sep 17 00:00:00 2001 From: Silvio Traversaro Date: Wed, 16 Feb 2022 00:28:42 +0100 Subject: [PATCH 2/3] SearchForStuff: Do not pass /usr/lib to PATH in qwt's find_library (#3178) --- cmake/SearchForStuff.cmake | 1 - 1 file changed, 1 deletion(-) diff --git a/cmake/SearchForStuff.cmake b/cmake/SearchForStuff.cmake index 9777a46dca..a78ce0dc52 100644 --- a/cmake/SearchForStuff.cmake +++ b/cmake/SearchForStuff.cmake @@ -845,7 +845,6 @@ find_path(QWT_INCLUDE_DIR NAMES qwt.h PATHS ) find_library(QWT_LIBRARY NAMES qwt-qt5 qwt PATHS - /usr/lib /usr/local/lib /usr/local/lib/qwt.framework ${QWT_WIN_LIBRARY_DIR} From 34ebf4e4ee48d1a4e4f08d2f76fdb0a471717019 Mon Sep 17 00:00:00 2001 From: Silvio Traversaro Date: Sun, 6 Mar 2022 08:33:56 +0100 Subject: [PATCH 3/3] Add CI for compiling gazebo with conda-forge dependencies (#3186) --- .github/workflows/conda-forge.yml | 104 ++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 .github/workflows/conda-forge.yml diff --git a/.github/workflows/conda-forge.yml b/.github/workflows/conda-forge.yml new file mode 100644 index 0000000000..e47287214f --- /dev/null +++ b/.github/workflows/conda-forge.yml @@ -0,0 +1,104 @@ +name: C++ CI Workflow with conda-forge dependencies + +on: + push: + branches: + - gazebo11 + pull_request: + schedule: + # * is a special character in YAML so you have to quote this string + # Execute a "nightly" build at 2 AM UTC + - cron: '0 2 * * *' + +jobs: + build: + name: '[${{ matrix.os }}@${{ matrix.build_type }}@conda]' + runs-on: ${{ matrix.os }} + strategy: + matrix: + build_type: [Release] + os: [ubuntu-latest, windows-2019, macos-latest] + fail-fast: false + + steps: + - uses: actions/checkout@v2 + + - uses: conda-incubator/setup-miniconda@v2 + with: + mamba-version: "*" + channels: conda-forge + channel-priority: true + + - name: Dependencies + shell: bash -l {0} + run: | + # Workaround for https://github.com/conda-incubator/setup-miniconda/issues/186 + conda config --remove channels defaults + # Compilation related dependencies + mamba install cmake compilers make ninja pkg-config + # Actual dependencies + mamba install libprotobuf libsdformat libignition-cmake2 libignition-math6 libignition-transport8 libignition-common3 libignition-fuel-tools4 qt=5.12.9=*_4 ogre=1.10 freeimage curl tbb-devel=2020 qwt tinyxml2 libccd boost-cpp libcurl tinyxml bzip2 zlib ffmpeg graphviz libgdal libusb bullet-cpp dartsim simbody hdf5 openal-soft glib gts + + - name: Linux-only Dependencies [Linux] + if: contains(matrix.os, 'ubuntu') + shell: bash -l {0} + run: | + # See https://github.com/robotology/robotology-superbuild/issues/477 + mamba install expat-cos6-x86_64 libselinux-cos6-x86_64 libxau-cos6-x86_64 libxcb-cos6-x86_64 libxdamage-cos6-x86_64 libxext-cos6-x86_64 libxfixes-cos6-x86_64 libxxf86vm-cos6-x86_64 mesalib mesa-libgl-cos6-x86_64 mesa-libgl-devel-cos6-x86_64 libuuid + + - name: Unix-only Dependencies [Linux&macOS] + if: contains(matrix.os, 'ubuntu') || contains(matrix.os, 'macos') + shell: bash -l {0} + run: | + mamba install libtar + + - name: Windows-only Dependencies [Windows] + if: contains(matrix.os, 'windows') + shell: bash -l {0} + run: | + # Compilation related dependencies + mamba install vs2019_win-64 dlfcn-win32 tiny-process-library + + - name: Configure [Linux&macOS] + if: contains(matrix.os, 'macos') || contains(matrix.os, 'ubuntu') + shell: bash -l {0} + run: | + mkdir -p build + cd build + cmake -GNinja -DBUILD_TESTING:BOOL=OFF -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} .. + + - name: Build [Linux&macOS] + if: contains(matrix.os, 'macos') || contains(matrix.os, 'ubuntu') + shell: bash -l {0} + run: | + cd build + cmake --build . --config ${{ matrix.build_type }} + +# - name: Test [Linux&macOS] +# if: contains(matrix.os, 'macos') || contains(matrix.os, 'ubuntu') +# shell: bash -l {0} +# run: | +# cd build +# ctest --output-on-failure -C ${{ matrix.build_type }} + + - name: Configure [Windows] + if: contains(matrix.os, 'windows') + shell: cmd /C call {0} + run: | + mkdir -p build + cd build + cmake -GNinja -DBUILD_TESTING:BOOL=OFF -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} .. + + - name: Build [Windows] + if: contains(matrix.os, 'windows') + shell: cmd /C call {0} + run: | + cd build + cmake --build . --config ${{ matrix.build_type }} --parallel 2 + +# - name: Test [Windows] +# if: contains(matrix.os, 'windows') +# shell: cmd /C call {0} +# run: | +# cd build +# ctest --output-on-failure -C ${{ matrix.build_type }}