From 7d6dcbbf64702b9be4c3773f4879393cd3acdef1 Mon Sep 17 00:00:00 2001 From: John Haddon Date: Tue, 28 May 2024 14:28:51 +0100 Subject: [PATCH] InteractiveRender : Fix source of globals for `resolvedRenderer` We were pulling on the adapted globals, which themselves could depend on `resolvedRenderer` via the `renderer` input to the adaptor. --- Changes.md | 3 ++ .../GafferSceneTest/InteractiveRenderTest.py | 46 +++++++++++++++++++ src/GafferScene/InteractiveRender.cpp | 2 +- 3 files changed, 50 insertions(+), 1 deletion(-) diff --git a/Changes.md b/Changes.md index d19c13b8aa5..34d04c1327f 100644 --- a/Changes.md +++ b/Changes.md @@ -30,6 +30,9 @@ Fixes - Fixed errors when the input image didn't contain the main `RGBA` channels. - Fixed inaccurate hash. - SceneAlgo : Fixed exception handling for Python render adaptors. Previously an exception during adaptor construction caused a `SystemError`. +- InteractiveRender : + - Fixed crash triggered by a render adaptor depending on its `renderer` input to adapt the scene globals. + - Removed unintentional ability for render adaptors to change the renderer being used. API --- diff --git a/python/GafferSceneTest/InteractiveRenderTest.py b/python/GafferSceneTest/InteractiveRenderTest.py index 10aa483b08f..e07e47da191 100644 --- a/python/GafferSceneTest/InteractiveRenderTest.py +++ b/python/GafferSceneTest/InteractiveRenderTest.py @@ -2252,6 +2252,52 @@ def testResolvedRenderer( self ) : render["renderer"].setValue( "Other" ) self.assertEqual( render["resolvedRenderer"].getValue(), "Other" ) + def testAdaptorsCantChangeRenderer( self ) : + + def adaptor() : + + result = GafferScene.StandardOptions() + result["options"]["defaultRenderer"]["enabled"].setValue( True ) + result["options"]["defaultRenderer"]["value"].setValue( "IAmNotAllowed" ) + return result + + GafferScene.SceneAlgo.registerRenderAdaptor( "Test", adaptor ) + + standardOptions = GafferScene.StandardOptions() + standardOptions["options"]["defaultRenderer"]["enabled"].setValue( True ) + standardOptions["options"]["defaultRenderer"]["value"].setValue( self.renderer ) + + interactiveRender = GafferScene.InteractiveRender() + interactiveRender["in"].setInput( standardOptions["out"] ) + + self.assertEqual( interactiveRender["resolvedRenderer"].getValue(), self.renderer ) + + def testAdaptorGlobalsDependingOnRenderer( self ) : + + def adaptor() : + + result = GafferScene.SceneProcessor() + result["renderer"] = Gaffer.StringPlug() + + result["__customOptions"] = GafferScene.CustomOptions() + result["__customOptions"]["options"].addChild( Gaffer.NameValuePlug( "test", Gaffer.StringPlug() ) ) + result["__customOptions"]["options"][0]["value"].setInput( result["renderer"] ) + + result["out"].setInput( result["__customOptions"]["out"] ) + return result + + GafferScene.SceneAlgo.registerRenderAdaptor( "Test", adaptor ) + + standardOptions = GafferScene.StandardOptions() + standardOptions["options"]["defaultRenderer"]["enabled"].setValue( True ) + standardOptions["options"]["defaultRenderer"]["value"].setValue( self.renderer ) + + interactiveRender = GafferScene.InteractiveRender() + interactiveRender["in"].setInput( standardOptions["out"] ) + + self.assertEqual( interactiveRender["resolvedRenderer"].getValue(), self.renderer ) + self.assertEqual( interactiveRender["__adaptedIn"].globals()["option:test"], IECore.StringData( self.renderer ) ) + def tearDown( self ) : GafferSceneTest.SceneTestCase.tearDown( self ) diff --git a/src/GafferScene/InteractiveRender.cpp b/src/GafferScene/InteractiveRender.cpp index 7cfe7327920..9f745f6f604 100644 --- a/src/GafferScene/InteractiveRender.cpp +++ b/src/GafferScene/InteractiveRender.cpp @@ -516,7 +516,7 @@ void InteractiveRender::compute( Gaffer::ValuePlug *output, const Gaffer::Contex std::string renderer = rendererPlug()->getValue(); if( renderer.empty() ) { - ConstCompoundObjectPtr globals = adaptedInPlug()->globals(); + ConstCompoundObjectPtr globals = inPlug()->globals(); if( auto rendererData = globals->member( g_rendererOptionName ) ) { renderer = rendererData->readable();