mirror of
https://github.com/ynput/ayon-core.git
synced 2026-01-01 16:34:53 +01:00
Merge branch 'develop' into feature/OP-2983_simple-texture-publishing
This commit is contained in:
commit
3282720b4e
25 changed files with 351 additions and 214 deletions
|
|
@ -5,14 +5,6 @@ from openpype.pipeline import HOST_WORKFILE_EXTENSIONS
|
|||
from .launch_logic import get_stub
|
||||
|
||||
|
||||
def _active_document():
|
||||
document_name = get_stub().get_active_document_name()
|
||||
if not document_name:
|
||||
return None
|
||||
|
||||
return document_name
|
||||
|
||||
|
||||
def file_extensions():
|
||||
return HOST_WORKFILE_EXTENSIONS["aftereffects"]
|
||||
|
||||
|
|
@ -39,7 +31,8 @@ def current_file():
|
|||
full_name = get_stub().get_active_document_full_name()
|
||||
if full_name and full_name != "null":
|
||||
return os.path.normpath(full_name).replace("\\", "/")
|
||||
except Exception:
|
||||
except ValueError:
|
||||
print("Nothing opened")
|
||||
pass
|
||||
|
||||
return None
|
||||
|
|
@ -47,3 +40,15 @@ def current_file():
|
|||
|
||||
def work_root(session):
|
||||
return os.path.normpath(session["AVALON_WORKDIR"]).replace("\\", "/")
|
||||
|
||||
|
||||
def _active_document():
|
||||
# TODO merge with current_file - even in extension
|
||||
document_name = None
|
||||
try:
|
||||
document_name = get_stub().get_active_document_name()
|
||||
except ValueError:
|
||||
print("Nothing opened")
|
||||
pass
|
||||
|
||||
return document_name
|
||||
|
|
@ -18,6 +18,7 @@ log = Logger.get_logger(__name__)
|
|||
|
||||
FRAME_PATTERN = re.compile(r"[\._](\d+)[\.]")
|
||||
|
||||
|
||||
class CTX:
|
||||
# singleton used for passing data between api modules
|
||||
app_framework = None
|
||||
|
|
@ -538,9 +539,17 @@ def get_segment_attributes(segment):
|
|||
|
||||
# head and tail with forward compatibility
|
||||
if segment.head:
|
||||
clip_data["segment_head"] = int(segment.head)
|
||||
# `infinite` can be also returned
|
||||
if isinstance(segment.head, str):
|
||||
clip_data["segment_head"] = 0
|
||||
else:
|
||||
clip_data["segment_head"] = int(segment.head)
|
||||
if segment.tail:
|
||||
clip_data["segment_tail"] = int(segment.tail)
|
||||
# `infinite` can be also returned
|
||||
if isinstance(segment.tail, str):
|
||||
clip_data["segment_tail"] = 0
|
||||
else:
|
||||
clip_data["segment_tail"] = int(segment.tail)
|
||||
|
||||
# add all available shot tokens
|
||||
shot_tokens = _get_shot_tokens_values(segment, [
|
||||
|
|
|
|||
|
|
@ -422,7 +422,13 @@ class WireTapCom(object):
|
|||
color_policy = color_policy or "Legacy"
|
||||
|
||||
# check if the colour policy in custom dir
|
||||
if not os.path.exists(color_policy):
|
||||
if "/" in color_policy:
|
||||
# if unlikelly full path was used make it redundant
|
||||
color_policy = color_policy.replace("/syncolor/policies/", "")
|
||||
# expecting input is `Shared/NameOfPolicy`
|
||||
color_policy = "/syncolor/policies/{}".format(
|
||||
color_policy)
|
||||
else:
|
||||
color_policy = "/syncolor/policies/Autodesk/{}".format(
|
||||
color_policy)
|
||||
|
||||
|
|
|
|||
|
|
@ -34,119 +34,125 @@ class CollectTimelineInstances(pyblish.api.ContextPlugin):
|
|||
def process(self, context):
|
||||
project = context.data["flameProject"]
|
||||
sequence = context.data["flameSequence"]
|
||||
selected_segments = context.data["flameSelectedSegments"]
|
||||
self.log.debug("__ selected_segments: {}".format(selected_segments))
|
||||
|
||||
self.otio_timeline = context.data["otioTimeline"]
|
||||
self.clips_in_reels = opfapi.get_clips_in_reels(project)
|
||||
self.fps = context.data["fps"]
|
||||
|
||||
# process all sellected
|
||||
with opfapi.maintained_segment_selection(sequence) as segments:
|
||||
for segment in segments:
|
||||
comment_attributes = self._get_comment_attributes(segment)
|
||||
self.log.debug("_ comment_attributes: {}".format(
|
||||
pformat(comment_attributes)))
|
||||
for segment in selected_segments:
|
||||
# get openpype tag data
|
||||
marker_data = opfapi.get_segment_data_marker(segment)
|
||||
self.log.debug("__ marker_data: {}".format(
|
||||
pformat(marker_data)))
|
||||
|
||||
clip_data = opfapi.get_segment_attributes(segment)
|
||||
clip_name = clip_data["segment_name"]
|
||||
self.log.debug("clip_name: {}".format(clip_name))
|
||||
if not marker_data:
|
||||
continue
|
||||
|
||||
# get openpype tag data
|
||||
marker_data = opfapi.get_segment_data_marker(segment)
|
||||
self.log.debug("__ marker_data: {}".format(
|
||||
pformat(marker_data)))
|
||||
if marker_data.get("id") != "pyblish.avalon.instance":
|
||||
continue
|
||||
|
||||
if not marker_data:
|
||||
continue
|
||||
self.log.debug("__ segment.name: {}".format(
|
||||
segment.name
|
||||
))
|
||||
|
||||
if marker_data.get("id") != "pyblish.avalon.instance":
|
||||
continue
|
||||
comment_attributes = self._get_comment_attributes(segment)
|
||||
|
||||
# get file path
|
||||
file_path = clip_data["fpath"]
|
||||
self.log.debug("_ comment_attributes: {}".format(
|
||||
pformat(comment_attributes)))
|
||||
|
||||
# get source clip
|
||||
source_clip = self._get_reel_clip(file_path)
|
||||
clip_data = opfapi.get_segment_attributes(segment)
|
||||
clip_name = clip_data["segment_name"]
|
||||
self.log.debug("clip_name: {}".format(clip_name))
|
||||
|
||||
first_frame = opfapi.get_frame_from_filename(file_path) or 0
|
||||
# get file path
|
||||
file_path = clip_data["fpath"]
|
||||
|
||||
head, tail = self._get_head_tail(clip_data, first_frame)
|
||||
# get source clip
|
||||
source_clip = self._get_reel_clip(file_path)
|
||||
|
||||
# solve handles length
|
||||
marker_data["handleStart"] = min(
|
||||
marker_data["handleStart"], head)
|
||||
marker_data["handleEnd"] = min(
|
||||
marker_data["handleEnd"], tail)
|
||||
first_frame = opfapi.get_frame_from_filename(file_path) or 0
|
||||
|
||||
with_audio = bool(marker_data.pop("audio"))
|
||||
head, tail = self._get_head_tail(clip_data, first_frame)
|
||||
|
||||
# add marker data to instance data
|
||||
inst_data = dict(marker_data.items())
|
||||
# solve handles length
|
||||
marker_data["handleStart"] = min(
|
||||
marker_data["handleStart"], head)
|
||||
marker_data["handleEnd"] = min(
|
||||
marker_data["handleEnd"], tail)
|
||||
|
||||
asset = marker_data["asset"]
|
||||
subset = marker_data["subset"]
|
||||
with_audio = bool(marker_data.pop("audio"))
|
||||
|
||||
# insert family into families
|
||||
family = marker_data["family"]
|
||||
families = [str(f) for f in marker_data["families"]]
|
||||
families.insert(0, str(family))
|
||||
# add marker data to instance data
|
||||
inst_data = dict(marker_data.items())
|
||||
|
||||
# form label
|
||||
label = asset
|
||||
if asset != clip_name:
|
||||
label += " ({})".format(clip_name)
|
||||
label += " {}".format(subset)
|
||||
label += " {}".format("[" + ", ".join(families) + "]")
|
||||
asset = marker_data["asset"]
|
||||
subset = marker_data["subset"]
|
||||
|
||||
inst_data.update({
|
||||
"name": "{}_{}".format(asset, subset),
|
||||
"label": label,
|
||||
"asset": asset,
|
||||
"item": segment,
|
||||
"families": families,
|
||||
"publish": marker_data["publish"],
|
||||
"fps": self.fps,
|
||||
"flameSourceClip": source_clip,
|
||||
"sourceFirstFrame": int(first_frame),
|
||||
"path": file_path
|
||||
})
|
||||
# insert family into families
|
||||
family = marker_data["family"]
|
||||
families = [str(f) for f in marker_data["families"]]
|
||||
families.insert(0, str(family))
|
||||
|
||||
# get otio clip data
|
||||
otio_data = self._get_otio_clip_instance_data(clip_data) or {}
|
||||
self.log.debug("__ otio_data: {}".format(pformat(otio_data)))
|
||||
# form label
|
||||
label = asset
|
||||
if asset != clip_name:
|
||||
label += " ({})".format(clip_name)
|
||||
label += " {} [{}]".format(subset, ", ".join(families))
|
||||
|
||||
# add to instance data
|
||||
inst_data.update(otio_data)
|
||||
self.log.debug("__ inst_data: {}".format(pformat(inst_data)))
|
||||
inst_data.update({
|
||||
"name": "{}_{}".format(asset, subset),
|
||||
"label": label,
|
||||
"asset": asset,
|
||||
"item": segment,
|
||||
"families": families,
|
||||
"publish": marker_data["publish"],
|
||||
"fps": self.fps,
|
||||
"flameSourceClip": source_clip,
|
||||
"sourceFirstFrame": int(first_frame),
|
||||
"path": file_path
|
||||
})
|
||||
|
||||
# add resolution
|
||||
self._get_resolution_to_data(inst_data, context)
|
||||
# get otio clip data
|
||||
otio_data = self._get_otio_clip_instance_data(clip_data) or {}
|
||||
self.log.debug("__ otio_data: {}".format(pformat(otio_data)))
|
||||
|
||||
# add comment attributes if any
|
||||
inst_data.update(comment_attributes)
|
||||
# add to instance data
|
||||
inst_data.update(otio_data)
|
||||
self.log.debug("__ inst_data: {}".format(pformat(inst_data)))
|
||||
|
||||
# create instance
|
||||
instance = context.create_instance(**inst_data)
|
||||
# add resolution
|
||||
self._get_resolution_to_data(inst_data, context)
|
||||
|
||||
# add colorspace data
|
||||
instance.data.update({
|
||||
"versionData": {
|
||||
"colorspace": clip_data["colour_space"],
|
||||
}
|
||||
})
|
||||
# add comment attributes if any
|
||||
inst_data.update(comment_attributes)
|
||||
|
||||
# create shot instance for shot attributes create/update
|
||||
self._create_shot_instance(context, clip_name, **inst_data)
|
||||
# create instance
|
||||
instance = context.create_instance(**inst_data)
|
||||
|
||||
self.log.info("Creating instance: {}".format(instance))
|
||||
self.log.info(
|
||||
"_ instance.data: {}".format(pformat(instance.data)))
|
||||
# add colorspace data
|
||||
instance.data.update({
|
||||
"versionData": {
|
||||
"colorspace": clip_data["colour_space"],
|
||||
}
|
||||
})
|
||||
|
||||
if not with_audio:
|
||||
continue
|
||||
# create shot instance for shot attributes create/update
|
||||
self._create_shot_instance(context, clip_name, **inst_data)
|
||||
|
||||
# add audioReview attribute to plate instance data
|
||||
# if reviewTrack is on
|
||||
if marker_data.get("reviewTrack") is not None:
|
||||
instance.data["reviewAudio"] = True
|
||||
self.log.info("Creating instance: {}".format(instance))
|
||||
self.log.info(
|
||||
"_ instance.data: {}".format(pformat(instance.data)))
|
||||
|
||||
if not with_audio:
|
||||
continue
|
||||
|
||||
# add audioReview attribute to plate instance data
|
||||
# if reviewTrack is on
|
||||
if marker_data.get("reviewTrack") is not None:
|
||||
instance.data["reviewAudio"] = True
|
||||
|
||||
def _get_comment_attributes(self, segment):
|
||||
comment = segment.comment.get_value()
|
||||
|
|
@ -188,7 +194,7 @@ class CollectTimelineInstances(pyblish.api.ContextPlugin):
|
|||
|
||||
# get pattern defined by type
|
||||
pattern = TXT_PATERN
|
||||
if a_type in ("number" , "float"):
|
||||
if a_type in ("number", "float"):
|
||||
pattern = NUM_PATERN
|
||||
|
||||
res_goup = pattern.findall(value)
|
||||
|
|
|
|||
|
|
@ -31,27 +31,28 @@ class CollecTimelineOTIO(pyblish.api.ContextPlugin):
|
|||
)
|
||||
|
||||
# adding otio timeline to context
|
||||
with opfapi.maintained_segment_selection(sequence):
|
||||
with opfapi.maintained_segment_selection(sequence) as selected_seg:
|
||||
otio_timeline = flame_export.create_otio_timeline(sequence)
|
||||
|
||||
instance_data = {
|
||||
"name": subset_name,
|
||||
"asset": asset_doc["name"],
|
||||
"subset": subset_name,
|
||||
"family": "workfile"
|
||||
}
|
||||
instance_data = {
|
||||
"name": subset_name,
|
||||
"asset": asset_doc["name"],
|
||||
"subset": subset_name,
|
||||
"family": "workfile"
|
||||
}
|
||||
|
||||
# create instance with workfile
|
||||
instance = context.create_instance(**instance_data)
|
||||
self.log.info("Creating instance: {}".format(instance))
|
||||
# create instance with workfile
|
||||
instance = context.create_instance(**instance_data)
|
||||
self.log.info("Creating instance: {}".format(instance))
|
||||
|
||||
# update context with main project attributes
|
||||
context.data.update({
|
||||
"flameProject": project,
|
||||
"flameSequence": sequence,
|
||||
"otioTimeline": otio_timeline,
|
||||
"currentFile": "Flame/{}/{}".format(
|
||||
project.name, sequence.name
|
||||
),
|
||||
"fps": float(str(sequence.frame_rate)[:-4])
|
||||
})
|
||||
# update context with main project attributes
|
||||
context.data.update({
|
||||
"flameProject": project,
|
||||
"flameSequence": sequence,
|
||||
"otioTimeline": otio_timeline,
|
||||
"currentFile": "Flame/{}/{}".format(
|
||||
project.name, sequence.name
|
||||
),
|
||||
"flameSelectedSegments": selected_seg,
|
||||
"fps": float(str(sequence.frame_rate)[:-4])
|
||||
})
|
||||
|
|
|
|||
|
|
@ -22,4 +22,6 @@ class CreateLook(plugin.Creator):
|
|||
self.data["maketx"] = self.make_tx
|
||||
|
||||
# Enable users to force a copy.
|
||||
# - on Windows is "forceCopy" always changed to `True` because of
|
||||
# windows implementation of hardlinks
|
||||
self.data["forceCopy"] = False
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import os
|
|||
import sys
|
||||
import json
|
||||
import tempfile
|
||||
import platform
|
||||
import contextlib
|
||||
import subprocess
|
||||
from collections import OrderedDict
|
||||
|
|
@ -334,7 +335,14 @@ class ExtractLook(openpype.api.Extractor):
|
|||
transfers = []
|
||||
hardlinks = []
|
||||
hashes = {}
|
||||
force_copy = instance.data.get("forceCopy", False)
|
||||
# Temporary fix to NOT create hardlinks on windows machines
|
||||
if platform.system().lower() == "windows":
|
||||
self.log.info(
|
||||
"Forcing copy instead of hardlink due to issues on Windows..."
|
||||
)
|
||||
force_copy = True
|
||||
else:
|
||||
force_copy = instance.data.get("forceCopy", False)
|
||||
|
||||
for filepath in files_metadata:
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
from openpype.hosts.traypublisher.api import pipeline
|
||||
from openpype.lib import FileDef
|
||||
from openpype.pipeline import (
|
||||
Creator,
|
||||
CreatedInstance,
|
||||
lib
|
||||
CreatedInstance
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -80,7 +80,7 @@ class WorkfileCreator(Creator):
|
|||
|
||||
def get_instance_attr_defs(self):
|
||||
output = [
|
||||
lib.FileDef(
|
||||
FileDef(
|
||||
"filepath",
|
||||
folders=False,
|
||||
extensions=self.extensions,
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ from openpype.pipeline import PublishValidationError
|
|||
class ValidateWorkfilePath(pyblish.api.InstancePlugin):
|
||||
"""Validate existence of workfile instance existence."""
|
||||
|
||||
label = "Collect Workfile"
|
||||
label = "Validate Workfile"
|
||||
order = pyblish.api.ValidatorOrder - 0.49
|
||||
families = ["workfile"]
|
||||
hosts = ["traypublisher"]
|
||||
|
|
|
|||
|
|
@ -211,6 +211,7 @@ class ApplicationGroup:
|
|||
data (dict): Group defying data loaded from settings.
|
||||
manager (ApplicationManager): Manager that created the group.
|
||||
"""
|
||||
|
||||
def __init__(self, name, data, manager):
|
||||
self.name = name
|
||||
self.manager = manager
|
||||
|
|
@ -374,6 +375,7 @@ class ApplicationManager:
|
|||
will always use these values. Gives ability to create manager
|
||||
using different settings.
|
||||
"""
|
||||
|
||||
def __init__(self, system_settings=None):
|
||||
self.log = PypeLogger.get_logger(self.__class__.__name__)
|
||||
|
||||
|
|
@ -530,13 +532,13 @@ class EnvironmentToolGroup:
|
|||
variants = data.get("variants") or {}
|
||||
label_by_key = variants.pop(M_DYNAMIC_KEY_LABEL, {})
|
||||
variants_by_name = {}
|
||||
for variant_name, variant_env in variants.items():
|
||||
for variant_name, variant_data in variants.items():
|
||||
if variant_name in METADATA_KEYS:
|
||||
continue
|
||||
|
||||
variant_label = label_by_key.get(variant_name) or variant_name
|
||||
tool = EnvironmentTool(
|
||||
variant_name, variant_label, variant_env, self
|
||||
variant_name, variant_label, variant_data, self
|
||||
)
|
||||
variants_by_name[variant_name] = tool
|
||||
self.variants = variants_by_name
|
||||
|
|
@ -560,15 +562,30 @@ class EnvironmentTool:
|
|||
|
||||
Args:
|
||||
name (str): Name of the tool.
|
||||
environment (dict): Variant environments.
|
||||
variant_data (dict): Variant data with environments and
|
||||
host and app variant filters.
|
||||
group (str): Name of group which wraps tool.
|
||||
"""
|
||||
|
||||
def __init__(self, name, label, environment, group):
|
||||
def __init__(self, name, label, variant_data, group):
|
||||
# Backwards compatibility 3.9.1 - 3.9.2
|
||||
# - 'variant_data' contained only environments but contain also host
|
||||
# and application variant filters
|
||||
host_names = variant_data.get("host_names", [])
|
||||
app_variants = variant_data.get("app_variants", [])
|
||||
|
||||
if "environment" in variant_data:
|
||||
environment = variant_data["environment"]
|
||||
else:
|
||||
environment = variant_data
|
||||
|
||||
self.host_names = host_names
|
||||
self.app_variants = app_variants
|
||||
self.name = name
|
||||
self.variant_label = label
|
||||
self.label = " ".join((group.label, label))
|
||||
self.group = group
|
||||
|
||||
self._environment = environment
|
||||
self.full_name = "/".join((group.name, name))
|
||||
|
||||
|
|
@ -579,6 +596,19 @@ class EnvironmentTool:
|
|||
def environment(self):
|
||||
return copy.deepcopy(self._environment)
|
||||
|
||||
def is_valid_for_app(self, app):
|
||||
"""Is tool valid for application.
|
||||
|
||||
Args:
|
||||
app (Application): Application for which are prepared environments.
|
||||
"""
|
||||
if self.app_variants and app.full_name not in self.app_variants:
|
||||
return False
|
||||
|
||||
if self.host_names and app.host_name not in self.host_names:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
class ApplicationExecutable:
|
||||
"""Representation of executable loaded from settings."""
|
||||
|
|
@ -1384,7 +1414,7 @@ def prepare_app_environments(data, env_group=None, implementation_envs=True):
|
|||
# Make sure each tool group can be added only once
|
||||
for key in asset_doc["data"].get("tools_env") or []:
|
||||
tool = app.manager.tools.get(key)
|
||||
if not tool:
|
||||
if not tool or not tool.is_valid_for_app(app):
|
||||
continue
|
||||
groups_by_name[tool.group.name] = tool.group
|
||||
tool_by_group_name[tool.group.name][tool.name] = tool
|
||||
|
|
|
|||
|
|
@ -478,8 +478,14 @@ def convert_for_ffmpeg(
|
|||
oiio_cmd.extend(["--eraseattrib", attr_name])
|
||||
|
||||
# Add last argument - path to output
|
||||
base_file_name = os.path.basename(first_input_path)
|
||||
output_path = os.path.join(output_dir, base_file_name)
|
||||
if is_sequence:
|
||||
ext = os.path.splitext(first_input_path)[1]
|
||||
base_filename = "tmp.%{:0>2}d{}".format(
|
||||
len(str(input_frame_end)), ext
|
||||
)
|
||||
else:
|
||||
base_filename = os.path.basename(first_input_path)
|
||||
output_path = os.path.join(output_dir, base_filename)
|
||||
oiio_cmd.extend([
|
||||
"-o", output_path
|
||||
])
|
||||
|
|
|
|||
|
|
@ -286,21 +286,6 @@ def from_dict_to_set(data, is_project):
|
|||
return result
|
||||
|
||||
|
||||
def get_avalon_project_template(project_name):
|
||||
"""Get avalon template
|
||||
Args:
|
||||
project_name: (string)
|
||||
Returns:
|
||||
dictionary with templates
|
||||
"""
|
||||
templates = Anatomy(project_name).templates
|
||||
return {
|
||||
"workfile": templates["avalon"]["workfile"],
|
||||
"work": templates["avalon"]["work"],
|
||||
"publish": templates["avalon"]["publish"]
|
||||
}
|
||||
|
||||
|
||||
def get_project_apps(in_app_list):
|
||||
""" Application definitions for app name.
|
||||
|
||||
|
|
|
|||
|
|
@ -27,11 +27,11 @@ class LogsWindow(QtWidgets.QWidget):
|
|||
|
||||
self.setStyleSheet(style.load_stylesheet())
|
||||
|
||||
self._frist_show = True
|
||||
self._first_show = True
|
||||
|
||||
def showEvent(self, event):
|
||||
super(LogsWindow, self).showEvent(event)
|
||||
|
||||
if self._frist_show:
|
||||
self._frist_show = False
|
||||
if self._first_show:
|
||||
self._first_show = False
|
||||
self.logs_widget.refresh()
|
||||
|
|
|
|||
|
|
@ -8,11 +8,11 @@ M_ENVIRONMENT_KEY = "__environment_keys__"
|
|||
# Metadata key for storing dynamic created labels
|
||||
M_DYNAMIC_KEY_LABEL = "__dynamic_keys_labels__"
|
||||
|
||||
METADATA_KEYS = (
|
||||
METADATA_KEYS = frozenset([
|
||||
M_OVERRIDDEN_KEY,
|
||||
M_ENVIRONMENT_KEY,
|
||||
M_DYNAMIC_KEY_LABEL
|
||||
)
|
||||
])
|
||||
|
||||
# Keys where studio's system overrides are stored
|
||||
GLOBAL_SETTINGS_KEY = "global_settings"
|
||||
|
|
|
|||
|
|
@ -25,10 +25,18 @@
|
|||
},
|
||||
"variants": {
|
||||
"3-2": {
|
||||
"MTOA_VERSION": "3.2"
|
||||
"host_names": [],
|
||||
"app_variants": [],
|
||||
"environment": {
|
||||
"MTOA_VERSION": "3.2"
|
||||
}
|
||||
},
|
||||
"3-1": {
|
||||
"MTOA_VERSION": "3.1"
|
||||
"host_names": [],
|
||||
"app_variants": [],
|
||||
"environment": {
|
||||
"MTOA_VERSION": "3.1"
|
||||
}
|
||||
},
|
||||
"__dynamic_keys_labels__": {
|
||||
"3-2": "3.2",
|
||||
|
|
|
|||
|
|
@ -25,7 +25,30 @@
|
|||
"key": "variants",
|
||||
"collapsible_key": true,
|
||||
"object_type": {
|
||||
"type": "raw-json"
|
||||
"type": "dict",
|
||||
"children": [
|
||||
{
|
||||
"key": "host_names",
|
||||
"label": "Hosts",
|
||||
"type": "hosts-enum",
|
||||
"multiselection": true
|
||||
},
|
||||
{
|
||||
"key": "app_variants",
|
||||
"label": "Applications",
|
||||
"type": "apps-enum",
|
||||
"multiselection": true,
|
||||
"tooltip": "Applications are not \"live\" and may require to Save and refresh settings UI to update values."
|
||||
},
|
||||
{
|
||||
"type": "separator"
|
||||
},
|
||||
{
|
||||
"key": "environment",
|
||||
"label": "Environments",
|
||||
"type": "raw-json"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
|
|
|
|||
|
|
@ -265,11 +265,43 @@ def save_project_anatomy(project_name, anatomy_data):
|
|||
raise SaveWarningExc(warnings)
|
||||
|
||||
|
||||
def _system_settings_backwards_compatible_conversion(studio_overrides):
|
||||
# Backwards compatibility of tools 3.9.1 - 3.9.2 to keep
|
||||
# "tools" environments
|
||||
if (
|
||||
"tools" in studio_overrides
|
||||
and "tool_groups" in studio_overrides["tools"]
|
||||
):
|
||||
tool_groups = studio_overrides["tools"]["tool_groups"]
|
||||
for tool_group, group_value in tool_groups.items():
|
||||
if tool_group in METADATA_KEYS:
|
||||
continue
|
||||
|
||||
variants = group_value.get("variants")
|
||||
if not variants:
|
||||
continue
|
||||
|
||||
for key in set(variants.keys()):
|
||||
if key in METADATA_KEYS:
|
||||
continue
|
||||
|
||||
variant_value = variants[key]
|
||||
if "environment" not in variant_value:
|
||||
variants[key] = {
|
||||
"environment": variant_value
|
||||
}
|
||||
|
||||
|
||||
@require_handler
|
||||
def get_studio_system_settings_overrides(return_version=False):
|
||||
return _SETTINGS_HANDLER.get_studio_system_settings_overrides(
|
||||
output = _SETTINGS_HANDLER.get_studio_system_settings_overrides(
|
||||
return_version
|
||||
)
|
||||
value = output
|
||||
if return_version:
|
||||
value, version = output
|
||||
_system_settings_backwards_compatible_conversion(value)
|
||||
return output
|
||||
|
||||
|
||||
@require_handler
|
||||
|
|
|
|||
|
|
@ -271,7 +271,7 @@ class CreateDialog(QtWidgets.QDialog):
|
|||
create_btn.setEnabled(False)
|
||||
|
||||
form_layout = QtWidgets.QFormLayout()
|
||||
form_layout.addRow("Name:", variant_layout)
|
||||
form_layout.addRow("Variant:", variant_layout)
|
||||
form_layout.addRow("Subset:", subset_name_input)
|
||||
|
||||
mid_widget = QtWidgets.QWidget(self)
|
||||
|
|
|
|||
|
|
@ -17,6 +17,8 @@ from openpype.lib import filter_profiles
|
|||
from openpype.style import get_objected_colors
|
||||
from openpype.resources import get_image_path
|
||||
|
||||
log = Logger.get_logger(__name__)
|
||||
|
||||
|
||||
def center_window(window):
|
||||
"""Move window to center of it's screen."""
|
||||
|
|
@ -111,13 +113,23 @@ def get_qta_icon_by_name_and_color(icon_name, icon_color):
|
|||
variants.append("{0}.{1}".format(key, icon_name))
|
||||
|
||||
icon = None
|
||||
used_variant = None
|
||||
for variant in variants:
|
||||
try:
|
||||
icon = qtawesome.icon(variant, color=icon_color)
|
||||
used_variant = variant
|
||||
break
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
if used_variant is None:
|
||||
log.info("Didn't find icon \"{}\"".format(icon_name))
|
||||
|
||||
elif used_variant != icon_name:
|
||||
log.debug("Icon \"{}\" was not found \"{}\" is used instead".format(
|
||||
icon_name, used_variant
|
||||
))
|
||||
|
||||
SharedObjects.icons[full_icon_name] = icon
|
||||
return icon
|
||||
|
||||
|
|
@ -140,8 +152,8 @@ def get_asset_icon_name(asset_doc, has_children=True):
|
|||
return icon_name
|
||||
|
||||
if has_children:
|
||||
return "folder"
|
||||
return "folder-o"
|
||||
return "fa.folder"
|
||||
return "fa.folder-o"
|
||||
|
||||
|
||||
def get_asset_icon_color(asset_doc):
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
"""Package declaring Pype version."""
|
||||
__version__ = "3.9.2-nightly.2"
|
||||
__version__ = "3.9.2-nightly.3"
|
||||
|
|
|
|||
|
|
@ -641,5 +641,6 @@ class SingleFileWidget(QtWidgets.QWidget):
|
|||
filepaths.append(filepath)
|
||||
# TODO filter check
|
||||
if len(filepaths) == 1:
|
||||
self.set_value(filepaths[0], False)
|
||||
self._filepath_input.setText(filepaths[0])
|
||||
|
||||
event.accept()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue