Add configurable octree max depth for meshes.
The maximum depth of the octree used for SDF generation can now be specified in the mesh definition via `mjsMesh::octree_maxdepth`. The default value is 6. PiperOrigin-RevId: 912494999 Change-Id: I6d828d1d3999b99d1210a6829a05b04fac591e1f
This commit is contained in:
committed by
Copybara-Service
parent
531a571dda
commit
8cef5bb978
@@ -2294,6 +2294,7 @@ typedef struct mjsMesh_ { // mesh specification
|
|||||||
mjIntVec* userfacetexcoord; // user texcoord indices
|
mjIntVec* userfacetexcoord; // user texcoord indices
|
||||||
mjsPlugin plugin; // sdf plugin
|
mjsPlugin plugin; // sdf plugin
|
||||||
mjString* material; // name of material
|
mjString* material; // name of material
|
||||||
|
int octree_maxdepth; // max octree depth
|
||||||
mjString* info; // message appended to compiler errors
|
mjString* info; // message appended to compiler errors
|
||||||
} mjsMesh;
|
} mjsMesh;
|
||||||
typedef struct mjsHField_ { // height field specification
|
typedef struct mjsHField_ { // height field specification
|
||||||
|
|||||||
@@ -490,6 +490,7 @@ typedef struct mjsMesh_ { // mesh specification
|
|||||||
mjIntVec* userfacetexcoord; // user texcoord indices
|
mjIntVec* userfacetexcoord; // user texcoord indices
|
||||||
mjsPlugin plugin; // sdf plugin
|
mjsPlugin plugin; // sdf plugin
|
||||||
mjString* material; // name of material
|
mjString* material; // name of material
|
||||||
|
int octree_maxdepth; // max octree depth
|
||||||
mjString* info; // message appended to compiler errors
|
mjString* info; // message appended to compiler errors
|
||||||
} mjsMesh;
|
} mjsMesh;
|
||||||
|
|
||||||
|
|||||||
@@ -8461,6 +8461,11 @@ STRUCTS: Mapping[str, StructDecl] = dict([
|
|||||||
),
|
),
|
||||||
doc='name of material',
|
doc='name of material',
|
||||||
),
|
),
|
||||||
|
StructFieldDecl(
|
||||||
|
name='octree_maxdepth',
|
||||||
|
type=ValueType(name='int'),
|
||||||
|
doc='max octree depth',
|
||||||
|
),
|
||||||
StructFieldDecl(
|
StructFieldDecl(
|
||||||
name='info',
|
name='info',
|
||||||
type=PointerType(
|
type=PointerType(
|
||||||
|
|||||||
@@ -243,6 +243,7 @@ void mjs_defaultMesh(mjsMesh* mesh) {
|
|||||||
mesh->scale[0] = mesh->scale[1] = mesh->scale[2] = 1;
|
mesh->scale[0] = mesh->scale[1] = mesh->scale[2] = 1;
|
||||||
mesh->maxhullvert = -1;
|
mesh->maxhullvert = -1;
|
||||||
mesh->inertia = mjMESH_INERTIA_LEGACY;
|
mesh->inertia = mjMESH_INERTIA_LEGACY;
|
||||||
|
mesh->octree_maxdepth = 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -782,6 +782,7 @@ void mjCMesh::TryCompile(const mjVFS* vfs) {
|
|||||||
} else if (octree_.NumNodes() == 0) {
|
} else if (octree_.NumNodes() == 0) {
|
||||||
std::vector<double> dvert(vert_.begin(), vert_.end());
|
std::vector<double> dvert(vert_.begin(), vert_.end());
|
||||||
octree_.SetFace(dvert, face_);
|
octree_.SetFace(dvert, face_);
|
||||||
|
octree_.SetMaxDepth(spec.octree_maxdepth);
|
||||||
octree_.CreateOctree(aamm_);
|
octree_.CreateOctree(aamm_);
|
||||||
if (!plugin.active) {
|
if (!plugin.active) {
|
||||||
octree_.ComputeSdfCoeffs(dvert.data(), nvert(), face_.data(), nface(), tree_);
|
octree_.ComputeSdfCoeffs(dvert.data(), nvert(), face_.data(), nface(), tree_);
|
||||||
@@ -1532,6 +1533,7 @@ void mjCMesh::Process() {
|
|||||||
// make octree
|
// make octree
|
||||||
if (needsdf) {
|
if (needsdf) {
|
||||||
octree_.SetFace(dvert, face_);
|
octree_.SetFace(dvert, face_);
|
||||||
|
octree_.SetMaxDepth(spec.octree_maxdepth);
|
||||||
octree_.CreateOctree(aamm_);
|
octree_.CreateOctree(aamm_);
|
||||||
|
|
||||||
if (!plugin.active) {
|
if (!plugin.active) {
|
||||||
|
|||||||
@@ -1285,7 +1285,7 @@ void mjCOctree::MakeOctree(const std::vector<Triangle*>& elements, const double
|
|||||||
}
|
}
|
||||||
|
|
||||||
// skip if the box is empty
|
// skip if the box is empty
|
||||||
if (colliding.empty() || task.lev >= 6) {
|
if (colliding.empty() || task.lev >= max_depth_) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -270,6 +270,7 @@ struct OctreeTask {
|
|||||||
struct mjCOctree_ {
|
struct mjCOctree_ {
|
||||||
int nnode_ = 0;
|
int nnode_ = 0;
|
||||||
int nvert_ = 0;
|
int nvert_ = 0;
|
||||||
|
int max_depth_ = 6; // max octree depth (default 6)
|
||||||
std::vector<OctNode> node_;
|
std::vector<OctNode> node_;
|
||||||
std::vector<Triangle> face_; // mesh faces (nmeshface x 3)
|
std::vector<Triangle> face_; // mesh faces (nmeshface x 3)
|
||||||
std::vector<Point> vert_; // octree vertices (nvert x 3)
|
std::vector<Point> vert_; // octree vertices (nvert x 3)
|
||||||
@@ -308,6 +309,10 @@ class mjCOctree : public mjCOctree_ {
|
|||||||
void AddCoeff(int n, int v, double coeff) { node_[n].coeff[v] = coeff; }
|
void AddCoeff(int n, int v, double coeff) { node_[n].coeff[v] = coeff; }
|
||||||
double Coeff(int n, int v) const { return node_[n].coeff[v]; }
|
double Coeff(int n, int v) const { return node_[n].coeff[v]; }
|
||||||
|
|
||||||
|
// Set max octree depth (default 6)
|
||||||
|
void SetMaxDepth(int depth) { max_depth_ = depth; }
|
||||||
|
int MaxDepth() const { return max_depth_; }
|
||||||
|
|
||||||
// Set number of Laplacian smoothing iterations (0 = disabled, default)
|
// Set number of Laplacian smoothing iterations (0 = disabled, default)
|
||||||
void SetSmoothingIterations(int iterations) { smoothing_iterations_ = iterations; }
|
void SetSmoothingIterations(int iterations) { smoothing_iterations_ = iterations; }
|
||||||
int SmoothingIterations() const { return smoothing_iterations_; }
|
int SmoothingIterations() const { return smoothing_iterations_; }
|
||||||
@@ -1208,6 +1213,7 @@ class mjCMesh: public mjCMesh_, private mjsMesh {
|
|||||||
|
|
||||||
// octree
|
// octree
|
||||||
const mjCOctree& octree() { return octree_; }
|
const mjCOctree& octree() { return octree_; }
|
||||||
|
mjCOctree& mutable_octree() { return octree_; }
|
||||||
|
|
||||||
void Compile(const mjVFS* vfs); // compiler
|
void Compile(const mjVFS* vfs); // compiler
|
||||||
double* GetPosPtr(); // get position
|
double* GetPosPtr(); // get position
|
||||||
|
|||||||
@@ -1501,6 +1501,8 @@ TEST_F(MjCMeshTest, OctreeIsBalanced) {
|
|||||||
mjSpec* spec = mj_parseXML(xml_path.c_str(), 0, error.data(), error.size());
|
mjSpec* spec = mj_parseXML(xml_path.c_str(), 0, error.data(), error.size());
|
||||||
mjsGeom* geom = mjs_asGeom(mjs_firstElement(spec, mjOBJ_GEOM));
|
mjsGeom* geom = mjs_asGeom(mjs_firstElement(spec, mjOBJ_GEOM));
|
||||||
geom->type = mjGEOM_SDF;
|
geom->type = mjGEOM_SDF;
|
||||||
|
mjsMesh* mesh = mjs_asMesh(mjs_firstElement(spec, mjOBJ_MESH));
|
||||||
|
mesh->octree_maxdepth = 5;
|
||||||
mjModel* model = mj_compile(spec, 0);
|
mjModel* model = mj_compile(spec, 0);
|
||||||
ASSERT_THAT(model, NotNull()) << error.data();
|
ASSERT_THAT(model, NotNull()) << error.data();
|
||||||
EXPECT_GT(model->mesh_octnum[0], 0);
|
EXPECT_GT(model->mesh_octnum[0], 0);
|
||||||
@@ -1564,6 +1566,8 @@ TEST_F(MjCMeshTest, OctreeHangingNodeInterpolation) {
|
|||||||
mjSpec* spec = mj_parseXML(xml_path.c_str(), 0, error.data(), error.size());
|
mjSpec* spec = mj_parseXML(xml_path.c_str(), 0, error.data(), error.size());
|
||||||
mjsGeom* geom = mjs_asGeom(mjs_firstElement(spec, mjOBJ_GEOM));
|
mjsGeom* geom = mjs_asGeom(mjs_firstElement(spec, mjOBJ_GEOM));
|
||||||
geom->type = mjGEOM_SDF;
|
geom->type = mjGEOM_SDF;
|
||||||
|
mjsMesh* mesh = mjs_asMesh(mjs_firstElement(spec, mjOBJ_MESH));
|
||||||
|
mesh->octree_maxdepth = 5;
|
||||||
mjModel* model = mj_compile(spec, 0);
|
mjModel* model = mj_compile(spec, 0);
|
||||||
ASSERT_THAT(model, NotNull()) << error.data();
|
ASSERT_THAT(model, NotNull()) << error.data();
|
||||||
EXPECT_GT(model->mesh_octnum[0], 0);
|
EXPECT_GT(model->mesh_octnum[0], 0);
|
||||||
|
|||||||
@@ -6246,6 +6246,12 @@ struct MjsMesh {
|
|||||||
*(ptr_->material) = value;
|
*(ptr_->material) = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
int octree_maxdepth() const {
|
||||||
|
return ptr_->octree_maxdepth;
|
||||||
|
}
|
||||||
|
void set_octree_maxdepth(int value) {
|
||||||
|
ptr_->octree_maxdepth = value;
|
||||||
|
}
|
||||||
mjString info() const {
|
mjString info() const {
|
||||||
return (ptr_ && ptr_->info) ? *(ptr_->info) : "";
|
return (ptr_ && ptr_->info) ? *(ptr_->info) : "";
|
||||||
}
|
}
|
||||||
@@ -12782,6 +12788,7 @@ EMSCRIPTEN_BINDINGS(mujoco_bindings) {
|
|||||||
.property("material", &MjsMesh::material, &MjsMesh::set_material, reference())
|
.property("material", &MjsMesh::material, &MjsMesh::set_material, reference())
|
||||||
.property("maxhullvert", &MjsMesh::maxhullvert, &MjsMesh::set_maxhullvert, reference())
|
.property("maxhullvert", &MjsMesh::maxhullvert, &MjsMesh::set_maxhullvert, reference())
|
||||||
.property("needsdf", &MjsMesh::needsdf, &MjsMesh::set_needsdf, reference())
|
.property("needsdf", &MjsMesh::needsdf, &MjsMesh::set_needsdf, reference())
|
||||||
|
.property("octree_maxdepth", &MjsMesh::octree_maxdepth, &MjsMesh::set_octree_maxdepth, reference())
|
||||||
.property("plugin", &MjsMesh::plugin, reference())
|
.property("plugin", &MjsMesh::plugin, reference())
|
||||||
.property("refpos", &MjsMesh::refpos)
|
.property("refpos", &MjsMesh::refpos)
|
||||||
.property("refquat", &MjsMesh::refquat)
|
.property("refquat", &MjsMesh::refquat)
|
||||||
|
|||||||
Reference in New Issue
Block a user