mirror of
https://github.com/ynput/ayon-core.git
synced 2025-12-26 22:02:15 +01:00
PEP8 compliance
This commit is contained in:
parent
7e8bb47ed7
commit
a3d025f784
16 changed files with 137 additions and 136 deletions
|
|
@ -10,14 +10,16 @@ from avalon import api
|
|||
VALID_EXTENSIONS = [".blend"]
|
||||
|
||||
|
||||
def asset_name(asset: str, subset: str, namespace: Optional[str] = None) -> str:
|
||||
def asset_name(
|
||||
asset: str, subset: str, namespace: Optional[str] = None
|
||||
) -> str:
|
||||
"""Return a consistent name for an asset."""
|
||||
name = f"{asset}_{subset}"
|
||||
if namespace:
|
||||
name = f"{namespace}:{name}"
|
||||
return name
|
||||
|
||||
def create_blender_context( obj: Optional[bpy.types.Object] = None ):
|
||||
def create_blender_context(obj: Optional[bpy.types.Object] = None):
|
||||
"""Create a new Blender context. If an object is passed as
|
||||
parameter, it is set as selected and active.
|
||||
"""
|
||||
|
|
@ -27,16 +29,16 @@ def create_blender_context( obj: Optional[bpy.types.Object] = None ):
|
|||
for region in area.regions:
|
||||
if region.type == 'WINDOW':
|
||||
override_context = {
|
||||
'window': win,
|
||||
'screen': win.screen,
|
||||
'area': area,
|
||||
'region': region,
|
||||
'window': win,
|
||||
'screen': win.screen,
|
||||
'area': area,
|
||||
'region': region,
|
||||
'scene': bpy.context.scene,
|
||||
'active_object': obj,
|
||||
'selected_objects': [obj]
|
||||
}
|
||||
return override_context
|
||||
raise Exception( "Could not create a custom Blender context." )
|
||||
raise Exception("Could not create a custom Blender context.")
|
||||
|
||||
class AssetLoader(api.Loader):
|
||||
"""A basic AssetLoader for Blender
|
||||
|
|
|
|||
|
|
@ -27,8 +27,8 @@ class CreateAction(Creator):
|
|||
|
||||
if (self.options or {}).get("useSelection"):
|
||||
for obj in lib.get_selection():
|
||||
if (obj.animation_data is not None
|
||||
and obj.animation_data.action is not None):
|
||||
if (obj.animation_data is not None and
|
||||
obj.animation_data.action is not None):
|
||||
|
||||
empty_obj = bpy.data.objects.new(name=name,
|
||||
object_data=None)
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ class CreateAnimation(Creator):
|
|||
|
||||
for obj in lib.get_selection():
|
||||
|
||||
objects_to_link.add( obj )
|
||||
objects_to_link.add(obj)
|
||||
|
||||
if obj.type == 'ARMATURE':
|
||||
|
||||
|
|
|
|||
|
|
@ -15,23 +15,6 @@ class CreateRig(Creator):
|
|||
family = "rig"
|
||||
icon = "wheelchair"
|
||||
|
||||
# @staticmethod
|
||||
# def _find_layer_collection(self, layer_collection, collection):
|
||||
|
||||
# found = None
|
||||
|
||||
# if (layer_collection.collection == collection):
|
||||
|
||||
# return layer_collection
|
||||
|
||||
# for layer in layer_collection.children:
|
||||
|
||||
# found = self._find_layer_collection(layer, collection)
|
||||
|
||||
# if found:
|
||||
|
||||
# return found
|
||||
|
||||
def process(self):
|
||||
|
||||
asset = self.data["asset"]
|
||||
|
|
@ -54,7 +37,7 @@ class CreateRig(Creator):
|
|||
|
||||
for obj in lib.get_selection():
|
||||
|
||||
objects_to_link.add( obj )
|
||||
objects_to_link.add(obj)
|
||||
|
||||
if obj.type == 'ARMATURE':
|
||||
|
||||
|
|
@ -62,30 +45,6 @@ class CreateRig(Creator):
|
|||
|
||||
objects_to_link.add(subobj)
|
||||
|
||||
# Create a new collection and link the widgets that
|
||||
# the rig uses.
|
||||
# custom_shapes = set()
|
||||
|
||||
# for posebone in obj.pose.bones:
|
||||
|
||||
# if posebone.custom_shape is not None:
|
||||
|
||||
# custom_shapes.add( posebone.custom_shape )
|
||||
|
||||
# if len( custom_shapes ) > 0:
|
||||
|
||||
# widgets_collection = bpy.data.collections.new(name="Widgets")
|
||||
|
||||
# collection.children.link(widgets_collection)
|
||||
|
||||
# for custom_shape in custom_shapes:
|
||||
|
||||
# widgets_collection.objects.link( custom_shape )
|
||||
|
||||
# layer_collection = self._find_layer_collection(bpy.context.view_layer.layer_collection, widgets_collection)
|
||||
|
||||
# layer_collection.exclude = True
|
||||
|
||||
for obj in objects_to_link:
|
||||
|
||||
collection.objects.link(obj)
|
||||
|
|
|
|||
|
|
@ -69,11 +69,11 @@ class BlendActionLoader(pype.blender.plugin.AssetLoader):
|
|||
) as (_, data_to):
|
||||
data_to.collections = [lib_container]
|
||||
|
||||
scene = bpy.context.scene
|
||||
collection = bpy.context.scene.collection
|
||||
|
||||
scene.collection.children.link(bpy.data.collections[lib_container])
|
||||
collection.children.link(bpy.data.collections[lib_container])
|
||||
|
||||
animation_container = scene.collection.children[lib_container].make_local()
|
||||
animation_container = collection.children[lib_container].make_local()
|
||||
|
||||
objects_list = []
|
||||
|
||||
|
|
@ -84,9 +84,11 @@ class BlendActionLoader(pype.blender.plugin.AssetLoader):
|
|||
|
||||
obj = obj.make_local()
|
||||
|
||||
if obj.animation_data is not None and obj.animation_data.action is not None:
|
||||
anim_data = obj.animation_data
|
||||
|
||||
obj.animation_data.action.make_local()
|
||||
if anim_data is not None and anim_data.action is not None:
|
||||
|
||||
anim_data.action.make_local()
|
||||
|
||||
if not obj.get(blender.pipeline.AVALON_PROPERTY):
|
||||
|
||||
|
|
@ -173,8 +175,12 @@ class BlendActionLoader(pype.blender.plugin.AssetLoader):
|
|||
strips = []
|
||||
|
||||
for obj in collection_metadata["objects"]:
|
||||
|
||||
# Get all the strips that use the action
|
||||
arm_objs = [
|
||||
arm for arm in bpy.data.objects if arm.type == 'ARMATURE']
|
||||
|
||||
for armature_obj in [ objj for objj in bpy.data.objects if objj.type == 'ARMATURE' ]:
|
||||
for armature_obj in arm_objs:
|
||||
|
||||
if armature_obj.animation_data is not None:
|
||||
|
||||
|
|
@ -203,25 +209,27 @@ class BlendActionLoader(pype.blender.plugin.AssetLoader):
|
|||
|
||||
scene.collection.children.link(bpy.data.collections[lib_container])
|
||||
|
||||
animation_container = scene.collection.children[lib_container].make_local()
|
||||
anim_container = scene.collection.children[lib_container].make_local()
|
||||
|
||||
objects_list = []
|
||||
|
||||
# Link meshes first, then armatures.
|
||||
# The armature is unparented for all the non-local meshes,
|
||||
# when it is made local.
|
||||
for obj in animation_container.objects:
|
||||
for obj in anim_container.objects:
|
||||
|
||||
obj = obj.make_local()
|
||||
|
||||
if obj.animation_data is not None and obj.animation_data.action is not None:
|
||||
anim_data = obj.animation_data
|
||||
|
||||
obj.animation_data.action.make_local()
|
||||
if anim_data is not None and anim_data.action is not None:
|
||||
|
||||
anim_data.action.make_local()
|
||||
|
||||
for strip in strips:
|
||||
|
||||
strip.action = obj.animation_data.action
|
||||
strip.action_frame_end = obj.animation_data.action.frame_range[1]
|
||||
strip.action = anim_data.action
|
||||
strip.action_frame_end = anim_data.action.frame_range[1]
|
||||
|
||||
if not obj.get(blender.pipeline.AVALON_PROPERTY):
|
||||
|
||||
|
|
@ -232,7 +240,7 @@ class BlendActionLoader(pype.blender.plugin.AssetLoader):
|
|||
|
||||
objects_list.append(obj)
|
||||
|
||||
animation_container.pop(blender.pipeline.AVALON_PROPERTY)
|
||||
anim_container.pop(blender.pipeline.AVALON_PROPERTY)
|
||||
|
||||
# Save the list of objects in the metadata container
|
||||
collection_metadata["objects"] = objects_list
|
||||
|
|
@ -271,7 +279,11 @@ class BlendActionLoader(pype.blender.plugin.AssetLoader):
|
|||
|
||||
for obj in objects:
|
||||
|
||||
for armature_obj in [ objj for objj in bpy.data.objects if objj.type == 'ARMATURE' ]:
|
||||
# Get all the strips that use the action
|
||||
arm_objs = [
|
||||
arm for arm in bpy.data.objects if arm.type == 'ARMATURE']
|
||||
|
||||
for armature_obj in arm_objs:
|
||||
|
||||
if armature_obj.animation_data is not None:
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,8 @@ import bpy
|
|||
import pype.blender.plugin
|
||||
|
||||
|
||||
logger = logging.getLogger("pype").getChild("blender").getChild("load_animation")
|
||||
logger = logging.getLogger("pype").getChild(
|
||||
"blender").getChild("load_animation")
|
||||
|
||||
|
||||
class BlendAnimationLoader(pype.blender.plugin.AssetLoader):
|
||||
|
|
@ -53,10 +54,11 @@ class BlendAnimationLoader(pype.blender.plugin.AssetLoader):
|
|||
|
||||
scene.collection.children.link(bpy.data.collections[lib_container])
|
||||
|
||||
animation_container = scene.collection.children[lib_container].make_local()
|
||||
anim_container = scene.collection.children[lib_container].make_local()
|
||||
|
||||
meshes = [obj for obj in animation_container.objects if obj.type == 'MESH']
|
||||
armatures = [obj for obj in animation_container.objects if obj.type == 'ARMATURE']
|
||||
meshes = [obj for obj in anim_container.objects if obj.type == 'MESH']
|
||||
armatures = [
|
||||
obj for obj in anim_container.objects if obj.type == 'ARMATURE']
|
||||
|
||||
# Should check if there is only an armature?
|
||||
|
||||
|
|
@ -71,9 +73,11 @@ class BlendAnimationLoader(pype.blender.plugin.AssetLoader):
|
|||
|
||||
obj.data.make_local()
|
||||
|
||||
if obj.animation_data is not None and obj.animation_data.action is not None:
|
||||
anim_data = obj.animation_data
|
||||
|
||||
obj.animation_data.action.make_local()
|
||||
if anim_data is not None and anim_data.action is not None:
|
||||
|
||||
anim_data.action.make_local()
|
||||
|
||||
if not obj.get(blender.pipeline.AVALON_PROPERTY):
|
||||
|
||||
|
|
@ -84,7 +88,7 @@ class BlendAnimationLoader(pype.blender.plugin.AssetLoader):
|
|||
|
||||
objects_list.append(obj)
|
||||
|
||||
animation_container.pop( blender.pipeline.AVALON_PROPERTY )
|
||||
anim_container.pop(blender.pipeline.AVALON_PROPERTY)
|
||||
|
||||
bpy.ops.object.select_all(action='DESELECT')
|
||||
|
||||
|
|
@ -126,7 +130,8 @@ class BlendAnimationLoader(pype.blender.plugin.AssetLoader):
|
|||
container_metadata["libpath"] = libpath
|
||||
container_metadata["lib_container"] = lib_container
|
||||
|
||||
objects_list = self._process(self, libpath, lib_container, container_name)
|
||||
objects_list = self._process(
|
||||
self, libpath, lib_container, container_name)
|
||||
|
||||
# Save the list of objects in the metadata container
|
||||
container_metadata["objects"] = objects_list
|
||||
|
|
@ -206,7 +211,8 @@ class BlendAnimationLoader(pype.blender.plugin.AssetLoader):
|
|||
|
||||
self._remove(self, objects, lib_container)
|
||||
|
||||
objects_list = self._process(self, str(libpath), lib_container, collection.name)
|
||||
objects_list = self._process(
|
||||
self, str(libpath), lib_container, collection.name)
|
||||
|
||||
# Save the list of objects in the metadata container
|
||||
collection_metadata["objects"] = objects_list
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ class BlendModelLoader(pype.blender.plugin.AssetLoader):
|
|||
|
||||
objects_list.append(obj)
|
||||
|
||||
model_container.pop( blender.pipeline.AVALON_PROPERTY )
|
||||
model_container.pop(blender.pipeline.AVALON_PROPERTY)
|
||||
|
||||
bpy.ops.object.select_all(action='DESELECT')
|
||||
|
||||
|
|
@ -117,7 +117,8 @@ class BlendModelLoader(pype.blender.plugin.AssetLoader):
|
|||
container_metadata["libpath"] = libpath
|
||||
container_metadata["lib_container"] = lib_container
|
||||
|
||||
objects_list = self._process(self, libpath, lib_container, container_name)
|
||||
objects_list = self._process(
|
||||
self, libpath, lib_container, container_name)
|
||||
|
||||
# Save the list of objects in the metadata container
|
||||
container_metadata["objects"] = objects_list
|
||||
|
|
@ -190,7 +191,8 @@ class BlendModelLoader(pype.blender.plugin.AssetLoader):
|
|||
|
||||
self._remove(self, objects, lib_container)
|
||||
|
||||
objects_list = self._process(self, str(libpath), lib_container, collection.name)
|
||||
objects_list = self._process(
|
||||
self, str(libpath), lib_container, collection.name)
|
||||
|
||||
# Save the list of objects in the metadata container
|
||||
collection_metadata["objects"] = objects_list
|
||||
|
|
|
|||
|
|
@ -58,7 +58,8 @@ class BlendRigLoader(pype.blender.plugin.AssetLoader):
|
|||
rig_container = scene.collection.children[lib_container].make_local()
|
||||
|
||||
meshes = [obj for obj in rig_container.objects if obj.type == 'MESH']
|
||||
armatures = [obj for obj in rig_container.objects if obj.type == 'ARMATURE']
|
||||
armatures = [
|
||||
obj for obj in rig_container.objects if obj.type == 'ARMATURE']
|
||||
|
||||
objects_list = []
|
||||
|
||||
|
|
@ -86,7 +87,7 @@ class BlendRigLoader(pype.blender.plugin.AssetLoader):
|
|||
|
||||
objects_list.append(obj)
|
||||
|
||||
rig_container.pop( blender.pipeline.AVALON_PROPERTY )
|
||||
rig_container.pop(blender.pipeline.AVALON_PROPERTY)
|
||||
|
||||
bpy.ops.object.select_all(action='DESELECT')
|
||||
|
||||
|
|
@ -128,7 +129,8 @@ class BlendRigLoader(pype.blender.plugin.AssetLoader):
|
|||
container_metadata["libpath"] = libpath
|
||||
container_metadata["lib_container"] = lib_container
|
||||
|
||||
objects_list = self._process(self, libpath, lib_container, container_name, None)
|
||||
objects_list = self._process(
|
||||
self, libpath, lib_container, container_name, None)
|
||||
|
||||
# Save the list of objects in the metadata container
|
||||
container_metadata["objects"] = objects_list
|
||||
|
|
@ -209,7 +211,8 @@ class BlendRigLoader(pype.blender.plugin.AssetLoader):
|
|||
|
||||
self._remove(self, objects, lib_container)
|
||||
|
||||
objects_list = self._process(self, str(libpath), lib_container, collection.name, action)
|
||||
objects_list = self._process(
|
||||
self, str(libpath), lib_container, collection.name, action)
|
||||
|
||||
# Save the list of objects in the metadata container
|
||||
collection_metadata["objects"] = objects_list
|
||||
|
|
|
|||
|
|
@ -1,9 +1,7 @@
|
|||
import typing
|
||||
from typing import Generator
|
||||
|
||||
import bpy
|
||||
|
||||
import avalon.api
|
||||
import pyblish.api
|
||||
from avalon.blender.pipeline import AVALON_PROPERTY
|
||||
|
||||
|
|
@ -25,8 +23,8 @@ class CollectAction(pyblish.api.ContextPlugin):
|
|||
"""
|
||||
for collection in bpy.data.collections:
|
||||
avalon_prop = collection.get(AVALON_PROPERTY) or dict()
|
||||
if (avalon_prop.get('family') == 'action'
|
||||
and not avalon_prop.get('representation')):
|
||||
if (avalon_prop.get('family') == 'action' and
|
||||
not avalon_prop.get('representation')):
|
||||
yield collection
|
||||
|
||||
def process(self, context):
|
||||
|
|
|
|||
|
|
@ -1,9 +1,7 @@
|
|||
import typing
|
||||
from typing import Generator
|
||||
|
||||
import bpy
|
||||
|
||||
import avalon.api
|
||||
import pyblish.api
|
||||
from avalon.blender.pipeline import AVALON_PROPERTY
|
||||
|
||||
|
|
@ -20,13 +18,13 @@ class CollectAnimation(pyblish.api.ContextPlugin):
|
|||
"""Return all 'animation' collections.
|
||||
|
||||
Check if the family is 'animation' and if it doesn't have the
|
||||
representation set. If the representation is set, it is a loaded animation
|
||||
and we don't want to publish it.
|
||||
representation set. If the representation is set, it is a loaded
|
||||
animation and we don't want to publish it.
|
||||
"""
|
||||
for collection in bpy.data.collections:
|
||||
avalon_prop = collection.get(AVALON_PROPERTY) or dict()
|
||||
if (avalon_prop.get('family') == 'animation'
|
||||
and not avalon_prop.get('representation')):
|
||||
if (avalon_prop.get('family') == 'animation' and
|
||||
not avalon_prop.get('representation')):
|
||||
yield collection
|
||||
|
||||
def process(self, context):
|
||||
|
|
|
|||
|
|
@ -15,4 +15,5 @@ class CollectBlenderCurrentFile(pyblish.api.ContextPlugin):
|
|||
current_file = bpy.data.filepath
|
||||
context.data['currentFile'] = current_file
|
||||
|
||||
assert current_file != '', "Current file is empty. Save the file before continuing."
|
||||
assert current_file != '', "Current file is empty. " \
|
||||
"Save the file before continuing."
|
||||
|
|
|
|||
|
|
@ -1,9 +1,7 @@
|
|||
import typing
|
||||
from typing import Generator
|
||||
|
||||
import bpy
|
||||
|
||||
import avalon.api
|
||||
import pyblish.api
|
||||
from avalon.blender.pipeline import AVALON_PROPERTY
|
||||
|
||||
|
|
@ -25,8 +23,8 @@ class CollectModel(pyblish.api.ContextPlugin):
|
|||
"""
|
||||
for collection in bpy.data.collections:
|
||||
avalon_prop = collection.get(AVALON_PROPERTY) or dict()
|
||||
if (avalon_prop.get('family') == 'model'
|
||||
and not avalon_prop.get('representation')):
|
||||
if (avalon_prop.get('family') == 'model' and
|
||||
not avalon_prop.get('representation')):
|
||||
yield collection
|
||||
|
||||
def process(self, context):
|
||||
|
|
|
|||
|
|
@ -1,9 +1,7 @@
|
|||
import typing
|
||||
from typing import Generator
|
||||
|
||||
import bpy
|
||||
|
||||
import avalon.api
|
||||
import pyblish.api
|
||||
from avalon.blender.pipeline import AVALON_PROPERTY
|
||||
|
||||
|
|
@ -25,8 +23,8 @@ class CollectRig(pyblish.api.ContextPlugin):
|
|||
"""
|
||||
for collection in bpy.data.collections:
|
||||
avalon_prop = collection.get(AVALON_PROPERTY) or dict()
|
||||
if (avalon_prop.get('family') == 'rig'
|
||||
and not avalon_prop.get('representation')):
|
||||
if (avalon_prop.get('family') == 'rig' and
|
||||
not avalon_prop.get('representation')):
|
||||
yield collection
|
||||
|
||||
def process(self, context):
|
||||
|
|
|
|||
|
|
@ -43,4 +43,5 @@ class ExtractBlend(pype.api.Extractor):
|
|||
}
|
||||
instance.data["representations"].append(representation)
|
||||
|
||||
self.log.info("Extracted instance '%s' to: %s", instance.name, representation)
|
||||
self.log.info("Extracted instance '%s' to: %s",
|
||||
instance.name, representation)
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
import os
|
||||
import avalon.blender.workio
|
||||
|
||||
import pype.api
|
||||
|
||||
import bpy
|
||||
|
||||
|
||||
class ExtractFBX(pype.api.Extractor):
|
||||
"""Extract as FBX."""
|
||||
|
||||
|
|
@ -20,29 +20,39 @@ class ExtractFBX(pype.api.Extractor):
|
|||
filename = f"{instance.name}.fbx"
|
||||
filepath = os.path.join(stagingdir, filename)
|
||||
|
||||
context = bpy.context
|
||||
scene = context.scene
|
||||
view_layer = context.view_layer
|
||||
|
||||
# Perform extraction
|
||||
self.log.info("Performing extraction..")
|
||||
|
||||
collections = [obj for obj in instance if type(obj) is bpy.types.Collection]
|
||||
collections = [
|
||||
obj for obj in instance if type(obj) is bpy.types.Collection]
|
||||
|
||||
assert len(collections) == 1, "There should be one and only one collection collected for this asset"
|
||||
assert len(collections) == 1, "There should be one and only one " \
|
||||
"collection collected for this asset"
|
||||
|
||||
old_active_layer_collection = bpy.context.view_layer.active_layer_collection
|
||||
old_active_layer_collection = view_layer.active_layer_collection
|
||||
|
||||
layers = view_layer.layer_collection.children
|
||||
|
||||
# Get the layer collection from the collection we need to export.
|
||||
# This is needed because in Blender you can only set the active
|
||||
# This is needed because in Blender you can only set the active
|
||||
# collection with the layer collection, and there is no way to get
|
||||
# the layer collection from the collection (but there is the vice versa).
|
||||
layer_collections = [layer for layer in bpy.context.view_layer.layer_collection.children if layer.collection == collections[0]]
|
||||
# the layer collection from the collection
|
||||
# (but there is the vice versa).
|
||||
layer_collections = [
|
||||
layer for layer in layers if layer.collection == collections[0]]
|
||||
|
||||
assert len(layer_collections) == 1
|
||||
|
||||
bpy.context.view_layer.active_layer_collection = layer_collections[0]
|
||||
view_layer.active_layer_collection = layer_collections[0]
|
||||
|
||||
old_scale = bpy.context.scene.unit_settings.scale_length
|
||||
old_scale = scene.unit_settings.scale_length
|
||||
|
||||
# We set the scale of the scene for the export
|
||||
bpy.context.scene.unit_settings.scale_length = 0.01
|
||||
scene.unit_settings.scale_length = 0.01
|
||||
|
||||
# We export the fbx
|
||||
bpy.ops.export_scene.fbx(
|
||||
|
|
@ -52,9 +62,9 @@ class ExtractFBX(pype.api.Extractor):
|
|||
add_leaf_bones=False
|
||||
)
|
||||
|
||||
bpy.context.view_layer.active_layer_collection = old_active_layer_collection
|
||||
view_layer.active_layer_collection = old_active_layer_collection
|
||||
|
||||
bpy.context.scene.unit_settings.scale_length = old_scale
|
||||
scene.unit_settings.scale_length = old_scale
|
||||
|
||||
if "representations" not in instance.data:
|
||||
instance.data["representations"] = []
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import os
|
||||
import avalon.blender.workio
|
||||
|
||||
import pype.api
|
||||
|
||||
|
|
@ -23,31 +22,42 @@ class ExtractAnimationFBX(pype.api.Extractor):
|
|||
filename = f"{instance.name}.fbx"
|
||||
filepath = os.path.join(stagingdir, filename)
|
||||
|
||||
context = bpy.context
|
||||
scene = context.scene
|
||||
view_layer = context.view_layer
|
||||
|
||||
# Perform extraction
|
||||
self.log.info("Performing extraction..")
|
||||
|
||||
collections = [obj for obj in instance if type(obj) is bpy.types.Collection]
|
||||
collections = [
|
||||
obj for obj in instance if type(obj) is bpy.types.Collection]
|
||||
|
||||
assert len(collections) == 1, "There should be one and only one collection collected for this asset"
|
||||
assert len(collections) == 1, "There should be one and only one " \
|
||||
"collection collected for this asset"
|
||||
|
||||
old_active_layer_collection = bpy.context.view_layer.active_layer_collection
|
||||
old_active_layer_collection = view_layer.active_layer_collection
|
||||
|
||||
layers = view_layer.layer_collection.children
|
||||
|
||||
# Get the layer collection from the collection we need to export.
|
||||
# This is needed because in Blender you can only set the active
|
||||
# This is needed because in Blender you can only set the active
|
||||
# collection with the layer collection, and there is no way to get
|
||||
# the layer collection from the collection (but there is the vice versa).
|
||||
layer_collections = [layer for layer in bpy.context.view_layer.layer_collection.children if layer.collection == collections[0]]
|
||||
# the layer collection from the collection
|
||||
# (but there is the vice versa).
|
||||
layer_collections = [
|
||||
layer for layer in layers if layer.collection == collections[0]]
|
||||
|
||||
assert len(layer_collections) == 1
|
||||
|
||||
bpy.context.view_layer.active_layer_collection = layer_collections[0]
|
||||
view_layer.active_layer_collection = layer_collections[0]
|
||||
|
||||
old_scale = bpy.context.scene.unit_settings.scale_length
|
||||
old_scale = scene.unit_settings.scale_length
|
||||
|
||||
# We set the scale of the scene for the export
|
||||
bpy.context.scene.unit_settings.scale_length = 0.01
|
||||
scene.unit_settings.scale_length = 0.01
|
||||
|
||||
armatures = [obj for obj in collections[0].objects if obj.type == 'ARMATURE']
|
||||
armatures = [
|
||||
obj for obj in collections[0].objects if obj.type == 'ARMATURE']
|
||||
|
||||
object_action_pairs = []
|
||||
original_actions = []
|
||||
|
|
@ -68,15 +78,15 @@ class ExtractAnimationFBX(pype.api.Extractor):
|
|||
|
||||
curr_frame_range = curr_action.frame_range
|
||||
|
||||
starting_frames.append( curr_frame_range[0] )
|
||||
ending_frames.append( curr_frame_range[1] )
|
||||
starting_frames.append(curr_frame_range[0])
|
||||
ending_frames.append(curr_frame_range[1])
|
||||
|
||||
object_action_pairs.append((obj, copy_action))
|
||||
original_actions.append(curr_action)
|
||||
|
||||
# We compute the starting and ending frames
|
||||
max_frame = min( starting_frames )
|
||||
min_frame = max( ending_frames )
|
||||
max_frame = min(starting_frames)
|
||||
min_frame = max(ending_frames)
|
||||
|
||||
# We bake the copy of the current action for each object
|
||||
bpy_extras.anim_utils.bake_action_objects(
|
||||
|
|
@ -95,21 +105,24 @@ class ExtractAnimationFBX(pype.api.Extractor):
|
|||
add_leaf_bones=False
|
||||
)
|
||||
|
||||
bpy.context.view_layer.active_layer_collection = old_active_layer_collection
|
||||
view_layer.active_layer_collection = old_active_layer_collection
|
||||
|
||||
bpy.context.scene.unit_settings.scale_length = old_scale
|
||||
scene.unit_settings.scale_length = old_scale
|
||||
|
||||
# We delete the baked action and set the original one back
|
||||
for i in range(0, len(object_action_pairs)):
|
||||
|
||||
if original_actions[i]:
|
||||
pair = object_action_pairs[i]
|
||||
action = original_actions[i]
|
||||
|
||||
object_action_pairs[i][0].animation_data.action = original_actions[i]
|
||||
if action:
|
||||
|
||||
if object_action_pairs[i][1]:
|
||||
pair[0].animation_data.action = action
|
||||
|
||||
object_action_pairs[i][1].user_clear()
|
||||
bpy.data.actions.remove(object_action_pairs[i][1])
|
||||
if pair[1]:
|
||||
|
||||
pair[1].user_clear()
|
||||
bpy.data.actions.remove(pair[1])
|
||||
|
||||
if "representations" not in instance.data:
|
||||
instance.data["representations"] = []
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue