Skip to content

Commit

Permalink
LightEditor : Fix missing icons for mute and solo
Browse files Browse the repository at this point in the history
In the process of hiding mute and solo icons for light blockers, we also
mistakenly hid them for groups. On further consideration, we also want
to show the icons for light blockers, which will eventually get mute and
solo capabilities. This restores the icons for all locations in the
Light Editor and also fixes an error causing the `filteredLights` plug
to be returned when querying any attribute from a `LightFilter`.
  • Loading branch information
ericmehl committed Jul 2, 2024
1 parent 0911923 commit e6fabdf
Show file tree
Hide file tree
Showing 6 changed files with 14 additions and 63 deletions.
2 changes: 2 additions & 0 deletions Changes.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ Improvements

- Cryptomatte : Renamed `__manifestScene` plug to `manifestScene` so it is no longer considered to be private.
- EditScopePlugValueWidget : Width can now be configured via `<layoutName>:width` metadata. This enables customisation of the Edit Scope menu width by registering metadata in a startup file, such as `Gaffer.Metadata.registerValue( GafferSceneUI.RenderPassEditor.Settings, "editScope", "layout:width", 450 )` to double the standard width of the Edit Scope menu in the Render Pass Editor.
- LightEditor : Mute and solo columns now accurately reflect the presence of the `light:mute` attribute (for the Mute column) and membership in the `soloLights` set (for the Solo column).

Fixes
-----
Expand All @@ -14,6 +15,7 @@ Fixes
- PrimitiveInspector : Fixed bug which claimed "Location does not exist" for objects without any primitive variables.
- OpenColorIO : Fixed the display transform used to show colours in popups.
- SceneInspector : Fixed "Show History" menu items.
- LightEditor : Fixed regression (introduced in 1.4.8.0) causing the mute and solo icons to not show up for groups.

API
---
Expand Down
20 changes: 3 additions & 17 deletions python/GafferSceneUI/LightEditor.py
Original file line number Diff line number Diff line change
Expand Up @@ -295,9 +295,9 @@ def __updateColumns( self ) :
sectionColumns += [ c( self.__settingsNode["in"], self.__settingsNode["editScope"] ) for c in section.values() ]

nameColumn = self.__pathListing.getColumns()[0]
self.__muteColumn = self.__pathListing.getColumns()[1]
self.__soloColumn = self.__pathListing.getColumns()[2]
self.__pathListing.setColumns( [ nameColumn, self.__muteColumn, self.__soloColumn ] + sectionColumns )
muteColumn = self.__pathListing.getColumns()[1]
soloColumn = self.__pathListing.getColumns()[2]
self.__pathListing.setColumns( [ nameColumn, muteColumn, soloColumn ] + sectionColumns )

def __settingsPlugSet( self, plug ) :

Expand Down Expand Up @@ -385,27 +385,13 @@ def __editSelectedCells( self, pathListing, quickBoolean = True ) :
inspections = []

with Gaffer.Context( self.getContext() ) as context :
lightSetMembers = self.__settingsNode["in"].set( "__lights" ).value

for selection, column in zip( pathListing.getSelection(), pathListing.getColumns() ) :
if not isinstance( column, _GafferSceneUI._LightEditorInspectorColumn ) :
continue
for pathString in selection.paths() :
path = GafferScene.ScenePlug.stringToPath( pathString )

if (
( column == self.__muteColumn or column == self.__soloColumn ) and
not ( lightSetMembers.match( path ) & (
IECore.PathMatcher.Result.ExactMatch | IECore.PathMatcher.Result.DescendantMatch
) )
) :
with GafferUI.PopupWindow() as self.__popup :
with GafferUI.ListContainer( GafferUI.ListContainer.Orientation.Horizontal, spacing = 4 ) :
GafferUI.Image( "warningSmall.png" )
GafferUI.Label( "<h4>The " + column.headerData().value + " column can only be toggled for lights." )
self.__popup.popup( parent = self )
return

context["scene:path"] = path
inspection = column.inspector().inspect()

Expand Down
2 changes: 2 additions & 0 deletions python/GafferSceneUITest/AttributeInspectorTest.py
Original file line number Diff line number Diff line change
Expand Up @@ -752,6 +752,8 @@ def testLightFilter( self ) :
edit = lightFilter["filteredLights"]
)

self.assertIsNone( self.__inspect( editScope["out"], "/lightFilter", "bogusAttribute" ) )

inspection = self.__inspect( editScope["out"], "/lightFilter", "filteredLights", editScope )
edit = inspection.acquireEdit()
edit["enabled"].setValue( True )
Expand Down
26 changes: 0 additions & 26 deletions python/GafferSceneUITest/LightEditorTest.py
Original file line number Diff line number Diff line change
Expand Up @@ -868,32 +868,6 @@ def testDeregisterColumn( self ) :
self.assertNotIn( "Y", columnNames )
self.assertNotIn( "Z", columnNames )

def testLightBlockerSoloDisabled( self ) :

script = Gaffer.ScriptNode()

script["blocker"] = GafferScene.Cube()
script["blocker"]["sets"].setValue( "__lightFilters" )

editor = GafferSceneUI.LightEditor( script )
editor._LightEditor__updateColumns()
GafferSceneUI.LightEditor._LightEditor__updateColumns.flush( editor )

editor.setNodeSet( Gaffer.StandardSet( [ script["blocker"] ] ) )

widget = editor._LightEditor__pathListing

columns = widget.getColumns()
for i, c in zip( range( 0, len( columns ) ), columns ) :
if isinstance( c, _GafferSceneUI._LightEditorSetMembershipColumn ) :
selection = [ IECore.PathMatcher() for i in range( 0, len( columns ) ) ]
selection[i].addPath( "/cube" )
widget.setSelection( selection )

editor._LightEditor__editSelectedCells( widget )

self.assertTrue( script["blocker"]["out"].set( "soloLights" ).value.isEmpty() )


if __name__ == "__main__" :
unittest.main()
7 changes: 6 additions & 1 deletion src/GafferSceneUI/AttributeInspector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,7 @@ Gaffer::ValuePlugPtr attributePlug( const Gaffer::CompoundDataPlug *parentPlug,
//////////////////////////////////////////////////////////////////////////

static InternedString g_lightMuteAttributeName( "light:mute" );
static InternedString g_filteredLightsAttributeName( "filteredLights");

AttributeInspector::AttributeInspector(
const GafferScene::ScenePlugPtr &scene,
Expand Down Expand Up @@ -263,7 +264,11 @@ Gaffer::ValuePlugPtr AttributeInspector::source( const GafferScene::SceneAlgo::H

else if( auto lightFilter = runTimeCast<LightFilter>( sceneNode ) )
{
return lightFilter->filteredLightsPlug();
if( m_attribute == g_filteredLightsAttributeName )
{
return lightFilter->filteredLightsPlug();
}
return nullptr;
}

else if( auto camera = runTimeCast<GafferScene::Camera>( sceneNode ) )
Expand Down
20 changes: 1 addition & 19 deletions src/GafferSceneUIModule/LightEditorBinding.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,15 +79,7 @@ namespace
{

ConstStringDataPtr g_emptyLocation = new StringData( "emptyLocation.png" );
const InternedString g_lightSetName( "__lights" );

bool isLight( const ScenePath *scenePath, const Canceller *canceller )
{
ScenePlug::SetScope scope( scenePath->getContext(), &g_lightSetName );
scope.setCanceller( canceller );
ConstPathMatcherDataPtr lightsData = scenePath->getScene()->setPlug()->getValue();
return lightsData->readable().match( scenePath->names() ) & PathMatcher::ExactMatch;
}
const InternedString g_lightFilterSetName( "__lightFilters" );

class LocationNameColumn : public StandardPathColumn
{
Expand Down Expand Up @@ -298,11 +290,6 @@ class MuteColumn : public InspectorColumn
return result;
}

if( !isLight( scenePath, canceller ) )
{
return CellData();
}

if( auto value = runTimeCast<const BoolData>( result.value ) )
{
result.icon = value->readable() ? m_muteIconData : m_unMuteIconData;
Expand Down Expand Up @@ -423,11 +410,6 @@ class SetMembershipColumn : public InspectorColumn
return result;
}

if( !isLight( scenePath, canceller ) )
{
return CellData();
}

std::string toolTip;
if( auto toolTipData = runTimeCast<const StringData>( result.toolTip ) )
{
Expand Down

0 comments on commit e6fabdf

Please sign in to comment.