fix issues
- fix Sector group no-successive issue when saving as nmo - add nong ventilator adder. - use copy.copy to write some code to reduce the calling of get/set_raw_vt_mtl() - keep texture when apply virtools mtl preset.
This commit is contained in:
parent
03e8feac67
commit
50b7eb0bce
@ -235,6 +235,74 @@ class BBP_OT_add_nong_extra_point(bpy.types.Operator, ComponentSectorParam, Comp
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
class BBP_OT_add_nong_ventilator(bpy.types.Operator, ComponentSectorParam, ComponentCountParam):
|
||||||
|
"""Add Nong Ventilator"""
|
||||||
|
bl_idname = "bbp.add_nong_ventilator"
|
||||||
|
bl_label = "Nong Ventilator"
|
||||||
|
bl_options = {'REGISTER', 'UNDO'}
|
||||||
|
|
||||||
|
ventilator_count_source: bpy.props.EnumProperty(
|
||||||
|
name = "Ventilator Count Source",
|
||||||
|
items = (
|
||||||
|
('DEFINED', "Predefined", "Pre-defined ventilator count."),
|
||||||
|
('CUSTOM', "Custom", "User specified ventilator count."),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
preset_vetilator_count: bpy.props.EnumProperty(
|
||||||
|
name = "Preset Count",
|
||||||
|
description = "Pick preset ventilator count.",
|
||||||
|
items = (
|
||||||
|
# (token, display name, descriptions, icon, index)
|
||||||
|
('PAPER', 'Paper', 'The ventilator count (1) can push paper ball up.'),
|
||||||
|
('WOOD', 'Wood', 'The ventilator count (6) can push wood ball up.'),
|
||||||
|
('STONE', 'Stone', 'The ventilator count (32) can push stone ball up.'),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
def draw(self, context):
|
||||||
|
layout = self.layout
|
||||||
|
# draw sector settings
|
||||||
|
self.draw_component_sector_params(layout)
|
||||||
|
|
||||||
|
# draw count settings by different source
|
||||||
|
layout.label(text = 'Count')
|
||||||
|
layout.prop(self, 'ventilator_count_source', expand = True)
|
||||||
|
if (self.ventilator_count_source == 'CUSTOM'):
|
||||||
|
self.draw_component_count_params(layout)
|
||||||
|
else:
|
||||||
|
layout.prop(self, 'preset_vetilator_count')
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
# get ventilator count
|
||||||
|
count: int = 0
|
||||||
|
if (self.ventilator_count_source == 'CUSTOM'):
|
||||||
|
count = self.general_get_component_count()
|
||||||
|
else:
|
||||||
|
match(self.preset_vetilator_count):
|
||||||
|
case 'PAPER': count = 1
|
||||||
|
case 'WOOD': count = 6
|
||||||
|
case 'STONE': count = 32
|
||||||
|
case _: raise UTIL_functions.BBPException('invalid enumprop data')
|
||||||
|
|
||||||
|
# create elements without any move
|
||||||
|
_general_create_component(
|
||||||
|
PROP_ballance_element.BallanceElementType.P_Modul_18,
|
||||||
|
self.general_get_component_sector(),
|
||||||
|
count,
|
||||||
|
lambda _: mathutils.Matrix.Identity(4)
|
||||||
|
)
|
||||||
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def draw_blc_menu(layout: bpy.types.UILayout):
|
||||||
|
layout.operator(
|
||||||
|
BBP_OT_add_nong_ventilator.bl_idname,
|
||||||
|
icon_value = UTIL_icons_manager.get_component_icon(
|
||||||
|
PROP_ballance_element.get_ballance_element_name(PROP_ballance_element.BallanceElementType.P_Modul_18)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Series Comp Adder
|
#region Series Comp Adder
|
||||||
@ -412,6 +480,7 @@ class BBP_OT_add_sector_component_pair(bpy.types.Operator, ComponentSectorParam)
|
|||||||
def register():
|
def register():
|
||||||
bpy.utils.register_class(BBP_OT_add_component)
|
bpy.utils.register_class(BBP_OT_add_component)
|
||||||
bpy.utils.register_class(BBP_OT_add_nong_extra_point)
|
bpy.utils.register_class(BBP_OT_add_nong_extra_point)
|
||||||
|
bpy.utils.register_class(BBP_OT_add_nong_ventilator)
|
||||||
bpy.utils.register_class(BBP_OT_add_tilting_block_series)
|
bpy.utils.register_class(BBP_OT_add_tilting_block_series)
|
||||||
bpy.utils.register_class(BBP_OT_add_ventilator_series)
|
bpy.utils.register_class(BBP_OT_add_ventilator_series)
|
||||||
bpy.utils.register_class(BBP_OT_add_sector_component_pair)
|
bpy.utils.register_class(BBP_OT_add_sector_component_pair)
|
||||||
@ -420,5 +489,6 @@ def unregister():
|
|||||||
bpy.utils.unregister_class(BBP_OT_add_sector_component_pair)
|
bpy.utils.unregister_class(BBP_OT_add_sector_component_pair)
|
||||||
bpy.utils.unregister_class(BBP_OT_add_ventilator_series)
|
bpy.utils.unregister_class(BBP_OT_add_ventilator_series)
|
||||||
bpy.utils.unregister_class(BBP_OT_add_tilting_block_series)
|
bpy.utils.unregister_class(BBP_OT_add_tilting_block_series)
|
||||||
|
bpy.utils.unregister_class(BBP_OT_add_nong_ventilator)
|
||||||
bpy.utils.unregister_class(BBP_OT_add_nong_extra_point)
|
bpy.utils.unregister_class(BBP_OT_add_nong_extra_point)
|
||||||
bpy.utils.unregister_class(BBP_OT_add_component)
|
bpy.utils.unregister_class(BBP_OT_add_component)
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import bpy
|
import bpy
|
||||||
from bpy_extras.wm_utils.progress_report import ProgressReport
|
from bpy_extras.wm_utils.progress_report import ProgressReport
|
||||||
import tempfile, os, typing
|
import tempfile, os, typing, re
|
||||||
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
|
from . import UTIL_virtools_types, UTIL_functions, UTIL_file_browser, UTIL_blender_mesh, UTIL_ballance_texture, UTIL_icons_manager
|
||||||
from . import PROP_virtools_group, PROP_virtools_material, PROP_virtools_mesh, PROP_virtools_texture
|
from . import PROP_virtools_group, PROP_virtools_material, PROP_virtools_mesh, PROP_virtools_texture
|
||||||
@ -164,15 +164,18 @@ def _export_virtools_groups(
|
|||||||
# start saving
|
# start saving
|
||||||
progress.enter_substeps(len(obj3d_crets), "Saving Groups")
|
progress.enter_substeps(len(obj3d_crets), "Saving Groups")
|
||||||
|
|
||||||
|
# create group exporting helper
|
||||||
|
group_cret_guard: VirtoolsGroupCreationGuard = VirtoolsGroupCreationGuard(writer)
|
||||||
|
|
||||||
for obj3d, vtobj3d in obj3d_crets:
|
for obj3d, vtobj3d in obj3d_crets:
|
||||||
# open group visitor
|
# open group visitor
|
||||||
with PROP_virtools_group.VirtoolsGroupsHelper(obj3d) as gp_visitor:
|
with PROP_virtools_group.VirtoolsGroupsHelper(obj3d) as gp_visitor:
|
||||||
for gp_name in gp_visitor.iterate_groups():
|
for gp_name in gp_visitor.iterate_groups():
|
||||||
# get group or create new group
|
# get group or create new group from guard
|
||||||
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:
|
||||||
vtgroup = writer.create_group()
|
# note: no need to set name, guard has set it.
|
||||||
vtgroup.set_name(gp_name)
|
vtgroup = group_cret_guard.create_group(gp_name)
|
||||||
group_cret_map[gp_name] = vtgroup
|
group_cret_map[gp_name] = vtgroup
|
||||||
|
|
||||||
# group this object
|
# group this object
|
||||||
@ -462,6 +465,72 @@ def _save_virtools_document(
|
|||||||
progress.step()
|
progress.step()
|
||||||
progress.leave_substeps()
|
progress.leave_substeps()
|
||||||
|
|
||||||
|
class VirtoolsGroupCreationGuard():
|
||||||
|
"""
|
||||||
|
This class is designed for ensure that the created sector group is successive.
|
||||||
|
|
||||||
|
Due to the design of Ballance, Ballance rely on checking the existance of Sector_XX to get how many sectors this map have.
|
||||||
|
Thus if there are no component in a sector, it still need to create a empty Sector_XX group, otherwise the game will crash
|
||||||
|
or be ended at a accident sector.
|
||||||
|
|
||||||
|
This class hook the operation of Virtools group creation and check all Sector group creation.
|
||||||
|
Create essential group to make Sector_XX group successive.
|
||||||
|
Thus all group creation in this module should be passed by this class.
|
||||||
|
"""
|
||||||
|
cRegexGroupSector: typing.ClassVar[re.Pattern] = re.compile('^Sector_(0[1-8]|[1-9][0-9]{1,2}|9)$')
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def __get_group_index(group_name: str) -> int | None:
|
||||||
|
"""
|
||||||
|
Return the sector index of group name if it is. Otherwise None.
|
||||||
|
"""
|
||||||
|
regex_result = VirtoolsGroupCreationGuard.cRegexGroupSector.match(group_name)
|
||||||
|
if regex_result is not None:
|
||||||
|
return int(regex_result.group(1))
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def __get_group_name(group_index: int) -> str:
|
||||||
|
"""
|
||||||
|
Output Sector group name by given sector index
|
||||||
|
"""
|
||||||
|
if group_index == 9:
|
||||||
|
return 'Sector_9'
|
||||||
|
else:
|
||||||
|
return f'Sector_{group_index:0>2d}'
|
||||||
|
|
||||||
|
__mWriter: bmap.BMFileWriter
|
||||||
|
__mSectors: list[bmap.BMGroup]
|
||||||
|
|
||||||
|
def __init__(self, assoc_writer: bmap.BMFileWriter):
|
||||||
|
self.__mWriter = assoc_writer
|
||||||
|
self.__mSectors = []
|
||||||
|
|
||||||
|
def create_group(self, group_name: str) -> bmap.BMGroup:
|
||||||
|
"""
|
||||||
|
The hooked group creation function.
|
||||||
|
|
||||||
|
Please note the passed group name argument is just for name checking.
|
||||||
|
This function will set group name for you, not like BMFileWriter.create_group() operated.
|
||||||
|
"""
|
||||||
|
# check whether it is sector group
|
||||||
|
# note: the return sector index is 1 based, not 0
|
||||||
|
sector_idx: int | None = VirtoolsGroupCreationGuard.__get_group_index(group_name)
|
||||||
|
# if it is regular group, return normal creation
|
||||||
|
if sector_idx is None:
|
||||||
|
gp: bmap.BMGroup = self.__mWriter.create_group()
|
||||||
|
gp.set_name(group_name)
|
||||||
|
return gp
|
||||||
|
|
||||||
|
# get from sector cahce list
|
||||||
|
# enlarge sector cache list if it is not fulfilled given sector index
|
||||||
|
while sector_idx > len(self.__mSectors):
|
||||||
|
gp: bmap.BMGroup = self.__mWriter.create_group()
|
||||||
|
self.__mSectors.append(gp)
|
||||||
|
gp.set_name(self.__get_group_name(len(self.__mSectors)))
|
||||||
|
# return ordered sector from sector caches
|
||||||
|
return self.__mSectors[sector_idx - 1]
|
||||||
|
|
||||||
def register() -> None:
|
def register() -> None:
|
||||||
bpy.utils.register_class(BBP_OT_export_virtools)
|
bpy.utils.register_class(BBP_OT_export_virtools)
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import bpy
|
import bpy
|
||||||
import typing, enum
|
import typing, enum, copy
|
||||||
from . import PROP_virtools_material, PROP_virtools_texture
|
from . import PROP_virtools_material, PROP_virtools_texture
|
||||||
from . import UTIL_ballance_texture, UTIL_functions
|
from . import UTIL_ballance_texture, UTIL_functions
|
||||||
|
|
||||||
@ -91,21 +91,19 @@ def _load_bme_material_preset(mtl: bpy.types.Material, preset_name: str) -> None
|
|||||||
# get preset first
|
# get preset first
|
||||||
preset: _BMEMaterialPreset = _g_BMEMaterialPresets[preset_name]
|
preset: _BMEMaterialPreset = _g_BMEMaterialPresets[preset_name]
|
||||||
|
|
||||||
# apply raw data first
|
# get raw mtl and do a shallow copy
|
||||||
PROP_virtools_material.set_raw_virtools_material(mtl, preset.mRawMtl)
|
# because we will change something later. but do not want to affect preset self.
|
||||||
|
raw_mtl: PROP_virtools_material.RawVirtoolsMaterial = copy.copy(preset.mRawMtl)
|
||||||
|
|
||||||
# load ballance texture
|
# load ballance texture
|
||||||
blctex: bpy.types.Image = UTIL_ballance_texture.load_ballance_texture(preset.mTexName)
|
blctex: bpy.types.Image = UTIL_ballance_texture.load_ballance_texture(preset.mTexName)
|
||||||
# apply texture props
|
# apply texture props
|
||||||
PROP_virtools_texture.set_raw_virtools_texture(blctex, PROP_virtools_texture.get_ballance_texture_preset(preset.mTexName))
|
PROP_virtools_texture.set_raw_virtools_texture(blctex, PROP_virtools_texture.get_ballance_texture_preset(preset.mTexName))
|
||||||
|
# set loaded texture to shallow copied raw mtl
|
||||||
|
raw_mtl.mTexture = blctex
|
||||||
|
|
||||||
# because preset's rawmtl is const, we can not change it directly
|
# set raw mtl
|
||||||
# so we need change its texture by triving it again as a new rawmtl
|
PROP_virtools_material.set_raw_virtools_material(mtl, raw_mtl)
|
||||||
# after we got ballance texture
|
|
||||||
newrawmtl: PROP_virtools_material.RawVirtoolsMaterial = PROP_virtools_material.get_raw_virtools_material(mtl)
|
|
||||||
newrawmtl.mTexture = blctex
|
|
||||||
PROP_virtools_material.set_raw_virtools_material(mtl, newrawmtl)
|
|
||||||
|
|
||||||
# apply vt mtl to blender mtl
|
# apply vt mtl to blender mtl
|
||||||
PROP_virtools_material.apply_to_blender_material(mtl)
|
PROP_virtools_material.apply_to_blender_material(mtl)
|
||||||
|
|
||||||
|
@ -270,7 +270,7 @@ class SharedGroupNameInputProperties():
|
|||||||
)
|
)
|
||||||
|
|
||||||
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)
|
||||||
if (self.group_name_source == 'CUSTOM'):
|
if (self.group_name_source == 'CUSTOM'):
|
||||||
layout.prop(self, 'custom_group_name')
|
layout.prop(self, 'custom_group_name')
|
||||||
else:
|
else:
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import bpy
|
import bpy
|
||||||
import typing, enum
|
import typing, enum, copy
|
||||||
from . import UTIL_virtools_types, UTIL_functions, UTIL_ballance_texture, UTIL_file_browser
|
from . import UTIL_virtools_types, UTIL_functions, UTIL_ballance_texture, UTIL_file_browser
|
||||||
from . import PROP_virtools_texture, PROP_preferences
|
from . import PROP_virtools_texture, PROP_preferences
|
||||||
|
|
||||||
@ -515,8 +515,17 @@ def get_virtools_material_preset(preset_type: MaterialPresetType) -> MaterialPre
|
|||||||
return _g_MaterialPresets[preset_type]
|
return _g_MaterialPresets[preset_type]
|
||||||
|
|
||||||
def preset_virtools_material(mtl: bpy.types.Material, preset_type: MaterialPresetType) -> None:
|
def preset_virtools_material(mtl: bpy.types.Material, preset_type: MaterialPresetType) -> None:
|
||||||
preset_data: MaterialPresetData = _g_MaterialPresets[preset_type]
|
# get preset raw mtl member first
|
||||||
set_raw_virtools_material(mtl, preset_data.mData)
|
# but we need create a shallow copy for it first.
|
||||||
|
preset_data: RawVirtoolsMaterial = copy.copy(_g_MaterialPresets[preset_type].mData)
|
||||||
|
# the we get texture setting from now texture
|
||||||
|
now_data: RawVirtoolsMaterial = get_raw_virtools_material(mtl)
|
||||||
|
# change preset texture to current texture
|
||||||
|
# because we do not want to change texture by preset.
|
||||||
|
# also this is the reason why i need do a shallow copy for preset data
|
||||||
|
preset_data.mTexture = now_data.mTexture
|
||||||
|
# apply preset
|
||||||
|
set_raw_virtools_material(mtl, preset_data)
|
||||||
|
|
||||||
# create preset enum blender helper
|
# create preset enum blender helper
|
||||||
_g_Helper_MtlPreset: UTIL_functions.EnumPropHelper = UTIL_functions.EnumPropHelper(
|
_g_Helper_MtlPreset: UTIL_functions.EnumPropHelper = UTIL_functions.EnumPropHelper(
|
||||||
|
@ -68,7 +68,7 @@ _g_BMEPrototypes: list[dict[str, typing.Any]] = []
|
|||||||
_g_BMEPrototypeIndexMap: dict[str, int] = {}
|
_g_BMEPrototypeIndexMap: dict[str, int] = {}
|
||||||
|
|
||||||
# the core loader
|
# the core loader
|
||||||
for walk_root, walk_dirs, walk_files in os.walk(os.path.join(os.path.dirname(__file__), 'json')):
|
for walk_root, walk_dirs, walk_files in os.walk(os.path.join(os.path.dirname(__file__), 'jsons')):
|
||||||
for relfile in walk_files:
|
for relfile in walk_files:
|
||||||
if not relfile.endswith('.json'): continue
|
if not relfile.endswith('.json'): continue
|
||||||
with open(os.path.join(walk_root, relfile), 'r', encoding = 'utf-8') as fp:
|
with open(os.path.join(walk_root, relfile), 'r', encoding = 'utf-8') as fp:
|
||||||
|
@ -78,6 +78,7 @@ class BBP_MT_AddComponentsMenu(bpy.types.Menu):
|
|||||||
layout.separator()
|
layout.separator()
|
||||||
layout.label(text="Nong Components")
|
layout.label(text="Nong Components")
|
||||||
OP_ADDS_component.BBP_OT_add_nong_extra_point.draw_blc_menu(layout)
|
OP_ADDS_component.BBP_OT_add_nong_extra_point.draw_blc_menu(layout)
|
||||||
|
OP_ADDS_component.BBP_OT_add_nong_ventilator.draw_blc_menu(layout)
|
||||||
|
|
||||||
layout.separator()
|
layout.separator()
|
||||||
layout.label(text="Series Components")
|
layout.label(text="Series Components")
|
||||||
|
Loading…
Reference in New Issue
Block a user