diff --git a/Changes.md b/Changes.md index 07c4bbd00bb..4dae30f3582 100644 --- a/Changes.md +++ b/Changes.md @@ -9,6 +9,7 @@ Fixes - Fixed translation of `vector` typed outputs defined as `vector ` in an output definition. - Fixed translation of `shadow:enable` and `shadow:color` parameters on UsdLux lights, which were previously ignored. - BranchCreator : Fixed bug which could cause inconsistent hashes to be generated. +- LightEditor : Fixed toggling values in cases where inherited light attributes were set by a script context variable without including a default. 1.2.10.0 (relative to 1.2.9.0) ======== diff --git a/python/GafferSceneUI/LightEditor.py b/python/GafferSceneUI/LightEditor.py index a21b44b5c0d..eab858f668e 100644 --- a/python/GafferSceneUI/LightEditor.py +++ b/python/GafferSceneUI/LightEditor.py @@ -371,17 +371,18 @@ def __editSelectedCells( self, pathListing, quickBoolean = True ) : nonEditable = [ i for i in inspections if not i.editable() ] if len( nonEditable ) == 0 : - if not quickBoolean or not self.__toggleBoolean( inspectors, inspections ) : - edits = [ i.acquireEdit() for i in inspections ] - warnings = "\n".join( [ i.editWarning() for i in inspections if i.editWarning() != "" ] ) - # The plugs are either not boolean, boolean with mixed values, - # or attributes that don't exist and are not boolean. Show the popup. - self.__popup = GafferUI.PlugPopup( edits, warning = warnings ) - - if isinstance( self.__popup.plugValueWidget(), GafferUI.TweakPlugValueWidget ) : - self.__popup.plugValueWidget().setNameVisible( False ) - - self.__popup.popup() + with Gaffer.Context( self.getContext() ) as context : + if not quickBoolean or not self.__toggleBoolean( inspectors, inspections ) : + edits = [ i.acquireEdit() for i in inspections ] + warnings = "\n".join( [ i.editWarning() for i in inspections if i.editWarning() != "" ] ) + # The plugs are either not boolean, boolean with mixed values, + # or attributes that don't exist and are not boolean. Show the popup. + self.__popup = GafferUI.PlugPopup( edits, warning = warnings ) + + if isinstance( self.__popup.plugValueWidget(), GafferUI.TweakPlugValueWidget ) : + self.__popup.plugValueWidget().setNameVisible( False ) + + self.__popup.popup() else : diff --git a/python/GafferSceneUITest/LightEditorTest.py b/python/GafferSceneUITest/LightEditorTest.py index 4c56cd18b1a..ae2359d67ed 100644 --- a/python/GafferSceneUITest/LightEditorTest.py +++ b/python/GafferSceneUITest/LightEditorTest.py @@ -49,6 +49,23 @@ class LightEditorTest( GafferUITest.TestCase ) : + def setLightEditorMuteSelection( self, widget, togglePaths ) : + + columns = widget.getColumns() + + muteIndex = None + for i, c in zip( range( 0, len( columns ) ), columns ) : + if isinstance( c, _GafferSceneUI._LightEditorMuteColumn ) : + muteIndex = i + + self.assertIsNotNone( muteIndex ) + + selection = [ IECore.PathMatcher() for i in range( 0, len( columns ) ) ] + for path in togglePaths : + selection[muteIndex].addPath( path ) + + widget.setSelection( selection ) + def testMuteToggle( self ) : # Scene Hierarchy @@ -622,8 +639,6 @@ def testLightMuteAttribute( toggleCount, toggleLocation, newStates ) : ) } - muteIndex = None - for togglePaths, toggleData in toggles.items() : firstNewStates, secondNewStates = toggleData @@ -633,20 +648,7 @@ def testLightMuteAttribute( toggleCount, toggleLocation, newStates ) : editor._LightEditor__settingsNode["editScope"].setInput( script["editScope"]["out"] ) widget = editor._LightEditor__pathListing - columns = widget.getColumns() - - if muteIndex is None : - for i, c in zip( range( 0, len( columns ) ), columns ) : - if isinstance( c, _GafferSceneUI._LightEditorMuteColumn ) : - muteIndex = i - - self.assertIsNotNone( muteIndex ) - - selection = [ IECore.PathMatcher() for i in range( 0, len( columns ) ) ] - for path in togglePaths : - selection[muteIndex].addPath( path ) - - widget.setSelection( selection ) + self.setLightEditorMuteSelection( widget, togglePaths ) editor._LightEditor__editSelectedCells( widget ) testLightMuteAttribute( 1, togglePaths, firstNewStates ) @@ -656,6 +658,51 @@ def testLightMuteAttribute( toggleCount, toggleLocation, newStates ) : del widget, editor + def testToggleContext( self ) : + + # Make sure the correct context is scoped when evaluating attributes + # to determine a new toggle value + + script = Gaffer.ScriptNode() + script["variables"].addChild( Gaffer.NameValuePlug( "test", IECore.FloatData( 5.0 ), flags = Gaffer.Plug.Flags.Default | Gaffer.Plug.Flags.Dynamic ) ) + + script["light"] = GafferSceneTest.TestLight() + + script["group"] = GafferScene.Group() + script["group"]["in"][0].setInput( script["light"]["out"] ) + + script["filter"] = GafferScene.PathFilter() + script["filter"]["paths"].setValue( IECore.StringVectorData( ["/group"] ) ) + + script["custAttr"] = GafferScene.CustomAttributes() + script["custAttr"]["in"].setInput( script["group"]["out"] ) + script["custAttr"]["filter"].setInput( script["filter"]["out"] ) + script["custAttr"]["attributes"].addChild( Gaffer.NameValuePlug( "gl:visualiser:scale", IECore.FloatData( 2.0 ), "scale", flags = Gaffer.Plug.Flags.Default | Gaffer.Plug.Flags.Dynamic ) ) + + script["expression"] = Gaffer.Expression() + script["expression"].setExpression( + 'parent["custAttr"]["attributes"]["scale"]["value"] = context["test"]', + "python" + ) + + self.assertEqual( script.context().get( "test" ), 5.0 ) + + with script.context() : + attr = script["custAttr"]["out"].attributes( "/group" ) + + self.assertIn( "gl:visualiser:scale", attr ) + self.assertEqual( attr["gl:visualiser:scale"].value, 5.0 ) + + editor = GafferSceneUI.LightEditor( script ) + widget = editor._LightEditor__pathListing + editor.setNodeSet( Gaffer.StandardSet( [ script["custAttr"] ] ) ) + self.setLightEditorMuteSelection( widget, ["/group/light"] ) + + # This will raise an exception if the context is not scoped correctly. + editor._LightEditor__editSelectedCells( + widget, + True # quickBoolean + ) if __name__ == "__main__" : unittest.main()