From 86d7e660095f985689c92d14fc65df522ef78ba2 Mon Sep 17 00:00:00 2001 From: John Haddon Date: Thu, 3 Jul 2025 11:21:51 +0100 Subject: [PATCH] USDScene : Use `extentsHint` to load bounds when `prim.IsModel()` Even if the UsdGeomModelAPI that provides that attribute has not been applied. This allows us to load the bounds from certain assets exported from certain DCCs. It also follows the behaviour of UsdGeomBBoxCache, where `_UseExtentsHintForPrim()` checks `prim.IsModel()` but doesn't check the for the application of the API. --- Changes | 3 +++ contrib/IECoreUSD/src/IECoreUSD/USDScene.cpp | 3 ++- contrib/IECoreUSD/test/IECoreUSD/USDSceneTest.py | 10 ++++++++++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/Changes b/Changes index 0deb0741ed..4383c47ebf 100644 --- a/Changes +++ b/Changes @@ -1,7 +1,10 @@ 10.5.x.x (relative to 10.5.15.0) ======== +Fixes +----- +- USDScene : Fixed reading of bounds from prims with `extentsHint` and model `kind` but without UsdGeomModelAPI applied. 10.5.15.0 (relative to 10.5.14.1) ========= diff --git a/contrib/IECoreUSD/src/IECoreUSD/USDScene.cpp b/contrib/IECoreUSD/src/IECoreUSD/USDScene.cpp index 2e676dad50..3b59183dfb 100644 --- a/contrib/IECoreUSD/src/IECoreUSD/USDScene.cpp +++ b/contrib/IECoreUSD/src/IECoreUSD/USDScene.cpp @@ -627,7 +627,8 @@ pxr::UsdAttribute boundAttribute( const pxr::UsdPrim &prim ) if( g_useModelAPIBounds ) { - if( auto modelAPI = pxr::UsdGeomModelAPI( prim ) ) + pxr::UsdGeomModelAPI modelAPI( prim ); + if( modelAPI || prim.IsModel() ) { return modelAPI.GetExtentsHintAttr(); } diff --git a/contrib/IECoreUSD/test/IECoreUSD/USDSceneTest.py b/contrib/IECoreUSD/test/IECoreUSD/USDSceneTest.py index b3f1328108..6e31c5fc50 100644 --- a/contrib/IECoreUSD/test/IECoreUSD/USDSceneTest.py +++ b/contrib/IECoreUSD/test/IECoreUSD/USDSceneTest.py @@ -4413,11 +4413,18 @@ def testModelBound( self ) : pxr.UsdGeom.Xform.Define( stage, "/withoutModelAPI" ) pxr.UsdGeom.Xform.Define( stage, "/withModelAPI" ) pxr.UsdGeom.Xform.Define( stage, "/withModelAPIAndExtent" ) + pxr.UsdGeom.Xform.Define( stage, "/withKind" ) + pxr.UsdGeom.Xform.Define( stage, "/withKindAndExtent" ) pxr.UsdGeom.ModelAPI.Apply( stage.GetPrimAtPath( "/withModelAPI" ) ) modelAPI = pxr.UsdGeom.ModelAPI.Apply( stage.GetPrimAtPath( "/withModelAPIAndExtent" ) ) modelAPI.SetExtentsHint( [ ( 1, 2, 3 ), ( 4, 5, 6 ) ] ) + stage.GetPrimAtPath( "/withKind" ).SetKind( "group" ) + stage.GetPrimAtPath( "/withKindAndExtent" ).SetKind( "group" ) + modelAPI = pxr.UsdGeom.ModelAPI( stage.GetPrimAtPath( "/withKindAndExtent" ) ) + modelAPI.SetExtentsHint( [ ( 1, 2, 3 ), ( 4, 5, 6 ) ] ) + stage.GetRootLayer().Save() del stage @@ -4428,6 +4435,9 @@ def testModelBound( self ) : self.assertFalse( root.child( "withModelAPI" ).hasBound() ) self.assertTrue( root.child( "withModelAPIAndExtent" ).hasBound() ) self.assertEqual( root.child( "withModelAPIAndExtent" ).readBound( 0 ), imath.Box3d( imath.V3d( 1, 2, 3 ), imath.V3d( 4, 5, 6 ) ) ) + self.assertFalse( root.child( "withKind" ).hasBound() ) + self.assertTrue( root.child( "withKindAndExtent" ).hasBound() ) + self.assertEqual( root.child( "withKindAndExtent" ).readBound( 0 ), imath.Box3d( imath.V3d( 1, 2, 3 ), imath.V3d( 4, 5, 6 ) ) ) def testAnimatedModelBound( self ) :