Add flex_bendingadr to mjModel.

PiperOrigin-RevId: 909088123
Change-Id: If062335d0aa3702c1e0b082dd9e29c3be0e76ea6
This commit is contained in:
Alessio Quaglino
2026-05-02 00:13:09 -07:00
committed by Copybara-Service
parent b2feed63e4
commit dbd451138c
10 changed files with 115 additions and 78 deletions
+15 -14
View File
@@ -205,9 +205,9 @@ void mj_makeModel(mjModel** dest,
mjtSize nbvhdynamic, mjtSize noct, mjtSize njnt, mjtSize ntree, mjtSize nM, mjtSize nB,
mjtSize nC, mjtSize nD, mjtSize ngeom, mjtSize nsite, mjtSize ncam, mjtSize nlight,
mjtSize nflex, mjtSize nflexnode, mjtSize nflexvert, mjtSize nflexedge, mjtSize nflexelem,
mjtSize nflexelemdata, mjtSize nflexstiffness, mjtSize nflexelemedge, mjtSize nflexshelldata,
mjtSize nflexevpair, mjtSize nflextexcoord, mjtSize nJfe, mjtSize nJfv, mjtSize nmesh,
mjtSize nmeshvert, mjtSize nmeshnormal, mjtSize nmeshtexcoord, mjtSize nmeshface,
mjtSize nflexelemdata, mjtSize nflexstiffness, mjtSize nflexbending, mjtSize nflexelemedge,
mjtSize nflexshelldata, mjtSize nflexevpair, mjtSize nflextexcoord, mjtSize nJfe, mjtSize nJfv,
mjtSize nmesh, mjtSize nmeshvert, mjtSize nmeshnormal, mjtSize nmeshtexcoord, mjtSize nmeshface,
mjtSize nmeshgraph, mjtSize nmeshpoly, mjtSize nmeshpolyvert, mjtSize nmeshpolymap,
mjtSize nskin, mjtSize nskinvert, mjtSize nskintexvert, mjtSize nskinface, mjtSize nskinbone,
mjtSize nskinbonevert, mjtSize nhfield, mjtSize nhfielddata, mjtSize ntex, mjtSize ntexdata,
@@ -294,6 +294,7 @@ void mj_makeModel(mjModel** dest,
m->nflexelem = nflexelem;
m->nflexelemdata = nflexelemdata;
m->nflexstiffness = nflexstiffness;
m->nflexbending = nflexbending;
m->nflexelemedge = nflexelemedge;
m->nflexshelldata = nflexshelldata;
m->nflexevpair = nflexevpair;
@@ -405,16 +406,16 @@ mjModel* mj_copyModel(mjModel* dest, const mjModel* src) {
src->nbvhdynamic, src->noct, src->njnt, src->ntree, src->nM, src->nB, src->nC, src->nD,
src->ngeom, src->nsite, src->ncam, src->nlight, src->nflex, src->nflexnode, src->nflexvert,
src->nflexedge, src->nflexelem, src->nflexelemdata, src->nflexstiffness,
src->nflexelemedge, src->nflexshelldata, src->nflexevpair, src->nflextexcoord, src->nJfe,
src->nJfv, src->nmesh, src->nmeshvert, src->nmeshnormal, src->nmeshtexcoord, src->nmeshface,
src->nmeshgraph, src->nmeshpoly, src->nmeshpolyvert, src->nmeshpolymap, src->nskin,
src->nskinvert, src->nskintexvert, src->nskinface, src->nskinbone, src->nskinbonevert,
src->nhfield, src->nhfielddata, src->ntex, src->ntexdata, src->nmat, src->npair,
src->nexclude, src->neq, src->ntendon, src->nJten, src->nwrap, src->nsensor, src->nnumeric,
src->nnumericdata, src->ntext, src->ntextdata, src->ntuple, src->ntupledata, src->nkey,
src->nmocap, src->nplugin, 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_sensor, src->nnames, src->npaths);
src->nflexbending, src->nflexelemedge, src->nflexshelldata, src->nflexevpair,
src->nflextexcoord, src->nJfe, src->nJfv, src->nmesh, src->nmeshvert, src->nmeshnormal,
src->nmeshtexcoord, src->nmeshface, src->nmeshgraph, src->nmeshpoly, src->nmeshpolyvert,
src->nmeshpolymap, src->nskin, src->nskinvert, src->nskintexvert, src->nskinface,
src->nskinbone, src->nskinbonevert, src->nhfield, src->nhfielddata, src->ntex,
src->ntexdata, src->nmat, src->npair, src->nexclude, src->neq, src->ntendon, src->nJten,
src->nwrap, src->nsensor, src->nnumeric, src->nnumericdata, src->ntext, src->ntextdata,
src->ntuple, src->ntupledata, src->nkey, src->nmocap, src->nplugin, 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_sensor, src->nnames, src->npaths);
}
if (!dest) {
mjERROR("failed to make mjModel. Invalid sizes.");
@@ -597,7 +598,7 @@ mjModel* mj_loadModelBuffer(const void* buffer, int buffer_sz) {
sizes[56], sizes[57], sizes[58], sizes[59], sizes[60], sizes[61], sizes[62],
sizes[63], sizes[64], sizes[65], sizes[66], sizes[67], sizes[68], sizes[69],
sizes[70], sizes[71], sizes[72], sizes[73], sizes[74], sizes[75], sizes[76],
sizes[77], sizes[78]);
sizes[77], sizes[78], sizes[79]);
// mj_makeModel may fail if the input buffer has invalid sizes
if (!m) {
+5 -5
View File
@@ -52,11 +52,11 @@ void mj_makeModel(mjModel** dest,
mjtSize nbvhdynamic, mjtSize noct, mjtSize njnt, mjtSize ntree, mjtSize nM, mjtSize nB,
mjtSize nC, mjtSize nD, mjtSize ngeom, mjtSize nsite, mjtSize ncam, mjtSize nlight,
mjtSize nflex, mjtSize nflexnode, mjtSize nflexvert, mjtSize nflexedge, mjtSize nflexelem,
mjtSize nflexelemdata, mjtSize nflexstiffness, mjtSize nflexelemedge, mjtSize nflexshelldata, mjtSize nflexevpair,
mjtSize nflextexcoord, mjtSize nJfe, mjtSize nJfv, mjtSize nmesh, mjtSize nmeshvert,
mjtSize nmeshnormal, mjtSize nmeshtexcoord, mjtSize nmeshface, mjtSize nmeshgraph,
mjtSize nmeshpoly, mjtSize nmeshpolyvert, mjtSize nmeshpolymap, mjtSize nskin,
mjtSize nskinvert, mjtSize nskintexvert, mjtSize nskinface, mjtSize nskinbone,
mjtSize nflexelemdata, mjtSize nflexstiffness, mjtSize nflexbending, mjtSize nflexelemedge,
mjtSize nflexshelldata, mjtSize nflexevpair, mjtSize nflextexcoord, mjtSize nJfe, mjtSize nJfv,
mjtSize nmesh, mjtSize nmeshvert, mjtSize nmeshnormal, mjtSize nmeshtexcoord, mjtSize nmeshface,
mjtSize nmeshgraph, mjtSize nmeshpoly, mjtSize nmeshpolyvert, mjtSize nmeshpolymap,
mjtSize nskin, mjtSize nskinvert, mjtSize nskintexvert, mjtSize nskinface, mjtSize nskinbone,
mjtSize nskinbonevert, mjtSize nhfield, mjtSize nhfielddata, mjtSize ntex, mjtSize ntexdata,
mjtSize nmat, mjtSize npair, mjtSize nexclude, mjtSize neq, mjtSize ntendon, mjtSize nJten,
mjtSize nwrap, mjtSize nsensor, mjtSize nnumeric, mjtSize nnumericdata, mjtSize ntext,
+57 -54
View File
@@ -1195,6 +1195,7 @@ void mjCModel::Clear() {
nflexelem = 0;
nflexelemdata = 0;
nflexstiffness = 0;
nflexbending = 0;
nflexelemedge = 0;
nflexshelldata = 0;
nflexevpair = 0;
@@ -2105,6 +2106,21 @@ static size_t getpathslength(std::vector<T> list) {
return result;
}
// compute extra stiffness/bending array size for an interpolated flex
static int flexInterpExtraSize(int order, const int cellcount[3], bool shell) {
int npe, nelem;
int cx = cellcount[0], cy = cellcount[1], cz = cellcount[2];
if (shell) {
npe = (int)pow(order + 1, 2);
nelem = 2*(cy*cz + cx*cz + cx*cy);
} else {
npe = (int)pow(order + 1, 3);
nelem = cx * cy * cz;
}
int ndof_elem = 3 * npe;
return nelem * ndof_elem * ndof_elem;
}
// set array sizes
void mjCModel::SetSizes() {
// set from object list sizes
@@ -2179,6 +2195,7 @@ void mjCModel::SetSizes() {
nbvh = nbvhstatic + nbvhdynamic;
int extra_stiffness_size = 0;
int extra_bending_size = 0;
// flex counts
for (int i=0; i < nflex; i++) {
nflexnode += flexes_[i]->nnode;
@@ -2191,20 +2208,11 @@ void mjCModel::SetSizes() {
nflexevpair += (int)flexes_[i]->evpair.size()/2;
nflextexcoord += (flexes_[i]->HasTexcoord() ? flexes_[i]->get_texcoord().size()/2 : 0);
if (flexes_[i]->spec.order != 0) {
int cx = flexes_[i]->spec.cellcount[0];
int cy = flexes_[i]->spec.cellcount[1];
int cz = flexes_[i]->spec.cellcount[2];
bool shell = (flexes_[i]->elastic2d != 0);
int npe, nelem;
if (shell) {
npe = (int)pow(flexes_[i]->spec.order + 1, 2);
nelem = 2*(cy*cz + cx*cz + cx*cy);
} else {
npe = (int)pow(flexes_[i]->spec.order + 1, 3);
nelem = cx * cy * cz;
}
int ndof_elem = 3 * npe;
extra_stiffness_size += nelem * ndof_elem * ndof_elem;
int extra_size = flexInterpExtraSize(
flexes_[i]->spec.order, flexes_[i]->spec.cellcount,
flexes_[i]->elastic2d != 0);
extra_stiffness_size += extra_size;
extra_bending_size += extra_size;
}
if (flexes_[i]->interpolated || flexes_[i]->rigid) {
continue;
@@ -2256,8 +2264,9 @@ void mjCModel::SetSizes() {
}
}
// TODO: This can be compacted further when we update mjwarp to not rely on
// 21*elem_adr for non-interpolated flexes.
// 21*elem_adr for non-interpolated flexes and 17*edge_adr for bending.
nflexstiffness = nflexelem * 21 + extra_stiffness_size;
nflexbending = nflexedge * 17 + extra_bending_size;
// mesh counts
for (int i=0; i < nmesh; i++) {
@@ -3458,6 +3467,8 @@ void mjCModel::CopyObjects(mjModel* m) {
texcoord_adr = 0;
int standard_stiffness_size = 21 * m->nflexelem;
int current_extra_stiffness_adr = standard_stiffness_size;
int standard_bending_size = 17 * m->nflexedge;
int current_extra_bending_adr = standard_bending_size;
for (int i=0; i < nflex; i++) {
// get pointer
mjCFlex* pfl = flexes_[i];
@@ -3484,20 +3495,8 @@ void mjCModel::CopyObjects(mjModel* m) {
m->flex_stiffnessadr[i] = 21 * elem_adr;
} else {
m->flex_stiffnessadr[i] = current_extra_stiffness_adr;
int pcx = pfl->spec.cellcount[0];
int pcy = pfl->spec.cellcount[1];
int pcz = pfl->spec.cellcount[2];
bool shell = (pfl->elastic2d != 0);
int npe, nelem;
if (shell) {
npe = (int)pow(pfl->spec.order + 1, 2);
nelem = 2*(pcy*pcz + pcx*pcz + pcx*pcy);
} else {
npe = (int)pow(pfl->spec.order + 1, 3);
nelem = pcx * pcy * pcz;
}
int ndof_elem = 3 * npe;
current_extra_stiffness_adr += nelem * ndof_elem * ndof_elem;
current_extra_stiffness_adr += flexInterpExtraSize(
pfl->spec.order, pfl->spec.cellcount, pfl->elastic2d != 0);
}
if (!pfl->stiffness.empty()) {
@@ -3508,27 +3507,30 @@ void mjCModel::CopyObjects(mjModel* m) {
if (pfl->spec.order == 0) {
stiff_size = 21 * pfl->nelem;
} else {
int scx = pfl->spec.cellcount[0];
int scy = pfl->spec.cellcount[1];
int scz = pfl->spec.cellcount[2];
bool shell = (pfl->elastic2d != 0);
int npe, sncells;
if (shell) {
npe = (int)pow(pfl->spec.order + 1, 2);
sncells = 2*(scy*scz + scx*scz + scx*scy);
} else {
npe = (int)pow(pfl->spec.order + 1, 3);
sncells = scx * scy * scz;
}
int ndof_elem = 3 * npe;
stiff_size = sncells * ndof_elem * ndof_elem;
stiff_size = flexInterpExtraSize(
pfl->spec.order, pfl->spec.cellcount, pfl->elastic2d != 0);
}
mjuu_zerovec(m->flex_stiffness + m->flex_stiffnessadr[i], stiff_size);
}
if (!pfl->bending.empty()) {
mjuu_copyvec(m->flex_bending + 17 * edge_adr, pfl->bending.data(), pfl->bending.size());
if (pfl->spec.order == 0) {
m->flex_bendingadr[i] = 17 * edge_adr;
} else {
mjuu_zerovec(m->flex_bending + 17 * edge_adr, 17 * pfl->nedge);
m->flex_bendingadr[i] = current_extra_bending_adr;
current_extra_bending_adr += flexInterpExtraSize(
pfl->spec.order, pfl->spec.cellcount, pfl->elastic2d != 0);
}
if (!pfl->bending.empty()) {
mjuu_copyvec(m->flex_bending + m->flex_bendingadr[i], pfl->bending.data(), pfl->bending.size());
} else {
int bending_size;
if (pfl->spec.order == 0) {
bending_size = 17 * pfl->nedge;
} else {
bending_size = flexInterpExtraSize(
pfl->spec.order, pfl->spec.cellcount, pfl->elastic2d != 0);
}
mjuu_zerovec(m->flex_bending + m->flex_bendingadr[i], bending_size);
}
m->flex_damping[i] = (mjtNum)pfl->damping;
@@ -3602,7 +3604,8 @@ void mjCModel::CopyObjects(mjModel* m) {
}
if (!pfl->rigid && m->flex_edgeequality[i] == 0 &&
!pfl->edgestiffness && !pfl->edgedamping && !pfl->damping) {
!pfl->edgestiffness && !pfl->edgedamping && !pfl->damping &&
pfl->bending.empty()) {
mju_warning("flex '%s' is not rigid and has no equality constraints "
"or passive forces", pfl->name.c_str());
}
@@ -5209,13 +5212,13 @@ void mjCModel::TryCompile(mjModel*& m, mjData*& d, const mjVFS* vfs) {
mj_makeModel(&m,
nq, nv, nu, na, nbody, nbvh, nbvhstatic, nbvhdynamic, noct, njnt, ntree, nM, nB, nC,
nD, ngeom, nsite, ncam, nlight, nflex, nflexnode, nflexvert, nflexedge, nflexelem,
nflexelemdata, nflexstiffness, nflexelemedge, nflexshelldata, nflexevpair,
nflextexcoord, nJfe, nJfv, nmesh, nmeshvert, nmeshnormal, nmeshtexcoord, nmeshface,
nmeshgraph, nmeshpoly, nmeshpolyvert, nmeshpolymap, nskin, nskinvert, nskintexvert,
nskinface, nskinbone, nskinbonevert, nhfield, nhfielddata, ntex, ntexdata, nmat,
npair, nexclude, neq, ntendon, nJten, nwrap, nsensor, nnumeric, nnumericdata, ntext,
ntextdata, ntuple, ntupledata, nkey, nmocap, nplugin, npluginattr,
nuser_body, nuser_jnt, nuser_geom, nuser_site, nuser_cam,
nflexelemdata, nflexstiffness, nflexbending, nflexelemedge, nflexshelldata,
nflexevpair, nflextexcoord, nJfe, nJfv, nmesh, nmeshvert, nmeshnormal, nmeshtexcoord,
nmeshface, nmeshgraph, nmeshpoly, nmeshpolyvert, nmeshpolymap, nskin, nskinvert,
nskintexvert, nskinface, nskinbone, nskinbonevert, nhfield, nhfielddata, ntex,
ntexdata, nmat, npair, nexclude, neq, ntendon, nJten, nwrap, nsensor, nnumeric,
nnumericdata, ntext, ntextdata, ntuple, ntupledata, nkey, nmocap, nplugin,
npluginattr, nuser_body, nuser_jnt, nuser_geom, nuser_site, nuser_cam,
nuser_tendon, nuser_actuator, nuser_sensor, nnames, npaths);
if (!m) {
throw mjCError(0, "could not create mjModel");
+1
View File
@@ -97,6 +97,7 @@ class mjCModel_ : public mjsElement {
mjtSize nflexelem; // number of elements in all flexes
mjtSize nflexelemdata; // number of element vertex ids in all flexes
mjtSize nflexstiffness; // number of stiffness parameters in all flexes
mjtSize nflexbending; // number of bending parameters in all flexes
mjtSize nflexelemedge; // number of element edges in all flexes
mjtSize nflexshelldata; // number of shell fragment vertex ids in all flexes
mjtSize nflexevpair; // number of element-vertex pairs in all flexes