diff --git a/Changes.md b/Changes.md index 268c863f305..62e9dd0a4bf 100644 --- a/Changes.md +++ b/Changes.md @@ -50,6 +50,7 @@ API - PlugValueWidget : - A `DeprecationWarning` is now emitted for any subclasses still implementing the legacy `_updateFromPlug()` or `_updateFromPlugs()` methods. Implement `_updateFromValues()`, `_updateFromMetadata()` and `_updateFromEditable()` instead. - A `DeprecationWarning` is now emitted by `_plugConnections()`. Use `_blockedUpdateFromValues()` instead. + - Added `scriptNode()` convenience method. - NodeGadget, ConnectionGadget : Added `updateFromContextTracker()` virtual methods. - Path : Added `inspectionContext()` virtual method. - PathColumn : @@ -58,6 +59,7 @@ API - ArrayPlug : - It is now legal to construct an ArrayPlug with a minimum size of 0. Previously the minimum size was 1. - Added `elementPrototype()` method. +- View : Added `scriptNode()` method. Breaking Changes ---------------- @@ -79,6 +81,10 @@ Breaking Changes - ArrayPlug : - Renamed `element` constructor argument to `elementPrototype`. - Deprecated the passing of `element = nullptr` to the constructor. +- View : + - Changed constructor arguments for View and all subclasses. A ScriptNode must now be passed. + - Changed `ViewCreator` signature. +- LightTool : Removed `selection()` and `selectionChangedSignal()`. Build ----- diff --git a/include/GafferImageUI/ImageView.h b/include/GafferImageUI/ImageView.h index 799fb38afc6..3235d081b2f 100644 --- a/include/GafferImageUI/ImageView.h +++ b/include/GafferImageUI/ImageView.h @@ -84,7 +84,7 @@ class GAFFERIMAGEUI_API ImageView : public GafferUI::View public : - explicit ImageView( const std::string &name = defaultName() ); + explicit ImageView( Gaffer::ScriptNodePtr scriptNode ); ~ImageView() override; GAFFER_NODE_DECLARE_TYPE( GafferImageUI::ImageView, ImageViewTypeId, GafferUI::View ); diff --git a/include/GafferSceneUI/LightTool.h b/include/GafferSceneUI/LightTool.h index b6a9c7c5d70..f9d4df9a8df 100644 --- a/include/GafferSceneUI/LightTool.h +++ b/include/GafferSceneUI/LightTool.h @@ -65,11 +65,6 @@ class GAFFERSCENEUI_API LightTool : public GafferSceneUI::SelectionTool GAFFER_NODE_DECLARE_TYPE( GafferSceneUI::LightTool, LightToolTypeId, SelectionTool ); - const IECore::PathMatcher selection() const; - - using SelectionChangedSignal = Gaffer::Signals::Signal; - SelectionChangedSignal &selectionChangedSignal(); - private : GafferScene::ScenePlug *scenePlug(); @@ -96,10 +91,7 @@ class GAFFERSCENEUI_API LightTool : public GafferSceneUI::SelectionTool bool m_priorityPathsDirty; - SelectionChangedSignal m_selectionChangedSignal; - bool m_dragging; - Gaffer::ScriptNodePtr m_scriptNode; Gaffer::Signals::ScopedConnection m_contextChangedConnection; Gaffer::Signals::ScopedConnection m_preRenderConnection; diff --git a/include/GafferSceneUI/SceneView.h b/include/GafferSceneUI/SceneView.h index a76dc376899..632882b6373 100644 --- a/include/GafferSceneUI/SceneView.h +++ b/include/GafferSceneUI/SceneView.h @@ -71,7 +71,7 @@ class GAFFERSCENEUI_API SceneView : public GafferUI::View public : - explicit SceneView( const std::string &name = defaultName() ); + explicit SceneView( Gaffer::ScriptNodePtr scriptNode ); ~SceneView() override; GAFFER_NODE_DECLARE_TYPE( GafferSceneUI::SceneView, SceneViewTypeId, GafferUI::View ); diff --git a/include/GafferSceneUI/ShaderView.h b/include/GafferSceneUI/ShaderView.h index f85f0f5936b..e3d1834f8fb 100644 --- a/include/GafferSceneUI/ShaderView.h +++ b/include/GafferSceneUI/ShaderView.h @@ -56,7 +56,7 @@ class GAFFERSCENEUI_API ShaderView : public GafferImageUI::ImageView public : - explicit ShaderView( const std::string &name = defaultName() ); + explicit ShaderView( Gaffer::ScriptNodePtr scriptNode ); ~ShaderView() override; GAFFER_NODE_DECLARE_TYPE( GafferSceneUI::ShaderView, ShaderViewTypeId, GafferImageUI::ImageView ); diff --git a/include/GafferSceneUI/UVView.h b/include/GafferSceneUI/UVView.h index d4349f0a78c..66de18d8528 100644 --- a/include/GafferSceneUI/UVView.h +++ b/include/GafferSceneUI/UVView.h @@ -61,7 +61,7 @@ class GAFFERSCENEUI_API UVView : public GafferUI::View public : - explicit UVView( const std::string &name = defaultName() ); + explicit UVView( Gaffer::ScriptNodePtr scriptNode ); ~UVView() override; GAFFER_NODE_DECLARE_TYPE( GafferSceneUI::UVView, UVViewTypeId, View ); diff --git a/include/GafferUI/View.h b/include/GafferUI/View.h index 6ca6e047925..bf4e2030fd2 100644 --- a/include/GafferUI/View.h +++ b/include/GafferUI/View.h @@ -96,6 +96,10 @@ class GAFFERUI_API View : public Gaffer::Node template const T *inPlug() const; + /// Returns the ScriptNode this view was created for. + Gaffer::ScriptNode *scriptNode(); + const Gaffer::ScriptNode *scriptNode() const; + /// The current EditScope for the view is specified by connecting /// an `EditScope::outPlug()` into this plug. Gaffer::Plug *editScopePlug(); @@ -131,7 +135,7 @@ class GAFFERUI_API View : public Gaffer::Node //@{ /// Creates a View for the specified plug. static ViewPtr create( Gaffer::PlugPtr input ); - using ViewCreator = std::function; + using ViewCreator = std::function; /// Registers a function which will return a View instance for a /// plug of a specific type. static void registerView( IECore::TypeId plugType, ViewCreator creator ); @@ -147,7 +151,7 @@ class GAFFERUI_API View : public Gaffer::Node /// class should construct a plug of a suitable type and pass it /// to the View constructor. For instance, the SceneView will pass /// a ScenePlug so that only scenes may be viewed. - View( const std::string &name, Gaffer::PlugPtr input ); + View( const std::string &name, Gaffer::ScriptNodePtr scriptNode, Gaffer::PlugPtr input ); /// The View may want to perform preprocessing of the input before /// displaying it, for instance by applying a LUT to an image. This @@ -185,14 +189,17 @@ class GAFFERUI_API View : public Gaffer::Node { ViewDescription( IECore::TypeId plugType ); ViewDescription( IECore::TypeId nodeType, const std::string &plugPathRegex ); - static ViewPtr creator( Gaffer::PlugPtr input ); }; + bool acceptsInput( const Gaffer::Plug *plug, const Gaffer::Plug *inputPlug ) const override; + private : void toolsChildAdded( Gaffer::GraphComponent *child ); void toolPlugSet( Gaffer::Plug *plug ); + const Gaffer::ScriptNodePtr m_scriptNode; + using ToolPlugSetMap = std::unordered_map; ToolPlugSetMap m_toolPlugSetConnections; diff --git a/include/GafferUI/View.inl b/include/GafferUI/View.inl index 1542d043ce5..0e915804a8c 100644 --- a/include/GafferUI/View.inl +++ b/include/GafferUI/View.inl @@ -85,21 +85,13 @@ T *View::preprocessedInPlug() template View::ViewDescription::ViewDescription( IECore::TypeId plugType ) { - View::registerView( plugType, &creator ); + View::registerView( plugType, []( Gaffer::ScriptNodePtr script ) { return new T( script ); } ); } template View::ViewDescription::ViewDescription( const IECore::TypeId nodeType, const std::string &plugPathRegex ) { - View::registerView( nodeType, plugPathRegex, &creator ); + View::registerView( nodeType, plugPathRegex, []( Gaffer::ScriptNodePtr script ) { return new T( script ); } ); } -template -ViewPtr View::ViewDescription::creator( Gaffer::PlugPtr input ) -{ - ViewPtr result = new T(); - result->inPlug()->setInput( input ); - return result; -}; - } // namespace GafferUI diff --git a/python/GafferImageUI/ChannelMaskPlugValueWidget.py b/python/GafferImageUI/ChannelMaskPlugValueWidget.py index bf047a06e5f..9559e3b51c4 100644 --- a/python/GafferImageUI/ChannelMaskPlugValueWidget.py +++ b/python/GafferImageUI/ChannelMaskPlugValueWidget.py @@ -207,13 +207,13 @@ def menuItem( matchPattern ) : def __setValue( self, unused, value ) : - with Gaffer.UndoScope( next( iter( self.getPlugs() ) ).ancestor( Gaffer.ScriptNode ) ) : + with Gaffer.UndoScope( self.scriptNode() ) : for plug in self.getPlugs() : plug.setValue( value ) def __toggleCustom( self, checked ) : - with Gaffer.UndoScope( next( iter( self.getPlugs() ) ).ancestor( Gaffer.ScriptNode ) ) : + with Gaffer.UndoScope( self.scriptNode() ) : for plug in self.getPlugs() : if not checked : Gaffer.Metadata.deregisterValue( plug, self.__customMetadataName ) diff --git a/python/GafferImageUI/ChannelPlugValueWidget.py b/python/GafferImageUI/ChannelPlugValueWidget.py index e721f26fc29..7b767ceb91e 100644 --- a/python/GafferImageUI/ChannelPlugValueWidget.py +++ b/python/GafferImageUI/ChannelPlugValueWidget.py @@ -172,14 +172,14 @@ def __menuDefinition( self ) : def __setValue( self, unused, value ) : - with Gaffer.UndoScope( next( iter( self.getPlugs() ) ).ancestor( Gaffer.ScriptNode ) ) : + with Gaffer.UndoScope( self.scriptNode() ) : for plug in self.getPlugs() : plug.setValue( value ) Gaffer.Metadata.deregisterValue( plug, "channelPlugValueWidget:isCustom" ) def __applyCustom( self, unused ) : - with Gaffer.UndoScope( next( iter( self.getPlugs() ) ).ancestor( Gaffer.ScriptNode ) ) : + with Gaffer.UndoScope( self.scriptNode() ) : for plug in self.getPlugs() : Gaffer.Metadata.registerValue( plug, "channelPlugValueWidget:isCustom", True ) diff --git a/python/GafferImageUI/FormatPlugValueWidget.py b/python/GafferImageUI/FormatPlugValueWidget.py index f00f72049de..74f2b3d8652 100644 --- a/python/GafferImageUI/FormatPlugValueWidget.py +++ b/python/GafferImageUI/FormatPlugValueWidget.py @@ -171,14 +171,14 @@ def __menuDefinition( self ) : def __applyFormat( self, unused, fmt ) : - with Gaffer.UndoScope( next( iter( self.getPlugs() ) ).ancestor( Gaffer.ScriptNode ) ) : + with Gaffer.UndoScope( self.scriptNode() ) : for plug in self.getPlugs() : Gaffer.Metadata.registerValue( plug, "formatPlugValueWidget:mode", "standard" ) plug.setValue( fmt ) def __applyCustomFormat( self, unused ) : - with Gaffer.UndoScope( next( iter( self.getPlugs() ) ).ancestor( Gaffer.ScriptNode ) ) : + with Gaffer.UndoScope( self.scriptNode() ) : if self.__currentFormat == GafferImage.Format() : # Format is empty. It's kindof confusing to display that diff --git a/python/GafferImageUI/RGBAChannelsPlugValueWidget.py b/python/GafferImageUI/RGBAChannelsPlugValueWidget.py index 8de59ada64c..ec32b3d6a37 100644 --- a/python/GafferImageUI/RGBAChannelsPlugValueWidget.py +++ b/python/GafferImageUI/RGBAChannelsPlugValueWidget.py @@ -178,6 +178,6 @@ def _menuDefinition( self ) : def __setValue( self, unused, value ) : - with Gaffer.UndoScope( next( iter( self.getPlugs() ) ).ancestor( Gaffer.ScriptNode ) ) : + with Gaffer.UndoScope( self.scriptNode() ) : for plug in self.getPlugs() : plug.setValue( value ) diff --git a/python/GafferImageUI/ViewPlugValueWidget.py b/python/GafferImageUI/ViewPlugValueWidget.py index 2ce7cb457d6..5aae9ed24b8 100644 --- a/python/GafferImageUI/ViewPlugValueWidget.py +++ b/python/GafferImageUI/ViewPlugValueWidget.py @@ -125,6 +125,6 @@ def _menuDefinition( self ) : def __setValue( self, unused, value ) : - with Gaffer.UndoScope( next( iter( self.getPlugs() ) ).ancestor( Gaffer.ScriptNode ) ) : + with Gaffer.UndoScope( self.scriptNode() ) : for plug in self.getPlugs() : plug.setValue( value ) diff --git a/python/GafferImageUITest/ImageViewTest.py b/python/GafferImageUITest/ImageViewTest.py index b7c81c3ab65..819af9974be 100644 --- a/python/GafferImageUITest/ImageViewTest.py +++ b/python/GafferImageUITest/ImageViewTest.py @@ -49,19 +49,20 @@ class ImageViewTest( GafferUITest.TestCase ) : def testFactory( self ) : - image = GafferImage.Constant() - view = GafferUI.View.create( image["out"] ) + script = Gaffer.ScriptNode() + script["image"] = GafferImage.Constant() + view = GafferUI.View.create( script["image"]["out"] ) self.assertTrue( isinstance( view, GafferImageUI.ImageView ) ) - self.assertTrue( view["in"].getInput().isSame( image["out"] ) ) + self.assertTrue( view["in"].getInput().isSame( script["image"]["out"] ) ) def testDeriving( self ) : class MyView( GafferImageUI.ImageView ) : - def __init__( self, viewedPlug = None ) : + def __init__( self, scriptNode ) : - GafferImageUI.ImageView.__init__( self, "MyView" ) + GafferImageUI.ImageView.__init__( self, scriptNode ) converter = Gaffer.Node() converter["in"] = Gaffer.StringPlug() @@ -72,22 +73,22 @@ def __init__( self, viewedPlug = None ) : self._insertConverter( converter ) - self["in"].setInput( viewedPlug ) - GafferUI.View.registerView( GafferTest.StringInOutNode, "out", MyView ) - string = GafferTest.StringInOutNode() + script = Gaffer.ScriptNode() + script["string"] = GafferTest.StringInOutNode() - view = GafferUI.View.create( string["out"] ) + view = GafferUI.View.create( script["string"]["out"] ) self.assertTrue( isinstance( view, MyView ) ) - self.assertTrue( view["in"].getInput().isSame( string["out"] ) ) + self.assertTrue( view["in"].getInput().isSame( script["string"]["out"] ) ) self.assertTrue( isinstance( view["in"], Gaffer.StringPlug ) ) view["displayTransform"]["exposure"].setValue( 1 ) view["displayTransform"]["gamma"].setValue( 0.5 ) def testImageGadget( self ) : - view = GafferImageUI.ImageView() + script = Gaffer.ScriptNode() + view = GafferImageUI.ImageView( script ) self.assertIsInstance( view.imageGadget(), GafferImageUI.ImageGadget ) self.assertTrue( view.viewportGadget().isAncestorOf( view.imageGadget() ) ) diff --git a/python/GafferSceneUI/SceneHistoryUI.py b/python/GafferSceneUI/SceneHistoryUI.py index 7e98dda0250..550c256f4e4 100644 --- a/python/GafferSceneUI/SceneHistoryUI.py +++ b/python/GafferSceneUI/SceneHistoryUI.py @@ -209,27 +209,19 @@ def __hierarchyViewKeyPress( hierarchyView, event ) : def __nodeEditorKeyPress( nodeEditor, event ) : - layout = nodeEditor.ancestor( GafferUI.CompoundEditor ) - if layout is None : + focusNode = nodeEditor.scriptNode().getFocus() + if focusNode is None : return False - ## \todo In Gaffer 0.61, we should get the scene directly from the focus node. - scene = None - for hierarchyView in layout.editors( GafferSceneUI.HierarchyView ) : - if hierarchyView.scene() is not None : - scene = hierarchyView.scene() - break - - if scene is None : - for viewer in layout.editors( GafferUI.Viewer ) : - if isinstance( viewer.view(), GafferSceneUI.SceneView ) : - scene = viewer.view()["in"] - break + scene = next( + ( p for p in GafferScene.ScenePlug.RecursiveOutputRange( focusNode ) if not p.getName().startswith( "__" ) ), + None + ) if scene is None : return False - context = layout.scriptNode().context() + context = nodeEditor.scriptNode().context() if event == __editSourceKeyPress : selectedPath = __contextSelectedPath( context ) diff --git a/python/GafferSceneUI/SetExpressionPlugValueWidget.py b/python/GafferSceneUI/SetExpressionPlugValueWidget.py index d0ed573db5e..e2a384264c3 100644 --- a/python/GafferSceneUI/SetExpressionPlugValueWidget.py +++ b/python/GafferSceneUI/SetExpressionPlugValueWidget.py @@ -157,7 +157,7 @@ def __setPlugValues( self, *unused ) : return text = self.__codeWidget.getText() - with Gaffer.UndoScope( next( iter( self.getPlugs() ) ).ancestor( Gaffer.ScriptNode ) ) : + with Gaffer.UndoScope( self.scriptNode() ) : for plug in self.getPlugs() : plug.setValue( text ) diff --git a/python/GafferSceneUI/ShaderUI.py b/python/GafferSceneUI/ShaderUI.py index 9b875c828e4..a45ac3cdffe 100644 --- a/python/GafferSceneUI/ShaderUI.py +++ b/python/GafferSceneUI/ShaderUI.py @@ -219,7 +219,7 @@ def _updateFromEditable( self ) : def __reloadButtonClicked( self, button ) : - with Gaffer.UndoScope( next( iter( self.getPlugs() ) ).ancestor( Gaffer.ScriptNode ) ) : + with Gaffer.UndoScope( self.scriptNode() ) : for plug in self.getPlugs() : plug.node().reloadShader() diff --git a/python/GafferSceneUI/StandardOptionsUI.py b/python/GafferSceneUI/StandardOptionsUI.py index 527ecf6bf17..e3e11cbb6c3 100644 --- a/python/GafferSceneUI/StandardOptionsUI.py +++ b/python/GafferSceneUI/StandardOptionsUI.py @@ -597,7 +597,7 @@ def __menuDefinition( self ) : def __togglePurpose( self, checked, purpose ) : with self.context() : - with Gaffer.UndoScope( next( iter( self.getPlugs() ) ).ancestor( Gaffer.ScriptNode ) ) : + with Gaffer.UndoScope( self.scriptNode() ) : for plug in self.getPlugs() : value = plug.getValue() # Conform value so that only valid purposes are present, and they are diff --git a/python/GafferSceneUI/UVInspector.py b/python/GafferSceneUI/UVInspector.py index 698d8d41ddc..b09764673b8 100644 --- a/python/GafferSceneUI/UVInspector.py +++ b/python/GafferSceneUI/UVInspector.py @@ -49,7 +49,7 @@ def __init__( self, scriptNode, **kw ) : GafferSceneUI.SceneEditor.__init__( self, column, scriptNode, **kw ) - self.__uvView = GafferSceneUI.UVView() + self.__uvView = GafferSceneUI.UVView( scriptNode ) self.__uvView["in"].setInput( self.settings()["in"] ) Gaffer.NodeAlgo.applyUserDefaults( self.__uvView ) self.__uvView.setContext( self.context() ) diff --git a/python/GafferSceneUITest/CameraToolTest.py b/python/GafferSceneUITest/CameraToolTest.py index 8d1175c84e6..d9930dd27db 100644 --- a/python/GafferSceneUITest/CameraToolTest.py +++ b/python/GafferSceneUITest/CameraToolTest.py @@ -63,7 +63,7 @@ def testCameraEditability( self ) : script = Gaffer.ScriptNode() script["camera"] = GafferScene.Camera() - view = GafferSceneUI.SceneView() + view = GafferSceneUI.SceneView( script ) view["in"].setInput( script["camera"]["out"] ) self.assertCameraEditable( view, True ) @@ -100,7 +100,7 @@ def testEditTransform( self ) : script = Gaffer.ScriptNode() script["camera"] = GafferScene.Camera() - view = GafferSceneUI.SceneView() + view = GafferSceneUI.SceneView( script ) view["in"].setInput( script["camera"]["out"] ) view["camera"]["lookThroughEnabled"].setValue( True ) @@ -141,7 +141,7 @@ def testNestedTransform( self ) : script["group"]["in"][0].setInput( script["camera"]["out"] ) script["group"]["transform"]["rotate"]["y"].setValue( 90 ) - view = GafferSceneUI.SceneView() + view = GafferSceneUI.SceneView( script ) view["in"].setInput( script["group"]["out"] ) view["camera"]["lookThroughEnabled"].setValue( True ) @@ -166,7 +166,7 @@ def testSwitchBackToDefaultCamera( self ) : script["camera"] = GafferScene.Camera() script["camera"]["fieldOfView"].setValue( 15 ) - view = GafferSceneUI.SceneView() + view = GafferSceneUI.SceneView( script ) view["in"].setInput( script["camera"]["out"] ) # Force update, since everything is done lazily in the SceneView @@ -211,7 +211,7 @@ def testCenterOfInterestAndUndo( self ) : script = Gaffer.ScriptNode() script["camera"] = GafferScene.Camera() - view = GafferSceneUI.SceneView() + view = GafferSceneUI.SceneView( script ) view["in"].setInput( script["camera"]["out"] ) view["camera"]["lookThroughCamera"].setValue( "/camera" ) view["camera"]["lookThroughEnabled"].setValue( True ) @@ -267,7 +267,7 @@ def testTransformNode( self ) : script["transform"]["in"].setInput( script["camera"]["out"] ) script["transform"]["filter"].setInput( script["filter"]["out"] ) - view = GafferSceneUI.SceneView() + view = GafferSceneUI.SceneView( script ) view["in"].setInput( script["transform"]["out"] ) view["camera"]["lookThroughEnabled"].setValue( True ) @@ -300,7 +300,7 @@ def testEditScopes( self ) : script["editScope"].setup( script["camera"]["out"] ) script["editScope"]["in"].setInput( script["camera"]["out"] ) - view = GafferSceneUI.SceneView() + view = GafferSceneUI.SceneView( script ) view["in"].setInput( script["editScope"]["out"] ) view["camera"]["lookThroughEnabled"].setValue( True ) @@ -346,7 +346,7 @@ def testNoUnecessaryHistoryCalls( self ) : script = Gaffer.ScriptNode() script["camera"] = GafferScene.Camera() - view = GafferSceneUI.SceneView() + view = GafferSceneUI.SceneView( script ) view["in"].setInput( script["camera"]["out"] ) view["camera"]["lookThroughEnabled"].setValue( True ) @@ -389,7 +389,7 @@ def testDontEditParentLocations( self ) : script["group"] = GafferScene.Group() script["group"]["in"][0].setInput( script["camera"]["out"] ) - view = GafferSceneUI.SceneView() + view = GafferSceneUI.SceneView( script ) view["in"].setInput( script["group"]["out"] ) view["camera"]["lookThroughEnabled"].setValue( True ) view["camera"]["lookThroughCamera"].setValue( "/group/camera" ) diff --git a/python/GafferSceneUITest/LightPositionToolTest.py b/python/GafferSceneUITest/LightPositionToolTest.py index ac24301800f..c68e284cc83 100644 --- a/python/GafferSceneUITest/LightPositionToolTest.py +++ b/python/GafferSceneUITest/LightPositionToolTest.py @@ -88,7 +88,7 @@ def testPositionShadow( self ) : script = Gaffer.ScriptNode() script["light"] = GafferSceneTest.TestLight() - view = GafferSceneUI.SceneView() + view = GafferSceneUI.SceneView( script ) view["in"].setInput( script["light"]["out"] ) GafferSceneUI.ContextAlgo.setSelectedPaths( view.getContext(), IECore.PathMatcher( [ "/light" ] ) ) @@ -142,7 +142,7 @@ def testPositionShadowWithParentTransform( self ) : script["group"] = GafferScene.Group() script["group"]["in"][0].setInput( script["light"]["out"] ) - view = GafferSceneUI.SceneView() + view = GafferSceneUI.SceneView( script ) view["in"].setInput( script["group"]["out"] ) GafferSceneUI.ContextAlgo.setSelectedPaths( view.getContext(), IECore.PathMatcher( [ "/group/light"] ) ) @@ -228,7 +228,7 @@ def testPositionHighlight( self ) : script = Gaffer.ScriptNode() script["light"] = GafferSceneTest.TestLight() - view = GafferSceneUI.SceneView() + view = GafferSceneUI.SceneView( script ) view["in"].setInput( script["light"]["out"] ) GafferSceneUI.ContextAlgo.setSelectedPaths( view.getContext(), IECore.PathMatcher( [ "/light" ] ) ) @@ -284,7 +284,7 @@ def testPositionDiffuse( self ) : script = Gaffer.ScriptNode() script["light"] = GafferSceneTest.TestLight() - view = GafferSceneUI.SceneView() + view = GafferSceneUI.SceneView( script ) view["in"].setInput( script["light"]["out"] ) GafferSceneUI.ContextAlgo.setSelectedPaths( view.getContext(), IECore.PathMatcher( [ "/light"] ) ) @@ -333,7 +333,7 @@ def testEmptySelectionModeChange( self ) : script = Gaffer.ScriptNode() script["light"] = GafferSceneTest.TestLight() - view = GafferSceneUI.SceneView() + view = GafferSceneUI.SceneView( script ) view["in"].setInput( script["light"]["out"] ) tool = GafferSceneUI.LightPositionTool( view ) diff --git a/python/GafferSceneUITest/LightToolTest.py b/python/GafferSceneUITest/LightToolTest.py index bc84bc35696..f129bfaf549 100644 --- a/python/GafferSceneUITest/LightToolTest.py +++ b/python/GafferSceneUITest/LightToolTest.py @@ -58,35 +58,6 @@ def setUp( self ) : Gaffer.Metadata.registerValue( "light:testLight", "coneAngleParameter", "coneAngle" ) Gaffer.Metadata.registerValue( "light:testLight", "penumbraAngleParameter", "penumbraAngle" ) - def testSelection( self ) : - - script = Gaffer.ScriptNode() - - script["light1"] = GafferSceneTest.TestLight() - script["light2"] = GafferSceneTest.TestLight() - - script["group"] = GafferScene.Group() - script["group"]["in"][0].setInput( script["light1"]["out"] ) - script["group"]["in"][1].setInput( script["light2"]["out"] ) - - view = GafferSceneUI.SceneView() - view["in"].setInput( script["group"]["out"] ) - - tool = GafferSceneUI.LightTool( view ) - tool["active"].setValue( True ) - - self.assertTrue( tool.selection().isEmpty() ) - - for selection in [ [ "/group/light" ], ["/group/light", "/group/light1" ], [ "/group/light"] ] : - with self.subTest( selection, selection = selection ) : - GafferSceneUI.ContextAlgo.setSelectedPaths( view.getContext(), IECore.PathMatcher( selection ) ) - s = tool.selection() - self.assertEqual( len( s.paths() ), len( selection ) ) - - GafferSceneUI.ContextAlgo.setSelectedPaths( view.getContext(), IECore.PathMatcher( [] ) ) - s = tool.selection() - self.assertTrue( s.isEmpty() ) - def testSpotLightHandleVisibility( self ) : script = Gaffer.ScriptNode() @@ -105,7 +76,7 @@ def testSpotLightHandleVisibility( self ) : script["group"]["in"][1].setInput( script["spotLight2"]["out"] ) script["group"]["in"][2].setInput( script["light1"]["out"] ) - view = GafferSceneUI.SceneView() + view = GafferSceneUI.SceneView( script ) view["in"].setInput( script["group"]["out"] ) tool = GafferSceneUI.LightTool( view ) @@ -126,22 +97,6 @@ def testSpotLightHandleVisibility( self ) : # and not visible with a non-spotlight selection. Currently handles come in as # `GraphComponent` which prevents testing that. - def testSelectionChangedSignal( self ) : - - script = Gaffer.ScriptNode() - script["light"] = GafferSceneTest.TestLight() - - view = GafferSceneUI.SceneView() - view["in"].setInput( script["light"]["out"] ) - - tool = GafferSceneUI.LightTool( view ) - tool["active"].setValue( True ) - - cs = GafferTest.CapturingSlot( tool.selectionChangedSignal() ) - GafferSceneUI.ContextAlgo.setSelectedPaths( view.getContext(), IECore.PathMatcher( [ "/light" ] ) ) - self.assertTrue( len( cs ) ) - self.assertEqual( cs[0][0], tool ) - def testDeleteNodeCrash( self ) : # Make a spotlight and get the LightTool to edit it. @@ -155,7 +110,7 @@ def testDeleteNodeCrash( self ) : script["shaderAssignment"] = GafferScene.ShaderAssignment() script["shaderAssignment"]["in"].setInput( script["spotLight"]["out"] ) - view = GafferSceneUI.SceneView() + view = GafferSceneUI.SceneView( script ) view["in"].setInput( script["shaderAssignment"]["out"] ) tool = GafferSceneUI.LightTool( view ) diff --git a/python/GafferSceneUITest/RotateToolTest.py b/python/GafferSceneUITest/RotateToolTest.py index 8d6acf5d832..7f3d26f2f1f 100644 --- a/python/GafferSceneUITest/RotateToolTest.py +++ b/python/GafferSceneUITest/RotateToolTest.py @@ -52,7 +52,7 @@ def testRotate( self ) : script = Gaffer.ScriptNode() script["cube"] = GafferScene.Cube() - view = GafferSceneUI.SceneView() + view = GafferSceneUI.SceneView( script ) view["in"].setInput( script["cube"]["out"] ) GafferSceneUI.ContextAlgo.setSelectedPaths( view.getContext(), IECore.PathMatcher( [ "/cube" ] ) ) @@ -74,7 +74,7 @@ def testInteractionWithGroupRotation( self ) : # Rotates the X axis onto the negative Z axis script["group"]["transform"]["rotate"]["y"].setValue( 90 ) - view = GafferSceneUI.SceneView() + view = GafferSceneUI.SceneView( script ) view["in"].setInput( script["group"]["out"] ) GafferSceneUI.ContextAlgo.setSelectedPaths( view.getContext(), IECore.PathMatcher( [ "/group/cube" ] ) ) @@ -114,7 +114,7 @@ def testOrientation( self ) : script["group"]["in"][0].setInput( script["cube"]["out"] ) script["group"]["transform"]["rotate"]["y"].setValue( 90 ) - view = GafferSceneUI.SceneView() + view = GafferSceneUI.SceneView( script ) view["in"].setInput( script["group"]["out"] ) GafferSceneUI.ContextAlgo.setSelectedPaths( view.getContext(), IECore.PathMatcher( [ "/group/cube" ] ) ) @@ -179,7 +179,7 @@ def testTransformWithRotation( self ) : script["transform"]["filter"].setInput( script["transformFilter"]["out"] ) script["transform"]["transform"]["rotate"]["y"].setValue( 90 ) - view = GafferSceneUI.SceneView() + view = GafferSceneUI.SceneView( script ) view["in"].setInput( script["transform"]["out"] ) GafferSceneUI.ContextAlgo.setSelectedPaths( view.getContext(), IECore.PathMatcher( [ "/plane" ] ) ) @@ -207,7 +207,7 @@ def testPivotAffectsHandlesTransform( self ) : script = Gaffer.ScriptNode() script["cube"] = GafferScene.Cube() - view = GafferSceneUI.SceneView() + view = GafferSceneUI.SceneView( script ) view["in"].setInput( script["cube"]["out"] ) GafferSceneUI.ContextAlgo.setSelectedPaths( view.getContext(), IECore.PathMatcher( [ "/cube" ] ) ) @@ -248,7 +248,7 @@ def testPivotAndExistingTransform( self ) : script["transform"]["in"].setInput( script["cube"]["out"] ) script["transform"]["filter"].setInput( script["transformFilter"]["out"] ) - view = GafferSceneUI.SceneView() + view = GafferSceneUI.SceneView( script ) view["in"].setInput( script["transform"]["out"] ) GafferSceneUI.ContextAlgo.setSelectedPaths( view.getContext(), IECore.PathMatcher( [ "/cube" ] ) ) @@ -306,7 +306,7 @@ def testEditScopes( self ) : script["editScope"].setup( script["sphere"]["out"] ) script["editScope"]["in"].setInput( script["sphere"]["out"] ) - view = GafferSceneUI.SceneView() + view = GafferSceneUI.SceneView( script ) view["in"].setInput( script["editScope"]["out"] ) view["editScope"].setInput( script["editScope"]["out"] ) @@ -354,7 +354,7 @@ def testInteractionWithPointConstraint( self ) : script["constraint"]["filter"].setInput( script["sphereFilter"]["out"] ) script["constraint"]["target"].setValue( "/cube" ) - view = GafferSceneUI.SceneView() + view = GafferSceneUI.SceneView( script ) view["in"].setInput( script["constraint"]["out"] ) GafferSceneUI.ContextAlgo.setSelectedPaths( view.getContext(), IECore.PathMatcher( [ "/sphere" ] ) ) @@ -389,7 +389,7 @@ def testInteractionWithParentConstraint( self ) : script["constraint"]["filter"].setInput( script["sphereFilter"]["out"] ) script["constraint"]["target"].setValue( "/cube" ) - view = GafferSceneUI.SceneView() + view = GafferSceneUI.SceneView( script ) view["in"].setInput( script["constraint"]["out"] ) GafferSceneUI.ContextAlgo.setSelectedPaths( view.getContext(), IECore.PathMatcher( [ "/sphere" ] ) ) @@ -413,7 +413,7 @@ def testNegativeLocalScale( self ) : script["plane"] = GafferScene.Plane() script["plane"]["transform"]["scale"]["z"].setValue( -10 ) - view = GafferSceneUI.SceneView() + view = GafferSceneUI.SceneView( script ) view["in"].setInput( script["plane"]["out"] ) GafferSceneUI.ContextAlgo.setSelectedPaths( view.getContext(), IECore.PathMatcher( [ "/plane" ] ) ) @@ -477,7 +477,7 @@ def testNegativeParentScale( self ) : script["group"]["transform"]["scale"]["z"].setValue( -10 ) - view = GafferSceneUI.SceneView() + view = GafferSceneUI.SceneView( script ) view["in"].setInput( script["group"]["out"] ) GafferSceneUI.ContextAlgo.setSelectedPaths( view.getContext(), IECore.PathMatcher( [ "/group/plane" ] ) ) diff --git a/python/GafferSceneUITest/ScaleToolTest.py b/python/GafferSceneUITest/ScaleToolTest.py index d4768ade4de..19416564153 100644 --- a/python/GafferSceneUITest/ScaleToolTest.py +++ b/python/GafferSceneUITest/ScaleToolTest.py @@ -51,7 +51,7 @@ def test( self ) : script["plane"] = GafferScene.Plane() - view = GafferSceneUI.SceneView() + view = GafferSceneUI.SceneView( script ) view["in"].setInput( script["plane"]["out"] ) tool = GafferSceneUI.ScaleTool( view ) @@ -80,7 +80,7 @@ def testHandles( self ) : script = Gaffer.ScriptNode() script["plane"] = GafferScene.Plane() - view = GafferSceneUI.SceneView() + view = GafferSceneUI.SceneView( script ) view["in"].setInput( script["plane"]["out"] ) tool = GafferSceneUI.ScaleTool( view ) @@ -120,7 +120,7 @@ def testEditScopes( self ) : script["editScope"].setup( script["sphere"]["out"] ) script["editScope"]["in"].setInput( script["sphere"]["out"] ) - view = GafferSceneUI.SceneView() + view = GafferSceneUI.SceneView( script ) view["in"].setInput( script["editScope"]["out"] ) view["editScope"].setInput( script["editScope"]["out"] ) @@ -165,7 +165,7 @@ def testHandleOriginsRespectPointConstraint( self ) : script["constraint"]["filter"].setInput( script["sphereFilter"]["out"] ) script["constraint"]["target"].setValue( "/cube" ) - view = GafferSceneUI.SceneView() + view = GafferSceneUI.SceneView( script ) view["in"].setInput( script["constraint"]["out"] ) GafferSceneUI.ContextAlgo.setSelectedPaths( view.getContext(), IECore.PathMatcher( [ "/sphere" ] ) ) @@ -183,7 +183,7 @@ def testEditIndividualPromotedAxis( self ) : script["box"]["sphere"] = GafferScene.Sphere() promoted = Gaffer.PlugAlgo.promote( script["box"]["sphere"]["transform"]["scale"]["y"] ) - view = GafferSceneUI.SceneView() + view = GafferSceneUI.SceneView( script ) view["in"].setInput( script["box"]["sphere"]["out"] ) GafferSceneUI.ContextAlgo.setSelectedPaths( view.getContext(), IECore.PathMatcher( [ "/sphere" ] ) ) @@ -202,7 +202,7 @@ def testGangedPlugs( self ) : script["sphere"] = GafferScene.Sphere() script["sphere"]["transform"]["scale"].gang() - view = GafferSceneUI.SceneView() + view = GafferSceneUI.SceneView( script ) view["in"].setInput( script["sphere"]["out"] ) GafferSceneUI.ContextAlgo.setSelectedPaths( view.getContext(), IECore.PathMatcher( [ "/sphere" ] ) ) diff --git a/python/GafferSceneUITest/SceneViewTest.py b/python/GafferSceneUITest/SceneViewTest.py index e4c67b239f4..a2e7d136574 100644 --- a/python/GafferSceneUITest/SceneViewTest.py +++ b/python/GafferSceneUITest/SceneViewTest.py @@ -53,11 +53,12 @@ class SceneViewTest( GafferUITest.TestCase ) : def testFactory( self ) : - sphere = GafferScene.Sphere() - view = GafferUI.View.create( sphere["out"] ) + script = Gaffer.ScriptNode() + script["sphere"] = GafferScene.Sphere() + view = GafferUI.View.create( script["sphere"]["out"] ) self.assertTrue( isinstance( view, GafferSceneUI.SceneView ) ) - self.assertTrue( view["in"].getInput().isSame( sphere["out"] ) ) + self.assertTrue( view["in"].getInput().isSame( script["sphere"]["out"] ) ) def testExpandSelection( self ) : @@ -67,27 +68,29 @@ def testExpandSelection( self ) : # |__D # |__E - D = GafferScene.Sphere() - D["name"].setValue( "D" ) + script = Gaffer.ScriptNode() - E = GafferScene.Sphere() - E["name"].setValue( "E" ) + script["D"] = GafferScene.Sphere() + script["D"]["name"].setValue( "D" ) - C = GafferScene.Group() - C["name"].setValue( "C" ) + script["E"] = GafferScene.Sphere() + script["E"]["name"].setValue( "E" ) - C["in"][0].setInput( D["out"] ) - C["in"][1].setInput( E["out"] ) + script["C"] = GafferScene.Group() + script["C"]["name"].setValue( "C" ) - B = GafferScene.Sphere() - B["name"].setValue( "B" ) + script["C"]["in"][0].setInput( script["D"]["out"] ) + script["C"]["in"][1].setInput( script["E"]["out"] ) - A = GafferScene.Group() - A["name"].setValue( "A" ) - A["in"][0].setInput( B["out"] ) - A["in"][1].setInput( C["out"] ) + script["B"] = GafferScene.Sphere() + script["B"]["name"].setValue( "B" ) - view = GafferUI.View.create( A["out"] ) + script["A"] = GafferScene.Group() + script["A"]["name"].setValue( "A" ) + script["A"]["in"][0].setInput( script["B"]["out"] ) + script["A"]["in"][1].setInput( script["C"]["out"] ) + + view = GafferUI.View.create( script["A"]["out"] ) def setSelection( paths ) : GafferSceneUI.ContextAlgo.setSelectedPaths( view.getContext(), IECore.PathMatcher( paths ) ) @@ -338,8 +341,9 @@ def cameraContains( scene, objectPath ) : def testInitialClippingPlanes( self ) : - sphere = GafferScene.Sphere() - view = GafferUI.View.create( sphere["out"] ) + script = Gaffer.ScriptNode() + script["sphere"] = GafferScene.Sphere() + view = GafferUI.View.create( script["sphere"]["out"] ) view["camera"]["clippingPlanes"].setValue( imath.V2f( 1, 10 ) ) view.viewportGadget().preRenderSignal()( view.viewportGadget() ) # Force update @@ -419,8 +423,9 @@ def assertLookThroughCamera() : def testClippingPlaneConstraints( self ) : - sphere = GafferScene.Sphere() - view = GafferUI.View.create( sphere["out"] ) + script = Gaffer.ScriptNode() + script["sphere"] = GafferScene.Sphere() + view = GafferUI.View.create( script["sphere"]["out"] ) # Far must be greater than near @@ -452,8 +457,9 @@ def testClippingPlaneConstraints( self ) : def testChangingClippingPlanesUpdatesAllFreeCameras( self ) : - sphere = GafferScene.Sphere() - view = GafferUI.View.create( sphere["out"] ) + script = Gaffer.ScriptNode() + script["sphere"] = GafferScene.Sphere() + view = GafferUI.View.create( script["sphere"]["out"] ) expectedClippingPlanes = view["camera"]["clippingPlanes"].getValue() view.viewportGadget().preRenderSignal()( view.viewportGadget() ) # Force update diff --git a/python/GafferSceneUITest/SelectionToolTest.py b/python/GafferSceneUITest/SelectionToolTest.py index df1476dfc4c..c70a307c065 100644 --- a/python/GafferSceneUITest/SelectionToolTest.py +++ b/python/GafferSceneUITest/SelectionToolTest.py @@ -64,7 +64,7 @@ def testSyncSelectMode( self ) : script = Gaffer.ScriptNode() script["cube"] = GafferScene.Cube() - view = GafferSceneUI.SceneView() + view = GafferSceneUI.SceneView( script ) view["in"].setInput( script["cube"]["out"] ) tool1 = GafferSceneUI.TranslateTool( view ) @@ -89,4 +89,4 @@ def tearDown( self ) : if __name__ == "__main__" : - unittest.main() \ No newline at end of file + unittest.main() diff --git a/python/GafferSceneUITest/ShaderViewTest.py b/python/GafferSceneUITest/ShaderViewTest.py index 13fcc8c61ea..c63532b6b9b 100644 --- a/python/GafferSceneUITest/ShaderViewTest.py +++ b/python/GafferSceneUITest/ShaderViewTest.py @@ -50,11 +50,12 @@ class ShaderViewTest( GafferUITest.TestCase ) : def testFactory( self ) : - shader = GafferSceneTest.TestShader() - shader["type"].setValue( "test:surface" ) - shader["name"].setValue( "test" ) + script = Gaffer.ScriptNode() + script["shader"] = GafferSceneTest.TestShader() + script["shader"]["type"].setValue( "test:surface" ) + script["shader"]["name"].setValue( "test" ) - view = GafferUI.View.create( shader["out"] ) + view = GafferUI.View.create( script["shader"]["out"] ) self.assertTrue( isinstance( view, GafferSceneUI.ShaderView ) ) def testRegisterScene( self ) : @@ -69,11 +70,12 @@ def __init__( self, name = "TestShaderBall" ) : GafferSceneUI.ShaderView.registerScene( "test", "Default", TestShaderBall ) - shader = GafferSceneTest.TestShader() - shader["type"].setValue( "test:surface" ) - shader["name"].setValue( "test" ) + script = Gaffer.ScriptNode() + script["shader"] = GafferSceneTest.TestShader() + script["shader"]["type"].setValue( "test:surface" ) + script["shader"]["name"].setValue( "test" ) - view = GafferUI.View.create( shader["out"] ) + view = GafferUI.View.create( script["shader"]["out"] ) self.assertTrue( isinstance( view.scene(), TestShaderBall ) ) def testRegisterReferenceScene( self ) : @@ -93,11 +95,12 @@ def testRegisterReferenceScene( self ) : GafferSceneUI.ShaderView.registerScene( "test", "Default", self.temporaryDirectory() / "test.grf" ) - shader = GafferSceneTest.TestShader() - shader["type"].setValue( "test:surface" ) - shader["name"].setValue( "test" ) + script = Gaffer.ScriptNode() + script["shader"] = GafferSceneTest.TestShader() + script["shader"]["type"].setValue( "test:surface" ) + script["shader"]["name"].setValue( "test" ) - view = GafferUI.View.create( shader["out"] ) + view = GafferUI.View.create( script["shader"]["out"] ) self.assertTrue( isinstance( view.scene(), Gaffer.Reference ) ) self.assertEqual( view.scene().fileName(), self.temporaryDirectory() / "test.grf" ) self.assertEqual( view.scene()["out"].childNames( "/" ), IECore.InternedStringVectorData( [ "cube" ] ) ) @@ -123,26 +126,27 @@ def __init__( self, name = "TestBShaderBall" ) : GafferSceneUI.ShaderView.registerScene( "testA", "Default", TestAShaderBall ) GafferSceneUI.ShaderView.registerScene( "testB", "Default", TestBShaderBall ) - shaderA = GafferSceneTest.TestShader() - shaderA["type"].setValue( "testA:surface" ) - shaderA["name"].setValue( "test" ) + script = Gaffer.ScriptNode() + script["shaderA"] = GafferSceneTest.TestShader() + script["shaderA"]["type"].setValue( "testA:surface" ) + script["shaderA"]["name"].setValue( "test" ) - shaderB = GafferSceneTest.TestShader() - shaderB["type"].setValue( "testB:surface" ) - shaderB["name"].setValue( "test" ) + script["shaderB"] = GafferSceneTest.TestShader() + script["shaderB"]["type"].setValue( "testB:surface" ) + script["shaderB"]["name"].setValue( "test" ) - view = GafferUI.View.create( shaderA["out"] ) + view = GafferUI.View.create( script["shaderA"]["out"] ) sceneA = view.scene() self.assertTrue( isinstance( sceneA, TestAShaderBall ) ) - view["in"].setInput( shaderB["out"] ) + view["in"].setInput( script["shaderB"]["out"] ) sceneB = view.scene() self.assertTrue( isinstance( sceneB, TestBShaderBall ) ) - view["in"].setInput( shaderA["out"] ) + view["in"].setInput( script["shaderA"]["out"] ) self.assertTrue( view.scene().isSame( sceneA ) ) - view["in"].setInput( shaderB["out"] ) + view["in"].setInput( script["shaderB"]["out"] ) self.assertTrue( view.scene().isSame( sceneB ) ) def testChangeScene( self ) : @@ -150,11 +154,12 @@ def testChangeScene( self ) : GafferSceneUI.ShaderView.registerScene( "sceneTest", "A", GafferScene.ShaderBall ) GafferSceneUI.ShaderView.registerScene( "sceneTest", "B", GafferScene.ShaderBall ) - shader = GafferSceneTest.TestShader() - shader["type"].setValue( "sceneTest:surface" ) - shader["name"].setValue( "test" ) + script = Gaffer.ScriptNode() + script["shader"] = GafferSceneTest.TestShader() + script["shader"]["type"].setValue( "sceneTest:surface" ) + script["shader"]["name"].setValue( "test" ) - view = GafferUI.View.create( shader["out"] ) + view = GafferUI.View.create( script["shader"]["out"] ) view["scene"].setValue( "A" ) sceneA = view.scene() @@ -176,11 +181,12 @@ def shaderBallCreator( resolution ) : GafferSceneUI.ShaderView.registerScene( "test", "Default", functools.partial( shaderBallCreator, 16 ) ) - shader = GafferSceneTest.TestShader() - shader["type"].setValue( "test:surface" ) - shader["name"].setValue( "test" ) + script = Gaffer.ScriptNode() + script["shader"] = GafferSceneTest.TestShader() + script["shader"]["type"].setValue( "test:surface" ) + script["shader"]["name"].setValue( "test" ) - view = GafferUI.View.create( shader["out"] ) + view = GafferUI.View.create( script["shader"]["out"] ) scene1 = view.scene() self.assertEqual( view.scene()["resolution"].getValue(), 16 ) @@ -197,20 +203,23 @@ def shaderBallCreator( resolution ) : def testCannotViewCatalogue( self ) : - view = GafferSceneUI.ShaderView() - catalogue = GafferImage.Catalogue() - self.assertFalse( view["in"].acceptsInput( catalogue["out"] ) ) + script = Gaffer.ScriptNode() + script["catalogue"] = GafferImage.Catalogue() + + view = GafferSceneUI.ShaderView( script ) + self.assertFalse( view["in"].acceptsInput( script["catalogue"]["out"] ) ) def testCannotViewSceneSwitch( self ) : - view = GafferSceneUI.ShaderView() + script = Gaffer.ScriptNode() + script["sphere"] = GafferScene.Sphere() + script["switch"] = Gaffer.Switch() + script["switch"].setup( script["sphere"]["out"] ) - sphere = GafferScene.Sphere() - switch = Gaffer.Switch() - switch.setup( sphere["out"] ) + view = GafferSceneUI.ShaderView( script ) - self.assertFalse( view["in"].acceptsInput( sphere["out"] ) ) - self.assertFalse( view["in"].acceptsInput( switch["out"] ) ) + self.assertFalse( view["in"].acceptsInput( script["sphere"]["out"] ) ) + self.assertFalse( view["in"].acceptsInput( script["switch"]["out"] ) ) if __name__ == "__main__": unittest.main() diff --git a/python/GafferSceneUITest/TranslateToolTest.py b/python/GafferSceneUITest/TranslateToolTest.py index 8a2bed69baa..4ae1aac165f 100644 --- a/python/GafferSceneUITest/TranslateToolTest.py +++ b/python/GafferSceneUITest/TranslateToolTest.py @@ -73,7 +73,7 @@ def testSelection( self ) : script["transform"]["in"].setInput( script["group"]["out"] ) script["transform"]["filter"].setInput( script["transformFilter"]["out"] ) - view = GafferSceneUI.SceneView() + view = GafferSceneUI.SceneView( script ) view["in"].setInput( script["transform"]["out"] ) tool = GafferSceneUI.TranslateTool( view ) @@ -127,7 +127,7 @@ def testTranslate( self ) : script["plane"] = GafferScene.Plane() - view = GafferSceneUI.SceneView() + view = GafferSceneUI.SceneView( script ) view["in"].setInput( script["plane"]["out"] ) GafferSceneUI.ContextAlgo.setSelectedPaths( view.getContext(), IECore.PathMatcher( [ "/plane" ] ) ) @@ -147,7 +147,7 @@ def testInteractionWithRotation( self ) : script["plane"] = GafferScene.Plane() - view = GafferSceneUI.SceneView() + view = GafferSceneUI.SceneView( script ) view["in"].setInput( script["plane"]["out"] ) GafferSceneUI.ContextAlgo.setSelectedPaths( view.getContext(), IECore.PathMatcher( [ "/plane" ] ) ) @@ -188,7 +188,7 @@ def testInteractionWithGroupRotation( self ) : script["group"]["in"][0].setInput( script["plane"]["out"] ) script["group"]["transform"]["rotate"]["y"].setValue( 90 ) - view = GafferSceneUI.SceneView() + view = GafferSceneUI.SceneView( script ) view["in"].setInput( script["group"]["out"] ) GafferSceneUI.ContextAlgo.setSelectedPaths( view.getContext(), IECore.PathMatcher( [ "/group/plane" ] ) ) @@ -213,7 +213,7 @@ def testInteractionWithGroupTranslation( self ) : script["group"]["in"][0].setInput( script["plane"]["out"] ) script["group"]["transform"]["translate"].setValue( imath.V3f( 1, 2, 3 ) ) - view = GafferSceneUI.SceneView() + view = GafferSceneUI.SceneView( script ) view["in"].setInput( script["group"]["out"] ) GafferSceneUI.ContextAlgo.setSelectedPaths( view.getContext(), IECore.PathMatcher( [ "/group/plane" ] ) ) @@ -238,7 +238,7 @@ def testOrientation( self ) : script["group"]["in"][0].setInput( script["plane"]["out"] ) script["group"]["transform"]["rotate"]["y"].setValue( 90 ) - view = GafferSceneUI.SceneView() + view = GafferSceneUI.SceneView( script ) view["in"].setInput( script["group"]["out"] ) GafferSceneUI.ContextAlgo.setSelectedPaths( view.getContext(), IECore.PathMatcher( [ "/group/plane" ] ) ) @@ -296,7 +296,7 @@ def testScale( self ) : script["plane"] = GafferScene.Plane() script["plane"]["transform"]["scale"].setValue( imath.V3f( 10 ) ) - view = GafferSceneUI.SceneView() + view = GafferSceneUI.SceneView( script ) view["in"].setInput( script["plane"]["out"] ) GafferSceneUI.ContextAlgo.setSelectedPaths( view.getContext(), IECore.PathMatcher( [ "/plane" ] ) ) @@ -334,7 +334,7 @@ def testNegativeScale( self ) : script["plane"] = GafferScene.Plane() script["plane"]["transform"]["scale"]["x"].setValue( -10 ) - view = GafferSceneUI.SceneView() + view = GafferSceneUI.SceneView( script ) view["in"].setInput( script["plane"]["out"] ) GafferSceneUI.ContextAlgo.setSelectedPaths( view.getContext(), IECore.PathMatcher( [ "/plane" ] ) ) @@ -370,7 +370,7 @@ def testGroup( self ) : script["group"] = GafferScene.Group() - view = GafferSceneUI.SceneView() + view = GafferSceneUI.SceneView( script ) view["in"].setInput( script["group"]["out"] ) GafferSceneUI.ContextAlgo.setSelectedPaths( view.getContext(), IECore.PathMatcher( [ "/group" ] ) ) @@ -398,7 +398,7 @@ def testTransform( self ) : script["transform"]["in"].setInput( script["plane"]["out"] ) script["transform"]["filter"].setInput( script["transformFilter"]["out"] ) - view = GafferSceneUI.SceneView() + view = GafferSceneUI.SceneView( script ) view["in"].setInput( script["transform"]["out"] ) GafferSceneUI.ContextAlgo.setSelectedPaths( view.getContext(), IECore.PathMatcher( [ "/plane" ] ) ) @@ -429,7 +429,7 @@ def testTransformWithRotation( self ) : script["transform"]["filter"].setInput( script["transformFilter"]["out"] ) script["transform"]["transform"]["rotate"]["y"].setValue( 90 ) - view = GafferSceneUI.SceneView() + view = GafferSceneUI.SceneView( script ) view["in"].setInput( script["transform"]["out"] ) GafferSceneUI.ContextAlgo.setSelectedPaths( view.getContext(), IECore.PathMatcher( [ "/plane" ] ) ) @@ -453,7 +453,7 @@ def testHandlesTransform( self ) : script["plane"] = GafferScene.Plane() script["plane"]["transform"]["rotate"]["y"].setValue( 90 ) - view = GafferSceneUI.SceneView() + view = GafferSceneUI.SceneView( script ) view["in"].setInput( script["plane"]["out"] ) GafferSceneUI.ContextAlgo.setSelectedPaths( view.getContext(), IECore.PathMatcher( [ "/plane" ] ) ) @@ -494,7 +494,7 @@ def testContext( self ) : """ ) ) - view = GafferSceneUI.SceneView() + view = GafferSceneUI.SceneView( script ) view["in"].setInput( script["plane"]["out"] ) view.setContext( script.context() ) @@ -524,7 +524,7 @@ def testPivotExpression( self ) : script["variables"]["in"].setInput( script["plane"]["out"] ) script["variables"]["variables"].addChild( Gaffer.NameValuePlug( "x", 1.0 ) ) - view = GafferSceneUI.SceneView() + view = GafferSceneUI.SceneView( script ) view["in"].setInput( script["variables"]["out"] ) view.setContext( script.context() ) @@ -548,7 +548,7 @@ def testMultipleSelection( self ) : script["group"]["in"][0].setInput( script["plane"]["out"] ) script["group"]["in"][1].setInput( script["sphere"]["out"] ) - view = GafferSceneUI.SceneView() + view = GafferSceneUI.SceneView( script ) view["in"].setInput( script["group"]["out"] ) tool = GafferSceneUI.TranslateTool( view ) @@ -581,7 +581,7 @@ def testMultipleSelectionDoesntPickSamePlugTwice( self ) : script["group"]["in"][0].setInput( script["plane"]["out"] ) script["group"]["in"][1].setInput( script["plane"]["out"] ) - view = GafferSceneUI.SceneView() + view = GafferSceneUI.SceneView( script ) view["in"].setInput( script["group"]["out"] ) tool = GafferSceneUI.TranslateTool( view ) @@ -610,7 +610,7 @@ def testHandlesFollowLastSelected( self ) : script["group"]["in"][0].setInput( script["plane"]["out"] ) script["group"]["in"][1].setInput( script["sphere"]["out"] ) - view = GafferSceneUI.SceneView() + view = GafferSceneUI.SceneView( script ) view["in"].setInput( script["group"]["out"] ) tool = GafferSceneUI.TranslateTool( view ) @@ -634,7 +634,7 @@ def testPromotedPlugs( self ) : Gaffer.PlugAlgo.promote( script["box"]["sphere"]["transform"] ) Gaffer.PlugAlgo.promote( script["box"]["sphere"]["out"] ) - view = GafferSceneUI.SceneView() + view = GafferSceneUI.SceneView( script ) view["in"].setInput( script["box"]["out"] ) tool = GafferSceneUI.TranslateTool( view ) @@ -649,7 +649,7 @@ def testSelectionChangedSignal( self ) : script = Gaffer.ScriptNode() script["plane"] = GafferScene.Plane() - view = GafferSceneUI.SceneView() + view = GafferSceneUI.SceneView( script ) view["in"].setInput( script["plane"]["out"] ) tool = GafferSceneUI.TranslateTool( view ) @@ -666,7 +666,7 @@ def testEditAncestorIfSelectionNotTransformable( self ) : script["sceneReader"] = GafferScene.SceneReader() script["sceneReader"]["fileName"].setValue( "${GAFFER_ROOT}/python/GafferSceneTest/alembicFiles/groupedPlane.abc" ) - view = GafferSceneUI.SceneView() + view = GafferSceneUI.SceneView( script ) view["in"].setInput( script["sceneReader"]["out"] ) tool = GafferSceneUI.TranslateTool( view ) @@ -684,7 +684,7 @@ def testSelectionRefersToFirstPublicPlug( self ) : script = Gaffer.ScriptNode() script["plane"] = GafferScene.Plane() - view = GafferSceneUI.SceneView() + view = GafferSceneUI.SceneView( script ) tool = GafferSceneUI.TranslateTool( view ) tool["active"].setValue( True ) @@ -727,7 +727,7 @@ def testSelectionRefersToCorrectPlug( self ) : script["group"]["in"][0].setInput( script["subTree"]["out"] ) script["group"]["in"][1].setInput( script["plane"]["out"] ) - view = GafferSceneUI.SceneView() + view = GafferSceneUI.SceneView( script ) tool = GafferSceneUI.TranslateTool( view ) tool["active"].setValue( True ) @@ -751,7 +751,7 @@ def testLastSelectedObjectWithSharedTransformPlug( self ) : script["group"]["in"][0].setInput( script["sphere"]["out"] ) script["group"]["in"][1].setInput( script["sphere"]["out"] ) - view = GafferSceneUI.SceneView() + view = GafferSceneUI.SceneView( script ) view["in"].setInput( script["group"]["out"] ) tool = GafferSceneUI.TranslateTool( view ) @@ -808,7 +808,7 @@ def testSelectionSorting( self ) : # Set up a TransformTool and tell it to transform each of the spheres. - view = GafferSceneUI.SceneView() + view = GafferSceneUI.SceneView( script ) view["in"].setInput( script["reader"]["out"] ) tool = GafferSceneUI.TranslateTool( view ) @@ -835,7 +835,7 @@ def testSetFilter( self ) : script["transform"]["in"].setInput( script["sphere"]["out"] ) script["transform"]["filter"].setInput( script["setFilter"]["out"] ) - view = GafferSceneUI.SceneView() + view = GafferSceneUI.SceneView( script ) view["in"].setInput( script["transform"]["out"] ) tool = GafferSceneUI.TranslateTool( view ) @@ -863,7 +863,7 @@ def testSpreadsheetAndCollect( self ) : self.assertEqual( script["collect"]["out"].childNames( "/" ), IECore.InternedStringVectorData( [ "sphere1", "sphere2" ] ) ) - view = GafferSceneUI.SceneView() + view = GafferSceneUI.SceneView( script ) view["in"].setInput( script["collect"]["out"] ) tool = GafferSceneUI.TranslateTool( view ) @@ -893,7 +893,7 @@ def testEditScopes( self ) : script["editScope"].setup( script["sphere"]["out"] ) script["editScope"]["in"].setInput( script["sphere"]["out"] ) - view = GafferSceneUI.SceneView() + view = GafferSceneUI.SceneView( script ) view["in"].setInput( script["editScope"]["out"] ) view["editScope"].setInput( script["editScope"]["out"] ) @@ -929,7 +929,7 @@ def testParentAndChildInSameEditScope( self ) : script["editScope"].setup( script["group"]["out"] ) script["editScope"]["in"].setInput( script["group"]["out"] ) - view = GafferSceneUI.SceneView() + view = GafferSceneUI.SceneView( script ) view["in"].setInput( script["editScope"]["out"] ) view["editScope"].setInput( script["editScope"]["out"] ) @@ -971,7 +971,7 @@ def testAnimationHotkey( self ) : script = Gaffer.ScriptNode() script["cube"] = GafferScene.Cube() - view = GafferSceneUI.SceneView() + view = GafferSceneUI.SceneView( script ) view["in"].setInput( script["cube"]["out"] ) GafferSceneUI.ContextAlgo.setSelectedPaths( view.getContext(), IECore.PathMatcher( [ "/cube" ] ) ) @@ -996,7 +996,7 @@ def testAnimationHotkeyWithEditScopes( self ) : script["editScope"].setup( script["cube"]["out"] ) script["editScope"]["in"].setInput( script["cube"]["out"] ) - view = GafferSceneUI.SceneView() + view = GafferSceneUI.SceneView( script ) view["in"].setInput( script["editScope"]["out"] ) view["editScope"].setInput( script["editScope"]["out"] ) @@ -1040,7 +1040,7 @@ def testTransformInEditScopeButEditScopeOff( self ) : transformEdit = GafferScene.EditScopeAlgo.acquireTransformEdit( script["editScope"], "/sphere" ) transformEdit.translate.setValue( imath.V3f( 1, 0, 0 ) ) - view = GafferSceneUI.SceneView() + view = GafferSceneUI.SceneView( script ) view["in"].setInput( script["editScope"]["out"] ) GafferSceneUI.ContextAlgo.setSelectedPaths( view.getContext(), IECore.PathMatcher( [ "/sphere" ] ) ) @@ -1070,7 +1070,7 @@ def testNonEditableSelections( self ) : script = Gaffer.ScriptNode() script["sphere"] = GafferScene.Sphere() - view = GafferSceneUI.SceneView() + view = GafferSceneUI.SceneView( script ) view["in"].setInput( script["sphere"]["out"] ) GafferSceneUI.ContextAlgo.setSelectedPaths( view.getContext(), IECore.PathMatcher( [ "/cube", "/plane" ] ) ) @@ -1121,7 +1121,7 @@ def testInteractionWithAimConstraints( self ) : imath.V3f( 0, 10, 0 ) ) - view = GafferSceneUI.SceneView() + view = GafferSceneUI.SceneView( script ) view["in"].setInput( script["aim"]["out"] ) GafferSceneUI.ContextAlgo.setSelectedPaths( view.getContext(), IECore.PathMatcher( [ "/cube" ] ) ) @@ -1196,7 +1196,7 @@ def testInteractionWithParentConstraints( self ) : # View and Tool - view = GafferSceneUI.SceneView() + view = GafferSceneUI.SceneView( script ) view["in"].setInput( script["constraint"]["out"] ) GafferSceneUI.ContextAlgo.setSelectedPaths( view.getContext(), IECore.PathMatcher( [ "/cube" ] ) ) @@ -1243,7 +1243,7 @@ def testMultipleSelectionWithEditScope( self ) : script["editScope"].setup( script["parent"]["out"] ) script["editScope"]["in"].setInput( script["parent"]["out"] ) - view = GafferSceneUI.SceneView() + view = GafferSceneUI.SceneView( script ) view["in"].setInput( script["editScope"]["out"] ) view["editScope"].setInput( script["editScope"]["out"] ) @@ -1271,7 +1271,7 @@ def testIndividualComponentConnections( self ) : promotedY = Gaffer.PlugAlgo.promote( script["box"]["cube"]["transform"]["translate"]["y"] ) promotedZ = Gaffer.PlugAlgo.promote( script["box"]["cube"]["transform"]["translate"]["z"] ) - view = GafferSceneUI.SceneView() + view = GafferSceneUI.SceneView( script ) view["in"].setInput( script["box"]["cube"]["out"] ) GafferSceneUI.ContextAlgo.setSelectedPaths( view.getContext(), IECore.PathMatcher( [ "/cube" ] ) ) diff --git a/python/GafferUI/BoolPlugValueWidget.py b/python/GafferUI/BoolPlugValueWidget.py index 57fd4052f0c..5784f05cb7b 100644 --- a/python/GafferUI/BoolPlugValueWidget.py +++ b/python/GafferUI/BoolPlugValueWidget.py @@ -115,7 +115,7 @@ def __setPlugValues( self ) : value = self.__boolWidget.getState() assert( value != self.__boolWidget.State.Indeterminate ) # Should be set by us, not by user action - with Gaffer.UndoScope( next( iter( self.getPlugs() ) ).ancestor( Gaffer.ScriptNode ) ) : + with Gaffer.UndoScope( self.scriptNode() ) : for plug in self.getPlugs() : if Gaffer.Animation.isAnimated( plug ) : diff --git a/python/GafferUI/ColorChooserPlugValueWidget.py b/python/GafferUI/ColorChooserPlugValueWidget.py index d6164b11d5d..0193d500c7b 100644 --- a/python/GafferUI/ColorChooserPlugValueWidget.py +++ b/python/GafferUI/ColorChooserPlugValueWidget.py @@ -81,7 +81,7 @@ def __colorChanged( self, colorChooser, reason ) : self.__lastChangedReason = reason with Gaffer.UndoScope( - next( iter( self.getPlugs() ) ).ancestor( Gaffer.ScriptNode ), + self.scriptNode(), mergeGroup = "ColorPlugValueWidget%d%d" % ( id( self, ), self.__mergeGroupId ) ) : diff --git a/python/GafferUI/CompoundNumericPlugValueWidget.py b/python/GafferUI/CompoundNumericPlugValueWidget.py index 3d5ff918ae2..082c4e2e9f7 100644 --- a/python/GafferUI/CompoundNumericPlugValueWidget.py +++ b/python/GafferUI/CompoundNumericPlugValueWidget.py @@ -130,13 +130,13 @@ def __keyPress( self, widget, event ) : def __gang( self ) : - with Gaffer.UndoScope( next( iter( self.getPlugs() ) ).ancestor( Gaffer.ScriptNode ) ) : + with Gaffer.UndoScope( self.scriptNode() ) : for plug in self.getPlugs() : plug.gang() def __ungang( self ) : - with Gaffer.UndoScope( next( iter( self.getPlugs() ) ).ancestor( Gaffer.ScriptNode ) ) : + with Gaffer.UndoScope( self.scriptNode() ) : for plug in self.getPlugs() : plug.ungang() diff --git a/python/GafferUI/NameValuePlugValueWidget.py b/python/GafferUI/NameValuePlugValueWidget.py index 8682c084cd8..073cd59e60c 100644 --- a/python/GafferUI/NameValuePlugValueWidget.py +++ b/python/GafferUI/NameValuePlugValueWidget.py @@ -149,7 +149,7 @@ def __drop( self, widget, event ) : # child plugs _except_ `name`. widget.setHighlighted( False ) - with Gaffer.UndoScope( next( iter( self.getPlugs() ) ).node().scriptNode() ) : + with Gaffer.UndoScope( self.scriptNode() ) : for p in self.getPlugs() : for c in p.children() : if c.getName() != "name" : diff --git a/python/GafferUI/NumericPlugValueWidget.py b/python/GafferUI/NumericPlugValueWidget.py index 877ce26cc9f..cbdc03fd563 100644 --- a/python/GafferUI/NumericPlugValueWidget.py +++ b/python/GafferUI/NumericPlugValueWidget.py @@ -173,7 +173,7 @@ def __valueChanged( self, widget, reason ) : def __setPlugValues( self, mergeGroup="" ) : - with Gaffer.UndoScope( next( iter( self.getPlugs() ) ).ancestor( Gaffer.ScriptNode ), mergeGroup=mergeGroup ) : + with Gaffer.UndoScope( self.scriptNode(), mergeGroup=mergeGroup ) : with self._blockedUpdateFromValues() : diff --git a/python/GafferUI/PlugValueWidget.py b/python/GafferUI/PlugValueWidget.py index 069a7da412d..af9bf22dd12 100644 --- a/python/GafferUI/PlugValueWidget.py +++ b/python/GafferUI/PlugValueWidget.py @@ -140,6 +140,15 @@ def context( self ) : return self.__context + ## Returns the ScriptNode ancestor for the plugs, or `None` if + # no such ancestor exists. + def scriptNode( self ) : + + if not len( self.__plugs ) : + return None + else : + return next( iter( self.__plugs ) ).ancestor( Gaffer.ScriptNode ) + ## Should be reimplemented to return True if this widget includes # some sort of labelling for the plug. This is used to prevent # extra labels being created in the NodeUI when they're not necessary. @@ -779,7 +788,7 @@ def __setValues( self, values ) : if not isinstance( values, list ) : values = itertools.repeat( values, len( self.getPlugs() ) ) - with Gaffer.UndoScope( next( iter( self.getPlugs() ) ).ancestor( Gaffer.ScriptNode ) ) : + with Gaffer.UndoScope( self.scriptNode() ) : for plug, value in zip( self.getPlugs(), values ) : plug.setValue( value ) @@ -807,13 +816,13 @@ def __editInputs( self ) : def __removeInputs( self ) : - with Gaffer.UndoScope( next( iter( self.getPlugs() ) ).ancestor( Gaffer.ScriptNode ) ) : + with Gaffer.UndoScope( self.scriptNode() ) : for p in self.getPlugs() : p.setInput( None ) def __applyUserDefaults( self ) : - with Gaffer.UndoScope( next( iter( self.getPlugs() ) ).ancestor( Gaffer.ScriptNode ) ) : + with Gaffer.UndoScope( self.scriptNode() ) : for p in self.getPlugs() : Gaffer.NodeAlgo.applyUserDefault( p ) @@ -851,13 +860,13 @@ def __presetsSubMenu( self ) : def __applyPreset( self, presetName, *unused ) : with self.context() : - with Gaffer.UndoScope( next( iter( self.getPlugs() ) ).ancestor( Gaffer.ScriptNode ) ) : + with Gaffer.UndoScope( self.scriptNode() ) : for p in self.getPlugs() : Gaffer.NodeAlgo.applyPreset( p, presetName ) def __applyReadOnly( self, readOnly ) : - with Gaffer.UndoScope( next( iter( self.getPlugs() ) ).ancestor( Gaffer.ScriptNode ) ) : + with Gaffer.UndoScope( self.scriptNode() ) : for p in self.getPlugs() : Gaffer.MetadataAlgo.setReadOnly( p, readOnly ) @@ -897,7 +906,7 @@ def __drop( self, widget, event ) : self.setHighlighted( False ) - with Gaffer.UndoScope( next( iter( self.getPlugs() ) ).node().scriptNode() ) : + with Gaffer.UndoScope( self.scriptNode() ) : if isinstance( event.data, Gaffer.Plug ) : for p in self.getPlugs() : p.setInput( event.data ) diff --git a/python/GafferUI/PresetsPlugValueWidget.py b/python/GafferUI/PresetsPlugValueWidget.py index df355791ceb..0dce2f2c87d 100644 --- a/python/GafferUI/PresetsPlugValueWidget.py +++ b/python/GafferUI/PresetsPlugValueWidget.py @@ -180,14 +180,14 @@ def __applyPreset( self, unused, preset ) : # Required for context-sensitive dynamic presets with self.context() : - with Gaffer.UndoScope( next( iter( self.getPlugs() ) ).ancestor( Gaffer.ScriptNode ) ) : + with Gaffer.UndoScope( self.scriptNode() ) : for plug in self.getPlugs() : Gaffer.Metadata.deregisterValue( plug, "presetsPlugValueWidget:isCustom" ) Gaffer.NodeAlgo.applyPreset( plug, preset ) def __applyCustomPreset( self, unused ) : - with Gaffer.UndoScope( next( iter( self.getPlugs() ) ).ancestor( Gaffer.ScriptNode ) ) : + with Gaffer.UndoScope( self.scriptNode() ) : for plug in self.getPlugs() : # When we first switch to custom mode, the current value will # actually be one of the registered presets. So we use this diff --git a/python/GafferUI/StringPlugValueWidget.py b/python/GafferUI/StringPlugValueWidget.py index 0ed944d6606..1b9ddca6961 100644 --- a/python/GafferUI/StringPlugValueWidget.py +++ b/python/GafferUI/StringPlugValueWidget.py @@ -176,7 +176,7 @@ def __setPlugValues( self ) : if self._editable() : text = self.__textWidget.getText() - with Gaffer.UndoScope( next( iter( self.getPlugs() ) ).ancestor( Gaffer.ScriptNode ) ) : + with Gaffer.UndoScope( self.scriptNode() ) : for plug in self.getPlugs() : plug.setValue( text ) diff --git a/python/GafferUITest/StandardNodeToolbarTest.py b/python/GafferUITest/StandardNodeToolbarTest.py index d59b79aa2a9..4ee7dd922d6 100644 --- a/python/GafferUITest/StandardNodeToolbarTest.py +++ b/python/GafferUITest/StandardNodeToolbarTest.py @@ -54,7 +54,8 @@ def testNoUnnecessaryUpdates( self ) : ) Gaffer.Metadata.registerValue( script["node"]["op1"], "toolbarLayout:section", "Top" ) - view = GafferUITest.ViewTest.MyView( script["node"]["op1"] ) + view = GafferUITest.ViewTest.MyView( script ) + view["in"].setInput( script["node"]["op1"] ) view.setContext( script.context() ) view["testPlug"] = Gaffer.IntPlug() Gaffer.Metadata.registerValue( diff --git a/python/GafferUITest/ToolTest.py b/python/GafferUITest/ToolTest.py index f8b58daf6d6..290ca03f462 100644 --- a/python/GafferUITest/ToolTest.py +++ b/python/GafferUITest/ToolTest.py @@ -59,7 +59,8 @@ def testDerivingInPython( self ) : self.assertIn( "TestTool", GafferUI.Tool.registeredTools( GafferUITest.ViewTest.MyView ) ) - view = GafferUITest.ViewTest.MyView() + script = Gaffer.ScriptNode() + view = GafferUITest.ViewTest.MyView( script ) tool = GafferUI.Tool.create( "TestTool", view ) self.assertIsInstance( tool, self.TestTool ) self.assertIsInstance( tool, GafferUI.Tool ) @@ -72,7 +73,8 @@ def testToolContainerParenting( self ) : # When a tool is created, it is automatically parented to the View's # tool container. - view1 = GafferUITest.ViewTest.MyView() + script = Gaffer.ScriptNode() + view1 = GafferUITest.ViewTest.MyView( script ) tool = GafferUI.Tool.create( "TestTool", view1 ) self.assertTrue( tool.parent().isSame( view1["tools"] ) ) self.assertTrue( tool.view().isSame( view1 ) ) @@ -80,7 +82,7 @@ def testToolContainerParenting( self ) : # After that, it can't be reparented to another view. This simplifies # tool implementation substantially. - view2 = GafferUITest.ViewTest.MyView() + view2 = GafferUITest.ViewTest.MyView( script ) self.assertFalse( tool.acceptsParent( view2["tools"] ) ) # Tool containers don't accept any other children. @@ -88,7 +90,8 @@ def testToolContainerParenting( self ) : def testToolOutlivingView( self ) : - view = GafferUITest.ViewTest.MyView() + script = Gaffer.ScriptNode() + view = GafferUITest.ViewTest.MyView( script ) tool = GafferUI.Tool.create( "TestTool", view ) del view while gc.collect() : diff --git a/python/GafferUITest/ViewTest.py b/python/GafferUITest/ViewTest.py index c0b8e7fd0dc..79bd8723d5e 100644 --- a/python/GafferUITest/ViewTest.py +++ b/python/GafferUITest/ViewTest.py @@ -61,45 +61,46 @@ def tearDown( self ) : class MyView( GafferUI.View ) : - def __init__( self, viewedPlug = None ) : + def __init__( self, scriptNode ) : - GafferUI.View.__init__( self, "MyView", Gaffer.IntPlug( "in" ) ) - - self["in"].setInput( viewedPlug ) + GafferUI.View.__init__( self, "MyView", scriptNode, Gaffer.IntPlug( "in" ) ) IECore.registerRunTimeTyped( MyView, typeName = "GafferUITest::MyView" ) def testFactory( self ) : - node = GafferTest.AddNode() - self.assertTrue( GafferUI.View.create( node["sum"] ) is None ) + script = Gaffer.ScriptNode() + script["node"] = GafferTest.AddNode() + self.assertTrue( GafferUI.View.create( script["node"]["sum"] ) is None ) # check that we can make our own view and register it for the node GafferUI.View.registerView( GafferTest.AddNode, "sum", self.MyView ) - view = GafferUI.View.create( node["sum"] ) + view = GafferUI.View.create( script["node"]["sum"] ) self.assertTrue( isinstance( view, self.MyView ) ) - self.assertTrue( view["in"].getInput().isSame( node["sum"] ) ) + self.assertTrue( view["in"].getInput().isSame( script["node"]["sum"] ) ) + self.assertTrue( view.scriptNode().isSame( script ) ) # and check that that registration leaves other nodes alone - n = Gaffer.Node() - n["sum"] = Gaffer.IntPlug( direction = Gaffer.Plug.Direction.Out ) + script["node2"] = Gaffer.Node() + script["node2"]["sum"] = Gaffer.IntPlug( direction = Gaffer.Plug.Direction.Out ) - self.assertTrue( GafferUI.View.create( n["sum"] ) is None ) + self.assertTrue( GafferUI.View.create( script["node2"]["sum"] ) is None ) def testEditScope( self ) : - view = self.MyView() + script = Gaffer.ScriptNode() + script["addNode"] = GafferTest.AddNode() + script["editScope"] = Gaffer.EditScope() + script["editScope"].setup( script["addNode"]["sum"] ) - addNode = GafferTest.AddNode() - editScope = Gaffer.EditScope() - editScope.setup( view["in"] ) + view = self.MyView( script ) self.assertEqual( view.editScope(), None ) - view["editScope"].setInput( editScope["out"] ) - self.assertEqual( view.editScope(), editScope ) + view["editScope"].setInput( script["editScope"]["out"] ) + self.assertEqual( view.editScope(), script["editScope"] ) def testDisplayTransformRegistrations( self ) : @@ -141,5 +142,18 @@ def dummyTransform() : # No need to clean up - `tearDown()` will do that for us. + def testScriptNode( self ) : + + script = Gaffer.ScriptNode() + script["node"] = GafferTest.AddNode() + + view = self.MyView( script ) + self.assertTrue( view.scriptNode().isSame( script ) ) + view["in"].setInput( script["node"]["sum"] ) + + script2 = Gaffer.ScriptNode() + script2["node"] = GafferTest.AddNode() + self.assertFalse( view["in"].acceptsInput( script2["node"]["sum"] ) ) + if __name__ == "__main__": unittest.main() diff --git a/src/GafferImageUI/ImageView.cpp b/src/GafferImageUI/ImageView.cpp index c8b03e6bf69..88ecc1bc3f2 100644 --- a/src/GafferImageUI/ImageView.cpp +++ b/src/GafferImageUI/ImageView.cpp @@ -60,6 +60,7 @@ #include "Gaffer/BoxPlug.h" #include "Gaffer/Metadata.h" #include "Gaffer/NameSwitch.h" +#include "Gaffer/ScriptNode.h" #include "IECoreGL/IECoreGL.h" #include "IECoreGL/Shader.h" @@ -1439,8 +1440,8 @@ GAFFER_NODE_DEFINE_TYPE( ImageView ); GAFFERIMAGEUI_API ImageView::ViewDescription ImageView::g_viewDescription( GafferImage::ImagePlug::staticTypeId() ); -ImageView::ImageView( const std::string &name ) - : View( name, new GafferImage::ImagePlug() ), +ImageView::ImageView( Gaffer::ScriptNodePtr scriptNode ) + : View( defaultName(), scriptNode, new GafferImage::ImagePlug() ), m_imageGadgets{ new ImageGadget(), new ImageGadget() }, m_framed( false ) { diff --git a/src/GafferImageUIModule/ImageViewBinding.cpp b/src/GafferImageUIModule/ImageViewBinding.cpp index a092d62dbbc..e20ff8ab62e 100644 --- a/src/GafferImageUIModule/ImageViewBinding.cpp +++ b/src/GafferImageUIModule/ImageViewBinding.cpp @@ -46,6 +46,8 @@ #include "GafferBindings/NodeBinding.h" #include "GafferBindings/PlugBinding.h" +#include "Gaffer/ScriptNode.h" + using namespace std; using namespace boost::python; using namespace Gaffer; @@ -61,8 +63,8 @@ class ImageViewWrapper : public NodeWrapper public : - ImageViewWrapper( PyObject *self, const std::string &name ) - : NodeWrapper( self, name ) + ImageViewWrapper( PyObject *self, ScriptNodePtr scriptNode ) + : NodeWrapper( self, scriptNode ) { } @@ -77,8 +79,8 @@ class ImageViewWrapper : public NodeWrapper void GafferImageUIModule::bindImageView() { - scope s = GafferBindings::NodeClass() - .def( init() ) + scope s = GafferBindings::NodeClass( nullptr, no_init ) + .def( init() ) .def( "imageGadget", (ImageGadget *(ImageView::*)())&ImageView::imageGadget, return_value_policy() ) .def( "_insertConverter", &ImageViewWrapper::insertConverter ) ; diff --git a/src/GafferSceneUI/CameraTool.cpp b/src/GafferSceneUI/CameraTool.cpp index f2d0427c69e..80bca8f9f3e 100644 --- a/src/GafferSceneUI/CameraTool.cpp +++ b/src/GafferSceneUI/CameraTool.cpp @@ -391,7 +391,7 @@ void CameraTool::viewportCameraChanged() // Now apply this offset to the current value on the transform plug. Gaffer::Private::ScopedAssignment editingScope( g_editingTransform, true ); - UndoScope undoScope( selection.editTarget()->ancestor(), UndoScope::Enabled, m_undoGroup ); + UndoScope undoScope( view()->scriptNode(), UndoScope::Enabled, m_undoGroup ); auto edit = selection.acquireTransformEdit(); M44f plugTransform; diff --git a/src/GafferSceneUI/CropWindowTool.cpp b/src/GafferSceneUI/CropWindowTool.cpp index 0d12b366c46..dc42623deac 100644 --- a/src/GafferSceneUI/CropWindowTool.cpp +++ b/src/GafferSceneUI/CropWindowTool.cpp @@ -739,7 +739,7 @@ void CropWindowTool::overlayRectangleChanged( unsigned reason ) flipNDCOrigin( b ); } - UndoScope undoScope( m_cropWindowPlug->ancestor() ); + UndoScope undoScope( view()->scriptNode() ); if( m_cropWindowEnabledPlug && !m_cropWindowEnabledPlug->getValue() ) { @@ -1032,7 +1032,7 @@ bool CropWindowTool::keyPress( const KeyEvent &event ) activePlug()->setValue( newState ); if( m_cropWindowEnabledPlug ) { - UndoScope undoScope( m_cropWindowPlug->ancestor() ); + UndoScope undoScope( view()->scriptNode() ); m_cropWindowEnabledPlug->setValue( newState ); } } diff --git a/src/GafferSceneUI/LightPositionTool.cpp b/src/GafferSceneUI/LightPositionTool.cpp index 2ee78c73943..53fbddce3df 100644 --- a/src/GafferSceneUI/LightPositionTool.cpp +++ b/src/GafferSceneUI/LightPositionTool.cpp @@ -789,7 +789,7 @@ IECore::RunTimeTypedPtr LightPositionTool::handleDragBegin( Gadget *gadget ) bool LightPositionTool::handleDragMove( Gadget *gadget, const DragDropEvent &event ) { - UndoScope undoScope( selection().back().editTarget()->ancestor(), UndoScope::Enabled, undoMergeGroup() ); + UndoScope undoScope( view()->scriptNode(), UndoScope::Enabled, undoMergeGroup() ); if( gadget == m_distanceHandle.get() ) { @@ -868,7 +868,7 @@ bool LightPositionTool::sceneGadgetDragMove( const DragDropEvent &event ) return true; } - UndoScope undoScope( selection().back().editTarget()->ancestor(), UndoScope::Enabled, undoMergeGroup() ); + UndoScope undoScope( view()->scriptNode(), UndoScope::Enabled, undoMergeGroup() ); placeTarget( event.line ); return true; @@ -973,7 +973,7 @@ bool LightPositionTool::buttonPress( const ButtonEvent &event ) return true; } - UndoScope undoScope( selection().back().editTarget()->ancestor(), UndoScope::Enabled, undoMergeGroup() ); + UndoScope undoScope( view()->scriptNode(), UndoScope::Enabled, undoMergeGroup() ); placeTarget( event.line ); return true; diff --git a/src/GafferSceneUI/LightTool.cpp b/src/GafferSceneUI/LightTool.cpp index 89dd140ab4d..35ae75faa37 100644 --- a/src/GafferSceneUI/LightTool.cpp +++ b/src/GafferSceneUI/LightTool.cpp @@ -2965,7 +2965,6 @@ LightTool::LightTool( SceneView *view, const std::string &name ) : m_handleTransformsDirty( true ), m_priorityPathsDirty( true ), m_dragging( false ), - m_scriptNode( nullptr ), m_mergeGroupId( 0 ) { view->viewportGadget()->addChild( m_handles ); @@ -3038,16 +3037,6 @@ LightTool::~LightTool() } -const PathMatcher LightTool::selection() const -{ - return ContextAlgo::getSelectedPaths( view()->getContext() ); -} - -LightTool::SelectionChangedSignal &LightTool::selectionChangedSignal() -{ - return m_selectionChangedSignal; -} - ScenePlug *LightTool::scenePlug() { return getChild( g_firstPlugIndex ); @@ -3076,7 +3065,6 @@ void LightTool::contextChanged( const InternedString &name ) m_handleInspectionsDirty = true; m_handleTransformsDirty = true; m_priorityPathsDirty = true; - selectionChangedSignal()( *this ); } } @@ -3103,7 +3091,7 @@ void LightTool::updateHandleInspections() m_inspectorsDirtiedConnection.clear(); - const PathMatcher selection = this->selection(); + const PathMatcher selection = ContextAlgo::getSelectedPaths( view()->getContext() ); if( selection.isEmpty() ) { for( auto &c : m_handles->children() ) @@ -3177,7 +3165,7 @@ void LightTool::updateHandleTransforms( float rasterScale ) return; } - const PathMatcher selection = this->selection(); + const PathMatcher selection = ContextAlgo::getSelectedPaths( view()->getContext() ); if( selection.isEmpty() ) { return; @@ -3226,10 +3214,6 @@ void LightTool::plugDirtied( const Plug *plug ) ( plug->ancestor() && plug == view()->editScopePlug() ) ) { - if( !m_dragging ) - { - selectionChangedSignal()( *this ); - } m_handleInspectionsDirty = true; m_priorityPathsDirty = true; } @@ -3281,14 +3265,7 @@ void LightTool::preRender() { m_priorityPathsDirty = false; auto sceneGadget = static_cast( view()->viewportGadget()->getPrimaryChild() ); - if( !selection().isEmpty() ) - { - sceneGadget->setPriorityPaths( ContextAlgo::getSelectedPaths( view()->getContext() ) ); - } - else - { - sceneGadget->setPriorityPaths( IECore::PathMatcher() ); - } + sceneGadget->setPriorityPaths( ContextAlgo::getSelectedPaths( view()->getContext() ) ); } } @@ -3323,8 +3300,6 @@ void LightTool::dirtyHandleTransforms() RunTimeTypedPtr LightTool::dragBegin( Gadget *gadget ) { m_dragging = true; - m_scriptNode = view()->inPlug()->source()->ancestor(); - return nullptr; } @@ -3333,7 +3308,7 @@ bool LightTool::dragMove( Gadget *gadget, const DragDropEvent &event ) auto handle = runTimeCast( gadget ); assert( handle ); - UndoScope undoScope( m_scriptNode.get(), UndoScope::Enabled, undoMergeGroup() ); + UndoScope undoScope( view()->scriptNode(), UndoScope::Enabled, undoMergeGroup() ); handle->handleDragMove( event ); @@ -3344,8 +3319,6 @@ bool LightTool::dragEnd( Gadget *gadget ) { m_dragging = false; m_mergeGroupId++; - selectionChangedSignal()( *this ); - auto handle = runTimeCast( gadget ); handle->handleDragEnd(); diff --git a/src/GafferSceneUI/RotateTool.cpp b/src/GafferSceneUI/RotateTool.cpp index 6ef65f9beaa..0ecbb05e0dc 100644 --- a/src/GafferSceneUI/RotateTool.cpp +++ b/src/GafferSceneUI/RotateTool.cpp @@ -247,7 +247,7 @@ IECore::RunTimeTypedPtr RotateTool::handleDragBegin() bool RotateTool::handleDragMove( GafferUI::Gadget *gadget, const GafferUI::DragDropEvent &event ) { - UndoScope undoScope( selection().back().editTarget()->ancestor(), UndoScope::Enabled, undoMergeGroup() ); + UndoScope undoScope( view()->scriptNode(), UndoScope::Enabled, undoMergeGroup() ); const V3f rotation = static_cast( gadget )->rotation( event ); for( auto &r : m_drag ) { @@ -289,7 +289,7 @@ bool RotateTool::buttonPress( const GafferUI::ButtonEvent &event ) return true; } - UndoScope undoScope( selection().back().editTarget()->ancestor() ); + UndoScope undoScope( view()->scriptNode() ); for( const auto &s : selection() ) { diff --git a/src/GafferSceneUI/ScaleTool.cpp b/src/GafferSceneUI/ScaleTool.cpp index fb7e5445b09..c226c80c805 100644 --- a/src/GafferSceneUI/ScaleTool.cpp +++ b/src/GafferSceneUI/ScaleTool.cpp @@ -140,7 +140,7 @@ IECore::RunTimeTypedPtr ScaleTool::dragBegin( GafferUI::Style::Axes axes ) bool ScaleTool::dragMove( GafferUI::Gadget *gadget, const GafferUI::DragDropEvent &event ) { - UndoScope undoScope( selection().back().editTarget()->ancestor(), UndoScope::Enabled, undoMergeGroup() ); + UndoScope undoScope( view()->scriptNode(), UndoScope::Enabled, undoMergeGroup() ); ScaleHandle *scaleHandle = static_cast( gadget ); const V3f &scaling = scaleHandle->scaling( event ); for( auto &s : m_drag ) diff --git a/src/GafferSceneUI/SceneView.cpp b/src/GafferSceneUI/SceneView.cpp index 2863fff8308..bdf9a93843d 100644 --- a/src/GafferSceneUI/SceneView.cpp +++ b/src/GafferSceneUI/SceneView.cpp @@ -58,6 +58,7 @@ #include "Gaffer/MetadataAlgo.h" #include "Gaffer/NameSwitch.h" #include "Gaffer/PlugAlgo.h" +#include "Gaffer/ScriptNode.h" #include "Gaffer/StringPlug.h" #include "IECoreGL/Camera.h" @@ -1935,8 +1936,8 @@ GAFFER_NODE_DEFINE_TYPE( SceneView ); size_t SceneView::g_firstPlugIndex = 0; SceneView::ViewDescription SceneView::g_viewDescription( GafferScene::ScenePlug::staticTypeId() ); -SceneView::SceneView( const std::string &name ) - : View( name, new GafferScene::ScenePlug() ), +SceneView::SceneView( ScriptNodePtr scriptNode ) + : View( defaultName(), scriptNode, new GafferScene::ScenePlug() ), m_sceneGadget( new SceneGadget ) { diff --git a/src/GafferSceneUI/ShaderView.cpp b/src/GafferSceneUI/ShaderView.cpp index 56d1d6e4a9e..5a7f039610a 100644 --- a/src/GafferSceneUI/ShaderView.cpp +++ b/src/GafferSceneUI/ShaderView.cpp @@ -49,6 +49,7 @@ #include "Gaffer/Context.h" #include "Gaffer/PlugAlgo.h" #include "Gaffer/Reference.h" +#include "Gaffer/ScriptNode.h" #include "Gaffer/StringPlug.h" #include "IECoreImage/DisplayDriverServer.h" @@ -131,8 +132,8 @@ GAFFER_NODE_DEFINE_TYPE( ShaderView ); /// but that would be a breaking change (albeit a small one). ShaderView::ViewDescription ShaderView::g_viewDescription( GafferScene::Shader::staticTypeId(), "out" ); -ShaderView::ShaderView( const std::string &name ) - : ImageView( name ), m_framed( false ) +ShaderView::ShaderView( Gaffer::ScriptNodePtr scriptNode ) + : ImageView( scriptNode ), m_framed( false ) { // Create a converter to generate an image // from the input shader. diff --git a/src/GafferSceneUI/TransformTool.cpp b/src/GafferSceneUI/TransformTool.cpp index 1bf5c08506f..f73ea5cf565 100644 --- a/src/GafferSceneUI/TransformTool.cpp +++ b/src/GafferSceneUI/TransformTool.cpp @@ -1253,7 +1253,7 @@ bool TransformTool::keyPress( const GafferUI::KeyEvent &event ) return false; } - UndoScope undoScope( selection().back().editTarget()->ancestor() ); + UndoScope undoScope( view()->scriptNode() ); for( const auto &s : selection() ) { Context::Scope contextScope( s.context() ); diff --git a/src/GafferSceneUI/TranslateTool.cpp b/src/GafferSceneUI/TranslateTool.cpp index 01d0b0a21d7..47ab6dc4415 100644 --- a/src/GafferSceneUI/TranslateTool.cpp +++ b/src/GafferSceneUI/TranslateTool.cpp @@ -246,7 +246,7 @@ IECore::RunTimeTypedPtr TranslateTool::handleDragBegin() bool TranslateTool::handleDragMove( GafferUI::Gadget *gadget, const GafferUI::DragDropEvent &event ) { - UndoScope undoScope( selection().back().editTarget()->ancestor(), UndoScope::Enabled, undoMergeGroup() ); + UndoScope undoScope( view()->scriptNode(), UndoScope::Enabled, undoMergeGroup() ); const V3f translation = static_cast( gadget )->translation( event ); for( auto &t : m_drag ) { @@ -301,7 +301,7 @@ bool TranslateTool::buttonPress( const GafferUI::ButtonEvent &event ) selectionCentroids.extendBy( s.scene()->bound( s.path() ).center() * worldTransform ); } - UndoScope undoScope( selection().back().editTarget()->ancestor() ); + UndoScope undoScope( view()->scriptNode() ); const V3f offset = targetPos - selectionCentroids.center(); for( const auto &s : selection() ) diff --git a/src/GafferSceneUI/UVView.cpp b/src/GafferSceneUI/UVView.cpp index d4cd65544c8..79a00ef0a64 100644 --- a/src/GafferSceneUI/UVView.cpp +++ b/src/GafferSceneUI/UVView.cpp @@ -56,6 +56,7 @@ #include "GafferUI/Style.h" #include "GafferUI/ViewportGadget.h" +#include "Gaffer/ScriptNode.h" #include "Gaffer/StringPlug.h" #include "IECore/Math.h" @@ -574,8 +575,8 @@ static InternedString g_gridGadgetName( "gridGadget" ); GAFFER_NODE_DEFINE_TYPE( UVView ) -UVView::UVView( const std::string &name ) - : View( name, new ScenePlug ), m_textureGadgetsDirty( true ), m_framed( false ) +UVView::UVView( Gaffer::ScriptNodePtr scriptNode ) + : View( defaultName(), scriptNode, new ScenePlug ), m_textureGadgetsDirty( true ), m_framed( false ) { storeIndexOfNextChild( g_firstPlugIndex ); diff --git a/src/GafferSceneUIModule/ToolBinding.cpp b/src/GafferSceneUIModule/ToolBinding.cpp index 22dc968c729..78bec3ce08d 100644 --- a/src/GafferSceneUIModule/ToolBinding.cpp +++ b/src/GafferSceneUIModule/ToolBinding.cpp @@ -109,12 +109,6 @@ boost::python::list selection( const TransformTool &tool ) return result; } -IECore::PathMatcher lightToolSelection( const LightTool &tool ) -{ - IECorePython::ScopedGILRelease gilRelease; - return tool.selection(); -} - bool selectionEditable( const TransformTool &tool ) { IECorePython::ScopedGILRelease gilRelease; @@ -302,15 +296,9 @@ void GafferSceneUIModule::bindTools() .def( init() ) ; - { - scope s = GafferBindings::NodeClass( nullptr, no_init ) - .def( init() ) - .def( "selection", &lightToolSelection ) - .def( "selectionChangedSignal", &LightTool::selectionChangedSignal, return_internal_reference<1>() ) - ; - - GafferBindings::SignalClass, SelectionChangedSlotCaller>( "SelectionChangedSignal" ); - } + GafferBindings::NodeClass( nullptr, no_init ) + .def( init() ) + ; { scope s = GafferBindings::NodeClass( nullptr, no_init ) diff --git a/src/GafferSceneUIModule/ViewBinding.cpp b/src/GafferSceneUIModule/ViewBinding.cpp index 40e044d4872..d7e5ad447d1 100644 --- a/src/GafferSceneUIModule/ViewBinding.cpp +++ b/src/GafferSceneUIModule/ViewBinding.cpp @@ -315,7 +315,8 @@ struct UVViewSlotCaller void GafferSceneUIModule::bindViews() { - GafferBindings::NodeClass() + GafferBindings::NodeClass( nullptr, no_init ) + .def( init() ) .def( "frame", &frame, ( boost::python::arg_( "filter" ), boost::python::arg_( "direction" ) = Imath::V3f( -0.64, -0.422, -0.64 ) ) ) .def( "resolutionGate", &resolutionGateWrapper ) .def( "expandSelection", &expandSelection, ( boost::python::arg_( "depth" ) = 1 ) ) @@ -330,7 +331,8 @@ void GafferSceneUIModule::bindViews() .staticmethod( "registeredShadingModes" ) ; - GafferBindings::NodeClass() + GafferBindings::NodeClass( nullptr, no_init ) + .def( init() ) .def( "shaderPrefix", &ShaderView::shaderPrefix ) .def( "scene", (Gaffer::Node *(ShaderView::*)())&ShaderView::scene, return_value_policy() ) .def( "sceneChangedSignal", &ShaderView::sceneChangedSignal, return_internal_reference<1>() ) @@ -348,7 +350,8 @@ void GafferSceneUIModule::bindViews() SignalClass, SceneChangedSlotCaller>( "SceneChangedSignal" ); { - scope s = GafferBindings::NodeClass() + scope s = GafferBindings::NodeClass( nullptr, no_init ) + .def( init() ) .def( "setPaused", &setPaused ) .def( "getPaused", &UVView::getPaused ) .def( "state", &UVView::state ) diff --git a/src/GafferUI/View.cpp b/src/GafferUI/View.cpp index ead95c46837..1cadc9a0996 100644 --- a/src/GafferUI/View.cpp +++ b/src/GafferUI/View.cpp @@ -42,6 +42,7 @@ #include "Gaffer/Metadata.h" #include "Gaffer/Plug.h" #include "Gaffer/PlugAlgo.h" +#include "Gaffer/ScriptNode.h" #include "Gaffer/StringPlug.h" #include "boost/algorithm/string/predicate.hpp" @@ -84,9 +85,9 @@ GAFFER_NODE_DEFINE_TYPE( View ); size_t View::g_firstPlugIndex = 0; -View::View( const std::string &name, Gaffer::PlugPtr inPlug ) +View::View( const std::string &name, Gaffer::ScriptNodePtr scriptNode, Gaffer::PlugPtr inPlug ) : Node( name ), - m_viewportGadget( new ViewportGadget ) + m_scriptNode( scriptNode ), m_viewportGadget( new ViewportGadget ) { storeIndexOfNextChild( g_firstPlugIndex ); setChild( "in", inPlug ); @@ -106,6 +107,16 @@ View::~View() tools()->clearChildren(); } +Gaffer::ScriptNode *View::scriptNode() +{ + return m_scriptNode.get(); +} + +const Gaffer::ScriptNode *View::scriptNode() const +{ + return m_scriptNode.get(); +} + Gaffer::Plug *View::editScopePlug() { /// \todo Fix ImageView so it doesn't reorder plugs, and then @@ -206,6 +217,17 @@ View::NamedCreatorMap &View::namedCreators() ViewPtr View::create( Gaffer::PlugPtr plug ) { + Gaffer::ScriptNodePtr scriptNode; + if( auto node = plug->source()->node() ) + { + scriptNode = node->scriptNode(); + } + + if( !scriptNode ) + { + throw IECore::Exception( fmt::format( "Unable to find ScriptNode for `{}`", plug->fullName() ) ); + } + const Gaffer::Node *node = plug->node(); if( node ) { @@ -221,7 +243,9 @@ ViewPtr View::create( Gaffer::PlugPtr plug ) { if( boost::regex_match( plugPath, nIt->first ) ) { - return nIt->second( plug ); + ViewPtr view = nIt->second( scriptNode ); + view->inPlug()->setInput( plug ); + return view; } } } @@ -236,7 +260,9 @@ ViewPtr View::create( Gaffer::PlugPtr plug ) CreatorMap::const_iterator it = m.find( t ); if( it!=m.end() ) { - return it->second( plug ); + ViewPtr view = it->second( scriptNode ); + view->inPlug()->setInput( plug ); + return view; } t = IECore::RunTimeTyped::baseTypeId( t ); } @@ -254,6 +280,26 @@ void View::registerView( const IECore::TypeId nodeType, const std::string &plugP namedCreators()[nodeType].push_back( RegexAndCreator( boost::regex( plugPath ), creator ) ); } +bool View::acceptsInput( const Gaffer::Plug *plug, const Gaffer::Plug *inputPlug ) const +{ + if( !Node::acceptsInput( plug, inputPlug ) ) + { + return false; + } + + if( plug != inPlug() || !inputPlug ) + { + return true; + } + + // Refuse to view anything which isn't owned by the ScriptNode we + // were constructed for. All our state (context etc) is derived from + // that ScriptNode, and it doesn't make sense to use it with nodes + // from another script. + const ScriptNode *script = inputPlug->source()->ancestor(); + return !script || script == scriptNode(); +} + void View::toolsChildAdded( Gaffer::GraphComponent *child ) { auto tool = static_cast( child ); // Type guaranteed by `ToolContainer::acceptsChild()` diff --git a/src/GafferUIModule/ViewBinding.cpp b/src/GafferUIModule/ViewBinding.cpp index 2cc7e19f819..d57adee0324 100644 --- a/src/GafferUIModule/ViewBinding.cpp +++ b/src/GafferUIModule/ViewBinding.cpp @@ -45,6 +45,7 @@ #include "Gaffer/Context.h" #include "Gaffer/EditScope.h" #include "Gaffer/Plug.h" +#include "Gaffer/ScriptNode.h" #include "IECorePython/ExceptionAlgo.h" #include "IECorePython/ScopedGILRelease.h" @@ -63,8 +64,8 @@ class ViewWrapper : public GafferBindings::NodeWrapper public : - ViewWrapper( PyObject *self, const std::string &name, PlugPtr input ) - : GafferBindings::NodeWrapper( self, name, input ) + ViewWrapper( PyObject *self, const std::string &name, ScriptNodePtr scriptNode, PlugPtr input ) + : GafferBindings::NodeWrapper( self, name, scriptNode, input ) { } @@ -77,10 +78,10 @@ struct ViewCreator { } - ViewPtr operator()( Gaffer::PlugPtr plug ) + ViewPtr operator()( Gaffer::ScriptNodePtr scriptNode ) { IECorePython::ScopedGILLock gilLock; - ViewPtr result = extract( m_fn( plug ) ); + ViewPtr result = extract( m_fn( scriptNode ) ); return result; } @@ -149,7 +150,8 @@ Gaffer::NodePtr getPreprocessor( View &v ) void bindView() { scope s = GafferBindings::NodeClass( nullptr, no_init ) - .def( init() ) + .def( init() ) + .def( "scriptNode", (ScriptNode *(View::*)())&View::scriptNode, return_value_policy() ) .def( "editScope", (EditScope *(View::*)())&View::editScope, return_value_policy() ) .def( "getContext", (Context *(View::*)())&View::getContext, return_value_policy() ) .def( "setContext", &View::setContext ) diff --git a/startup/gui/viewer.py b/startup/gui/viewer.py index b631ccf5682..d8b2e36521d 100644 --- a/startup/gui/viewer.py +++ b/startup/gui/viewer.py @@ -59,10 +59,9 @@ # register a customised view for viewing scenes -def __sceneView( plug ) : +def __sceneView( scriptNode ) : - view = GafferSceneUI.SceneView() - view["in"].setInput( plug ) + view = GafferSceneUI.SceneView( scriptNode ) view["grid"]["dimensions"].setInput( preferences["viewer"]["gridDimensions"] ) return view