diff --git a/src/user/user_mesh.cc b/src/user/user_mesh.cc index 32b281de..7c691dc8 100644 --- a/src/user/user_mesh.cc +++ b/src/user/user_mesh.cc @@ -2526,16 +2526,15 @@ void mjCSkin::Compile(const mjVFS* vfs) { // load file if (!file_.empty()) { // make sure data is not present - if (!vert_.empty() || - !texcoord_.empty() || - !face_.empty() || - !bodyname_.empty() || - !bindpos_.empty() || - !bindquat_.empty() || - !vertid_.empty() || - !vertweight_.empty() || - !bodyid.empty()) { - throw mjCError(this, "Data already exists, trying to load from skin file: %s", file_.c_str()); + if (!spec_vert_.empty() || + !spec_texcoord_.empty() || + !spec_face_.empty() || + !spec_bodyname_.empty() || + !spec_bindpos_.empty() || + !spec_bindquat_.empty() || + !spec_vertid_.empty() || + !spec_vertweight_.empty()) { + throw mjCError(this, "Both skin data and file were specified: %s", file_.c_str()); } // remove path from file if necessary diff --git a/test/user/testdata/cube.skn b/test/user/testdata/cube.skn new file mode 100644 index 00000000..498a7926 Binary files /dev/null and b/test/user/testdata/cube.skn differ diff --git a/test/user/testdata/cube.stl b/test/user/testdata/cube.stl new file mode 100644 index 00000000..e2f72542 Binary files /dev/null and b/test/user/testdata/cube.stl differ diff --git a/test/user/testdata/cube_skin.xml b/test/user/testdata/cube_skin.xml new file mode 100644 index 00000000..69004072 --- /dev/null +++ b/test/user/testdata/cube_skin.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/test/user/user_mesh_test.cc b/test/user/user_mesh_test.cc index 2e1eb1e0..167b1480 100644 --- a/test/user/user_mesh_test.cc +++ b/test/user/user_mesh_test.cc @@ -66,6 +66,8 @@ static const char* const kDuplicateOBJPath = "user/testdata/duplicate.xml"; static const char* const kMalformedFaceOBJPath = "user/testdata/malformed_face.xml"; +static const char* const kCubeSkinPath = + "user/testdata/cube_skin.xml"; using ::testing::ElementsAre; using ::testing::HasSubstr; @@ -1184,6 +1186,19 @@ TEST_F(MjCMeshTest, InvalidIndexInFace) { mj_deleteModel(model); } +TEST_F(MjCMeshTest, LoadSkin) { + const std::string xml_path = GetTestDataFilePath(kCubeSkinPath); + std::array error; + mjSpec* spec = mj_parseXML(xml_path.c_str(), 0, error.data(), error.size()); + EXPECT_THAT(spec, NotNull()) << error.data(); + mjModel* m1 = mj_compile(spec, 0); + EXPECT_THAT(m1, NotNull()); + mj_deleteModel(m1); + mjModel* m2 = mj_compile(spec, 0); + EXPECT_THAT(m2, NotNull()); + mj_deleteModel(m2); + mj_deleteSpec(spec); +} } // namespace