feat: update virtools file importer and exporter
- use panel to organise property group in virtools file importer and exporter. - move all ballance params and virtools params into ioport_shared module and enable different showcase according to the argument passed to show function presenting whether current window is importer or exporter. - add multiple type ignore to ignore the error of bpy operator member field type hints.
This commit is contained in:
parent
fe47861bd0
commit
729e12ed7b
@ -3,44 +3,15 @@ from bpy_extras.wm_utils.progress_report import ProgressReport
|
|||||||
import tempfile, os, typing
|
import tempfile, os, typing
|
||||||
from . import PROP_preferences, UTIL_ioport_shared
|
from . import PROP_preferences, UTIL_ioport_shared
|
||||||
from . import UTIL_virtools_types, UTIL_functions, UTIL_file_browser, UTIL_blender_mesh, UTIL_ballance_texture, UTIL_icons_manager, UTIL_naming_convension
|
from . import UTIL_virtools_types, UTIL_functions, UTIL_file_browser, UTIL_blender_mesh, UTIL_ballance_texture, UTIL_icons_manager, UTIL_naming_convension
|
||||||
from . import PROP_virtools_group, PROP_virtools_material, PROP_virtools_mesh, PROP_virtools_texture, PROP_ballance_map_info
|
from . import PROP_virtools_group, PROP_virtools_material, PROP_virtools_mesh, PROP_virtools_texture
|
||||||
from .PyBMap import bmap_wrapper as bmap
|
from .PyBMap import bmap_wrapper as bmap
|
||||||
|
|
||||||
# define global tex save opt blender enum prop helper
|
class BBP_OT_export_virtools(bpy.types.Operator, UTIL_file_browser.ExportVirtoolsFile, UTIL_ioport_shared.ExportParams, UTIL_ioport_shared.VirtoolsParams, UTIL_ioport_shared.BallanceParams):
|
||||||
_g_EnumHelper_CK_TEXTURE_SAVEOPTIONS: UTIL_virtools_types.EnumPropHelper = UTIL_virtools_types.EnumPropHelper(UTIL_virtools_types.CK_TEXTURE_SAVEOPTIONS)
|
|
||||||
|
|
||||||
class BBP_OT_export_virtools(bpy.types.Operator, UTIL_file_browser.ExportVirtoolsFile, UTIL_ioport_shared.ExportParams, UTIL_ioport_shared.VirtoolsParams):
|
|
||||||
"""Export Virtools File"""
|
"""Export Virtools File"""
|
||||||
bl_idname = "bbp.export_virtools"
|
bl_idname = "bbp.export_virtools"
|
||||||
bl_label = "Export Virtools File"
|
bl_label = "Export Virtools File"
|
||||||
bl_options = {'PRESET'}
|
bl_options = {'PRESET'}
|
||||||
|
|
||||||
texture_save_opt: bpy.props.EnumProperty(
|
|
||||||
name = "Global Texture Save Options",
|
|
||||||
description = "Decide how texture saved if texture is specified as Use Global as its Save Options.",
|
|
||||||
items = _g_EnumHelper_CK_TEXTURE_SAVEOPTIONS.generate_items(),
|
|
||||||
default = _g_EnumHelper_CK_TEXTURE_SAVEOPTIONS.to_selection(UTIL_virtools_types.CK_TEXTURE_SAVEOPTIONS.CKTEXTURE_EXTERNAL)
|
|
||||||
) # type: ignore
|
|
||||||
|
|
||||||
use_compress: bpy.props.BoolProperty(
|
|
||||||
name="Use Compress",
|
|
||||||
description = "Whether use ZLib to compress result when saving composition.",
|
|
||||||
default = True,
|
|
||||||
) # type: ignore
|
|
||||||
|
|
||||||
compress_level: bpy.props.IntProperty(
|
|
||||||
name = "Compress Level",
|
|
||||||
description = "The ZLib compress level used by Virtools Engine when saving composition.",
|
|
||||||
min = 1, max = 9,
|
|
||||||
default = 5,
|
|
||||||
) # type: ignore
|
|
||||||
|
|
||||||
successive_sector: bpy.props.BoolProperty(
|
|
||||||
name="Successive Sector",
|
|
||||||
description = "Whether order exporter to use document specified sector count to make sure sector is successive.",
|
|
||||||
default = True,
|
|
||||||
) # type: ignore
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def poll(self, context):
|
def poll(self, context):
|
||||||
return (
|
return (
|
||||||
@ -58,15 +29,26 @@ class BBP_OT_export_virtools(bpy.types.Operator, UTIL_file_browser.ExportVirtool
|
|||||||
)
|
)
|
||||||
return {'CANCELLED'}
|
return {'CANCELLED'}
|
||||||
|
|
||||||
|
# check texture save option to prevent real stupid user.
|
||||||
|
texture_save_opt = self.general_get_texture_save_opt()
|
||||||
|
if texture_save_opt == UTIL_virtools_types.CK_TEXTURE_SAVEOPTIONS.CKTEXTURE_USEGLOBAL:
|
||||||
|
UTIL_functions.message_box(
|
||||||
|
('You can not specify "Use Global" as global texture save option!', ),
|
||||||
|
'Wrong Parameters',
|
||||||
|
UTIL_icons_manager.BlenderPresetIcons.Error.value
|
||||||
|
)
|
||||||
|
return {'CANCELLED'}
|
||||||
|
|
||||||
# start exporting
|
# start exporting
|
||||||
with UTIL_ioport_shared.ExportEditModeBackup() as editmode_guard:
|
with UTIL_ioport_shared.ExportEditModeBackup() as editmode_guard:
|
||||||
_export_virtools(
|
_export_virtools(
|
||||||
self.general_get_filename(),
|
self.general_get_filename(),
|
||||||
self.general_get_vt_encodings(),
|
self.general_get_vt_encodings(),
|
||||||
_g_EnumHelper_CK_TEXTURE_SAVEOPTIONS.get_selection(self.texture_save_opt),
|
texture_save_opt,
|
||||||
self.use_compress,
|
self.general_get_use_compress(),
|
||||||
self.compress_level,
|
self.general_get_compress_level(),
|
||||||
self.successive_sector,
|
self.general_get_successive_sector(),
|
||||||
|
self.general_get_successive_sector_count(),
|
||||||
objls
|
objls
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -75,30 +57,9 @@ class BBP_OT_export_virtools(bpy.types.Operator, UTIL_file_browser.ExportVirtool
|
|||||||
|
|
||||||
def draw(self, context):
|
def draw(self, context):
|
||||||
layout = self.layout
|
layout = self.layout
|
||||||
layout.label(text = 'Export Target')
|
self.draw_export_params(layout)
|
||||||
self.draw_export_params(layout.box())
|
self.draw_virtools_params(layout, False)
|
||||||
|
self.draw_ballance_params(layout, False)
|
||||||
layout.separator()
|
|
||||||
layout.label(text = 'Virtools Params')
|
|
||||||
box = layout.box()
|
|
||||||
self.draw_virtools_params(box)
|
|
||||||
|
|
||||||
box.separator()
|
|
||||||
box.label(text = 'Global Texture Save Option')
|
|
||||||
box.prop(self, 'texture_save_opt', text = '')
|
|
||||||
|
|
||||||
box.separator()
|
|
||||||
box.prop(self, 'use_compress')
|
|
||||||
if self.use_compress:
|
|
||||||
box.prop(self, 'compress_level')
|
|
||||||
|
|
||||||
# show sector info to notice user
|
|
||||||
layout.separator()
|
|
||||||
layout.label(text = 'Ballance Params')
|
|
||||||
box = layout.box()
|
|
||||||
map_info: PROP_ballance_map_info.RawBallanceMapInfo = PROP_ballance_map_info.get_raw_ballance_map_info(bpy.context.scene)
|
|
||||||
box.prop(self, 'successive_sector')
|
|
||||||
box.label(text = f'Map Sectors: {map_info.mSectorCount}')
|
|
||||||
|
|
||||||
_TObj3dPair = tuple[bpy.types.Object, bmap.BM3dObject]
|
_TObj3dPair = tuple[bpy.types.Object, bmap.BM3dObject]
|
||||||
_TMeshPair = tuple[bpy.types.Object, bpy.types.Mesh, bmap.BMMesh]
|
_TMeshPair = tuple[bpy.types.Object, bpy.types.Mesh, bmap.BMMesh]
|
||||||
@ -112,6 +73,7 @@ def _export_virtools(
|
|||||||
use_compress_: bool,
|
use_compress_: bool,
|
||||||
compress_level_: int,
|
compress_level_: int,
|
||||||
successive_sector_: bool,
|
successive_sector_: bool,
|
||||||
|
successive_sector_count_: int,
|
||||||
export_objects: tuple[bpy.types.Object, ...]
|
export_objects: tuple[bpy.types.Object, ...]
|
||||||
) -> None:
|
) -> None:
|
||||||
|
|
||||||
@ -131,7 +93,7 @@ def _export_virtools(
|
|||||||
obj3d_crets: tuple[_TObj3dPair, ...] = _prepare_virtools_3dobjects(
|
obj3d_crets: tuple[_TObj3dPair, ...] = _prepare_virtools_3dobjects(
|
||||||
writer, progress, export_objects)
|
writer, progress, export_objects)
|
||||||
# export group and 3dobject by prepared 3dobject
|
# export group and 3dobject by prepared 3dobject
|
||||||
_export_virtools_groups(writer, progress, successive_sector_, obj3d_crets)
|
_export_virtools_groups(writer, progress, successive_sector_, successive_sector_count_, obj3d_crets)
|
||||||
mesh_crets: tuple[_TMeshPair, ...] = _export_virtools_3dobjects(
|
mesh_crets: tuple[_TMeshPair, ...] = _export_virtools_3dobjects(
|
||||||
writer, progress, obj3d_crets)
|
writer, progress, obj3d_crets)
|
||||||
# export mesh
|
# export mesh
|
||||||
@ -181,6 +143,7 @@ def _export_virtools_groups(
|
|||||||
writer: bmap.BMFileWriter,
|
writer: bmap.BMFileWriter,
|
||||||
progress: ProgressReport,
|
progress: ProgressReport,
|
||||||
successive_sector: bool,
|
successive_sector: bool,
|
||||||
|
successive_sector_count: int,
|
||||||
obj3d_crets: tuple[_TObj3dPair, ...]
|
obj3d_crets: tuple[_TObj3dPair, ...]
|
||||||
) -> None:
|
) -> None:
|
||||||
# create virtools group
|
# create virtools group
|
||||||
@ -197,9 +160,7 @@ def _export_virtools_groups(
|
|||||||
#
|
#
|
||||||
# So we create all needed sector group in here to make sure exported virtools file can be read by Ballancde correctly.
|
# So we create all needed sector group in here to make sure exported virtools file can be read by Ballancde correctly.
|
||||||
if successive_sector:
|
if successive_sector:
|
||||||
map_info: PROP_ballance_map_info.RawBallanceMapInfo
|
for i in range(successive_sector_count):
|
||||||
map_info = PROP_ballance_map_info.get_raw_ballance_map_info(bpy.context.scene)
|
|
||||||
for i in range(map_info.mSectorCount):
|
|
||||||
gp_name: str = UTIL_naming_convension.build_name_from_sector_index(i + 1)
|
gp_name: str = UTIL_naming_convension.build_name_from_sector_index(i + 1)
|
||||||
vtgroup: bmap.BMGroup | None = group_cret_map.get(gp_name, None)
|
vtgroup: bmap.BMGroup | None = group_cret_map.get(gp_name, None)
|
||||||
if vtgroup is None:
|
if vtgroup is None:
|
||||||
|
@ -6,7 +6,7 @@ from . import UTIL_virtools_types, UTIL_functions, UTIL_file_browser, UTIL_blend
|
|||||||
from . import PROP_virtools_group, PROP_virtools_material, PROP_virtools_mesh, PROP_virtools_texture, PROP_ballance_map_info
|
from . import PROP_virtools_group, PROP_virtools_material, PROP_virtools_mesh, PROP_virtools_texture, PROP_ballance_map_info
|
||||||
from .PyBMap import bmap_wrapper as bmap
|
from .PyBMap import bmap_wrapper as bmap
|
||||||
|
|
||||||
class BBP_OT_import_virtools(bpy.types.Operator, UTIL_file_browser.ImportVirtoolsFile, UTIL_ioport_shared.ImportParams, UTIL_ioport_shared.VirtoolsParams):
|
class BBP_OT_import_virtools(bpy.types.Operator, UTIL_file_browser.ImportVirtoolsFile, UTIL_ioport_shared.ImportParams, UTIL_ioport_shared.VirtoolsParams, UTIL_ioport_shared.BallanceParams):
|
||||||
"""Import Virtools File"""
|
"""Import Virtools File"""
|
||||||
bl_idname = "bbp.import_virtools"
|
bl_idname = "bbp.import_virtools"
|
||||||
bl_label = "Import Virtools File"
|
bl_label = "Import Virtools File"
|
||||||
@ -29,11 +29,9 @@ class BBP_OT_import_virtools(bpy.types.Operator, UTIL_file_browser.ImportVirtool
|
|||||||
|
|
||||||
def draw(self, context):
|
def draw(self, context):
|
||||||
layout = self.layout
|
layout = self.layout
|
||||||
layout.label(text = 'Conflict Options')
|
self.draw_import_params(layout)
|
||||||
self.draw_import_params(layout.box())
|
self.draw_virtools_params(layout, True)
|
||||||
layout.separator()
|
self.draw_ballance_params(layout, True)
|
||||||
layout.label(text = 'Virtools Params')
|
|
||||||
self.draw_virtools_params(layout.box())
|
|
||||||
|
|
||||||
def _import_virtools(file_name_: str, encodings_: tuple[str], resolver: UTIL_ioport_shared.ConflictResolver) -> None:
|
def _import_virtools(file_name_: str, encodings_: tuple[str], resolver: UTIL_ioport_shared.ConflictResolver) -> None:
|
||||||
# create temp folder
|
# create temp folder
|
||||||
|
@ -97,12 +97,12 @@ class BBP_PG_ballance_element(bpy.types.PropertyGroup):
|
|||||||
element_id: bpy.props.IntProperty(
|
element_id: bpy.props.IntProperty(
|
||||||
name = "Element Id",
|
name = "Element Id",
|
||||||
default = 0
|
default = 0
|
||||||
)
|
) # type: ignore
|
||||||
|
|
||||||
mesh_ptr: bpy.props.PointerProperty(
|
mesh_ptr: bpy.props.PointerProperty(
|
||||||
name = "Mesh",
|
name = "Mesh",
|
||||||
type = bpy.types.Mesh
|
type = bpy.types.Mesh
|
||||||
)
|
) # type: ignore
|
||||||
|
|
||||||
def get_ballance_elements(scene: bpy.types.Scene) -> bpy.types.CollectionProperty:
|
def get_ballance_elements(scene: bpy.types.Scene) -> bpy.types.CollectionProperty:
|
||||||
return scene.ballance_elements
|
return scene.ballance_elements
|
||||||
|
@ -73,12 +73,12 @@ class BBP_PG_bme_material(bpy.types.PropertyGroup):
|
|||||||
bme_material_name: bpy.props.StringProperty(
|
bme_material_name: bpy.props.StringProperty(
|
||||||
name = "Name",
|
name = "Name",
|
||||||
default = ""
|
default = ""
|
||||||
)
|
) # type: ignore
|
||||||
|
|
||||||
material_ptr: bpy.props.PointerProperty(
|
material_ptr: bpy.props.PointerProperty(
|
||||||
name = "Material",
|
name = "Material",
|
||||||
type = bpy.types.Material
|
type = bpy.types.Material
|
||||||
)
|
) # type: ignore
|
||||||
|
|
||||||
def get_bme_materials(scene: bpy.types.Scene) -> bpy.types.CollectionProperty:
|
def get_bme_materials(scene: bpy.types.Scene) -> bpy.types.CollectionProperty:
|
||||||
return scene.bme_materials
|
return scene.bme_materials
|
||||||
|
@ -24,13 +24,13 @@ class BBPPreferences(bpy.types.AddonPreferences):
|
|||||||
description = "The path to folder which will be used by this plugin to get external Ballance texture.",
|
description = "The path to folder which will be used by this plugin to get external Ballance texture.",
|
||||||
subtype='DIR_PATH',
|
subtype='DIR_PATH',
|
||||||
default = RawPreferences.cBallanceTextureFolder,
|
default = RawPreferences.cBallanceTextureFolder,
|
||||||
)
|
) # type: ignore
|
||||||
|
|
||||||
no_component_collection: bpy.props.StringProperty(
|
no_component_collection: bpy.props.StringProperty(
|
||||||
name = "No Component Collection",
|
name = "No Component Collection",
|
||||||
description = "(Import) The object which stored in this collectiion will not be saved as component. (Export) All forced no component objects will be stored in this collection",
|
description = "(Import) The object which stored in this collectiion will not be saved as component. (Export) All forced no component objects will be stored in this collection",
|
||||||
default = RawPreferences.cNoComponentCollection,
|
default = RawPreferences.cNoComponentCollection,
|
||||||
)
|
) # type: ignore
|
||||||
|
|
||||||
def draw(self, context):
|
def draw(self, context):
|
||||||
layout = self.layout
|
layout = self.layout
|
||||||
|
@ -10,19 +10,19 @@ class BBP_PG_ptrprop_resolver(bpy.types.PropertyGroup):
|
|||||||
name = "Material",
|
name = "Material",
|
||||||
description = "The material used for rail",
|
description = "The material used for rail",
|
||||||
type = bpy.types.Material,
|
type = bpy.types.Material,
|
||||||
)
|
) # type: ignore
|
||||||
|
|
||||||
export_collection: bpy.props.PointerProperty(
|
export_collection: bpy.props.PointerProperty(
|
||||||
type = bpy.types.Collection,
|
type = bpy.types.Collection,
|
||||||
name = "Collection",
|
name = "Collection",
|
||||||
description = "The collection exported. Nested collections allowed."
|
description = "The collection exported. Nested collections allowed."
|
||||||
)
|
) # type: ignore
|
||||||
|
|
||||||
export_object: bpy.props.PointerProperty(
|
export_object: bpy.props.PointerProperty(
|
||||||
type = bpy.types.Object,
|
type = bpy.types.Object,
|
||||||
name = "Object",
|
name = "Object",
|
||||||
description = "The object exported"
|
description = "The object exported"
|
||||||
)
|
) # type: ignore
|
||||||
|
|
||||||
def get_ptrprop_resolver() -> BBP_PG_ptrprop_resolver:
|
def get_ptrprop_resolver() -> BBP_PG_ptrprop_resolver:
|
||||||
return bpy.context.scene.bbp_ptrprop_resolver
|
return bpy.context.scene.bbp_ptrprop_resolver
|
||||||
|
@ -255,19 +255,19 @@ class SharedGroupNameInputProperties():
|
|||||||
('DEFINED', "Predefined", "Pre-defined group name."),
|
('DEFINED', "Predefined", "Pre-defined group name."),
|
||||||
('CUSTOM', "Custom", "User specified group name."),
|
('CUSTOM', "Custom", "User specified group name."),
|
||||||
),
|
),
|
||||||
)
|
) # type: ignore
|
||||||
|
|
||||||
preset_group_name: bpy.props.EnumProperty(
|
preset_group_name: bpy.props.EnumProperty(
|
||||||
name = "Group Name",
|
name = "Group Name",
|
||||||
description = "Pick vanilla Ballance group name.",
|
description = "Pick vanilla Ballance group name.",
|
||||||
items = _g_EnumHelper_Group.generate_items(),
|
items = _g_EnumHelper_Group.generate_items(),
|
||||||
)
|
) # type: ignore
|
||||||
|
|
||||||
custom_group_name: bpy.props.StringProperty(
|
custom_group_name: bpy.props.StringProperty(
|
||||||
name = "Custom Group Name",
|
name = "Custom Group Name",
|
||||||
description = "Input your custom group name.",
|
description = "Input your custom group name.",
|
||||||
default = "",
|
default = "",
|
||||||
)
|
) # type: ignore
|
||||||
|
|
||||||
def draw_group_name_input(self, layout: bpy.types.UILayout) -> None:
|
def draw_group_name_input(self, layout: bpy.types.UILayout) -> None:
|
||||||
layout.prop(self, 'group_name_source', expand = True)
|
layout.prop(self, 'group_name_source', expand = True)
|
||||||
|
@ -25,7 +25,7 @@ class BBP_PG_virtools_mesh(bpy.types.PropertyGroup):
|
|||||||
description = "Lighting mode of the mesh.",
|
description = "Lighting mode of the mesh.",
|
||||||
items = _g_Helper_VXMESH_LITMODE.generate_items(),
|
items = _g_Helper_VXMESH_LITMODE.generate_items(),
|
||||||
default = _g_Helper_VXMESH_LITMODE.to_selection(RawVirtoolsMesh.cDefaultLitMode)
|
default = _g_Helper_VXMESH_LITMODE.to_selection(RawVirtoolsMesh.cDefaultLitMode)
|
||||||
)
|
) # type: ignore
|
||||||
|
|
||||||
# Getter Setter
|
# Getter Setter
|
||||||
|
|
||||||
|
@ -30,14 +30,14 @@ class BBP_PG_virtools_texture(bpy.types.PropertyGroup):
|
|||||||
description = "When saving a composition textures or sprites can be kept as reference to external files or converted to a given format and saved inside the composition file.",
|
description = "When saving a composition textures or sprites can be kept as reference to external files or converted to a given format and saved inside the composition file.",
|
||||||
items = _g_Helper_CK_TEXTURE_SAVEOPTIONS.generate_items(),
|
items = _g_Helper_CK_TEXTURE_SAVEOPTIONS.generate_items(),
|
||||||
default = _g_Helper_CK_TEXTURE_SAVEOPTIONS.to_selection(RawVirtoolsTexture.cDefaultSaveOptions)
|
default = _g_Helper_CK_TEXTURE_SAVEOPTIONS.to_selection(RawVirtoolsTexture.cDefaultSaveOptions)
|
||||||
)
|
) # type: ignore
|
||||||
|
|
||||||
video_format: bpy.props.EnumProperty(
|
video_format: bpy.props.EnumProperty(
|
||||||
name = "Video Format",
|
name = "Video Format",
|
||||||
description = "The desired surface pixel format in video memory.",
|
description = "The desired surface pixel format in video memory.",
|
||||||
items = _g_Helper_VX_PIXELFORMAT.generate_items(),
|
items = _g_Helper_VX_PIXELFORMAT.generate_items(),
|
||||||
default = _g_Helper_VX_PIXELFORMAT.to_selection(RawVirtoolsTexture.cDefaultVideoFormat)
|
default = _g_Helper_VX_PIXELFORMAT.to_selection(RawVirtoolsTexture.cDefaultVideoFormat)
|
||||||
)
|
) # type: ignore
|
||||||
|
|
||||||
#region Virtools Texture Getter Setter
|
#region Virtools Texture Getter Setter
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ class ImportBallanceImage(bpy_extras.io_utils.ImportHelper):
|
|||||||
filter_glob: bpy.props.StringProperty(
|
filter_glob: bpy.props.StringProperty(
|
||||||
default = "*.bmp;*.tga",
|
default = "*.bmp;*.tga",
|
||||||
options = {'HIDDEN'}
|
options = {'HIDDEN'}
|
||||||
)
|
) # type: ignore
|
||||||
|
|
||||||
def general_set_filename(self, filename: str) -> None:
|
def general_set_filename(self, filename: str) -> None:
|
||||||
self.filepath = filename
|
self.filepath = filename
|
||||||
@ -44,7 +44,7 @@ class ImportBmxFile(bpy_extras.io_utils.ImportHelper):
|
|||||||
filter_glob: bpy.props.StringProperty(
|
filter_glob: bpy.props.StringProperty(
|
||||||
default = "*.bmx",
|
default = "*.bmx",
|
||||||
options = {'HIDDEN'}
|
options = {'HIDDEN'}
|
||||||
)
|
) # type: ignore
|
||||||
|
|
||||||
def general_get_filename(self) -> str:
|
def general_get_filename(self) -> str:
|
||||||
return self.filepath
|
return self.filepath
|
||||||
@ -56,7 +56,7 @@ class ExportBmxFile(bpy_extras.io_utils.ExportHelper):
|
|||||||
filter_glob: bpy.props.StringProperty(
|
filter_glob: bpy.props.StringProperty(
|
||||||
default = "*.bmx",
|
default = "*.bmx",
|
||||||
options = {'HIDDEN'}
|
options = {'HIDDEN'}
|
||||||
)
|
) # type: ignore
|
||||||
|
|
||||||
def general_get_filename(self) -> str:
|
def general_get_filename(self) -> str:
|
||||||
return self.filepath
|
return self.filepath
|
||||||
@ -68,7 +68,7 @@ class ImportVirtoolsFile(bpy_extras.io_utils.ImportHelper):
|
|||||||
filter_glob: bpy.props.StringProperty(
|
filter_glob: bpy.props.StringProperty(
|
||||||
default = "*.nmo;*.cmo;*.vmo",
|
default = "*.nmo;*.cmo;*.vmo",
|
||||||
options = {'HIDDEN'}
|
options = {'HIDDEN'}
|
||||||
)
|
) # type: ignore
|
||||||
|
|
||||||
def general_get_filename(self) -> str:
|
def general_get_filename(self) -> str:
|
||||||
return self.filepath
|
return self.filepath
|
||||||
@ -80,7 +80,7 @@ class ExportVirtoolsFile(bpy_extras.io_utils.ExportHelper):
|
|||||||
filter_glob: bpy.props.StringProperty(
|
filter_glob: bpy.props.StringProperty(
|
||||||
default = "*.nmo",
|
default = "*.nmo",
|
||||||
options = {'HIDDEN'}
|
options = {'HIDDEN'}
|
||||||
)
|
) # type: ignore
|
||||||
|
|
||||||
def general_get_filename(self) -> str:
|
def general_get_filename(self) -> str:
|
||||||
return self.filepath
|
return self.filepath
|
||||||
@ -94,7 +94,7 @@ class ImportDirectory(bpy_extras.io_utils.ImportHelper):
|
|||||||
filter_glob: bpy.props.StringProperty(
|
filter_glob: bpy.props.StringProperty(
|
||||||
default = "",
|
default = "",
|
||||||
options = {'HIDDEN'}
|
options = {'HIDDEN'}
|
||||||
)
|
) # type: ignore
|
||||||
|
|
||||||
def general_get_directory(self) -> str:
|
def general_get_directory(self) -> str:
|
||||||
return self.directory
|
return self.directory
|
||||||
|
@ -2,6 +2,10 @@ import bpy, mathutils
|
|||||||
import struct, os, io, typing
|
import struct, os, io, typing
|
||||||
from . import UTIL_virtools_types
|
from . import UTIL_virtools_types
|
||||||
|
|
||||||
|
## MARK:
|
||||||
|
# This module may be deprecated because the host refering this module,
|
||||||
|
# BM file import and export is no longer existing.
|
||||||
|
|
||||||
_FileWriter_t = io.BufferedWriter
|
_FileWriter_t = io.BufferedWriter
|
||||||
_FileReader_t = io.BufferedReader
|
_FileReader_t = io.BufferedReader
|
||||||
|
|
||||||
@ -31,10 +35,10 @@ def write_float(fs: _FileWriter_t, fl: float) -> None:
|
|||||||
fs.write(struct.pack("<f", fl))
|
fs.write(struct.pack("<f", fl))
|
||||||
|
|
||||||
def write_world_matrix(fs: _FileWriter_t, mat: UTIL_virtools_types.VxMatrix) -> None:
|
def write_world_matrix(fs: _FileWriter_t, mat: UTIL_virtools_types.VxMatrix) -> None:
|
||||||
fs.write(struct.pack("<16f", *mat.to_tuple()))
|
fs.write(struct.pack("<16f", *mat.to_const()))
|
||||||
|
|
||||||
def write_color(fs: _FileWriter_t, colors: UTIL_virtools_types.VxColor) -> None:
|
def write_color(fs: _FileWriter_t, colors: UTIL_virtools_types.VxColor) -> None:
|
||||||
fs.write(struct.pack("<fff", *colors.to_tuple_rgb()))
|
fs.write(struct.pack("<fff", *colors.to_const_rgb()))
|
||||||
|
|
||||||
def write_uint32_array(fs: _FileWriter_t, vals: typing.Iterable[int], count: int) -> None:
|
def write_uint32_array(fs: _FileWriter_t, vals: typing.Iterable[int], count: int) -> None:
|
||||||
fs.write(struct.pack('<' + str(count) + 'I', *vals))
|
fs.write(struct.pack('<' + str(count) + 'I', *vals))
|
||||||
@ -67,11 +71,11 @@ def read_string(fs: _FileReader_t) -> str:
|
|||||||
count = read_uint32(fs)
|
count = read_uint32(fs)
|
||||||
return fs.read(count * 4).decode("utf_32_le")
|
return fs.read(count * 4).decode("utf_32_le")
|
||||||
|
|
||||||
def read_bool(fs: _FileReader_t) -> None:
|
def read_bool(fs: _FileReader_t) -> bool:
|
||||||
return read_uint8(fs) != 0
|
return read_uint8(fs) != 0
|
||||||
|
|
||||||
def read_world_materix(fs: _FileReader_t, mat: UTIL_virtools_types.VxMatrix) -> None:
|
def read_world_materix(fs: _FileReader_t, mat: UTIL_virtools_types.VxMatrix) -> None:
|
||||||
mat.from_tuple(struct.unpack("<16f", fs.read(16 * 4)))
|
mat.from_const(struct.unpack("<16f", fs.read(16 * 4)))
|
||||||
|
|
||||||
def read_color(fs: _FileReader_t, target: UTIL_virtools_types.VxColor) -> None:
|
def read_color(fs: _FileReader_t, target: UTIL_virtools_types.VxColor) -> None:
|
||||||
target.from_const_rgb(struct.unpack("fff", fs.read(3 * 4)))
|
target.from_const_rgb(struct.unpack("fff", fs.read(3 * 4)))
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import bpy
|
import bpy
|
||||||
import enum, typing
|
import enum, typing
|
||||||
from . import UTIL_virtools_types, UTIL_functions
|
from . import UTIL_virtools_types, UTIL_functions
|
||||||
from . import PROP_ptrprop_resolver
|
from . import PROP_ptrprop_resolver, PROP_ballance_map_info
|
||||||
|
|
||||||
## Intent
|
## Intent
|
||||||
# Some importer or exporter may share same properties.
|
# Some importer or exporter may share same properties.
|
||||||
@ -152,14 +152,20 @@ class ImportParams():
|
|||||||
) # type: ignore
|
) # type: ignore
|
||||||
|
|
||||||
def draw_import_params(self, layout: bpy.types.UILayout) -> None:
|
def draw_import_params(self, layout: bpy.types.UILayout) -> None:
|
||||||
layout.label(text = 'Object Name Conflict')
|
header: bpy.types.UILayout
|
||||||
layout.prop(self, 'object_conflict_strategy', text = '')
|
body: bpy.types.UILayout
|
||||||
layout.label(text = 'Mesh Name Conflict')
|
header, body = layout.panel("BBP_PT_ioport_shared_import_params", default_closed=False)
|
||||||
layout.prop(self, 'mesh_conflict_strategy', text = '')
|
header.label(text = 'Import Parameters')
|
||||||
layout.label(text = 'Material Name Conflict')
|
if body is None: return
|
||||||
layout.prop(self, 'material_conflict_strategy', text = '')
|
|
||||||
layout.label(text = 'Texture Name Conflict')
|
body.label(text = 'Object Name Conflict')
|
||||||
layout.prop(self, 'texture_conflict_strategy', text = '')
|
body.prop(self, 'object_conflict_strategy', text = '')
|
||||||
|
body.label(text = 'Mesh Name Conflict')
|
||||||
|
body.prop(self, 'mesh_conflict_strategy', text = '')
|
||||||
|
body.label(text = 'Material Name Conflict')
|
||||||
|
body.prop(self, 'material_conflict_strategy', text = '')
|
||||||
|
body.label(text = 'Texture Name Conflict')
|
||||||
|
body.prop(self, 'texture_conflict_strategy', text = '')
|
||||||
|
|
||||||
def general_get_texture_conflict_strategy(self) -> ConflictStrategy:
|
def general_get_texture_conflict_strategy(self) -> ConflictStrategy:
|
||||||
return _g_EnumHelper_ConflictStrategy.get_selection(self.texture_conflict_strategy)
|
return _g_EnumHelper_ConflictStrategy.get_selection(self.texture_conflict_strategy)
|
||||||
@ -191,16 +197,22 @@ class ExportParams():
|
|||||||
) # type: ignore
|
) # type: ignore
|
||||||
|
|
||||||
def draw_export_params(self, layout: bpy.types.UILayout) -> None:
|
def draw_export_params(self, layout: bpy.types.UILayout) -> None:
|
||||||
|
header: bpy.types.UILayout
|
||||||
|
body: bpy.types.UILayout
|
||||||
|
header, body = layout.panel("BBP_PT_ioport_shared_export_params", default_closed=False)
|
||||||
|
header.label(text = 'Export Parameters')
|
||||||
|
if body is None: return
|
||||||
|
|
||||||
# make prop expand horizontaly, not vertical.
|
# make prop expand horizontaly, not vertical.
|
||||||
sublayout = layout.row()
|
horizon_body = body.row()
|
||||||
# draw switch
|
# draw switch
|
||||||
sublayout.prop(self, "export_mode", expand = True)
|
horizon_body.prop(self, "export_mode", expand = True)
|
||||||
|
|
||||||
# draw picker
|
# draw picker
|
||||||
if self.export_mode == 'COLLECTION':
|
if self.export_mode == 'COLLECTION':
|
||||||
PROP_ptrprop_resolver.draw_export_collection(layout)
|
PROP_ptrprop_resolver.draw_export_collection(body)
|
||||||
elif self.export_mode == 'OBJECT':
|
elif self.export_mode == 'OBJECT':
|
||||||
PROP_ptrprop_resolver.draw_export_object(layout)
|
PROP_ptrprop_resolver.draw_export_object(body)
|
||||||
|
|
||||||
def general_get_export_objects(self) -> tuple[bpy.types.Object] | None:
|
def general_get_export_objects(self) -> tuple[bpy.types.Object] | None:
|
||||||
"""
|
"""
|
||||||
@ -216,6 +228,9 @@ class ExportParams():
|
|||||||
if obj is None: return None
|
if obj is None: return None
|
||||||
else: return (obj, )
|
else: return (obj, )
|
||||||
|
|
||||||
|
# define global tex save opt blender enum prop helper
|
||||||
|
_g_EnumHelper_CK_TEXTURE_SAVEOPTIONS: UTIL_virtools_types.EnumPropHelper = UTIL_virtools_types.EnumPropHelper(UTIL_virtools_types.CK_TEXTURE_SAVEOPTIONS)
|
||||||
|
|
||||||
class VirtoolsParams():
|
class VirtoolsParams():
|
||||||
vt_encodings: bpy.props.StringProperty(
|
vt_encodings: bpy.props.StringProperty(
|
||||||
name = "Encodings",
|
name = "Encodings",
|
||||||
@ -223,11 +238,95 @@ class VirtoolsParams():
|
|||||||
default = UTIL_virtools_types.g_PyBMapDefaultEncoding
|
default = UTIL_virtools_types.g_PyBMapDefaultEncoding
|
||||||
) # type: ignore
|
) # type: ignore
|
||||||
|
|
||||||
def draw_virtools_params(self, layout: bpy.types.UILayout) -> None:
|
texture_save_opt: bpy.props.EnumProperty(
|
||||||
layout.label(text = 'Encodings')
|
name = "Global Texture Save Options",
|
||||||
layout.prop(self, 'vt_encodings', text = '')
|
description = "Decide how texture saved if texture is specified as Use Global as its Save Options.",
|
||||||
|
items = _g_EnumHelper_CK_TEXTURE_SAVEOPTIONS.generate_items(),
|
||||||
|
default = _g_EnumHelper_CK_TEXTURE_SAVEOPTIONS.to_selection(UTIL_virtools_types.CK_TEXTURE_SAVEOPTIONS.CKTEXTURE_EXTERNAL)
|
||||||
|
) # type: ignore
|
||||||
|
|
||||||
|
use_compress: bpy.props.BoolProperty(
|
||||||
|
name="Use Compress",
|
||||||
|
description = "Whether use ZLib to compress result when saving composition.",
|
||||||
|
default = True,
|
||||||
|
) # type: ignore
|
||||||
|
|
||||||
|
compress_level: bpy.props.IntProperty(
|
||||||
|
name = "Compress Level",
|
||||||
|
description = "The ZLib compress level used by Virtools Engine when saving composition.",
|
||||||
|
min = 1, max = 9,
|
||||||
|
default = 5,
|
||||||
|
) # type: ignore
|
||||||
|
|
||||||
|
def draw_virtools_params(self, layout: bpy.types.UILayout, is_importer: bool) -> None:
|
||||||
|
header: bpy.types.UILayout
|
||||||
|
body: bpy.types.UILayout
|
||||||
|
header, body = layout.panel("BBP_PT_ioport_shared_virtools_params", default_closed=False)
|
||||||
|
header.label(text = 'Virtools Parameters')
|
||||||
|
if body is None: return
|
||||||
|
|
||||||
|
# draw encodings
|
||||||
|
body.label(text = 'Encodings')
|
||||||
|
body.prop(self, 'vt_encodings', text = '')
|
||||||
|
|
||||||
|
# following field are only valid in exporter
|
||||||
|
if not is_importer:
|
||||||
|
body.separator()
|
||||||
|
body.label(text = 'Global Texture Save Options')
|
||||||
|
body.prop(self, 'texture_save_opt', text = '')
|
||||||
|
|
||||||
|
body.separator()
|
||||||
|
body.prop(self, 'use_compress')
|
||||||
|
if self.use_compress:
|
||||||
|
body.prop(self, 'compress_level')
|
||||||
|
|
||||||
|
|
||||||
def general_get_vt_encodings(self) -> tuple[str]:
|
def general_get_vt_encodings(self) -> tuple[str]:
|
||||||
# get encoding, split it by `;` and strip blank chars.
|
# get encoding, split it by `;` and strip blank chars.
|
||||||
encodings: str = self.vt_encodings
|
encodings: str = self.vt_encodings
|
||||||
return tuple(map(lambda x: x.strip(), encodings.split(';')))
|
return tuple(map(lambda x: x.strip(), encodings.split(';')))
|
||||||
|
|
||||||
|
def general_get_texture_save_opt(self) -> UTIL_virtools_types.CK_TEXTURE_SAVEOPTIONS:
|
||||||
|
return _g_EnumHelper_CK_TEXTURE_SAVEOPTIONS.get_selection(self.texture_save_opt)
|
||||||
|
|
||||||
|
def general_get_use_compress(self) -> bool:
|
||||||
|
return self.use_compress
|
||||||
|
|
||||||
|
def general_get_compress_level(self) -> int:
|
||||||
|
return self.compress_level
|
||||||
|
|
||||||
|
class BallanceParams():
|
||||||
|
successive_sector: bpy.props.BoolProperty(
|
||||||
|
name="Successive Sector",
|
||||||
|
description = "Whether order exporter to use document specified sector count to make sure sector is successive.",
|
||||||
|
default = True,
|
||||||
|
) # type: ignore
|
||||||
|
|
||||||
|
def draw_ballance_params(self, layout: bpy.types.UILayout, is_importer: bool) -> None:
|
||||||
|
# ballance params only presented in exporter.
|
||||||
|
# so if we are in impoerter, we skip the whole function
|
||||||
|
# because we don't want to create an empty panel.
|
||||||
|
if is_importer: return
|
||||||
|
|
||||||
|
header: bpy.types.UILayout
|
||||||
|
body: bpy.types.UILayout
|
||||||
|
header, body = layout.panel("BBP_PT_ioport_shared_ballance_params", default_closed=False)
|
||||||
|
header.label(text = 'Ballance Parameters')
|
||||||
|
if body is None: return
|
||||||
|
|
||||||
|
map_info: PROP_ballance_map_info.RawBallanceMapInfo = PROP_ballance_map_info.get_raw_ballance_map_info(bpy.context.scene)
|
||||||
|
body.prop(self, 'successive_sector')
|
||||||
|
body.label(text = f'Map Sectors: {map_info.mSectorCount}')
|
||||||
|
|
||||||
|
def general_get_successive_sector(self) -> bool:
|
||||||
|
return self.successive_sector
|
||||||
|
|
||||||
|
def general_get_successive_sector_count(self) -> int:
|
||||||
|
# if user do not pick successive sector, return a random int directly.
|
||||||
|
if not self.general_get_successive_sector():
|
||||||
|
return 0
|
||||||
|
|
||||||
|
# otherwise fetch user specified sector number
|
||||||
|
map_info: PROP_ballance_map_info.RawBallanceMapInfo
|
||||||
|
map_info = PROP_ballance_map_info.get_raw_ballance_map_info(bpy.context.scene)
|
||||||
|
return map_info.mSectorCount
|
||||||
|
Loading…
Reference in New Issue
Block a user