[feat] add 2 new features

- add tunnel section creation and re-organise rail creation menu.
- allow duplicated elements (Nong xxx) creation for some special, such as Fan and Extra Point.
This commit is contained in:
yyc12345 2023-01-09 11:10:13 +08:00
parent 2a87e98904
commit e7376a3e9c
5 changed files with 136 additions and 40 deletions

View File

@ -13,9 +13,9 @@ This plugin contain various aspect of Ballance mapping. However, if some feature
## Technical Infomation ## Technical Infomation
Used BM file spec can be found in [there](https://github.com/yyc12345/gist/blob/master/BMFileSpec/BMSpec_ZH.md)(Chinese only). Used BM file spec can be found in [there](https://github.com/yyc12345/gist/blob/master/BMFileSpec/BMSpec_ZH.md) (Chinese only).
Used tools chain principle and the file format located in `meshes` can be found in [there](https://github.com/yyc12345/gist/blob/master/BMFileSpec/YYCToolsChainSpec_ZH.md)(Chinese only). Used tools chain principle and the file format located in `meshes` can be found in [there](https://github.com/yyc12345/gist/blob/master/BMFileSpec/YYCToolsChainSpec_ZH.md) (Chinese only).
The format of the files which are under the `jsons` folder and belong to the BMERevenge section, can be found in [here](https://github.com/yyc12345/gist/blob/master/BMERevenge/DevDocument_ZH.md) The format of the files which are under the `jsons` folder and belong to the BMERevenge section, can be found in [here](https://github.com/yyc12345/gist/blob/master/BMERevenge/DevDocument_ZH.md) (Chinese only).
This plugin will continuously support Blender lastest **LTS** version. This plugin will migrate to new version when the new LTS version released. Currently, it based on Blender **3.3.x**. This plugin will continuously support Blender lastest **LTS** version. This plugin will migrate to new version when the new LTS version released. Currently, it based on Blender **3.3.x**.

View File

@ -15,14 +15,27 @@ class BALLANCE_OT_add_components(bpy.types.Operator):
items=tuple(map(lambda x: (x, x, ""), UTILS_constants.bmfile_componentList)), items=tuple(map(lambda x: (x, x, ""), UTILS_constants.bmfile_componentList)),
) )
attentionElements = ["PC_TwoFlames", "PR_Resetpoint"] attentionElements = ("PC_TwoFlames", "PR_Resetpoint")
uniqueElements = ["PS_FourFlames", "PE_Balloon"] uniqueElements = ("PS_FourFlames", "PE_Balloon")
canDuplicatedElements = ('P_Extra_Point', 'P_Modul_18', 'P_Modul_26')
elements_sector: bpy.props.IntProperty( elements_sector: bpy.props.IntProperty(
name="Sector", name="Sector",
description="Define which sector the object will be grouped in", description="Define which sector the object will be grouped in",
min=1, min=1, max=8,
max=8, default=1,
)
elements_duplicated: bpy.props.BoolProperty(
name="Duplicated",
description="Whether duplicate elements (Nong xxx / 脓xxx)",
default=False,
)
elements_dup_times: bpy.props.IntProperty(
name="Duplication Times",
description="How many this element should be duplicated.",
min=1, max=64,
soft_min=1, soft_max=32,
default=1, default=1,
) )
@ -41,6 +54,13 @@ class BALLANCE_OT_add_components(bpy.types.Operator):
obj = bpy.data.objects.new(finalObjectName, loadedMesh) obj = bpy.data.objects.new(finalObjectName, loadedMesh)
UTILS_functions.add_into_scene_and_move_to_cursor(obj) UTILS_functions.add_into_scene_and_move_to_cursor(obj)
# extra duplication
if self.elements_type in self.canDuplicatedElements:
for i in range(self.elements_dup_times - 1):
obj = bpy.data.objects.new(finalObjectName, loadedMesh)
UTILS_functions.add_into_scene_and_move_to_cursor(obj)
return {'FINISHED'} return {'FINISHED'}
def invoke(self, context, event): def invoke(self, context, event):
@ -49,8 +69,18 @@ class BALLANCE_OT_add_components(bpy.types.Operator):
def draw(self, context): def draw(self, context):
layout = self.layout layout = self.layout
# attension notice
if self.elements_type in self.attentionElements:
layout.label(text="Please note that sector is suffix.")
if self.elements_type in self.canDuplicatedElements:
layout.label(text="This element can use duplication feature.")
# cfg
layout.prop(self, "elements_type") layout.prop(self, "elements_type")
if self.elements_type not in self.uniqueElements: if self.elements_type not in self.uniqueElements:
layout.prop(self, "elements_sector") layout.prop(self, "elements_sector")
if self.elements_type in self.attentionElements:
layout.label(text="Please note that sector is suffix.") if self.elements_type in self.canDuplicatedElements:
layout.separator()
layout.prop(self, "elements_duplicated")
layout.prop(self, "elements_dup_times")

View File

@ -16,48 +16,27 @@ class BALLANCE_OT_add_rails(bpy.types.Operator):
) )
rail_radius: bpy.props.FloatProperty( rail_radius: bpy.props.FloatProperty(
name="Rail radius", name="Rail Radius",
description="Define rail section radius", description="Define rail section radius",
default=0.375, default=0.375,
) )
rail_span: bpy.props.FloatProperty( rail_span: bpy.props.FloatProperty(
name="Rail span", name="Rail Span",
description="Define rail span", description="The length between 2 single rails.",
default=3.75, default=3.75,
) )
def execute(self, context): def execute(self, context):
bpy.ops.object.select_all(action='DESELECT')
# create one first # create one first
bpy.ops.mesh.primitive_circle_add(vertices=8, firstObj = _create_ballance_circle(self.rail_radius, (0.0, 0.0, 0.0))
radius=self.rail_radius,
fill_type='NOTHING',
calc_uvs=False,
enter_editmode=False,
align='WORLD',
location=(0.0, 0.0, 0.0))
firstObj = bpy.context.selected_objects[0]
# for double rail # for double rail
if self.rail_type == 'DOUBLE': if self.rail_type == 'DOUBLE':
bpy.ops.object.select_all(action='DESELECT') # create another one
bpy.ops.mesh.primitive_circle_add(vertices=8, secondObj = _create_ballance_circle(self.rail_radius, (self.rail_span, 0.0, 0.0))
radius=self.rail_radius,
fill_type='NOTHING',
calc_uvs=False,
enter_editmode=False,
align='WORLD',
location=(self.rail_span, 0.0, 0.0))
secondObj = bpy.context.selected_objects[0]
# merge # merge
bpy.ops.object.select_all(action='DESELECT') firstObj = _merge_two_circle(firstObj, secondObj)
bpy.context.view_layer.objects.active = firstObj
firstObj.select_set(True)
secondObj.select_set(True)
bpy.ops.object.join()
# apply 3d cursor # apply 3d cursor
UTILS_functions.move_to_cursor(firstObj) UTILS_functions.move_to_cursor(firstObj)
@ -75,3 +54,78 @@ class BALLANCE_OT_add_rails(bpy.types.Operator):
if self.rail_type == 'DOUBLE': if self.rail_type == 'DOUBLE':
layout.prop(self, "rail_span") layout.prop(self, "rail_span")
class BALLANCE_OT_add_tunnels(bpy.types.Operator):
"""Add rail"""
bl_idname = "ballance.add_tunnels"
bl_label = "Add tunnel section"
bl_options = {'UNDO'}
use_outside: bpy.props.BoolProperty(
name="Double Sides",
description="Create tunnel section with double sides, not a single face.",
default=True,
)
inside_radius: bpy.props.FloatProperty(
name="Inside Radius",
description="Tunnel inside radius",
default=2.5,
)
outside_radius: bpy.props.FloatProperty(
name="Outside Radius",
description="Tunnel outside radius",
default=2.6,
)
def execute(self, context):
# create one first
firstObj = _create_ballance_circle(self.inside_radius, (0.0, 0.0, 0.0))
# for double rail
if self.use_outside:
# create another one
secondObj = _create_ballance_circle(self.outside_radius, (0.0, 0.0, 0.0))
# merge
firstObj = _merge_two_circle(firstObj, secondObj)
# apply 3d cursor
UTILS_functions.move_to_cursor(firstObj)
return {'FINISHED'}
def invoke(self, context, event):
wm = context.window_manager
return wm.invoke_props_dialog(self)
def draw(self, context):
layout = self.layout
layout.prop(self, "use_outside")
layout.prop(self, "inside_radius")
if self.use_outside:
layout.prop(self, "outside_radius")
def _create_ballance_circle(radius, loc):
bpy.ops.object.select_all(action='DESELECT')
bpy.ops.mesh.primitive_circle_add(
vertices=8,
radius=radius,
fill_type='NOTHING',
calc_uvs=False,
enter_editmode=False,
align='WORLD',
location=loc
)
created_obj = bpy.context.selected_objects[0]
bpy.ops.object.select_all(action='DESELECT')
return created_obj
def _merge_two_circle(obj1, obj2):
bpy.ops.object.select_all(action='DESELECT')
bpy.context.view_layer.objects.active = obj1
obj1.select_set(True)
obj2.select_set(True)
bpy.ops.object.join()
return obj1

View File

@ -98,7 +98,7 @@ class common_group_name_props(bpy.types.Operator):
if (self.group_name_source == 'CUSTOM'): if (self.group_name_source == 'CUSTOM'):
parent_layout.prop(self, 'custom_group_name') parent_layout.prop(self, 'custom_group_name')
else: else:
parent_layout.prop(self, 'group_name') parent_layout.prop(self, 'group_name') # do not translate group name. it's weird
def get_group_name_string(self): def get_group_name_string(self):
return str(self.custom_group_name if self.group_name_source == 'CUSTOM' else self.group_name) return str(self.custom_group_name if self.group_name_source == 'CUSTOM' else self.group_name)

View File

@ -108,6 +108,16 @@ class BALLANCE_MT_AddFloorMenu(bpy.types.Menu):
text=item, icon_value = UTILS_constants.icons_floorDict[item]) text=item, icon_value = UTILS_constants.icons_floorDict[item])
cop.floor_type = item cop.floor_type = item
class BALLANCE_MT_AddRailMenu(bpy.types.Menu):
"""Add Ballance rail"""
bl_idname = "BALLANCE_MT_AddRailMenu"
bl_label = "Rails"
def draw(self, context):
layout = self.layout
layout.operator(OBJS_add_rails.BALLANCE_OT_add_rails.bl_idname, text="Rail Section")
layout.operator(OBJS_add_rails.BALLANCE_OT_add_tunnels.bl_idname, text="Tunnel Section")
# ============================================= # =============================================
# blender call system # blender call system
@ -126,8 +136,10 @@ classes = (
OBJS_add_components.BALLANCE_OT_add_components, OBJS_add_components.BALLANCE_OT_add_components,
OBJS_add_rails.BALLANCE_OT_add_rails, OBJS_add_rails.BALLANCE_OT_add_rails,
OBJS_add_rails.BALLANCE_OT_add_tunnels,
OBJS_add_floors.BALLANCE_OT_add_floors, OBJS_add_floors.BALLANCE_OT_add_floors,
BALLANCE_MT_AddFloorMenu, BALLANCE_MT_AddFloorMenu,
BALLANCE_MT_AddRailMenu,
NAMES_rename_system.BALLANCE_OT_rename_by_group, NAMES_rename_system.BALLANCE_OT_rename_by_group,
NAMES_rename_system.BALLANCE_OT_convert_name, NAMES_rename_system.BALLANCE_OT_convert_name,
@ -162,11 +174,11 @@ def menu_func_ballance_add(self, context):
layout = self.layout layout = self.layout
layout.separator() layout.separator()
layout.label(text="Ballance") layout.label(text="Ballance")
layout.menu(BALLANCE_MT_AddFloorMenu.bl_idname, icon='MESH_CUBE')
layout.menu(BALLANCE_MT_AddRailMenu.bl_idname, icon='MESH_CIRCLE')
layout.operator_menu_enum( layout.operator_menu_enum(
OBJS_add_components.BALLANCE_OT_add_components.bl_idname, OBJS_add_components.BALLANCE_OT_add_components.bl_idname,
"elements_type", icon='MESH_ICOSPHERE', text="Elements") "elements_type", icon='MESH_ICOSPHERE', text="Elements")
layout.operator(OBJS_add_rails.BALLANCE_OT_add_rails.bl_idname, icon='MESH_CIRCLE', text="Rail section")
layout.menu(BALLANCE_MT_AddFloorMenu.bl_idname, icon='MESH_CUBE')
def menu_func_ballance_rename(self, context): def menu_func_ballance_rename(self, context):
layout = self.layout layout = self.layout
layout.separator() layout.separator()