From e7212d86bc49427b44e772463c97c922b616d542 Mon Sep 17 00:00:00 2001 From: Sam Haves Date: Thu, 10 Jul 2025 04:58:20 -0700 Subject: [PATCH] Add maxhullvert attribute to mjcPhysics MeshCollisionAPI. PiperOrigin-RevId: 781482346 Change-Id: I0d53f9ad99ac842629243b0375907b2f91bd3b61 --- .../usd/mjcPhysics/meshCollisionAPI.h | 27 ++++++++++++++++++- .../experimental/usd/mjcPhysics/tokens.h | 4 +++ .../usd/mjcPhysics/generatedSchema.usda | 4 +++ .../usd/mjcPhysics/meshCollisionAPI.cpp | 12 +++++++++ src/experimental/usd/mjcPhysics/schema.usda | 8 ++++++ src/experimental/usd/mjcPhysics/tokens.cpp | 2 ++ .../usd/plugins/mjcf/mujoco_to_usd.cc | 4 +++ src/experimental/usd/usd_to_mjspec.cc | 5 ++++ .../usd/plugins/mjcf/mjcf_file_format_test.cc | 4 +++ 9 files changed, 69 insertions(+), 1 deletion(-) diff --git a/include/mujoco/experimental/usd/mjcPhysics/meshCollisionAPI.h b/include/mujoco/experimental/usd/mjcPhysics/meshCollisionAPI.h index b01756e4..653e6ecd 100644 --- a/include/mujoco/experimental/usd/mjcPhysics/meshCollisionAPI.h +++ b/include/mujoco/experimental/usd/mjcPhysics/meshCollisionAPI.h @@ -40,7 +40,7 @@ class SdfAssetPath; /// \class MjcPhysicsMeshCollisionAPI /// -/// API describing a Mujoco mesh collider. +/// API describing a MuJoCo mesh collider. /// /// For any described attribute \em Fallback \em Value or \em Allowed \em Values /// below that are text/tokens, the actual token is published and defined in @@ -173,6 +173,31 @@ class MjcPhysicsMeshCollisionAPI : public UsdAPISchemaBase { UsdAttribute CreateInertiaAttr(VtValue const &defaultValue = VtValue(), bool writeSparsely = false) const; + public: + // --------------------------------------------------------------------- // + // MAXHULLVERT + // --------------------------------------------------------------------- // + /// Sets an upper limit on the number of vertices in the meshes convex hull. + /// The default value of -1 means unlimited. + /// + /// | || + /// | -- | -- | + /// | Declaration | `uniform int mjc:maxhullvert = -1` | + /// | C++ Type | int | + /// | \ref Usd_Datatypes "Usd Type" | SdfValueTypeNames->Int | + /// | \ref SdfVariability "Variability" | SdfVariabilityUniform | + MJCPHYSICS_API + UsdAttribute GetMaxHullVertAttr() const; + + /// See GetMaxHullVertAttr(), and also + /// \ref Usd_Create_Or_Get_Property for when to use Get vs Create. + /// If specified, author \p defaultValue as the attribute's default, + /// sparsely (when it makes sense to do so) if \p writeSparsely is \c true - + /// the default for \p writeSparsely is \c false. + MJCPHYSICS_API + UsdAttribute CreateMaxHullVertAttr(VtValue const &defaultValue = VtValue(), + bool writeSparsely = false) const; + public: // ===================================================================== // // Feel free to add custom code below this line, it will be preserved by diff --git a/include/mujoco/experimental/usd/mjcPhysics/tokens.h b/include/mujoco/experimental/usd/mjcPhysics/tokens.h index af49243b..46ff1ad3 100644 --- a/include/mujoco/experimental/usd/mjcPhysics/tokens.h +++ b/include/mujoco/experimental/usd/mjcPhysics/tokens.h @@ -356,6 +356,10 @@ struct MjcPhysicsTokensType { /// /// MjcPhysicsJointAPI const TfToken mjcMargin; + /// \brief "mjc:maxhullvert" + /// + /// MjcPhysicsMeshCollisionAPI + const TfToken mjcMaxhullvert; /// \brief "mjc:mpos" /// /// MjcPhysicsKeyframe diff --git a/src/experimental/usd/mjcPhysics/generatedSchema.usda b/src/experimental/usd/mjcPhysics/generatedSchema.usda index d4b0b733..5efaff73 100644 --- a/src/experimental/usd/mjcPhysics/generatedSchema.usda +++ b/src/experimental/usd/mjcPhysics/generatedSchema.usda @@ -245,6 +245,10 @@ class "MjcMeshCollisionAPI" ( displayName = "Inertia" doc = "Controls how a mesh is used when mass and inertia are inferred from geometry." ) + uniform int mjc:maxhullvert = -1 ( + displayName = "Maximum Hull Vertices" + doc = "Sets an upper limit on the number of vertices in the meshes convex hull. The default value of -1 means unlimited." + ) } class "MjcActuatorAPI" ( diff --git a/src/experimental/usd/mjcPhysics/meshCollisionAPI.cpp b/src/experimental/usd/mjcPhysics/meshCollisionAPI.cpp index 9d9b00dc..e8db13f4 100644 --- a/src/experimental/usd/mjcPhysics/meshCollisionAPI.cpp +++ b/src/experimental/usd/mjcPhysics/meshCollisionAPI.cpp @@ -88,6 +88,17 @@ UsdAttribute MjcPhysicsMeshCollisionAPI::CreateInertiaAttr( /* custom = */ false, SdfVariabilityUniform, defaultValue, writeSparsely); } +UsdAttribute MjcPhysicsMeshCollisionAPI::GetMaxHullVertAttr() const { + return GetPrim().GetAttribute(MjcPhysicsTokens->mjcMaxhullvert); +} + +UsdAttribute MjcPhysicsMeshCollisionAPI::CreateMaxHullVertAttr( + VtValue const &defaultValue, bool writeSparsely) const { + return UsdSchemaBase::_CreateAttr( + MjcPhysicsTokens->mjcMaxhullvert, SdfValueTypeNames->Int, + /* custom = */ false, SdfVariabilityUniform, defaultValue, writeSparsely); +} + namespace { static inline TfTokenVector _ConcatenateAttributeNames( const TfTokenVector &left, const TfTokenVector &right) { @@ -104,6 +115,7 @@ const TfTokenVector &MjcPhysicsMeshCollisionAPI::GetSchemaAttributeNames( bool includeInherited) { static TfTokenVector localNames = { MjcPhysicsTokens->mjcInertia, + MjcPhysicsTokens->mjcMaxhullvert, }; static TfTokenVector allNames = _ConcatenateAttributeNames( UsdAPISchemaBase::GetSchemaAttributeNames(true), localNames); diff --git a/src/experimental/usd/mjcPhysics/schema.usda b/src/experimental/usd/mjcPhysics/schema.usda index cf27ceb5..e55a6f78 100644 --- a/src/experimental/usd/mjcPhysics/schema.usda +++ b/src/experimental/usd/mjcPhysics/schema.usda @@ -559,6 +559,14 @@ class "MjcMeshCollisionAPI" displayName = "Inertia" doc = """Controls how a mesh is used when mass and inertia are inferred from geometry.""" ) + + uniform int mjc:maxhullvert = -1 ( + customData = { + string apiName = "MaxHullVert" + } + displayName = "Maximum Hull Vertices" + doc = """Sets an upper limit on the number of vertices in the meshes convex hull. The default value of -1 means unlimited.""" + ) } class "MjcActuatorAPI" diff --git a/src/experimental/usd/mjcPhysics/tokens.cpp b/src/experimental/usd/mjcPhysics/tokens.cpp index 11235ab2..433ed2f1 100644 --- a/src/experimental/usd/mjcPhysics/tokens.cpp +++ b/src/experimental/usd/mjcPhysics/tokens.cpp @@ -89,6 +89,7 @@ MjcPhysicsTokensType::MjcPhysicsTokensType() mjcLengthRangeMax("mjc:lengthRange:max", TfToken::Immortal), mjcLengthRangeMin("mjc:lengthRange:min", TfToken::Immortal), mjcMargin("mjc:margin", TfToken::Immortal), + mjcMaxhullvert("mjc:maxhullvert", TfToken::Immortal), mjcMpos("mjc:mpos", TfToken::Immortal), mjcMquat("mjc:mquat", TfToken::Immortal), mjcOptionActuatorgroupdisable("mjc:option:actuatorgroupdisable", @@ -222,6 +223,7 @@ MjcPhysicsTokensType::MjcPhysicsTokensType() mjcLengthRangeMax, mjcLengthRangeMin, mjcMargin, + mjcMaxhullvert, mjcMpos, mjcMquat, mjcOptionActuatorgroupdisable, diff --git a/src/experimental/usd/plugins/mjcf/mujoco_to_usd.cc b/src/experimental/usd/plugins/mjcf/mujoco_to_usd.cc index d15c17d0..86c0fa9f 100644 --- a/src/experimental/usd/plugins/mjcf/mujoco_to_usd.cc +++ b/src/experimental/usd/plugins/mjcf/mujoco_to_usd.cc @@ -360,6 +360,10 @@ class ModelWriter { WriteUniformAttribute(mesh_path, pxr::SdfValueTypeNames->Token, MjcPhysicsTokens->mjcInertia, inertia); + + WriteUniformAttribute(mesh_path, pxr::SdfValueTypeNames->Int, + MjcPhysicsTokens->mjcMaxhullvert, + mesh->maxhullvert); } // NOTE: The geometry data taken from the spec is the post-compilation diff --git a/src/experimental/usd/usd_to_mjspec.cc b/src/experimental/usd/usd_to_mjspec.cc index c923384c..394965b2 100644 --- a/src/experimental/usd/usd_to_mjspec.cc +++ b/src/experimental/usd/usd_to_mjspec.cc @@ -546,6 +546,11 @@ void ParseMjcPhysicsMeshCollisionAPI( mesh->inertia = mjtMeshInertia::mjMESH_INERTIA_LEGACY; } } + + auto maxhullvert_attr = mesh_collision_api.GetMaxHullVertAttr(); + if (maxhullvert_attr.HasAuthoredValue()) { + maxhullvert_attr.Get(&mesh->maxhullvert); + } } void ParseMjcPhysicsGeneralActuatorAPI(mjSpec* spec, diff --git a/test/experimental/usd/plugins/mjcf/mjcf_file_format_test.cc b/test/experimental/usd/plugins/mjcf/mjcf_file_format_test.cc index 65c4b8dc..17204cf2 100644 --- a/test/experimental/usd/plugins/mjcf/mjcf_file_format_test.cc +++ b/test/experimental/usd/plugins/mjcf/mjcf_file_format_test.cc @@ -1440,6 +1440,7 @@ TEST_F(MjcfSdfFileFormatPluginTest, TestMjcPhysicsMeshCollisionAPI) { + @@ -1447,6 +1448,7 @@ TEST_F(MjcfSdfFileFormatPluginTest, TestMjcPhysicsMeshCollisionAPI) { + @@ -1461,6 +1463,8 @@ TEST_F(MjcfSdfFileFormatPluginTest, TestMjcPhysicsMeshCollisionAPI) { MjcPhysicsTokens->convex); ExpectAttributeEqual(stage, "/test/body/tet_shell/Mesh.mjc:inertia", MjcPhysicsTokens->shell); + ExpectAttributeEqual(stage, "/test/body/tet_max_vert/Mesh.mjc:maxhullvert", + 12); } TEST_F(MjcfSdfFileFormatPluginTest, TestMassAPIApplied) {