diff --git a/README.md b/README.md index a6f0777..1abf3e3 100644 --- a/README.md +++ b/README.md @@ -13,9 +13,9 @@ This plugin contain various aspect of Ballance mapping. However, if some feature ## 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 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) +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). +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**. diff --git a/ballance_blender_plugin/OBJS_add_components.py b/ballance_blender_plugin/OBJS_add_components.py index 69ab3b2..2475f62 100644 --- a/ballance_blender_plugin/OBJS_add_components.py +++ b/ballance_blender_plugin/OBJS_add_components.py @@ -15,14 +15,27 @@ class BALLANCE_OT_add_components(bpy.types.Operator): items=tuple(map(lambda x: (x, x, ""), UTILS_constants.bmfile_componentList)), ) - attentionElements = ["PC_TwoFlames", "PR_Resetpoint"] - uniqueElements = ["PS_FourFlames", "PE_Balloon"] + attentionElements = ("PC_TwoFlames", "PR_Resetpoint") + uniqueElements = ("PS_FourFlames", "PE_Balloon") + canDuplicatedElements = ('P_Extra_Point', 'P_Modul_18', 'P_Modul_26') elements_sector: bpy.props.IntProperty( name="Sector", description="Define which sector the object will be grouped in", - min=1, - max=8, + min=1, 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, ) @@ -41,6 +54,13 @@ class BALLANCE_OT_add_components(bpy.types.Operator): obj = bpy.data.objects.new(finalObjectName, loadedMesh) 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'} def invoke(self, context, event): @@ -49,8 +69,18 @@ class BALLANCE_OT_add_components(bpy.types.Operator): def draw(self, context): 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") if self.elements_type not in self.uniqueElements: 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") diff --git a/ballance_blender_plugin/OBJS_add_rails.py b/ballance_blender_plugin/OBJS_add_rails.py index 3798609..9fd41fa 100644 --- a/ballance_blender_plugin/OBJS_add_rails.py +++ b/ballance_blender_plugin/OBJS_add_rails.py @@ -16,48 +16,27 @@ class BALLANCE_OT_add_rails(bpy.types.Operator): ) rail_radius: bpy.props.FloatProperty( - name="Rail radius", + name="Rail Radius", description="Define rail section radius", default=0.375, ) rail_span: bpy.props.FloatProperty( - name="Rail span", - description="Define rail span", + name="Rail Span", + description="The length between 2 single rails.", default=3.75, ) def execute(self, context): - bpy.ops.object.select_all(action='DESELECT') # create one first - bpy.ops.mesh.primitive_circle_add(vertices=8, - 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] + firstObj = _create_ballance_circle(self.rail_radius, (0.0, 0.0, 0.0)) # for double rail if self.rail_type == 'DOUBLE': - bpy.ops.object.select_all(action='DESELECT') - bpy.ops.mesh.primitive_circle_add(vertices=8, - 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] - + # create another one + secondObj = _create_ballance_circle(self.rail_radius, (self.rail_span, 0.0, 0.0)) # merge - bpy.ops.object.select_all(action='DESELECT') - bpy.context.view_layer.objects.active = firstObj - firstObj.select_set(True) - secondObj.select_set(True) - bpy.ops.object.join() + firstObj = _merge_two_circle(firstObj, secondObj) # apply 3d cursor UTILS_functions.move_to_cursor(firstObj) @@ -75,3 +54,78 @@ class BALLANCE_OT_add_rails(bpy.types.Operator): if self.rail_type == 'DOUBLE': 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 diff --git a/ballance_blender_plugin/UTILS_virtools_prop.py b/ballance_blender_plugin/UTILS_virtools_prop.py index 7027dd0..e34a571 100644 --- a/ballance_blender_plugin/UTILS_virtools_prop.py +++ b/ballance_blender_plugin/UTILS_virtools_prop.py @@ -98,7 +98,7 @@ class common_group_name_props(bpy.types.Operator): if (self.group_name_source == 'CUSTOM'): parent_layout.prop(self, 'custom_group_name') 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): return str(self.custom_group_name if self.group_name_source == 'CUSTOM' else self.group_name) diff --git a/ballance_blender_plugin/__init__.py b/ballance_blender_plugin/__init__.py index 9d443b9..d2484a9 100644 --- a/ballance_blender_plugin/__init__.py +++ b/ballance_blender_plugin/__init__.py @@ -108,6 +108,16 @@ class BALLANCE_MT_AddFloorMenu(bpy.types.Menu): text=item, icon_value = UTILS_constants.icons_floorDict[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 @@ -126,8 +136,10 @@ classes = ( OBJS_add_components.BALLANCE_OT_add_components, OBJS_add_rails.BALLANCE_OT_add_rails, + OBJS_add_rails.BALLANCE_OT_add_tunnels, OBJS_add_floors.BALLANCE_OT_add_floors, BALLANCE_MT_AddFloorMenu, + BALLANCE_MT_AddRailMenu, NAMES_rename_system.BALLANCE_OT_rename_by_group, NAMES_rename_system.BALLANCE_OT_convert_name, @@ -162,11 +174,11 @@ def menu_func_ballance_add(self, context): layout = self.layout layout.separator() 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( OBJS_add_components.BALLANCE_OT_add_components.bl_idname, "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): layout = self.layout layout.separator()