Skip to content

Commit

Permalink
Merge branch '1.5_maintenance'
Browse files Browse the repository at this point in the history
  • Loading branch information
johnhaddon committed Nov 22, 2024
2 parents bee53cd + 58eaee1 commit e383445
Show file tree
Hide file tree
Showing 33 changed files with 1,048 additions and 200 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/main/installDependencies.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@

# Determine default archive URL.

defaultURL = "https://github.com/GafferHQ/dependencies/releases/download/9.0.0/gafferDependencies-9.0.0-{platform}{buildEnvironment}.{extension}"
defaultURL = "https://github.com/GafferHQ/dependencies/releases/download/9.1.0/gafferDependencies-9.1.0-{platform}{buildEnvironment}.{extension}"

# Parse command line arguments.

Expand Down
43 changes: 41 additions & 2 deletions Changes.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,22 @@



1.5.x.x (relative to 1.5.0.1)
1.5.x.x (relative to 1.5.1.0)
=======



1.5.1.0 (relative to 1.5.0.1)
=======

Features
--------

- EditScope : Introduced the Global Edit Target, providing script-level control over the target used by editors. The Global Edit Target can be set from a new "Edit Target" menu in the menu bar, which displays all available edit targets upstream of the focus node.
- Editors now follow the Global Edit Target by default, allowing for a simpler experience when switching multiple editors to a common target.
- Individual editors can be overridden to use a specific edit target where necessary. An overridden editor can return to following the Global Edit Target via the new "Follow Global Edit Target" menu item.
- While following the Global Edit Target, an editor's Edit Scope menu will shrink to only display an icon. When an Editor is overridden to a specific edit target, the menu grows to display the name of the target.

Improvements
------------

Expand All @@ -15,7 +28,22 @@ Improvements
- DeletePoints : Added modes for deleting points based on a list of ids.
- Light Editor, Attribute Editor, Spreadsheet : Add original and current color swatches to color popups.
- SceneView : Added fallback framing extents to create a reasonable view when `SceneGadget` is empty, for example if the grid is hidden.
- ColorChooser : Added an option to toggle the dynamic update of colors displayed in the slider and color field backgrounds. When enabled, the widget backgrounds update to show the color that will result from moving the indicator to a given position. When disabled, a static range of values is displayed instead.
- ColorChooser :
- Added an option to toggle the dynamic update of colors displayed in the slider and color field backgrounds. When enabled, the widget backgrounds update to show the color that will result from moving the indicator to a given position. When disabled, a static range of values is displayed instead.
- Holding the <kbd>Control</kbd> key now constrains dragging in the color field to a single axis.
- EditScope :
- Simplified the Edit Scope menu UI :
- Removed the dark background.
- Changed the menu button color to be always blue.
- Removed the "Navigation Arrow" button from the right side of the Edit Scope menu. Its actions have been relocated to a "Show Edits" submenu of the Edit Scope menu.
- Hid the label. It can be made visible for a specific plug by registering `editScopePlugValueWidget:showLabel` metadata with a value of `True`.
- Renamed "None" mode to "Source" and added icon.
- The "Source" menu item now displays a checkbox when chosen.
- Added a "No EditScopes Available" menu item that is displayed when no upstream EditScopes are available.
- Increased menu item icon sizes.
- A lock icon is now displayed next to read-only nodes.
- RenderPassEditor : Changed the current render pass indicator to yellow to match other context-related UI elements.
- GraphEditor : Moved "Show Input Connections" and "Show Output Connections" to "Connections" sub-menu and added "Show Input Labels" and "Show Output Labels" items.

Fixes
-----
Expand All @@ -27,6 +55,9 @@ Fixes
- `gaffer view` : Fixed default OpenColorIO display transform.
- AnimationEditor : Fixed changing of the current frame by dragging the frame indicator or clicking on the time axis.
- ImageWriter : Matched view metadata to Nuke when using the Nuke options for `layout`. This should address an issue where EXRs written from Gaffer using Nuke layouts sometimes did not load correctly in Nuke (#6120). In the unlikely situation that you were relying on the old behaviour, you can set the env var `GAFFERIMAGE_IMAGEWRITER_OMIT_DEFAULT_NUKE_VIEW = 1` in order to keep the old behaviour.
- OSLObject : Fixed `getattribute()` to support 64 bit integer data, such as an `instanceId` primitive variable loaded from USD. Since OSL doesn't provide a 64 bit integer type, values are truncated to 32 bits.
- MeshSplit : Vertex order is now preserved.
- DispatchDialogue : Removed `_DispatcherCreationWidget` from shown nodes.

API
---
Expand All @@ -35,6 +66,14 @@ API
- OpenColorIOConfigPlugUI :
- Added `connectToApplication()` function.
- Deprecated `connect()` function. Use `connectToApplication()` instead.
- SceneEditor : Added `editScope()` method.
- Image : Added optional `image` argument to `createSwatch()` static method.
- StandardNodeGadget : Added support for `nodeGadget:inputNoduleLabelsVisible` and `nodeGadget:outputNoduleLabelsVisible` metadata for setting nodule labels always on. If the metadata entry is not set or `False`, labels will be visible only when they are hovered over.

Build
-----

- Cortex : Updated to version 10.5.11.0.

1.5.0.1 (relative to 1.5.0.0)
=======
Expand Down
6 changes: 6 additions & 0 deletions doc/source/Interface/ControlsAndShortcuts/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -438,3 +438,9 @@ Toggle cell selection | {kbd}`Ctrl` + {{leftClick
Edit selected cells | {kbd}`Return`<br>or<br>{kbd}`Enter`
Disable edit | {kbd}`D`
Toggle a render pass as active | {kbd}`Return` or {{leftClick}} {{leftClick}} a cell within the {{activeRenderPass}} column

## Color Chooser Color Field ##

Action | Control or shortcut
-----------------------------------------------------|--------------------
Constrain drag to single axis | {kbd}`Ctrl`
6 changes: 6 additions & 0 deletions include/GafferUI/StandardNodeGadget.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ namespace GafferUI
class PlugAdder;
class NoduleLayout;
class ConnectionCreator;
class StandardNodule;

/// The standard means of representing a Node in a GraphGadget.
/// Nodes are represented as rectangular boxes with the name displayed
Expand Down Expand Up @@ -150,6 +151,7 @@ class GAFFERUI_API StandardNodeGadget : public NodeGadget
bool dragMove( GadgetPtr gadget, const DragDropEvent &event );
bool dragLeave( GadgetPtr gadget, const DragDropEvent &event );
bool drop( GadgetPtr gadget, const DragDropEvent &event );
void noduleAdded( Nodule *nodule );

ConnectionCreator *closestDragDestination( const DragDropEvent &event ) const;

Expand All @@ -164,6 +166,10 @@ class GAFFERUI_API StandardNodeGadget : public NodeGadget
void updateFocusGadgetVisibility();
void updateTextDimming();

friend class StandardNodule;
// Set the visibility for all nodules based on the metadata registered for this node.
void applyNoduleLabelVisibilityMetadata();

IE_CORE_FORWARDDECLARE( ErrorGadget );
ErrorGadget *errorGadget( bool createIfMissing = true );
void error( const Gaffer::Plug *plug, const Gaffer::Plug *source, const std::string &message );
Expand Down
4 changes: 4 additions & 0 deletions include/GafferUI/StandardNodule.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,11 @@ class GAFFERUI_API StandardNodule : public Nodule
bool dragEnd( GadgetPtr gadget, const DragDropEvent &event );
bool drop( GadgetPtr gadget, const DragDropEvent &event );

/// \deprecated Use overloaded method without `visible` when setting `visible = true`
/// or `StandardNodeGadget::applyNoduleLabelVisibilityMetadata()` to restore
/// metadata-aware visibility.
void setCompatibleLabelsVisible( const DragDropEvent &event, bool visible );
void setCompatibleLabelsVisible( const DragDropEvent &event );

private :

Expand Down
2 changes: 2 additions & 0 deletions python/GafferDispatchUI/DispatchDialogue.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@ def __init__( self, tasks, dispatchers, nodesToShow, postDispatchBehaviour=PostD
nodeFrame.addChild( self.__nodeEditor( node ) )
# remove the per-node execute button
Gaffer.Metadata.registerValue( node, "layout:customWidget:dispatchButton:widgetType", "", persistent = False )
# remove the per-node widget to create a dispatcher
Gaffer.Metadata.registerValue( node, "layout:customWidget:dispatcherCreationWidget:widgetType", "", persistent = False )
self.__tabs.setLabel( nodeFrame, node.relativeName( self.__script ) )

with GafferUI.ListContainer() as dispatcherTab :
Expand Down
2 changes: 1 addition & 1 deletion python/GafferImageUI/OpenColorIOConfigPlugUI.py
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ def __menuDefinition( self ) :
result.append( "/__OptionsDivider__", { "divider" : True, "label" : "Options" } )

result.append(
f"/Use Default Display And View", {
f"/Follow Default Display And View", {
"command" : functools.partial( Gaffer.WeakMethod( self.__setToDefault ) ),
"checkBox" : self.__currentValue == "__default__",
"description" : "Always uses the default display and view for the current config. Useful when changing configs often, or using context-sensitive configs."
Expand Down
27 changes: 27 additions & 0 deletions python/GafferOSLTest/ShadingEngineTest.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,33 @@ def testDoubleAsIntViaGetAttribute( self ) :
for i, c in enumerate( p["Ci"] ) :
self.assertEqual( c[0], float(i) )

def testInt64GetAttribute( self ) :

shader = self.compileShader( pathlib.Path( __file__ ).parent / "shaders" / "intAttribute.osl" )

for dataType in ( IECore.Int64VectorData, IECore.UInt64VectorData ) :

with self.subTest( dataType = dataType ) :

points = IECore.CompoundData( {
"P" : IECore.V3fVectorData( [ imath.V3f( i ) for i in range( 0, 10 ) ] ),
"int64Data" : dataType( range( 0, 10 ) )
} )

engine = GafferOSL.ShadingEngine( IECoreScene.ShaderNetwork(
shaders = {
"output" : IECoreScene.Shader( shader, "osl:surface", { "name" : "int64Data" } ),
},
output = "output"
) )

self.assertTrue( engine.needsAttribute( "int64Data" ) )

points = engine.shade( points )

for i, c in enumerate( points["Ci"] ) :
self.assertEqual( c[0], float( i ) )

def testUserDataViaGetAttribute( self ) :

shader = self.compileShader( pathlib.Path( __file__ ).parent / "shaders" / "attribute.osl" )
Expand Down
2 changes: 1 addition & 1 deletion python/GafferSceneUI/AttributeEditor.py
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,7 @@ def __transferSelectionFromScriptNode( self ) :
"editScope" : [

"plugValueWidget:type", "GafferUI.EditScopeUI.EditScopePlugValueWidget",
"layout:width", 225,
"layout:width", 130,

],

Expand Down
9 changes: 4 additions & 5 deletions python/GafferSceneUI/LightEditor.py
Original file line number Diff line number Diff line change
Expand Up @@ -311,9 +311,8 @@ def __columnContextMenuSignal( self, column, pathListing, menuDefinition ) :
# or unintuitive
deleteEnabled = True
inputNode = self.settings()["in"].getInput().node()
editScopeInput = self.settings()["editScope"].getInput()
if editScopeInput is not None :
editScopeNode = editScopeInput.node()
editScopeNode = self.editScope()
if editScopeNode is not None :
if inputNode != editScopeNode and editScopeNode not in Gaffer.NodeAlgo.upstreamNodes( inputNode ) :
# Edit scope is downstream of input
deleteEnabled = False
Expand Down Expand Up @@ -368,7 +367,7 @@ def __deleteLights( self, *unused ) :
# There may be multiple columns with a selection, but we only operate on the name column.
selection = self.__pathListing.getSelection()[0]

editScope = self.settings()["editScope"].getInput().node()
editScope = self.editScope()

with Gaffer.UndoScope( editScope.ancestor( Gaffer.ScriptNode ) ) :
GafferScene.EditScopeAlgo.setPruned( editScope, selection, True )
Expand Down Expand Up @@ -414,7 +413,7 @@ def __deleteLights( self, *unused ) :
"editScope" : [

"plugValueWidget:type", "GafferUI.EditScopeUI.EditScopePlugValueWidget",
"layout:width", 225,
"layout:width", 130,

],

Expand Down
26 changes: 11 additions & 15 deletions python/GafferSceneUI/RenderPassEditor.py
Original file line number Diff line number Diff line change
Expand Up @@ -402,13 +402,11 @@ def __canEditRenderPasses( self, editScope = None ) :

if editScope is None :
# No edit scope provided so use the current selected
editScopeInput = self.settings()["editScope"].getInput()
if editScopeInput is None :
editScope = self.editScope()
if editScope is None :
# No edit scope selected
return False

editScope = editScopeInput.node()

if inputNode != editScope and editScope not in Gaffer.NodeAlgo.upstreamNodes( inputNode ) :
# Edit scope is downstream of input
return False
Expand Down Expand Up @@ -456,11 +454,10 @@ def __deleteSelectedRenderPasses( self ) :
if len( selectedRenderPasses ) == 0 :
return

editScopeInput = self.settings()["editScope"].getInput()
if editScopeInput is None :
editScope = self.editScope()
if editScope is None :
return

editScope = editScopeInput.node()
localRenderPasses = []
renderPassesProcessor = editScope.acquireProcessor( "RenderPasses", createIfNecessary = False )
if renderPassesProcessor is not None :
Expand Down Expand Up @@ -528,10 +525,9 @@ def __renderPassNames( self, plug ) :

def __renderPassCreationDialogue( self ) :

editScopeInput = self.settings()["editScope"].getInput()
assert( editScopeInput is not None )
editScope = self.editScope()
assert( editScope is not None )

editScope = editScopeInput.node()
dialogue = _RenderPassCreationDialogue( self.__renderPassNames( self.settings()["in"] ), editScope )
renderPassName = dialogue.waitForRenderPassName( parentWindow = self.ancestor( GafferUI.Window ) )
if renderPassName :
Expand Down Expand Up @@ -564,14 +560,14 @@ def __removeButtonClicked( self, button ) :

def __metadataChanged( self, nodeTypeId, key, node ) :

editScopeInput = self.settings()["editScope"].getInput()
if editScopeInput is None :
editScope = self.editScope()
if editScope is None :
return

renderPassesProcessor = editScopeInput.node().acquireProcessor( "RenderPasses", createIfNecessary = False )
renderPassesProcessor = editScope.acquireProcessor( "RenderPasses", createIfNecessary = False )

if (
Gaffer.MetadataAlgo.readOnlyAffectedByChange( editScopeInput, nodeTypeId, key, node ) or
Gaffer.MetadataAlgo.readOnlyAffectedByChange( editScope, nodeTypeId, key, node ) or
( renderPassesProcessor and Gaffer.MetadataAlgo.readOnlyAffectedByChange( renderPassesProcessor, nodeTypeId, key, node ) )
) :
self.__updateButtonStatus()
Expand Down Expand Up @@ -638,7 +634,7 @@ def __updateButtonStatus( self, *unused ) :
"editScope" : [

"plugValueWidget:type", "GafferUI.EditScopeUI.EditScopePlugValueWidget",
"layout:width", 225,
"layout:width", 130,

],

Expand Down
23 changes: 23 additions & 0 deletions python/GafferSceneUI/SceneEditor.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,19 @@ def __init__( self, topLevelWidget, scriptNode, **kw ) :

self.__parentingConnections = {}

self.__globalEditTargetLinked = False
self.parentChangedSignal().connect( Gaffer.WeakMethod( self.__parentChanged ) )

def editScope( self ) :

if not "editScope" in self.settings() :
return None

return Gaffer.PlugAlgo.findSource(
self.settings()["editScope"],
lambda plug : plug.node() if isinstance( plug.node(), Gaffer.EditScope ) else None
)

def _updateFromSet( self ) :

# Find ScenePlugs and connect them to `settings()["in"]`.
Expand Down Expand Up @@ -124,6 +137,16 @@ def _titleFormat( self ) :
_ellipsis = False
)

def __parentChanged( self, widget ) :

if self.__globalEditTargetLinked or not "editScope" in self.settings() :
return

compoundEditor = self.ancestor( GafferUI.CompoundEditor )
if compoundEditor :
self.settings()["editScope"].setInput( compoundEditor.settings()["editScope"] )
self.__globalEditTargetLinked = True

def __scenePlugParentChanged( self, plug, newParent ) :

self._updateFromSet()
Expand Down
Loading

0 comments on commit e383445

Please sign in to comment.