Merging objects by their name without suffix?

Hi!

I’m trying to merge several objects of the same name (without suffix, that is).

But at this point, I’m already going cross eyed and could use some help. Basically, I’m trying merge objects into 3 separate objects. Each ending either with HIGH, MED or LOW.

The structure of collections doesn’t play any role here, it’s just for a better looking demonstration.

If anyone could take a look at my sh*tty code and help me out, I’d appreciate it! :slight_smile:

import bpy

def remove_number_suffix(string: str):
    """Remove the .00# at that Blender puts at the end of object names."""
    return string.split(".")[0]

def remove_number_suffix2(string: str):
    """Remove the .00# at that Blender puts at the end of object names."""
    return string.split("£")[0]

def remove_duplicate_entries(list):
  """Removes duplicate entries from the specified list."""
  # Create a set to store the unique elements.
  unique_elements = set()
  newList = []
  # Iterate over the elements in the list and add them to the set if they are unique.
  for element in list:
    if element not in unique_elements:
      unique_elements.add(element)
      newList.append(element)
    else:
      list.remove(element)

  return newList

def set_object_active(object):
  """Sets the specified object as active."""
  # Get the current view layer.
  view_layer = bpy.context.view_layer

  # Set the active object to the specified object.
  view_layer.objects.active = object


list = []

for obj in bpy.data.objects:
    obj.select_set(False)    
    thename = remove_number_suffix(obj.name)
    list.append(thename)


list = remove_duplicate_entries(list)

print(f"List to be {list}")    
for listing in list:
    print("1",listing)        
    #obj.select_set(False)       
    for obj in bpy.data.objects:
        print("2",obj.name)     
        if obj.name in listing:
            print("3","hit")          
            obj.select_set(True) 
            object = bpy.data.objects[obj.name]
            set_object_active(object)
        bpy.ops.object.join()

test_merging_texts.blend (2.2 MB)

Hopefully one of the smarter posters in the forum will offer a cleaner solution but based on a quick read of your described goal and the image posted it looks as though the following code should be functional for you:

import bpy

unique_names = set([obj.name.split(".")[0] for obj in bpy.context.view_layer.objects if obj.type == 'MESH'])

for obj_name in unique_names:
    bpy.ops.object.select_all(action='DESELECT')
    for obj in bpy.context.view_layer.objects:
        if obj.name.startswith(obj_name):
            obj.select_set(True)
        if obj.name == obj_name:
            bpy.context.view_layer.objects.active = obj
    if len(bpy.context.selected_objects) > 1:
        bpy.ops.object.join()
1 Like

Thank you, I tested this in a few scenarios and it seems to work! :slight_smile: