mirror of
https://github.com/ynput/ayon-core.git
synced 2025-12-25 05:14:40 +01:00
blender is using product name and type
This commit is contained in:
parent
d19a9cc24c
commit
36129a12bd
38 changed files with 275 additions and 240 deletions
|
|
@ -30,13 +30,13 @@ VALID_EXTENSIONS = [".blend", ".json", ".abc", ".fbx"]
|
|||
|
||||
|
||||
def prepare_scene_name(
|
||||
asset: str, subset: str, namespace: Optional[str] = None
|
||||
folder_name: str, product_name: str, namespace: Optional[str] = None
|
||||
) -> str:
|
||||
"""Return a consistent name for an asset."""
|
||||
name = f"{asset}"
|
||||
name = f"{folder_name}"
|
||||
if namespace:
|
||||
name = f"{name}_{namespace}"
|
||||
name = f"{name}_{subset}"
|
||||
name = f"{name}_{product_name}"
|
||||
|
||||
# Blender name for a collection or object cannot be longer than 63
|
||||
# characters. If the name is longer, it will raise an error.
|
||||
|
|
@ -47,7 +47,7 @@ def prepare_scene_name(
|
|||
|
||||
|
||||
def get_unique_number(
|
||||
asset: str, subset: str
|
||||
folder_name: str, product_name: str
|
||||
) -> str:
|
||||
"""Return a unique number based on the asset name."""
|
||||
avalon_container = bpy.data.collections.get(AVALON_CONTAINERS)
|
||||
|
|
@ -64,10 +64,10 @@ def get_unique_number(
|
|||
if c.get(AVALON_PROPERTY)}
|
||||
container_names = obj_group_names.union(coll_group_names)
|
||||
count = 1
|
||||
name = f"{asset}_{count:0>2}_{subset}"
|
||||
name = f"{folder_name}_{count:0>2}_{product_name}"
|
||||
while name in container_names:
|
||||
count += 1
|
||||
name = f"{asset}_{count:0>2}_{subset}"
|
||||
name = f"{folder_name}_{count:0>2}_{product_name}"
|
||||
return f"{count:0>2}"
|
||||
|
||||
|
||||
|
|
@ -161,24 +161,24 @@ class BaseCreator(Creator):
|
|||
create_as_asset_group = False
|
||||
|
||||
@staticmethod
|
||||
def cache_subsets(shared_data):
|
||||
def cache_instance_data(shared_data):
|
||||
"""Cache instances for Creators shared data.
|
||||
|
||||
Create `blender_cached_subsets` key when needed in shared data and
|
||||
Create `blender_cached_instances` key when needed in shared data and
|
||||
fill it with all collected instances from the scene under its
|
||||
respective creator identifiers.
|
||||
|
||||
If legacy instances are detected in the scene, create
|
||||
`blender_cached_legacy_subsets` key and fill it with
|
||||
all legacy subsets from this family as a value. # key or value?
|
||||
`blender_cached_legacy_instances` key and fill it with
|
||||
all legacy products from this family as a value. # key or value?
|
||||
|
||||
Args:
|
||||
shared_data(Dict[str, Any]): Shared data.
|
||||
|
||||
Return:
|
||||
Dict[str, Any]: Shared data with cached subsets.
|
||||
Dict[str, Any]: Shared data with cached products.
|
||||
"""
|
||||
if not shared_data.get('blender_cached_subsets'):
|
||||
if not shared_data.get('blender_cached_instances'):
|
||||
cache = {}
|
||||
cache_legacy = {}
|
||||
|
||||
|
|
@ -210,19 +210,19 @@ class BaseCreator(Creator):
|
|||
# Legacy creator instance
|
||||
cache_legacy.setdefault(family, []).append(obj_or_col)
|
||||
|
||||
shared_data["blender_cached_subsets"] = cache
|
||||
shared_data["blender_cached_legacy_subsets"] = cache_legacy
|
||||
shared_data["blender_cached_instances"] = cache
|
||||
shared_data["blender_cached_legacy_instances"] = cache_legacy
|
||||
|
||||
return shared_data
|
||||
|
||||
def create(
|
||||
self, subset_name: str, instance_data: dict, pre_create_data: dict
|
||||
self, product_name: str, instance_data: dict, pre_create_data: dict
|
||||
):
|
||||
"""Override abstract method from Creator.
|
||||
Create new instance and store it.
|
||||
|
||||
Args:
|
||||
subset_name(str): Subset name of created instance.
|
||||
product_name(str): Subset name of created instance.
|
||||
instance_data(dict): Instance base data.
|
||||
pre_create_data(dict): Data based on pre creation attributes.
|
||||
Those may affect how creator works.
|
||||
|
|
@ -236,7 +236,7 @@ class BaseCreator(Creator):
|
|||
# Create asset group
|
||||
asset_name = instance_data["folderPath"].split("/")[-1]
|
||||
|
||||
name = prepare_scene_name(asset_name, subset_name)
|
||||
name = prepare_scene_name(asset_name, product_name)
|
||||
if self.create_as_asset_group:
|
||||
# Create instance as empty
|
||||
instance_node = bpy.data.objects.new(name=name, object_data=None)
|
||||
|
|
@ -247,10 +247,10 @@ class BaseCreator(Creator):
|
|||
instance_node = bpy.data.collections.new(name=name)
|
||||
instances.children.link(instance_node)
|
||||
|
||||
self.set_instance_data(subset_name, instance_data)
|
||||
self.set_instance_data(product_name, instance_data)
|
||||
|
||||
instance = CreatedInstance(
|
||||
self.family, subset_name, instance_data, self
|
||||
self.product_type, product_name, instance_data, self
|
||||
)
|
||||
instance.transient_data["instance_node"] = instance_node
|
||||
self._add_instance_to_context(instance)
|
||||
|
|
@ -263,18 +263,18 @@ class BaseCreator(Creator):
|
|||
"""Override abstract method from BaseCreator.
|
||||
Collect existing instances related to this creator plugin."""
|
||||
|
||||
# Cache subsets in shared data
|
||||
self.cache_subsets(self.collection_shared_data)
|
||||
# Cache instances in shared data
|
||||
self.cache_instance_data(self.collection_shared_data)
|
||||
|
||||
# Get cached subsets
|
||||
cached_subsets = self.collection_shared_data.get(
|
||||
"blender_cached_subsets"
|
||||
# Get cached instances
|
||||
cached_instances = self.collection_shared_data.get(
|
||||
"blender_cached_instances"
|
||||
)
|
||||
if not cached_subsets:
|
||||
if not cached_instances:
|
||||
return
|
||||
|
||||
# Process only instances that were created by this creator
|
||||
for instance_node in cached_subsets.get(self.identifier, []):
|
||||
for instance_node in cached_instances.get(self.identifier, []):
|
||||
property = instance_node.get(AVALON_PROPERTY)
|
||||
# Create instance object from existing data
|
||||
instance = CreatedInstance.from_existing(
|
||||
|
|
@ -306,16 +306,17 @@ class BaseCreator(Creator):
|
|||
)
|
||||
return
|
||||
|
||||
# Rename the instance node in the scene if subset or asset changed.
|
||||
# Rename the instance node in the scene if product
|
||||
# or folder changed.
|
||||
# Do not rename the instance if the family is workfile, as the
|
||||
# workfile instance is included in the AVALON_CONTAINER collection.
|
||||
if (
|
||||
"subset" in changes.changed_keys
|
||||
"productName" in changes.changed_keys
|
||||
or "folderPath" in changes.changed_keys
|
||||
) and created_instance.family != "workfile":
|
||||
) and created_instance.product_type != "workfile":
|
||||
asset_name = data["folderPath"].split("/")[-1]
|
||||
name = prepare_scene_name(
|
||||
asset=asset_name, subset=data["subset"]
|
||||
asset_name, data["productName"]
|
||||
)
|
||||
node.name = name
|
||||
|
||||
|
|
@ -341,13 +342,13 @@ class BaseCreator(Creator):
|
|||
|
||||
def set_instance_data(
|
||||
self,
|
||||
subset_name: str,
|
||||
product_name: str,
|
||||
instance_data: dict
|
||||
):
|
||||
"""Fill instance data with required items.
|
||||
|
||||
Args:
|
||||
subset_name(str): Subset name of created instance.
|
||||
product_name(str): Subset name of created instance.
|
||||
instance_data(dict): Instance base data.
|
||||
instance_node(bpy.types.ID): Instance node in blender scene.
|
||||
"""
|
||||
|
|
@ -358,7 +359,7 @@ class BaseCreator(Creator):
|
|||
{
|
||||
"id": AVALON_INSTANCE_ID,
|
||||
"creator_identifier": self.identifier,
|
||||
"subset": subset_name,
|
||||
"productName": product_name,
|
||||
}
|
||||
)
|
||||
|
||||
|
|
@ -466,14 +467,14 @@ class AssetLoader(LoaderPlugin):
|
|||
filepath = self.filepath_from_context(context)
|
||||
assert Path(filepath).exists(), f"{filepath} doesn't exist."
|
||||
|
||||
asset = context["asset"]["name"]
|
||||
subset = context["subset"]["name"]
|
||||
folder_name = context["asset"]["name"]
|
||||
product_name = context["subset"]["name"]
|
||||
unique_number = get_unique_number(
|
||||
asset, subset
|
||||
folder_name, product_name
|
||||
)
|
||||
namespace = namespace or f"{asset}_{unique_number}"
|
||||
namespace = namespace or f"{folder_name}_{unique_number}"
|
||||
name = name or prepare_scene_name(
|
||||
asset, subset, unique_number
|
||||
folder_name, product_name, unique_number
|
||||
)
|
||||
|
||||
nodes = self.process_asset(
|
||||
|
|
@ -499,10 +500,10 @@ class AssetLoader(LoaderPlugin):
|
|||
# loader=self.__class__.__name__,
|
||||
# )
|
||||
|
||||
# asset = context["asset"]["name"]
|
||||
# subset = context["subset"]["name"]
|
||||
# folder_name = context["asset"]["name"]
|
||||
# product_name = context["subset"]["name"]
|
||||
# instance_name = prepare_scene_name(
|
||||
# asset, subset, unique_number
|
||||
# folder_name, product_name, unique_number
|
||||
# ) + '_CON'
|
||||
|
||||
# return self._get_instance_collection(instance_name, nodes)
|
||||
|
|
|
|||
|
|
@ -1,24 +1,24 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
"""Converter for legacy Houdini subsets."""
|
||||
"""Converter for legacy Houdini products."""
|
||||
from ayon_core.pipeline.create.creator_plugins import SubsetConvertorPlugin
|
||||
from ayon_core.hosts.blender.api.lib import imprint
|
||||
|
||||
|
||||
class BlenderLegacyConvertor(SubsetConvertorPlugin):
|
||||
"""Find and convert any legacy subsets in the scene.
|
||||
"""Find and convert any legacy products in the scene.
|
||||
|
||||
This Converter will find all legacy subsets in the scene and will
|
||||
transform them to the current system. Since the old subsets doesn't
|
||||
This Converter will find all legacy products in the scene and will
|
||||
transform them to the current system. Since the old products doesn't
|
||||
retain any information about their original creators, the only mapping
|
||||
we can do is based on their families.
|
||||
we can do is based on their product types.
|
||||
|
||||
Its limitation is that you can have multiple creators creating subset
|
||||
of the same family and there is no way to handle it. This code should
|
||||
nevertheless cover all creators that came with OpenPype.
|
||||
Its limitation is that you can have multiple creators creating product
|
||||
of the same product type and there is no way to handle it. This code
|
||||
should nevertheless cover all creators that came with OpenPype.
|
||||
|
||||
"""
|
||||
identifier = "io.openpype.creators.blender.legacy"
|
||||
family_to_id = {
|
||||
product_type_to_id = {
|
||||
"action": "io.openpype.creators.blender.action",
|
||||
"camera": "io.openpype.creators.blender.camera",
|
||||
"animation": "io.openpype.creators.blender.animation",
|
||||
|
|
@ -33,42 +33,42 @@ class BlenderLegacyConvertor(SubsetConvertorPlugin):
|
|||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(BlenderLegacyConvertor, self).__init__(*args, **kwargs)
|
||||
self.legacy_subsets = {}
|
||||
self.legacy_instances = {}
|
||||
|
||||
def find_instances(self):
|
||||
"""Find legacy subsets in the scene.
|
||||
"""Find legacy products in the scene.
|
||||
|
||||
Legacy subsets are the ones that doesn't have `creator_identifier`
|
||||
Legacy products are the ones that doesn't have `creator_identifier`
|
||||
parameter on them.
|
||||
|
||||
This is using cached entries done in
|
||||
:py:meth:`~BaseCreator.cache_subsets()`
|
||||
:py:meth:`~BaseCreator.cache_instance_data()`
|
||||
|
||||
"""
|
||||
self.legacy_subsets = self.collection_shared_data.get(
|
||||
"blender_cached_legacy_subsets")
|
||||
if not self.legacy_subsets:
|
||||
self.legacy_instances = self.collection_shared_data.get(
|
||||
"blender_cached_legacy_instances")
|
||||
if not self.legacy_instances:
|
||||
return
|
||||
self.add_convertor_item(
|
||||
"Found {} incompatible subset{}".format(
|
||||
len(self.legacy_subsets),
|
||||
"s" if len(self.legacy_subsets) > 1 else ""
|
||||
"Found {} incompatible product{}".format(
|
||||
len(self.legacy_instances),
|
||||
"s" if len(self.legacy_instances) > 1 else ""
|
||||
)
|
||||
)
|
||||
|
||||
def convert(self):
|
||||
"""Convert all legacy subsets to current.
|
||||
"""Convert all legacy products to current.
|
||||
|
||||
It is enough to add `creator_identifier` and `instance_node`.
|
||||
|
||||
"""
|
||||
if not self.legacy_subsets:
|
||||
if not self.legacy_instances:
|
||||
return
|
||||
|
||||
for family, instance_nodes in self.legacy_subsets.items():
|
||||
if family in self.family_to_id:
|
||||
for product_type, instance_nodes in self.legacy_instances.items():
|
||||
if product_type in self.product_type_to_id:
|
||||
for instance_node in instance_nodes:
|
||||
creator_identifier = self.family_to_id[family]
|
||||
creator_identifier = self.product_type_to_id[product_type]
|
||||
self.log.info(
|
||||
"Converting {} to {}".format(instance_node.name,
|
||||
creator_identifier)
|
||||
|
|
|
|||
|
|
@ -10,20 +10,20 @@ class CreateAction(plugin.BaseCreator):
|
|||
|
||||
identifier = "io.openpype.creators.blender.action"
|
||||
label = "Action"
|
||||
family = "action"
|
||||
product_type = "action"
|
||||
icon = "male"
|
||||
|
||||
def create(
|
||||
self, subset_name: str, instance_data: dict, pre_create_data: dict
|
||||
self, product_name: str, instance_data: dict, pre_create_data: dict
|
||||
):
|
||||
# Run parent create method
|
||||
collection = super().create(
|
||||
subset_name, instance_data, pre_create_data
|
||||
product_name, instance_data, pre_create_data
|
||||
)
|
||||
|
||||
# Get instance name
|
||||
name = plugin.prepare_scene_name(
|
||||
instance_data["folderPath"], subset_name
|
||||
instance_data["folderPath"], product_name
|
||||
)
|
||||
|
||||
if pre_create_data.get("use_selection"):
|
||||
|
|
|
|||
|
|
@ -8,15 +8,15 @@ class CreateAnimation(plugin.BaseCreator):
|
|||
|
||||
identifier = "io.openpype.creators.blender.animation"
|
||||
label = "Animation"
|
||||
family = "animation"
|
||||
product_type = "animation"
|
||||
icon = "male"
|
||||
|
||||
def create(
|
||||
self, subset_name: str, instance_data: dict, pre_create_data: dict
|
||||
self, product_name: str, instance_data: dict, pre_create_data: dict
|
||||
):
|
||||
# Run parent create method
|
||||
collection = super().create(
|
||||
subset_name, instance_data, pre_create_data
|
||||
product_name, instance_data, pre_create_data
|
||||
)
|
||||
|
||||
if pre_create_data.get("use_selection"):
|
||||
|
|
|
|||
|
|
@ -10,16 +10,16 @@ class CreateBlendScene(plugin.BaseCreator):
|
|||
|
||||
identifier = "io.openpype.creators.blender.blendscene"
|
||||
label = "Blender Scene"
|
||||
family = "blendScene"
|
||||
product_type = "blendScene"
|
||||
icon = "cubes"
|
||||
|
||||
maintain_selection = False
|
||||
|
||||
def create(
|
||||
self, subset_name: str, instance_data: dict, pre_create_data: dict
|
||||
self, product_name: str, instance_data: dict, pre_create_data: dict
|
||||
):
|
||||
|
||||
instance_node = super().create(subset_name,
|
||||
instance_node = super().create(product_name,
|
||||
instance_data,
|
||||
pre_create_data)
|
||||
|
||||
|
|
|
|||
|
|
@ -11,16 +11,16 @@ class CreateCamera(plugin.BaseCreator):
|
|||
|
||||
identifier = "io.openpype.creators.blender.camera"
|
||||
label = "Camera"
|
||||
family = "camera"
|
||||
product_type = "camera"
|
||||
icon = "video-camera"
|
||||
|
||||
create_as_asset_group = True
|
||||
|
||||
def create(
|
||||
self, subset_name: str, instance_data: dict, pre_create_data: dict
|
||||
self, product_name: str, instance_data: dict, pre_create_data: dict
|
||||
):
|
||||
|
||||
asset_group = super().create(subset_name,
|
||||
asset_group = super().create(product_name,
|
||||
instance_data,
|
||||
pre_create_data)
|
||||
|
||||
|
|
@ -30,8 +30,8 @@ class CreateCamera(plugin.BaseCreator):
|
|||
obj.parent = asset_group
|
||||
else:
|
||||
plugin.deselect_all()
|
||||
camera = bpy.data.cameras.new(subset_name)
|
||||
camera_obj = bpy.data.objects.new(subset_name, camera)
|
||||
camera = bpy.data.cameras.new(product_name)
|
||||
camera_obj = bpy.data.objects.new(product_name, camera)
|
||||
|
||||
instances = bpy.data.collections.get(AVALON_INSTANCES)
|
||||
instances.objects.link(camera_obj)
|
||||
|
|
|
|||
|
|
@ -10,16 +10,16 @@ class CreateLayout(plugin.BaseCreator):
|
|||
|
||||
identifier = "io.openpype.creators.blender.layout"
|
||||
label = "Layout"
|
||||
family = "layout"
|
||||
product_type = "layout"
|
||||
icon = "cubes"
|
||||
|
||||
create_as_asset_group = True
|
||||
|
||||
def create(
|
||||
self, subset_name: str, instance_data: dict, pre_create_data: dict
|
||||
self, product_name: str, instance_data: dict, pre_create_data: dict
|
||||
):
|
||||
|
||||
asset_group = super().create(subset_name,
|
||||
asset_group = super().create(product_name,
|
||||
instance_data,
|
||||
pre_create_data)
|
||||
|
||||
|
|
|
|||
|
|
@ -10,15 +10,15 @@ class CreateModel(plugin.BaseCreator):
|
|||
|
||||
identifier = "io.openpype.creators.blender.model"
|
||||
label = "Model"
|
||||
family = "model"
|
||||
product_type = "model"
|
||||
icon = "cube"
|
||||
|
||||
create_as_asset_group = True
|
||||
|
||||
def create(
|
||||
self, subset_name: str, instance_data: dict, pre_create_data: dict
|
||||
self, product_name: str, instance_data: dict, pre_create_data: dict
|
||||
):
|
||||
asset_group = super().create(subset_name,
|
||||
asset_group = super().create(product_name,
|
||||
instance_data,
|
||||
pre_create_data)
|
||||
|
||||
|
|
|
|||
|
|
@ -8,15 +8,15 @@ class CreatePointcache(plugin.BaseCreator):
|
|||
|
||||
identifier = "io.openpype.creators.blender.pointcache"
|
||||
label = "Point Cache"
|
||||
family = "pointcache"
|
||||
product_type = "pointcache"
|
||||
icon = "gears"
|
||||
|
||||
def create(
|
||||
self, subset_name: str, instance_data: dict, pre_create_data: dict
|
||||
self, product_name: str, instance_data: dict, pre_create_data: dict
|
||||
):
|
||||
# Run parent create method
|
||||
collection = super().create(
|
||||
subset_name, instance_data, pre_create_data
|
||||
product_name, instance_data, pre_create_data
|
||||
)
|
||||
|
||||
if pre_create_data.get("use_selection"):
|
||||
|
|
|
|||
|
|
@ -12,16 +12,16 @@ class CreateRenderlayer(plugin.BaseCreator):
|
|||
|
||||
identifier = "io.openpype.creators.blender.render"
|
||||
label = "Render"
|
||||
family = "render"
|
||||
product_type = "render"
|
||||
icon = "eye"
|
||||
|
||||
def create(
|
||||
self, subset_name: str, instance_data: dict, pre_create_data: dict
|
||||
self, product_name: str, instance_data: dict, pre_create_data: dict
|
||||
):
|
||||
try:
|
||||
# Run parent create method
|
||||
collection = super().create(
|
||||
subset_name, instance_data, pre_create_data
|
||||
product_name, instance_data, pre_create_data
|
||||
)
|
||||
|
||||
prepare_rendering(collection)
|
||||
|
|
|
|||
|
|
@ -8,15 +8,15 @@ class CreateReview(plugin.BaseCreator):
|
|||
|
||||
identifier = "io.openpype.creators.blender.review"
|
||||
label = "Review"
|
||||
family = "review"
|
||||
product_type = "review"
|
||||
icon = "video-camera"
|
||||
|
||||
def create(
|
||||
self, subset_name: str, instance_data: dict, pre_create_data: dict
|
||||
self, product_name: str, instance_data: dict, pre_create_data: dict
|
||||
):
|
||||
# Run parent create method
|
||||
collection = super().create(
|
||||
subset_name, instance_data, pre_create_data
|
||||
product_name, instance_data, pre_create_data
|
||||
)
|
||||
|
||||
if pre_create_data.get("use_selection"):
|
||||
|
|
|
|||
|
|
@ -10,15 +10,15 @@ class CreateRig(plugin.BaseCreator):
|
|||
|
||||
identifier = "io.openpype.creators.blender.rig"
|
||||
label = "Rig"
|
||||
family = "rig"
|
||||
product_type = "rig"
|
||||
icon = "wheelchair"
|
||||
|
||||
create_as_asset_group = True
|
||||
|
||||
def create(
|
||||
self, subset_name: str, instance_data: dict, pre_create_data: dict
|
||||
self, product_name: str, instance_data: dict, pre_create_data: dict
|
||||
):
|
||||
asset_group = super().create(subset_name,
|
||||
asset_group = super().create(product_name,
|
||||
instance_data,
|
||||
pre_create_data)
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ class CreateWorkfile(BaseCreator, AutoCreator):
|
|||
"""
|
||||
identifier = "io.openpype.creators.blender.workfile"
|
||||
label = "Workfile"
|
||||
family = "workfile"
|
||||
product_type = "workfile"
|
||||
icon = "fa5.file"
|
||||
|
||||
def create(self):
|
||||
|
|
@ -43,7 +43,7 @@ class CreateWorkfile(BaseCreator, AutoCreator):
|
|||
|
||||
if not workfile_instance:
|
||||
asset_doc = get_asset_by_name(project_name, asset_name)
|
||||
subset_name = self.get_subset_name(
|
||||
product_name = self.get_product_name(
|
||||
task_name, task_name, asset_doc, project_name, host_name
|
||||
)
|
||||
data = {
|
||||
|
|
@ -63,7 +63,7 @@ class CreateWorkfile(BaseCreator, AutoCreator):
|
|||
)
|
||||
self.log.info("Auto-creating workfile instance...")
|
||||
workfile_instance = CreatedInstance(
|
||||
self.family, subset_name, data, self
|
||||
self.product_type, product_name, data, self
|
||||
)
|
||||
self._add_instance_to_context(workfile_instance)
|
||||
|
||||
|
|
@ -73,13 +73,13 @@ class CreateWorkfile(BaseCreator, AutoCreator):
|
|||
):
|
||||
# Update instance context if it's different
|
||||
asset_doc = get_asset_by_name(project_name, asset_name)
|
||||
subset_name = self.get_subset_name(
|
||||
product_name = self.get_product_name(
|
||||
task_name, task_name, asset_doc, project_name, host_name
|
||||
)
|
||||
|
||||
workfile_instance["folderPath"] = asset_name
|
||||
workfile_instance["task"] = task_name
|
||||
workfile_instance["subset"] = subset_name
|
||||
workfile_instance["productName"] = product_name
|
||||
|
||||
instance_node = bpy.data.collections.get(AVALON_CONTAINERS)
|
||||
if not instance_node:
|
||||
|
|
|
|||
|
|
@ -4,10 +4,10 @@ from ayon_core.hosts.blender.api import plugin
|
|||
|
||||
|
||||
def append_workfile(context, fname, do_import):
|
||||
asset = context['asset']['name']
|
||||
subset = context['subset']['name']
|
||||
folder_name = context['asset']['name']
|
||||
product_name = context['subset']['name']
|
||||
|
||||
group_name = plugin.prepare_scene_name(asset, subset)
|
||||
group_name = plugin.prepare_scene_name(folder_name, product_name)
|
||||
|
||||
# We need to preserve the original names of the scenes, otherwise,
|
||||
# if there are duplicate names in the current workfile, the imported
|
||||
|
|
|
|||
|
|
@ -134,13 +134,15 @@ class CacheModelLoader(plugin.AssetLoader):
|
|||
"""
|
||||
|
||||
libpath = self.filepath_from_context(context)
|
||||
asset = context["asset"]["name"]
|
||||
subset = context["subset"]["name"]
|
||||
folder_name = context["asset"]["name"]
|
||||
product_name = context["subset"]["name"]
|
||||
|
||||
asset_name = plugin.prepare_scene_name(asset, subset)
|
||||
unique_number = plugin.get_unique_number(asset, subset)
|
||||
group_name = plugin.prepare_scene_name(asset, subset, unique_number)
|
||||
namespace = namespace or f"{asset}_{unique_number}"
|
||||
asset_name = plugin.prepare_scene_name(folder_name, product_name)
|
||||
unique_number = plugin.get_unique_number(folder_name, product_name)
|
||||
group_name = plugin.prepare_scene_name(
|
||||
folder_name, product_name, unique_number
|
||||
)
|
||||
namespace = namespace or f"{folder_name}_{unique_number}"
|
||||
|
||||
containers = bpy.data.collections.get(AVALON_CONTAINERS)
|
||||
if not containers:
|
||||
|
|
@ -159,6 +161,7 @@ class CacheModelLoader(plugin.AssetLoader):
|
|||
|
||||
self._link_objects(objects, asset_group, containers, asset_group)
|
||||
|
||||
product_type = context["subset"]["data"]["family"]
|
||||
asset_group[AVALON_PROPERTY] = {
|
||||
"schema": "openpype:container-2.0",
|
||||
"id": AVALON_CONTAINER_ID,
|
||||
|
|
@ -169,7 +172,7 @@ class CacheModelLoader(plugin.AssetLoader):
|
|||
"libpath": libpath,
|
||||
"asset_name": asset_name,
|
||||
"parent": str(context["representation"]["parent"]),
|
||||
"family": context["representation"]["context"]["family"],
|
||||
"productType": product_type,
|
||||
"objectName": group_name
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -44,11 +44,11 @@ class BlendActionLoader(plugin.AssetLoader):
|
|||
"""
|
||||
|
||||
libpath = self.filepath_from_context(context)
|
||||
asset = context["asset"]["name"]
|
||||
subset = context["subset"]["name"]
|
||||
lib_container = plugin.prepare_scene_name(asset, subset)
|
||||
folder_name = context["asset"]["name"]
|
||||
product_name = context["subset"]["name"]
|
||||
lib_container = plugin.prepare_scene_name(folder_name, product_name)
|
||||
container_name = plugin.prepare_scene_name(
|
||||
asset, subset, namespace
|
||||
folder_name, product_name, namespace
|
||||
)
|
||||
|
||||
container = bpy.data.collections.new(lib_container)
|
||||
|
|
|
|||
|
|
@ -39,13 +39,15 @@ class AudioLoader(plugin.AssetLoader):
|
|||
options: Additional settings dictionary
|
||||
"""
|
||||
libpath = self.filepath_from_context(context)
|
||||
asset = context["asset"]["name"]
|
||||
subset = context["subset"]["name"]
|
||||
folder_name = context["asset"]["name"]
|
||||
product_name = context["subset"]["name"]
|
||||
|
||||
asset_name = plugin.prepare_scene_name(asset, subset)
|
||||
unique_number = plugin.get_unique_number(asset, subset)
|
||||
group_name = plugin.prepare_scene_name(asset, subset, unique_number)
|
||||
namespace = namespace or f"{asset}_{unique_number}"
|
||||
asset_name = plugin.prepare_scene_name(folder_name, product_name)
|
||||
unique_number = plugin.get_unique_number(folder_name, product_name)
|
||||
group_name = plugin.prepare_scene_name(
|
||||
folder_name, product_name, unique_number
|
||||
)
|
||||
namespace = namespace or f"{folder_name}_{unique_number}"
|
||||
|
||||
avalon_container = bpy.data.collections.get(AVALON_CONTAINERS)
|
||||
if not avalon_container:
|
||||
|
|
@ -85,7 +87,7 @@ class AudioLoader(plugin.AssetLoader):
|
|||
"libpath": libpath,
|
||||
"asset_name": asset_name,
|
||||
"parent": str(context["representation"]["parent"]),
|
||||
"family": context["representation"]["context"]["family"],
|
||||
"productType": context["subset"]["data"]["family"],
|
||||
"objectName": group_name,
|
||||
"audio": audio
|
||||
}
|
||||
|
|
|
|||
|
|
@ -127,20 +127,22 @@ class BlendLoader(plugin.AssetLoader):
|
|||
options: Additional settings dictionary
|
||||
"""
|
||||
libpath = self.filepath_from_context(context)
|
||||
asset = context["asset"]["name"]
|
||||
subset = context["subset"]["name"]
|
||||
folder_name = context["asset"]["name"]
|
||||
product_name = context["subset"]["name"]
|
||||
|
||||
try:
|
||||
family = context["representation"]["context"]["family"]
|
||||
product_type = context["subset"]["data"]["family"]
|
||||
except ValueError:
|
||||
family = "model"
|
||||
product_type = "model"
|
||||
|
||||
representation = str(context["representation"]["_id"])
|
||||
|
||||
asset_name = plugin.prepare_scene_name(asset, subset)
|
||||
unique_number = plugin.get_unique_number(asset, subset)
|
||||
group_name = plugin.prepare_scene_name(asset, subset, unique_number)
|
||||
namespace = namespace or f"{asset}_{unique_number}"
|
||||
asset_name = plugin.prepare_scene_name(folder_name, product_name)
|
||||
unique_number = plugin.get_unique_number(folder_name, product_name)
|
||||
group_name = plugin.prepare_scene_name(
|
||||
folder_name, product_name, unique_number
|
||||
)
|
||||
namespace = namespace or f"{folder_name}_{unique_number}"
|
||||
|
||||
avalon_container = bpy.data.collections.get(AVALON_CONTAINERS)
|
||||
if not avalon_container:
|
||||
|
|
@ -149,8 +151,8 @@ class BlendLoader(plugin.AssetLoader):
|
|||
|
||||
container, members = self._process_data(libpath, group_name)
|
||||
|
||||
if family == "layout":
|
||||
self._post_process_layout(container, asset, representation)
|
||||
if product_type == "layout":
|
||||
self._post_process_layout(container, folder_name, representation)
|
||||
|
||||
avalon_container.objects.link(container)
|
||||
|
||||
|
|
@ -164,7 +166,7 @@ class BlendLoader(plugin.AssetLoader):
|
|||
"libpath": libpath,
|
||||
"asset_name": asset_name,
|
||||
"parent": str(context["representation"]["parent"]),
|
||||
"family": context["representation"]["context"]["family"],
|
||||
"productType": context["subset"]["data"]["family"],
|
||||
"objectName": group_name,
|
||||
"members": members,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ class BlendSceneLoader(plugin.AssetLoader):
|
|||
|
||||
return None
|
||||
|
||||
def _process_data(self, libpath, group_name, family):
|
||||
def _process_data(self, libpath, group_name, product_type):
|
||||
# Append all the data from the .blend file
|
||||
with bpy.data.libraries.load(
|
||||
libpath, link=False, relative=False
|
||||
|
|
@ -82,25 +82,29 @@ class BlendSceneLoader(plugin.AssetLoader):
|
|||
options: Additional settings dictionary
|
||||
"""
|
||||
libpath = self.filepath_from_context(context)
|
||||
asset = context["asset"]["name"]
|
||||
subset = context["subset"]["name"]
|
||||
folder_name = context["asset"]["name"]
|
||||
product_name = context["subset"]["name"]
|
||||
|
||||
try:
|
||||
family = context["representation"]["context"]["family"]
|
||||
product_type = context["subset"]["data"]["family"]
|
||||
except ValueError:
|
||||
family = "model"
|
||||
product_type = "model"
|
||||
|
||||
asset_name = plugin.prepare_scene_name(asset, subset)
|
||||
unique_number = plugin.get_unique_number(asset, subset)
|
||||
group_name = plugin.prepare_scene_name(asset, subset, unique_number)
|
||||
namespace = namespace or f"{asset}_{unique_number}"
|
||||
asset_name = plugin.prepare_scene_name(folder_name, product_name)
|
||||
unique_number = plugin.get_unique_number(folder_name, product_name)
|
||||
group_name = plugin.prepare_scene_name(
|
||||
folder_name, product_name, unique_number
|
||||
)
|
||||
namespace = namespace or f"{folder_name}_{unique_number}"
|
||||
|
||||
avalon_container = bpy.data.collections.get(AVALON_CONTAINERS)
|
||||
if not avalon_container:
|
||||
avalon_container = bpy.data.collections.new(name=AVALON_CONTAINERS)
|
||||
bpy.context.scene.collection.children.link(avalon_container)
|
||||
|
||||
container, members = self._process_data(libpath, group_name, family)
|
||||
container, members = self._process_data(
|
||||
libpath, group_name, product_type
|
||||
)
|
||||
|
||||
avalon_container.children.link(container)
|
||||
|
||||
|
|
@ -114,7 +118,7 @@ class BlendSceneLoader(plugin.AssetLoader):
|
|||
"libpath": libpath,
|
||||
"asset_name": asset_name,
|
||||
"parent": str(context["representation"]["parent"]),
|
||||
"family": context["representation"]["context"]["family"],
|
||||
"productType": context["subset"]["data"]["family"],
|
||||
"objectName": group_name,
|
||||
"members": members,
|
||||
}
|
||||
|
|
@ -167,8 +171,12 @@ class BlendSceneLoader(plugin.AssetLoader):
|
|||
|
||||
self.exec_remove(container)
|
||||
|
||||
family = container["family"]
|
||||
asset_group, members = self._process_data(libpath, group_name, family)
|
||||
product_type = container.get("productType")
|
||||
if product_type is None:
|
||||
product_type = container["family"]
|
||||
asset_group, members = self._process_data(
|
||||
libpath, group_name, product_type
|
||||
)
|
||||
|
||||
for member in members:
|
||||
if member.name in collection_parents:
|
||||
|
|
|
|||
|
|
@ -84,13 +84,15 @@ class AbcCameraLoader(plugin.AssetLoader):
|
|||
|
||||
libpath = self.filepath_from_context(context)
|
||||
|
||||
asset = context["asset"]["name"]
|
||||
subset = context["subset"]["name"]
|
||||
folder_name = context["asset"]["name"]
|
||||
product_name = context["subset"]["name"]
|
||||
|
||||
asset_name = plugin.prepare_scene_name(asset, subset)
|
||||
unique_number = plugin.get_unique_number(asset, subset)
|
||||
group_name = plugin.prepare_scene_name(asset, subset, unique_number)
|
||||
namespace = namespace or f"{asset}_{unique_number}"
|
||||
asset_name = plugin.prepare_scene_name(folder_name, product_name)
|
||||
unique_number = plugin.get_unique_number(folder_name, product_name)
|
||||
group_name = plugin.prepare_scene_name(
|
||||
folder_name, product_name, unique_number
|
||||
)
|
||||
namespace = namespace or f"{folder_name}_{unique_number}"
|
||||
|
||||
avalon_container = bpy.data.collections.get(AVALON_CONTAINERS)
|
||||
if not avalon_container:
|
||||
|
|
@ -121,7 +123,7 @@ class AbcCameraLoader(plugin.AssetLoader):
|
|||
"libpath": libpath,
|
||||
"asset_name": asset_name,
|
||||
"parent": str(context["representation"]["parent"]),
|
||||
"family": context["representation"]["context"]["family"],
|
||||
"productType": context["subset"]["data"]["family"],
|
||||
"objectName": group_name,
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -87,13 +87,15 @@ class FbxCameraLoader(plugin.AssetLoader):
|
|||
options: Additional settings dictionary
|
||||
"""
|
||||
libpath = self.filepath_from_context(context)
|
||||
asset = context["asset"]["name"]
|
||||
subset = context["subset"]["name"]
|
||||
folder_name = context["asset"]["name"]
|
||||
product_name = context["subset"]["name"]
|
||||
|
||||
asset_name = plugin.prepare_scene_name(asset, subset)
|
||||
unique_number = plugin.get_unique_number(asset, subset)
|
||||
group_name = plugin.prepare_scene_name(asset, subset, unique_number)
|
||||
namespace = namespace or f"{asset}_{unique_number}"
|
||||
asset_name = plugin.prepare_scene_name(folder_name, product_name)
|
||||
unique_number = plugin.get_unique_number(folder_name, product_name)
|
||||
group_name = plugin.prepare_scene_name(
|
||||
folder_name, product_name, unique_number
|
||||
)
|
||||
namespace = namespace or f"{folder_name}_{unique_number}"
|
||||
|
||||
avalon_container = bpy.data.collections.get(AVALON_CONTAINERS)
|
||||
if not avalon_container:
|
||||
|
|
@ -124,7 +126,7 @@ class FbxCameraLoader(plugin.AssetLoader):
|
|||
"libpath": libpath,
|
||||
"asset_name": asset_name,
|
||||
"parent": str(context["representation"]["parent"]),
|
||||
"family": context["representation"]["context"]["family"],
|
||||
"productType": context["subset"]["data"]["family"],
|
||||
"objectName": group_name
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -131,13 +131,15 @@ class FbxModelLoader(plugin.AssetLoader):
|
|||
options: Additional settings dictionary
|
||||
"""
|
||||
libpath = self.filepath_from_context(context)
|
||||
asset = context["asset"]["name"]
|
||||
subset = context["subset"]["name"]
|
||||
folder_name = context["asset"]["name"]
|
||||
product_name = context["subset"]["name"]
|
||||
|
||||
asset_name = plugin.prepare_scene_name(asset, subset)
|
||||
unique_number = plugin.get_unique_number(asset, subset)
|
||||
group_name = plugin.prepare_scene_name(asset, subset, unique_number)
|
||||
namespace = namespace or f"{asset}_{unique_number}"
|
||||
asset_name = plugin.prepare_scene_name(folder_name, product_name)
|
||||
unique_number = plugin.get_unique_number(folder_name, product_name)
|
||||
group_name = plugin.prepare_scene_name(
|
||||
folder_name, product_name, unique_number
|
||||
)
|
||||
namespace = namespace or f"{folder_name}_{unique_number}"
|
||||
|
||||
avalon_container = bpy.data.collections.get(AVALON_CONTAINERS)
|
||||
if not avalon_container:
|
||||
|
|
@ -168,7 +170,7 @@ class FbxModelLoader(plugin.AssetLoader):
|
|||
"libpath": libpath,
|
||||
"asset_name": asset_name,
|
||||
"parent": str(context["representation"]["parent"]),
|
||||
"family": context["representation"]["context"]["family"],
|
||||
"productType": context["subset"]["data"]["family"],
|
||||
"objectName": group_name
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -50,11 +50,11 @@ class JsonLayoutLoader(plugin.AssetLoader):
|
|||
if anim_collection:
|
||||
bpy.data.collections.remove(anim_collection)
|
||||
|
||||
def _get_loader(self, loaders, family):
|
||||
def _get_loader(self, loaders, product_type):
|
||||
name = ""
|
||||
if family == 'rig':
|
||||
if product_type == 'rig':
|
||||
name = "BlendRigLoader"
|
||||
elif family == 'model':
|
||||
elif product_type == 'model':
|
||||
name = "BlendModelLoader"
|
||||
|
||||
if name == "":
|
||||
|
|
@ -76,10 +76,12 @@ class JsonLayoutLoader(plugin.AssetLoader):
|
|||
|
||||
for element in data:
|
||||
reference = element.get('reference')
|
||||
family = element.get('family')
|
||||
product_type = element.get("product_type")
|
||||
if product_type is None:
|
||||
product_type = element.get("family")
|
||||
|
||||
loaders = loaders_from_representation(all_loaders, reference)
|
||||
loader = self._get_loader(loaders, family)
|
||||
loader = self._get_loader(loaders, product_type)
|
||||
|
||||
if not loader:
|
||||
continue
|
||||
|
|
@ -95,7 +97,7 @@ class JsonLayoutLoader(plugin.AssetLoader):
|
|||
'parent': asset_group,
|
||||
'transform': element.get('transform'),
|
||||
'action': action,
|
||||
'create_animation': True if family == 'rig' else False,
|
||||
'create_animation': True if product_type == 'rig' else False,
|
||||
'animation_asset': asset
|
||||
}
|
||||
|
||||
|
|
@ -127,7 +129,7 @@ class JsonLayoutLoader(plugin.AssetLoader):
|
|||
# legacy_create(
|
||||
# creator_plugin,
|
||||
# name="camera",
|
||||
# # name=f"{unique_number}_{subset}_animation",
|
||||
# # name=f"{unique_number}_{product[name]}_animation",
|
||||
# asset=asset,
|
||||
# options={"useSelection": False}
|
||||
# # data={"dependencies": str(context["representation"]["_id"])}
|
||||
|
|
@ -146,13 +148,15 @@ class JsonLayoutLoader(plugin.AssetLoader):
|
|||
options: Additional settings dictionary
|
||||
"""
|
||||
libpath = self.filepath_from_context(context)
|
||||
asset = context["asset"]["name"]
|
||||
subset = context["subset"]["name"]
|
||||
folder_name = context["asset"]["name"]
|
||||
product_name = context["subset"]["name"]
|
||||
|
||||
asset_name = plugin.prepare_scene_name(asset, subset)
|
||||
unique_number = plugin.get_unique_number(asset, subset)
|
||||
group_name = plugin.prepare_scene_name(asset, subset, unique_number)
|
||||
namespace = namespace or f"{asset}_{unique_number}"
|
||||
asset_name = plugin.prepare_scene_name(folder_name, product_name)
|
||||
unique_number = plugin.get_unique_number(folder_name, product_name)
|
||||
group_name = plugin.prepare_scene_name(
|
||||
folder_name, product_name, unique_number
|
||||
)
|
||||
namespace = namespace or f"{folder_name}_{unique_number}"
|
||||
|
||||
avalon_container = bpy.data.collections.get(AVALON_CONTAINERS)
|
||||
if not avalon_container:
|
||||
|
|
@ -177,7 +181,7 @@ class JsonLayoutLoader(plugin.AssetLoader):
|
|||
"libpath": libpath,
|
||||
"asset_name": asset_name,
|
||||
"parent": str(context["representation"]["parent"]),
|
||||
"family": context["representation"]["context"]["family"],
|
||||
"productType": context["subset"]["data"]["family"],
|
||||
"objectName": group_name
|
||||
}
|
||||
|
||||
|
|
@ -239,7 +243,10 @@ class JsonLayoutLoader(plugin.AssetLoader):
|
|||
|
||||
for obj in asset_group.children:
|
||||
obj_meta = obj.get(AVALON_PROPERTY)
|
||||
if obj_meta.get('family') == 'rig':
|
||||
product_type = obj_meta.get("productType")
|
||||
if product_type is None:
|
||||
product_type = obj_meta.get("family")
|
||||
if product_type == "rig":
|
||||
rig = None
|
||||
for child in obj.children:
|
||||
if child.type == 'ARMATURE':
|
||||
|
|
|
|||
|
|
@ -93,18 +93,18 @@ class BlendLookLoader(plugin.AssetLoader):
|
|||
"""
|
||||
|
||||
libpath = self.filepath_from_context(context)
|
||||
asset = context["asset"]["name"]
|
||||
subset = context["subset"]["name"]
|
||||
folder_name = context["asset"]["name"]
|
||||
product_name = context["subset"]["name"]
|
||||
|
||||
lib_container = plugin.prepare_scene_name(
|
||||
asset, subset
|
||||
folder_name, product_name
|
||||
)
|
||||
unique_number = plugin.get_unique_number(
|
||||
asset, subset
|
||||
folder_name, product_name
|
||||
)
|
||||
namespace = namespace or f"{asset}_{unique_number}"
|
||||
namespace = namespace or f"{folder_name}_{unique_number}"
|
||||
container_name = plugin.prepare_scene_name(
|
||||
asset, subset, unique_number
|
||||
folder_name, product_name, unique_number
|
||||
)
|
||||
|
||||
container = bpy.data.collections.new(lib_container)
|
||||
|
|
@ -131,7 +131,7 @@ class BlendLookLoader(plugin.AssetLoader):
|
|||
metadata["materials"] = materials
|
||||
|
||||
metadata["parent"] = str(context["representation"]["parent"])
|
||||
metadata["family"] = context["representation"]["context"]["family"]
|
||||
metadata["product_type"] = context["subset"]["data"]["family"]
|
||||
|
||||
nodes = list(container.objects)
|
||||
nodes.append(container)
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ class CollectBlenderInstanceData(pyblish.api.InstancePlugin):
|
|||
members.extend(instance_node.children)
|
||||
|
||||
# Special case for animation instances, include armatures
|
||||
if instance.data["family"] == "animation":
|
||||
if instance.data["productType"] == "animation":
|
||||
for obj in instance_node.objects:
|
||||
if obj.type == 'EMPTY' and obj.get(AVALON_PROPERTY):
|
||||
members.extend(
|
||||
|
|
|
|||
|
|
@ -19,9 +19,9 @@ class ExtractABC(publish.Extractor, publish.OptionalPyblishPluginMixin):
|
|||
|
||||
# Define extract output file path
|
||||
stagingdir = self.staging_dir(instance)
|
||||
asset_name = instance.data["assetEntity"]["name"]
|
||||
subset = instance.data["subset"]
|
||||
instance_name = f"{asset_name}_{subset}"
|
||||
folder_name = instance.data["assetEntity"]["name"]
|
||||
product_name = instance.data["productName"]
|
||||
instance_name = f"{folder_name}_{product_name}"
|
||||
filename = f"{instance_name}.abc"
|
||||
filepath = os.path.join(stagingdir, filename)
|
||||
|
||||
|
|
|
|||
|
|
@ -23,9 +23,9 @@ class ExtractAnimationABC(
|
|||
|
||||
# Define extract output file path
|
||||
stagingdir = self.staging_dir(instance)
|
||||
asset_name = instance.data["assetEntity"]["name"]
|
||||
subset = instance.data["subset"]
|
||||
instance_name = f"{asset_name}_{subset}"
|
||||
folder_name = instance.data["assetEntity"]["name"]
|
||||
product_name = instance.data["prouctName"]
|
||||
instance_name = f"{folder_name}_{product_name}"
|
||||
filename = f"{instance_name}.abc"
|
||||
|
||||
filepath = os.path.join(stagingdir, filename)
|
||||
|
|
|
|||
|
|
@ -20,9 +20,9 @@ class ExtractBlend(publish.Extractor, publish.OptionalPyblishPluginMixin):
|
|||
# Define extract output file path
|
||||
|
||||
stagingdir = self.staging_dir(instance)
|
||||
asset_name = instance.data["assetEntity"]["name"]
|
||||
subset = instance.data["subset"]
|
||||
instance_name = f"{asset_name}_{subset}"
|
||||
folder_name = instance.data["assetEntity"]["name"]
|
||||
product_name = instance.data["prouctName"]
|
||||
instance_name = f"{folder_name}_{product_name}"
|
||||
filename = f"{instance_name}.blend"
|
||||
filepath = os.path.join(stagingdir, filename)
|
||||
|
||||
|
|
|
|||
|
|
@ -23,9 +23,9 @@ class ExtractBlendAnimation(
|
|||
# Define extract output file path
|
||||
|
||||
stagingdir = self.staging_dir(instance)
|
||||
asset_name = instance.data["assetEntity"]["name"]
|
||||
subset = instance.data["subset"]
|
||||
instance_name = f"{asset_name}_{subset}"
|
||||
folder_name = instance.data["assetEntity"]["name"]
|
||||
product_name = instance.data["prouctName"]
|
||||
instance_name = f"{folder_name}_{product_name}"
|
||||
filename = f"{instance_name}.blend"
|
||||
filepath = os.path.join(stagingdir, filename)
|
||||
|
||||
|
|
|
|||
|
|
@ -21,9 +21,9 @@ class ExtractCameraABC(publish.Extractor, publish.OptionalPyblishPluginMixin):
|
|||
|
||||
# Define extract output file path
|
||||
stagingdir = self.staging_dir(instance)
|
||||
asset_name = instance.data["assetEntity"]["name"]
|
||||
subset = instance.data["subset"]
|
||||
instance_name = f"{asset_name}_{subset}"
|
||||
folder_name = instance.data["assetEntity"]["name"]
|
||||
product_name = instance.data["productName"]
|
||||
instance_name = f"{folder_name}_{product_name}"
|
||||
filename = f"{instance_name}.abc"
|
||||
filepath = os.path.join(stagingdir, filename)
|
||||
|
||||
|
|
|
|||
|
|
@ -20,9 +20,9 @@ class ExtractCamera(publish.Extractor, publish.OptionalPyblishPluginMixin):
|
|||
|
||||
# Define extract output file path
|
||||
stagingdir = self.staging_dir(instance)
|
||||
asset_name = instance.data["assetEntity"]["name"]
|
||||
subset = instance.data["subset"]
|
||||
instance_name = f"{asset_name}_{subset}"
|
||||
folder_name = instance.data["assetEntity"]["name"]
|
||||
product_name = instance.data["prouctName"]
|
||||
instance_name = f"{folder_name}_{product_name}"
|
||||
filename = f"{instance_name}.fbx"
|
||||
filepath = os.path.join(stagingdir, filename)
|
||||
|
||||
|
|
|
|||
|
|
@ -21,9 +21,9 @@ class ExtractFBX(publish.Extractor, publish.OptionalPyblishPluginMixin):
|
|||
|
||||
# Define extract output file path
|
||||
stagingdir = self.staging_dir(instance)
|
||||
asset_name = instance.data["assetEntity"]["name"]
|
||||
subset = instance.data["subset"]
|
||||
instance_name = f"{asset_name}_{subset}"
|
||||
folder_name = instance.data["assetEntity"]["name"]
|
||||
product_name = instance.data["prouctName"]
|
||||
instance_name = f"{folder_name}_{product_name}"
|
||||
filename = f"{instance_name}.fbx"
|
||||
filepath = os.path.join(stagingdir, filename)
|
||||
|
||||
|
|
|
|||
|
|
@ -145,9 +145,9 @@ class ExtractAnimationFBX(
|
|||
|
||||
root.select_set(True)
|
||||
armature.select_set(True)
|
||||
asset_name = instance.data["assetEntity"]["name"]
|
||||
subset = instance.data["subset"]
|
||||
instance_name = f"{asset_name}_{subset}"
|
||||
folder_name = instance.data["assetEntity"]["name"]
|
||||
product_name = instance.data["prouctName"]
|
||||
instance_name = f"{folder_name}_{product_name}"
|
||||
fbx_filename = f"{instance_name}_{armature.name}.fbx"
|
||||
filepath = os.path.join(stagingdir, fbx_filename)
|
||||
|
||||
|
|
|
|||
|
|
@ -133,7 +133,7 @@ class ExtractLayout(publish.Extractor, publish.OptionalPyblishPluginMixin):
|
|||
|
||||
fbx_count = 0
|
||||
|
||||
project_name = instance.context.data["projectEntity"]["name"]
|
||||
project_name = instance.context.data["projectName"]
|
||||
for asset in asset_group.children:
|
||||
metadata = asset.get(AVALON_PROPERTY)
|
||||
if not metadata:
|
||||
|
|
@ -147,7 +147,9 @@ class ExtractLayout(publish.Extractor, publish.OptionalPyblishPluginMixin):
|
|||
continue
|
||||
|
||||
version_id = metadata["parent"]
|
||||
family = metadata["family"]
|
||||
product_type = metadata.get("product_type")
|
||||
if product_type is None:
|
||||
product_type = metadata["family"]
|
||||
|
||||
self.log.debug("Parent: {}".format(version_id))
|
||||
# Get blend reference
|
||||
|
|
@ -179,7 +181,8 @@ class ExtractLayout(publish.Extractor, publish.OptionalPyblishPluginMixin):
|
|||
json_element["reference_fbx"] = str(fbx_id)
|
||||
if abc_id:
|
||||
json_element["reference_abc"] = str(abc_id)
|
||||
json_element["family"] = family
|
||||
json_element["family"] = product_type
|
||||
json_element["product_type"] = product_type
|
||||
json_element["instance_name"] = asset.name
|
||||
json_element["asset_name"] = metadata["asset_name"]
|
||||
json_element["file_path"] = metadata["libpath"]
|
||||
|
|
@ -215,7 +218,7 @@ class ExtractLayout(publish.Extractor, publish.OptionalPyblishPluginMixin):
|
|||
]
|
||||
|
||||
# Extract the animation as well
|
||||
if family == "rig":
|
||||
if product_type == "rig":
|
||||
f, n = self._export_animation(
|
||||
asset, instance, stagingdir, fbx_count)
|
||||
if f:
|
||||
|
|
@ -225,9 +228,9 @@ class ExtractLayout(publish.Extractor, publish.OptionalPyblishPluginMixin):
|
|||
|
||||
json_data.append(json_element)
|
||||
|
||||
asset_name = instance.data["assetEntity"]["name"]
|
||||
subset = instance.data["subset"]
|
||||
instance_name = f"{asset_name}_{subset}"
|
||||
folder_name = instance.data["assetEntity"]["name"]
|
||||
product_name = instance.data["productName"]
|
||||
instance_name = f"{folder_name}_{product_name}"
|
||||
json_filename = f"{instance_name}.json"
|
||||
|
||||
json_path = os.path.join(stagingdir, json_filename)
|
||||
|
|
|
|||
|
|
@ -55,9 +55,9 @@ class ExtractPlayblast(publish.Extractor, publish.OptionalPyblishPluginMixin):
|
|||
|
||||
# get output path
|
||||
stagingdir = self.staging_dir(instance)
|
||||
asset_name = instance.data["assetEntity"]["name"]
|
||||
subset = instance.data["subset"]
|
||||
filename = f"{asset_name}_{subset}"
|
||||
folder_name = instance.data["assetEntity"]["name"]
|
||||
product_name = instance.data["prouctName"]
|
||||
filename = f"{folder_name}_{product_name}"
|
||||
|
||||
path = os.path.join(stagingdir, filename)
|
||||
|
||||
|
|
|
|||
|
|
@ -32,9 +32,9 @@ class ExtractThumbnail(publish.Extractor):
|
|||
return
|
||||
|
||||
stagingdir = self.staging_dir(instance)
|
||||
asset_name = instance.data["assetEntity"]["name"]
|
||||
subset = instance.data["subset"]
|
||||
filename = f"{asset_name}_{subset}"
|
||||
folder_name = instance.data["assetEntity"]["name"]
|
||||
product_name = instance.data["prouctName"]
|
||||
filename = f"{folder_name}_{product_name}"
|
||||
|
||||
path = os.path.join(stagingdir, filename)
|
||||
|
||||
|
|
@ -42,11 +42,11 @@ class ExtractThumbnail(publish.Extractor):
|
|||
|
||||
camera = instance.data.get("review_camera", "AUTO")
|
||||
start = instance.data.get("frameStart", bpy.context.scene.frame_start)
|
||||
family = instance.data.get("family")
|
||||
product_type = instance.data["productType"]
|
||||
isolate = instance.data("isolate", None)
|
||||
|
||||
presets = json.loads(self.presets)
|
||||
preset = presets.get(family, {})
|
||||
preset = presets.get(product_type, {})
|
||||
|
||||
preset.update({
|
||||
"camera": camera,
|
||||
|
|
|
|||
|
|
@ -28,25 +28,27 @@ class IntegrateAnimation(
|
|||
# Update the json file for the setdress to add the published
|
||||
# representations of the animations
|
||||
for json_dict in data:
|
||||
json_product_name = json_dict["productName"]
|
||||
i = None
|
||||
for elem in instance.context:
|
||||
if elem.data.get('subset') == json_dict['subset']:
|
||||
if elem.data["productName"] == json_product_name:
|
||||
i = elem
|
||||
break
|
||||
if not i:
|
||||
continue
|
||||
rep = None
|
||||
pub_repr = i.data.get('published_representations')
|
||||
pub_repr = i.data["published_representations"]
|
||||
for elem in pub_repr:
|
||||
if pub_repr.get(elem).get('representation').get('name') == "fbx":
|
||||
rep = pub_repr.get(elem)
|
||||
if pub_repr[elem]["representation"]["name"] == "fbx":
|
||||
rep = pub_repr[elem]
|
||||
break
|
||||
if not rep:
|
||||
continue
|
||||
obj_id = rep.get('representation').get('_id')
|
||||
obj_id = rep["representation"]["_id"]
|
||||
|
||||
if obj_id:
|
||||
json_dict['_id'] = str(obj_id)
|
||||
json_dict["_id"] = str(obj_id)
|
||||
json_dict["representation_id"] = str(obj_id)
|
||||
|
||||
with open(json_path, "w") as file:
|
||||
json.dump(data, fp=file, indent=2)
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ class ValidateFileSaved(pyblish.api.ContextPlugin,
|
|||
hosts = ["blender"]
|
||||
label = "Validate File Saved"
|
||||
optional = False
|
||||
# TODO rename to 'exclude_product_types'
|
||||
exclude_families = []
|
||||
actions = [SaveWorkfileAction]
|
||||
|
||||
|
|
@ -41,8 +42,8 @@ class ValidateFileSaved(pyblish.api.ContextPlugin,
|
|||
|
||||
# Do not validate workfile has unsaved changes if only instances
|
||||
# present of families that should be excluded
|
||||
families = {
|
||||
instance.data["family"] for instance in context
|
||||
product_types = {
|
||||
instance.data["productType"] for instance in context
|
||||
# Consider only enabled instances
|
||||
if instance.data.get("publish", True)
|
||||
and instance.data.get("active", True)
|
||||
|
|
@ -52,7 +53,7 @@ class ValidateFileSaved(pyblish.api.ContextPlugin,
|
|||
return any(family in exclude_family
|
||||
for exclude_family in self.exclude_families)
|
||||
|
||||
if all(is_excluded(family) for family in families):
|
||||
if all(is_excluded(product_type) for product_type in product_types):
|
||||
self.log.debug("Only excluded families found, skipping workfile "
|
||||
"unsaved changes validation..")
|
||||
return
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue