mirror of
https://github.com/ynput/ayon-core.git
synced 2025-12-25 05:14:40 +01:00
189 lines
6 KiB
Python
189 lines
6 KiB
Python
import re
|
|
|
|
from openpype.pipeline import LoaderPlugin
|
|
from openpype.pipeline.create import (
|
|
CreatedInstance,
|
|
get_subset_name,
|
|
AutoCreator,
|
|
Creator,
|
|
)
|
|
from openpype.pipeline.create.creator_plugins import cache_and_get_instances
|
|
|
|
from .lib import get_layers_data
|
|
|
|
|
|
SHARED_DATA_KEY = "openpype.tvpaint.instances"
|
|
|
|
|
|
class TVPaintCreatorCommon:
|
|
@property
|
|
def subset_template_family_filter(self):
|
|
return self.family
|
|
|
|
def _cache_and_get_instances(self):
|
|
return cache_and_get_instances(
|
|
self, SHARED_DATA_KEY, self.host.list_instances
|
|
)
|
|
|
|
def _collect_create_instances(self):
|
|
instances_by_identifier = self._cache_and_get_instances()
|
|
for instance_data in instances_by_identifier[self.identifier]:
|
|
instance = CreatedInstance.from_existing(instance_data, self)
|
|
self._add_instance_to_context(instance)
|
|
|
|
def _update_create_instances(self, update_list):
|
|
if not update_list:
|
|
return
|
|
|
|
cur_instances = self.host.list_instances()
|
|
cur_instances_by_id = {}
|
|
for instance_data in cur_instances:
|
|
instance_id = instance_data.get("instance_id")
|
|
if instance_id:
|
|
cur_instances_by_id[instance_id] = instance_data
|
|
|
|
for instance, changes in update_list:
|
|
instance_data = changes.new_value
|
|
cur_instance_data = cur_instances_by_id.get(instance.id)
|
|
if cur_instance_data is None:
|
|
cur_instances.append(instance_data)
|
|
continue
|
|
for key in set(cur_instance_data) - set(instance_data):
|
|
cur_instance_data.pop(key)
|
|
cur_instance_data.update(instance_data)
|
|
self.host.write_instances(cur_instances)
|
|
|
|
def _custom_get_subset_name(
|
|
self,
|
|
variant,
|
|
task_name,
|
|
asset_doc,
|
|
project_name,
|
|
host_name=None,
|
|
instance=None
|
|
):
|
|
dynamic_data = self.get_dynamic_data(
|
|
variant, task_name, asset_doc, project_name, host_name, instance
|
|
)
|
|
|
|
return get_subset_name(
|
|
self.family,
|
|
variant,
|
|
task_name,
|
|
asset_doc,
|
|
project_name,
|
|
host_name,
|
|
dynamic_data=dynamic_data,
|
|
project_settings=self.project_settings,
|
|
family_filter=self.subset_template_family_filter
|
|
)
|
|
|
|
|
|
class TVPaintCreator(Creator, TVPaintCreatorCommon):
|
|
def collect_instances(self):
|
|
self._collect_create_instances()
|
|
|
|
def update_instances(self, update_list):
|
|
self._update_create_instances(update_list)
|
|
|
|
def remove_instances(self, instances):
|
|
ids_to_remove = {
|
|
instance.id
|
|
for instance in instances
|
|
}
|
|
cur_instances = self.host.list_instances()
|
|
changed = False
|
|
new_instances = []
|
|
for instance_data in cur_instances:
|
|
if instance_data.get("instance_id") in ids_to_remove:
|
|
changed = True
|
|
else:
|
|
new_instances.append(instance_data)
|
|
|
|
if changed:
|
|
self.host.write_instances(new_instances)
|
|
|
|
for instance in instances:
|
|
self._remove_instance_from_context(instance)
|
|
|
|
def get_dynamic_data(self, *args, **kwargs):
|
|
# Change asset and name by current workfile context
|
|
create_context = self.create_context
|
|
asset_name = create_context.get_current_asset_name()
|
|
task_name = create_context.get_current_task_name()
|
|
output = {}
|
|
if asset_name:
|
|
output["asset"] = asset_name
|
|
if task_name:
|
|
output["task"] = task_name
|
|
return output
|
|
|
|
def get_subset_name(self, *args, **kwargs):
|
|
return self._custom_get_subset_name(*args, **kwargs)
|
|
|
|
def _store_new_instance(self, new_instance):
|
|
instances_data = self.host.list_instances()
|
|
instances_data.append(new_instance.data_to_store())
|
|
self.host.write_instances(instances_data)
|
|
self._add_instance_to_context(new_instance)
|
|
|
|
|
|
class TVPaintAutoCreator(AutoCreator, TVPaintCreatorCommon):
|
|
def collect_instances(self):
|
|
self._collect_create_instances()
|
|
|
|
def update_instances(self, update_list):
|
|
self._update_create_instances(update_list)
|
|
|
|
def get_subset_name(self, *args, **kwargs):
|
|
return self._custom_get_subset_name(*args, **kwargs)
|
|
|
|
|
|
class Loader(LoaderPlugin):
|
|
hosts = ["tvpaint"]
|
|
|
|
@staticmethod
|
|
def get_members_from_container(container):
|
|
if "members" not in container and "objectName" in container:
|
|
# Backwards compatibility
|
|
layer_ids_str = container.get("objectName")
|
|
return [
|
|
int(layer_id) for layer_id in layer_ids_str.split("|")
|
|
]
|
|
return container["members"]
|
|
|
|
def get_unique_layer_name(self, asset_name, name):
|
|
"""Layer name with counter as suffix.
|
|
|
|
Find higher 3 digit suffix from all layer names in scene matching regex
|
|
`{asset_name}_{name}_{suffix}`. Higher 3 digit suffix is used
|
|
as base for next number if scene does not contain layer matching regex
|
|
`0` is used ase base.
|
|
|
|
Args:
|
|
asset_name (str): Name of subset's parent asset document.
|
|
name (str): Name of loaded subset.
|
|
|
|
Returns:
|
|
(str): `{asset_name}_{name}_{higher suffix + 1}`
|
|
"""
|
|
layer_name_base = "{}_{}".format(asset_name, name)
|
|
|
|
counter_regex = re.compile(r"_(\d{3})$")
|
|
|
|
higher_counter = 0
|
|
for layer in get_layers_data():
|
|
layer_name = layer["name"]
|
|
if not layer_name.startswith(layer_name_base):
|
|
continue
|
|
number_subpart = layer_name[len(layer_name_base):]
|
|
groups = counter_regex.findall(number_subpart)
|
|
if len(groups) != 1:
|
|
continue
|
|
|
|
counter = int(groups[0])
|
|
if counter > higher_counter:
|
|
higher_counter = counter
|
|
continue
|
|
|
|
return "{}_{:0>3d}".format(layer_name_base, higher_counter + 1)
|