diff --git a/Changes.md b/Changes.md index 6239e20468a..12c4e74f63b 100644 --- a/Changes.md +++ b/Changes.md @@ -20,7 +20,7 @@ Improvements - PlugLayout : - A warning widget is now displayed when an invalid custom widget is registered. - `layout:customWidget::width` and `layout:customWidget::minimumWidth` metadata registrations are now supported for custom widgets. -- RenderPassEditor / RenderPassChooserWidget : Render passes disabled by render adaptors registered to `client = "RenderPassWedge"` are now shown as disabled. To differentiate these from user disabled render passes, an orange dot is shown in the corner of the disabled icon and the tooltip describes them as automatically disabled. +- RenderPassEditor / RenderPassChooserWidget : Render passes deleted or disabled by render adaptors registered to `client = "RenderPassWedge"` are now shown as disabled. To differentiate these from user disabled render passes, an orange dot is shown in the corner of the disabled icon and the tooltip describes them as automatically disabled. Fixes ----- diff --git a/python/GafferSceneUI/RenderPassEditor.py b/python/GafferSceneUI/RenderPassEditor.py index d7e96462705..edf5a4585ae 100644 --- a/python/GafferSceneUI/RenderPassEditor.py +++ b/python/GafferSceneUI/RenderPassEditor.py @@ -1036,11 +1036,16 @@ def _valuesForUpdate( plugs, auxiliaryPlugs ) : renderPasses = {} with Gaffer.Context( Gaffer.Context.current() ) as context : + adaptedRenderPassNames = globalsPlug.getValue().get( "option:renderPass:names", IECore.StringVectorData() ) + context["renderPassEditor:disableAdaptors"] = True for renderPass in globalsPlug.getValue().get( "option:renderPass:names", IECore.StringVectorData() ) : renderPasses.setdefault( "all", [] ).append( renderPass ) context["renderPass"] = renderPass context["renderPassEditor:disableAdaptors"] = False - if globalsPlug.getValue().get( "option:renderPass:enabled", IECore.BoolData( True ) ).value : + if renderPass not in adaptedRenderPassNames : + # The render pass has been deleted by a render adaptor so present it as disabled + renderPasses.setdefault( "adaptorDisabled", [] ).append( renderPass ) + elif globalsPlug.getValue().get( "option:renderPass:enabled", IECore.BoolData( True ) ).value : renderPasses.setdefault( "enabled", [] ).append( renderPass ) else : context["renderPassEditor:disableAdaptors"] = True diff --git a/python/GafferSceneUITest/RenderPassEditorTest.py b/python/GafferSceneUITest/RenderPassEditorTest.py index c72f7981bdf..3954c4b4c4d 100644 --- a/python/GafferSceneUITest/RenderPassEditorTest.py +++ b/python/GafferSceneUITest/RenderPassEditorTest.py @@ -208,6 +208,35 @@ def createAdaptor() : self.assertEqual( pathCopy.property( "renderPassPath:enabled" ), p in ( "/A", "/D" ) ) self.assertTrue( pathCopy.property( "renderPassPath:enabledWithoutAdaptors" ) ) + def testRenderPassPathAdaptorDeletingPasses( self ) : + + def createAdaptor() : + + node = GafferScene.DeleteRenderPasses() + node["names"].setValue( "B C" ) + return node + + GafferScene.SceneAlgo.registerRenderAdaptor( "RenderPassEditorTest", createAdaptor, client = "RenderPassWedge" ) + self.addCleanup( GafferScene.SceneAlgo.deregisterRenderAdaptor, "RenderPassEditorTest" ) + + renderPasses = GafferScene.RenderPasses() + renderPasses["names"].setValue( IECore.StringVectorData( [ "A", "B", "C", "D" ] ) ) + + adaptors = GafferSceneUI.RenderPassEditor._createRenderAdaptors() + adaptors["in"].setInput( renderPasses["out"] ) + + context = Gaffer.Context() + path = _GafferSceneUI._RenderPassEditor.RenderPassPath( adaptors["out"], context, "/" ) + + self.assertEqual( [ str( c ) for c in path.children() ], [ "/A", "/B", "/C", "/D" ] ) + + pathCopy = path.copy() + + for p in [ "/A", "/B", "/C", "/D" ] : + pathCopy.setFromString( p ) + self.assertEqual( pathCopy.property( "renderPassPath:enabled" ), p in ( "/A", "/D" ) ) + self.assertTrue( pathCopy.property( "renderPassPath:enabledWithoutAdaptors" ) ) + def testSearchFilter( self ) : renderPasses = GafferScene.RenderPasses() diff --git a/src/GafferSceneUIModule/RenderPassEditorBinding.cpp b/src/GafferSceneUIModule/RenderPassEditorBinding.cpp index 859ab499faf..c315b2d8022 100644 --- a/src/GafferSceneUIModule/RenderPassEditorBinding.cpp +++ b/src/GafferSceneUIModule/RenderPassEditorBinding.cpp @@ -192,7 +192,7 @@ PathMatcher pathMatcherCacheGetter( const PathMatcherCacheGetterKey &key, size_t } using PathMatcherCache = IECorePreview::LRUCache; -PathMatcherCache g_pathMatcherCache( pathMatcherCacheGetter, 25 ); +PathMatcherCache g_pathMatcherCache( pathMatcherCacheGetter, 50 ); const InternedString g_renderPassContextName( "renderPass" ); const InternedString g_disableAdaptorsContextName( "renderPassEditor:disableAdaptors" ); @@ -320,6 +320,15 @@ class RenderPassPath : public Gaffer::Path } else if( name == g_renderPassEnabledPropertyName || name == g_renderPassEnabledWithoutAdaptorsPropertyName ) { + if( + name == g_renderPassEnabledPropertyName && + !( pathMatcher( canceller, /* disableAdaptors = */ false ).match( names() ) & PathMatcher::ExactMatch ) + ) + { + // The render pass has been deleted by a render adaptor, so present it to the user as disabled. + return new BoolData( false ); + } + const PathMatcher p = pathMatcher( canceller ); if( p.match( names() ) & PathMatcher::ExactMatch ) { @@ -402,7 +411,7 @@ class RenderPassPath : public Gaffer::Path // practical as render pass names are used in output file paths where the included '/' characters would be // interpreted as subdirectories. Validation in the UI will prevent users from inserting invalid characters // such as '/' into render pass names. - const IECore::PathMatcher pathMatcher( const IECore::Canceller *canceller ) const + const IECore::PathMatcher pathMatcher( const IECore::Canceller *canceller, bool disableAdaptors = true ) const { Context::EditableScope scopedContext( m_context.get() ); if( canceller ) @@ -410,6 +419,10 @@ class RenderPassPath : public Gaffer::Path scopedContext.setCanceller( canceller ); } + if( disableAdaptors ) + { + scopedContext.set( g_disableAdaptorsContextName, &disableAdaptors ); + } if( ConstStringVectorDataPtr renderPassData = m_scene.get()->globals()->member( g_renderPassNamesOption ) ) { const PathMatcherCacheGetterKey key( renderPassData, m_grouped );