Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 26 additions & 22 deletions client/ayon_nuke/api/pipeline.py
Original file line number Diff line number Diff line change
Expand Up @@ -226,11 +226,8 @@ def add_nuke_callbacks(project_settings: dict = None):

nuke_settings = project_settings["nuke"]

# Set all workfile settings.'
nuke.addOnCreate(on_root_create, nodeClass="Root")
# set checker for last versions on loaded containers
nuke.addOnScriptLoad(check_inventory_versions)
# fix ffmpeg settings on script

nuke.addOnScriptLoad(on_script_load)

# set checker for last versions on loaded containers
Expand All @@ -245,29 +242,33 @@ def add_nuke_callbacks(project_settings: dict = None):


def on_root_create() -> None:
"""Callback function for on script create."""
# set apply all workfile settings on script load and save
"""Callback function for on root node create."""
# adding favorites to file browser
workfile_settings = WorkfileSettings()
on_script_create_settings = (
workfile_settings.project_settings
["nuke"]
["workfile_callbacks"]
["on_script_create"]
)
workfile_settings.set_favorites()

if on_script_create_settings["set_resolution"]:
workfile_settings.reset_resolution()
# Root created callback is also triggered on scene load because that also
# creates a new root node. So we check if current file is None to run
# logic that we only want to apply on new scene creation.
if current_file() is None:
Comment thread
BigRoy marked this conversation as resolved.
on_script_create_settings = (
workfile_settings.project_settings
["nuke"]
["workfile_callbacks"]
["on_script_create"]
)

if on_script_create_settings["set_frame_range"]:
workfile_settings.reset_frame_range_handles()
if on_script_create_settings["set_resolution"]:
workfile_settings.reset_resolution()

if on_script_create_settings["set_colorspace"]:
workfile_settings.set_colorspace()
if on_script_create_settings["set_frame_range"]:
workfile_settings.reset_frame_range_handles()

# adding favorites to file browser
workfile_settings.set_favorites()
# template builder callbacks
start_workfile_template_builder()
if on_script_create_settings["set_colorspace"]:
workfile_settings.set_colorspace()

# template builder callbacks
start_workfile_template_builder()


def on_script_load() -> None:
Expand Down Expand Up @@ -298,6 +299,9 @@ def on_script_load() -> None:
if on_script_load_settings["set_colorspace"]:
workfile_settings.set_colorspace()

# set checker for last versions on loaded containers
check_inventory_versions()


def reload_config():
"""Attempt to reload pipeline at run-time.
Expand Down
77 changes: 59 additions & 18 deletions client/ayon_nuke/api/workio.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,22 @@
"""Host API required Work Files tool"""
import os
import contextlib
import nuke
import shutil
from .constants import ASSIST


@contextlib.contextmanager
def _no_create_callbacks():
"""Context manager to temporarily disable `nuke.onCreate` callbacks."""
callbacks = nuke.onCreates.copy()
try:
nuke.onCreates.clear()
yield
finally:
nuke.onCreates.update(callbacks)


def file_extensions():
return [".nk"]

Expand All @@ -21,40 +33,69 @@ def save_file(filepath):
nuke.Root().setModified(False)


def _get_autosave_filepath(filepath: str) -> str | None:
"""Query autosave file path for a given file path, by evaluating the
autosave name preferences with root name temporarily set to the given
file path.

This allows us to get the autosave path for a file that is not currently
open in Nuke.
"""
root = nuke.Root()
original_name = root.name()
root["name"].setValue(filepath)
try:
autosave = nuke.toNode("preferences")["AutoSaveName"].evaluate()
if os.path.isfile(autosave):
return autosave
return None
finally:
root["name"].setValue(original_name)


def open_file(filepath):

def read_script(nuke_script):
if not ASSIST:
nuke.scriptClear()
with _no_create_callbacks():
nuke.scriptClear()
nuke.scriptReadFile(nuke_script)
nuke.Root()["name"].setValue(nuke_script)
nuke.Root()["project_directory"].setValue(os.path.dirname(nuke_script))
nuke.Root().setModified(False)

root = nuke.Root()
root["name"].setValue(nuke_script)
root["project_directory"].setValue(os.path.dirname(nuke_script))
root.setModified(False)

# Above way of loading script does not trigger onCreate() nor
# onScriptLoad() callback, so we need to call it manually here
# after root name has been set so the callbacks behave similar
# to how they would if user would do File > Open or on Nuke
# launch with a comp script file.
nuke.onCreate()
nuke.onScriptLoad()
else:
nuke.scriptOpen(nuke_script)

filepath = filepath.replace("\\", "/")

# To remain in the same window, we have to clear the script and read
# in the contents of the workfile.
# Nuke Preferences can be read after the script is read.
read_script(filepath)

if nuke.GUI:
autosave = nuke.toNode("preferences")["AutoSaveName"].evaluate()
autosave_prmpt = "Autosave detected.\n" \
"Would you like to load the autosave file?" # noqa
if os.path.isfile(autosave) and nuke.ask(autosave_prmpt):
# Before opening the file, see if it has an autosave file and ask the user
# if they want to load it instead.
if nuke.GUI and (autosave := _get_autosave_filepath(filepath)):
if nuke.ask(
"Autosave detected.\n"
"Would you like to load the autosave file?"
):
try:
# Overwrite the filepath with autosave
shutil.copy(autosave, filepath)
# Now read the (auto-saved) script again
read_script(filepath)
except shutil.Error as err:
nuke.message(
"Detected autosave file could not be used.\n{}"
f"Detected autosave file could not be used.\n{err}"
)

.format(err))
# To remain in the same window, we have to clear the script and read
# in the contents of the workfile.
read_script(filepath)

return True

Expand Down
Loading