diff --git a/bbp_ng/OP_ADDS_component.py b/bbp_ng/OP_ADDS_component.py index ada7e18..bad0a67 100644 --- a/bbp_ng/OP_ADDS_component.py +++ b/bbp_ng/OP_ADDS_component.py @@ -1,12 +1,47 @@ -import bpy +import bpy, mathutils +import math, typing from . import UTIL_functions, UTIL_icons_manager, UTIL_naming_convension from . import PROP_ballance_element, PROP_virtools_group +#region Param Help Classes + +class ComponentSectorParam(): + component_sector: bpy.props.IntProperty( + name = "Sector", + description = "Define which sector the object will be grouped in", + min = 1, max = 999, + soft_min = 1, soft_max = 8, + default = 1, + ) + + def general_get_component_sector(self) -> int: + return self.component_sector + + def draw_component_sector_params(self, layout: bpy.types.UILayout) -> None: + layout.prop(self, 'component_sector') + +class ComponentCountParam(): + component_count: bpy.props.IntProperty( + name = "Count", + description = "The count of components you want to generate", + min = 1, max = 64, + soft_min = 1, soft_max = 32, + default = 1, + ) + + def general_get_component_count(self) -> int: + return self.component_count + + def draw_component_count_params(self, layout: bpy.types.UILayout) -> None: + layout.prop(self, 'component_count') + +#endregion + #region Help Classes & Functions def _get_component_info(comp_type: PROP_ballance_element.BallanceElementType, comp_sector: int) -> UTIL_naming_convension.BallanceObjectInfo: match(comp_type): - # process special for 2 unique components + # process for 2 special unique components case PROP_ballance_element.BallanceElementType.PS_FourFlames: return UTIL_naming_convension.BallanceObjectInfo.create_from_others(UTIL_naming_convension.BallanceObjectType.LEVEL_START) case PROP_ballance_element.BallanceElementType.PE_Balloon: @@ -18,7 +53,10 @@ def _get_component_info(comp_type: PROP_ballance_element.BallanceElementType, co return UTIL_naming_convension.BallanceObjectInfo.create_from_resetpoint(comp_sector) # process for other components case _: - return UTIL_naming_convension.BallanceObjectInfo.create_from_component(comp_type.name, comp_sector) + return UTIL_naming_convension.BallanceObjectInfo.create_from_component( + PROP_ballance_element.get_ballance_element_name(comp_type), + comp_sector + ) def _set_component_by_info(obj: bpy.types.Object, info: UTIL_naming_convension.BallanceObjectInfo) -> None: # set component name and grouping it into virtools group at the same time @@ -56,7 +94,34 @@ def _check_component_existance(comp_type: PROP_ballance_element.BallanceElementT if expect_name in bpy.data.objects: return expect_name else: return None +def _general_create_component(comp_type: PROP_ballance_element.BallanceElementType, comp_sector: int, comp_count: int, comp_offset: typing.Callable[[int], mathutils.Matrix]) -> None: + """ + General component creation function. + @param comp_type[in] The component type created. + @param comp_sector[in] The sector param which passed to other functions. For non-sector component, pass any number. + @param comp_count[in] The count of created component. For single component creation, please pass 1. + @param comp_offset[in] The function pointer which receive 1 argument indicating the index of object which we want to get its offset. + You can pass `lambda _: mathutils.Matrix.Identity(4)` to get zero offset for every items. + You can pass `lambda _: mathutils.Matrix( xxx )` to get same offset for every items. + You can pass `lambda i: mathutils.Matrix( func(i) )` to get index based offset for each items. + The offset is the offset to the origin point, not the previous object. + """ + # get element info first + ele_info: UTIL_naming_convension.BallanceObjectInfo = _get_component_info(comp_type, comp_sector) + # create blc element context + with PROP_ballance_element.BallanceElementsHelper(bpy.context.scene) as creator: + # object creation counter + for i in range(comp_count): + # get mesh from element context, and create with empty name first. we assign name later. + obj: bpy.types.Object = bpy.data.objects.new('', creator.get_element(comp_type)) + # assign virtools group, object name by we gotten element info. + _set_component_by_info(obj, ele_info) + # add into scene and move to cursor + UTIL_functions.add_into_scene_and_move_to_cursor(obj) + # move with extra offset by calling offset getter + obj.matrix_world = obj.matrix_world @ comp_offset(i) + class EnumPropHelper(): """ Generate component types for this module's operator @@ -69,7 +134,7 @@ class EnumPropHelper(): str(item.value), item.name, "", - UTIL_icons_manager.get_element_icon(item.name), + UTIL_icons_manager.get_element_icon(PROP_ballance_element.get_ballance_element_name(item)), item.value ) for item in PROP_ballance_element.BallanceElementType ) @@ -88,20 +153,14 @@ class EnumPropHelper(): #endregion -class BBP_OT_add_component(bpy.types.Operator): +#region Noemal Component Adder + +class BBP_OT_add_component(bpy.types.Operator, ComponentSectorParam): """Add Component""" bl_idname = "bbp.add_component" bl_label = "Add Component" bl_options = {'UNDO'} - component_sector: bpy.props.IntProperty( - name = "Sector", - description = "Define which sector the object will be grouped in", - min = 1, max = 999, - soft_min = 1, soft_max = 8, - default = 1, - ) - component_type: bpy.props.EnumProperty( name = "Type", description = "This component type", @@ -120,39 +179,255 @@ class BBP_OT_add_component(bpy.types.Operator): # only show sector for non-PE/PS component eletype: PROP_ballance_element.BallanceElementType = EnumPropHelper.get_selection(self.component_type) if eletype != PROP_ballance_element.BallanceElementType.PS_FourFlames and eletype != PROP_ballance_element.BallanceElementType.PE_Balloon: - layout.prop(self, "component_sector") + self.draw_component_sector_params(layout) # check for some special components and show warning - elename: str | None = _check_component_existance(EnumPropHelper.get_selection(self.component_type), self.component_sector) + elename: str | None = _check_component_existance(EnumPropHelper.get_selection(self.component_type), self.general_get_component_sector()) if elename is not None: layout.label(text = f'Warning: {elename} already exist.') def execute(self, context): - # create by ballance components - eletype: PROP_ballance_element.BallanceElementType = EnumPropHelper.get_selection(self.component_type) - eleinfo: UTIL_naming_convension.BallanceObjectInfo = _get_component_info(eletype, self.component_sector) - - with PROP_ballance_element.BallanceElementsHelper(bpy.context.scene) as creator: - # create with empty name first - obj = bpy.data.objects.new('', creator.get_element(eletype.value)) - # assign its props, including name - _set_component_by_info(obj, eleinfo) - # scene cursor - UTIL_functions.add_into_scene_and_move_to_cursor(obj) - + # call general creator + _general_create_component( + EnumPropHelper.get_selection(self.component_type), + self.general_get_component_sector(), + 1, # only create one + lambda _: mathutils.Matrix.Identity(4) + ) return {'FINISHED'} @classmethod def draw_blc_menu(self, layout: bpy.types.UILayout): for item in PROP_ballance_element.BallanceElementType: + item_name: str = PROP_ballance_element.get_ballance_element_name(item) + cop = layout.operator( - self.bl_idname, text = item.name, - icon_value = UTIL_icons_manager.get_element_icon(item.name)) + self.bl_idname, text = item_name, + icon_value = UTIL_icons_manager.get_element_icon(item_name) + ) cop.component_type = EnumPropHelper.to_selection(item) +#endregion + +#region Nong Comp Adder + +class BBP_OT_add_nong_extra_point(bpy.types.Operator, ComponentSectorParam, ComponentCountParam): + """Add Nong Extra Point""" + bl_idname = "bbp.add_nong_extra_point" + bl_label = "Nong Extra Point" + bl_options = {'REGISTER', 'UNDO'} + + def draw(self, context): + layout = self.layout + self.draw_component_sector_params(layout) + self.draw_component_count_params(layout) + + def execute(self, context): + # create objects and rotate it by a certain degree calculated by its index + # calc percent first + percent: float = 1.0 / self.general_get_component_count() + # create elements + _general_create_component( + PROP_ballance_element.BallanceElementType.P_Extra_Point, + self.general_get_component_sector(), + self.general_get_component_count(), + lambda i: mathutils.Matrix.Rotation(percent * i * math.pi * 2, 4, 'Z') + ) + return {'FINISHED'} + + @classmethod + def draw_blc_menu(self, layout: bpy.types.UILayout): + layout.operator( + BBP_OT_add_nong_extra_point.bl_idname, + icon_value = UTIL_icons_manager.get_element_icon( + PROP_ballance_element.get_ballance_element_name(PROP_ballance_element.BallanceElementType.P_Extra_Point) + ) + ) + +#endregion + +#region Series Comp Adder + +class BBP_OT_add_tilting_block_series(bpy.types.Operator, ComponentSectorParam, ComponentCountParam): + """Add Tilting Block Series""" + bl_idname = "bbp.add_tilting_block_series" + bl_label = "Tilting Block Series" + bl_options = {'REGISTER', 'UNDO'} + + component_span: bpy.props.FloatProperty( + name = "Span", + description = "The distance between each titling blocks", + min = 0.0, max = 100.0, + soft_min = 0.0, soft_max = 12.0, + default = 6.0022, + ) + + def draw(self, context): + layout = self.layout + self.draw_component_sector_params(layout) + self.draw_component_count_params(layout) + layout.prop(self, 'component_span') + + def execute(self, context): + # create objects and move it by delta + # get span first + span: float = self.component_span + # create elements + _general_create_component( + PROP_ballance_element.BallanceElementType.P_Modul_41, + self.general_get_component_sector(), + self.general_get_component_count(), + lambda i: mathutils.Matrix.Translation(mathutils.Vector((span * i, 0.0, 0.0))) # move with extra delta in x axis + ) + + return {'FINISHED'} + + @classmethod + def draw_blc_menu(self, layout: bpy.types.UILayout): + layout.operator( + BBP_OT_add_tilting_block_series.bl_idname, + icon_value = UTIL_icons_manager.get_element_icon( + PROP_ballance_element.get_ballance_element_name(PROP_ballance_element.BallanceElementType.P_Modul_41) + ) + ) + +class BBP_OT_add_ventilator_series(bpy.types.Operator, ComponentSectorParam, ComponentCountParam): + """Add Ventilator Series""" + bl_idname = "bbp.add_ventilator_series" + bl_label = "Ventilator Series" + bl_options = {'REGISTER', 'UNDO'} + + component_translation: bpy.props.FloatVectorProperty( + name = "Delta Vector", + description = "The translation between each ventilators. You can use this property to implement vertical or horizontal ventilator series. Set all factors to zero can get Nong ventilator.", + size = 3, subtype = 'TRANSLATION', + min = 0.0, max = 100.0, + soft_min = 0.0, soft_max = 50.0, + default = (0.0, 0.0, 15.0), + ) + + def draw(self, context): + layout = self.layout + self.draw_component_sector_params(layout) + self.draw_component_count_params(layout) + layout.prop(self, 'component_translation') + + def execute(self, context): + # create objects and move it by delta + # get translation first + translation: mathutils.Vector = mathutils.Vector(self.component_translation) + # create elements + _general_create_component( + PROP_ballance_element.BallanceElementType.P_Modul_18, + self.general_get_component_sector(), + self.general_get_component_count(), + lambda i: mathutils.Matrix.Translation(i * translation) # move with extra translation + ) + + return {'FINISHED'} + + @classmethod + def draw_blc_menu(self, layout: bpy.types.UILayout): + layout.operator( + BBP_OT_add_ventilator_series.bl_idname, + icon_value = UTIL_icons_manager.get_element_icon( + PROP_ballance_element.get_ballance_element_name(PROP_ballance_element.BallanceElementType.P_Modul_18) + ) + ) + +#endregion + +#region Comp Pair Adder + +class BBP_OT_add_sector_component_pair(bpy.types.Operator, ComponentSectorParam): + """Add Sector Pair, both check point and reset point.""" + bl_idname = "bbp.add_sector_component_pair" + bl_label = "Sector Pair" + bl_options = {'UNDO'} + + def __get_checkpoint(self) -> tuple[PROP_ballance_element.BallanceElementType, int]: + if self.general_get_component_sector() == 1: + return (PROP_ballance_element.BallanceElementType.PS_FourFlames, 1) + else: + # the sector of two flames should be `sector - 1` because first one was occupied by FourFlams + return (PROP_ballance_element.BallanceElementType.PC_TwoFlames, self.general_get_component_sector() - 1) + + def __get_resetpoint(self) -> tuple[PROP_ballance_element.BallanceElementType, int]: + # resetpoint's sector is just sector it self. + return (PROP_ballance_element.BallanceElementType.PR_Resetpoint, self.general_get_component_sector()) + + def invoke(self, context, event): + wm = context.window_manager + return wm.invoke_props_dialog(self) + + def draw(self, context): + layout = self.layout + self.draw_component_sector_params(layout) + + # check checkpoint and resetpoint name conflict and show warnings + (checkp_ty, checkp_sector) = self.__get_checkpoint() + elename: str | None = _check_component_existance(checkp_ty, checkp_sector) + if elename is not None: + layout.label(text = f'Warning: {elename} already exist.') + + (resetp_ty, resetp_sector) = self.__get_resetpoint() + elename = _check_component_existance(resetp_ty, resetp_sector) + if elename is not None: + layout.label(text = f'Warning: {elename} already exist.') + + def execute(self, context): + # create checkpoint and resetpoint individually in element context + # get type and sector data first + (checkp_ty, checkp_sector) = self.__get_checkpoint() + (resetp_ty, resetp_sector) = self.__get_resetpoint() + # calc resetpoint offset + # resetpoint need a extra offset between checkpoint + # but it is different in FourFlams and TwoFlams + resetp_offset: float + if checkp_ty == PROP_ballance_element.BallanceElementType.PS_FourFlames: + resetp_offset = 3.25 + else: + resetp_offset = 2.0 + + # add elements + # create checkpoint + _general_create_component( + checkp_ty, + checkp_sector, + 1, # only create one + lambda _: mathutils.Matrix.Identity(4) + ) + # create resetpoint + _general_create_component( + resetp_ty, + resetp_sector, + 1, # only create one + lambda _: mathutils.Matrix.Translation(mathutils.Vector((0.0, 0.0, resetp_offset))) # apply resetpoint offset + ) + + return {'FINISHED'} + + @classmethod + def draw_blc_menu(self, layout: bpy.types.UILayout): + layout.operator( + BBP_OT_add_sector_component_pair.bl_idname, + icon_value = UTIL_icons_manager.get_element_icon( + PROP_ballance_element.get_ballance_element_name(PROP_ballance_element.BallanceElementType.PR_Resetpoint) + ) + ) + +#endregion + def register(): - # register all classes 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_tilting_block_series) + bpy.utils.register_class(BBP_OT_add_ventilator_series) + bpy.utils.register_class(BBP_OT_add_sector_component_pair) def unregister(): + 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_tilting_block_series) + bpy.utils.unregister_class(BBP_OT_add_nong_extra_point) bpy.utils.unregister_class(BBP_OT_add_component) diff --git a/bbp_ng/PROP_ballance_element.py b/bbp_ng/PROP_ballance_element.py index 0752903..0f5ffe8 100644 --- a/bbp_ng/PROP_ballance_element.py +++ b/bbp_ng/PROP_ballance_element.py @@ -35,26 +35,48 @@ class BallanceElementType(enum.IntEnum): PS_FourFlames = 26 _g_ElementCount: int = len(BallanceElementType) -_g_ElementNameIdMap: dict[str, int] = dict((entry.name, entry.value) for entry in BallanceElementType) -_g_ElementIdNameMap: dict[int, str] = dict((entry.value, entry.name) for entry in BallanceElementType) -def get_ballance_element_id(name: str) -> int | None: +def get_ballance_element_type_from_id(id: int) -> BallanceElementType | None: """ - Get Ballance element ID by its name. + Get Ballance element type by its id. + + @param id[in] The id of element + @return the type of this Ballance element name distributed by this plugin. or None if providing id is invalid. + """ + try: + return BallanceElementType(id) # https://docs.python.org/zh-cn/3/library/enum.html#enum.EnumType.__call__ + except ValueError: + return None + +def get_ballance_element_type_from_name(name: str) -> BallanceElementType | None: + """ + Get Ballance element type by its name. @param name[in] The name of element - @return the ID of this Ballance element name distributed by this plugin. or None if providing name is invalid. + @return the type of this Ballance element name distributed by this plugin. or None if providing name is invalid. """ - return _g_ElementNameIdMap.get(name, None) + try: + return BallanceElementType[name] # https://docs.python.org/zh-cn/3/library/enum.html#enum.EnumType.__getitem__ + except KeyError: + return None -def get_ballance_element_name(id: int) -> str | None: +def get_ballance_element_id(ty: BallanceElementType) -> int: """ - Get Ballance element name by its ID + Get Ballance element id by its type - @param id[in] The ID of element - @return the name of this Ballance element, or None if ID is invalid. + @param ty[in] The type of element + @return the id of this Ballance element. """ - return _g_ElementIdNameMap.get(id, None) + return ty.value + +def get_ballance_element_name(ty: BallanceElementType) -> str: + """ + Get Ballance element name by its type + + @param ty[in] The type of element + @return the name of this Ballance element. + """ + return ty.name def is_ballance_element(name: str) -> bool: """ @@ -65,16 +87,16 @@ def is_ballance_element(name: str) -> bool: @param name[in] The name of element @return True if providing name is Ballance element name. """ - return get_ballance_element_id(name) is not None + return get_ballance_element_type_from_name(name) is not None #endregion #region Ballance Elements Define & Visitor class BBP_PG_ballance_element(bpy.types.PropertyGroup): - element_name: bpy.props.StringProperty( - name = "Element Name", - default = "" + element_id: bpy.props.IntProperty( + name = "Element Id", + default = 0 ) mesh_ptr: bpy.props.PointerProperty( @@ -94,12 +116,9 @@ def _save_element(mesh: bpy.types.Mesh, filename: str) -> None: # write this function and call this function in operator. pass -def _load_element(mesh: bpy.types.Mesh, element_id: int) -> None: +def _load_element(mesh: bpy.types.Mesh, element_type: BallanceElementType) -> None: # resolve mesh path - element_name: str | None = get_ballance_element_name(element_id) - if element_name is None: - raise UTIL_functions.BBPException('invalid element id in _load_element()') - + element_name: str = get_ballance_element_name(element_type) element_filename: str = os.path.join( os.path.dirname(__file__), "meshes", @@ -208,7 +227,7 @@ class BallanceElementsHelper(): __mSingletonMutex: typing.ClassVar[bool] = False __mIsValid: bool __mAssocScene: bpy.types.Scene - __mElementMap: dict[int, bpy.types.Mesh] + __mElementMap: dict[BallanceElementType, bpy.types.Mesh] def __init__(self, assoc: bpy.types.Scene): self.__mElementMap = {} @@ -240,36 +259,30 @@ class BallanceElementsHelper(): self.__mIsValid = False BallanceElementsHelper.__mSingletonMutex = False - def get_element(self, element_id: int) -> bpy.types.Mesh: + def get_element(self, element_type: BallanceElementType) -> bpy.types.Mesh: if not self.is_valid(): raise UTIL_functions.BBPException('calling invalid BallanceElementsHelper') # get exist one - mesh: bpy.types.Mesh | None = self.__mElementMap.get(element_id, None) + mesh: bpy.types.Mesh | None = self.__mElementMap.get(element_type, None) if mesh is not None: return mesh # if no existing one, create new one - new_mesh_name: str | None = get_ballance_element_name(element_id) - if new_mesh_name is None: - raise UTIL_functions.BBPException('invalid element id') + new_mesh_name: str = get_ballance_element_name(element_type) new_mesh: bpy.types.Mesh = bpy.data.meshes.new(new_mesh_name) - _load_element(new_mesh, element_id) - self.__mElementMap[element_id] = new_mesh + _load_element(new_mesh, element_type) + self.__mElementMap[element_type] = new_mesh return new_mesh def __write_to_ballance_elements(self) -> None: elements: bpy.types.CollectionProperty = get_ballance_elements(self.__mAssocScene) elements.clear() - for eleid, elemesh in self.__mElementMap.items(): - name: str | None = get_ballance_element_name(eleid) - if name is None: - continue - + for elety, elemesh in self.__mElementMap.items(): item: BBP_PG_ballance_element = elements.add() - item.element_name = name + item.element_id = get_ballance_element_id(elety) item.mesh_ptr = elemesh def __read_from_ballance_element(self) -> None: @@ -280,11 +293,11 @@ class BallanceElementsHelper(): for item in elements: # check requirements if item.mesh_ptr is None: continue - mesh_id: int | None = get_ballance_element_id(item.element_name) - if mesh_id is None: continue + element_type: BallanceElementType | None = get_ballance_element_type_from_id(item.element_id) + if element_type is None: continue # add into map - self.__mElementMap[mesh_id] = item.mesh_ptr + self.__mElementMap[element_type] = item.mesh_ptr def reset_ballance_elements(scene: bpy.types.Scene) -> None: invalid_idx: list[int] = [] @@ -294,13 +307,13 @@ def reset_ballance_elements(scene: bpy.types.Scene) -> None: index: int = 0 item: BBP_PG_ballance_element for item in elements: - eleid: int | None = get_ballance_element_id(item.element_name) + elety: BallanceElementType | None = get_ballance_element_type_from_id(item.element_id) # load or record invalid entry - if eleid is None or item.mesh_ptr is None: + if elety is None or item.mesh_ptr is None: invalid_idx.append(index) else: - _load_element(item.mesh_ptr, eleid) + _load_element(item.mesh_ptr, elety) # inc counter index += 1 @@ -316,9 +329,13 @@ def reset_ballance_elements(scene: bpy.types.Scene) -> None: class BBP_UL_ballance_elements(bpy.types.UIList): def draw_item(self, context, layout: bpy.types.UILayout, data, item: BBP_PG_ballance_element, icon, active_data, active_propname): - if item.element_name != "" and item.mesh_ptr is not None: - layout.label(text = item.element_name, translate = False) - layout.label(text = item.mesh_ptr.name, translate = False, icon = 'MESH_DATA') + # check requirements + elety: BallanceElementType | None = get_ballance_element_type_from_id(item.element_id) + if elety is None or item.mesh_ptr is None: return + + # draw list item + layout.label(text = get_ballance_element_name(elety), translate = False) + layout.label(text = item.mesh_ptr.name, translate = False, icon = 'MESH_DATA') class BBP_OT_reset_ballance_elements(bpy.types.Operator): """Reset all Meshes of Loaded Ballance Elements to Original Geometry.""" diff --git a/bbp_ng/UTIL_functions.py b/bbp_ng/UTIL_functions.py index a837d75..8c9fba7 100644 --- a/bbp_ng/UTIL_functions.py +++ b/bbp_ng/UTIL_functions.py @@ -1,4 +1,4 @@ -import bpy +import bpy, mathutils import math, typing, enum, sys class BBPException(Exception): @@ -53,11 +53,17 @@ def message_box(message: tuple[str, ...], title: str, icon: str): bpy.context.window_manager.popup_menu(draw, title = title, icon = icon) def move_to_cursor(obj: bpy.types.Object): - obj.location = bpy.context.scene.cursor.location + # use obj.matrix_world to move, not obj.location because this bug: + # https://blender.stackexchange.com/questions/27667/incorrect-matrix-world-after-transformation + # the update of matrix_world after setting location is not immediately. + # and calling update() function for view_layer for the translation of each object is not suit for too much objects. + + # obj.location = bpy.context.scene.cursor.location + obj.matrix_world = obj.matrix_world @ mathutils.Matrix.Translation(bpy.context.scene.cursor.location - obj.location) def add_into_scene_and_move_to_cursor(obj: bpy.types.Object): - move_to_cursor(obj) - view_layer = bpy.context.view_layer collection = view_layer.active_layer_collection.collection collection.objects.link(obj) + + move_to_cursor(obj) diff --git a/bbp_ng/__init__.py b/bbp_ng/__init__.py index 3dd18a4..4a8b225 100644 --- a/bbp_ng/__init__.py +++ b/bbp_ng/__init__.py @@ -67,23 +67,28 @@ class BBP_MT_AddRailMenu(bpy.types.Menu): def draw(self, context): layout = self.layout -class BBP_MT_AddElementsMenu(bpy.types.Menu): - """Add Ballance Elements""" - bl_idname = "BBP_MT_AddElementsMenu" - bl_label = "Elements" +class BBP_MT_AddComponentsMenu(bpy.types.Menu): + """Add Ballance Components""" + bl_idname = "BBP_MT_AddComponentsMenu" + bl_label = "Components" def draw(self, context): layout = self.layout - layout.label(text="Basic Elements") + layout.label(text="Basic Components") OP_ADDS_component.BBP_OT_add_component.draw_blc_menu(layout) layout.separator() - layout.label(text="Duplicated Elements") - #OBJS_add_components.BBP_OT_add_components_dup.draw_blc_menu(layout) + layout.label(text="Nong Components") + OP_ADDS_component.BBP_OT_add_nong_extra_point.draw_blc_menu(layout) layout.separator() - layout.label(text="Elements Pair") - #OBJS_add_components.BBP_OT_add_components_series.draw_blc_menu(layout) + layout.label(text="Series Components") + OP_ADDS_component.BBP_OT_add_tilting_block_series.draw_blc_menu(layout) + OP_ADDS_component.BBP_OT_add_ventilator_series.draw_blc_menu(layout) + + layout.separator() + layout.label(text="Components Pair") + OP_ADDS_component.BBP_OT_add_sector_component_pair.draw_blc_menu(layout) # ===== Menu Drawer ===== @@ -109,10 +114,10 @@ def menu_drawer_add(self, context): layout.label(text="Ballance") layout.menu(BBP_MT_AddFloorMenu.bl_idname, icon='MESH_CUBE') layout.menu(BBP_MT_AddRailMenu.bl_idname, icon='MESH_CIRCLE') - layout.menu(BBP_MT_AddElementsMenu.bl_idname, icon='MESH_ICOSPHERE') + layout.menu(BBP_MT_AddComponentsMenu.bl_idname, icon='MESH_ICOSPHERE') #layout.operator_menu_enum( # OBJS_add_components.BALLANCE_OT_add_components.bl_idname, - # "elements_type", icon='MESH_ICOSPHERE', text="Elements") + # "Components_type", icon='MESH_ICOSPHERE', text="Components") #endregion #region Register and Unregister. @@ -121,7 +126,7 @@ g_BldClasses: tuple[typing.Any, ...] = ( BBP_MT_View3DMenu, BBP_MT_AddFloorMenu, BBP_MT_AddRailMenu, - BBP_MT_AddElementsMenu + BBP_MT_AddComponentsMenu ) class MenuEntry():