Skip to content

Commit

Permalink
Feature/build anim instance for setdress (ynput#41)
Browse files Browse the repository at this point in the history
* create anim instance for animated obj

* optimize with add_datablocks_to_container

* optimize animated_objects set

* instances_to_create using containers

* clear old code

* added collection type to anim instance

* set publish prop for setdress anim instance

* optimized code and comments

* fix if conditions

* fix comment
  • Loading branch information
kaamaurice authored and Tilix4 committed Jun 27, 2023
1 parent bec2161 commit 7eeb196
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 20 deletions.
3 changes: 2 additions & 1 deletion openpype/hosts/blender/plugins/create/create_animation.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import bpy

from openpype.hosts.blender.api import plugin
from openpype.hosts.blender.api.utils import BL_OUTLINER_TYPES


class CreateAnimation(plugin.Creator):
Expand All @@ -11,4 +12,4 @@ class CreateAnimation(plugin.Creator):
label = "Animation"
family = "animation"
icon = "male"
bl_types = frozenset({bpy.types.Action, bpy.types.Object})
bl_types = frozenset(BL_OUTLINER_TYPES | {bpy.types.Action})
28 changes: 21 additions & 7 deletions openpype/hosts/blender/plugins/publish/extract_blend_animation.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,30 @@ def process(self, instance):
bpy.context.scene.use_preview_range = False

# Keep animation assignations for auto reassign at loading
actions = set()
for datablock in instance:
if isinstance(datablock, bpy.types.Object):
if isinstance(datablock, bpy.types.Collection):
actions.update(
{
obj.animation_data.action
for obj in datablock.all_objects
if obj.animation_data and obj.animation_data.action
}
)

elif isinstance(datablock, bpy.types.Object):
# Skip if object not animated
if not datablock.animation_data:
continue
if (
datablock.animation_data
and datablock.animation_data.action
):
actions.add(datablock.animation_data.action)

action = datablock.animation_data.action
else:
action = datablock
# TODO could be optimized with user_map
elif isinstance(datablock, bpy.types.Action):
actions.add(datablock)

# TODO could be optimized with user_map
for action in actions:
action["users"] = [
o.name
for o in bpy.data.objects
Expand Down
70 changes: 58 additions & 12 deletions openpype/hosts/blender/scripts/build_workfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,11 @@
get_version_by_id,
)
from openpype.hosts.blender.api.properties import OpenpypeContainer
from openpype.hosts.blender.api.lib import update_scene_containers
from openpype.hosts.blender.api.lib import (
add_datablocks_to_container,
update_scene_containers,
)
from openpype.hosts.blender.api.utils import BL_TYPE_DATAPATH
from openpype.lib.local_settings import get_local_site_id
from openpype.modules import ModulesManager
from openpype.pipeline import (
Expand Down Expand Up @@ -747,18 +751,60 @@ def build_anim(project_name, asset_name):
use_selection=False,
)

for obj in bpy.context.scene.objects:
if obj.type == "ARMATURE":
# Create animation instance
variant_name = obj.name[obj.name.find("RIG_") + 4 :].capitalize()
bpy.ops.scene.create_openpype_instance(
creator_name="CreateAnimation",
asset_name=asset_name,
subset_name=f"animation{variant_name}",
datapath="objects",
datablock_name=obj.name,
use_selection=False,
instances_to_create = {}
for container in bpy.context.scene.openpype_containers:
container_metadata = container["avalon"]
variant_name = container_metadata.get("asset_name")
family = container_metadata.get("family")
container_datablocks = container.get_datablocks(bpy.types.Object)

if family == "setdress":
# For setdress container we gather only the root collection.
instances_to_create[variant_name] = list(
container.get_root_outliner_datablocks()
)
else:
# Get rigs
armature_objects = [
o for o in container_datablocks if o.type == "ARMATURE"
]
# Get animated objects
animated_objects = [
o for o in container_datablocks
if o.animation_data and o.animation_data.action
]
# Add new instance creation container had rigs or animated members.
if armature_objects or animated_objects:
instances_to_create[variant_name] = (
armature_objects + animated_objects
)

# Create instances and add datablocks
for variant_name, objects in instances_to_create.items():
bpy.ops.scene.create_openpype_instance(
creator_name="CreateAnimation",
asset_name=asset_name,
subset_name=f"animation{variant_name}",
datapath=BL_TYPE_DATAPATH.get(type(objects[0])),
datablock_nam=objects[0].name,
use_selection=False,
)
animation_instance = bpy.context.scene.openpype_instances[-1]
add_datablocks_to_container(objects[1:], animation_instance)

# Enabled instance for publishing if any member objects are animated.
publish_enabled = False
for obj in objects:
if (
isinstance(obj, bpy.types.Object)
and obj.animation_data
and obj.animation_data.action
):
publish_enabled = True
break
elif isinstance(obj, bpy.types.Collection):
objects.extend(obj.all_objects)
animation_instance.publish = publish_enabled

# load the board mov as image background linked into the camera
try:
Expand Down

0 comments on commit 7eeb196

Please sign in to comment.