Merge pull request #5779 from ynput/bugfix/OP-7126_Nuke-Load-Published-Gizmos

This commit is contained in:
Jakub Ježek 2023-10-17 16:20:40 +02:00 committed by GitHub
commit 37aba49044
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 112 additions and 53 deletions

View file

@ -48,20 +48,15 @@ from openpype.pipeline import (
get_current_asset_name,
)
from openpype.pipeline.context_tools import (
get_current_project_asset,
get_custom_workfile_template_from_session
)
from openpype.pipeline.colorspace import (
get_imageio_config
)
from openpype.pipeline.colorspace import get_imageio_config
from openpype.pipeline.workfile import BuildWorkfile
from . import gizmo_menu
from .constants import ASSIST
from .workio import (
save_file,
open_file
)
from .workio import save_file
from .utils import get_node_outputs
log = Logger.get_logger(__name__)
@ -2802,16 +2797,28 @@ def find_free_space_to_paste_nodes(
@contextlib.contextmanager
def maintained_selection():
def maintained_selection(exclude_nodes=None):
"""Maintain selection during context
Maintain selection during context and unselect
all nodes after context is done.
Arguments:
exclude_nodes (list[nuke.Node]): list of nodes to be unselected
before context is done
Example:
>>> with maintained_selection():
... node["selected"].setValue(True)
>>> print(node["selected"].value())
False
"""
if exclude_nodes:
for node in exclude_nodes:
node["selected"].setValue(False)
previous_selection = nuke.selectedNodes()
try:
yield
finally:
@ -2823,6 +2830,51 @@ def maintained_selection():
select_nodes(previous_selection)
@contextlib.contextmanager
def swap_node_with_dependency(old_node, new_node):
""" Swap node with dependency
Swap node with dependency and reconnect all inputs and outputs.
It removes old node.
Arguments:
old_node (nuke.Node): node to be replaced
new_node (nuke.Node): node to replace with
Example:
>>> old_node_name = old_node["name"].value()
>>> print(old_node_name)
old_node_name_01
>>> with swap_node_with_dependency(old_node, new_node) as node_name:
... new_node["name"].setValue(node_name)
>>> print(new_node["name"].value())
old_node_name_01
"""
# preserve position
xpos, ypos = old_node.xpos(), old_node.ypos()
# preserve selection after all is done
outputs = get_node_outputs(old_node)
inputs = old_node.dependencies()
node_name = old_node["name"].value()
try:
nuke.delete(old_node)
yield node_name
finally:
# Reconnect inputs
for i, node in enumerate(inputs):
new_node.setInput(i, node)
# Reconnect outputs
if outputs:
for n, pipes in outputs.items():
for i in pipes:
n.setInput(i, new_node)
# return to original position
new_node.setXYpos(xpos, ypos)
def reset_selection():
"""Deselect all selected nodes"""
for node in nuke.selectedNodes():
@ -2920,13 +2972,13 @@ def process_workfile_builder():
"workfile_builder", {})
# get settings
createfv_on = workfile_builder.get("create_first_version") or None
create_fv_on = workfile_builder.get("create_first_version") or None
builder_on = workfile_builder.get("builder_on_start") or None
last_workfile_path = os.environ.get("AVALON_LAST_WORKFILE")
# generate first version in file not existing and feature is enabled
if createfv_on and not os.path.exists(last_workfile_path):
if create_fv_on and not os.path.exists(last_workfile_path):
# get custom template path if any
custom_template_path = get_custom_workfile_template_from_session(
project_settings=project_settings

View file

@ -12,7 +12,8 @@ from openpype.pipeline import (
from openpype.hosts.nuke.api.lib import (
maintained_selection,
get_avalon_knob_data,
set_avalon_knob_data
set_avalon_knob_data,
swap_node_with_dependency,
)
from openpype.hosts.nuke.api import (
containerise,
@ -26,7 +27,7 @@ class LoadGizmo(load.LoaderPlugin):
families = ["gizmo"]
representations = ["*"]
extensions = {"gizmo"}
extensions = {"nk"}
label = "Load Gizmo"
order = 0
@ -45,7 +46,7 @@ class LoadGizmo(load.LoaderPlugin):
data (dict): compulsory attribute > not used
Returns:
nuke node: containerised nuke node object
nuke node: containerized nuke node object
"""
# get main variables
@ -83,12 +84,12 @@ class LoadGizmo(load.LoaderPlugin):
# add group from nk
nuke.nodePaste(file)
GN = nuke.selectedNode()
group_node = nuke.selectedNode()
GN["name"].setValue(object_name)
group_node["name"].setValue(object_name)
return containerise(
node=GN,
node=group_node,
name=name,
namespace=namespace,
context=context,
@ -110,7 +111,7 @@ class LoadGizmo(load.LoaderPlugin):
version_doc = get_version_by_id(project_name, representation["parent"])
# get corresponding node
GN = nuke.toNode(container['objectName'])
group_node = nuke.toNode(container['objectName'])
file = get_representation_path(representation).replace("\\", "/")
name = container['name']
@ -135,22 +136,24 @@ class LoadGizmo(load.LoaderPlugin):
for k in add_keys:
data_imprint.update({k: version_data[k]})
# capture pipeline metadata
avalon_data = get_avalon_knob_data(group_node)
# adding nodes to node graph
# just in case we are in group lets jump out of it
nuke.endGroup()
with maintained_selection():
xpos = GN.xpos()
ypos = GN.ypos()
avalon_data = get_avalon_knob_data(GN)
nuke.delete(GN)
# add group from nk
with maintained_selection([group_node]):
# insert nuke script to the script
nuke.nodePaste(file)
GN = nuke.selectedNode()
set_avalon_knob_data(GN, avalon_data)
GN.setXYpos(xpos, ypos)
GN["name"].setValue(object_name)
# convert imported to selected node
new_group_node = nuke.selectedNode()
# swap nodes with maintained connections
with swap_node_with_dependency(
group_node, new_group_node) as node_name:
new_group_node["name"].setValue(node_name)
# set updated pipeline metadata
set_avalon_knob_data(new_group_node, avalon_data)
last_version_doc = get_last_version_by_subset_id(
project_name, version_doc["parent"], fields=["_id"]
@ -161,11 +164,12 @@ class LoadGizmo(load.LoaderPlugin):
color_value = self.node_color
else:
color_value = "0xd88467ff"
GN["tile_color"].setValue(int(color_value, 16))
new_group_node["tile_color"].setValue(int(color_value, 16))
self.log.info("updated to version: {}".format(version_doc.get("name")))
return update_container(GN, data_imprint)
return update_container(new_group_node, data_imprint)
def switch(self, container, representation):
self.update(container, representation)

View file

@ -14,7 +14,8 @@ from openpype.hosts.nuke.api.lib import (
maintained_selection,
create_backdrop,
get_avalon_knob_data,
set_avalon_knob_data
set_avalon_knob_data,
swap_node_with_dependency,
)
from openpype.hosts.nuke.api import (
containerise,
@ -28,7 +29,7 @@ class LoadGizmoInputProcess(load.LoaderPlugin):
families = ["gizmo"]
representations = ["*"]
extensions = {"gizmo"}
extensions = {"nk"}
label = "Load Gizmo - Input Process"
order = 0
@ -47,7 +48,7 @@ class LoadGizmoInputProcess(load.LoaderPlugin):
data (dict): compulsory attribute > not used
Returns:
nuke node: containerised nuke node object
nuke node: containerized nuke node object
"""
# get main variables
@ -85,17 +86,17 @@ class LoadGizmoInputProcess(load.LoaderPlugin):
# add group from nk
nuke.nodePaste(file)
GN = nuke.selectedNode()
group_node = nuke.selectedNode()
GN["name"].setValue(object_name)
group_node["name"].setValue(object_name)
# try to place it under Viewer1
if not self.connect_active_viewer(GN):
nuke.delete(GN)
if not self.connect_active_viewer(group_node):
nuke.delete(group_node)
return
return containerise(
node=GN,
node=group_node,
name=name,
namespace=namespace,
context=context,
@ -117,7 +118,7 @@ class LoadGizmoInputProcess(load.LoaderPlugin):
version_doc = get_version_by_id(project_name, representation["parent"])
# get corresponding node
GN = nuke.toNode(container['objectName'])
group_node = nuke.toNode(container['objectName'])
file = get_representation_path(representation).replace("\\", "/")
name = container['name']
@ -142,22 +143,24 @@ class LoadGizmoInputProcess(load.LoaderPlugin):
for k in add_keys:
data_imprint.update({k: version_data[k]})
# capture pipeline metadata
avalon_data = get_avalon_knob_data(group_node)
# adding nodes to node graph
# just in case we are in group lets jump out of it
nuke.endGroup()
with maintained_selection():
xpos = GN.xpos()
ypos = GN.ypos()
avalon_data = get_avalon_knob_data(GN)
nuke.delete(GN)
# add group from nk
with maintained_selection([group_node]):
# insert nuke script to the script
nuke.nodePaste(file)
GN = nuke.selectedNode()
set_avalon_knob_data(GN, avalon_data)
GN.setXYpos(xpos, ypos)
GN["name"].setValue(object_name)
# convert imported to selected node
new_group_node = nuke.selectedNode()
# swap nodes with maintained connections
with swap_node_with_dependency(
group_node, new_group_node) as node_name:
new_group_node["name"].setValue(node_name)
# set updated pipeline metadata
set_avalon_knob_data(new_group_node, avalon_data)
last_version_doc = get_last_version_by_subset_id(
project_name, version_doc["parent"], fields=["_id"]
@ -168,11 +171,11 @@ class LoadGizmoInputProcess(load.LoaderPlugin):
color_value = self.node_color
else:
color_value = "0xd88467ff"
GN["tile_color"].setValue(int(color_value, 16))
new_group_node["tile_color"].setValue(int(color_value, 16))
self.log.info("updated to version: {}".format(version_doc.get("name")))
return update_container(GN, data_imprint)
return update_container(new_group_node, data_imprint)
def connect_active_viewer(self, group_node):
"""