Skip to content

Commit

Permalink
Version 0.7.0
Browse files Browse the repository at this point in the history
Purpose: Ensure that empty objects with children are included in the FBX export, preserving the parent-child relationship upon re-import.

Changes:

Handling Empty Objects:

Modified the do_export method to include empty objects in the export process.
Added 'EMPTY' to the ex_object_types set, ensuring that both empty objects and their children are exported together.
Parent-Child Relationship Preservation:

By including empty objects during export, the parent-child hierarchy is maintained when the FBX file is re-imported into Blender or another 3D software.
Material Handling:

Updated the remove_materials method to avoid errors when processing objects without mesh data, such as empty objects.
  • Loading branch information
erondiel authored Aug 17, 2024
1 parent 7b147b8 commit 7bd39fd
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 40 deletions.
32 changes: 16 additions & 16 deletions __init__.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
bl_info = {
"name" : "Batex",
"author" : "jayanam",
"author" : "jayanam, Rodrigo Camacho (forked from jayanam)",
"descrtion" : "Batch export as Fbx",
"blender" : (2, 80, 0),
"version" : (0, 6, 0, 0),
"version" : (0, 7, 0, 0),
"location" : "Batex panel",
"warning" : "",
"category" : "Import-Export"
Expand All @@ -16,17 +16,17 @@
from . bex_op import *
from . bex_folder_op import *

bpy.types.Scene.export_folder = StringProperty(name="Export folder",
subtype="DIR_PATH",
description="Directory to export the fbx files into")
bpy.types.Scene.export_folder = StringProperty(name="Export folder",
subtype="DIR_PATH",
description="Directory to export the fbx files into")

bpy.types.Scene.center_transform = BoolProperty(name="Center transform",
default=True,
description="Set the pivot point of the object to the center")
default=True,
description="Set the pivot point of the object to the center")

bpy.types.Scene.apply_transform = BoolProperty(name="Apply transform",
default=True,
description="Applies scale and transform (Experimental)")
default=True,
description="Applies scale and transform (Experimental)")

bpy.types.Scene.export_smoothing = EnumProperty(
name="Smoothing",
Expand All @@ -35,21 +35,21 @@
('EDGE', 'Edge', 'Write edge smoothing',0),
('FACE', 'Face', 'Write face smoothing',1),
('OFF', 'Normals Only', 'Write normals only',2)
),
),
default='OFF'
)
)

bpy.types.Scene.export_animations = BoolProperty(name="Export Rig & Animations",
default=False,
description="Export rig and animations")
default=False,
description="Export rig and animations")

bpy.types.Scene.one_material_ID = BoolProperty(name="One material ID",
default=True,
description="Export just one material per object")
default=True,
description="Export just one material per object")

classes = ( BATEX_PT_Panel, BATEX_OT_Operator, BATEX_OT_OpenFolder )

register, unregister = bpy.utils.register_classes_factory(classes)

if __name__ == "__main__":
register()
51 changes: 27 additions & 24 deletions bex_export.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,15 @@ def do_center(self, obj):
return None

def remove_materials(self, obj):
if obj.type == 'ARMATURE':
# Check if the object has mesh data and is not an armature
if obj.type != 'MESH' or obj.data is None:
return False

mat_count = len(obj.data.materials)

if mat_count > 1 and self.__one_material_id:

# Save material ids for faces
bpy.ops.object.mode_set(mode='EDIT')

bm = bmesh.from_edit_mesh(obj.data)

for face in bm.faces:
Expand All @@ -58,6 +57,7 @@ def remove_materials(self, obj):
else:
return False


def restore_materials(self, obj):

# Restore the materials for the object
Expand Down Expand Up @@ -86,7 +86,7 @@ def do_export(self):
bpy.ops.object.mode_set(mode='OBJECT')

for obj in self.__export_objects:
bpy.ops.object.select_all(action='DESELECT')
bpy.ops.object.select_all(action='DESELECT')
obj.select_set(state=True)

# Center selected object
Expand All @@ -96,31 +96,34 @@ def do_export(self):
for child in get_children(obj):
child.select_set(state=True)

# Remove materials except the last one
materials_removed = self.remove_materials(obj)
# Include empty objects in the export
ex_object_types = {'MESH', 'EMPTY'}

ex_object_types = { 'MESH' }

if(self.__export_animations):
if self.__export_animations:
ex_object_types.add('ARMATURE')

# Export the selected object as fbx
bpy.ops.export_scene.fbx(check_existing=False,
filepath=self.__export_folder + "/" + obj.name + ".fbx",
filter_glob="*.fbx",
use_selection=True,
object_types=ex_object_types,
bake_anim=self.__export_animations,
bake_anim_use_all_bones=self.__export_animations,
bake_anim_use_all_actions=self.__export_animations,
use_armature_deform_only=True,
bake_space_transform=self.__apply_transform,
mesh_smooth_type=self.__context.scene.export_smoothing,
add_leaf_bones=False,
path_mode='ABSOLUTE')
# Remove materials except the last one
materials_removed = self.remove_materials(obj)

# Export the selected object and its children as fbx
bpy.ops.export_scene.fbx(
check_existing=False,
filepath=os.path.join(self.__export_folder, f"{obj.name}.fbx"),
filter_glob="*.fbx",
use_selection=True,
object_types=ex_object_types,
bake_anim=self.__export_animations,
bake_anim_use_all_bones=self.__export_animations,
bake_anim_use_all_actions=self.__export_animations,
use_armature_deform_only=True,
bake_space_transform=self.__apply_transform,
mesh_smooth_type=self.__context.scene.export_smoothing,
add_leaf_bones=False,
path_mode='ABSOLUTE'
)

if materials_removed:
self.restore_materials(obj)

if old_pos is not None:
set_object_to_loc(obj, old_pos)
set_object_to_loc(obj, old_pos)

0 comments on commit 7bd39fd

Please sign in to comment.