390 lines
14 KiB
Python
390 lines
14 KiB
Python
from ..config import ADDON_MODULE_NAME
|
|
|
|
from typing import Optional, List, Tuple
|
|
import bpy
|
|
|
|
|
|
def get_addon_preferences() -> 'WBS_AP_Preferences':
|
|
"""
|
|
Gets current Blender addon preferences for this addon in any context.
|
|
:return: Addon preferences.
|
|
"""
|
|
return bpy.context.preferences.addons[ADDON_MODULE_NAME].preferences
|
|
|
|
|
|
def get_project_preferences() -> Optional['WBS_PG_ProjectPreferences']:
|
|
"""
|
|
Gets current project preferences in any context.
|
|
:return: Project preferences or None.
|
|
"""
|
|
addon_preferences = get_addon_preferences()
|
|
|
|
if not len(addon_preferences.projects):
|
|
raise UserWarning("No active project. Check WBS settings.")
|
|
|
|
return addon_preferences.projects[addon_preferences.active_project_index]
|
|
|
|
|
|
class WBS_UL_Projects(bpy.types.UIList):
|
|
""" UI List displaying currently saved projects. """
|
|
|
|
def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
|
|
split = layout.split(factor=0.3)
|
|
split.prop(item, "name", text="", emboss=False, translate=False
|
|
, icon='RADIOBUT_ON' if index == data.active_project_index else 'RADIOBUT_OFF')
|
|
|
|
def invoke(self, context, event):
|
|
...
|
|
|
|
class WBS_PG_ExportMethodSetting(bpy.types.PropertyGroup):
|
|
""" Property group for individual export method settings. """
|
|
|
|
name: bpy.props.StringProperty(
|
|
name="Export Setting Name",
|
|
description="Name of the export folder setting"
|
|
)
|
|
|
|
value: bpy.props.StringProperty(
|
|
name="Export Directory Path",
|
|
description="Value of the export folder setting",
|
|
subtype='DIR_PATH'
|
|
)
|
|
|
|
class WBS_PG_ProjectPreferences(bpy.types.PropertyGroup):
|
|
""" Property group holding data for project preferences set. """
|
|
|
|
wow_path: bpy.props.StringProperty(
|
|
name="WoW Client Path",
|
|
subtype='DIR_PATH'
|
|
)
|
|
|
|
wmv_path: bpy.props.StringProperty(
|
|
name="WoW Model Viewer Log Path",
|
|
subtype='FILE_PATH'
|
|
)
|
|
|
|
wow_export_path: bpy.props.StringProperty(
|
|
name="WoW Export Runtimelog Path",
|
|
subtype='FILE_PATH'
|
|
)
|
|
|
|
noggit_red_path: bpy.props.StringProperty(
|
|
name="Noggit Red log Path",
|
|
subtype='FILE_PATH'
|
|
)
|
|
|
|
time_import_method: bpy.props.EnumProperty(
|
|
name="Time Conversion Import Method",
|
|
items=[
|
|
('Convert', "Convert to 30 FPS", "(WBS Method)"),
|
|
('Keep Original', "Keep_Original", "Don't convert timestamps"),
|
|
],
|
|
default='Convert',
|
|
description="Choose the preferred method for timestamp import."
|
|
)
|
|
|
|
import_method: bpy.props.EnumProperty(
|
|
name="Import Method",
|
|
items=[
|
|
('WMV', "WMV", "Use WoW Model Viewer"),
|
|
('WowExport', "WowExport", "Use WoW Export"),
|
|
('NoggitRed', "NoggitRed", "Use Noggit Red"),
|
|
],
|
|
default='WMV',
|
|
description="Choose the preferred method of import for WoW files."
|
|
)
|
|
|
|
export_method_settings: bpy.props.CollectionProperty(
|
|
type=WBS_PG_ExportMethodSetting,
|
|
name="Export Folder Settings",
|
|
description="Settings for the export methods"
|
|
)
|
|
|
|
export_dir_path: bpy.props.StringProperty(
|
|
name="Export Directory Path",
|
|
description="A directory for WBS to export M2/WBS, could be ascension Data client, or a patch folder inside it.",
|
|
subtype="DIR_PATH"
|
|
)
|
|
|
|
active_export_method_index: bpy.props.IntProperty(default=0)
|
|
|
|
def update_export_dir_path(self, context):
|
|
method = self.export_method_settings[int(self.export_method_enum)]
|
|
self.active_export_method_index = int(self.export_method_enum)
|
|
self.export_dir_path = method.value
|
|
|
|
def export_method_items(self, context) -> List[Tuple[str, str, str]]:
|
|
return [(str(i), method.name, "") for i, method in enumerate(self.export_method_settings)]
|
|
|
|
export_method_enum: bpy.props.EnumProperty(
|
|
name="Export Method",
|
|
description="Select Export Method",
|
|
items=export_method_items,
|
|
update=update_export_dir_path
|
|
)
|
|
|
|
cache_dir_path: bpy.props.StringProperty(
|
|
name="Cache Directory Path",
|
|
description="Any folder that can be used to store textures and other temporary files.",
|
|
subtype="DIR_PATH"
|
|
)
|
|
|
|
project_dir_path: bpy.props.StringProperty(
|
|
name="Project Directory Path",
|
|
description="A directory Blender saves WoW files to and treats it as top-priority patch.",
|
|
subtype="DIR_PATH"
|
|
)
|
|
|
|
merge_vertices: bpy.props.BoolProperty(
|
|
name="Merge Vertices Algorythm when quick saving M2's",
|
|
description="Use the merge vertices algorythm when quick saving m2's with topbar button",
|
|
default=True
|
|
)
|
|
|
|
verbosity_level: bpy.props.EnumProperty(
|
|
name="Log Verbosity",
|
|
description="Controls how detailed output messages should be",
|
|
items=[
|
|
('1', "ERROR", "Only show critical errors"),
|
|
('2', "WARNING", "Show warnings and errors"),
|
|
('3', "INFO", "Show general info, warnings, and errors"),
|
|
('4', "DEBUG", "Show all messages including debug output"),
|
|
],
|
|
default='3',
|
|
options=set()
|
|
)
|
|
|
|
scene_type: bpy.props.EnumProperty(
|
|
name="Default Scene Type",
|
|
description="Controls which scene type should be the default",
|
|
items=[
|
|
('M2', "M2", "Default to M2"),
|
|
('WMO', "WMO", "Default to WMO"),
|
|
],
|
|
default='WMO',
|
|
options=set()
|
|
)
|
|
|
|
class WBS_OT_ProjectListActions(bpy.types.Operator):
|
|
"""
|
|
Moves items up and down the list of projects, adds or removes.
|
|
"""
|
|
|
|
bl_idname = "wbs.project_list_action"
|
|
bl_label = "List Actions"
|
|
bl_description = "Move items up and down, add and remove"
|
|
bl_options = {'REGISTER', 'INTERNAL'}
|
|
|
|
action: bpy.props.EnumProperty(
|
|
items=(
|
|
('UP', "Up", ""),
|
|
('DOWN', "Down", ""),
|
|
('REMOVE', "Remove", ""),
|
|
('ADD', "Add", ""),
|
|
('DUPLICATE', "Duplicate", "")))
|
|
|
|
@classmethod
|
|
def description(cls, context, properties):
|
|
match properties.action:
|
|
case 'UP':
|
|
return "Move project up the list"
|
|
case 'DOWN':
|
|
return "Move project down the list"
|
|
case 'ADD':
|
|
return "Add new project"
|
|
case 'DUPLICATE':
|
|
return "Duplicate current project"
|
|
case 'REMOVE':
|
|
return "Remove project from the list"
|
|
case _:
|
|
raise NotImplementedError()
|
|
|
|
def duplicate_project(self, source, target):
|
|
target.name = f"{source.name}_copy"
|
|
target.verbosity_level = source.verbosity_level
|
|
target.scene_type = source.scene_type
|
|
target.wow_path = source.wow_path
|
|
target.wmv_path = source.wmv_path
|
|
target.wow_export_path = source.wow_export_path
|
|
target.noggit_red_path = source.noggit_red_path
|
|
target.time_import_method = source.time_import_method
|
|
target.import_method = source.import_method
|
|
target.cache_dir_path = source.cache_dir_path
|
|
target.project_dir_path = source.project_dir_path
|
|
target.export_dir_path = source.export_dir_path
|
|
target.merge_vertices = source.merge_vertices
|
|
|
|
for setting in source.export_method_settings:
|
|
new_setting = target.export_method_settings.add()
|
|
new_setting.name = setting.name
|
|
new_setting.value = setting.value
|
|
|
|
def invoke(self, context, event):
|
|
addon_prefs = get_addon_preferences()
|
|
idx = addon_prefs.active_project_index
|
|
|
|
match self.action:
|
|
case 'DOWN':
|
|
if idx < len(addon_prefs.projects) - 1:
|
|
addon_prefs.projects.move(idx, idx + 1)
|
|
addon_prefs.active_project_index += 1
|
|
case 'UP':
|
|
if idx >= 1:
|
|
addon_prefs.projects.move(idx, idx - 1)
|
|
addon_prefs.active_project_index -= 1
|
|
case 'REMOVE':
|
|
if len(addon_prefs.projects):
|
|
addon_prefs.active_project_index -= 1
|
|
addon_prefs.projects.remove(idx)
|
|
case 'ADD':
|
|
item = addon_prefs.projects.add()
|
|
item.name = 'New project'
|
|
addon_prefs.active_project_index = len(addon_prefs.projects) - 1
|
|
case 'DUPLICATE':
|
|
if len(addon_prefs.projects):
|
|
source = addon_prefs.projects[idx]
|
|
target = addon_prefs.projects.add()
|
|
self.duplicate_project(source, target)
|
|
addon_prefs.active_project_index = len(addon_prefs.projects) - 1
|
|
|
|
return {"FINISHED"}
|
|
|
|
class WBS_UL_Export(bpy.types.UIList):
|
|
""" UI List displaying currently saved export methods. """
|
|
|
|
def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
|
|
split = layout.split(factor=0.3)
|
|
split.prop(item, "name", text="", emboss=False, translate=False
|
|
, icon='RADIOBUT_ON' if index == data.active_export_method_index else 'RADIOBUT_OFF')
|
|
|
|
def invoke(self, context, event):
|
|
...
|
|
|
|
class WBS_OT_ExportMethodActions(bpy.types.Operator):
|
|
"""
|
|
Adds or removes export method settings.
|
|
"""
|
|
|
|
bl_idname = "wbs.export_method_action"
|
|
bl_label = "Export Method Actions"
|
|
bl_description = "Add or remove export method settings"
|
|
bl_options = {'REGISTER', 'INTERNAL'}
|
|
|
|
action: bpy.props.EnumProperty(
|
|
items=(
|
|
('UP', "Up", ""),
|
|
('DOWN', "Down", ""),
|
|
('ADD', "Add", ""),
|
|
('REMOVE', "Remove", "")))
|
|
|
|
@classmethod
|
|
def description(cls, context, properties):
|
|
match properties.action:
|
|
case 'UP':
|
|
return "Move project up the list"
|
|
case 'DOWN':
|
|
return "Move project down the list"
|
|
case 'ADD':
|
|
return "Add new export method setting"
|
|
case 'REMOVE':
|
|
return "Remove selected export method setting"
|
|
case _:
|
|
raise NotImplementedError()
|
|
|
|
def invoke(self, context, event):
|
|
proj_prefs = get_project_preferences()
|
|
idx = proj_prefs.active_export_method_index
|
|
|
|
match self.action:
|
|
case 'DOWN':
|
|
if idx < len(proj_prefs.export_method_settings) - 1:
|
|
proj_prefs.export_method_settings.move(idx, idx + 1)
|
|
proj_prefs.active_export_method_index += 1
|
|
case 'UP':
|
|
if idx >= 1:
|
|
proj_prefs.export_method_settings.move(idx, idx - 1)
|
|
proj_prefs.active_export_method_index -= 1
|
|
case 'ADD':
|
|
item = proj_prefs.export_method_settings.add()
|
|
item.name = 'New setting'
|
|
item.value = ''
|
|
proj_prefs.active_export_method_index = len(proj_prefs.export_method_settings) - 1
|
|
case 'REMOVE':
|
|
if len(proj_prefs.export_method_settings):
|
|
proj_prefs.export_method_settings.remove(idx)
|
|
proj_prefs.active_export_method_index -= 1
|
|
|
|
return {"FINISHED"}
|
|
|
|
class WBS_AP_Preferences(bpy.types.AddonPreferences):
|
|
"""
|
|
Stores global preferences for the addon.
|
|
"""
|
|
|
|
bl_idname = 'io_scene_wmo'
|
|
|
|
projects: bpy.props.CollectionProperty(
|
|
type=WBS_PG_ProjectPreferences,
|
|
name='Projects',
|
|
description='Project presets.',
|
|
options=set()
|
|
)
|
|
|
|
active_project_index: bpy.props.IntProperty(default=0)
|
|
|
|
def draw(self, context: bpy.types.Context):
|
|
layout = self.layout
|
|
|
|
row = layout.row()
|
|
row.template_list('WBS_UL_Projects', '', self, 'projects', self, 'active_project_index', rows=2)
|
|
|
|
col = row.column(align=True)
|
|
col.operator("wbs.project_list_action", text="Create project").action = 'ADD'
|
|
col.operator("wbs.project_list_action", text="Duplicate project").action = 'DUPLICATE'
|
|
col.operator("wbs.project_list_action", text="Remove project").action = 'REMOVE'
|
|
col.separator()
|
|
col.operator("wbs.project_list_action", icon='TRIA_UP', text="").action = 'UP'
|
|
col.operator("wbs.project_list_action", icon='TRIA_DOWN', text="").action = 'DOWN'
|
|
col.separator()
|
|
|
|
if proj_prefs := get_project_preferences():
|
|
col = layout.column(align=True)
|
|
col.label(text='Project settings:', icon='SETTINGS')
|
|
box = col.box()
|
|
box.prop(proj_prefs, 'wow_path')
|
|
box.prop(proj_prefs, 'time_import_method')
|
|
box.prop(proj_prefs, 'import_method')
|
|
if proj_prefs.import_method == 'WMV':
|
|
box.prop(proj_prefs, 'wmv_path')
|
|
elif proj_prefs.import_method == 'WowExport':
|
|
box.prop(proj_prefs, 'wow_export_path')
|
|
elif proj_prefs.import_method == 'NoggitRed':
|
|
box.prop(proj_prefs, 'noggit_red_path')
|
|
box.prop(proj_prefs, 'cache_dir_path')
|
|
box.prop(proj_prefs, 'project_dir_path')
|
|
box.prop(proj_prefs, 'export_method_enum', text='Export Directory Path')
|
|
box.prop(proj_prefs, "verbosity_level")
|
|
box.prop(proj_prefs, "scene_type")
|
|
|
|
col = layout.column(align=True)
|
|
col.label(text='Export Folder Settings:', icon='SETTINGS')
|
|
row = col.row()
|
|
row.template_list('WBS_UL_Export', '', proj_prefs, 'export_method_settings', proj_prefs, 'active_export_method_index')
|
|
|
|
sub_col = row.column(align=True)
|
|
sub_col.operator("wbs.export_method_action", text="", icon='ADD').action = 'ADD'
|
|
sub_col.operator("wbs.export_method_action", text="", icon='REMOVE').action = 'REMOVE'
|
|
|
|
sub_col.operator("wbs.export_method_action", icon='TRIA_UP', text="").action = 'UP'
|
|
sub_col.operator("wbs.export_method_action", icon='TRIA_DOWN', text="").action = 'DOWN'
|
|
|
|
if proj_prefs.export_method_settings:
|
|
setting = proj_prefs.export_method_settings[proj_prefs.active_export_method_index]
|
|
box = col.box()
|
|
box.prop(setting, 'name')
|
|
box.prop(setting, 'value')
|
|
col.separator()
|
|
col = layout.column(align=True)
|
|
col.label(text='M2 Quick Save Settings:', icon='SETTINGS')
|
|
box = col.box()
|
|
box.prop(proj_prefs, 'merge_vertices', text='Merge Vertices') |