FBX IO: Add file handler #105212
@ -43,6 +43,65 @@ from bpy_extras.io_utils import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class FBX_Import_Draw:
|
||||||
|
@staticmethod
|
||||||
|
def include(layout, context, operator):
|
||||||
|
layout.use_property_split = True
|
||||||
|
layout.use_property_decorate = False # No animation.
|
||||||
|
|
||||||
|
layout.prop(operator, "use_custom_normals")
|
||||||
|
layout.prop(operator, "use_subsurf")
|
||||||
|
layout.prop(operator, "use_custom_props")
|
||||||
|
sub = layout.row()
|
||||||
|
sub.enabled = operator.use_custom_props
|
||||||
|
sub.prop(operator, "use_custom_props_enum_as_string")
|
||||||
|
layout.prop(operator, "use_image_search")
|
||||||
|
layout.prop(operator, "colors_type")
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def transform(layout, context, operator):
|
||||||
|
layout.use_property_split = True
|
||||||
|
layout.use_property_decorate = False # No animation.
|
||||||
|
|
||||||
|
layout.prop(operator, "global_scale")
|
||||||
|
layout.prop(operator, "decal_offset")
|
||||||
|
row = layout.row()
|
||||||
|
row.prop(operator, "bake_space_transform")
|
||||||
|
row.label(text="", icon='ERROR')
|
||||||
|
layout.prop(operator, "use_prepost_rot")
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def transform_manual_orientation(layout, context, operator):
|
||||||
|
layout.use_property_split = True
|
||||||
|
layout.use_property_decorate = False # No animation.
|
||||||
|
|
||||||
|
layout.enabled = operator.use_manual_orientation
|
||||||
|
|
||||||
|
layout.prop(operator, "axis_forward")
|
||||||
|
layout.prop(operator, "axis_up")
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def animation(layout, context, operator):
|
||||||
|
layout.use_property_split = True
|
||||||
|
layout.use_property_decorate = False # No animation.
|
||||||
|
|
||||||
|
layout.enabled = operator.use_anim
|
||||||
|
|
||||||
|
layout.prop(operator, "anim_offset")
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def armature(layout, context, operator):
|
||||||
|
layout.use_property_split = True
|
||||||
|
layout.use_property_decorate = False # No animation.
|
||||||
|
|
||||||
|
layout.prop(operator, "ignore_leaf_bones")
|
||||||
|
layout.prop(operator, "force_connect_children"),
|
||||||
|
layout.prop(operator, "automatic_bone_orientation"),
|
||||||
|
sub = layout.column()
|
||||||
|
sub.enabled = not operator.automatic_bone_orientation
|
||||||
|
sub.prop(operator, "primary_bone_axis")
|
||||||
|
sub.prop(operator, "secondary_bone_axis")
|
||||||
|
|
||||||
@orientation_helper(axis_forward='-Z', axis_up='Y')
|
@orientation_helper(axis_forward='-Z', axis_up='Y')
|
||||||
class ImportFBX(bpy.types.Operator, ImportHelper):
|
class ImportFBX(bpy.types.Operator, ImportHelper):
|
||||||
"""Load a FBX file"""
|
"""Load a FBX file"""
|
||||||
@ -50,7 +109,8 @@ class ImportFBX(bpy.types.Operator, ImportHelper):
|
|||||||
bl_label = "Import FBX"
|
bl_label = "Import FBX"
|
||||||
bl_options = {'UNDO', 'PRESET'}
|
bl_options = {'UNDO', 'PRESET'}
|
||||||
|
|
||||||
directory: StringProperty()
|
filepath: StringProperty(subtype='FILE_PATH', options={'SKIP_PRESET'})
|
||||||
|
directory: StringProperty(options={'SKIP_PRESET'})
|
||||||
|
|
||||||
filename_ext = ".fbx"
|
filename_ext = ".fbx"
|
||||||
filter_glob: StringProperty(default="*.fbx", options={'HIDDEN'})
|
filter_glob: StringProperty(default="*.fbx", options={'HIDDEN'})
|
||||||
@ -58,6 +118,7 @@ class ImportFBX(bpy.types.Operator, ImportHelper):
|
|||||||
files: CollectionProperty(
|
files: CollectionProperty(
|
||||||
name="File Path",
|
name="File Path",
|
||||||
type=bpy.types.OperatorFileListElement,
|
type=bpy.types.OperatorFileListElement,
|
||||||
|
options={'SKIP_PRESET'}
|
||||||
)
|
)
|
||||||
|
|
||||||
ui_tab: EnumProperty(
|
ui_tab: EnumProperty(
|
||||||
@ -193,7 +254,41 @@ class ImportFBX(bpy.types.Operator, ImportHelper):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def draw(self, context):
|
def draw(self, context):
|
||||||
pass
|
space = context.space_data
|
||||||
|
if space and space.type == 'FILE_BROWSER' and space.active_operator == self:
|
||||||
|
return
|
||||||
|
|
||||||
|
layout = self.layout
|
||||||
|
|
||||||
|
box = layout.box()
|
||||||
|
box.row().label(text="Include")
|
||||||
|
FBX_Import_Draw.include(box.column(), context, self)
|
||||||
|
|
||||||
|
box = layout.box()
|
||||||
|
box.row().label(text="Transform")
|
||||||
|
FBX_Import_Draw.transform(box.column(), context, self)
|
||||||
|
|
||||||
|
box.row().prop(self, "use_manual_orientation")
|
||||||
|
FBX_Import_Draw.transform_manual_orientation(box.column(), context, self)
|
||||||
|
|
||||||
|
box = layout.box()
|
||||||
|
box.row().prop(self, "use_anim")
|
||||||
|
FBX_Import_Draw.animation(box.column(), context, self)
|
||||||
|
|
||||||
|
box = layout.box()
|
||||||
|
box.row().label(text="Armature")
|
||||||
|
FBX_Import_Draw.armature(box.column(), context, self)
|
||||||
|
|
||||||
|
def invoke(self, context, event):
|
||||||
|
if self.properties.is_property_set("filepath"):
|
||||||
|
title = self.filepath
|
||||||
|
if len(self.files) > 1:
|
||||||
|
title = "Import %d files" % len(self.files)
|
||||||
|
context.window_manager.invoke_props_dialog(self, confirm_text="Import FBX", title=title)
|
||||||
|
return {'RUNNING_MODAL'}
|
||||||
|
context.window_manager.fileselect_add(self)
|
||||||
|
return {'RUNNING_MODAL'}
|
||||||
|
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
keywords = self.as_keywords(ignore=("filter_glob", "directory", "ui_tab", "filepath", "files"))
|
keywords = self.as_keywords(ignore=("filter_glob", "directory", "ui_tab", "filepath", "files"))
|
||||||
@ -227,22 +322,8 @@ class FBX_PT_import_include(bpy.types.Panel):
|
|||||||
return operator.bl_idname == "IMPORT_SCENE_OT_fbx"
|
return operator.bl_idname == "IMPORT_SCENE_OT_fbx"
|
||||||
|
|
||||||
def draw(self, context):
|
def draw(self, context):
|
||||||
layout = self.layout
|
|
||||||
layout.use_property_split = True
|
|
||||||
layout.use_property_decorate = False # No animation.
|
|
||||||
|
|
||||||
sfile = context.space_data
|
sfile = context.space_data
|
||||||
operator = sfile.active_operator
|
FBX_Import_Draw.include(self.layout,context, sfile.active_operator)
|
||||||
|
|
||||||
layout.prop(operator, "use_custom_normals")
|
|
||||||
layout.prop(operator, "use_subsurf")
|
|
||||||
layout.prop(operator, "use_custom_props")
|
|
||||||
sub = layout.row()
|
|
||||||
sub.enabled = operator.use_custom_props
|
|
||||||
sub.prop(operator, "use_custom_props_enum_as_string")
|
|
||||||
layout.prop(operator, "use_image_search")
|
|
||||||
layout.prop(operator, "colors_type")
|
|
||||||
|
|
||||||
|
|
||||||
class FBX_PT_import_transform(bpy.types.Panel):
|
class FBX_PT_import_transform(bpy.types.Panel):
|
||||||
bl_space_type = 'FILE_BROWSER'
|
bl_space_type = 'FILE_BROWSER'
|
||||||
@ -258,19 +339,9 @@ class FBX_PT_import_transform(bpy.types.Panel):
|
|||||||
return operator.bl_idname == "IMPORT_SCENE_OT_fbx"
|
return operator.bl_idname == "IMPORT_SCENE_OT_fbx"
|
||||||
|
|
||||||
def draw(self, context):
|
def draw(self, context):
|
||||||
layout = self.layout
|
|
||||||
layout.use_property_split = True
|
|
||||||
layout.use_property_decorate = False # No animation.
|
|
||||||
|
|
||||||
sfile = context.space_data
|
sfile = context.space_data
|
||||||
operator = sfile.active_operator
|
FBX_Import_Draw.transform(self.layout,context, sfile.active_operator)
|
||||||
|
|
||||||
layout.prop(operator, "global_scale")
|
|
||||||
layout.prop(operator, "decal_offset")
|
|
||||||
row = layout.row()
|
|
||||||
row.prop(operator, "bake_space_transform")
|
|
||||||
row.label(text="", icon='ERROR')
|
|
||||||
layout.prop(operator, "use_prepost_rot")
|
|
||||||
|
|
||||||
|
|
||||||
class FBX_PT_import_transform_manual_orientation(bpy.types.Panel):
|
class FBX_PT_import_transform_manual_orientation(bpy.types.Panel):
|
||||||
@ -293,17 +364,9 @@ class FBX_PT_import_transform_manual_orientation(bpy.types.Panel):
|
|||||||
self.layout.prop(operator, "use_manual_orientation", text="")
|
self.layout.prop(operator, "use_manual_orientation", text="")
|
||||||
|
|
||||||
def draw(self, context):
|
def draw(self, context):
|
||||||
layout = self.layout
|
|
||||||
layout.use_property_split = True
|
|
||||||
layout.use_property_decorate = False # No animation.
|
|
||||||
|
|
||||||
sfile = context.space_data
|
sfile = context.space_data
|
||||||
operator = sfile.active_operator
|
FBX_Import_Draw.transform_manual_orientation(self.layout,context, sfile.active_operator)
|
||||||
|
|
||||||
layout.enabled = operator.use_manual_orientation
|
|
||||||
|
|
||||||
layout.prop(operator, "axis_forward")
|
|
||||||
layout.prop(operator, "axis_up")
|
|
||||||
|
|
||||||
|
|
||||||
class FBX_PT_import_animation(bpy.types.Panel):
|
class FBX_PT_import_animation(bpy.types.Panel):
|
||||||
@ -327,16 +390,9 @@ class FBX_PT_import_animation(bpy.types.Panel):
|
|||||||
self.layout.prop(operator, "use_anim", text="")
|
self.layout.prop(operator, "use_anim", text="")
|
||||||
|
|
||||||
def draw(self, context):
|
def draw(self, context):
|
||||||
layout = self.layout
|
|
||||||
layout.use_property_split = True
|
|
||||||
layout.use_property_decorate = False # No animation.
|
|
||||||
|
|
||||||
sfile = context.space_data
|
sfile = context.space_data
|
||||||
operator = sfile.active_operator
|
FBX_Import_Draw.animation(self.layout,context, sfile.active_operator)
|
||||||
|
|
||||||
layout.enabled = operator.use_anim
|
|
||||||
|
|
||||||
layout.prop(operator, "anim_offset")
|
|
||||||
|
|
||||||
|
|
||||||
class FBX_PT_import_armature(bpy.types.Panel):
|
class FBX_PT_import_armature(bpy.types.Panel):
|
||||||
@ -354,20 +410,8 @@ class FBX_PT_import_armature(bpy.types.Panel):
|
|||||||
return operator.bl_idname == "IMPORT_SCENE_OT_fbx"
|
return operator.bl_idname == "IMPORT_SCENE_OT_fbx"
|
||||||
|
|
||||||
def draw(self, context):
|
def draw(self, context):
|
||||||
layout = self.layout
|
|
||||||
layout.use_property_split = True
|
|
||||||
layout.use_property_decorate = False # No animation.
|
|
||||||
|
|
||||||
sfile = context.space_data
|
sfile = context.space_data
|
||||||
operator = sfile.active_operator
|
FBX_Import_Draw.armature(self.layout,context, sfile.active_operator)
|
||||||
|
|
||||||
layout.prop(operator, "ignore_leaf_bones")
|
|
||||||
layout.prop(operator, "force_connect_children"),
|
|
||||||
layout.prop(operator, "automatic_bone_orientation"),
|
|
||||||
sub = layout.column()
|
|
||||||
sub.enabled = not operator.automatic_bone_orientation
|
|
||||||
sub.prop(operator, "primary_bone_axis")
|
|
||||||
sub.prop(operator, "secondary_bone_axis")
|
|
||||||
|
|
||||||
|
|
||||||
@orientation_helper(axis_forward='-Z', axis_up='Y')
|
@orientation_helper(axis_forward='-Z', axis_up='Y')
|
||||||
@ -871,9 +915,19 @@ def menu_func_import(self, context):
|
|||||||
def menu_func_export(self, context):
|
def menu_func_export(self, context):
|
||||||
self.layout.operator(ExportFBX.bl_idname, text="FBX (.fbx)")
|
self.layout.operator(ExportFBX.bl_idname, text="FBX (.fbx)")
|
||||||
|
|
||||||
|
class IO_FH_fbx_import(bpy.types.FileHandler):
|
||||||
|
bl_idname = "IO_FH_fbx"
|
||||||
|
bl_label = "FBX"
|
||||||
|
bl_import_operator = "import_scene.fbx"
|
||||||
|
bl_file_extensions = ".fbx"
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def poll_drop(cls, context):
|
||||||
|
return (context.area and context.area.type == 'VIEW_3D')
|
||||||
|
|
||||||
classes = (
|
classes = (
|
||||||
ImportFBX,
|
ImportFBX,
|
||||||
|
IO_FH_fbx_import,
|
||||||
FBX_PT_import_include,
|
FBX_PT_import_include,
|
||||||
FBX_PT_import_transform,
|
FBX_PT_import_transform,
|
||||||
FBX_PT_import_transform_manual_orientation,
|
FBX_PT_import_transform_manual_orientation,
|
||||||
|
Loading…
Reference in New Issue
Block a user