[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:
parent
2a87e98904
commit
e7376a3e9c
@ -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**.
|
||||||
|
|
||||||
|
@ -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")
|
||||||
|
@ -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
|
||||||
|
@ -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)
|
||||||
|
@ -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()
|
||||||
|
Loading…
Reference in New Issue
Block a user