diff --git a/Changes.md b/Changes.md index 2b9cf610e13..a1fd3e613fa 100644 --- a/Changes.md +++ b/Changes.md @@ -74,6 +74,7 @@ Fixes - 3Delight : Fixed loading of surface shaders such as `dlStandard` so that they can be connected to the inputs of shaders such as `dlLayeredMaterial`. - DeepState : Fixed handling of `NaN` values and samples where `ZBack` is less than `Z`. - Premultiply : Fixed handling of non-existent alpha channel. +- PlugAlgo : Fixed promotion of CompoundDataPlugs with non-dynamic children, such as the `Camera.renderSettingOverrides` plug. API --- diff --git a/python/GafferSceneTest/CameraTest.py b/python/GafferSceneTest/CameraTest.py index 1c5176d7809..e86b8508032 100644 --- a/python/GafferSceneTest/CameraTest.py +++ b/python/GafferSceneTest/CameraTest.py @@ -241,5 +241,17 @@ def testFrustum( self ) : c["orthographicAperture"].setValue( imath.V2f( 0.1, 12 ) ) self.assertEqual( c["out"].object( "/camera" ).frustum( IECoreScene.Camera.FilmFit.Distort ).max() * 2.0, c["orthographicAperture"].getValue() ) + def testPromoteRenderOverrides( self ) : + + script = Gaffer.ScriptNode() + script["box"] = Gaffer.Box() + script["box"]["camera"] = GafferScene.Camera() + Gaffer.PlugAlgo.promote( script["box"]["camera"]["renderSettingOverrides"] ) + + script2 = Gaffer.ScriptNode() + script2.execute( script.serialise() ) + self.assertEqual( script2["box"]["renderSettingOverrides"].keys(), script["box"]["renderSettingOverrides"].keys() ) + self.assertTrue( Gaffer.PlugAlgo.isPromoted( script2["box"]["camera"]["renderSettingOverrides"] ) ) + if __name__ == "__main__": unittest.main() diff --git a/python/GafferTest/PlugAlgoTest.py b/python/GafferTest/PlugAlgoTest.py index 3e1d5ef41fe..016c009c54f 100644 --- a/python/GafferTest/PlugAlgoTest.py +++ b/python/GafferTest/PlugAlgoTest.py @@ -1099,5 +1099,38 @@ def testNumericDataConversions( self ) : value = ord( data.value ) if isinstance( data, IECore.CharData ) else data.value self.assertEqual( plug.getValue(), plugType.ValueType( value ) ) + class CompoundDataNode( Gaffer.Node ) : + + def __init__( self, name = "CompoundDataNode" ) : + + Gaffer.Node.__init__( self, name ) + + self["plug"] = Gaffer.CompoundDataPlug() + self["plug"]["child1"] = Gaffer.NameValuePlug( "value1", 10 ) + self["plug"]["child2"] = Gaffer.NameValuePlug( "value2", 20 ) + + IECore.registerRunTimeTyped( CompoundDataNode ) + + def testPromoteCompoundDataPlug( self ) : + + script = Gaffer.ScriptNode() + script["box"] = Gaffer.Box() + script["box"]["node"] = self.CompoundDataNode() + + Gaffer.PlugAlgo.promote( script["box"]["node"]["plug"] ) + script["box"]["plug"]["child1"]["value"].setValue( 100 ) + script["box"]["plug"]["child2"]["value"].setInput( script["box"]["plug"]["child1"]["value"] ) + + script2 = Gaffer.ScriptNode() + script2.execute( script.serialise() ) + + self.assertEqual( script2["box"]["plug"].keys(), script["box"]["plug"].keys() ) + self.assertTrue( Gaffer.PlugAlgo.isPromoted( script2["box"]["node"]["plug"] ) ) + self.assertEqual( script2["box"]["node"]["plug"]["child1"]["value"].getValue(), 100 ) + self.assertEqual( + script2["box"]["node"]["plug"]["child2"]["value"].source(), + script2["box"]["plug"]["child1"]["value"].source() + ) + if __name__ == "__main__": unittest.main() diff --git a/src/Gaffer/PlugAlgo.cpp b/src/Gaffer/PlugAlgo.cpp index 1d0bf6424fd..58bae493263 100644 --- a/src/Gaffer/PlugAlgo.cpp +++ b/src/Gaffer/PlugAlgo.cpp @@ -56,6 +56,8 @@ #include "fmt/format.h" +#include + using namespace std; using namespace IECore; using namespace Gaffer; @@ -1177,14 +1179,13 @@ void applyDynamicFlag( Plug *plug ) // for types like CompoundNumericPlug that create children in their constructors. // Or, even better, abolish the Dynamic flag entirely and deal with everything // via serialisers. - const Gaffer::TypeId compoundTypes[] = { PlugTypeId, ValuePlugTypeId, ArrayPlugTypeId }; - const Gaffer::TypeId *compoundTypesEnd = compoundTypes + 3; - if( find( compoundTypes, compoundTypesEnd, (Gaffer::TypeId)plug->typeId() ) != compoundTypesEnd ) + std::array compoundTypes = { PlugTypeId, ValuePlugTypeId, ArrayPlugTypeId, CompoundDataPlugTypeId }; + if( find( compoundTypes.begin(), compoundTypes.end(), (Gaffer::TypeId)plug->typeId() ) != compoundTypes.end() ) { for( Plug::RecursiveIterator it( plug ); !it.done(); ++it ) { (*it)->setFlags( Plug::Dynamic, true ); - if( find( compoundTypes, compoundTypesEnd, (Gaffer::TypeId)(*it)->typeId() ) == compoundTypesEnd ) + if( find( compoundTypes.begin(), compoundTypes.end(), (Gaffer::TypeId)plug->typeId() ) != compoundTypes.end() ) { it.prune(); }