fusion is using product name and type

This commit is contained in:
Jakub Trllo 2024-02-23 10:19:08 +01:00
parent cf0ac31aa6
commit 800249daab
7 changed files with 81 additions and 57 deletions

View file

@ -33,14 +33,16 @@ class GenericCreateSaver(Creator):
# TODO: This should be renamed together with Nuke so it is aligned
temp_rendering_path_template = (
"{workdir}/renders/fusion/{subset}/{subset}.{frame}.{ext}")
"{workdir}/renders/fusion/{product[name]}/"
"{product[name]}.{frame}.{ext}"
)
def create(self, subset_name, instance_data, pre_create_data):
def create(self, product_name, instance_data, pre_create_data):
self.pass_pre_attributes_to_instance(instance_data, pre_create_data)
instance = CreatedInstance(
family=self.family,
subset_name=subset_name,
product_type=self.product_type,
product_name=product_name,
data=instance_data,
creator=self,
)
@ -111,23 +113,23 @@ class GenericCreateSaver(Creator):
tool.SetData(f"openpype.{key}", value)
def _update_tool_with_data(self, tool, data):
"""Update tool node name and output path based on subset data"""
if "subset" not in data:
"""Update tool node name and output path based on product data"""
if "productName" not in data:
return
original_subset = tool.GetData("openpype.subset")
original_product_name = tool.GetData("openpype.productName")
original_format = tool.GetData(
"openpype.creator_attributes.image_format"
)
subset = data["subset"]
product_name = data["productName"]
if (
original_subset != subset
original_product_name != product_name
or original_format != data["creator_attributes"]["image_format"]
):
self._configure_saver_tool(data, tool, subset)
self._configure_saver_tool(data, tool, product_name)
def _configure_saver_tool(self, data, tool, subset):
def _configure_saver_tool(self, data, tool, product_name):
formatting_data = deepcopy(data)
# get frame padding from anatomy templates
@ -137,25 +139,39 @@ class GenericCreateSaver(Creator):
ext = data["creator_attributes"]["image_format"]
# Subset change detected
product_type = formatting_data["productType"]
f_product_name = formatting_data["productName"]
folder_path = formatting_data["folderPath"]
folder_name = folder_path.rsplit("/", 1)[-1]
workdir = os.path.normpath(os.getenv("AYON_WORKDIR"))
formatting_data.update({
"workdir": workdir,
"frame": "0" * frame_padding,
"ext": ext,
"product": {
"name": formatting_data["subset"],
"type": formatting_data["family"],
"name": f_product_name,
"type": product_type,
},
# TODO add more variants for 'folder' and 'task'
"folder": {
"name": folder_name,
},
"task": {
"name": data["task"],
},
# Backwards compatibility
"asset": folder_name,
"subset": f_product_name,
"family": product_type,
})
# build file path to render
# TODO make sure the keys are available in 'formatting_data'
temp_rendering_path_template = (
self.temp_rendering_path_template
.replace("{product[name]}", "{subset}")
.replace("{product[type]}", "{family}")
.replace("{folder[name]}", "{asset}")
.replace("{task[name]}", "{task}")
.replace("{task}", "{task[name]}")
)
filepath = temp_rendering_path_template.format(**formatting_data)
@ -164,9 +180,9 @@ class GenericCreateSaver(Creator):
tool["Clip"] = comp.ReverseMapPath(os.path.normpath(filepath))
# Rename tool
if tool.Name != subset:
print(f"Renaming {tool.Name} -> {subset}")
tool.SetAttrs({"TOOLS_Name": subset})
if tool.Name != product_name:
print(f"Renaming {tool.Name} -> {product_name}")
tool.SetAttrs({"TOOLS_Name": product_name})
def get_managed_tool_data(self, tool):
"""Return data of the tool if it matches creator identifier"""

View file

@ -17,7 +17,7 @@ class CreateImageSaver(GenericCreateSaver):
identifier = "io.openpype.creators.fusion.imagesaver"
label = "Image (saver)"
name = "image"
family = "image"
product_type = "image"
description = "Fusion Saver to generate image"
default_frame = 0

View file

@ -12,7 +12,7 @@ class CreateSaver(GenericCreateSaver):
identifier = "io.openpype.creators.fusion.saver"
label = "Render (saver)"
name = "render"
family = "render"
product_type = "render"
description = "Fusion Saver to generate image sequence"
default_frame_range_option = "asset_db"

View file

@ -10,7 +10,7 @@ from ayon_core.pipeline import (
class FusionWorkfileCreator(AutoCreator):
identifier = "workfile"
family = "workfile"
product_type = "workfile"
label = "Workfile"
icon = "fa5.file"
@ -27,9 +27,12 @@ class FusionWorkfileCreator(AutoCreator):
if not data:
return
product_name = data.get("productName")
if product_name is None:
product_name = data["subset"]
instance = CreatedInstance(
family=self.family,
subset_name=data["subset"],
product_type=self.product_type,
product_name=product_name,
data=data,
creator=self
)
@ -59,7 +62,7 @@ class FusionWorkfileCreator(AutoCreator):
existing_instance = None
for instance in self.create_context.instances:
if instance.family == self.family:
if instance.product_type == self.product_type:
existing_instance = instance
break
@ -75,7 +78,7 @@ class FusionWorkfileCreator(AutoCreator):
if existing_instance is None:
asset_doc = get_asset_by_name(project_name, asset_name)
subset_name = self.get_subset_name(
product_name = self.get_product_name(
self.default_variant, task_name, asset_doc,
project_name, host_name
)
@ -90,7 +93,7 @@ class FusionWorkfileCreator(AutoCreator):
))
new_instance = CreatedInstance(
self.family, subset_name, data, self
self.product_type, product_name, data, self
)
new_instance.transient_data["comp"] = comp
self._add_instance_to_context(new_instance)
@ -100,10 +103,10 @@ class FusionWorkfileCreator(AutoCreator):
or existing_instance["task"] != task_name
):
asset_doc = get_asset_by_name(project_name, asset_name)
subset_name = self.get_subset_name(
product_name = self.get_product_name(
self.default_variant, task_name, asset_doc,
project_name, host_name
)
existing_instance["folderPath"] = asset_name
existing_instance["task"] = task_name
existing_instance["subset"] = subset_name
existing_instance["productName"] = product_name

View file

@ -26,7 +26,7 @@ class CollectInstanceData(pyblish.api.InstancePlugin):
instance.data["frame_range_source"] = frame_range_source
# get asset frame ranges to all instances
# render family instances `asset_db` render target
# render product type instances `asset_db` render target
start = context.data["frameStart"]
end = context.data["frameEnd"]
handle_start = context.data["handleStart"]
@ -34,7 +34,7 @@ class CollectInstanceData(pyblish.api.InstancePlugin):
start_with_handle = start - handle_start
end_with_handle = end + handle_end
# conditions for render family instances
# conditions for render product type instances
if frame_range_source == "render_range":
# set comp render frame ranges
start = context.data["renderFrameStart"]
@ -70,11 +70,11 @@ class CollectInstanceData(pyblish.api.InstancePlugin):
end_with_handle = frame
# Include start and end render frame in label
subset = instance.data["subset"]
product_name = instance.data["productName"]
label = (
"{subset} ({start}-{end}) [{handle_start}-{handle_end}]"
"{product_name} ({start}-{end}) [{handle_start}-{handle_end}]"
).format(
subset=subset,
product_name=product_name,
start=int(start),
end=int(end),
handle_start=int(handle_start),

View file

@ -49,17 +49,17 @@ class CollectFusionRender(
if not inst.data.get("active", True):
continue
family = inst.data["family"]
if family not in ["render", "image"]:
product_type = inst.data["productType"]
if product_type not in ["render", "image"]:
continue
task_name = context.data["task"]
tool = inst.data["transientData"]["tool"]
instance_families = inst.data.get("families", [])
subset_name = inst.data["subset"]
product_name = inst.data["productName"]
instance = FusionRenderInstance(
family=family,
productType=product_type,
tool=tool,
workfileComp=comp,
families=instance_families,
@ -67,13 +67,13 @@ class CollectFusionRender(
time="",
source=current_file,
label=inst.data["label"],
subset=subset_name,
productName=product_name,
folderPath=inst.data["folderPath"],
task=task_name,
attachTo=False,
setMembers='',
publish=True,
name=subset_name,
name=product_name,
resolutionWidth=comp_frame_format_prefs.get("Width"),
resolutionHeight=comp_frame_format_prefs.get("Height"),
pixelAspect=aspect_x / aspect_y,

View file

@ -7,7 +7,7 @@ from ayon_core.hosts.fusion.api.action import SelectInvalidAction
class ValidateUniqueSubsets(pyblish.api.ContextPlugin):
"""Ensure all instances have a unique subset name"""
"""Ensure all instances have a unique product name"""
order = pyblish.api.ValidatorOrder
label = "Validate Unique Subsets"
@ -18,27 +18,31 @@ class ValidateUniqueSubsets(pyblish.api.ContextPlugin):
@classmethod
def get_invalid(cls, context):
# Collect instances per subset per asset
instances_per_subset_asset = defaultdict(lambda: defaultdict(list))
# Collect instances per product per folder
instances_per_product_folder = defaultdict(lambda: defaultdict(list))
for instance in context:
asset = instance.data.get(
"folderPath", context.data.get("folderPath")
folder_path = instance.data["folderPath"]
product_name = instance.data["productName"]
instances_per_product_folder[folder_path][product_name].append(
instance
)
subset = instance.data.get("subset", context.data.get("subset"))
instances_per_subset_asset[asset][subset].append(instance)
# Find which asset + subset combination has more than one instance
# Those are considered invalid because they'd integrate to the same
# destination.
invalid = []
for asset, instances_per_subset in instances_per_subset_asset.items():
for subset, instances in instances_per_subset.items():
for folder_path, instances_per_product in (
instances_per_product_folder.items()
):
for product_name, instances in instances_per_product.items():
if len(instances) > 1:
cls.log.warning(
"{asset} > {subset} used by more than "
"one instance: {instances}".format(
asset=asset,
subset=subset,
(
"{folder_path} > {product_name} used by more than "
"one instance: {instances}"
).format(
folder_path=folder_path,
product_name=product_name,
instances=instances
)
)
@ -52,6 +56,7 @@ class ValidateUniqueSubsets(pyblish.api.ContextPlugin):
def process(self, context):
invalid = self.get_invalid(context)
if invalid:
raise PublishValidationError("Multiple instances are set to "
"the same asset > subset.",
title=self.label)
raise PublishValidationError(
"Multiple instances are set to the same folder > product.",
title=self.label
)