From 47a02c2386f79bbbd63ac7328154bd1943499849 Mon Sep 17 00:00:00 2001 From: Simone Barbieri Date: Wed, 11 Oct 2023 14:34:10 +0100 Subject: [PATCH 01/15] Change pointcache creator to be in line with other creators --- .../plugins/create/create_pointcache.py | 42 +++++++++++++------ 1 file changed, 29 insertions(+), 13 deletions(-) diff --git a/openpype/hosts/blender/plugins/create/create_pointcache.py b/openpype/hosts/blender/plugins/create/create_pointcache.py index 6220f68dc5..65cf18472d 100644 --- a/openpype/hosts/blender/plugins/create/create_pointcache.py +++ b/openpype/hosts/blender/plugins/create/create_pointcache.py @@ -3,11 +3,11 @@ import bpy from openpype.pipeline import get_current_task_name -import openpype.hosts.blender.api.plugin -from openpype.hosts.blender.api import lib +from openpype.hosts.blender.api import plugin, lib, ops +from openpype.hosts.blender.api.pipeline import AVALON_INSTANCES -class CreatePointcache(openpype.hosts.blender.api.plugin.Creator): +class CreatePointcache(plugin.Creator): """Polygonal static geometry""" name = "pointcacheMain" @@ -16,20 +16,36 @@ class CreatePointcache(openpype.hosts.blender.api.plugin.Creator): icon = "gears" def process(self): + """ Run the creator on Blender main thread""" + mti = ops.MainThreadItem(self._process) + ops.execute_in_main_thread(mti) + def _process(self): + # Get Instance Container or create it if it does not exist + instances = bpy.data.collections.get(AVALON_INSTANCES) + if not instances: + instances = bpy.data.collections.new(name=AVALON_INSTANCES) + bpy.context.scene.collection.children.link(instances) + + # Create instance object asset = self.data["asset"] subset = self.data["subset"] - name = openpype.hosts.blender.api.plugin.asset_name(asset, subset) - collection = bpy.data.collections.new(name=name) - bpy.context.scene.collection.children.link(collection) + name = plugin.asset_name(asset, subset) + asset_group = bpy.data.objects.new(name=name, object_data=None) + asset_group.empty_display_type = 'SINGLE_ARROW' + instances.objects.link(asset_group) self.data['task'] = get_current_task_name() - lib.imprint(collection, self.data) + lib.imprint(asset_group, self.data) + # Add selected objects to instance if (self.options or {}).get("useSelection"): - objects = lib.get_selection() - for obj in objects: - collection.objects.link(obj) - if obj.type == 'EMPTY': - objects.extend(obj.children) + bpy.context.view_layer.objects.active = asset_group + selected = lib.get_selection() + for obj in selected: + if obj.parent in selected: + obj.select_set(False) + continue + selected.append(asset_group) + bpy.ops.object.parent_set(keep_transform=True) - return collection + return asset_group From 7fec582a2d472c8a956621a53d556a8ee784e52a Mon Sep 17 00:00:00 2001 From: Simone Barbieri Date: Wed, 11 Oct 2023 14:34:55 +0100 Subject: [PATCH 02/15] Improve instance collector --- .../plugins/publish/collect_instances.py | 101 +++++++----------- 1 file changed, 40 insertions(+), 61 deletions(-) diff --git a/openpype/hosts/blender/plugins/publish/collect_instances.py b/openpype/hosts/blender/plugins/publish/collect_instances.py index bc4b5ab092..4915e4a7cf 100644 --- a/openpype/hosts/blender/plugins/publish/collect_instances.py +++ b/openpype/hosts/blender/plugins/publish/collect_instances.py @@ -1,4 +1,5 @@ import json +from itertools import chain from typing import Generator import bpy @@ -19,85 +20,63 @@ class CollectInstances(pyblish.api.ContextPlugin): @staticmethod def get_asset_groups() -> Generator: - """Return all 'model' collections. - - Check if the family is 'model' and if it doesn't have the - representation set. If the representation is set, it is a loaded model - and we don't want to publish it. + """Return all instances that are empty objects asset groups. """ instances = bpy.data.collections.get(AVALON_INSTANCES) for obj in instances.objects: - avalon_prop = obj.get(AVALON_PROPERTY) or dict() + avalon_prop = obj.get(AVALON_PROPERTY) or {} if avalon_prop.get('id') == 'pyblish.avalon.instance': yield obj @staticmethod def get_collections() -> Generator: - """Return all 'model' collections. - - Check if the family is 'model' and if it doesn't have the - representation set. If the representation is set, it is a loaded model - and we don't want to publish it. + """Return all instances that are collections. """ - for collection in bpy.data.collections: - avalon_prop = collection.get(AVALON_PROPERTY) or dict() + instances = bpy.data.collections.get(AVALON_INSTANCES) + for collection in instances.children: + avalon_prop = collection.get(AVALON_PROPERTY) or {} if avalon_prop.get('id') == 'pyblish.avalon.instance': yield collection + @staticmethod + def create_instance(context, group): + avalon_prop = group[AVALON_PROPERTY] + asset = avalon_prop['asset'] + family = avalon_prop['family'] + subset = avalon_prop['subset'] + task = avalon_prop['task'] + name = f"{asset}_{subset}" + return context.create_instance( + name=name, + family=family, + families=[family], + subset=subset, + asset=asset, + task=task, + ), family + def process(self, context): """Collect the models from the current Blender scene.""" asset_groups = self.get_asset_groups() collections = self.get_collections() - for group in asset_groups: - avalon_prop = group[AVALON_PROPERTY] - asset = avalon_prop['asset'] - family = avalon_prop['family'] - subset = avalon_prop['subset'] - task = avalon_prop['task'] - name = f"{asset}_{subset}" - instance = context.create_instance( - name=name, - family=family, - families=[family], - subset=subset, - asset=asset, - task=task, - ) - objects = list(group.children) - members = set() - for obj in objects: - objects.extend(list(obj.children)) - members.add(obj) - members.add(group) - instance[:] = list(members) - self.log.debug(json.dumps(instance.data, indent=4)) - for obj in instance: - self.log.debug(obj) + instances = chain(asset_groups, collections) - for collection in collections: - avalon_prop = collection[AVALON_PROPERTY] - asset = avalon_prop['asset'] - family = avalon_prop['family'] - subset = avalon_prop['subset'] - task = avalon_prop['task'] - name = f"{asset}_{subset}" - instance = context.create_instance( - name=name, - family=family, - families=[family], - subset=subset, - asset=asset, - task=task, - ) - members = list(collection.objects) - if family == "animation": - for obj in collection.objects: - if obj.type == 'EMPTY' and obj.get(AVALON_PROPERTY): - for child in obj.children: - if child.type == 'ARMATURE': - members.append(child) - members.append(collection) + for group in instances: + instance, family = self.create_instance(context, group) + members = [] + if type(group) == bpy.types.Collection: + members = list(group.objects) + if family == "animation": + for obj in group.objects: + if obj.type == 'EMPTY' and obj.get(AVALON_PROPERTY): + members.extend( + child for child in obj.children + if child.type == 'ARMATURE') + else: + members = group.children_recursive + + members.append(group) instance[:] = members self.log.debug(json.dumps(instance.data, indent=4)) for obj in instance: From 9f82f8ee2ff35aa66f0c3447a8aefb0adff101c6 Mon Sep 17 00:00:00 2001 From: Simone Barbieri Date: Wed, 11 Oct 2023 14:38:23 +0100 Subject: [PATCH 03/15] Changed how alembic files are extracted --- .../plugins/publish/collect_instances.py | 3 +++ .../blender/plugins/publish/extract_abc.py | 3 +-- .../plugins/publish/extract_abc_model.py | 17 +++++++++++++++++ .../defaults/project_settings/blender.json | 2 +- .../schemas/schema_blender_publish.json | 8 ++++---- .../blender/server/settings/publish_plugins.py | 4 ++-- 6 files changed, 28 insertions(+), 9 deletions(-) create mode 100644 openpype/hosts/blender/plugins/publish/extract_abc_model.py diff --git a/openpype/hosts/blender/plugins/publish/collect_instances.py b/openpype/hosts/blender/plugins/publish/collect_instances.py index 4915e4a7cf..1e0db9d9ce 100644 --- a/openpype/hosts/blender/plugins/publish/collect_instances.py +++ b/openpype/hosts/blender/plugins/publish/collect_instances.py @@ -76,6 +76,9 @@ class CollectInstances(pyblish.api.ContextPlugin): else: members = group.children_recursive + if family == "pointcache": + instance.data["families"].append("abc.export") + members.append(group) instance[:] = members self.log.debug(json.dumps(instance.data, indent=4)) diff --git a/openpype/hosts/blender/plugins/publish/extract_abc.py b/openpype/hosts/blender/plugins/publish/extract_abc.py index 87159e53f0..b113685842 100644 --- a/openpype/hosts/blender/plugins/publish/extract_abc.py +++ b/openpype/hosts/blender/plugins/publish/extract_abc.py @@ -12,8 +12,7 @@ class ExtractABC(publish.Extractor): label = "Extract ABC" hosts = ["blender"] - families = ["model", "pointcache"] - optional = True + families = ["abc.export"] def process(self, instance): # Define extract output file path diff --git a/openpype/hosts/blender/plugins/publish/extract_abc_model.py b/openpype/hosts/blender/plugins/publish/extract_abc_model.py new file mode 100644 index 0000000000..b31e36c681 --- /dev/null +++ b/openpype/hosts/blender/plugins/publish/extract_abc_model.py @@ -0,0 +1,17 @@ +import pyblish.api +from openpype.pipeline import publish + + +class ExtractModelABC(publish.Extractor): + """Extract model as ABC.""" + + order = pyblish.api.ExtractorOrder - 0.1 + label = "Extract Model ABC" + hosts = ["blender"] + families = ["model"] + optional = True + + def process(self, instance): + # Add abc.export family to the instance, to allow the extraction + # as alembic of the asset. + instance.data["families"].append("abc.export") diff --git a/openpype/settings/defaults/project_settings/blender.json b/openpype/settings/defaults/project_settings/blender.json index f3eb31174f..2bc518e329 100644 --- a/openpype/settings/defaults/project_settings/blender.json +++ b/openpype/settings/defaults/project_settings/blender.json @@ -89,7 +89,7 @@ "optional": true, "active": false }, - "ExtractABC": { + "ExtractModelABC": { "enabled": true, "optional": true, "active": false diff --git a/openpype/settings/entities/schemas/projects_schema/schemas/schema_blender_publish.json b/openpype/settings/entities/schemas/projects_schema/schemas/schema_blender_publish.json index 7f1a8a915b..b84c663e6c 100644 --- a/openpype/settings/entities/schemas/projects_schema/schemas/schema_blender_publish.json +++ b/openpype/settings/entities/schemas/projects_schema/schemas/schema_blender_publish.json @@ -181,12 +181,12 @@ "name": "template_publish_plugin", "template_data": [ { - "key": "ExtractFBX", - "label": "Extract FBX (model and rig)" + "key": "ExtractModelABC", + "label": "Extract ABC (model)" }, { - "key": "ExtractABC", - "label": "Extract ABC (model and pointcache)" + "key": "ExtractFBX", + "label": "Extract FBX (model and rig)" }, { "key": "ExtractBlendAnimation", diff --git a/server_addon/blender/server/settings/publish_plugins.py b/server_addon/blender/server/settings/publish_plugins.py index 5e047b7013..102320cfed 100644 --- a/server_addon/blender/server/settings/publish_plugins.py +++ b/server_addon/blender/server/settings/publish_plugins.py @@ -103,7 +103,7 @@ class PublishPuginsModel(BaseSettingsModel): default_factory=ValidatePluginModel, title="Extract FBX" ) - ExtractABC: ValidatePluginModel = Field( + ExtractModelABC: ValidatePluginModel = Field( default_factory=ValidatePluginModel, title="Extract ABC" ) @@ -197,7 +197,7 @@ DEFAULT_BLENDER_PUBLISH_SETTINGS = { "optional": True, "active": False }, - "ExtractABC": { + "ExtractModelABC": { "enabled": True, "optional": True, "active": False From 08e10fd59af02725011886e0e133fc0a70b084d1 Mon Sep 17 00:00:00 2001 From: Simone Barbieri Date: Wed, 11 Oct 2023 14:43:38 +0100 Subject: [PATCH 04/15] Make extraction of models as alembic on by default --- openpype/settings/defaults/project_settings/blender.json | 2 +- server_addon/blender/server/settings/publish_plugins.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/openpype/settings/defaults/project_settings/blender.json b/openpype/settings/defaults/project_settings/blender.json index 2bc518e329..7fb8c333a6 100644 --- a/openpype/settings/defaults/project_settings/blender.json +++ b/openpype/settings/defaults/project_settings/blender.json @@ -92,7 +92,7 @@ "ExtractModelABC": { "enabled": true, "optional": true, - "active": false + "active": true }, "ExtractBlendAnimation": { "enabled": true, diff --git a/server_addon/blender/server/settings/publish_plugins.py b/server_addon/blender/server/settings/publish_plugins.py index 102320cfed..27dc0b232f 100644 --- a/server_addon/blender/server/settings/publish_plugins.py +++ b/server_addon/blender/server/settings/publish_plugins.py @@ -200,7 +200,7 @@ DEFAULT_BLENDER_PUBLISH_SETTINGS = { "ExtractModelABC": { "enabled": True, "optional": True, - "active": False + "active": True }, "ExtractBlendAnimation": { "enabled": True, From 23b29c947cb59fc626047846d86cf5d714d515f5 Mon Sep 17 00:00:00 2001 From: Simone Barbieri Date: Wed, 11 Oct 2023 15:17:33 +0100 Subject: [PATCH 05/15] Improved function to create the instance --- openpype/hosts/blender/plugins/publish/collect_instances.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/openpype/hosts/blender/plugins/publish/collect_instances.py b/openpype/hosts/blender/plugins/publish/collect_instances.py index 1e0db9d9ce..cc163fc97e 100644 --- a/openpype/hosts/blender/plugins/publish/collect_instances.py +++ b/openpype/hosts/blender/plugins/publish/collect_instances.py @@ -53,7 +53,7 @@ class CollectInstances(pyblish.api.ContextPlugin): subset=subset, asset=asset, task=task, - ), family + ) def process(self, context): """Collect the models from the current Blender scene.""" @@ -63,7 +63,8 @@ class CollectInstances(pyblish.api.ContextPlugin): instances = chain(asset_groups, collections) for group in instances: - instance, family = self.create_instance(context, group) + instance = self.create_instance(context, group) + family = instance.data["family"] members = [] if type(group) == bpy.types.Collection: members = list(group.objects) From 70abe6b7b7576699918ef6cb818c019b888567bf Mon Sep 17 00:00:00 2001 From: Simone Barbieri Date: Wed, 11 Oct 2023 15:21:44 +0100 Subject: [PATCH 06/15] Merged the two functions to get asset groups --- .../plugins/publish/collect_instances.py | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/openpype/hosts/blender/plugins/publish/collect_instances.py b/openpype/hosts/blender/plugins/publish/collect_instances.py index cc163fc97e..b4fc167638 100644 --- a/openpype/hosts/blender/plugins/publish/collect_instances.py +++ b/openpype/hosts/blender/plugins/publish/collect_instances.py @@ -1,5 +1,4 @@ import json -from itertools import chain from typing import Generator import bpy @@ -23,21 +22,11 @@ class CollectInstances(pyblish.api.ContextPlugin): """Return all instances that are empty objects asset groups. """ instances = bpy.data.collections.get(AVALON_INSTANCES) - for obj in instances.objects: + for obj in list(instances.objects) + list(instances.children): avalon_prop = obj.get(AVALON_PROPERTY) or {} if avalon_prop.get('id') == 'pyblish.avalon.instance': yield obj - @staticmethod - def get_collections() -> Generator: - """Return all instances that are collections. - """ - instances = bpy.data.collections.get(AVALON_INSTANCES) - for collection in instances.children: - avalon_prop = collection.get(AVALON_PROPERTY) or {} - if avalon_prop.get('id') == 'pyblish.avalon.instance': - yield collection - @staticmethod def create_instance(context, group): avalon_prop = group[AVALON_PROPERTY] @@ -58,11 +47,8 @@ class CollectInstances(pyblish.api.ContextPlugin): def process(self, context): """Collect the models from the current Blender scene.""" asset_groups = self.get_asset_groups() - collections = self.get_collections() - instances = chain(asset_groups, collections) - - for group in instances: + for group in asset_groups: instance = self.create_instance(context, group) family = instance.data["family"] members = [] From 68b281fdedad5df6339452418335e5f7f771ca07 Mon Sep 17 00:00:00 2001 From: Simone Barbieri Date: Thu, 12 Oct 2023 10:10:29 +0100 Subject: [PATCH 07/15] Improved how models abc extractor is implemented Co-authored-by: Kayla Man --- .../plugins/publish/collect_instances.py | 5 +---- .../blender/plugins/publish/extract_abc.py | 10 +++++++++- .../plugins/publish/extract_abc_model.py | 17 ----------------- 3 files changed, 10 insertions(+), 22 deletions(-) delete mode 100644 openpype/hosts/blender/plugins/publish/extract_abc_model.py diff --git a/openpype/hosts/blender/plugins/publish/collect_instances.py b/openpype/hosts/blender/plugins/publish/collect_instances.py index b4fc167638..c95d718187 100644 --- a/openpype/hosts/blender/plugins/publish/collect_instances.py +++ b/openpype/hosts/blender/plugins/publish/collect_instances.py @@ -50,10 +50,10 @@ class CollectInstances(pyblish.api.ContextPlugin): for group in asset_groups: instance = self.create_instance(context, group) - family = instance.data["family"] members = [] if type(group) == bpy.types.Collection: members = list(group.objects) + family = instance.data["family"] if family == "animation": for obj in group.objects: if obj.type == 'EMPTY' and obj.get(AVALON_PROPERTY): @@ -63,9 +63,6 @@ class CollectInstances(pyblish.api.ContextPlugin): else: members = group.children_recursive - if family == "pointcache": - instance.data["families"].append("abc.export") - members.append(group) instance[:] = members self.log.debug(json.dumps(instance.data, indent=4)) diff --git a/openpype/hosts/blender/plugins/publish/extract_abc.py b/openpype/hosts/blender/plugins/publish/extract_abc.py index b113685842..a603366f30 100644 --- a/openpype/hosts/blender/plugins/publish/extract_abc.py +++ b/openpype/hosts/blender/plugins/publish/extract_abc.py @@ -12,7 +12,7 @@ class ExtractABC(publish.Extractor): label = "Extract ABC" hosts = ["blender"] - families = ["abc.export"] + families = ["pointcache"] def process(self, instance): # Define extract output file path @@ -61,3 +61,11 @@ class ExtractABC(publish.Extractor): self.log.info("Extracted instance '%s' to: %s", instance.name, representation) + +class ExtractModelABC(ExtractABC): + """Extract model as ABC.""" + + label = "Extract Model ABC" + hosts = ["blender"] + families = ["model"] + optional = True diff --git a/openpype/hosts/blender/plugins/publish/extract_abc_model.py b/openpype/hosts/blender/plugins/publish/extract_abc_model.py deleted file mode 100644 index b31e36c681..0000000000 --- a/openpype/hosts/blender/plugins/publish/extract_abc_model.py +++ /dev/null @@ -1,17 +0,0 @@ -import pyblish.api -from openpype.pipeline import publish - - -class ExtractModelABC(publish.Extractor): - """Extract model as ABC.""" - - order = pyblish.api.ExtractorOrder - 0.1 - label = "Extract Model ABC" - hosts = ["blender"] - families = ["model"] - optional = True - - def process(self, instance): - # Add abc.export family to the instance, to allow the extraction - # as alembic of the asset. - instance.data["families"].append("abc.export") From 7cce128c2027f88cb5dc54d526ff3f944dc3a14f Mon Sep 17 00:00:00 2001 From: Simone Barbieri Date: Thu, 12 Oct 2023 10:11:28 +0100 Subject: [PATCH 08/15] Hound fixes --- openpype/hosts/blender/plugins/publish/extract_abc.py | 1 + 1 file changed, 1 insertion(+) diff --git a/openpype/hosts/blender/plugins/publish/extract_abc.py b/openpype/hosts/blender/plugins/publish/extract_abc.py index a603366f30..7b6c4d7ae7 100644 --- a/openpype/hosts/blender/plugins/publish/extract_abc.py +++ b/openpype/hosts/blender/plugins/publish/extract_abc.py @@ -62,6 +62,7 @@ class ExtractABC(publish.Extractor): self.log.info("Extracted instance '%s' to: %s", instance.name, representation) + class ExtractModelABC(ExtractABC): """Extract model as ABC.""" From 6259687b32c9216f0f111e07b5c6228242d1d25e Mon Sep 17 00:00:00 2001 From: Simone Barbieri Date: Thu, 12 Oct 2023 10:14:30 +0100 Subject: [PATCH 09/15] Increment workfile version when publishing pointcache --- .../hosts/blender/plugins/publish/increment_workfile_version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/hosts/blender/plugins/publish/increment_workfile_version.py b/openpype/hosts/blender/plugins/publish/increment_workfile_version.py index 3d176f9c30..6ace14d77c 100644 --- a/openpype/hosts/blender/plugins/publish/increment_workfile_version.py +++ b/openpype/hosts/blender/plugins/publish/increment_workfile_version.py @@ -10,7 +10,7 @@ class IncrementWorkfileVersion(pyblish.api.ContextPlugin): optional = True hosts = ["blender"] families = ["animation", "model", "rig", "action", "layout", "blendScene", - "render"] + "pointcache", "render"] def process(self, context): From 95fefaaa169a7404d3fae9ed5906b1227cde7c95 Mon Sep 17 00:00:00 2001 From: Simone Barbieri Date: Thu, 12 Oct 2023 10:45:16 +0100 Subject: [PATCH 10/15] Fix wrong hierarchy when loading --- .../hosts/blender/plugins/load/load_abc.py | 20 ++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/openpype/hosts/blender/plugins/load/load_abc.py b/openpype/hosts/blender/plugins/load/load_abc.py index 9b3d940536..a7077f98f2 100644 --- a/openpype/hosts/blender/plugins/load/load_abc.py +++ b/openpype/hosts/blender/plugins/load/load_abc.py @@ -60,16 +60,30 @@ class CacheModelLoader(plugin.AssetLoader): imported = lib.get_selection() + empties = [obj for obj in imported if obj.type == 'EMPTY'] + + container = None + + for empty in empties: + if not empty.parent: + container = empty + break + + assert container, "No asset group found" + # Children must be linked before parents, # otherwise the hierarchy will break objects = [] + nodes = list(container.children) - for obj in imported: + for obj in nodes: obj.parent = asset_group - for obj in imported: + bpy.data.objects.remove(container) + + for obj in nodes: objects.append(obj) - imported.extend(list(obj.children)) + nodes.extend(list(obj.children)) objects.reverse() From 7589de5aa14cb595f7646f68e7f9d8eaf373a0b5 Mon Sep 17 00:00:00 2001 From: Simone Barbieri Date: Thu, 12 Oct 2023 11:33:18 +0100 Subject: [PATCH 11/15] Improved loop to get all loaded objects --- openpype/hosts/blender/plugins/load/load_abc.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/hosts/blender/plugins/load/load_abc.py b/openpype/hosts/blender/plugins/load/load_abc.py index a7077f98f2..91d7356a2c 100644 --- a/openpype/hosts/blender/plugins/load/load_abc.py +++ b/openpype/hosts/blender/plugins/load/load_abc.py @@ -83,7 +83,7 @@ class CacheModelLoader(plugin.AssetLoader): for obj in nodes: objects.append(obj) - nodes.extend(list(obj.children)) + objects.extend(list(obj.children_recursive)) objects.reverse() From 251740891980ad37a7d3d326bbb833b36ced2f24 Mon Sep 17 00:00:00 2001 From: Simone Barbieri Date: Thu, 12 Oct 2023 11:40:21 +0100 Subject: [PATCH 12/15] Fixed handling of missing container in the abc file being loaded --- .../hosts/blender/plugins/load/load_abc.py | 27 ++++++++++--------- 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/openpype/hosts/blender/plugins/load/load_abc.py b/openpype/hosts/blender/plugins/load/load_abc.py index 91d7356a2c..531a820436 100644 --- a/openpype/hosts/blender/plugins/load/load_abc.py +++ b/openpype/hosts/blender/plugins/load/load_abc.py @@ -69,23 +69,26 @@ class CacheModelLoader(plugin.AssetLoader): container = empty break - assert container, "No asset group found" - - # Children must be linked before parents, - # otherwise the hierarchy will break objects = [] - nodes = list(container.children) + if container: + # Children must be linked before parents, + # otherwise the hierarchy will break + nodes = list(container.children) - for obj in nodes: - obj.parent = asset_group + for obj in nodes: + obj.parent = asset_group - bpy.data.objects.remove(container) + bpy.data.objects.remove(container) - for obj in nodes: - objects.append(obj) - objects.extend(list(obj.children_recursive)) + for obj in nodes: + objects.append(obj) + objects.extend(list(obj.children_recursive)) - objects.reverse() + objects.reverse() + else: + for obj in imported: + obj.parent = asset_group + objects = imported for obj in objects: # Unlink the object from all collections From 4418d1116477add6da68e33abeca492c669bba73 Mon Sep 17 00:00:00 2001 From: Simone Barbieri Date: Thu, 19 Oct 2023 11:18:59 +0100 Subject: [PATCH 13/15] Code improvements from suggestions Co-authored-by: Roy Nieterau --- .../hosts/blender/plugins/load/load_abc.py | 21 +++++++------------ .../plugins/publish/collect_instances.py | 2 +- 2 files changed, 8 insertions(+), 15 deletions(-) diff --git a/openpype/hosts/blender/plugins/load/load_abc.py b/openpype/hosts/blender/plugins/load/load_abc.py index 531a820436..af28cff7fe 100644 --- a/openpype/hosts/blender/plugins/load/load_abc.py +++ b/openpype/hosts/blender/plugins/load/load_abc.py @@ -60,19 +60,14 @@ class CacheModelLoader(plugin.AssetLoader): imported = lib.get_selection() - empties = [obj for obj in imported if obj.type == 'EMPTY'] - - container = None - - for empty in empties: - if not empty.parent: - container = empty - break + # Use first EMPTY without parent as container + container = next( + (obj for obj in imported if obj.type == "EMPTY" and not obj.parent), + None + ) objects = [] if container: - # Children must be linked before parents, - # otherwise the hierarchy will break nodes = list(container.children) for obj in nodes: @@ -80,11 +75,9 @@ class CacheModelLoader(plugin.AssetLoader): bpy.data.objects.remove(container) + objects.extend(nodes) for obj in nodes: - objects.append(obj) - objects.extend(list(obj.children_recursive)) - - objects.reverse() + objects.extend(obj.children_recursive) else: for obj in imported: obj.parent = asset_group diff --git a/openpype/hosts/blender/plugins/publish/collect_instances.py b/openpype/hosts/blender/plugins/publish/collect_instances.py index c95d718187..ad2ce54147 100644 --- a/openpype/hosts/blender/plugins/publish/collect_instances.py +++ b/openpype/hosts/blender/plugins/publish/collect_instances.py @@ -51,7 +51,7 @@ class CollectInstances(pyblish.api.ContextPlugin): for group in asset_groups: instance = self.create_instance(context, group) members = [] - if type(group) == bpy.types.Collection: + if isinstance(group, bpy.types.Collection): members = list(group.objects) family = instance.data["family"] if family == "animation": From 0b69ce120a23cb2393f4a281030b8696d357d780 Mon Sep 17 00:00:00 2001 From: Simone Barbieri Date: Thu, 19 Oct 2023 11:21:13 +0100 Subject: [PATCH 14/15] Hound fixes --- openpype/hosts/blender/plugins/load/load_abc.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openpype/hosts/blender/plugins/load/load_abc.py b/openpype/hosts/blender/plugins/load/load_abc.py index af28cff7fe..73f08fcc98 100644 --- a/openpype/hosts/blender/plugins/load/load_abc.py +++ b/openpype/hosts/blender/plugins/load/load_abc.py @@ -62,7 +62,8 @@ class CacheModelLoader(plugin.AssetLoader): # Use first EMPTY without parent as container container = next( - (obj for obj in imported if obj.type == "EMPTY" and not obj.parent), + (obj for obj in imported + if obj.type == "EMPTY" and not obj.parent), None ) From a37c7539bb6477ce26f7f5c816230a4783e2ccf0 Mon Sep 17 00:00:00 2001 From: Simone Barbieri Date: Thu, 19 Oct 2023 12:52:48 +0100 Subject: [PATCH 15/15] Changed empty type to Single Arrow --- openpype/hosts/blender/plugins/load/load_abc.py | 1 + 1 file changed, 1 insertion(+) diff --git a/openpype/hosts/blender/plugins/load/load_abc.py b/openpype/hosts/blender/plugins/load/load_abc.py index 73f08fcc98..8d1863d4d5 100644 --- a/openpype/hosts/blender/plugins/load/load_abc.py +++ b/openpype/hosts/blender/plugins/load/load_abc.py @@ -148,6 +148,7 @@ class CacheModelLoader(plugin.AssetLoader): bpy.context.scene.collection.children.link(containers) asset_group = bpy.data.objects.new(group_name, object_data=None) + asset_group.empty_display_type = 'SINGLE_ARROW' containers.objects.link(asset_group) objects = self._process(libpath, asset_group, group_name)