Skip to content

Commit c4f495a

Browse files
authored
Add files via upload
1 parent fb56192 commit c4f495a

File tree

1 file changed

+270
-0
lines changed

1 file changed

+270
-0
lines changed

export_actions.py

Lines changed: 270 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,270 @@
1+
bl_info = {
2+
"name": "FBX Action Exporter (Full Settings)",
3+
"author": "You",
4+
"version": (2, 2),
5+
"blender": (4, 0, 0),
6+
"location": "View3D > Sidebar > Armature Tools",
7+
"description": "FBX exporter for all actions with full export settings and collapsible layout",
8+
"category": "Import-Export",
9+
}
10+
11+
import bpy
12+
import os
13+
from bpy.types import Operator, Panel, PropertyGroup
14+
from bpy.props import *
15+
16+
class FBXExportSettings(PropertyGroup):
17+
export_path: StringProperty(name="Export Path", subtype="DIR_PATH")
18+
19+
# Transform
20+
global_scale: FloatProperty(name="Scale", default=1.0, min=0.001, max=1000.0)
21+
apply_scale_options: EnumProperty(
22+
name="Apply Scalings",
23+
items=[
24+
('FBX_SCALE_NONE', "All Local", ""),
25+
('FBX_SCALE_UNITS', "FBX Units Scale", ""),
26+
('FBX_SCALE_CUSTOM', "FBX Custom Scale", ""),
27+
('FBX_SCALE_ALL', "FBX All", "")
28+
],
29+
default='FBX_SCALE_NONE'
30+
)
31+
axis_forward: EnumProperty(
32+
name="Forward",
33+
items=[(x, x, "") for x in ['X', 'Y', 'Z', '-X', '-Y', '-Z']],
34+
default='-Z'
35+
)
36+
axis_up: EnumProperty(
37+
name="Up",
38+
items=[(x, x, "") for x in ['X', 'Y', 'Z', '-X', '-Y', '-Z']],
39+
default='Y'
40+
)
41+
apply_unit_scale: BoolProperty(name="Apply Unit")
42+
use_space_transform: BoolProperty(name="Use Space Transform", default=True)
43+
bake_space_transform: BoolProperty(name="Apply Transform")
44+
45+
# Geometry
46+
mesh_smooth_type: EnumProperty(
47+
name="Smoothing",
48+
items=[('OFF', "Normals Only", ""), ('FACE', "Face", ""), ('EDGE', "Edge", "")],
49+
default='OFF'
50+
)
51+
use_subsurf: BoolProperty(name="Export Subdivision Surface")
52+
use_mesh_modifiers: BoolProperty(name="Apply Modifiers", default=True)
53+
use_mesh_edges: BoolProperty(name="Loose Edges")
54+
use_triangles: BoolProperty(name="Triangulate Faces")
55+
use_tspace: BoolProperty(name="Tangent Space")
56+
colors_type: EnumProperty(
57+
name="Vertex Colors",
58+
items=[('NONE', "None", ""), ('SRGB', "sRGB", ""), ('LINEAR', "Linear", "")],
59+
default='SRGB'
60+
)
61+
prioritize_active_color: BoolProperty(name="Prioritize Active Color")
62+
63+
# Armature
64+
use_armature_deform_only: BoolProperty(name="Only Deform Bones")
65+
add_leaf_bones: BoolProperty(name="Add Leaf Bones", default=True)
66+
armature_nodetype: EnumProperty(
67+
name="Armature FBXNode Type",
68+
items=[('NULL', "Null", ""), ('ROOT', "Root", ""), ('LIMBNODE', "LimbNode", "")],
69+
default='NULL'
70+
)
71+
primary_bone_axis: EnumProperty(
72+
name="Primary Bone Axis",
73+
items=[(x, x, "") for x in ['X', 'Y', 'Z', '-X', '-Y', '-Z']],
74+
default='Y'
75+
)
76+
secondary_bone_axis: EnumProperty(
77+
name="Secondary Bone Axis",
78+
items=[(x, x, "") for x in ['X', 'Y', 'Z', '-X', '-Y', '-Z']],
79+
default='X'
80+
)
81+
82+
class FBX_PT_export_main(Panel):
83+
bl_label = "FBX Action Export"
84+
bl_idname = "FBX_PT_export_main"
85+
bl_space_type = 'VIEW_3D'
86+
bl_region_type = 'UI'
87+
bl_category = "Armature Tools"
88+
89+
def draw(self, context):
90+
pass
91+
92+
class FBX_PT_path(Panel):
93+
bl_label = "Export Path"
94+
bl_parent_id = "FBX_PT_export_main"
95+
bl_space_type = 'VIEW_3D'
96+
bl_region_type = 'UI'
97+
bl_category = "Armature Tools"
98+
bl_options = {'DEFAULT_CLOSED'}
99+
100+
def draw(self, context):
101+
layout = self.layout
102+
layout.prop(context.scene.fbx_export, "export_path")
103+
104+
class FBX_PT_transform(Panel):
105+
bl_label = "Transform"
106+
bl_parent_id = "FBX_PT_export_main"
107+
bl_space_type = 'VIEW_3D'
108+
bl_region_type = 'UI'
109+
bl_category = "Armature Tools"
110+
bl_options = {'DEFAULT_CLOSED'}
111+
112+
def draw(self, context):
113+
p = context.scene.fbx_export
114+
layout = self.layout
115+
layout.prop(p, "global_scale")
116+
layout.prop(p, "apply_scale_options")
117+
layout.prop(p, "axis_forward")
118+
layout.prop(p, "axis_up")
119+
layout.prop(p, "apply_unit_scale")
120+
layout.prop(p, "use_space_transform")
121+
layout.prop(p, "bake_space_transform")
122+
123+
class FBX_PT_geometry(Panel):
124+
bl_label = "Geometry"
125+
bl_parent_id = "FBX_PT_export_main"
126+
bl_space_type = 'VIEW_3D'
127+
bl_region_type = 'UI'
128+
bl_category = "Armature Tools"
129+
bl_options = {'DEFAULT_CLOSED'}
130+
131+
def draw(self, context):
132+
p = context.scene.fbx_export
133+
layout = self.layout
134+
layout.prop(p, "mesh_smooth_type")
135+
layout.prop(p, "use_subsurf")
136+
layout.prop(p, "use_mesh_modifiers")
137+
layout.prop(p, "use_mesh_edges")
138+
layout.prop(p, "use_triangles")
139+
layout.prop(p, "use_tspace")
140+
layout.prop(p, "colors_type")
141+
layout.prop(p, "prioritize_active_color")
142+
143+
class FBX_PT_armature(Panel):
144+
bl_label = "Armature"
145+
bl_parent_id = "FBX_PT_export_main"
146+
bl_space_type = 'VIEW_3D'
147+
bl_region_type = 'UI'
148+
bl_category = "Armature Tools"
149+
bl_options = {'DEFAULT_CLOSED'}
150+
151+
def draw(self, context):
152+
p = context.scene.fbx_export
153+
layout = self.layout
154+
layout.prop(p, "primary_bone_axis")
155+
layout.prop(p, "secondary_bone_axis")
156+
layout.prop(p, "armature_nodetype")
157+
layout.prop(p, "use_armature_deform_only")
158+
layout.prop(p, "add_leaf_bones")
159+
160+
class FBX_PT_export_button(Panel):
161+
bl_label = "Export"
162+
bl_parent_id = "FBX_PT_export_main"
163+
bl_space_type = 'VIEW_3D'
164+
bl_region_type = 'UI'
165+
bl_category = "Armature Tools"
166+
bl_options = {'DEFAULT_CLOSED'}
167+
168+
def draw(self, context):
169+
layout = self.layout
170+
layout.operator("export_fbx.actions", text="Export All Actions")
171+
172+
class ExportAllActionsOperator(Operator):
173+
bl_idname = "export_fbx.actions"
174+
bl_label = "Export All Actions"
175+
176+
def execute(self, context):
177+
obj = context.object
178+
p = context.scene.fbx_export
179+
180+
if not obj or obj.type != 'ARMATURE':
181+
self.report({'ERROR'}, "Select an Armature")
182+
return {'CANCELLED'}
183+
184+
if not p.export_path:
185+
self.report({'ERROR'}, "Set an export directory")
186+
return {'CANCELLED'}
187+
188+
if not obj.animation_data:
189+
obj.animation_data_create()
190+
191+
scene = context.scene
192+
old_start = scene.frame_start
193+
old_end = scene.frame_end
194+
exported = 0
195+
196+
for action in bpy.data.actions:
197+
if not action.use_fake_user:
198+
continue
199+
200+
start = int(action.frame_range[0])
201+
end = int(action.frame_range[1])
202+
track = obj.animation_data.nla_tracks.new()
203+
track.name = f"TEMP_{action.name}"
204+
strip = track.strips.new(action.name, start, action)
205+
strip.action_frame_start = start
206+
strip.action_frame_end = end
207+
208+
scene.frame_start = start
209+
scene.frame_end = end
210+
filepath = os.path.join(p.export_path, f"{action.name}.fbx")
211+
212+
try:
213+
bpy.ops.export_scene.fbx(
214+
filepath=filepath,
215+
global_scale=p.global_scale,
216+
apply_scale_options=p.apply_scale_options,
217+
axis_forward=p.axis_forward,
218+
axis_up=p.axis_up,
219+
apply_unit_scale=p.apply_unit_scale,
220+
use_space_transform=p.use_space_transform,
221+
bake_space_transform=p.bake_space_transform,
222+
mesh_smooth_type=p.mesh_smooth_type,
223+
use_subsurf=p.use_subsurf,
224+
use_mesh_modifiers=p.use_mesh_modifiers,
225+
use_mesh_edges=p.use_mesh_edges,
226+
use_triangles=p.use_triangles,
227+
use_tspace=p.use_tspace,
228+
colors_type=p.colors_type,
229+
prioritize_active_color=p.prioritize_active_color,
230+
object_types={'ARMATURE'},
231+
use_armature_deform_only=p.use_armature_deform_only,
232+
add_leaf_bones=p.add_leaf_bones,
233+
armature_nodetype=p.armature_nodetype,
234+
primary_bone_axis=p.primary_bone_axis,
235+
secondary_bone_axis=p.secondary_bone_axis
236+
)
237+
exported += 1
238+
except Exception as e:
239+
self.report({'WARNING'}, f"Export failed: {action.name}: {e}")
240+
241+
obj.animation_data.nla_tracks.remove(track)
242+
243+
scene.frame_start = old_start
244+
scene.frame_end = old_end
245+
self.report({'INFO'}, f"Exported {exported} actions")
246+
return {'FINISHED'}
247+
248+
classes = [
249+
FBXExportSettings,
250+
FBX_PT_export_main,
251+
FBX_PT_path,
252+
FBX_PT_transform,
253+
FBX_PT_geometry,
254+
FBX_PT_armature,
255+
FBX_PT_export_button,
256+
ExportAllActionsOperator
257+
]
258+
259+
def register():
260+
for cls in classes:
261+
bpy.utils.register_class(cls)
262+
bpy.types.Scene.fbx_export = PointerProperty(type=FBXExportSettings)
263+
264+
def unregister():
265+
for cls in reversed(classes):
266+
bpy.utils.unregister_class(cls)
267+
del bpy.types.Scene.fbx_export
268+
269+
if __name__ == "__main__":
270+
register()

0 commit comments

Comments
 (0)