Skip to content

Commit 3a33c32

Browse files
committedJun 5, 2024·
merge from gz-sim8
Signed-off-by: Ian Chen <ichen@openrobotics.org>
2 parents 6f46876 + 9e60fdc commit 3a33c32

File tree

5 files changed

+109
-80
lines changed

5 files changed

+109
-80
lines changed
 

‎CMakeLists.txt

+3
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,9 @@ cmake_dependent_option(USE_DIST_PACKAGES_FOR_PYTHON
6565
# Search for project-specific dependencies
6666
#============================================================================
6767

68+
# Setting this policy enables using the protobuf_MODULE_COMPATIBLE
69+
# set command when cmake_minimum_required is less than 3.13
70+
set(CMAKE_POLICY_DEFAULT_CMP0077 NEW)
6871
# This option is needed to use the PROTOBUF_GENERATE_CPP
6972
# in case protobuf is found with the CMake config files
7073
# It needs to be set before any find_package(...) call

‎include/gz/sim/Util.hh

+7
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,13 @@ namespace gz
316316
/// \return The loaded mesh or null if the mesh can not be loaded.
317317
GZ_SIM_VISIBLE const common::Mesh *loadMesh(const sdf::Mesh &_meshSdf);
318318

319+
/// \brief Optimize input mesh.
320+
/// \param[in] _meshSdf Mesh SDF DOM with mesh optimization parameters
321+
/// \param[in] _mesh Input mesh to optimize.
322+
/// \return The optimized mesh or null if the mesh can not be optimized.
323+
GZ_SIM_VISIBLE const common::Mesh *optimizeMesh(const sdf::Mesh &_meshSdf,
324+
const common::Mesh &_mesh);
325+
319326
/// \brief Environment variable holding resource paths.
320327
const std::string kResourcePathEnv{"GZ_SIM_RESOURCE_PATH"};
321328

‎src/Util.cc

+78
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,17 @@
1515
*
1616
*/
1717

18+
#include <cstddef>
19+
#include <string>
20+
#include <vector>
21+
1822
#include <gz/msgs/entity.pb.h>
1923

2024
#include <gz/common/Filesystem.hh>
2125
#include <gz/common/Mesh.hh>
2226
#include <gz/common/MeshManager.hh>
2327
#include <gz/common/StringUtils.hh>
28+
#include <gz/common/SubMesh.hh>
2429
#include <gz/common/URI.hh>
2530
#include <gz/common/Util.hh>
2631
#include <gz/math/Helpers.hh>
@@ -862,8 +867,81 @@ const common::Mesh *loadMesh(const sdf::Mesh &_meshSdf)
862867
<< "]." << std::endl;
863868
return nullptr;
864869
}
870+
871+
if (mesh && _meshSdf.Optimization() != sdf::MeshOptimization::NONE)
872+
{
873+
const common::Mesh *optimizedMesh = optimizeMesh(_meshSdf, *mesh);
874+
if (optimizedMesh)
875+
return optimizedMesh;
876+
else
877+
gzwarn << "Failed to optimize Mesh " << mesh->Name() << std::endl;
878+
}
879+
865880
return mesh;
866881
}
882+
883+
const common::Mesh *optimizeMesh(const sdf::Mesh &_meshSdf,
884+
const common::Mesh &_mesh)
885+
{
886+
if (_meshSdf.Optimization() !=
887+
sdf::MeshOptimization::CONVEX_DECOMPOSITION &&
888+
_meshSdf.Optimization() !=
889+
sdf::MeshOptimization::CONVEX_HULL)
890+
return nullptr;
891+
892+
auto &meshManager = *common::MeshManager::Instance();
893+
std::size_t maxConvexHulls = 16u;
894+
if (_meshSdf.Optimization() == sdf::MeshOptimization::CONVEX_HULL)
895+
{
896+
/// create 1 convex hull for the whole submesh
897+
maxConvexHulls = 1u;
898+
}
899+
else if (_meshSdf.ConvexDecomposition())
900+
{
901+
// limit max number of convex hulls to generate
902+
maxConvexHulls = _meshSdf.ConvexDecomposition()->MaxConvexHulls();
903+
}
904+
// Check if MeshManager contains the decomposed mesh already. If not
905+
// add it to the MeshManager so we do not need to decompose it again.
906+
const std::string convexMeshName =
907+
_mesh.Name() + "_CONVEX_" + std::to_string(maxConvexHulls);
908+
auto *optimizedMesh = meshManager.MeshByName(convexMeshName);
909+
if (!optimizedMesh)
910+
{
911+
// Merge meshes before convex decomposition
912+
auto mergedMesh = gz::common::MeshManager::MergeSubMeshes(_mesh);
913+
if (mergedMesh && mergedMesh->SubMeshCount() == 1u)
914+
{
915+
// Decompose and add mesh to MeshManager
916+
auto mergedSubmesh = mergedMesh->SubMeshByIndex(0u).lock();
917+
std::vector<common::SubMesh> decomposed =
918+
gz::common::MeshManager::ConvexDecomposition(
919+
*mergedSubmesh.get(), maxConvexHulls);
920+
gzdbg << "Optimizing mesh (" << _meshSdf.OptimizationStr() << "): "
921+
<< _mesh.Name() << std::endl;
922+
// Create decomposed mesh and add it to MeshManager
923+
// Note: MeshManager will call delete on this mesh in its destructor
924+
// \todo(iche033) Consider updating MeshManager to accept
925+
// unique pointers instead
926+
common::Mesh *convexMesh = new common::Mesh;
927+
convexMesh->SetName(convexMeshName);
928+
for (const auto & submesh : decomposed)
929+
convexMesh->AddSubMesh(submesh);
930+
meshManager.AddMesh(convexMesh);
931+
if (decomposed.empty())
932+
{
933+
// Print an error if convex decomposition returned empty submeshes
934+
// but still add it to MeshManager to avoid going through the
935+
// expensive convex decomposition process for the same mesh again
936+
gzerr << "Convex decomposition generated zero meshes: "
937+
<< _mesh.Name() << std::endl;
938+
}
939+
optimizedMesh = meshManager.MeshByName(convexMeshName);
940+
}
941+
}
942+
return optimizedMesh;
943+
}
944+
867945
}
868946
}
869947
}

‎src/Util_TEST.cc

+8
Original file line numberDiff line numberDiff line change
@@ -1023,4 +1023,12 @@ TEST_F(UtilTest, LoadMesh)
10231023
"test", "media", "duck.dae");
10241024
meshSdf.SetFilePath(filePath);
10251025
EXPECT_NE(nullptr, loadMesh(meshSdf));
1026+
1027+
EXPECT_TRUE(meshSdf.SetOptimization("convex_decomposition"));
1028+
sdf::ConvexDecomposition convexDecomp;
1029+
convexDecomp.SetMaxConvexHulls(16u);
1030+
meshSdf.SetConvexDecomposition(convexDecomp);
1031+
auto *optimizedMesh = loadMesh(meshSdf);
1032+
EXPECT_NE(nullptr, optimizedMesh);
1033+
EXPECT_EQ(16u, optimizedMesh->SubMeshCount());
10261034
}

‎src/rendering/RenderUtil.cc

+13-80
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include <vector>
2525

2626
#include <sdf/Actor.hh>
27+
#include <sdf/Camera.hh>
2728
#include <sdf/Collision.hh>
2829
#include <sdf/Element.hh>
2930
#include <sdf/Joint.hh>
@@ -1323,6 +1324,18 @@ void RenderUtil::Update()
13231324
gzerr << "Failed to create sensor [" << sensorName << "]"
13241325
<< std::endl;
13251326
}
1327+
else
1328+
{
1329+
auto sensorNode = this->dataPtr->sceneManager.NodeById(entity);
1330+
auto semPose = dataSdf.SemanticPose();
1331+
math::Pose3d sensorPose;
1332+
sdf::Errors errors = semPose.Resolve(sensorPose);
1333+
if (!errors.empty())
1334+
{
1335+
sensorPose = dataSdf.RawPose();
1336+
}
1337+
sensorNode->SetLocalPose(sensorPose);
1338+
}
13261339
}
13271340
}
13281341
}
@@ -2388,86 +2401,6 @@ void RenderUtilPrivate::UpdateRenderingEntities(
23882401
this->entityPoses[_entity] = _pose->Data();
23892402
return true;
23902403
});
2391-
2392-
// Update cameras
2393-
_ecm.Each<components::Camera, components::Pose>(
2394-
[&](const Entity &_entity,
2395-
const components::Camera *,
2396-
const components::Pose *_pose)->bool
2397-
{
2398-
this->entityPoses[_entity] = _pose->Data();
2399-
return true;
2400-
});
2401-
2402-
// Update depth cameras
2403-
_ecm.Each<components::DepthCamera, components::Pose>(
2404-
[&](const Entity &_entity,
2405-
const components::DepthCamera *,
2406-
const components::Pose *_pose)->bool
2407-
{
2408-
this->entityPoses[_entity] = _pose->Data();
2409-
return true;
2410-
});
2411-
2412-
// Update RGBD cameras
2413-
_ecm.Each<components::RgbdCamera, components::Pose>(
2414-
[&](const Entity &_entity,
2415-
const components::RgbdCamera *,
2416-
const components::Pose *_pose)->bool
2417-
{
2418-
this->entityPoses[_entity] = _pose->Data();
2419-
return true;
2420-
});
2421-
2422-
// Update gpu_lidar
2423-
_ecm.Each<components::GpuLidar, components::Pose>(
2424-
[&](const Entity &_entity,
2425-
const components::GpuLidar *,
2426-
const components::Pose *_pose)->bool
2427-
{
2428-
this->entityPoses[_entity] = _pose->Data();
2429-
return true;
2430-
});
2431-
2432-
// Update thermal cameras
2433-
_ecm.Each<components::ThermalCamera, components::Pose>(
2434-
[&](const Entity &_entity,
2435-
const components::ThermalCamera *,
2436-
const components::Pose *_pose)->bool
2437-
{
2438-
this->entityPoses[_entity] = _pose->Data();
2439-
return true;
2440-
});
2441-
2442-
// Update segmentation cameras
2443-
_ecm.Each<components::SegmentationCamera, components::Pose>(
2444-
[&](const Entity &_entity,
2445-
const components::SegmentationCamera *,
2446-
const components::Pose *_pose)->bool
2447-
{
2448-
this->entityPoses[_entity] = _pose->Data();
2449-
return true;
2450-
});
2451-
2452-
// Update bounding box cameras
2453-
_ecm.Each<components::BoundingBoxCamera, components::Pose>(
2454-
[&](const Entity &_entity,
2455-
const components::BoundingBoxCamera *,
2456-
const components::Pose *_pose)->bool
2457-
{
2458-
this->entityPoses[_entity] = _pose->Data();
2459-
return true;
2460-
});
2461-
2462-
// Update wide angle cameras
2463-
_ecm.Each<components::WideAngleCamera, components::Pose>(
2464-
[&](const Entity &_entity,
2465-
const components::WideAngleCamera *,
2466-
const components::Pose *_pose)->bool
2467-
{
2468-
this->entityPoses[_entity] = _pose->Data();
2469-
return true;
2470-
});
24712404
}
24722405

24732406
//////////////////////////////////////////////////

0 commit comments

Comments
 (0)
Please sign in to comment.