I have a script that is runing fine but I think there is a way to make it more efficient and is by using a list of items, the problem I have is that I'm not sure if I can use the list to perform some operations depending on the items order or names from the list. In this case I would like to know if I could use the same operator for each item independently or I just have to make a operator for each item (which I think is not efficient at all to write it), since each operator points to a different string.
As you can see in the code, between the lines 122 and 236 there are 3 operators almost exactly the same but changing the string pointer and the class name, imagine now if I have like 20 items do I have to make 20 operators? So I think that having a list I could just add a new item without the need of creating another operator. Hope all this makes sense. Bear with me, I'm a noob on this coding thingy :)
import bpy
#my_list_that_want_to_use = [
# {
# 'name': 'WINDOWS'
# },
# {
# 'name': 'DOORS'
# },
# {
# 'name': 'WALLS'
# },
#]
class MyProperties(bpy.types.PropertyGroup):
my_string_windows : bpy.props.StringProperty(name = "Windows", default ="WINDOWS")
my_string_doors : bpy.props.StringProperty(name = "Doors", default ="DOORS")
my_string_walls : bpy.props.StringProperty(name = "Walls", default ="WALLS")
class SelectByNameOperator_windows(bpy.types.Operator):
"""Select objects by name"""
bl_idname = "object.selected_by_name_operator_windows"
bl_label = "Select by Name"
bl_options = {'REGISTER', 'UNDO'}
def execute(self, context):
bpy.ops.object.select_all(action='DESELECT')
bpy.data.objects['Light'].select_set(True)
bpy.context.view_layer.objects.active = bpy.context.selected_objects[0]
return {'FINISHED'}
class SelectByNameOperator_doors(bpy.types.Operator):
"""Select objects by name"""
bl_idname = "object.selected_by_name_operator_doors"
bl_label = "Select by Name"
bl_options = {'REGISTER', 'UNDO'}
def execute(self, context):
bpy.ops.object.select_all(action='DESELECT')
bpy.data.objects['Camera'].select_set(True)
bpy.context.view_layer.objects.active = bpy.context.selected_objects[0]
return {'FINISHED'}
class SelectByNameOperator_walls(bpy.types.Operator):
"""Select objects by name"""
bl_idname = "object.selected_by_name_operator_walls"
bl_label = "Select by Name"
bl_options = {'REGISTER', 'UNDO'}
def execute(self, context):
bpy.ops.object.select_all(action='DESELECT')
bpy.data.objects['Cube'].select_set(True)
bpy.context.view_layer.objects.active = bpy.context.selected_objects[0]
return {'FINISHED'}
class ADDONNAME_OT_my_op_windows(bpy.types.Operator):
bl_label = "Sort"
bl_idname = "addonname.myop_operator_windows"
bl_options = {'REGISTER', 'UNDO'}
def execute(self, context):
scene = context.scene
mytool = scene.my_tool
collectionFound = False
for myCol in bpy.data.collections:
#print(myCol.name)
if myCol.name == mytool.my_string_windows:
collectionFound = True
#print ("Collection found in scene")
break
# Creates a new collection
if collectionFound == False:
myCol = bpy.data.collections.new(mytool.my_string_windows)
bpy.context.scene.collection.children.link(myCol)
# Set the new collection as active
def recurLayerCollection(layerColl, collName):
found = None
if (layerColl.name == collName):
return layerColl
for layer in layerColl.children:
found = recurLayerCollection(layer, collName)
if found:
return found
layer_collection = bpy.context.view_layer.layer_collection
layerColl = recurLayerCollection(layer_collection, mytool.my_string_windows)
bpy.context.view_layer.active_layer_collection = layerColl
# MOVE SELECTED OBJECTS TO ANOTHER COLLECTION ONLY
objs = bpy.context.selected_objects # List of object references
coll_target = bpy.context.scene.collection.children.get(mytool.my_string_windows) # Set target collection to a known collection
coll_target = bpy.context.collection # Set target collection based on the collection in context (selected)
if coll_target and objs: # If target found and object list not empty
for ob in objs: # Loop through all objects
for coll in ob.users_collection: # Loop through all collections the obj is linked to
coll.objects.unlink(ob) # Unlink the object
coll_target.objects.link(ob) # Link each object to the target collection
bpy.ops.object.select_all(action="DESELECT")
return {'FINISHED'}
class ADDONNAME_OT_my_op_doors(bpy.types.Operator):
bl_label = "Sort"
bl_idname = "addonname.myop_operator_doors"
bl_options = {'REGISTER', 'UNDO'}
def execute(self, context):
scene = context.scene
mytool = scene.my_tool
collectionFound = False
for myCol in bpy.data.collections:
#print(myCol.name)
if myCol.name == mytool.my_string_doors:
collectionFound = True
#print ("Collection found in scene")
break
# Creates a new collection
if collectionFound == False:
myCol = bpy.data.collections.new(mytool.my_string_doors)
bpy.context.scene.collection.children.link(myCol)
# Set the new collection as active
def recurLayerCollection(layerColl, collName):
found = None
if (layerColl.name == collName):
return layerColl
for layer in layerColl.children:
found = recurLayerCollection(layer, collName)
if found:
return found
layer_collection = bpy.context.view_layer.layer_collection
layerColl = recurLayerCollection(layer_collection, mytool.my_string_doors)
bpy.context.view_layer.active_layer_collection = layerColl
# MOVE SELECTED OBJECTS TO ANOTHER COLLECTION ONLY
objs = bpy.context.selected_objects # List of object references
coll_target = bpy.context.scene.collection.children.get(mytool.my_string_doors) # Set target collection to a known collection
coll_target = bpy.context.collection # Set target collection based on the collection in context (selected)
if coll_target and objs: # If target found and object list not empty
for ob in objs: # Loop through all objects
for coll in ob.users_collection: # Loop through all collections the obj is linked to
coll.objects.unlink(ob) # Unlink the object
coll_target.objects.link(ob) # Link each object to the target collection
bpy.ops.object.select_all(action="DESELECT")
return {'FINISHED'}
class ADDONNAME_OT_my_op_walls(bpy.types.Operator):
bl_label = "Sort"
bl_idname = "addonname.myop_operator_walls"
bl_options = {'REGISTER', 'UNDO'}
def execute(self, context):
scene = context.scene
mytool = scene.my_tool
collectionFound = False
for myCol in bpy.data.collections:
#print(myCol.name)
if myCol.name == mytool.my_string_walls:
collectionFound = True
#print ("Collection found in scene")
break
# Creates a new collection
if collectionFound == False:
myCol = bpy.data.collections.new(mytool.my_string_walls)
bpy.context.scene.collection.children.link(myCol)
# Set the new collection as active
def recurLayerCollection(layerColl, collName):
found = None
if (layerColl.name == collName):
return layerColl
for layer in layerColl.children:
found = recurLayerCollection(layer, collName)
if found:
return found
layer_collection = bpy.context.view_layer.layer_collection
layerColl = recurLayerCollection(layer_collection, mytool.my_string_walls)
bpy.context.view_layer.active_layer_collection = layerColl
# MOVE SELECTED OBJECTS TO ANOTHER COLLECTION ONLY
objs = bpy.context.selected_objects # List of object references
coll_target = bpy.context.scene.collection.children.get(mytool.my_string_walls) # Set target collection to a known collection
coll_target = bpy.context.collection # Set target collection based on the collection in context (selected)
if coll_target and objs: # If target found and object list not empty
for ob in objs: # Loop through all objects
for coll in ob.users_collection: # Loop through all collections the obj is linked to
coll.objects.unlink(ob) # Unlink the object
coll_target.objects.link(ob) # Link each object to the target collection
bpy.ops.object.select_all(action="DESELECT")
return {'FINISHED'}
#################### UI #######################
class ADDONNAME_PT_main_panel(bpy.types.Panel):
bl_label = "Main Panel"
bl_idname = "ADDONNAME_PT_main_panel"
bl_space_type = 'VIEW_3D'
bl_region_type = 'UI'
bl_category = "New Tab"
def draw(self, context):
layout = self.layout
scene = context.scene
mytool = scene.my_tool
split = layout.split(factor=0.75)
col_1 = split.column()
col_2 = split.column()
col_3 = split.column()
col_1.prop(mytool, "my_string_windows")
col_2.operator('object.selected_by_name_operator_windows', text='Select')
col_3.operator("addonname.myop_operator")
split = layout.split(factor=0.75)
col_1 = split.column()
col_2 = split.column()
col_3 = split.column()
col_1.prop(mytool, "my_string_doors")
col_2.operator('object.selected_by_name_operator_doors', text='Select')
col_3.operator("addonname.myop_operator_doors")
split = layout.split(factor=0.75)
col_1 = split.column()
col_2 = split.column()
col_3 = split.column()
col_1.prop(mytool, "my_string_walls")
col_2.operator('object.selected_by_name_operator_walls', text='Select')
col_3.operator("addonname.myop_operator_walls")
classes = [MyProperties,
ADDONNAME_PT_main_panel,
ADDONNAME_OT_my_op_windows,
ADDONNAME_OT_my_op_doors,
ADDONNAME_OT_my_op_walls,
SelectByNameOperator_windows,
SelectByNameOperator_doors,
SelectByNameOperator_walls,
]
def register():
for cls in classes:
bpy.utils.register_class(cls)
bpy.types.Scene.my_tool = bpy.props.PointerProperty(type= MyProperties)
def unregister():
for cls in classes:
bpy.utils.unregister_class(cls)
del bpy.types.Scene.my_tool
if __name__ == "__main__":
register()