From 95f05402f1fc952b55052821eae7f82a23e8d9a2 Mon Sep 17 00:00:00 2001 From: VihaanAgarwal Date: Sun, 26 Jul 2026 16:04:15 -0700 Subject: [PATCH] Fix segfault on a mesh with convex inertia that no geom references needhull_ was only set while iterating geoms, so a mesh whose inertia is computed from its convex hull never got one unless some geom pointed at it. mjCMesh::ComputeVolume and ComputeInertia then read graph_[1] and GraphFaces() off a null pointer and the compiler crashed. Whether a mesh needs its hull for inertia is a property of the mesh, not of any geom, so move that condition out of the geom loop and apply it to every mesh. Fixes #3431 --- src/user/user_model.cc | 11 +++++++++-- test/user/user_mesh_test.cc | 16 ++++++++++++++++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/src/user/user_model.cc b/src/user/user_model.cc index 9f46d8d4..e5d88214 100644 --- a/src/user/user_model.cc +++ b/src/user/user_model.cc @@ -5279,12 +5279,19 @@ void mjCModel::TryCompile(mjModel*& m, mjData*& d, const mjVFS* vfs) { if (geoms_[i]->mesh && (geoms_[i]->spec.type == mjGEOM_MESH || geoms_[i]->spec.type == mjGEOM_SDF) && - (geoms_[i]->spec.contype || geoms_[i]->spec.conaffinity || is_in_pair || - geoms_[i]->mesh->spec.inertia == mjMESH_INERTIA_CONVEX)) { + (geoms_[i]->spec.contype || geoms_[i]->spec.conaffinity || is_in_pair)) { geoms_[i]->mesh->SetNeedHull(true); } } + // convex inertia is computed from the hull, so it is needed whether or not + // any geom references the mesh + for (mjCMesh* mesh : meshes_) { + if (mesh->spec.inertia == mjMESH_INERTIA_CONVEX) { + mesh->SetNeedHull(true); + } + } + // automatically set nuser fields SetNuser(); diff --git a/test/user/user_mesh_test.cc b/test/user/user_mesh_test.cc index 5d1cde99..46c4c048 100644 --- a/test/user/user_mesh_test.cc +++ b/test/user/user_mesh_test.cc @@ -975,6 +975,22 @@ TEST_F(MjCMeshTest, ExactConvexInertia) { mj_deleteModel(model); } +TEST_F(MjCMeshTest, UnreferencedConvexInertiaMesh) { + static constexpr char xml[] = R"( + + + + + + + )"; + std::array error; + MjModelPtr model = LoadModelFromString(xml, error.data(), error.size()); + EXPECT_THAT(model.get(), NotNull()) << error.data(); +} + TEST_F(MjCMeshTest, ExactShellInertia) { const std::string xml_path = GetTestDataFilePath(kShellInertiaPath); std::array error;