Add mjs_makeMesh to create a builtin mesh.

PiperOrigin-RevId: 788538127
Change-Id: I999733399a1a0da07b0f915f34d31364ab8b3b52
This commit is contained in:
Alessio Quaglino
2025-07-29 11:30:19 -07:00
committed by Copybara-Service
parent 46dc67b7eb
commit 89f4789085
23 changed files with 569 additions and 649 deletions
+15
View File
@@ -791,6 +791,21 @@ ENUMS: Mapping[str, EnumDecl] = dict([
('mjMESH_INERTIA_SHELL', 3),
]),
)),
('mjtMeshBuiltin',
EnumDecl(
name='mjtMeshBuiltin',
declname='enum mjtMeshBuiltin_',
values=dict([
('mjMESH_BUILTIN_NONE', 0),
('mjMESH_BUILTIN_SPHERE', 1),
('mjMESH_BUILTIN_HEMISPHERE', 2),
('mjMESH_BUILTIN_PRISM', 3),
('mjMESH_BUILTIN_CONE', 4),
('mjMESH_BUILTIN_TORUS', 5),
('mjMESH_BUILTIN_WEDGE', 6),
('mjMESH_BUILTIN_PLATE', 7),
]),
)),
('mjtBuiltin',
EnumDecl(
name='mjtBuiltin',
+28
View File
@@ -9869,6 +9869,34 @@ FUNCTIONS: Mapping[str, FunctionDecl] = dict([
),
doc='Add material.',
)),
('mjs_makeMesh',
FunctionDecl(
name='mjs_makeMesh',
return_type=ValueType(name='int'),
parameters=(
FunctionParameterDecl(
name='mesh',
type=PointerType(
inner_type=ValueType(name='mjsMesh'),
),
),
FunctionParameterDecl(
name='builtin',
type=ValueType(name='mjtMeshBuiltin'),
),
FunctionParameterDecl(
name='params',
type=PointerType(
inner_type=ValueType(name='double'),
),
),
FunctionParameterDecl(
name='nparams',
type=ValueType(name='int'),
),
),
doc='Sets the vertices and normals of a mesh.',
)),
('mjs_getSpec',
FunctionDecl(
name='mjs_getSpec',
+32
View File
@@ -1001,6 +1001,38 @@ PYBIND11_MODULE(_specs, m) {
mjs_setDefault(self.element, &default_);
},
py::return_value_policy::reference_internal);
mjsMesh.def(
"make_wedge",
[](raw::MjsMesh* self, std::array<int, 2>& resolution, double radius,
std::array<double, 2>& fov, double gamma) {
double params[5] = {static_cast<double>(resolution[0]),
static_cast<double>(resolution[1]), fov[0], fov[1],
gamma};
if (mjs_makeMesh(self, mjMESH_BUILTIN_WEDGE, params, 5)) {
throw pybind11::value_error(mjs_getError(mjs_getSpec(self->element)));
}
},
py::arg("resolution") = std::array<int, 2>{0, 0}, py::arg("radius"),
py::arg("fov") = std::array<double, 2>{0, 0}, py::arg("gamma") = 0);
mjsMesh.def(
"make_prism",
[](raw::MjsMesh* self, int nedge) {
double params[1] = {static_cast<double>(nedge)};
if (mjs_makeMesh(self, mjMESH_BUILTIN_PRISM, params, 1)) {
throw pybind11::value_error(mjs_getError(mjs_getSpec(self->element)));
}
},
py::arg("nedge"));
mjsMesh.def(
"make_plate",
[](raw::MjsMesh* self, std::array<int, 2>& resolution) {
double params[2] = {static_cast<double>(resolution[0]),
static_cast<double>(resolution[1])};
if (mjs_makeMesh(self, mjMESH_BUILTIN_PLATE, params, 2)) {
throw pybind11::value_error(mjs_getError(mjs_getSpec(self->element)));
}
},
py::arg("resolution") = std::array<int, 2>{0, 0});
// ============================= MJSPAIR =====================================
mjSpec.def("delete", [](MjSpec& self, raw::MjsPair& obj) {
+8
View File
@@ -484,6 +484,14 @@ class SpecsTest(absltest.TestCase):
# Check that the state is the same.
np.testing.assert_array_equal(state1, state2)
def test_make_mesh(self):
spec = mujoco.MjSpec()
mesh = spec.add_mesh(name='wedge')
mesh.make_wedge(resolution=[25, 25], radius=1, fov=[90, 45], gamma=0)
model = spec.compile()
self.assertEqual(model.nmesh, 1)
self.assertEqual(model.nmeshvert, 25 * 25)
def test_compile_errors_with_line_info(self):
spec = mujoco.MjSpec()