Merge branch 'feature/PYPE-488-nk-loading-nks-lut-soft-effects' into feature/PYPE-331-nks-lut-workflow_altered

This commit is contained in:
Jakub Jezek 2019-08-30 15:49:39 +02:00
commit 731b34acdc
9 changed files with 138 additions and 107 deletions

View file

@ -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:

View file

@ -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):

View file

@ -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

View file

@ -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("\\", "/")

View file

@ -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)

View file

@ -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)

View file

@ -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))

View file

@ -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,

View 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