mirror of
https://github.com/ynput/ayon-core.git
synced 2026-01-01 08:24:53 +01:00
Merge branch 'develop' into feature/OP-4364_Flame-load-clip-with-colorspace-remapping
This commit is contained in:
commit
414fecd9e5
6 changed files with 81 additions and 35 deletions
|
|
@ -225,7 +225,8 @@ class FlameMenuUniversal(_FlameMenuApp):
|
||||||
|
|
||||||
menu['actions'].append({
|
menu['actions'].append({
|
||||||
"name": "Load...",
|
"name": "Load...",
|
||||||
"execute": lambda x: self.tools_helper.show_loader()
|
"execute": lambda x: callback_selection(
|
||||||
|
x, self.tools_helper.show_loader)
|
||||||
})
|
})
|
||||||
menu['actions'].append({
|
menu['actions'].append({
|
||||||
"name": "Manage...",
|
"name": "Manage...",
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
from copy import deepcopy
|
||||||
import os
|
import os
|
||||||
import flame
|
import flame
|
||||||
from pprint import pformat
|
from pprint import pformat
|
||||||
|
|
@ -22,7 +23,7 @@ class LoadClipBatch(opfapi.ClipLoader):
|
||||||
|
|
||||||
# settings
|
# settings
|
||||||
reel_name = "OP_LoadedReel"
|
reel_name = "OP_LoadedReel"
|
||||||
clip_name_template = "{asset}_{subset}<_{output}>"
|
clip_name_template = "{batch}_{asset}_{subset}<_{output}>"
|
||||||
|
|
||||||
def load(self, context, name, namespace, options):
|
def load(self, context, name, namespace, options):
|
||||||
|
|
||||||
|
|
@ -40,8 +41,11 @@ class LoadClipBatch(opfapi.ClipLoader):
|
||||||
if not context["representation"]["context"].get("output"):
|
if not context["representation"]["context"].get("output"):
|
||||||
self.clip_name_template.replace("output", "representation")
|
self.clip_name_template.replace("output", "representation")
|
||||||
|
|
||||||
|
formating_data = deepcopy(context["representation"]["context"])
|
||||||
|
formating_data["batch"] = self.batch.name.get_value()
|
||||||
|
|
||||||
clip_name = StringTemplate(self.clip_name_template).format(
|
clip_name = StringTemplate(self.clip_name_template).format(
|
||||||
context["representation"]["context"])
|
formating_data)
|
||||||
|
|
||||||
# convert colorspace with ocio to flame mapping
|
# convert colorspace with ocio to flame mapping
|
||||||
# in imageio flame section
|
# in imageio flame section
|
||||||
|
|
@ -56,6 +60,7 @@ class LoadClipBatch(opfapi.ClipLoader):
|
||||||
openclip_path = os.path.join(
|
openclip_path = os.path.join(
|
||||||
openclip_dir, clip_name + ".clip"
|
openclip_dir, clip_name + ".clip"
|
||||||
)
|
)
|
||||||
|
|
||||||
if not os.path.exists(openclip_dir):
|
if not os.path.exists(openclip_dir):
|
||||||
os.makedirs(openclip_dir)
|
os.makedirs(openclip_dir)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
import os
|
|
||||||
import nuke
|
import nuke
|
||||||
import qargparse
|
import qargparse
|
||||||
|
from pprint import pformat
|
||||||
|
from copy import deepcopy
|
||||||
|
from openpype.lib import Logger
|
||||||
from openpype.client import (
|
from openpype.client import (
|
||||||
get_version_by_id,
|
get_version_by_id,
|
||||||
get_last_version_by_subset_id,
|
get_last_version_by_subset_id,
|
||||||
|
|
@ -28,6 +29,7 @@ class LoadClip(plugin.NukeLoader):
|
||||||
|
|
||||||
Either it is image sequence or video file.
|
Either it is image sequence or video file.
|
||||||
"""
|
"""
|
||||||
|
log = Logger.get_logger(__name__)
|
||||||
|
|
||||||
families = [
|
families = [
|
||||||
"source",
|
"source",
|
||||||
|
|
@ -85,24 +87,19 @@ class LoadClip(plugin.NukeLoader):
|
||||||
+ plugin.get_review_presets_config()
|
+ plugin.get_review_presets_config()
|
||||||
)
|
)
|
||||||
|
|
||||||
def _fix_path_for_knob(self, filepath, repre_cont):
|
|
||||||
basename = os.path.basename(filepath)
|
|
||||||
dirname = os.path.dirname(filepath)
|
|
||||||
frame = repre_cont.get("frame")
|
|
||||||
assert frame, "Representation is not sequence"
|
|
||||||
|
|
||||||
padding = len(str(frame))
|
|
||||||
basename = basename.replace(frame, "#" * padding)
|
|
||||||
return os.path.join(dirname, basename).replace("\\", "/")
|
|
||||||
|
|
||||||
def load(self, context, name, namespace, options):
|
def load(self, context, name, namespace, options):
|
||||||
repre = context["representation"]
|
representation = context["representation"]
|
||||||
# reste container id so it is always unique for each instance
|
# reste container id so it is always unique for each instance
|
||||||
self.reset_container_id()
|
self.reset_container_id()
|
||||||
|
|
||||||
is_sequence = len(repre["files"]) > 1
|
is_sequence = len(representation["files"]) > 1
|
||||||
|
|
||||||
filepath = self.fname.replace("\\", "/")
|
if is_sequence:
|
||||||
|
representation = self._representation_with_hash_in_frame(
|
||||||
|
representation
|
||||||
|
)
|
||||||
|
filepath = get_representation_path(representation).replace("\\", "/")
|
||||||
|
self.log.debug("_ filepath: {}".format(filepath))
|
||||||
|
|
||||||
start_at_workfile = options.get(
|
start_at_workfile = options.get(
|
||||||
"start_at_workfile", self.options_defaults["start_at_workfile"])
|
"start_at_workfile", self.options_defaults["start_at_workfile"])
|
||||||
|
|
@ -112,11 +109,10 @@ class LoadClip(plugin.NukeLoader):
|
||||||
|
|
||||||
version = context['version']
|
version = context['version']
|
||||||
version_data = version.get("data", {})
|
version_data = version.get("data", {})
|
||||||
repre_id = repre["_id"]
|
repre_id = representation["_id"]
|
||||||
|
|
||||||
repre_cont = repre["context"]
|
self.log.debug("_ version_data: {}\n".format(
|
||||||
|
pformat(version_data)))
|
||||||
self.log.info("version_data: {}\n".format(version_data))
|
|
||||||
self.log.debug(
|
self.log.debug(
|
||||||
"Representation id `{}` ".format(repre_id))
|
"Representation id `{}` ".format(repre_id))
|
||||||
|
|
||||||
|
|
@ -132,8 +128,6 @@ class LoadClip(plugin.NukeLoader):
|
||||||
duration = last - first
|
duration = last - first
|
||||||
first = 1
|
first = 1
|
||||||
last = first + duration
|
last = first + duration
|
||||||
elif "#" not in filepath:
|
|
||||||
filepath = self._fix_path_for_knob(filepath, repre_cont)
|
|
||||||
|
|
||||||
# Fallback to asset name when namespace is None
|
# Fallback to asset name when namespace is None
|
||||||
if namespace is None:
|
if namespace is None:
|
||||||
|
|
@ -144,7 +138,7 @@ class LoadClip(plugin.NukeLoader):
|
||||||
"Representation id `{}` is failing to load".format(repre_id))
|
"Representation id `{}` is failing to load".format(repre_id))
|
||||||
return
|
return
|
||||||
|
|
||||||
read_name = self._get_node_name(repre)
|
read_name = self._get_node_name(representation)
|
||||||
|
|
||||||
# Create the Loader with the filename path set
|
# Create the Loader with the filename path set
|
||||||
read_node = nuke.createNode(
|
read_node = nuke.createNode(
|
||||||
|
|
@ -157,7 +151,7 @@ class LoadClip(plugin.NukeLoader):
|
||||||
read_node["file"].setValue(filepath)
|
read_node["file"].setValue(filepath)
|
||||||
|
|
||||||
used_colorspace = self._set_colorspace(
|
used_colorspace = self._set_colorspace(
|
||||||
read_node, version_data, repre["data"])
|
read_node, version_data, representation["data"])
|
||||||
|
|
||||||
self._set_range_to_node(read_node, first, last, start_at_workfile)
|
self._set_range_to_node(read_node, first, last, start_at_workfile)
|
||||||
|
|
||||||
|
|
@ -179,7 +173,7 @@ class LoadClip(plugin.NukeLoader):
|
||||||
data_imprint[k] = version
|
data_imprint[k] = version
|
||||||
|
|
||||||
elif k == 'colorspace':
|
elif k == 'colorspace':
|
||||||
colorspace = repre["data"].get(k)
|
colorspace = representation["data"].get(k)
|
||||||
colorspace = colorspace or version_data.get(k)
|
colorspace = colorspace or version_data.get(k)
|
||||||
data_imprint["db_colorspace"] = colorspace
|
data_imprint["db_colorspace"] = colorspace
|
||||||
if used_colorspace:
|
if used_colorspace:
|
||||||
|
|
@ -213,6 +207,20 @@ class LoadClip(plugin.NukeLoader):
|
||||||
def switch(self, container, representation):
|
def switch(self, container, representation):
|
||||||
self.update(container, representation)
|
self.update(container, representation)
|
||||||
|
|
||||||
|
def _representation_with_hash_in_frame(self, representation):
|
||||||
|
"""Convert frame key value to padded hash
|
||||||
|
|
||||||
|
Args:
|
||||||
|
representation (dict): representation data
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
dict: altered representation data
|
||||||
|
"""
|
||||||
|
representation = deepcopy(representation)
|
||||||
|
frame = representation["context"]["frame"]
|
||||||
|
representation["context"]["frame"] = "#" * len(str(frame))
|
||||||
|
return representation
|
||||||
|
|
||||||
def update(self, container, representation):
|
def update(self, container, representation):
|
||||||
"""Update the Loader's path
|
"""Update the Loader's path
|
||||||
|
|
||||||
|
|
@ -225,7 +233,13 @@ class LoadClip(plugin.NukeLoader):
|
||||||
is_sequence = len(representation["files"]) > 1
|
is_sequence = len(representation["files"]) > 1
|
||||||
|
|
||||||
read_node = nuke.toNode(container['objectName'])
|
read_node = nuke.toNode(container['objectName'])
|
||||||
|
|
||||||
|
if is_sequence:
|
||||||
|
representation = self._representation_with_hash_in_frame(
|
||||||
|
representation
|
||||||
|
)
|
||||||
filepath = get_representation_path(representation).replace("\\", "/")
|
filepath = get_representation_path(representation).replace("\\", "/")
|
||||||
|
self.log.debug("_ filepath: {}".format(filepath))
|
||||||
|
|
||||||
start_at_workfile = "start at" in read_node['frame_mode'].value()
|
start_at_workfile = "start at" in read_node['frame_mode'].value()
|
||||||
|
|
||||||
|
|
@ -240,8 +254,6 @@ class LoadClip(plugin.NukeLoader):
|
||||||
version_data = version_doc.get("data", {})
|
version_data = version_doc.get("data", {})
|
||||||
repre_id = representation["_id"]
|
repre_id = representation["_id"]
|
||||||
|
|
||||||
repre_cont = representation["context"]
|
|
||||||
|
|
||||||
# colorspace profile
|
# colorspace profile
|
||||||
colorspace = representation["data"].get("colorspace")
|
colorspace = representation["data"].get("colorspace")
|
||||||
colorspace = colorspace or version_data.get("colorspace")
|
colorspace = colorspace or version_data.get("colorspace")
|
||||||
|
|
@ -258,8 +270,6 @@ class LoadClip(plugin.NukeLoader):
|
||||||
duration = last - first
|
duration = last - first
|
||||||
first = 1
|
first = 1
|
||||||
last = first + duration
|
last = first + duration
|
||||||
elif "#" not in filepath:
|
|
||||||
filepath = self._fix_path_for_knob(filepath, repre_cont)
|
|
||||||
|
|
||||||
if not filepath:
|
if not filepath:
|
||||||
self.log.warning(
|
self.log.warning(
|
||||||
|
|
@ -348,8 +358,10 @@ class LoadClip(plugin.NukeLoader):
|
||||||
time_warp_nodes = version_data.get('timewarps', [])
|
time_warp_nodes = version_data.get('timewarps', [])
|
||||||
last_node = None
|
last_node = None
|
||||||
source_id = self.get_container_id(parent_node)
|
source_id = self.get_container_id(parent_node)
|
||||||
self.log.info("__ source_id: {}".format(source_id))
|
self.log.debug("__ source_id: {}".format(source_id))
|
||||||
self.log.info("__ members: {}".format(self.get_members(parent_node)))
|
self.log.debug("__ members: {}".format(
|
||||||
|
self.get_members(parent_node)))
|
||||||
|
|
||||||
dependent_nodes = self.clear_members(parent_node)
|
dependent_nodes = self.clear_members(parent_node)
|
||||||
|
|
||||||
with maintained_selection():
|
with maintained_selection():
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
|
||||||
|
import pyblish.api
|
||||||
|
|
||||||
|
|
||||||
|
class CollectKitsuUsername(pyblish.api.ContextPlugin):
|
||||||
|
"""Collect Kitsu username from the kitsu login"""
|
||||||
|
|
||||||
|
order = pyblish.api.CollectorOrder + 0.499
|
||||||
|
label = "Kitsu username"
|
||||||
|
|
||||||
|
def process(self, context):
|
||||||
|
kitsu_login = os.environ.get('KITSU_LOGIN')
|
||||||
|
|
||||||
|
if not kitsu_login:
|
||||||
|
return
|
||||||
|
|
||||||
|
kitsu_username = kitsu_login.split("@")[0].replace('.', ' ')
|
||||||
|
new_username = re.sub('[^a-zA-Z]', ' ', kitsu_username).title()
|
||||||
|
|
||||||
|
for instance in context:
|
||||||
|
# Don't override customData if it already exists
|
||||||
|
if 'customData' not in instance.data:
|
||||||
|
instance.data['customData'] = {}
|
||||||
|
|
||||||
|
instance.data['customData']["kitsuUsername"] = new_username
|
||||||
|
|
@ -142,7 +142,7 @@
|
||||||
"exr16fpdwaa"
|
"exr16fpdwaa"
|
||||||
],
|
],
|
||||||
"reel_name": "OP_LoadedReel",
|
"reel_name": "OP_LoadedReel",
|
||||||
"clip_name_template": "{asset}_{subset}<_{output}>"
|
"clip_name_template": "{batch}_{asset}_{subset}<_{output}>"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
"""Package declaring Pype version."""
|
"""Package declaring Pype version."""
|
||||||
__version__ = "3.14.7-nightly.2"
|
__version__ = "3.14.7-nightly.3"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue