@@ -58,6 +58,7 @@ IECORE_PUSH_DEFAULT_VISIBILITY
58
58
#include " pxr/usd/usdGeom/camera.h"
59
59
#include " pxr/usd/usdGeom/gprim.h"
60
60
#include " pxr/usd/usdGeom/metrics.h"
61
+ #include " pxr/usd/usdGeom/modelAPI.h"
61
62
#include " pxr/usd/usdGeom/pointInstancer.h"
62
63
#include " pxr/usd/usdGeom/primvar.h"
63
64
#include " pxr/usd/usdGeom/primvarsAPI.h"
@@ -528,6 +529,33 @@ Imath::M44d localTransform( const pxr::UsdPrim &prim, pxr::UsdTimeCode time )
528
529
return result;
529
530
}
530
531
532
+ static const bool g_useModelAPIBounds = []() -> bool {
533
+ const char *c = getenv ( " IECOREUSD_USE_MODELAPI_BOUNDS" );
534
+ if ( !c )
535
+ {
536
+ return true ;
537
+ }
538
+ return strcmp ( c, " 0" );
539
+ }();
540
+
541
+ pxr::UsdAttribute boundAttribute ( const pxr::UsdPrim &prim )
542
+ {
543
+ if ( auto boundable = pxr::UsdGeomBoundable ( prim ) )
544
+ {
545
+ return boundable.GetExtentAttr ();
546
+ }
547
+
548
+ if ( g_useModelAPIBounds )
549
+ {
550
+ if ( auto modelAPI = pxr::UsdGeomModelAPI ( prim ) )
551
+ {
552
+ return modelAPI.GetExtentsHintAttr ();
553
+ }
554
+ }
555
+
556
+ return pxr::UsdAttribute ();
557
+ }
558
+
531
559
// Used to assign a unique hash to each USD file. Using a global counter rather than the file name
532
560
// means that we treat the same file as separate if it is closed and reopened. This means it's not
533
561
// a problem if USD changes things when a file is reopened. USD appears to not in general guarantee
@@ -820,30 +848,32 @@ std::string USDScene::fileName() const
820
848
821
849
Imath::Box3d USDScene::readBound ( double time ) const
822
850
{
823
- pxr::UsdGeomBoundable boundable = pxr::UsdGeomBoundable ( m_location->prim );
824
- if ( !boundable )
825
- {
826
- return Imath::Box3d ();
827
- }
828
-
829
- pxr::UsdAttribute attr = boundable.GetExtentAttr ();
851
+ pxr::UsdAttribute attr = boundAttribute ( m_location->prim );
830
852
if ( !attr.IsValid () )
831
853
{
832
854
return Imath::Box3d ();
833
855
}
834
856
835
857
pxr::VtArray<pxr::GfVec3f> extents;
836
- attr.Get <pxr::VtArray<pxr::GfVec3f> > ( &extents, m_root->getTime ( time ) );
858
+ attr.Get ( &extents, m_root->getTime ( time ) );
837
859
838
- if ( extents.size () == 2 )
860
+ // When coming from UsdGeomModelAPI, `extents` may contain several bounds,
861
+ // on a per-purpose basis. Take the union, since the SceneInterface API only
862
+ // has a single bound per location.
863
+ Imath::Box3d result;
864
+ for ( size_t i = 0 ; i + 1 < extents.size (); i += 2 )
839
865
{
840
- return Imath::Box3d (
841
- DataAlgo::fromUSD ( extents[0 ] ),
842
- DataAlgo::fromUSD ( extents[1 ] )
866
+ const Imath::Box3d b (
867
+ DataAlgo::fromUSD ( extents[i ] ),
868
+ DataAlgo::fromUSD ( extents[i+ 1 ] )
843
869
);
870
+ if ( !b.isEmpty () )
871
+ {
872
+ result.extendBy ( b );
873
+ }
844
874
}
845
875
846
- return Imath::Box3d () ;
876
+ return result ;
847
877
}
848
878
849
879
ConstDataPtr USDScene::readTransform ( double time ) const
@@ -873,14 +903,7 @@ void USDScene::path( SceneInterface::Path &p ) const
873
903
874
904
bool USDScene::hasBound () const
875
905
{
876
- pxr::UsdGeomBoundable boundable = pxr::UsdGeomBoundable ( m_location->prim );
877
- pxr::UsdAttribute attr;
878
-
879
- if ( boundable )
880
- {
881
- attr = boundable.GetExtentAttr ();
882
- }
883
-
906
+ pxr::UsdAttribute attr = boundAttribute ( m_location->prim );
884
907
return attr.IsValid ();
885
908
}
886
909
0 commit comments