diff --git a/src/xml/xml_native_writer.cc b/src/xml/xml_native_writer.cc index b34eb2e5..44646531 100644 --- a/src/xml/xml_native_writer.cc +++ b/src/xml/xml_native_writer.cc @@ -220,9 +220,6 @@ void mjXWriter::OneMesh(XMLElement* elem, const mjCMesh* mesh, mjCDef* def) { } WriteAttrTxt(elem, "content_type", mesh->ContentType()); WriteAttrTxt(elem, "file", mesh->File()); - if (mesh->Inertia() != def->Mesh().Inertia()) { - WriteAttrTxt(elem, "inertia", FindValue(meshinertia_map, 4, mesh->Inertia())); - } // write vertex data if (!mesh->UserVert().empty()) { @@ -250,6 +247,9 @@ void mjXWriter::OneMesh(XMLElement* elem, const mjCMesh* mesh, mjCDef* def) { } // defaults and regular + if (mesh->Inertia() != def->Mesh().Inertia()) { + WriteAttrTxt(elem, "inertia", FindValue(meshinertia_map, 4, mesh->Inertia())); + } WriteAttr(elem, "refpos", 3, mesh->Refpos(), def->Mesh().Refpos()); WriteAttr(elem, "refquat", 4, mesh->Refquat(), def->Mesh().Refquat()); WriteAttr(elem, "scale", 3, mesh->Scale(), def->Mesh().Scale()); diff --git a/test/xml/xml_api_test.cc b/test/xml/xml_api_test.cc index dea098c6..fdd1421b 100644 --- a/test/xml/xml_api_test.cc +++ b/test/xml/xml_api_test.cc @@ -34,6 +34,7 @@ namespace { using ::testing::IsNull; using ::testing::NotNull; using ::testing::StartsWith; +using ::testing::HasSubstr; static constexpr char xml[] = R"( @@ -151,11 +152,46 @@ TEST_F(MujocoTest, SaveXml) { mjModel* saved_model = mj_compile(saved_spec, 0); EXPECT_THAT(saved_model, NotNull()) << "Invalid model: " << error.data(); - mjtNum tol = 0; - std::string field = ""; - EXPECT_LE(CompareModel(model, saved_model, field), tol) - << "Expected and attached models are different!\n" - << "Different field: " << field << '\n'; + mj_deleteSpec(spec); + mj_deleteSpec(saved_spec); + mj_deleteModel(model); + mj_deleteModel(saved_model); +} + +TEST_F(MujocoTest, SaveXmlWithDefaultMesh) { + static constexpr char xml[] = R"( + + + + + + + + + + + + + + )"; + + std::array error; + mjSpec* spec = mj_parseXMLString(xml, 0, error.data(), error.size()); + EXPECT_THAT(spec, NotNull()) << "Failed to parse spec: " << error.data(); + mjModel* model = mj_compile(spec, 0); + EXPECT_THAT(model, NotNull()) << "Failed to compile model: " << error.data(); + + std::array out; + EXPECT_THAT(mj_saveXMLString(spec, out.data(), out.size(), error.data(), + error.size()), 0) << error.data(); + + mjSpec* saved_spec = mj_parseXMLString(xml, 0, error.data(), error.size()); + EXPECT_THAT(saved_spec, NotNull()) << "Invalid saved spec: " << error.data(); + mjModel* saved_model = mj_compile(saved_spec, 0); + EXPECT_THAT(saved_model, NotNull()) << "Invalid model: " << error.data(); + + // check that the mesh has inertia="shell" + EXPECT_THAT(out.data(), HasSubstr(R"()")); mj_deleteSpec(spec); mj_deleteSpec(saved_spec);