Merge branch 'develop' into bugfix/1587-hiero-published-whole-edit-mov

This commit is contained in:
Jakub Jezek 2021-06-14 11:19:45 +02:00
commit 71fc0fceef
No known key found for this signature in database
GPG key ID: D8548FBF690B100A
27 changed files with 992 additions and 202 deletions

View file

@ -190,7 +190,7 @@ def get_track_items(
if not item.isEnabled():
continue
if track_item_name:
if item.name() in track_item_name:
if track_item_name in item.name():
return item
# make sure only track items with correct track names are added
if track_name and track_name in track.name():
@ -949,6 +949,54 @@ def sync_clip_name_to_data_asset(track_items_list):
print("asset was changed in clip: {}".format(ti_name))
def check_inventory_versions():
"""
Actual version color idetifier of Loaded containers
Check all track items and filter only
Loader nodes for its version. It will get all versions from database
and check if the node is having actual version. If not then it will color
it to red.
"""
from . import parse_container
from avalon import io
# presets
clip_color_last = "green"
clip_color = "red"
# get all track items from current timeline
for track_item in get_track_items():
container = parse_container(track_item)
if container:
# get representation from io
representation = io.find_one({
"type": "representation",
"_id": io.ObjectId(container["representation"])
})
# 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)
# set clip colour
if version.get("name") == max_version:
track_item.source().binItem().setColor(clip_color_last)
else:
track_item.source().binItem().setColor(clip_color)
def selection_changed_timeline(event):
"""Callback on timeline to check if asset in data is the same as clip name.
@ -958,9 +1006,15 @@ def selection_changed_timeline(event):
timeline_editor = event.sender
selection = timeline_editor.selection()
selection = [ti for ti in selection
if isinstance(ti, hiero.core.TrackItem)]
# run checking function
sync_clip_name_to_data_asset(selection)
# also mark old versions of loaded containers
check_inventory_versions()
def before_project_save(event):
track_items = get_track_items(
@ -972,3 +1026,6 @@ def before_project_save(event):
# run checking function
sync_clip_name_to_data_asset(track_items)
# also mark old versions of loaded containers
check_inventory_versions()

View file

@ -1,9 +1,11 @@
from avalon.api import CreatorError
from avalon.tvpaint import (
pipeline,
lib,
CommunicationWrapper
)
from openpype.hosts.tvpaint.api import plugin
from openpype.lib import prepare_template_data
class CreateRenderlayer(plugin.Creator):
@ -15,13 +17,31 @@ class CreateRenderlayer(plugin.Creator):
defaults = ["Main"]
rename_group = True
render_pass = "beauty"
subset_template = "{family}_{name}"
rename_script_template = (
"tv_layercolor \"setcolor\""
" {clip_id} {group_id} {r} {g} {b} \"{name}\""
)
dynamic_subset_keys = ["render_pass", "render_layer", "group"]
@classmethod
def get_dynamic_data(
cls, variant, task_name, asset_id, project_name, host_name
):
dynamic_data = super(CreateRenderlayer, cls).get_dynamic_data(
variant, task_name, asset_id, project_name, host_name
)
# Use render pass name from creator's plugin
dynamic_data["render_pass"] = cls.render_pass
# Add variant to render layer
dynamic_data["render_layer"] = variant
# Change family for subset name fill
dynamic_data["family"] = "render"
return dynamic_data
@classmethod
def get_default_variant(cls):
"""Default value for variant in Creator tool.
@ -70,34 +90,44 @@ class CreateRenderlayer(plugin.Creator):
# Raise if there is no selection
if not group_ids:
raise AssertionError("Nothing is selected.")
raise CreatorError("Nothing is selected.")
# This creator should run only on one group
if len(group_ids) > 1:
raise AssertionError("More than one group is in selection.")
raise CreatorError("More than one group is in selection.")
group_id = tuple(group_ids)[0]
# If group id is `0` it is `default` group which is invalid
if group_id == 0:
raise AssertionError(
raise CreatorError(
"Selection is not in group. Can't mark selection as Beauty."
)
self.log.debug(f"Selected group id is \"{group_id}\".")
self.data["group_id"] = group_id
family = self.data["family"]
# Extract entered name
name = self.data["subset"][len(family):]
self.log.info(f"Extracted name from subset name \"{name}\".")
self.data["name"] = name
group_data = lib.groups_data()
group_name = None
for group in group_data:
if group["group_id"] == group_id:
group_name = group["name"]
break
# Change subset name by template
subset_name = self.subset_template.format(**{
"family": self.family,
"name": name
})
self.log.info(f"New subset name \"{subset_name}\".")
if group_name is None:
raise AssertionError(
"Couldn't find group by id \"{}\"".format(group_id)
)
subset_name_fill_data = {
"group": group_name
}
family = self.family = self.data["family"]
# Fill dynamic key 'group'
subset_name = self.data["subset"].format(
**prepare_template_data(subset_name_fill_data)
)
self.data["subset"] = subset_name
# Check for instances of same group
@ -153,7 +183,7 @@ class CreateRenderlayer(plugin.Creator):
# Rename TVPaint group (keep color same)
# - groups can't contain spaces
new_group_name = name.replace(" ", "_")
new_group_name = self.data["variant"].replace(" ", "_")
rename_script = self.rename_script_template.format(
clip_id=selected_group["clip_id"],
group_id=selected_group["group_id"],

View file

@ -1,9 +1,11 @@
from avalon.api import CreatorError
from avalon.tvpaint import (
pipeline,
lib,
CommunicationWrapper
)
from openpype.hosts.tvpaint.api import plugin
from openpype.lib import prepare_template_data
class CreateRenderPass(plugin.Creator):
@ -18,7 +20,19 @@ class CreateRenderPass(plugin.Creator):
icon = "cube"
defaults = ["Main"]
subset_template = "{family}_{render_layer}_{pass}"
dynamic_subset_keys = ["render_pass", "render_layer"]
@classmethod
def get_dynamic_data(
cls, variant, task_name, asset_id, project_name, host_name
):
dynamic_data = super(CreateRenderPass, cls).get_dynamic_data(
variant, task_name, asset_id, project_name, host_name
)
dynamic_data["render_pass"] = variant
dynamic_data["family"] = "render"
return dynamic_data
@classmethod
def get_default_variant(cls):
@ -66,11 +80,11 @@ class CreateRenderPass(plugin.Creator):
# Raise if nothing is selected
if not selected_layers:
raise AssertionError("Nothing is selected.")
raise CreatorError("Nothing is selected.")
# Raise if layers from multiple groups are selected
if len(group_ids) != 1:
raise AssertionError("More than one group is in selection.")
raise CreatorError("More than one group is in selection.")
group_id = tuple(group_ids)[0]
self.log.debug(f"Selected group id is \"{group_id}\".")
@ -87,34 +101,40 @@ class CreateRenderPass(plugin.Creator):
# Beauty is required for this creator so raise if was not found
if beauty_instance is None:
raise AssertionError("Beauty pass does not exist yet.")
raise CreatorError("Beauty pass does not exist yet.")
render_layer = beauty_instance["name"]
subset_name = self.data["subset"]
subset_name_fill_data = {}
# Backwards compatibility
# - beauty may be created with older creator where variant was not
# stored
if "variant" not in beauty_instance:
render_layer = beauty_instance["name"]
else:
render_layer = beauty_instance["variant"]
subset_name_fill_data["render_layer"] = render_layer
# Format dynamic keys in subset name
new_subset_name = subset_name.format(
**prepare_template_data(subset_name_fill_data)
)
self.data["subset"] = new_subset_name
self.log.info(f"New subset name is \"{new_subset_name}\".")
# Extract entered name
family = self.data["family"]
name = self.data["subset"]
# Is this right way how to get name?
name = name[len(family):]
self.log.info(f"Extracted name from subset name \"{name}\".")
variant = self.data["variant"]
self.data["group_id"] = group_id
self.data["pass"] = name
self.data["pass"] = variant
self.data["render_layer"] = render_layer
# Collect selected layer ids to be stored into instance
layer_names = [layer["name"] for layer in selected_layers]
self.data["layer_names"] = layer_names
# Replace `beauty` in beauty's subset name with entered name
subset_name = self.subset_template.format(**{
"family": family,
"render_layer": render_layer,
"pass": name
})
self.data["subset"] = subset_name
self.log.info(f"New subset name is \"{subset_name}\".")
# Check if same instance already exists
existing_instance = None
existing_instance_idx = None
@ -122,7 +142,7 @@ class CreateRenderPass(plugin.Creator):
if (
instance["family"] == family
and instance["group_id"] == group_id
and instance["pass"] == name
and instance["pass"] == variant
):
existing_instance = instance
existing_instance_idx = idx
@ -131,7 +151,7 @@ class CreateRenderPass(plugin.Creator):
if existing_instance is not None:
self.log.info(
f"Render pass instance for group id {group_id}"
f" and name \"{name}\" already exists, overriding."
f" and name \"{variant}\" already exists, overriding."
)
instances[existing_instance_idx] = self.data
else:

View file

@ -4,6 +4,8 @@ import copy
import pyblish.api
from avalon import io
from openpype.lib import get_subset_name
class CollectInstances(pyblish.api.ContextPlugin):
label = "Collect Instances"
@ -62,9 +64,38 @@ class CollectInstances(pyblish.api.ContextPlugin):
# Different instance creation based on family
instance = None
if family == "review":
# Change subset name
# Change subset name of review instance
# Collect asset doc to get asset id
# - not sure if it's good idea to require asset id in
# get_subset_name?
asset_name = context.data["workfile_context"]["asset"]
asset_doc = io.find_one(
{
"type": "asset",
"name": asset_name
},
{"_id": 1}
)
asset_id = None
if asset_doc:
asset_id = asset_doc["_id"]
# Project name from workfile context
project_name = context.data["workfile_context"]["project"]
# Host name from environemnt variable
host_name = os.environ["AVALON_APP"]
# Use empty variant value
variant = ""
task_name = io.Session["AVALON_TASK"]
new_subset_name = "{}{}".format(family, task_name.capitalize())
new_subset_name = get_subset_name(
family,
variant,
task_name,
asset_id,
project_name,
host_name
)
instance_data["subset"] = new_subset_name
instance = context.create_instance(**instance_data)
@ -119,19 +150,23 @@ class CollectInstances(pyblish.api.ContextPlugin):
name = instance_data["name"]
# Change label
subset_name = instance_data["subset"]
instance_data["label"] = "{}_Beauty".format(name)
# Change subset name
# Final family of an instance will be `render`
new_family = "render"
task_name = io.Session["AVALON_TASK"]
new_subset_name = "{}{}_{}_Beauty".format(
new_family, task_name.capitalize(), name
)
instance_data["subset"] = new_subset_name
self.log.debug("Changed subset name \"{}\"->\"{}\"".format(
subset_name, new_subset_name
))
# Backwards compatibility
# - subset names were not stored as final subset names during creation
if "variant" not in instance_data:
instance_data["label"] = "{}_Beauty".format(name)
# Change subset name
# Final family of an instance will be `render`
new_family = "render"
task_name = io.Session["AVALON_TASK"]
new_subset_name = "{}{}_{}_Beauty".format(
new_family, task_name.capitalize(), name
)
instance_data["subset"] = new_subset_name
self.log.debug("Changed subset name \"{}\"->\"{}\"".format(
subset_name, new_subset_name
))
# Get all layers for the layer
layers_data = context.data["layersData"]
@ -163,20 +198,23 @@ class CollectInstances(pyblish.api.ContextPlugin):
)
# Change label
render_layer = instance_data["render_layer"]
instance_data["label"] = "{}_{}".format(render_layer, pass_name)
# Change subset name
# Final family of an instance will be `render`
new_family = "render"
old_subset_name = instance_data["subset"]
task_name = io.Session["AVALON_TASK"]
new_subset_name = "{}{}_{}_{}".format(
new_family, task_name.capitalize(), render_layer, pass_name
)
instance_data["subset"] = new_subset_name
self.log.debug("Changed subset name \"{}\"->\"{}\"".format(
old_subset_name, new_subset_name
))
# Backwards compatibility
# - subset names were not stored as final subset names during creation
if "variant" not in instance_data:
instance_data["label"] = "{}_{}".format(render_layer, pass_name)
# Change subset name
# Final family of an instance will be `render`
new_family = "render"
old_subset_name = instance_data["subset"]
task_name = io.Session["AVALON_TASK"]
new_subset_name = "{}{}_{}_{}".format(
new_family, task_name.capitalize(), render_layer, pass_name
)
instance_data["subset"] = new_subset_name
self.log.debug("Changed subset name \"{}\"->\"{}\"".format(
old_subset_name, new_subset_name
))
layers_data = context.data["layersData"]
layers_by_name = {

View file

@ -3,6 +3,8 @@ import json
import pyblish.api
from avalon import io
from openpype.lib import get_subset_name
class CollectWorkfile(pyblish.api.ContextPlugin):
label = "Collect Workfile"
@ -20,8 +22,38 @@ class CollectWorkfile(pyblish.api.ContextPlugin):
basename, ext = os.path.splitext(filename)
instance = context.create_instance(name=basename)
# Get subset name of workfile instance
# Collect asset doc to get asset id
# - not sure if it's good idea to require asset id in
# get_subset_name?
family = "workfile"
asset_name = context.data["workfile_context"]["asset"]
asset_doc = io.find_one(
{
"type": "asset",
"name": asset_name
},
{"_id": 1}
)
asset_id = None
if asset_doc:
asset_id = asset_doc["_id"]
# Project name from workfile context
project_name = context.data["workfile_context"]["project"]
# Host name from environemnt variable
host_name = os.environ["AVALON_APP"]
# Use empty variant value
variant = ""
task_name = io.Session["AVALON_TASK"]
subset_name = "workfile" + task_name.capitalize()
subset_name = get_subset_name(
family,
variant,
task_name,
asset_id,
project_name,
host_name
)
# Create Workfile instance
instance.data.update({