Skip to content

Commit c46e929

Browse files
committed
Derive NewtonActuator from UsdTyped instead of UsdGeomImageable
Per the schema working group decision, actuators are not imageable. An actuator carries a control law bound to a joint via `newton:targets`; it has no extent and is never rendered. This also fixes the crash reported in #77. `plugInfo.json` declared `UsdGeomImageable` as the base, but the prim definition in `generatedSchema.usda` only contains `newton:targets` — the inherited `visibility`, `purpose` and `proxyPrim` properties were never baked in. `UsdGeom.BBoxCache` therefore recognized the prim as Imageable and then failed to read its visibility attribute: Failed verification: ' attr ' -- Unable to get attribute 'Visibility' on prim at path </World/Actuator> `UsdTyped` contributes no properties, so the declared base and the prim definition are now consistent with no change to `generatedSchema.usda`. This matches how core USD types the same category of non-renderable prim: `PhysicsScene`, `PhysicsCollisionGroup`, `UsdShadeShader`, `UsdRenderVar` and `UsdSkelAnimation` are all concreteTyped on UsdTyped. Note that `UsdGeomScope` would not have fixed the crash, as it is also Imageable.
1 parent ac1107a commit c46e929

2 files changed

Lines changed: 23 additions & 2 deletions

File tree

newton_usd_schemas/plugInfo.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@
175175
},
176176
"autoGenerated": false,
177177
"bases": [
178-
"UsdGeomImageable"
178+
"UsdTyped"
179179
],
180180
"schemaKind": "concreteTyped"
181181
},

tests/test_actuator.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import math
55
import unittest
66

7-
from pxr import Plug, Sdf, Usd
7+
from pxr import Plug, Sdf, Usd, UsdGeom
88

99
import newton_usd_schemas # noqa: F401
1010

@@ -35,6 +35,27 @@ def test_targets_relationship(self):
3535
self.assertEqual(len(targets), 1)
3636
self.assertEqual(str(targets[0]), "/World/Joint")
3737

38+
def test_not_imageable(self):
39+
# Actuators carry a control law bound to a joint; they have no extent and are
40+
# never rendered, so they derive from UsdTyped rather than UsdGeomImageable.
41+
self.assertFalse(self.prim.IsA(UsdGeom.Imageable))
42+
43+
# The prim definition must not advertise Imageable properties it does not have.
44+
definition = Usd.SchemaRegistry().FindConcretePrimDefinition("NewtonActuator")
45+
self.assertIsNotNone(definition)
46+
self.assertEqual(sorted(definition.GetPropertyNames()), ["newton:targets"])
47+
48+
def test_bbox_cache_skips_actuator(self):
49+
# Regression test: when NewtonActuator declared UsdGeomImageable as its base
50+
# without baking in the inherited visibility/purpose/proxyPrim properties,
51+
# UsdGeom.BBoxCache treated the prim as Imageable and then failed to read its
52+
# visibility attribute, raising from _GetOrCreateVisibilityQuery.
53+
root = self.stage.DefinePrim("/World", "Xform")
54+
self.stage.DefinePrim("/World/Actuator", "NewtonActuator")
55+
cache = UsdGeom.BBoxCache(Usd.TimeCode.Default(), [UsdGeom.Tokens.default_])
56+
bound = cache.ComputeWorldBound(root)
57+
self.assertTrue(bound.GetRange().IsEmpty())
58+
3859

3960
class TestNewtonActuatorDelayAPI(unittest.TestCase):
4061
def setUp(self):

0 commit comments

Comments
 (0)