2024-01-29 13:21:04 -05:00
|
|
|
import bpy
|
2024-04-15 13:23:17 -04:00
|
|
|
from bpy.types import Collection, LayerCollection, Object, Armature
|
|
|
|
|
|
|
|
# Enter object mode
|
|
|
|
bpy.ops.object.mode_set(mode='OBJECT')
|
|
|
|
|
|
|
|
# FIRST, toggle collections
|
|
|
|
collections_exportable = [
|
|
|
|
"insurrectionist", "infantry", "rigging", "geometry", "grapple", "baton", "helmet", "gun", "jetpack"
|
|
|
|
]
|
|
|
|
def toggle_collection(coll: LayerCollection):
|
|
|
|
# Iterate over all child LayerCollections
|
|
|
|
for child in coll.children.values():
|
|
|
|
c: LayerCollection = child
|
|
|
|
|
|
|
|
# Force include/exclude character-related collections so they're included/excluded from export
|
|
|
|
c.exclude = not (c.name in collections_exportable)
|
|
|
|
if c.name == "insurrectionist" or c.name == "infantry":
|
|
|
|
bpy.context.view_layer.active_layer_collection = c
|
|
|
|
toggle_collection(bpy.context.view_layer.layer_collection)
|
|
|
|
|
|
|
|
# Find rig to make it active
|
|
|
|
armatureObj: Object = None
|
|
|
|
for objBase in bpy.context.scene.objects:
|
|
|
|
# print(objBase)
|
|
|
|
obj: Object = objBase
|
|
|
|
# print(obj.data)
|
|
|
|
if obj.type == 'ARMATURE':
|
|
|
|
print("FOUND AN ARMATURE")
|
|
|
|
armatureObj = obj
|
|
|
|
obj.select_set(True)
|
|
|
|
bpy.context.active_object
|
|
|
|
print(bpy.context.active_object)
|
|
|
|
#bpy.context.active_object.animation_data.nla_tracks
|
|
|
|
|
|
|
|
exit()
|
2024-01-29 13:21:04 -05:00
|
|
|
|
|
|
|
# Get export directory
|
2024-03-01 01:07:12 -05:00
|
|
|
path: str = bpy.data.filepath.replace('\\Shelby', '').replace('\\Tommy', '')
|
2024-01-29 13:21:04 -05:00
|
|
|
pathPrefix = max(path.rfind('animations/'), path.rfind('animations\\'))
|
|
|
|
pathStart = pathPrefix + len('animations/')
|
|
|
|
pathEnd = max(path.rfind('/'), path.rfind('\\'))
|
|
|
|
|
|
|
|
# Figure out who made these animations based on filepath
|
|
|
|
fileIndividual = ''
|
|
|
|
if 'tommy' in path:
|
|
|
|
fileIndividual = 'tommy'
|
|
|
|
elif 'shelby' in path:
|
|
|
|
fileIndividual = 'shelby'
|
|
|
|
elif 'alan' in path:
|
|
|
|
fileIndividual = 'alan'
|
|
|
|
|
|
|
|
# Build export filepath
|
|
|
|
dirName = path[pathStart:pathEnd]
|
|
|
|
filePath = path[:pathPrefix] + 'export\\' + dirName + '\\anims_' + dirName + '_' + fileIndividual + '.fbx'
|
|
|
|
|
|
|
|
|
|
|
|
# RIG MUST BE ACTIVE
|
|
|
|
armature = bpy.context.active_object.data
|
2024-03-05 23:39:01 -05:00
|
|
|
# Set all bone layers, INCLUDING mechanical bones, to be visible
|
2024-01-29 13:21:04 -05:00
|
|
|
for i in range(0, 29):
|
|
|
|
armature.layers[i] = True
|
|
|
|
for i in range(29,32):
|
2024-03-05 23:39:01 -05:00
|
|
|
armature.layers[i] = True
|
|
|
|
|
|
|
|
# Use BoneJuice to bake down all actions
|
2024-03-23 12:31:33 -04:00
|
|
|
# bpy.ops.bj.anim_bakeall()
|
2024-03-05 23:39:01 -05:00
|
|
|
|
|
|
|
# Make armature local so we can clear all constraints
|
2024-03-23 12:31:33 -04:00
|
|
|
# bpy.ops.object.mode_set(mode='OBJECT')
|
|
|
|
# bpy.ops.object.make_local(type='SELECT_OBDATA')
|
2024-01-29 13:21:04 -05:00
|
|
|
|
2024-03-05 23:39:01 -05:00
|
|
|
# Clear all posing and pose constraints
|
2024-03-29 00:08:37 -04:00
|
|
|
bpy.ops.object.mode_set(mode='POSE') # Enter pose mode
|
|
|
|
bpy.ops.pose.select_all(action='SELECT')
|
2024-03-23 12:31:33 -04:00
|
|
|
# bpy.ops.pose.constraints_clear() # Clear all constraints
|
2024-03-29 00:08:37 -04:00
|
|
|
bpy.ops.pose.transforms_clear() # Clear all transforms
|
2024-01-29 13:21:04 -05:00
|
|
|
|
|
|
|
# Export animations
|
|
|
|
bpy.ops.export_scene.fbx(
|
|
|
|
# I/O
|
|
|
|
filepath = filePath,
|
|
|
|
check_existing = False,
|
|
|
|
path_mode = 'STRIP',
|
|
|
|
batch_mode = 'OFF',
|
|
|
|
use_visible = True,
|
|
|
|
object_types = {'MESH', 'ARMATURE'},
|
|
|
|
axis_forward = '-Y',
|
|
|
|
axis_up = 'Z',
|
|
|
|
|
|
|
|
# Mesh Settings
|
|
|
|
use_mesh_modifiers = True,
|
|
|
|
use_mesh_modifiers_render = False,
|
|
|
|
use_triangles = True,
|
|
|
|
colors_type = 'NONE',
|
|
|
|
|
|
|
|
# Animation
|
|
|
|
use_armature_deform_only = True,
|
|
|
|
add_leaf_bones = True,
|
|
|
|
bake_anim = True,
|
|
|
|
bake_anim_use_all_bones = True,
|
|
|
|
bake_anim_use_nla_strips = False,
|
|
|
|
bake_anim_use_all_actions = True,
|
|
|
|
bake_anim_force_startend_keying = True,
|
2024-03-05 23:39:01 -05:00
|
|
|
bake_anim_simplify_factor = 0.0,
|
2024-01-29 13:21:04 -05:00
|
|
|
)
|
|
|
|
|
|
|
|
bpy.ops.pose.transforms_clear() # Clear all transforms
|
|
|
|
bpy.ops.object.mode_set(mode='OBJECT')
|
|
|
|
|
|
|
|
## FOR DEBUGGING, see https://blender.stackexchange.com/questions/93728/blender-script-run-print-to-console
|
|
|
|
# from bpy import context
|
|
|
|
# import builtins as __builtin__
|
|
|
|
# def console_print(*args, **kwargs):
|
|
|
|
# for a in context.screen.areas:
|
|
|
|
# if a.type == 'CONSOLE':
|
|
|
|
# c = {}
|
|
|
|
# c['area'] = a
|
|
|
|
# c['space_data'] = a.spaces.active
|
|
|
|
# c['region'] = a.regions[-1]
|
|
|
|
# c['window'] = context.window
|
|
|
|
# c['screen'] = context.screen
|
|
|
|
# s = " ".join([str(arg) for arg in args])
|
|
|
|
# for line in s.split("\n"):
|
|
|
|
# bpy.ops.console.scrollback_append(c, text=line)
|
|
|
|
|
|
|
|
# def print(*args, **kwargs):
|
|
|
|
# """Console print() function."""
|
|
|
|
# console_print(*args, **kwargs) # to py consoles
|
|
|
|
# __builtin__.print(*args, **kwargs) # to system console
|