[feat] promote experience about floor creation.

- change bl_options and rewrite invoke and draw functions to let floor creating window become more visual. credit: BLumia.
- also change 3ds max align and flatten uv presentation after changing creating floor window.
- seperate icon loader/unload module.
This commit is contained in:
yyc12345 2023-01-27 16:28:32 +08:00
parent ef459a210d
commit 9b9fc9cde8
6 changed files with 90 additions and 41 deletions

View File

@ -5,7 +5,7 @@ class BALLANCE_OT_super_align(bpy.types.Operator):
"""Align object with 3ds Max style"""
bl_idname = "ballance.super_align"
bl_label = "3ds Max Align"
bl_options = {'UNDO'}
bl_options = {'REGISTER', 'UNDO'}
align_x: bpy.props.BoolProperty(name="X position")
align_y: bpy.props.BoolProperty(name="Y position")
@ -18,7 +18,8 @@ class BALLANCE_OT_super_align(bpy.types.Operator):
('POINT', "Center (axis)", ""),
('MAX', "Max", "")
),
)
default='POINT',
)
target_references: bpy.props.EnumProperty(
name="Target (Other Objects)",
@ -27,7 +28,8 @@ class BALLANCE_OT_super_align(bpy.types.Operator):
('POINT', "Center (axis)", ""),
('MAX', "Max", "")
),
)
default='POINT',
)
@classmethod
def poll(self, context):
@ -37,9 +39,11 @@ class BALLANCE_OT_super_align(bpy.types.Operator):
_align_object(self.align_x, self.align_y, self.align_z, self.current_references, self.target_references)
return {'FINISHED'}
"""
def invoke(self, context, event):
wm = context.window_manager
return wm.invoke_props_dialog(self)
"""
def draw(self, context):
layout = self.layout

View File

@ -6,7 +6,7 @@ class BALLANCE_OT_flatten_uv(bpy.types.Operator):
"""Flatten selected face UV. Only works for convex face"""
bl_idname = "ballance.flatten_uv"
bl_label = "Flatten UV"
bl_options = {'UNDO'}
bl_options = {'REGISTER', 'UNDO'}
reference_edge : bpy.props.IntProperty(
name="Reference edge",
@ -20,7 +20,7 @@ class BALLANCE_OT_flatten_uv(bpy.types.Operator):
@classmethod
def poll(self, context):
obj = bpy.context.active_object
if obj == None:
if obj is None:
return False
if obj.type != 'MESH':
return False
@ -28,17 +28,16 @@ class BALLANCE_OT_flatten_uv(bpy.types.Operator):
return False
return True
"""
def invoke(self, context, event):
wm = context.window_manager
return wm.invoke_props_dialog(self)
"""
def execute(self, context):
no_processed_count = _real_flatten_uv(bpy.context.active_object.data, self.reference_edge)
if no_processed_count != 0:
UTILS_functions.show_message_box(
("{} faces may not be processed correctly because they have problem.".format(no_processed_count), ),
"Warning", 'ERROR'
)
print("[Flatten UV] {} faces may not be processed correctly because they have problem.".format(no_processed_count))
return {'FINISHED'}
def draw(self, context):

View File

@ -4,18 +4,28 @@ import ast
from bpy_extras import io_utils,node_shader_utils
# from bpy_extras.io_utils import unpack_list
from bpy_extras.image_utils import load_image
from . import UTILS_constants, UTILS_functions, UTILS_safe_eval
from . import UTILS_constants, UTILS_functions, UTILS_safe_eval, UTILS_icons_manager
class BALLANCE_OT_add_floors(bpy.types.Operator):
"""Add Ballance floor"""
bl_idname = "ballance.add_floors"
bl_label = "Add floor"
bl_options = {'UNDO'}
bl_options = {'REGISTER', 'UNDO'}
floor_type: bpy.props.EnumProperty(
name="Type",
description="Floor type",
items=tuple((x, x, "") for x in UTILS_constants.floor_blockDict.keys()),
items=tuple(
# token, display name, descriptions
(blk, blk, "")
for blk in UTILS_constants.floor_blockDict.keys()
),
#items=tuple(
# # token, display name, descriptions, icon, index
# (blk, blk, "", UTILS_icons_manager.get_floor_icon(blk), idx)
# for idx, blk in enumerate(UTILS_constants.floor_blockDict.keys())
#),
)
expand_length_1 : bpy.props.IntProperty(
@ -40,22 +50,28 @@ class BALLANCE_OT_add_floors(bpy.types.Operator):
)
use_2d_top : bpy.props.BoolProperty(
name="Top edge"
name="Top edge",
default=True
)
use_2d_right : bpy.props.BoolProperty(
name="Right edge"
name="Right edge",
default=False
)
use_2d_bottom : bpy.props.BoolProperty(
name="Bottom edge"
name="Bottom edge",
default=True
)
use_2d_left : bpy.props.BoolProperty(
name="Left edge"
name="Left edge",
default=True
)
use_3d_top : bpy.props.BoolProperty(
name="Top face"
name="Top face",
default=True
)
use_3d_bottom : bpy.props.BoolProperty(
name="Bottom face"
name="Bottom face",
default=True
)
previous_floor_type = ''
@ -114,11 +130,13 @@ class BALLANCE_OT_add_floors(bpy.types.Operator):
UTILS_functions.add_into_scene_and_move_to_cursor(obj)
return {'FINISHED'}
def invoke(self, context, event):
wm = context.window_manager
return wm.invoke_props_dialog(self)
# yyc marked. Blumia reported.
# prepare settings before registing
# otherwise the mesh will not be created when first run.
# (do not change any properties)
def draw(self, context):
# get floor prototype
floor_prototype = UTILS_constants.floor_blockDict[self.floor_type]
@ -134,6 +152,13 @@ class BALLANCE_OT_add_floors(bpy.types.Operator):
self.use_3d_top = default_sides['UseThreeDTop']
self.use_3d_bottom = default_sides['UseThreeDBottom']
return self.execute(context)
def draw(self, context):
# get floor prototype
floor_prototype = UTILS_constants.floor_blockDict[self.floor_type]
# show property
layout = self.layout
col = layout.column()
@ -154,7 +179,7 @@ class BALLANCE_OT_add_floors(bpy.types.Operator):
grids.label(text=UTILS_constants.floor_expandDirectionMap[floor_prototype['InitColumnDirection']][floor_prototype['ExpandType']][0])
grids.separator()
grids.label(text=UTILS_constants.floor_expandDirectionMap[floor_prototype['InitColumnDirection']][floor_prototype['ExpandType']][3])
grids.template_icon(icon_value = UTILS_constants.icons_floorDict[self.floor_type])
grids.template_icon(icon_value = UTILS_icons_manager.get_floor_icon(self.floor_type))
grids.label(text=UTILS_constants.floor_expandDirectionMap[floor_prototype['InitColumnDirection']][floor_prototype['ExpandType']][1])
grids.separator()
grids.label(text=UTILS_constants.floor_expandDirectionMap[floor_prototype['InitColumnDirection']][floor_prototype['ExpandType']][2])
@ -173,7 +198,7 @@ class BALLANCE_OT_add_floors(bpy.types.Operator):
grids.prop(self, "use_2d_top")
grids.separator()
grids.prop(self, "use_2d_left")
grids.template_icon(icon_value = UTILS_constants.icons_floorDict[self.floor_type])
grids.template_icon(icon_value = UTILS_icons_manager.get_floor_icon(self.floor_type))
grids.prop(self, "use_2d_right")
grids.separator()
grids.prop(self, "use_2d_bottom")

View File

@ -290,11 +290,6 @@ for walk_root, walk_dirs, walk_files in os.walk(os.path.join(os.path.dirname(__f
floor_derivedBlockList.append(item["Type"])
floor_blockDict[item["Type"]] = item
icons_floor = None
icons_floorDict = {}
# blenderIcon_elements = None
# blenderIcon_elements_dict = {}
rename_normalComponentsGroupName = set([
"P_Extra_Life",
"P_Extra_Point",

View File

@ -0,0 +1,30 @@
import bpy
import bpy.utils.previews
import os
from . import UTILS_constants
# ImagePreviewCollection ccreated by Blender
floor_icons = None
# a map. key is block name, value is loaded icon id
floor_icons_map: dict = {}
def register_icons():
global floor_icons, floor_icons_map
icon_path = os.path.join(os.path.dirname(__file__), "icons")
floor_icons = bpy.utils.previews.new()
for key, value in UTILS_constants.floor_blockDict.items():
blockIconName = "Ballance_FloorIcon_" + key
floor_icons.load(blockIconName, os.path.join(icon_path, "floor", value["BindingDisplayTexture"]), 'IMAGE')
floor_icons_map[key] = floor_icons[blockIconName].icon_id
def unregister_icons():
global floor_icons, floor_icons_map
bpy.utils.previews.remove(floor_icons)
floor_icons_map.clear()
def get_floor_icon(floor_blk_name: str):
global floor_icons_map
return floor_icons_map[floor_blk_name]

View File

@ -13,9 +13,8 @@ bl_info={
# =============================================
# import system
import bpy, bpy_extras
import bpy.utils.previews
import os
import bpy
# import my code (with reload)
if "bpy" in locals():
import importlib
@ -33,6 +32,8 @@ if "bpy" in locals():
importlib.reload(UTILS_virtools_prop)
if "UTILS_safe_eval" in locals():
importlib.reload(UTILS_safe_eval)
if "UTILS_icons_manager" in locals():
importlib.reload(UTILS_icons_manager)
if "BMFILE_export" in locals():
importlib.reload(BMFILE_export)
@ -63,7 +64,7 @@ if "bpy" in locals():
if "PROPS_virtools_material" in locals():
importlib.reload(PROPS_virtools_material)
from . import UTILS_constants, UTILS_functions, UTILS_preferences, UTILS_virtools_prop, UTILS_safe_eval
from . import UTILS_constants, UTILS_functions, UTILS_preferences, UTILS_virtools_prop, UTILS_safe_eval, UTILS_icons_manager
from . import BMFILE_export, BMFILE_import
from . import MODS_3dsmax_align, MODS_flatten_uv, MODS_rail_uv
from . import OBJS_add_components, OBJS_add_floors, OBJS_add_rails, OBJS_group_opers
@ -97,7 +98,7 @@ class BALLANCE_MT_AddFloorMenu(bpy.types.Menu):
for item in UTILS_constants.floor_basicBlockList:
cop = layout.operator(
OBJS_add_floors.BALLANCE_OT_add_floors.bl_idname,
text=item, icon_value = UTILS_constants.icons_floorDict[item])
text=item, icon_value = UTILS_icons_manager.get_floor_icon(item))
cop.floor_type = item
layout.separator()
@ -105,7 +106,7 @@ class BALLANCE_MT_AddFloorMenu(bpy.types.Menu):
for item in UTILS_constants.floor_derivedBlockList:
cop = layout.operator(
OBJS_add_floors.BALLANCE_OT_add_floors.bl_idname,
text=item, icon_value = UTILS_constants.icons_floorDict[item])
text=item, icon_value = UTILS_icons_manager.get_floor_icon(item))
cop.floor_type = item
class BALLANCE_MT_AddRailMenu(bpy.types.Menu):
@ -208,12 +209,7 @@ def menu_func_ballance_grouping(self, context):
def register():
# we need init all icon first
icon_path = os.path.join(os.path.dirname(__file__), "icons")
UTILS_constants.icons_floor = bpy.utils.previews.new()
for key, value in UTILS_constants.floor_blockDict.items():
blockIconName = "Ballance_FloorIcon_" + key
UTILS_constants.icons_floor.load(blockIconName, os.path.join(icon_path, "floor", value["BindingDisplayTexture"]), 'IMAGE')
UTILS_constants.icons_floorDict[key] = UTILS_constants.icons_floor[blockIconName].icon_id
UTILS_icons_manager.register_icons()
for cls in classes:
bpy.utils.register_class(cls)
@ -254,7 +250,7 @@ def unregister():
bpy.utils.unregister_class(cls)
# we need uninstall all icon after all classes unregister
bpy.utils.previews.remove(UTILS_constants.icons_floor)
UTILS_icons_manager.unregister_icons()
if __name__=="__main__":
register()