Merge remote-tracking branch 'origin/develop' into enhancement/maya-deadline-scene-patching

This commit is contained in:
Ondrej Samohel 2021-08-10 17:57:44 +02:00
commit ab63709a64
No known key found for this signature in database
GPG key ID: 02376E18990A97C6
16 changed files with 269 additions and 23 deletions

View file

@ -54,6 +54,10 @@ class LoadClip(phiero.SequenceLoader):
object_name = self.clip_name_template.format(
**context["representation"]["context"])
# set colorspace
if colorspace:
track_item.source().setSourceMediaColourTransform(colorspace)
# add additional metadata from the version to imprint Avalon knob
add_keys = [
"frameStart", "frameEnd", "source", "author",
@ -109,9 +113,14 @@ class LoadClip(phiero.SequenceLoader):
colorspace = version_data.get("colorspace", None)
object_name = "{}_{}".format(name, namespace)
file = api.get_representation_path(representation).replace("\\", "/")
clip = track_item.source()
# reconnect media to new path
track_item.source().reconnectMedia(file)
clip.reconnectMedia(file)
# set colorspace
if colorspace:
clip.setSourceMediaColourTransform(colorspace)
# add additional metadata from the version to imprint Avalon knob
add_keys = [
@ -160,6 +169,7 @@ class LoadClip(phiero.SequenceLoader):
@classmethod
def set_item_color(cls, track_item, version):
clip = track_item.source()
# define version name
version_name = version.get("name", None)
# get all versions in list
@ -172,6 +182,6 @@ class LoadClip(phiero.SequenceLoader):
# set clip colour
if version_name == max_version:
track_item.source().binItem().setColor(cls.clip_color_last)
clip.binItem().setColor(cls.clip_color_last)
else:
track_item.source().binItem().setColor(cls.clip_color)
clip.binItem().setColor(cls.clip_color)

View file

@ -120,6 +120,13 @@ class PrecollectInstances(pyblish.api.ContextPlugin):
# create instance
instance = context.create_instance(**data)
# add colorspace data
instance.data.update({
"versionData": {
"colorspace": track_item.sourceMediaColourTransform(),
}
})
# create shot instance for shot attributes create/update
self.create_shot_instance(context, **data)
@ -133,13 +140,6 @@ class PrecollectInstances(pyblish.api.ContextPlugin):
# create audio subset instance
self.create_audio_instance(context, **data)
# add colorspace data
instance.data.update({
"versionData": {
"colorspace": track_item.sourceMediaColourTransform(),
}
})
# add audioReview attribute to plate instance data
# if reviewTrack is on
if tag_data.get("reviewTrack") is not None:

View file

@ -259,7 +259,8 @@ class LoadMov(api.Loader):
read_node["last"].setValue(last)
read_node['frame_mode'].setValue("start at")
if int(self.first_frame) == int(read_node['frame'].value()):
if int(float(self.first_frame)) == int(
float(read_node['frame'].value())):
# start at workfile start
read_node['frame'].setValue(str(self.first_frame))
else:

View file

@ -270,6 +270,7 @@ class CollectTextures(pyblish.api.ContextPlugin):
# store origin
if family == 'workfile':
families = self.workfile_families
families.append("texture_batch_workfile")
new_instance.data["source"] = "standalone publisher"
else:

View file

@ -8,7 +8,7 @@ class ValidateTextureBatch(pyblish.api.InstancePlugin):
label = "Validate Texture Presence"
hosts = ["standalonepublisher"]
order = openpype.api.ValidateContentsOrder
families = ["workfile"]
families = ["texture_batch_workfile"]
optional = False
def process(self, instance):

View file

@ -8,7 +8,7 @@ class ValidateTextureBatchNaming(pyblish.api.InstancePlugin):
label = "Validate Texture Batch Naming"
hosts = ["standalonepublisher"]
order = openpype.api.ValidateContentsOrder
families = ["workfile", "textures"]
families = ["texture_batch_workfile", "textures"]
optional = False
def process(self, instance):

View file

@ -11,7 +11,7 @@ class ValidateTextureBatchWorkfiles(pyblish.api.InstancePlugin):
label = "Validate Texture Workfile Has Resources"
hosts = ["standalonepublisher"]
order = openpype.api.ValidateContentsOrder
families = ["workfile"]
families = ["texture_batch_workfile"]
optional = True
# from presets

View file

@ -1138,7 +1138,8 @@ def prepare_host_environments(data, implementation_envs=True):
# Merge dictionaries
env_values = _merge_env(tool_env, env_values)
loaded_env = _merge_env(acre.compute(env_values), data["env"])
merged_env = _merge_env(env_values, data["env"])
loaded_env = acre.compute(merged_env, cleanup=False)
final_env = None
# Add host specific environments
@ -1189,7 +1190,10 @@ def apply_project_environments_value(project_name, env, project_settings=None):
env_value = project_settings["global"]["project_environments"]
if env_value:
env.update(_merge_env(acre.parse(env_value), env))
env.update(acre.compute(
_merge_env(acre.parse(env_value), env),
cleanup=False
))
return env

View file

@ -3,6 +3,7 @@ import re
import json
import copy
import inspect
import contextlib
from .exceptions import (
SchemaTemplateMissingKeys,
@ -111,6 +112,10 @@ class SchemasHub:
self._loaded_templates = {}
self._loaded_schemas = {}
# Store validating and validated dynamic template or schemas
self._validating_dynamic = set()
self._validated_dynamic = set()
# It doesn't make sence to reload types on each reset as they can't be
# changed
self._load_types()
@ -126,6 +131,60 @@ class SchemasHub:
def gui_types(self):
return self._gui_types
def get_template_name(self, item_def, default=None):
"""Get template name from passed item definition.
Args:
item_def(dict): Definition of item with "type".
default(object): Default return value.
"""
output = default
if not item_def or not isinstance(item_def, dict):
return output
item_type = item_def.get("type")
if item_type in ("template", "schema_template"):
output = item_def["name"]
return output
def is_dynamic_template_validating(self, template_name):
"""Is template validating using different entity.
Returns:
bool: Is template validating.
"""
if template_name in self._validating_dynamic:
return True
return False
def is_dynamic_template_validated(self, template_name):
"""Is template already validated.
Returns:
bool: Is template validated.
"""
if template_name in self._validated_dynamic:
return True
return False
@contextlib.contextmanager
def validating_dynamic(self, template_name):
"""Template name is validating and validated.
Context manager that cares about storing template name validations of
template.
This is to avoid infinite loop of dynamic children validation.
"""
self._validating_dynamic.add(template_name)
try:
yield
self._validated_dynamic.add(template_name)
finally:
self._validating_dynamic.remove(template_name)
def get_schema(self, schema_name):
"""Get schema definition data by it's name.

View file

@ -141,7 +141,20 @@ class ListEntity(EndpointEntity):
item_schema = self.schema_data["object_type"]
if not isinstance(item_schema, dict):
item_schema = {"type": item_schema}
self.item_schema = item_schema
obj_template_name = self.schema_hub.get_template_name(item_schema)
_item_schemas = self.schema_hub.resolve_schema_data(item_schema)
if len(_item_schemas) == 1:
self.item_schema = _item_schemas[0]
if self.item_schema != item_schema:
if "label" in self.item_schema:
self.item_schema.pop("label")
self.item_schema["use_label_wrap"] = False
else:
self.item_schema = _item_schemas
# Store if was used template or schema
self._obj_template_name = obj_template_name
if self.group_item is None:
self.is_group = True
@ -150,6 +163,12 @@ class ListEntity(EndpointEntity):
self.initial_value = []
def schema_validations(self):
if isinstance(self.item_schema, list):
reason = (
"`ListWidget` has multiple items as object type."
)
raise EntitySchemaError(self, reason)
super(ListEntity, self).schema_validations()
if self.is_dynamic_item and self.use_label_wrap:
@ -167,18 +186,36 @@ class ListEntity(EndpointEntity):
raise EntitySchemaError(self, reason)
# Validate object type schema
child_validated = False
validate_children = True
for child_entity in self.children:
child_entity.schema_validations()
child_validated = True
validate_children = False
break
if not child_validated:
if validate_children and self._obj_template_name:
_validated = self.schema_hub.is_dynamic_template_validated(
self._obj_template_name
)
_validating = self.schema_hub.is_dynamic_template_validating(
self._obj_template_name
)
validate_children = not _validated and not _validating
if not validate_children:
return
def _validate():
idx = 0
tmp_child = self._add_new_item(idx)
tmp_child.schema_validations()
self.children.pop(idx)
if self._obj_template_name:
with self.schema_hub.validating_dynamic(self._obj_template_name):
_validate()
else:
_validate()
def get_child_path(self, child_obj):
result_idx = None
for idx, _child_obj in enumerate(self.children):

View file

@ -417,6 +417,8 @@ How output of the schema could look like on save:
- there are 2 possible ways how to set the type:
1.) dictionary with item modifiers (`number` input has `minimum`, `maximum` and `decimals`) in that case item type must be set as value of `"type"` (example below)
2.) item type name as string without modifiers (e.g. `text`)
3.) enhancement of 1.) there is also support of `template` type but be carefull about endless loop of templates
- goal of using `template` is to easily change same item definitions in multiple lists
1.) with item modifiers
```
@ -442,6 +444,65 @@ How output of the schema could look like on save:
}
```
3.) with template definition
```
# Schema of list item where template is used
{
"type": "list",
"key": "menu_items",
"label": "Menu Items",
"object_type": {
"type": "template",
"name": "template_object_example"
}
}
# WARNING:
# In this example the template use itself inside which will work in `list`
# but may cause an issue in other entity types (e.g. `dict`).
'template_object_example.json' :
[
{
"type": "dict-conditional",
"use_label_wrap": true,
"collapsible": true,
"key": "menu_items",
"label": "Menu items",
"enum_key": "type",
"enum_label": "Type",
"enum_children": [
{
"key": "action",
"label": "Action",
"children": [
{
"type": "text",
"key": "key",
"label": "Key"
}
]
},
{
"key": "menu",
"label": "Menu",
"children": [
{
"key": "children",
"label": "Children",
"type": "list",
"object_type": {
"type": "template",
"name": "template_object_example"
}
}
]
}
]
}
]
```
### dict-modifiable
- one of dictionary inputs, this is only used as value input
- items in this input can be removed and added same way as in `list` input

View file

@ -0,0 +1,58 @@
[
{
"type": "dict-conditional",
"use_label_wrap": true,
"collapsible": true,
"key": "menu_items",
"label": "Menu items",
"enum_key": "type",
"enum_label": "Type",
"enum_children": [
{
"key": "action",
"label": "Action",
"children": [
{
"type": "text",
"key": "key",
"label": "Key"
},
{
"type": "text",
"key": "label",
"label": "Label"
},
{
"type": "text",
"key": "command",
"label": "Comand"
}
]
},
{
"key": "menu",
"label": "Menu",
"children": [
{
"type": "text",
"key": "label",
"label": "Label"
},
{
"key": "children",
"label": "Children",
"type": "list",
"object_type": {
"type": "template",
"name": "example_infinite_hierarchy"
}
}
]
},
{
"key": "separator",
"label": "Separator"
}
]
}
]

View file

@ -82,6 +82,17 @@
}
]
},
{
"type": "list",
"use_label_wrap": true,
"collapsible": true,
"key": "infinite_hierarchy",
"label": "Infinite list template hierarchy",
"object_type": {
"type": "template",
"name": "example_infinite_hierarchy"
}
},
{
"type": "dict",
"key": "schema_template_exaples",

2
poetry.lock generated
View file

@ -11,7 +11,7 @@ develop = false
type = "git"
url = "https://github.com/pypeclub/acre.git"
reference = "master"
resolved_reference = "5a812c6dcfd3aada87adb49be98c548c894d6566"
resolved_reference = "55a7c331e6dc5f81639af50ca4a8cc9d73e9273d"
[[package]]
name = "aiohttp"

@ -1 +1 @@
Subproject commit cfd4191e364b47de7364096f45d9d9d9a901692a
Subproject commit e5c8a15fde77708c924eab3018bda255f17b5390

View file

@ -221,10 +221,14 @@ def set_openpype_global_environments() -> None:
all_env = get_environments()
general_env = all_env["global"]
env = acre.merge(
merged_env = acre.merge(
acre.parse(general_env),
dict(os.environ)
)
env = acre.compute(
merged_env,
cleanup=False
)
os.environ.clear()
os.environ.update(env)