diff --git a/bbp_ng/OP_OBJECT_naming_convention.py b/bbp_ng/OP_OBJECT_naming_convention.py new file mode 100644 index 0000000..23f7645 --- /dev/null +++ b/bbp_ng/OP_OBJECT_naming_convention.py @@ -0,0 +1,100 @@ +import bpy +import typing +from . import UTIL_naming_convension, UTIL_functions, UTIL_icons_manager + +class BBP_OT_regulate_objects_name(bpy.types.Operator): + """Regulate Objects Name by Virtools Group and Naming Convention""" + bl_idname = "bbp.regulate_objects_name" + bl_label = "Regulate Objects Name" + bl_options = {'UNDO'} + + def invoke(self, context, event): + wm = context.window_manager + return wm.invoke_confirm(self, event) + + def execute(self, context): + _rename_core( + UTIL_naming_convension.VirtoolsGroupConvention.parse_from_object, + UTIL_naming_convension.YYCToolchainConvention.set_to_object + ) + return {'FINISHED'} + +class BBP_OT_auto_grouping(bpy.types.Operator): + """Auto Grouping Objects by Its Name and Name Convention""" + bl_idname = "bbp.auto_grouping" + bl_label = "Auto Grouping" + bl_options = {'UNDO'} + + def invoke(self, context, event): + wm = context.window_manager + return wm.invoke_confirm(self, event) + + def execute(self, context): + _rename_core( + UTIL_naming_convension.YYCToolchainConvention.parse_from_object, + UTIL_naming_convension.VirtoolsGroupConvention.set_to_object + ) + return {'FINISHED'} + +class BBP_OT_convert_to_imengyu(bpy.types.Operator): + """Convert Objects Name from YYC Convention to Imengyu Convention.""" + bl_idname = "bbp.convert_to_imengyu" + bl_label = "Convert to Imengyu" + bl_options = {'UNDO'} + + def invoke(self, context, event): + wm = context.window_manager + return wm.invoke_confirm(self, event) + + def execute(self, context): + _rename_core( + UTIL_naming_convension.YYCToolchainConvention.parse_from_object, + UTIL_naming_convension.ImengyuConvention.set_to_object + ) + return {'FINISHED'} + +def _rename_core( + fct_get_info: typing.Callable[[bpy.types.Object, UTIL_naming_convension.RenameErrorReporter], UTIL_naming_convension.BallanceObjectInfo | None], + ftc_set_info: typing.Callable[[bpy.types.Object, UTIL_naming_convension.BallanceObjectInfo, UTIL_naming_convension.RenameErrorReporter], bool] + ) -> None: + # get selected objects. allow nested collection + selected_objects: typing.Iterable[bpy.types.Object] = bpy.context.view_layer.active_layer_collection.collection.all_objects + + # create reporter + with UTIL_naming_convension.RenameErrorReporter() as reporter: + # iterate objects + for obj in selected_objects: + reporter.enter_object(obj) + + # try get info + info: UTIL_naming_convension.BallanceObjectInfo | None = fct_get_info(obj, reporter) + if info is not None: + # if info is valid, try assign it + if not ftc_set_info(obj, info, reporter): + reporter.add_error('Fail to set info to object.') + else: + reporter.add_error('Fail to get info from object.') + + # end obj process + reporter.leave_object(obj) + + # report data + UTIL_functions.message_box( + ( + 'View console to get more detail', + f'All: {reporter.get_all_objs_count()}', + f'Failed: {reporter.get_failed_objs_count()}' + ), + 'Rename System Report', + UTIL_icons_manager.BlenderPresetIcons.Info.value + ) + +def register(): + bpy.utils.register_class(BBP_OT_regulate_objects_name) + bpy.utils.register_class(BBP_OT_auto_grouping) + bpy.utils.register_class(BBP_OT_convert_to_imengyu) + +def unregister(): + bpy.utils.unregister_class(BBP_OT_convert_to_imengyu) + bpy.utils.unregister_class(BBP_OT_auto_grouping) + bpy.utils.unregister_class(BBP_OT_regulate_objects_name) diff --git a/bbp_ng/__init__.py b/bbp_ng/__init__.py index cf6f196..09482a2 100644 --- a/bbp_ng/__init__.py +++ b/bbp_ng/__init__.py @@ -33,7 +33,7 @@ from . import PROP_preferences, PROP_ptrprop_resolver, PROP_virtools_material, P from . import OP_IMPORT_bmfile, OP_EXPORT_bmfile, OP_IMPORT_virtools, OP_EXPORT_virtools from . import OP_UV_flatten_uv, OP_UV_rail_uv from . import OP_ADDS_component, OP_ADDS_bme -from . import OP_OBJECT_legacy_align, OP_OBJECT_virtools_group +from . import OP_OBJECT_legacy_align, OP_OBJECT_virtools_group, OP_OBJECT_naming_convention #region Menu @@ -118,7 +118,7 @@ def menu_drawer_view3d(self, context) -> None: def menu_drawer_add(self, context) -> None: layout: bpy.types.UILayout = self.layout layout.separator() - layout.label(text="Ballance") + layout.label(text = "Ballance") layout.menu(BBP_MT_AddBmeMenu.bl_idname, icon='MESH_CUBE') layout.menu(BBP_MT_AddRailMenu.bl_idname, icon='MESH_CIRCLE') layout.menu(BBP_MT_AddComponentsMenu.bl_idname, icon='MESH_ICOSPHERE') @@ -134,11 +134,24 @@ def menu_drawer_grouping(self, context) -> None: col = layout.column() col.operator_context = 'INVOKE_DEFAULT' - col.label(text="Virtools Group") + col.label(text = "Virtools Group") col.operator(OP_OBJECT_virtools_group.BBP_OT_add_objects_virtools_group.bl_idname, icon = 'ADD', text = "Group into...") col.operator(OP_OBJECT_virtools_group.BBP_OT_rm_objects_virtools_group.bl_idname, icon = 'REMOVE', text = "Ungroup from...") col.operator(OP_OBJECT_virtools_group.BBP_OT_clear_objects_virtools_group.bl_idname, icon = 'TRASH', text = "Clear All Groups") +def menu_drawer_naming_convention(self, context) -> None: + layout: bpy.types.UILayout = self.layout + layout.separator() + + # same reason in `menu_drawer_grouping()`` + col = layout.column() + col.operator_context = 'INVOKE_DEFAULT' + + col.label(text = "Ballance") + col.operator(OP_OBJECT_naming_convention.BBP_OT_regulate_objects_name.bl_idname, icon = 'GREASEPENCIL') + col.operator(OP_OBJECT_naming_convention.BBP_OT_auto_grouping.bl_idname, icon = 'GROUP') + col.operator(OP_OBJECT_naming_convention.BBP_OT_convert_to_imengyu.bl_idname, icon = 'ARROW_LEFTRIGHT') + #endregion #region Register and Unregister. @@ -168,6 +181,8 @@ g_BldMenus: tuple[MenuEntry, ...] = ( # register double (for 2 menus) MenuEntry(bpy.types.VIEW3D_MT_object_context_menu, True, menu_drawer_grouping), MenuEntry(bpy.types.OUTLINER_MT_object, True, menu_drawer_grouping), + + MenuEntry(bpy.types.OUTLINER_MT_collection, True, menu_drawer_naming_convention), ) def register() -> None: @@ -194,6 +209,7 @@ def register() -> None: OP_OBJECT_legacy_align.register() OP_OBJECT_virtools_group.register() + OP_OBJECT_naming_convention.register() # register other classes for cls in g_BldClasses: @@ -216,6 +232,7 @@ def unregister() -> None: bpy.utils.unregister_class(cls) # unregister modules + OP_OBJECT_naming_convention.unregister() OP_OBJECT_virtools_group.unregister() OP_OBJECT_legacy_align.unregister()