Fix vfs load for mesh gmeshs type

This commit is contained in:
Mark Yang
2026-03-07 21:45:12 -05:00
parent 6bc6c11c49
commit 95724d1ec2
4 changed files with 56 additions and 11 deletions
+7 -7
View File
@@ -99,7 +99,7 @@ mjCFlexcomp::mjCFlexcomp(void) {
// make flexcomp object
bool mjCFlexcomp::Make(mjsBody* body, char* error, int error_sz) {
bool mjCFlexcomp::Make(mjsBody* body, char* error, int error_sz, const mjVFS* vfs) {
mjCModel* model = static_cast<mjCBody*>(body->element)->model;
mjsCompiler* compiler = static_cast<mjCBody*>(body->element)->compiler;
mjsFlex* dflex = def.spec.flex;
@@ -170,11 +170,11 @@ bool mjCFlexcomp::Make(mjsBody* body, char* error, int error_sz) {
break;
case mjFCOMPTYPE_MESH:
res = MakeMesh(model, compiler, error, error_sz);
res = MakeMesh(model, compiler, error, error_sz, vfs);
break;
case mjFCOMPTYPE_GMSH:
res = MakeGMSH(model, compiler, error, error_sz);
res = MakeGMSH(model, compiler, error, error_sz, vfs);
break;
case mjFCOMPTYPE_DIRECT:
@@ -1129,7 +1129,7 @@ template <typename T> static T* VecToArray(std::vector<T>& vector, bool clear =
// make mesh
bool mjCFlexcomp::MakeMesh(mjCModel* model, mjsCompiler* compiler, char* error, int error_sz) {
bool mjCFlexcomp::MakeMesh(mjCModel* model, mjsCompiler* compiler, char* error, int error_sz, const mjVFS* vfs) {
// strip path
if (!file.empty() && model->spec.strippath) {
file = mjuu_strippath(file);
@@ -1156,7 +1156,7 @@ bool mjCFlexcomp::MakeMesh(mjCModel* model, mjsCompiler* compiler, char* error,
try {
resource = mjCBase::LoadResource(mjs_getString(model->spec.modelfiledir),
filename, 0);
filename, vfs);
} catch (mjCError err) {
return comperr(error, err.message, error_sz);
}
@@ -1248,7 +1248,7 @@ static int findstring(const char* buffer, int buffer_sz, const char* str) {
// load points and elements from GMSH file
bool mjCFlexcomp::MakeGMSH(mjCModel* model, mjsCompiler* compiler, char* error, int error_sz) {
bool mjCFlexcomp::MakeGMSH(mjCModel* model, mjsCompiler* compiler, char* error, int error_sz, const mjVFS* vfs) {
// strip path
if (!file.empty() && model->spec.strippath) {
file = mjuu_strippath(file);
@@ -1264,7 +1264,7 @@ bool mjCFlexcomp::MakeGMSH(mjCModel* model, mjsCompiler* compiler, char* error,
try {
std::string filename = mjuu_combinePaths(mjs_getString(compiler->meshdir), file);
resource = mjCBase::LoadResource(mjs_getString(model->spec.modelfiledir),
filename, 0);
filename, vfs);
} catch (mjCError err) {
return comperr(error, err.message, error_sz);
}
+5 -3
View File
@@ -53,13 +53,15 @@ typedef enum _mjtDof {
class mjCFlexcomp {
public:
mjCFlexcomp(void);
bool Make(mjsBody* body, char* error, int error_sz);
bool Make(mjsBody* body, char* error, int error_sz, const mjVFS* vfs = nullptr);
bool MakeGrid(char* error, int error_sz);
bool MakeBox(char* error, int error_sz, int dim, bool open = true);
bool MakeSquare(char* error, int error_sz);
bool MakeMesh(mjCModel* model, mjsCompiler* compiler, char* error, int error_sz);
bool MakeGMSH(mjCModel* model, mjsCompiler* compiler, char* error, int error_sz);
bool MakeMesh(mjCModel* model, mjsCompiler* compiler, char* error, int error_sz,
const mjVFS* vfs = nullptr);
bool MakeGMSH(mjCModel* model, mjsCompiler* compiler, char* error, int error_sz,
const mjVFS* vfs = nullptr);
void LoadGMSH(mjCModel* model, mjResource* resource);
void LoadGMSH41(char* buffer, int binary, int nodeend, int nodebegin,
int elemend, int elembegin);
+1 -1
View File
@@ -2849,7 +2849,7 @@ void mjXReader::OneFlexcomp(XMLElement* elem, mjsBody* body, const mjVFS* vfs) {
// make flexcomp
char error[200];
bool res = fcomp.Make(body, error, 200);
bool res = fcomp.Make(body, error, 200, vfs);
// throw error
if (!res) {
+43
View File
@@ -15,6 +15,7 @@
// Tests for user/user_model.cc.
#include <array>
#include <cstdio>
#include <string>
#include <gmock/gmock.h>
@@ -876,5 +877,47 @@ TEST_F(UserFlexTest, MeshNodePinning) {
mj_deleteModel(m);
}
TEST_F(UserFlexTest, FlexcompMeshLoadsFromVFS) {
// read cube.stl from testdata into a buffer
const std::string stl_path =
GetTestDataFilePath("user/testdata/cube.stl");
FILE* f = fopen(stl_path.c_str(), "rb");
ASSERT_THAT(f, NotNull()) << "Could not open " << stl_path;
fseek(f, 0, SEEK_END);
long stl_size = ftell(f);
fseek(f, 0, SEEK_SET);
std::string stl_data(stl_size, '\0');
fread(stl_data.data(), 1, stl_size, f);
fclose(f);
// add the STL data to a VFS
mjVFS vfs;
mj_defaultVFS(&vfs);
mj_addBufferVFS(&vfs, "cube.stl", stl_data.data(), stl_size);
// XML that uses flexcomp type="mesh" referencing the VFS file
static constexpr char xml[] = R"(
<mujoco>
<worldbody>
<body name="flex_body" pos="0 0 1">
<flexcomp name="flex_object" type="mesh" file="cube.stl" rigid="true">
<contact contype="1" conaffinity="1"/>
</flexcomp>
</body>
</worldbody>
</mujoco>
)";
// cleanup
std::array<char, 1024> error;
mjModel* m = LoadModelFromString(xml, error.data(), error.size(), &vfs);
ASSERT_THAT(m, NotNull()) << error.data();
mjData* d = mj_makeData(m);
mj_step(m, d);
mj_deleteData(d);
mj_deleteModel(m);
mj_deleteVFS(&vfs);
}
} // namespace
} // namespace mujoco