diff --git a/Changes b/Changes index d03bdabcfb..802a799022 100644 --- a/Changes +++ b/Changes @@ -6,6 +6,11 @@ Improvements - USDScene : Added loading of ArnoldProcedural prims as Cortex ExternalProcedural objects. +Fixes +----- + +- USDScene : Fixed writing of animated camera parameters. + 10.6.4.0 (relative to 10.6.3.1) ======== diff --git a/contrib/IECoreUSD/src/IECoreUSD/CameraAlgo.cpp b/contrib/IECoreUSD/src/IECoreUSD/CameraAlgo.cpp index 677c4b25d8..034e28d881 100644 --- a/contrib/IECoreUSD/src/IECoreUSD/CameraAlgo.cpp +++ b/contrib/IECoreUSD/src/IECoreUSD/CameraAlgo.cpp @@ -156,27 +156,27 @@ bool writeCamera( const IECoreScene::Camera *camera, const pxr::UsdStagePtr &sta auto usdCamera = pxr::UsdGeomCamera::Define( stage, path ); if( camera->getProjection() == "orthographic" ) { - usdCamera.GetProjectionAttr().Set( pxr::UsdGeomTokens->orthographic ); + usdCamera.GetProjectionAttr().Set( pxr::UsdGeomTokens->orthographic, time ); // For ortho cameras, USD uses aperture units of tenths of scene units - usdCamera.GetHorizontalApertureAttr().Set( 10.0f * camera->getAperture()[0] ); - usdCamera.GetVerticalApertureAttr().Set( 10.0f * camera->getAperture()[1] ); - usdCamera.GetHorizontalApertureOffsetAttr().Set( 10.0f * camera->getApertureOffset()[0] ); - usdCamera.GetVerticalApertureOffsetAttr().Set( 10.0f * camera->getApertureOffset()[1] ); + usdCamera.GetHorizontalApertureAttr().Set( 10.0f * camera->getAperture()[0], time ); + usdCamera.GetVerticalApertureAttr().Set( 10.0f * camera->getAperture()[1], time ); + usdCamera.GetHorizontalApertureOffsetAttr().Set( 10.0f * camera->getApertureOffset()[0], time ); + usdCamera.GetVerticalApertureOffsetAttr().Set( 10.0f * camera->getApertureOffset()[1], time ); } else if( camera->getProjection() == "perspective" ) { - usdCamera.GetProjectionAttr().Set( pxr::UsdGeomTokens->perspective ); + usdCamera.GetProjectionAttr().Set( pxr::UsdGeomTokens->perspective, time ); // We store focalLength and aperture in arbitary units. USD uses tenths // of scene units float scale = 10.0f * camera->getFocalLengthWorldScale(); - usdCamera.GetFocalLengthAttr().Set( camera->getFocalLength() * scale ); - usdCamera.GetHorizontalApertureAttr().Set( camera->getAperture()[0] * scale ); - usdCamera.GetVerticalApertureAttr().Set( camera->getAperture()[1] * scale ); - usdCamera.GetHorizontalApertureOffsetAttr().Set( camera->getApertureOffset()[0] * scale ); - usdCamera.GetVerticalApertureOffsetAttr().Set( camera->getApertureOffset()[1] * scale ); + usdCamera.GetFocalLengthAttr().Set( camera->getFocalLength() * scale, time ); + usdCamera.GetHorizontalApertureAttr().Set( camera->getAperture()[0] * scale, time ); + usdCamera.GetVerticalApertureAttr().Set( camera->getAperture()[1] * scale, time ); + usdCamera.GetHorizontalApertureOffsetAttr().Set( camera->getApertureOffset()[0] * scale, time ); + usdCamera.GetVerticalApertureOffsetAttr().Set( camera->getApertureOffset()[1] * scale, time ); } else { @@ -189,9 +189,9 @@ bool writeCamera( const IECoreScene::Camera *camera, const pxr::UsdStagePtr &sta ); } - usdCamera.GetClippingRangeAttr().Set( pxr::GfVec2f( camera->getClippingPlanes().getValue() ) ); - usdCamera.GetFStopAttr().Set( camera->getFStop() ); - usdCamera.GetFocusDistanceAttr().Set( camera->getFocusDistance() ); + usdCamera.GetClippingRangeAttr().Set( pxr::GfVec2f( camera->getClippingPlanes().getValue() ), time ); + usdCamera.GetFStopAttr().Set( camera->getFStop(), time ); + usdCamera.GetFocusDistanceAttr().Set( camera->getFocusDistance(), time ); if( camera->hasShutter() ) { @@ -201,8 +201,8 @@ bool writeCamera( const IECoreScene::Camera *camera, const pxr::UsdStagePtr &sta /// and Houdini plugin sources, I've been unable to find evidence for /// anyone else doing this though, so maybe it's one of those things /// everyone is just getting wrong? - usdCamera.GetShutterOpenAttr().Set( (double)camera->getShutter()[0] ); - usdCamera.GetShutterCloseAttr().Set( (double)camera->getShutter()[1] ); + usdCamera.GetShutterOpenAttr().Set( (double)camera->getShutter()[0], time ); + usdCamera.GetShutterCloseAttr().Set( (double)camera->getShutter()[1], time ); } return true; diff --git a/contrib/IECoreUSD/test/IECoreUSD/USDSceneTest.py b/contrib/IECoreUSD/test/IECoreUSD/USDSceneTest.py index af7902d4a1..369a6aed25 100644 --- a/contrib/IECoreUSD/test/IECoreUSD/USDSceneTest.py +++ b/contrib/IECoreUSD/test/IECoreUSD/USDSceneTest.py @@ -1306,7 +1306,7 @@ def formatCameraName( **kw ) : for name, cortexCam in testCameras.items() : cG = pxr.UsdGeom.Camera.Get( usdFile, "/" + name ) - c = cG.GetCamera() + c = cG.GetCamera( 0.0 ) self.assertEqual( c.projection.name.lower(), cortexCam.getProjection() ) @@ -1329,8 +1329,8 @@ def formatCameraName( **kw ) : self.assertEqual( c.fStop, cortexCam.getFStop() ) self.assertEqual( c.focusDistance, cortexCam.getFocusDistance() ) if cortexCam.hasShutter() : - self.assertEqual( cG.GetShutterOpenAttr().Get(), cortexCam.getShutter()[0] ) - self.assertEqual( cG.GetShutterCloseAttr().Get(), cortexCam.getShutter()[1] ) + self.assertEqual( cG.GetShutterOpenAttr().Get( 0.0 ), cortexCam.getShutter()[0] ) + self.assertEqual( cG.GetShutterCloseAttr().Get( 0.0 ), cortexCam.getShutter()[1] ) else : self.assertFalse( cG.GetShutterOpenAttr().HasAuthoredValue() ) self.assertFalse( cG.GetShutterCloseAttr().HasAuthoredValue() ) @@ -1426,6 +1426,34 @@ def assertVectorsAlmostEqual( a, b,**kw ) : self.assertEqual( camera, roundTripCamera ) + def testWriteAnimatedCamera( self ) : + + fileName = os.path.join( self.temporaryDirectory(), "test.usda" ) + root = IECoreScene.SceneInterface.create( fileName, IECore.IndexedIO.OpenMode.Write ) + child = root.createChild( "camera" ) + + cameras = {} + for time in range( 0, 10 ) : + + camera = IECoreScene.Camera() + camera.setProjection( "perspective" ) + camera.setShutter( imath.V2f( time - 0.25, time + 0.25 ) ) + camera.setFocalLength( 1.0 + time * 0.1 ) + camera.setClippingPlanes( imath.V2f( time, 1000 ) ) + + child.writeObject( camera, time ) + cameras[time] = camera + + del child, root + + root = IECoreScene.SceneInterface.create( fileName, IECore.IndexedIO.OpenMode.Read ) + child = root.child( "camera" ) + + for time in range( 0, 10 ) : + camera = child.readObject( time ) + for parameter in ( "shutter", "focalLength", "clippingPlanes" ) : + self.assertEqual( camera.parameters()[parameter], cameras[time].parameters()[parameter] ) + def testCornersAndCreases( self ) : mesh = IECoreScene.MeshPrimitive.createPlane( imath.Box2f( imath.V2f( -1 ), imath.V2f( 1 ) ) )