Update XML parsing to store asset path so that assets can be recovered and sent to external renderers
PiperOrigin-RevId: 567347908 Change-Id: I4d8e1abe35be3a67643ff925af709921280856f8
This commit is contained in:
committed by
Copybara-Service
parent
4f34cacf35
commit
7f8018a3f3
@@ -861,6 +861,7 @@ struct mjModel_ {
|
|||||||
int nuser_sensor; // number of mjtNums in sensor_user
|
int nuser_sensor; // number of mjtNums in sensor_user
|
||||||
int nnames; // number of chars in all names
|
int nnames; // number of chars in all names
|
||||||
int nnames_map; // number of slots in the names hash map
|
int nnames_map; // number of slots in the names hash map
|
||||||
|
int npaths; // number of chars in all paths
|
||||||
|
|
||||||
// sizes set after mjModel construction (only affect mjData)
|
// sizes set after mjModel construction (only affect mjData)
|
||||||
int nM; // number of non-zeros in sparse inertia matrix
|
int nM; // number of non-zeros in sparse inertia matrix
|
||||||
@@ -1045,6 +1046,7 @@ struct mjModel_ {
|
|||||||
int* mesh_graphadr; // graph data address; -1: no graph (nmesh x 1)
|
int* mesh_graphadr; // graph data address; -1: no graph (nmesh x 1)
|
||||||
mjtNum* mesh_pos; // translation applied to asset vertices (nmesh x 3)
|
mjtNum* mesh_pos; // translation applied to asset vertices (nmesh x 3)
|
||||||
mjtNum* mesh_quat; // rotation applied to asset vertices (nmesh x 4)
|
mjtNum* mesh_quat; // rotation applied to asset vertices (nmesh x 4)
|
||||||
|
int* mesh_assetpathadr; // address of asset path for mesh; -1: none (nmesh x 1)
|
||||||
float* mesh_vert; // vertex positions for all meshes (nmeshvert x 3)
|
float* mesh_vert; // vertex positions for all meshes (nmeshvert x 3)
|
||||||
float* mesh_normal; // normals for all meshes (nmeshnormal x 3)
|
float* mesh_normal; // normals for all meshes (nmeshnormal x 3)
|
||||||
float* mesh_texcoord; // vertex texcoords for all meshes (nmeshtexcoord x 2)
|
float* mesh_texcoord; // vertex texcoords for all meshes (nmeshtexcoord x 2)
|
||||||
@@ -1251,6 +1253,9 @@ struct mjModel_ {
|
|||||||
int* name_pluginadr; // plugin instance name pointers (nplugin x 1)
|
int* name_pluginadr; // plugin instance name pointers (nplugin x 1)
|
||||||
char* names; // names of all objects, 0-terminated (nnames x 1)
|
char* names; // names of all objects, 0-terminated (nnames x 1)
|
||||||
int* names_map; // internal hash map of names (nnames_map x 1)
|
int* names_map; // internal hash map of names (nnames_map x 1)
|
||||||
|
|
||||||
|
// paths
|
||||||
|
char* paths; // paths to assets, 0-terminated (npaths x 1)
|
||||||
};
|
};
|
||||||
typedef struct mjModel_ mjModel;
|
typedef struct mjModel_ mjModel;
|
||||||
struct mjResource_ {
|
struct mjResource_ {
|
||||||
@@ -1995,6 +2000,7 @@ struct mjvSceneState_ {
|
|||||||
int nwrap;
|
int nwrap;
|
||||||
int nsensor;
|
int nsensor;
|
||||||
int nnames;
|
int nnames;
|
||||||
|
int npaths;
|
||||||
int nsensordata;
|
int nsensordata;
|
||||||
|
|
||||||
mjOption opt;
|
mjOption opt;
|
||||||
@@ -2062,6 +2068,7 @@ struct mjvSceneState_ {
|
|||||||
int* mesh_bvhnum;
|
int* mesh_bvhnum;
|
||||||
int* mesh_texcoordadr;
|
int* mesh_texcoordadr;
|
||||||
int* mesh_graphadr;
|
int* mesh_graphadr;
|
||||||
|
int* mesh_assetpathadr;
|
||||||
|
|
||||||
int* skin_matid;
|
int* skin_matid;
|
||||||
int* skin_group;
|
int* skin_group;
|
||||||
@@ -2137,6 +2144,7 @@ struct mjvSceneState_ {
|
|||||||
int* name_tendonadr;
|
int* name_tendonadr;
|
||||||
int* name_actuatoradr;
|
int* name_actuatoradr;
|
||||||
char* names;
|
char* names;
|
||||||
|
char* paths;
|
||||||
} model;
|
} model;
|
||||||
|
|
||||||
// fields in mjData that are necessary to re-render a scene
|
// fields in mjData that are necessary to re-render a scene
|
||||||
|
|||||||
@@ -593,6 +593,7 @@ struct mjModel_ {
|
|||||||
int nuser_sensor; // number of mjtNums in sensor_user
|
int nuser_sensor; // number of mjtNums in sensor_user
|
||||||
int nnames; // number of chars in all names
|
int nnames; // number of chars in all names
|
||||||
int nnames_map; // number of slots in the names hash map
|
int nnames_map; // number of slots in the names hash map
|
||||||
|
int npaths; // number of chars in all paths
|
||||||
|
|
||||||
// sizes set after mjModel construction (only affect mjData)
|
// sizes set after mjModel construction (only affect mjData)
|
||||||
int nM; // number of non-zeros in sparse inertia matrix
|
int nM; // number of non-zeros in sparse inertia matrix
|
||||||
@@ -777,6 +778,7 @@ struct mjModel_ {
|
|||||||
int* mesh_graphadr; // graph data address; -1: no graph (nmesh x 1)
|
int* mesh_graphadr; // graph data address; -1: no graph (nmesh x 1)
|
||||||
mjtNum* mesh_pos; // translation applied to asset vertices (nmesh x 3)
|
mjtNum* mesh_pos; // translation applied to asset vertices (nmesh x 3)
|
||||||
mjtNum* mesh_quat; // rotation applied to asset vertices (nmesh x 4)
|
mjtNum* mesh_quat; // rotation applied to asset vertices (nmesh x 4)
|
||||||
|
int* mesh_assetpathadr; // address of asset path for mesh; -1: none (nmesh x 1)
|
||||||
float* mesh_vert; // vertex positions for all meshes (nmeshvert x 3)
|
float* mesh_vert; // vertex positions for all meshes (nmeshvert x 3)
|
||||||
float* mesh_normal; // normals for all meshes (nmeshnormal x 3)
|
float* mesh_normal; // normals for all meshes (nmeshnormal x 3)
|
||||||
float* mesh_texcoord; // vertex texcoords for all meshes (nmeshtexcoord x 2)
|
float* mesh_texcoord; // vertex texcoords for all meshes (nmeshtexcoord x 2)
|
||||||
@@ -983,6 +985,9 @@ struct mjModel_ {
|
|||||||
int* name_pluginadr; // plugin instance name pointers (nplugin x 1)
|
int* name_pluginadr; // plugin instance name pointers (nplugin x 1)
|
||||||
char* names; // names of all objects, 0-terminated (nnames x 1)
|
char* names; // names of all objects, 0-terminated (nnames x 1)
|
||||||
int* names_map; // internal hash map of names (nnames_map x 1)
|
int* names_map; // internal hash map of names (nnames_map x 1)
|
||||||
|
|
||||||
|
// paths
|
||||||
|
char* paths; // paths to assets, 0-terminated (npaths x 1)
|
||||||
};
|
};
|
||||||
typedef struct mjModel_ mjModel;
|
typedef struct mjModel_ mjModel;
|
||||||
|
|
||||||
|
|||||||
@@ -401,6 +401,7 @@ struct mjvSceneState_ {
|
|||||||
int nwrap;
|
int nwrap;
|
||||||
int nsensor;
|
int nsensor;
|
||||||
int nnames;
|
int nnames;
|
||||||
|
int npaths;
|
||||||
int nsensordata;
|
int nsensordata;
|
||||||
|
|
||||||
mjOption opt;
|
mjOption opt;
|
||||||
@@ -468,6 +469,7 @@ struct mjvSceneState_ {
|
|||||||
int* mesh_bvhnum;
|
int* mesh_bvhnum;
|
||||||
int* mesh_texcoordadr;
|
int* mesh_texcoordadr;
|
||||||
int* mesh_graphadr;
|
int* mesh_graphadr;
|
||||||
|
int* mesh_assetpathadr;
|
||||||
|
|
||||||
int* skin_matid;
|
int* skin_matid;
|
||||||
int* skin_group;
|
int* skin_group;
|
||||||
@@ -543,6 +545,7 @@ struct mjvSceneState_ {
|
|||||||
int* name_tendonadr;
|
int* name_tendonadr;
|
||||||
int* name_actuatoradr;
|
int* name_actuatoradr;
|
||||||
char* names;
|
char* names;
|
||||||
|
char* paths;
|
||||||
} model;
|
} model;
|
||||||
|
|
||||||
// fields in mjData that are necessary to re-render a scene
|
// fields in mjData that are necessary to re-render a scene
|
||||||
|
|||||||
@@ -118,6 +118,7 @@
|
|||||||
X ( nuser_actuator ) \
|
X ( nuser_actuator ) \
|
||||||
X ( nuser_sensor ) \
|
X ( nuser_sensor ) \
|
||||||
XMJV( nnames ) \
|
XMJV( nnames ) \
|
||||||
|
XMJV( npaths ) \
|
||||||
X ( nnames_map ) \
|
X ( nnames_map ) \
|
||||||
X ( nM ) \
|
X ( nM ) \
|
||||||
X ( nD ) \
|
X ( nD ) \
|
||||||
@@ -132,6 +133,8 @@
|
|||||||
X ( narena ) \
|
X ( narena ) \
|
||||||
X ( nbuffer )
|
X ( nbuffer )
|
||||||
|
|
||||||
|
/* nbuffer needs to be the final field */
|
||||||
|
|
||||||
|
|
||||||
// define symbols needed in MJMODEL_POINTERS (corresponding to number of columns)
|
// define symbols needed in MJMODEL_POINTERS (corresponding to number of columns)
|
||||||
#define MJMODEL_POINTERS_PREAMBLE( m ) \
|
#define MJMODEL_POINTERS_PREAMBLE( m ) \
|
||||||
@@ -296,6 +299,7 @@
|
|||||||
XMJV( int, mesh_graphadr, nmesh, 1 ) \
|
XMJV( int, mesh_graphadr, nmesh, 1 ) \
|
||||||
X ( mjtNum, mesh_pos, nmesh, 3 ) \
|
X ( mjtNum, mesh_pos, nmesh, 3 ) \
|
||||||
X ( mjtNum, mesh_quat, nmesh, 4 ) \
|
X ( mjtNum, mesh_quat, nmesh, 4 ) \
|
||||||
|
XMJV( int, mesh_assetpathadr, nmesh, 1 ) \
|
||||||
X ( float, mesh_vert, nmeshvert, 3 ) \
|
X ( float, mesh_vert, nmeshvert, 3 ) \
|
||||||
X ( float, mesh_normal, nmeshnormal, 3 ) \
|
X ( float, mesh_normal, nmeshnormal, 3 ) \
|
||||||
X ( float, mesh_texcoord, nmeshtexcoord, 2 ) \
|
X ( float, mesh_texcoord, nmeshtexcoord, 2 ) \
|
||||||
@@ -468,6 +472,7 @@
|
|||||||
X ( int, name_pluginadr, nplugin, 1 ) \
|
X ( int, name_pluginadr, nplugin, 1 ) \
|
||||||
XMJV( char, names, nnames, 1 ) \
|
XMJV( char, names, nnames, 1 ) \
|
||||||
X ( int, names_map, nnames_map, 1 ) \
|
X ( int, names_map, nnames_map, 1 ) \
|
||||||
|
XMJV( char, paths, npaths, 1 ) \
|
||||||
|
|
||||||
//-------------------------------- mjData ----------------------------------------------------------
|
//-------------------------------- mjData ----------------------------------------------------------
|
||||||
|
|
||||||
|
|||||||
@@ -1070,6 +1070,11 @@ STRUCTS: Mapping[str, StructDecl] = dict([
|
|||||||
type=ValueType(name='int'),
|
type=ValueType(name='int'),
|
||||||
doc='number of slots in the names hash map',
|
doc='number of slots in the names hash map',
|
||||||
),
|
),
|
||||||
|
StructFieldDecl(
|
||||||
|
name='npaths',
|
||||||
|
type=ValueType(name='int'),
|
||||||
|
doc='number of chars in all paths',
|
||||||
|
),
|
||||||
StructFieldDecl(
|
StructFieldDecl(
|
||||||
name='nM',
|
name='nM',
|
||||||
type=ValueType(name='int'),
|
type=ValueType(name='int'),
|
||||||
@@ -2118,6 +2123,13 @@ STRUCTS: Mapping[str, StructDecl] = dict([
|
|||||||
),
|
),
|
||||||
doc='rotation applied to asset vertices (nmesh x 4)',
|
doc='rotation applied to asset vertices (nmesh x 4)',
|
||||||
),
|
),
|
||||||
|
StructFieldDecl(
|
||||||
|
name='mesh_assetpathadr',
|
||||||
|
type=PointerType(
|
||||||
|
inner_type=ValueType(name='int'),
|
||||||
|
),
|
||||||
|
doc='address of asset path for mesh; -1: none (nmesh x 1)',
|
||||||
|
),
|
||||||
StructFieldDecl(
|
StructFieldDecl(
|
||||||
name='mesh_vert',
|
name='mesh_vert',
|
||||||
type=PointerType(
|
type=PointerType(
|
||||||
@@ -3322,6 +3334,13 @@ STRUCTS: Mapping[str, StructDecl] = dict([
|
|||||||
),
|
),
|
||||||
doc='internal hash map of names (nnames_map x 1)', # pylint: disable=line-too-long
|
doc='internal hash map of names (nnames_map x 1)', # pylint: disable=line-too-long
|
||||||
),
|
),
|
||||||
|
StructFieldDecl(
|
||||||
|
name='paths',
|
||||||
|
type=PointerType(
|
||||||
|
inner_type=ValueType(name='char'),
|
||||||
|
),
|
||||||
|
doc='paths to assets, 0-terminated (npaths x 1)',
|
||||||
|
),
|
||||||
),
|
),
|
||||||
)),
|
)),
|
||||||
('mjThreadPool',
|
('mjThreadPool',
|
||||||
@@ -5554,6 +5573,11 @@ STRUCTS: Mapping[str, StructDecl] = dict([
|
|||||||
type=ValueType(name='int'),
|
type=ValueType(name='int'),
|
||||||
doc='',
|
doc='',
|
||||||
),
|
),
|
||||||
|
StructFieldDecl(
|
||||||
|
name='npaths',
|
||||||
|
type=ValueType(name='int'),
|
||||||
|
doc='',
|
||||||
|
),
|
||||||
StructFieldDecl(
|
StructFieldDecl(
|
||||||
name='nsensordata',
|
name='nsensordata',
|
||||||
type=ValueType(name='int'),
|
type=ValueType(name='int'),
|
||||||
@@ -5952,6 +5976,13 @@ STRUCTS: Mapping[str, StructDecl] = dict([
|
|||||||
),
|
),
|
||||||
doc='',
|
doc='',
|
||||||
),
|
),
|
||||||
|
StructFieldDecl(
|
||||||
|
name='mesh_assetpathadr',
|
||||||
|
type=PointerType(
|
||||||
|
inner_type=ValueType(name='int'),
|
||||||
|
),
|
||||||
|
doc='',
|
||||||
|
),
|
||||||
StructFieldDecl(
|
StructFieldDecl(
|
||||||
name='skin_matid',
|
name='skin_matid',
|
||||||
type=PointerType(
|
type=PointerType(
|
||||||
@@ -6428,6 +6459,13 @@ STRUCTS: Mapping[str, StructDecl] = dict([
|
|||||||
),
|
),
|
||||||
doc='',
|
doc='',
|
||||||
),
|
),
|
||||||
|
StructFieldDecl(
|
||||||
|
name='paths',
|
||||||
|
type=PointerType(
|
||||||
|
inner_type=ValueType(name='char'),
|
||||||
|
),
|
||||||
|
doc='',
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
doc='',
|
doc='',
|
||||||
|
|||||||
@@ -234,6 +234,7 @@ MjModelWrapper::MjWrapper(raw::MjModel* ptr)
|
|||||||
MJMODEL_POINTERS,
|
MJMODEL_POINTERS,
|
||||||
text_data_bytes(ptr->text_data, ptr->ntextdata),
|
text_data_bytes(ptr->text_data, ptr->ntextdata),
|
||||||
names_bytes(ptr->names, ptr->nnames),
|
names_bytes(ptr->names, ptr->nnames),
|
||||||
|
paths_bytes(ptr->paths, ptr->npaths),
|
||||||
indexer_(ptr, owner_) {
|
indexer_(ptr, owner_) {
|
||||||
bool is_newly_inserted = false;
|
bool is_newly_inserted = false;
|
||||||
{
|
{
|
||||||
@@ -255,6 +256,7 @@ MjModelWrapper::MjWrapper(MjModelWrapper&& other)
|
|||||||
MJMODEL_POINTERS,
|
MJMODEL_POINTERS,
|
||||||
text_data_bytes(ptr_->text_data, ptr_->ntextdata),
|
text_data_bytes(ptr_->text_data, ptr_->ntextdata),
|
||||||
names_bytes(ptr_->names, ptr_->nnames),
|
names_bytes(ptr_->names, ptr_->nnames),
|
||||||
|
paths_bytes(ptr_->paths, ptr_->npaths),
|
||||||
indexer_(ptr_, owner_) {
|
indexer_(ptr_, owner_) {
|
||||||
bool is_newly_inserted = false;
|
bool is_newly_inserted = false;
|
||||||
{
|
{
|
||||||
@@ -1509,10 +1511,11 @@ This is useful for example when the MJB is not available as a file on disk.)"));
|
|||||||
MJMODEL_INTS
|
MJMODEL_INTS
|
||||||
#undef X
|
#undef X
|
||||||
|
|
||||||
#define X(dtype, var, dim0, dim1) \
|
#define X(dtype, var, dim0, dim1) \
|
||||||
if constexpr (std::string_view(#var) != "text_data" && \
|
if constexpr (std::string_view(#var) != "text_data" && \
|
||||||
std::string_view(#var) != "names") { \
|
std::string_view(#var) != "names" && \
|
||||||
DefinePyArray(mjModel, #var, &MjModelWrapper::var); \
|
std::string_view(#var) != "paths") { \
|
||||||
|
DefinePyArray(mjModel, #var, &MjModelWrapper::var); \
|
||||||
}
|
}
|
||||||
MJMODEL_POINTERS
|
MJMODEL_POINTERS
|
||||||
#undef X
|
#undef X
|
||||||
@@ -1527,6 +1530,11 @@ This is useful for example when the MJB is not available as a file on disk.)"));
|
|||||||
// Return the full bytes array of concatenated names
|
// Return the full bytes array of concatenated names
|
||||||
return m.names_bytes;
|
return m.names_bytes;
|
||||||
});
|
});
|
||||||
|
mjModel.def_property_readonly(
|
||||||
|
"paths", [](const MjModelWrapper& m) -> const auto& {
|
||||||
|
// Return the full bytes array of concatenated paths
|
||||||
|
return m.paths_bytes;
|
||||||
|
});
|
||||||
|
|
||||||
#define XGROUP(MjModelGroupedViews, field, nfield, FIELD_XMACROS) \
|
#define XGROUP(MjModelGroupedViews, field, nfield, FIELD_XMACROS) \
|
||||||
mjModel.def( \
|
mjModel.def( \
|
||||||
|
|||||||
@@ -477,6 +477,7 @@ class MjWrapper<raw::MjModel> : public WrapperBase<raw::MjModel> {
|
|||||||
// TODO(nimrod): Exclude text_data and names from the MJMODEL_POINTERS macro.
|
// TODO(nimrod): Exclude text_data and names from the MJMODEL_POINTERS macro.
|
||||||
pybind11::bytes text_data_bytes;
|
pybind11::bytes text_data_bytes;
|
||||||
pybind11::bytes names_bytes;
|
pybind11::bytes names_bytes;
|
||||||
|
pybind11::bytes paths_bytes;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
explicit MjWrapper(raw::MjModel* ptr);
|
explicit MjWrapper(raw::MjModel* ptr);
|
||||||
|
|||||||
@@ -450,7 +450,7 @@ mjModel* mj_makeModel(int nq, int nv, int nu, int na, int nbody, int nbvh, int n
|
|||||||
int ntuple, int ntupledata, int nkey, int nmocap, int nplugin,
|
int ntuple, int ntupledata, int nkey, int nmocap, int nplugin,
|
||||||
int npluginattr, int nuser_body, int nuser_jnt, int nuser_geom,
|
int npluginattr, int nuser_body, int nuser_jnt, int nuser_geom,
|
||||||
int nuser_site, int nuser_cam, int nuser_tendon, int nuser_actuator,
|
int nuser_site, int nuser_cam, int nuser_tendon, int nuser_actuator,
|
||||||
int nuser_sensor, int nnames) {
|
int nuser_sensor, int nnames, int npaths) {
|
||||||
intptr_t offset = 0;
|
intptr_t offset = 0;
|
||||||
|
|
||||||
// allocate mjModel
|
// allocate mjModel
|
||||||
@@ -519,6 +519,7 @@ mjModel* mj_makeModel(int nq, int nv, int nu, int na, int nbody, int nbvh, int n
|
|||||||
+ nskin + nhfield + ntex + nmat + npair + nexclude + neq
|
+ nskin + nhfield + ntex + nmat + npair + nexclude + neq
|
||||||
+ ntendon + nu + nsensor + nnumeric + ntext + ntuple
|
+ ntendon + nu + nsensor + nnumeric + ntext + ntuple
|
||||||
+ nkey + nplugin);
|
+ nkey + nplugin);
|
||||||
|
m->npaths = npaths;
|
||||||
|
|
||||||
#define X(name) \
|
#define X(name) \
|
||||||
if ((m->name) < 0) { \
|
if ((m->name) < 0) { \
|
||||||
@@ -597,7 +598,7 @@ mjModel* mj_copyModel(mjModel* dest, const mjModel* src) {
|
|||||||
src->ntuple, src->ntupledata, src->nkey, src->nmocap, src->nplugin,
|
src->ntuple, src->ntupledata, src->nkey, src->nmocap, src->nplugin,
|
||||||
src->npluginattr, src->nuser_body, src->nuser_jnt, src->nuser_geom,
|
src->npluginattr, src->nuser_body, src->nuser_jnt, src->nuser_geom,
|
||||||
src->nuser_site, src->nuser_cam, src->nuser_tendon, src->nuser_actuator,
|
src->nuser_site, src->nuser_cam, src->nuser_tendon, src->nuser_actuator,
|
||||||
src->nuser_sensor, src->nnames);
|
src->nuser_sensor, src->nnames, src->npaths);
|
||||||
}
|
}
|
||||||
if (!dest) {
|
if (!dest) {
|
||||||
mjERROR("failed to make mjModel. Invalid sizes.");
|
mjERROR("failed to make mjModel. Invalid sizes.");
|
||||||
@@ -762,7 +763,7 @@ mjModel* mj_loadModel(const char* filename, const mjVFS* vfs) {
|
|||||||
ints[28], ints[29], ints[30], ints[31], ints[32], ints[33], ints[34],
|
ints[28], ints[29], ints[30], ints[31], ints[32], ints[33], ints[34],
|
||||||
ints[35], ints[36], ints[37], ints[38], ints[39], ints[40], ints[41],
|
ints[35], ints[36], ints[37], ints[38], ints[39], ints[40], ints[41],
|
||||||
ints[42], ints[43], ints[44], ints[45], ints[46], ints[47], ints[48],
|
ints[42], ints[43], ints[44], ints[45], ints[46], ints[47], ints[48],
|
||||||
ints[49], ints[50], ints[51], ints[52]);
|
ints[49], ints[50], ints[51], ints[52], ints[53]);
|
||||||
if (!m || m->nbuffer != sizes[getnsize()-1]) {
|
if (!m || m->nbuffer != sizes[getnsize()-1]) {
|
||||||
mju_closeResource(r);
|
mju_closeResource(r);
|
||||||
mju_warning("Corrupted model, wrong size parameters");
|
mju_warning("Corrupted model, wrong size parameters");
|
||||||
@@ -1791,7 +1792,8 @@ const char* mj_validateReferences(const mjModel* m) {
|
|||||||
X(name_numericadr, nnumeric, nnames , 0 ) \
|
X(name_numericadr, nnumeric, nnames , 0 ) \
|
||||||
X(name_textadr, ntext, nnames , 0 ) \
|
X(name_textadr, ntext, nnames , 0 ) \
|
||||||
X(name_tupleadr, ntuple, nnames , 0 ) \
|
X(name_tupleadr, ntuple, nnames , 0 ) \
|
||||||
X(name_keyadr, nkey, nnames , 0 )
|
X(name_keyadr, nkey, nnames , 0 ) \
|
||||||
|
X(mesh_assetpathadr, nmesh, npaths , 0 )
|
||||||
|
|
||||||
#define X(adrarray, nadrs, ntarget, numarray) { \
|
#define X(adrarray, nadrs, ntarget, numarray) { \
|
||||||
int *nums = (numarray); \
|
int *nums = (numarray); \
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ mjModel* mj_makeModel(int nq, int nv, int nu, int na, int nbody, int nbvh, int n
|
|||||||
int ntuple, int ntupledata, int nkey, int nmocap, int nplugin,
|
int ntuple, int ntupledata, int nkey, int nmocap, int nplugin,
|
||||||
int npluginattr, int nuser_body, int nuser_jnt, int nuser_geom,
|
int npluginattr, int nuser_body, int nuser_jnt, int nuser_geom,
|
||||||
int nuser_site, int nuser_cam, int nuser_tendon, int nuser_actuator,
|
int nuser_site, int nuser_cam, int nuser_tendon, int nuser_actuator,
|
||||||
int nuser_sensor, int nnames);
|
int nuser_sensor, int nnames, int npaths);
|
||||||
|
|
||||||
// copy mjModel; allocate new if dest is NULL
|
// copy mjModel; allocate new if dest is NULL
|
||||||
MJAPI mjModel* mj_copyModel(mjModel* dest, const mjModel* src);
|
MJAPI mjModel* mj_copyModel(mjModel* dest, const mjModel* src);
|
||||||
|
|||||||
+41
-3
@@ -275,6 +275,7 @@ void mjCModel::Clear(void) {
|
|||||||
ntupledata = 0;
|
ntupledata = 0;
|
||||||
npluginattr = 0;
|
npluginattr = 0;
|
||||||
nnames = 0;
|
nnames = 0;
|
||||||
|
npaths = 0;
|
||||||
memory = -1;
|
memory = -1;
|
||||||
nstack = -1;
|
nstack = -1;
|
||||||
nemax = 0;
|
nemax = 0;
|
||||||
@@ -1002,6 +1003,18 @@ void mjCModel::SetSizes(void) {
|
|||||||
for (int i=0; i<nkey; i++) nnames += (int)keys[i]->name.length() + 1;
|
for (int i=0; i<nkey; i++) nnames += (int)keys[i]->name.length() + 1;
|
||||||
for (int i=0; i<nplugin; i++) nnames += (int)plugins[i]->name.length() + 1;
|
for (int i=0; i<nplugin; i++) nnames += (int)plugins[i]->name.length() + 1;
|
||||||
|
|
||||||
|
// npaths
|
||||||
|
npaths = 0;
|
||||||
|
for (int i=0; i<nmesh; i++) {
|
||||||
|
if (meshes[i]->file().empty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
npaths += (int)meshes[i]->file().length() + 1;
|
||||||
|
}
|
||||||
|
if (npaths == 0) {
|
||||||
|
npaths = 1;
|
||||||
|
}
|
||||||
|
|
||||||
// nemax
|
// nemax
|
||||||
for (int i=0; i<neq; i++)
|
for (int i=0; i<neq; i++)
|
||||||
if (equalities[i]->type==mjEQ_CONNECT) {
|
if (equalities[i]->type==mjEQ_CONNECT) {
|
||||||
@@ -1197,7 +1210,6 @@ void mjCModel::LengthRange(mjModel* m, mjData* data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// process names from one list: concatenate, compute addresses
|
// process names from one list: concatenate, compute addresses
|
||||||
template <class T>
|
template <class T>
|
||||||
static int namelist(vector<T*>& list, int adr, int* name_adr, char* names, int* map) {
|
static int namelist(vector<T*>& list, int adr, int* name_adr, char* names, int* map) {
|
||||||
@@ -1313,6 +1325,30 @@ void mjCModel::CopyNames(mjModel* m) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void mjCModel::CopyPaths(mjModel* m) {
|
||||||
|
// start with 0 address.
|
||||||
|
size_t adr = 0;
|
||||||
|
m->paths[0] = 0;
|
||||||
|
|
||||||
|
for (unsigned int i=0; i<meshes.size(); i++) {
|
||||||
|
if (meshes[i]->file().empty()) {
|
||||||
|
m->mesh_assetpathadr[i] = -1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
m->mesh_assetpathadr[i] = adr;
|
||||||
|
|
||||||
|
// copy path
|
||||||
|
size_t path_size = meshes[i]->file().size();
|
||||||
|
memcpy(m->paths+adr, meshes[i]->file().c_str(), path_size);
|
||||||
|
adr += path_size;
|
||||||
|
|
||||||
|
// append 0
|
||||||
|
m->paths[adr] = 0;
|
||||||
|
adr++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// copy objects inside kinematic tree
|
// copy objects inside kinematic tree
|
||||||
void mjCModel::CopyTree(mjModel* m) {
|
void mjCModel::CopyTree(mjModel* m) {
|
||||||
@@ -2703,7 +2739,7 @@ void mjCModel::TryCompile(mjModel*& m, mjData*& d, const mjVFS* vfs) {
|
|||||||
nnumeric, nnumericdata, ntext, ntextdata,
|
nnumeric, nnumericdata, ntext, ntextdata,
|
||||||
ntuple, ntupledata, nkey, nmocap, nplugin, npluginattr,
|
ntuple, ntupledata, nkey, nmocap, nplugin, npluginattr,
|
||||||
nuser_body, nuser_jnt, nuser_geom, nuser_site, nuser_cam,
|
nuser_body, nuser_jnt, nuser_geom, nuser_site, nuser_cam,
|
||||||
nuser_tendon, nuser_actuator, nuser_sensor, nnames);
|
nuser_tendon, nuser_actuator, nuser_sensor, nnames, npaths);
|
||||||
if (!m) {
|
if (!m) {
|
||||||
throw mjCError(0, "could not create mjModel");
|
throw mjCError(0, "could not create mjModel");
|
||||||
}
|
}
|
||||||
@@ -2712,6 +2748,7 @@ void mjCModel::TryCompile(mjModel*& m, mjData*& d, const mjVFS* vfs) {
|
|||||||
m->opt = option;
|
m->opt = option;
|
||||||
m->vis = visual;
|
m->vis = visual;
|
||||||
CopyNames(m);
|
CopyNames(m);
|
||||||
|
CopyPaths(m);
|
||||||
CopyTree(m);
|
CopyTree(m);
|
||||||
|
|
||||||
// assign plugin slots and copy plugin config attributes
|
// assign plugin slots and copy plugin config attributes
|
||||||
@@ -2918,7 +2955,8 @@ bool mjCModel::CopyBack(const mjModel* m) {
|
|||||||
neq!=m->neq || ntendon!=m->ntendon || nwrap!=m->nwrap || nsensor!=m->nsensor ||
|
neq!=m->neq || ntendon!=m->ntendon || nwrap!=m->nwrap || nsensor!=m->nsensor ||
|
||||||
nnumeric!=m->nnumeric || nnumericdata!=m->nnumericdata || ntext!=m->ntext ||
|
nnumeric!=m->nnumeric || nnumericdata!=m->nnumericdata || ntext!=m->ntext ||
|
||||||
ntextdata!=m->ntextdata || nnames!=m->nnames || nM!=m->nM || nD!=m->nD ||
|
ntextdata!=m->ntextdata || nnames!=m->nnames || nM!=m->nM || nD!=m->nD ||
|
||||||
nB!=m->nB || nemax!=m->nemax || nconmax!=m->nconmax || njmax!=m->njmax) {
|
nB!=m->nB || nemax!=m->nemax || nconmax!=m->nconmax || njmax!=m->njmax ||
|
||||||
|
npaths!=m->npaths) {
|
||||||
errInfo = mjCError(0, "incompatible models in CopyBack");
|
errInfo = mjCError(0, "incompatible models in CopyBack");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -182,6 +182,7 @@ class mjCModel {
|
|||||||
void AutoSpringDamper(mjModel*);// automatic stiffness and damping computation
|
void AutoSpringDamper(mjModel*);// automatic stiffness and damping computation
|
||||||
void LengthRange(mjModel*, mjData*); // compute actuator lengthrange
|
void LengthRange(mjModel*, mjData*); // compute actuator lengthrange
|
||||||
void CopyNames(mjModel*); // copy names, compute name addresses
|
void CopyNames(mjModel*); // copy names, compute name addresses
|
||||||
|
void CopyPaths(mjModel*); // copy paths, compute path addresses
|
||||||
void CopyObjects(mjModel*); // copy objects outside kinematic tree
|
void CopyObjects(mjModel*); // copy objects outside kinematic tree
|
||||||
void CopyTree(mjModel*); // copy objects inside kinematic tree
|
void CopyTree(mjModel*); // copy objects inside kinematic tree
|
||||||
|
|
||||||
@@ -235,6 +236,7 @@ class mjCModel {
|
|||||||
int ntupledata; // number of objects in all tuple fields
|
int ntupledata; // number of objects in all tuple fields
|
||||||
int npluginattr; // number of chars in all plugin config attributes
|
int npluginattr; // number of chars in all plugin config attributes
|
||||||
int nnames; // number of chars in all names
|
int nnames; // number of chars in all names
|
||||||
|
int npaths; // number of chars in all paths
|
||||||
int nM; // number of non-zeros in sparse inertia matrix
|
int nM; // number of non-zeros in sparse inertia matrix
|
||||||
int nD; // number of non-zeros in sparse dof-dof matrix
|
int nD; // number of non-zeros in sparse dof-dof matrix
|
||||||
int nB; // number of non-zeros in sparse body-dof matrix
|
int nB; // number of non-zeros in sparse body-dof matrix
|
||||||
|
|||||||
@@ -321,6 +321,7 @@ mjCModel* mjParseXML(const char* filename, const mjVFS* vfs, char* error, int er
|
|||||||
// this is separate from the Parser to allow multiple URDFs to be loaded.
|
// this is separate from the Parser to allow multiple URDFs to be loaded.
|
||||||
model->strippath = true;
|
model->strippath = true;
|
||||||
model->fusestatic = true;
|
model->fusestatic = true;
|
||||||
|
model->discardvisual = true;
|
||||||
|
|
||||||
parser.SetModel(model);
|
parser.SetModel(model);
|
||||||
parser.Parse(root);
|
parser.Parse(root);
|
||||||
|
|||||||
@@ -87,9 +87,6 @@ void mjXURDF::Parse(
|
|||||||
int id_parent, id_child;
|
int id_parent, id_child;
|
||||||
urPrefix = prefix;
|
urPrefix = prefix;
|
||||||
|
|
||||||
// set compiler defaults suitable for URDF
|
|
||||||
model->discardvisual = true;
|
|
||||||
|
|
||||||
// parse MuJoCo sections (not part of URDF)
|
// parse MuJoCo sections (not part of URDF)
|
||||||
XMLElement* mjc = FindSubElem(root, "mujoco");
|
XMLElement* mjc = FindSubElem(root, "mujoco");
|
||||||
if (mjc) {
|
if (mjc) {
|
||||||
|
|||||||
@@ -375,6 +375,9 @@ TEST_F(MjCMeshTest, SaveMeshOnce) {
|
|||||||
const std::string xml_path = GetTestDataFilePath(kCubePath);
|
const std::string xml_path = GetTestDataFilePath(kCubePath);
|
||||||
std::array<char, 1024> error;
|
std::array<char, 1024> error;
|
||||||
mjModel* model = mj_loadXML(xml_path.c_str(), 0, error.data(), error.size());
|
mjModel* model = mj_loadXML(xml_path.c_str(), 0, error.data(), error.size());
|
||||||
|
// Confirm the mesh file is loaded and stored in paths
|
||||||
|
EXPECT_EQ(
|
||||||
|
std::string(&model->paths[model->mesh_assetpathadr[0]]), "cube.obj");
|
||||||
std::string saved_xml = SaveAndReadXml(model);
|
std::string saved_xml = SaveAndReadXml(model);
|
||||||
EXPECT_THAT(saved_xml, Not(testing::HasSubstr("vertex")));
|
EXPECT_THAT(saved_xml, Not(testing::HasSubstr("vertex")));
|
||||||
mj_deleteModel(model);
|
mj_deleteModel(model);
|
||||||
|
|||||||
@@ -5095,6 +5095,7 @@ public unsafe struct mjModel_ {
|
|||||||
public int nuser_sensor;
|
public int nuser_sensor;
|
||||||
public int nnames;
|
public int nnames;
|
||||||
public int nnames_map;
|
public int nnames_map;
|
||||||
|
public int npaths;
|
||||||
public int nM;
|
public int nM;
|
||||||
public int nD;
|
public int nD;
|
||||||
public int nB;
|
public int nB;
|
||||||
@@ -5249,6 +5250,7 @@ public unsafe struct mjModel_ {
|
|||||||
public int* mesh_graphadr;
|
public int* mesh_graphadr;
|
||||||
public double* mesh_pos;
|
public double* mesh_pos;
|
||||||
public double* mesh_quat;
|
public double* mesh_quat;
|
||||||
|
public int* mesh_assetpathadr;
|
||||||
public float* mesh_vert;
|
public float* mesh_vert;
|
||||||
public float* mesh_normal;
|
public float* mesh_normal;
|
||||||
public float* mesh_texcoord;
|
public float* mesh_texcoord;
|
||||||
@@ -5421,6 +5423,7 @@ public unsafe struct mjModel_ {
|
|||||||
public int* name_pluginadr;
|
public int* name_pluginadr;
|
||||||
public char* names;
|
public char* names;
|
||||||
public int* names_map;
|
public int* names_map;
|
||||||
|
public char* paths;
|
||||||
}
|
}
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
@@ -5944,6 +5947,7 @@ public unsafe struct model {
|
|||||||
public int nwrap;
|
public int nwrap;
|
||||||
public int nsensor;
|
public int nsensor;
|
||||||
public int nnames;
|
public int nnames;
|
||||||
|
public int npaths;
|
||||||
public int nsensordata;
|
public int nsensordata;
|
||||||
public mjOption_ opt;
|
public mjOption_ opt;
|
||||||
public mjVisual_ vis;
|
public mjVisual_ vis;
|
||||||
@@ -6002,6 +6006,7 @@ public unsafe struct model {
|
|||||||
public int* mesh_bvhnum;
|
public int* mesh_bvhnum;
|
||||||
public int* mesh_texcoordadr;
|
public int* mesh_texcoordadr;
|
||||||
public int* mesh_graphadr;
|
public int* mesh_graphadr;
|
||||||
|
public int* mesh_assetpathadr;
|
||||||
public int* skin_matid;
|
public int* skin_matid;
|
||||||
public int* skin_group;
|
public int* skin_group;
|
||||||
public float* skin_rgba;
|
public float* skin_rgba;
|
||||||
@@ -6070,6 +6075,7 @@ public unsafe struct model {
|
|||||||
public int* name_tendonadr;
|
public int* name_tendonadr;
|
||||||
public int* name_actuatoradr;
|
public int* name_actuatoradr;
|
||||||
public char* names;
|
public char* names;
|
||||||
|
public char* paths;
|
||||||
}
|
}
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
|||||||
Reference in New Issue
Block a user