From 997839a187dce425f76f05d81fc8708646b4ec4f Mon Sep 17 00:00:00 2001 From: yyc12345 Date: Sun, 11 Feb 2024 17:11:05 +0800 Subject: [PATCH] feat: select object after creation of floor, rail and component --- bbp_ng/OP_ADDS_bme.py | 14 ++-- bbp_ng/OP_ADDS_component.py | 134 ++++++++++++++++++++++-------------- bbp_ng/OP_ADDS_rail.py | 2 + bbp_ng/UTIL_functions.py | 12 ++++ 4 files changed, 105 insertions(+), 57 deletions(-) diff --git a/bbp_ng/OP_ADDS_bme.py b/bbp_ng/OP_ADDS_bme.py index 3da1fc2..148065d 100644 --- a/bbp_ng/OP_ADDS_bme.py +++ b/bbp_ng/OP_ADDS_bme.py @@ -14,18 +14,18 @@ class BBP_PG_bme_adder_cfgs(bpy.types.PropertyGroup): soft_min = 0, soft_max = 32, step = 1, default = 1, - ) + ) # type: ignore prop_float: bpy.props.FloatProperty( name = 'Single Float', description = 'Single Float', min = 0.0, max = 1024.0, soft_min = 0.0, soft_max = 512.0, step = 50, # Step is in UI, in [1, 100] (WARNING: actual value is /100). So we choose 50, mean 0.5 default = 5.0, - ) + ) # type: ignore prop_bool: bpy.props.BoolProperty( name = 'Single Bool', description = 'Single Bool', default = True - ) + ) # type: ignore class BBP_OT_add_bme_struct(bpy.types.Operator): """Add BME Struct""" @@ -55,7 +55,7 @@ class BBP_OT_add_bme_struct(bpy.types.Operator): description = "Internal flag.", options = {'HIDDEN', 'SKIP_SAVE'}, default = False - ) + ) # type: ignore ## A BME struct cfgs descriptor cache list # Not only the descriptor self, also the cfg associated index in bme_struct_cfgs @@ -133,13 +133,13 @@ def bme_struct_type_updated(self, context): description = "BME struct type", items = _g_EnumHelper_BmeStructType.generate_items(), update = bme_struct_type_updated - ) + ) # type: ignore bme_struct_cfgs : bpy.props.CollectionProperty( name = "Cfgs", description = "Cfg collection.", type = BBP_PG_bme_adder_cfgs, - ) + ) # type: ignore @classmethod def poll(self, context): @@ -180,6 +180,8 @@ def execute(self, context): # move to cursor UTIL_functions.add_into_scene_and_move_to_cursor(obj) + # select created object + UTIL_functions.select_certain_objects((obj, )) return {'FINISHED'} def draw(self, context): diff --git a/bbp_ng/OP_ADDS_component.py b/bbp_ng/OP_ADDS_component.py index 728e00e..db1a7b6 100644 --- a/bbp_ng/OP_ADDS_component.py +++ b/bbp_ng/OP_ADDS_component.py @@ -12,7 +12,7 @@ class ComponentSectorParam(): min = 1, max = 999, soft_min = 1, soft_max = 8, default = 1, - ) + ) # type: ignore def general_get_component_sector(self) -> int: return self.component_sector @@ -27,7 +27,7 @@ class ComponentCountParam(): min = 1, max = 64, soft_min = 1, soft_max = 32, default = 1, - ) + ) # type: ignore def general_get_component_count(self) -> int: return self.component_count @@ -94,38 +94,61 @@ 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: +class _GeneralComponentCreator(): """ - 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. + The assist class for general component creation function. + Because we need select all created component, thus we need collect all created object into a list. + This is the reason why we create this class. """ - # 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) + + ## The list storing all created component within this creation. + __mObjList: list[bpy.types.Object] + + def __init__(self): + self.__mObjList = [] + + def create_component(self, + 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. + @return The created component instance. + """ + # 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) + # put into created object list + self.__mObjList.append(obj) + + def finish_component(self) -> None: + """ + Finish up component creation. + Just deselect all objects and select all created components. + """ + UTIL_functions.select_certain_objects(tuple(self.__mObjList)) #endregion @@ -156,7 +179,7 @@ class BBP_OT_add_component(bpy.types.Operator, ComponentSectorParam): name = "Type", description = "This component type", items = _g_EnumHelper_Component.generate_items(), - ) + ) # type: ignore def invoke(self, context, event): wm = context.window_manager @@ -179,12 +202,14 @@ def draw(self, context): def execute(self, context): # call general creator - _general_create_component( + creator: _GeneralComponentCreator = _GeneralComponentCreator() + creator.create_component( _g_EnumHelper_Component.get_selection(self.component_type), self.general_get_component_sector(), 1, # only create one lambda _: mathutils.Matrix.Identity(4) ) + creator.finish_component() return {'FINISHED'} @staticmethod @@ -218,12 +243,14 @@ def execute(self, context): # calc percent first percent: float = 1.0 / self.general_get_component_count() # create elements - _general_create_component( + creator: _GeneralComponentCreator = _GeneralComponentCreator() + creator.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') ) + creator.finish_component() return {'FINISHED'} @staticmethod @@ -243,22 +270,22 @@ class BBP_OT_add_nong_ventilator(bpy.types.Operator, ComponentSectorParam, Compo ventilator_count_source: bpy.props.EnumProperty( name = "Ventilator Count Source", - items = ( + items = [ ('DEFINED', "Predefined", "Pre-defined ventilator count."), ('CUSTOM', "Custom", "User specified ventilator count."), - ), - ) + ], + ) # type: ignore preset_vetilator_count: bpy.props.EnumProperty( name = "Preset Count", description = "Pick preset ventilator count.", - items = ( + items = [ # (token, display name, descriptions, icon, index) ('PAPER', 'Paper', 'The ventilator count (1) can push paper ball up.'), ('WOOD', 'Wood', 'The ventilator count (6) can push wood ball up.'), ('STONE', 'Stone', 'The ventilator count (32) can push stone ball up.'), - ), - ) + ], + ) # type: ignore def draw(self, context): layout = self.layout @@ -286,12 +313,14 @@ def execute(self, context): case _: raise UTIL_functions.BBPException('invalid enumprop data') # create elements without any move - _general_create_component( + creator: _GeneralComponentCreator = _GeneralComponentCreator() + creator.create_component( PROP_ballance_element.BallanceElementType.P_Modul_18, self.general_get_component_sector(), count, lambda _: mathutils.Matrix.Identity(4) ) + creator.finish_component() return {'FINISHED'} @staticmethod @@ -319,7 +348,7 @@ class BBP_OT_add_tilting_block_series(bpy.types.Operator, ComponentSectorParam, min = 0.0, max = 100.0, soft_min = 0.0, soft_max = 12.0, default = 6.0022, - ) + ) # type: ignore def draw(self, context): layout = self.layout @@ -332,13 +361,14 @@ def execute(self, context): # get span first span: float = self.component_span # create elements - _general_create_component( + creator: _GeneralComponentCreator = _GeneralComponentCreator() + creator.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 ) - + creator.finish_component() return {'FINISHED'} @staticmethod @@ -363,7 +393,7 @@ class BBP_OT_add_ventilator_series(bpy.types.Operator, ComponentSectorParam, Com min = 0.0, max = 100.0, soft_min = 0.0, soft_max = 50.0, default = (0.0, 0.0, 15.0), - ) + ) # type: ignore def draw(self, context): layout = self.layout @@ -376,13 +406,14 @@ def execute(self, context): # get translation first translation: mathutils.Vector = mathutils.Vector(self.component_translation) # create elements - _general_create_component( + creator: _GeneralComponentCreator = _GeneralComponentCreator() + creator.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 ) - + creator.finish_component() return {'FINISHED'} @staticmethod @@ -450,20 +481,21 @@ def execute(self, context): # add elements # create checkpoint - _general_create_component( + creator: _GeneralComponentCreator = _GeneralComponentCreator() + creator.create_component( checkp_ty, checkp_sector, 1, # only create one lambda _: mathutils.Matrix.Identity(4) ) # create resetpoint - _general_create_component( + creator.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 ) - + creator.finish_component() return {'FINISHED'} @staticmethod diff --git a/bbp_ng/OP_ADDS_rail.py b/bbp_ng/OP_ADDS_rail.py index a535c47..f8c742e 100644 --- a/bbp_ng/OP_ADDS_rail.py +++ b/bbp_ng/OP_ADDS_rail.py @@ -492,6 +492,8 @@ def _rail_creator_wrapper(fct_poly_cret: typing.Callable[[bmesh.types.BMesh], No # move to cursor UTIL_functions.add_into_scene_and_move_to_cursor(obj) + # select created object + UTIL_functions.select_certain_objects((obj, )) # return rail return obj diff --git a/bbp_ng/UTIL_functions.py b/bbp_ng/UTIL_functions.py index 64f59c7..54a3d75 100644 --- a/bbp_ng/UTIL_functions.py +++ b/bbp_ng/UTIL_functions.py @@ -68,6 +68,18 @@ def add_into_scene_and_move_to_cursor(obj: bpy.types.Object): move_to_cursor(obj) +def select_certain_objects(objs: tuple[bpy.types.Object, ...]) -> None: + # deselect all objects first + bpy.ops.object.select_all(action = 'DESELECT') + # if no objects, return + if len(objs) == 0: return + + # set selection for each object + for obj in objs: + obj.select_set(True) + # select first object as active object + bpy.context.view_layer.objects.active = objs[0] + class EnumPropHelper(): """ These class contain all functions related to EnumProperty, including generating `items`,