Skip to content

Commit

Permalink
ShaderUI : Add parameter filter
Browse files Browse the repository at this point in the history
  • Loading branch information
ericmehl committed Jun 16, 2023
1 parent 0d48347 commit afb5c1c
Show file tree
Hide file tree
Showing 2 changed files with 122 additions and 15 deletions.
1 change: 1 addition & 0 deletions Changes.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ Improvements
- SceneReader :
- Fixed `I/O Exception` errors triggered by closing and reopening the same USD file.
- Increased the default limit for the number of open files to 2000 (or 25% of the file handle limit, whichever is lowest).
- ShaderQuery and ShaderTweaks : Added a filter for shader parameter names in the shader browser.

Fixes
-----
Expand Down
136 changes: 121 additions & 15 deletions python/GafferSceneUI/ShaderUI.py
Original file line number Diff line number Diff line change
Expand Up @@ -621,6 +621,89 @@ def __parameterValues( self ) :

return None

# A path filter that keeps a path if it, any of its ancestors or any of its descendants have a
# property `propertyName` that matches `patterns`.

class _PathMatcherPathFilter( Gaffer.PathFilter ) :

def __init__( self, patterns, paths = [], propertyName = "name", userData = {} ) :

Gaffer.PathFilter.__init__( self, userData )

self.__paths = paths
self.__patterns = patterns
self.__propertyName = propertyName
self.__pathMatcherDirty = True
self.__pathMatcher = IECore.PathMatcher()

def setPaths( self, paths ) :

if self.__paths == paths :
return

self.__paths = paths
self.__pathMatcherDirty = True
self.changedSignal()( self )

def getPaths( self ) :

return self.__paths

def setMatchPatterns( self, patterns ) :

if self.__patterns == patterns :
return

self.__patterns = patterns
self.__pathMatcherDirty = True
self.changedSignal()( self )

def getMatchPatterns( self ) :

return self.__patterns

def setPropertyName( self, propertyName ) :

if( self.__propertyName == propertyName ) :
return

self.__propertyName = propertyName
self.__pathMatcherDirty = True
self.changedSignal()( self )

def getPropertyName( self ) :

return self.__propertyName

def _filter( self, paths, canceller ) :

if self.__patterns == "" or len( paths ) == 0 :
return

self.__updatePathMatcher()

result = [ p for p in paths if self.__pathMatcher.match( str( p ) ) ]

return result

def __updatePathMatcher( self ) :

if not self.__pathMatcherDirty :
return

self.__pathMatcher.clear()

for p in self.__paths :
property = p.property( self.__propertyName )
if property is None :
continue

for pattern in self.__patterns :
if IECore.StringAlgo.match( property, pattern ) :
self.__pathMatcher.addPath( str( p ) )

GafferUI.PathFilterWidget.registerType( _PathMatcherPathFilter, GafferUI.MatchPatternPathFilterWidget )

class _ShaderParameterDialogue( GafferUI.Dialogue ) :

def __init__( self, shaderNetworks, title = None, **kw ) :
Expand All @@ -630,27 +713,39 @@ def __init__( self, shaderNetworks, title = None, **kw ) :

GafferUI.Dialogue.__init__( self, title, **kw )

self.__filter = _PathMatcherPathFilter( [ "" ] )
self.__filter.setEnabled( False )
self.__filter.userData()["UI"] = {
"editable" : True,
"label" : "Filter",
"propertyFilters" : { "name": "Name", "shader:type": "Type" }
}

self.__shaderNetworks = shaderNetworks
self.__path = None

tmpPath = Gaffer.DictPath( {}, "/" )
self.__pathListingWidget = GafferUI.PathListingWidget(
tmpPath,
columns = (
_DuplicateIconColumn( "Name", "name" ),
GafferUI.PathListingWidget.StandardColumn( "Type", "shader:type" ),
GafferUI.PathListingWidget.StandardColumn( "Value", "shader:value" ),
_ShaderInputColumn( "Input" ),
),
allowMultipleSelection = True,
displayMode = GafferUI.PathListingWidget.DisplayMode.Tree,
sortable = False,
horizontalScrollMode = GafferUI.ScrollMode.Automatic
)

with GafferUI.ListContainer( spacing = 4 ) as self.__column :
self.__pathListingWidget = GafferUI.PathListingWidget(
tmpPath,
columns = (
_DuplicateIconColumn( "Name", "name" ),
GafferUI.PathListingWidget.StandardColumn( "Type", "shader:type" ),
GafferUI.PathListingWidget.StandardColumn( "Value", "shader:value" ),
_ShaderInputColumn( "Input" ),
),
allowMultipleSelection = True,
displayMode = GafferUI.PathListingWidget.DisplayMode.Tree,
sortable = False,
horizontalScrollMode = GafferUI.ScrollMode.Automatic
)

GafferUI.PathFilterWidget.create( self.__filter )

self.__inputNavigateColumn = self.__pathListingWidget.getColumns()[3]

self._setWidget( self.__pathListingWidget )
self._setWidget( self.__column )

self.__pathListingWidget.selectionChangedSignal().connect( Gaffer.WeakMethod( self.__updateButtonState ), scoped = False )
self.__pathListingWidget.buttonReleaseSignal().connectFront( Gaffer.WeakMethod( self.__buttonRelease ), scoped = False )
Expand All @@ -664,8 +759,19 @@ def __init__( self, shaderNetworks, title = None, **kw ) :

self.__updateButtonState()

self.setPath( _ShaderPath( self.__shaderNetworks, path = "/" ) )
rootPath = _ShaderPath( self.__shaderNetworks, path = "/", filter = self.__filter )

def collectPaths( parentPath ) :
result = []
for p in parentPath.children() :
result.append( p )
result += collectPaths( p )

return result

self.__filter.setPaths( collectPaths( rootPath ) )

self.setPath( rootPath )

def getPath( self ) :

Expand Down

0 comments on commit afb5c1c

Please sign in to comment.