Archived
1
Fork 0
This repository has been archived on 2025-04-12. You can view files and clone it, but cannot push or open issues or pull requests.
prism/addon/addon.py
2020-08-11 12:07:21 -04:00

226 lines
7.8 KiB
Python

bl_info = {
"name": "Prism Asset Pipeline",
"blender": (2, 80, 0),
"location": "File > Import-Export",
"category": "Import-Export"
}
import bpy
from bpy.types import Operator, AddonPreferences
from bpy.props import StringProperty, BoolProperty, PointerProperty
from bpy_extras.io_utils import (
ExportHelper,
)
import subprocess
class MarkExportOperator(bpy.types.Operator):
bl_idname = "scene.mark_export_operator"
bl_label = "Mark All Objects for Export"
def execute(self, context):
for ob in context.scene.objects:
if ob.type == 'MESH':
ob.willExport = True
return {'FINISHED'}
class HelloWorldPanel(bpy.types.Panel):
bl_idname = "OBJECT_PT_hello_world"
bl_label = "Prism Asset Pipeline"
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_context = "object"
def draw(self, context):
self.layout.prop(context.object, "modelContainer", text="Model Group")
self.layout.prop(context.object, "willExport", text="Will Export")
self.layout.prop(context.object, "exportArmature", text="Export Armature")
self.layout.prop(context.object, "exportAnim", text="Export Animations")
class ExportSettingsPanel(bpy.types.Panel):
bl_idname = "OBJECT_PT_prism_srttings"
bl_label = "Prism Asset Pipeline"
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_context = "scene"
def draw(self, context):
self.layout.operator("scene.mark_export_operator")
self.layout.prop(context.scene, "export_prefix", text="Export Prefix")
self.layout.prop(context.scene, "removeTransforms", text="Remove Transforms")
def console_get():
for area in bpy.context.screen.areas:
if area.type == 'CONSOLE':
for space in area.spaces:
if space.type == 'CONSOLE':
return area, space
return None, None
def console_write(text):
area, space = console_get()
if space is None:
return
context = bpy.context.copy()
context.update(dict(
space=space,
area=area,
))
for line in text.split("\n"):
bpy.ops.console.scrollback_append(context, text=line, type='OUTPUT')
class ExampleAddonPreferences(AddonPreferences):
bl_idname = __name__
def update_func(self, context):
if "//" in self.modelCompilerPath:
self.modelCompilerPath = bpy.path.abspath(self.modelCompilerPath)
if "//" in self.dataExportPath:
self.dataExportPath = bpy.path.abspath(self.dataExportPath)
modelCompilerPath = StringProperty(
name="Model Compiler Path",
subtype='FILE_PATH',
update=update_func
)
dataExportPath = StringProperty(
name="Data Export Path",
subtype='DIR_PATH',
update=update_func
)
def draw(self, context):
layout = self.layout
layout.prop(self, "modelCompilerPath")
layout.prop(self, "dataExportPath")
class ExportAssetPipeline(bpy.types.Operator):
bl_idname = "prism.export_pipeline"
bl_label = "Export Prism Engine"
action = bpy.props.StringProperty(default="EVERYTHING")
def execute(self, context):
preferences = context.preferences
addon_prefs = preferences.addons[__name__].preferences
if len(addon_prefs.modelCompilerPath) == 0 or len(addon_prefs.dataExportPath) == 0:
console_write("No modelS compiler or export path!")
return {'FINISHED'}
model_compiler = bpy.path.abspath(addon_prefs.modelCompilerPath)
export_groups = {}
for object in context.scene.objects:
if object.willExport:
if not object.modelContainer in export_groups:
export_groups[object.modelContainer] = {}
export_groups[object.modelContainer]["objects"] = []
console_write("exporting " + object.name + " as " + object.modelContainer)
export_groups[object.modelContainer]["objects"].append(object.name)
if object.exportArmature is not None:
export_groups[object.modelContainer]["armature"] = object.exportArmature.name
console_write(str(export_groups))
for group in export_groups.keys():
bpy.ops.object.select_all(action='DESELECT')
will_export_anim = False
if "armature" in export_groups[group]:
object = context.scene.objects[export_groups[group]["armature"]]
object.select_set(state=True)
for object_name in export_groups[group]["objects"]:
object = context.scene.objects[object_name]
if object.exportAnim == True:
will_export_anim = True
object.select_set(state=True)
name_part = context.scene.export_prefix + group
fbx_path = "//" + name_part + ".fbx"
fbx_path = bpy.path.abspath(fbx_path)
if self.action == 'ONLY_MESH':
will_export_anim = False
options_dict = {'filepath': fbx_path,
'check_existing': False,
'use_selection': True,
'bake_anim': will_export_anim,
'apply_unit_scale': True,
'add_leaf_bones': False,
'use_armature_deform_only': True,
'mesh_smooth_type': 'OFF',
'bake_space_transform': context.scene.removeTransforms,
'use_tspace': True
}
if context.scene.removeTransforms:
#options_dict['bake_space_transform'] =True
bpy.ops.export_scene.fbx(**options_dict)
else:
bpy.ops.export_scene.fbx(**options_dict)
args = [model_compiler, "--no_ui", "--model-path", fbx_path, "--data-path", bpy.path.abspath(addon_prefs.dataExportPath)]
if context.scene.removeTransforms:
args.append("--compile-static")
p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
output, errors = p.communicate()
return {'FINISHED'}
class PrismExportSubMenu(bpy.types.Menu):
bl_idname = "OBJECT_MT_prism_export_submenu"
bl_label = "Prism Asset Pipeline"
def draw(self, context):
self.layout.operator(ExportAssetPipeline.bl_idname, text="Everything").action = 'EVERYTHING'
self.layout.operator(ExportAssetPipeline.bl_idname, text="Only Meshes").action = 'ONLY_MESH'
def menu_func_export(self, context):
self.layout.menu(PrismExportSubMenu.bl_idname)
def register():
bpy.utils.register_class(HelloWorldPanel)
bpy.utils.register_class(ExportSettingsPanel)
bpy.utils.register_class(ExportAssetPipeline)
bpy.utils.register_class(MarkExportOperator)
bpy.utils.register_class(PrismExportSubMenu)
# properties
bpy.types.Object.modelContainer = StringProperty()
bpy.types.Object.willExport = BoolProperty()
bpy.types.Object.exportAnim = BoolProperty()
bpy.types.Scene.export_prefix = StringProperty()
bpy.types.Scene.removeTransforms = BoolProperty()
bpy.types.Object.exportArmature = PointerProperty(type=bpy.types.Object)
bpy.types.TOPBAR_MT_file_export.append(menu_func_export)
bpy.utils.register_class(ExampleAddonPreferences)
def unregister():
bpy.utils.unregister_class(HelloWorldPanel)
bpy.types.TOPBAR_MT_file_export.remove(menu_func_export)
bpy.utils.unregister_class(ExportAssetPipeline)
bpy.utils.unregister_class(ExampleAddonPreferences)
bpy.utils.unregister_class(MarkExportOperator)
if __name__ == "__main__":
register()