mirror of
https://github.com/ynput/ayon-core.git
synced 2025-12-24 21:04:40 +01:00
Merge branch 'feature/PYPE-488-nk-loading-nks-lut-soft-effects' into feature/PYPE-331-nks-lut-workflow_altered
This commit is contained in:
commit
731b34acdc
9 changed files with 138 additions and 107 deletions
|
|
@ -421,7 +421,7 @@ def get_version_from_path(file):
|
|||
v: version number in string ('001')
|
||||
|
||||
"""
|
||||
pattern = re.compile(r"[\._]v([0-9]*)")
|
||||
pattern = re.compile(r"[\._]v([0-9]+)")
|
||||
try:
|
||||
return pattern.findall(file)[0]
|
||||
except IndexError:
|
||||
|
|
|
|||
147
pype/nuke/lib.py
147
pype/nuke/lib.py
|
|
@ -379,6 +379,14 @@ def add_rendering_knobs(node):
|
|||
return node
|
||||
|
||||
|
||||
def add_deadline_tab(node):
|
||||
node.addKnob(nuke.Tab_Knob("Deadline"))
|
||||
|
||||
knob = nuke.Int_Knob("deadlineChunkSize", "Chunk Size")
|
||||
knob.setValue(1)
|
||||
node.addKnob(knob)
|
||||
|
||||
|
||||
def create_backdrop(label="", color=None, layer=0,
|
||||
nodes=None):
|
||||
"""
|
||||
|
|
@ -665,87 +673,80 @@ class WorkfileSettings(object):
|
|||
def reset_resolution(self):
|
||||
"""Set resolution to project resolution."""
|
||||
log.info("Reseting resolution")
|
||||
project = io.find_one({"type": "project"})
|
||||
asset = api.Session["AVALON_ASSET"]
|
||||
asset = io.find_one({"name": asset, "type": "asset"})
|
||||
asset_data = asset.get('data', {})
|
||||
|
||||
width = self._asset_entity.get('data', {}).get("resolutionWidth")
|
||||
height = self._asset_entity.get('data', {}).get("resolutionHeight")
|
||||
pixel_aspect = self._asset_entity.get('data', {}).get("pixelAspect")
|
||||
data = {
|
||||
"width": int(asset_data.get(
|
||||
'resolutionWidth',
|
||||
asset_data.get('resolution_width'))),
|
||||
"height": int(asset_data.get(
|
||||
'resolutionHeight',
|
||||
asset_data.get('resolution_height'))),
|
||||
"pixel_aspect": asset_data.get(
|
||||
'pixelAspect',
|
||||
asset_data.get('pixel_aspect', 1)),
|
||||
"name": project["name"]
|
||||
}
|
||||
|
||||
if any(not x for x in [width, height, pixel_aspect]):
|
||||
log.error("Missing set shot attributes in DB. \nContact"
|
||||
"your supervisor!. \n\nWidth: `{0}` \nHeight: `{1}`"
|
||||
"\nPixel Asspect: `{2}`".format(
|
||||
width, height, pixel_aspect))
|
||||
return
|
||||
if any(x for x in data.values() if x is None):
|
||||
log.error(
|
||||
"Missing set shot attributes in DB."
|
||||
"\nContact your supervisor!."
|
||||
"\n\nWidth: `{width}`"
|
||||
"\nHeight: `{height}`"
|
||||
"\nPixel Asspect: `{pixel_aspect}`".format(**data)
|
||||
)
|
||||
|
||||
bbox = self._asset_entity.get('data', {}).get('crop')
|
||||
|
||||
if bbox:
|
||||
try:
|
||||
x, y, r, t = bbox.split(".")
|
||||
data.update(
|
||||
{
|
||||
"x": int(x),
|
||||
"y": int(y),
|
||||
"r": int(r),
|
||||
"t": int(t),
|
||||
}
|
||||
)
|
||||
except Exception as e:
|
||||
bbox = None
|
||||
log.error("{}: {} \nFormat:Crop need to be set with dots,"
|
||||
" example: 0.0.1920.1080, /nSetting to"
|
||||
" default".format(__name__, e))
|
||||
log.error(
|
||||
"{}: {} \nFormat:Crop need to be set with dots, example: "
|
||||
"0.0.1920.1080, /nSetting to default".format(__name__, e)
|
||||
)
|
||||
|
||||
used_formats = list()
|
||||
for f in nuke.formats():
|
||||
if self._project["name"] in str(f.name()):
|
||||
used_formats.append(f)
|
||||
else:
|
||||
format_name = self._project["name"] + "_1"
|
||||
existing_format = None
|
||||
for format in nuke.formats():
|
||||
if data["name"] == format.name():
|
||||
existing_format = format
|
||||
break
|
||||
|
||||
if existing_format:
|
||||
# Enforce existing format to be correct.
|
||||
existing_format.setWidth(data["width"])
|
||||
existing_format.setHeight(data["height"])
|
||||
existing_format.setPixelAspect(data["pixel_aspect"])
|
||||
|
||||
crnt_fmt_str = ""
|
||||
if used_formats:
|
||||
check_format = used_formats[-1]
|
||||
format_name = "{}_{}".format(
|
||||
self._project["name"],
|
||||
int(used_formats[-1].name()[-1]) + 1
|
||||
)
|
||||
log.info(
|
||||
"Format exists: {}. "
|
||||
"Will create new: {}...".format(
|
||||
used_formats[-1].name(),
|
||||
format_name)
|
||||
)
|
||||
crnt_fmt_kargs = {
|
||||
"width": (check_format.width()),
|
||||
"height": (check_format.height()),
|
||||
"pixelAspect": float(check_format.pixelAspect())
|
||||
}
|
||||
if bbox:
|
||||
crnt_fmt_kargs.update({
|
||||
"x": int(check_format.x()),
|
||||
"y": int(check_format.y()),
|
||||
"r": int(check_format.r()),
|
||||
"t": int(check_format.t()),
|
||||
})
|
||||
crnt_fmt_str = self.make_format_string(**crnt_fmt_kargs)
|
||||
existing_format.setX(data["x"])
|
||||
existing_format.setY(data["y"])
|
||||
existing_format.setR(data["r"])
|
||||
existing_format.setT(data["t"])
|
||||
else:
|
||||
format_string = self.make_format_string(**data)
|
||||
log.info("Creating new format: {}".format(format_string))
|
||||
nuke.addFormat(format_string)
|
||||
|
||||
new_fmt_kargs = {
|
||||
"width": int(width),
|
||||
"height": int(height),
|
||||
"pixelAspect": float(pixel_aspect),
|
||||
"project_name": format_name
|
||||
}
|
||||
if bbox:
|
||||
new_fmt_kargs.update({
|
||||
"x": int(x),
|
||||
"y": int(y),
|
||||
"r": int(r),
|
||||
"t": int(t),
|
||||
})
|
||||
nuke.root()["format"].setValue(data["name"])
|
||||
log.info("Format is set.")
|
||||
|
||||
new_fmt_str = self.make_format_string(**new_fmt_kargs)
|
||||
|
||||
if new_fmt_str not in crnt_fmt_str:
|
||||
self.make_format(frm_str=new_fmt_str,
|
||||
project_name=new_fmt_kargs["project_name"])
|
||||
|
||||
log.info("Format is set")
|
||||
|
||||
def make_format_string(self, **args):
|
||||
if args.get("r"):
|
||||
def make_format_string(self, **kwargs):
|
||||
if kwargs.get("r"):
|
||||
return (
|
||||
"{width} "
|
||||
"{height} "
|
||||
|
|
@ -753,21 +754,17 @@ class WorkfileSettings(object):
|
|||
"{y} "
|
||||
"{r} "
|
||||
"{t} "
|
||||
"{pixelAspect:.2f}".format(**args)
|
||||
"{pixel_aspect:.2f} "
|
||||
"{name}".format(**kwargs)
|
||||
)
|
||||
else:
|
||||
return (
|
||||
"{width} "
|
||||
"{height} "
|
||||
"{pixelAspect:.2f}".format(**args)
|
||||
"{pixel_aspect:.2f} "
|
||||
"{name}".format(**kwargs)
|
||||
)
|
||||
|
||||
def make_format(self, **args):
|
||||
log.info("Format does't exist, will create: \n{}".format(args))
|
||||
nuke.addFormat("{frm_str} "
|
||||
"{project_name}".format(**args))
|
||||
self._root_node["format"].setValue("{project_name}".format(**args))
|
||||
|
||||
def set_context_settings(self):
|
||||
# replace reset resolution from avalon core to pype's
|
||||
self.reset_resolution()
|
||||
|
|
@ -1108,7 +1105,7 @@ class BuildWorkfile(WorkfileSettings):
|
|||
"""
|
||||
assert isinstance(nodes, list), "`nodes` should be a list of nodes"
|
||||
layer = self.pos_layer + layer
|
||||
|
||||
|
||||
create_backdrop(label=label, color=color, layer=layer, nodes=nodes)
|
||||
|
||||
def position_reset(self, xpos=0, ypos=0):
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
import os
|
||||
from pypeapp import Logger
|
||||
import hiero
|
||||
from avalon.tools import workfiles
|
||||
from avalon import api as avalon
|
||||
from pyblish import api as pyblish
|
||||
|
||||
|
|
|
|||
|
|
@ -1,19 +1,22 @@
|
|||
"""Host API required Work Files tool"""
|
||||
import os
|
||||
|
||||
import hiero
|
||||
|
||||
from avalon import api
|
||||
|
||||
|
||||
def file_extensions():
|
||||
return [".hrox"]
|
||||
|
||||
|
||||
def has_unsaved_changes():
|
||||
return hiero.core.projects()[-1]
|
||||
# There are no methods for querying unsaved changes to a project, so
|
||||
# enforcing to always save.
|
||||
return True
|
||||
|
||||
|
||||
def save(filepath):
|
||||
project = hiero.core.projects()[-1]
|
||||
|
||||
if project:
|
||||
project.saveAs(filepath)
|
||||
else:
|
||||
|
|
@ -22,40 +25,20 @@ def save(filepath):
|
|||
|
||||
|
||||
def open(filepath):
|
||||
try:
|
||||
hiero.core.openProject(filepath)
|
||||
return True
|
||||
except Exception as e:
|
||||
try:
|
||||
from PySide.QtGui import *
|
||||
from PySide.QtCore import *
|
||||
except:
|
||||
from PySide2.QtGui import *
|
||||
from PySide2.QtWidgets import *
|
||||
from PySide2.QtCore import *
|
||||
|
||||
prompt = "Cannot open the selected file: `{}`".format(e)
|
||||
hiero.core.log.error(prompt)
|
||||
dialog = QMessageBox.critical(
|
||||
hiero.ui.mainWindow(), "Error", unicode(prompt))
|
||||
hiero.core.openProject(filepath)
|
||||
return True
|
||||
|
||||
|
||||
def current_file():
|
||||
import os
|
||||
import hiero
|
||||
|
||||
current_file = hiero.core.projects()[-1].path()
|
||||
normalised = os.path.normpath(current_file)
|
||||
|
||||
# Unsaved current file
|
||||
if normalised is '':
|
||||
return "NOT SAVED"
|
||||
if normalised == "":
|
||||
return None
|
||||
|
||||
return normalised
|
||||
|
||||
|
||||
|
||||
def work_root():
|
||||
from avalon import api
|
||||
|
||||
return os.path.normpath(api.Session["AVALON_WORKDIR"]).replace("\\", "/")
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ def is_subdir(path, root_dir):
|
|||
root_dir = os.path.realpath(root_dir)
|
||||
|
||||
# If not on same drive
|
||||
if os.path.splitdrive(path)[0] != os.path.splitdrive(root_dir)[0]:
|
||||
if os.path.splitdrive(path)[0].lower() != os.path.splitdrive(root_dir)[0].lower(): # noqa: E501
|
||||
return False
|
||||
|
||||
# Get 'relative path' (can contain ../ which means going up)
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
from collections import OrderedDict
|
||||
import avalon.api
|
||||
import avalon.nuke
|
||||
from pype.nuke.lib import create_write_node
|
||||
from pype.nuke.lib import create_write_node, add_deadline_tab
|
||||
from pype import api as pype
|
||||
from pypeapp import config
|
||||
|
||||
|
|
@ -51,7 +51,7 @@ class CreateWriteRender(avalon.nuke.Creator):
|
|||
node = 'write'
|
||||
|
||||
instance = nuke.toNode(self.data["subset"])
|
||||
|
||||
node = None
|
||||
if not instance:
|
||||
write_data = {
|
||||
"class": node,
|
||||
|
|
@ -69,6 +69,9 @@ class CreateWriteRender(avalon.nuke.Creator):
|
|||
write_data.update({
|
||||
"fpath_template": "{work}/renders/nuke/{subset}/{subset}.{frame}.{ext}"})
|
||||
|
||||
# Deadline tab.
|
||||
add_deadline_tab(node)
|
||||
|
||||
return create_write_node(self.data["subset"], write_data)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -101,6 +101,11 @@ class CollectNukeWrites(pyblish.api.InstancePlugin):
|
|||
"fps": instance.context.data["fps"]
|
||||
}
|
||||
|
||||
group_node = [x for x in instance if x.Class() == "Group"][0]
|
||||
deadlineChunkSize = 1
|
||||
if "deadlineChunkSize" in group_node.knobs():
|
||||
deadlineChunkSize = group_node["deadlineChunkSize"].value()
|
||||
|
||||
instance.data.update({
|
||||
"versionData": version_data,
|
||||
"path": path,
|
||||
|
|
@ -112,6 +117,7 @@ class CollectNukeWrites(pyblish.api.InstancePlugin):
|
|||
"frameEnd": last_frame,
|
||||
"outputType": output_type,
|
||||
"colorspace": node["colorspace"].value(),
|
||||
"deadlineChunkSize": deadlineChunkSize
|
||||
})
|
||||
|
||||
self.log.debug("instance.data: {}".format(instance.data))
|
||||
|
|
|
|||
|
|
@ -84,6 +84,7 @@ class NukeSubmitDeadline(pyblish.api.InstancePlugin):
|
|||
start=int(instance.data["frameStart"]),
|
||||
end=int(instance.data["frameEnd"])
|
||||
),
|
||||
"ChunkSize": instance.data["deadlineChunkSize"],
|
||||
|
||||
"Comment": comment,
|
||||
|
||||
|
|
|
|||
42
pype/plugins/nuke/publish/validate_write_deadline_tab.py
Normal file
42
pype/plugins/nuke/publish/validate_write_deadline_tab.py
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
import pyblish.api
|
||||
import pype.nuke.lib
|
||||
|
||||
|
||||
class RepairNukeWriteDeadlineTab(pyblish.api.Action):
|
||||
|
||||
label = "Repair"
|
||||
icon = "wrench"
|
||||
on = "failed"
|
||||
|
||||
def process(self, context, plugin):
|
||||
|
||||
# Get the errored instances
|
||||
failed = []
|
||||
for result in context.data["results"]:
|
||||
if (result["error"] is not None and result["instance"] is not None
|
||||
and result["instance"] not in failed):
|
||||
failed.append(result["instance"])
|
||||
|
||||
# Apply pyblish.logic to get the instances for the plug-in
|
||||
instances = pyblish.api.instances_by_plugin(failed, plugin)
|
||||
|
||||
for instance in instances:
|
||||
group_node = [x for x in instance if x.Class() == "Group"][0]
|
||||
pype.nuke.lib.add_deadline_tab(group_node)
|
||||
|
||||
|
||||
class ValidateNukeWriteDeadlineTab(pyblish.api.InstancePlugin):
|
||||
"""Ensure Deadline tab is present and current."""
|
||||
|
||||
order = pyblish.api.ValidatorOrder
|
||||
label = "Deadline Tab"
|
||||
hosts = ["nuke"]
|
||||
optional = True
|
||||
families = ["write"]
|
||||
actions = [RepairNukeWriteDeadlineTab]
|
||||
|
||||
def process(self, instance):
|
||||
group_node = [x for x in instance if x.Class() == "Group"][0]
|
||||
|
||||
msg = "Deadline tab missing on \"{}\"".format(group_node.name())
|
||||
assert "Deadline" in group_node.knobs(), msg
|
||||
Loading…
Add table
Add a link
Reference in a new issue