mirror of
https://github.com/ynput/ayon-core.git
synced 2025-12-24 21:04:40 +01:00
233 lines
7.1 KiB
Python
233 lines
7.1 KiB
Python
import re
|
|
import nuke
|
|
|
|
from avalon.vendor import qargparse
|
|
from avalon import api, io
|
|
|
|
from pype.hosts.nuke import presets
|
|
|
|
|
|
class LoadImage(api.Loader):
|
|
"""Load still image into Nuke"""
|
|
|
|
families = [
|
|
"render2d", "source", "plate",
|
|
"render", "prerender", "review",
|
|
"image"
|
|
]
|
|
representations = ["exr", "dpx", "jpg", "jpeg", "png", "psd"]
|
|
|
|
label = "Load Image"
|
|
order = -10
|
|
icon = "image"
|
|
color = "white"
|
|
|
|
options = [
|
|
qargparse.Integer(
|
|
"frame_number",
|
|
label="Frame Number",
|
|
default=int(nuke.root()["first_frame"].getValue()),
|
|
min=1,
|
|
max=999999,
|
|
help="What frame is reading from?"
|
|
)
|
|
]
|
|
|
|
def load(self, context, name, namespace, options):
|
|
from avalon.nuke import (
|
|
containerise,
|
|
viewer_update_and_undo_stop
|
|
)
|
|
self.log.info("__ options: `{}`".format(options))
|
|
frame_number = options.get("frame_number", 1)
|
|
|
|
version = context['version']
|
|
version_data = version.get("data", {})
|
|
repr_id = context["representation"]["_id"]
|
|
|
|
self.log.info("version_data: {}\n".format(version_data))
|
|
self.log.debug(
|
|
"Representation id `{}` ".format(repr_id))
|
|
|
|
last = first = int(frame_number)
|
|
|
|
# Fallback to asset name when namespace is None
|
|
if namespace is None:
|
|
namespace = context['asset']['name']
|
|
|
|
file = self.fname
|
|
|
|
if not file:
|
|
repr_id = context["representation"]["_id"]
|
|
self.log.warning(
|
|
"Representation id `{}` is failing to load".format(repr_id))
|
|
return
|
|
|
|
file = file.replace("\\", "/")
|
|
|
|
repr_cont = context["representation"]["context"]
|
|
frame = repr_cont.get("frame")
|
|
if frame:
|
|
padding = len(frame)
|
|
file = file.replace(
|
|
frame,
|
|
format(frame_number, "0{}".format(padding)))
|
|
|
|
read_name = "Read_{0}_{1}_{2}".format(
|
|
repr_cont["asset"],
|
|
repr_cont["subset"],
|
|
repr_cont["representation"])
|
|
|
|
# Create the Loader with the filename path set
|
|
with viewer_update_and_undo_stop():
|
|
r = nuke.createNode(
|
|
"Read",
|
|
"name {}".format(read_name))
|
|
r["file"].setValue(file)
|
|
|
|
# Set colorspace defined in version data
|
|
colorspace = context["version"]["data"].get("colorspace")
|
|
if colorspace:
|
|
r["colorspace"].setValue(str(colorspace))
|
|
|
|
# load nuke presets for Read's colorspace
|
|
read_clrs_presets = presets.get_colorspace_preset().get(
|
|
"nuke", {}).get("read", {})
|
|
|
|
# check if any colorspace presets for read is mathing
|
|
preset_clrsp = next((read_clrs_presets[k]
|
|
for k in read_clrs_presets
|
|
if bool(re.search(k, file))),
|
|
None)
|
|
if preset_clrsp is not None:
|
|
r["colorspace"].setValue(str(preset_clrsp))
|
|
|
|
r["origfirst"].setValue(first)
|
|
r["first"].setValue(first)
|
|
r["origlast"].setValue(last)
|
|
r["last"].setValue(last)
|
|
|
|
# add additional metadata from the version to imprint Avalon knob
|
|
add_keys = ["source", "colorspace", "author", "fps", "version"]
|
|
|
|
data_imprint = {
|
|
"frameStart": first,
|
|
"frameEnd": last
|
|
}
|
|
for k in add_keys:
|
|
if k == 'version':
|
|
data_imprint.update({k: context["version"]['name']})
|
|
else:
|
|
data_imprint.update(
|
|
{k: context["version"]['data'].get(k, str(None))})
|
|
|
|
data_imprint.update({"objectName": read_name})
|
|
|
|
r["tile_color"].setValue(int("0x4ecd25ff", 16))
|
|
|
|
return containerise(r,
|
|
name=name,
|
|
namespace=namespace,
|
|
context=context,
|
|
loader=self.__class__.__name__,
|
|
data=data_imprint)
|
|
|
|
def switch(self, container, representation):
|
|
self.update(container, representation)
|
|
|
|
def update(self, container, representation):
|
|
"""Update the Loader's path
|
|
|
|
Nuke automatically tries to reset some variables when changing
|
|
the loader's path to a new file. These automatic changes are to its
|
|
inputs:
|
|
|
|
"""
|
|
|
|
from avalon.nuke import (
|
|
update_container
|
|
)
|
|
|
|
node = nuke.toNode(container["objectName"])
|
|
frame_number = node["first"].value()
|
|
|
|
assert node.Class() == "Read", "Must be Read"
|
|
|
|
repr_cont = representation["context"]
|
|
|
|
file = api.get_representation_path(representation)
|
|
|
|
if not file:
|
|
repr_id = representation["_id"]
|
|
self.log.warning(
|
|
"Representation id `{}` is failing to load".format(repr_id))
|
|
return
|
|
|
|
file = file.replace("\\", "/")
|
|
|
|
frame = repr_cont.get("frame")
|
|
if frame:
|
|
padding = len(frame)
|
|
file = file.replace(
|
|
frame,
|
|
format(frame_number, "0{}".format(padding)))
|
|
|
|
# Get start frame from version data
|
|
version = io.find_one({
|
|
"type": "version",
|
|
"_id": representation["parent"]
|
|
})
|
|
|
|
# get all versions in list
|
|
versions = io.find({
|
|
"type": "version",
|
|
"parent": version["parent"]
|
|
}).distinct('name')
|
|
|
|
max_version = max(versions)
|
|
|
|
version_data = version.get("data", {})
|
|
|
|
last = first = int(frame_number)
|
|
|
|
# Set the global in to the start frame of the sequence
|
|
node["origfirst"].setValue(first)
|
|
node["first"].setValue(first)
|
|
node["origlast"].setValue(last)
|
|
node["last"].setValue(last)
|
|
|
|
updated_dict = {}
|
|
updated_dict.update({
|
|
"representation": str(representation["_id"]),
|
|
"frameStart": str(first),
|
|
"frameEnd": str(last),
|
|
"version": str(version.get("name")),
|
|
"colorspace": version_data.get("colorspace"),
|
|
"source": version_data.get("source"),
|
|
"fps": str(version_data.get("fps")),
|
|
"author": version_data.get("author"),
|
|
"outputDir": version_data.get("outputDir"),
|
|
})
|
|
|
|
# change color of node
|
|
if version.get("name") not in [max_version]:
|
|
node["tile_color"].setValue(int("0xd84f20ff", 16))
|
|
else:
|
|
node["tile_color"].setValue(int("0x4ecd25ff", 16))
|
|
|
|
# Update the imprinted representation
|
|
update_container(
|
|
node,
|
|
updated_dict
|
|
)
|
|
self.log.info("udated to version: {}".format(version.get("name")))
|
|
|
|
def remove(self, container):
|
|
|
|
from avalon.nuke import viewer_update_and_undo_stop
|
|
|
|
node = nuke.toNode(container['objectName'])
|
|
assert node.Class() == "Read", "Must be Read"
|
|
|
|
with viewer_update_and_undo_stop():
|
|
nuke.delete(node)
|