0
$\begingroup$

enter image description here

I regularly work with objects that I import into blender as a single mesh and then split into separate parts for the purpose of renaming them. These parts have different geometry from one another and are arranged in a grid. These parts need to be renamed so that they always have the same name according to their position in the grid, e.g. the object at (0,0,0) is always going to be 'Torus' irrespective of its geometry, the one at (1,0,2) is always going to be 'Susanne', etc. However, when you split an object based on separate parts, the order in which the parts are named seems to be completely random, making it impossible to use batch rename to change specific numbers into specific names.

Is there a way to split the original object while keeping the numbering consistent so that the renaming can be automated? I know that the numbering would be consistent if I separate the meshes manually, in order, but they are close to 100 parts and it wouldn't save any time compared to what I do currently.

Alternatively, is there a way to automate the renaming of an object based on the position of their origin in 3D space?

$\endgroup$
2
  • $\begingroup$ It can, but the purpose doesn't seem accurate enough, it would be easier to tell if you showed the two images "before" and "after". $\endgroup$
    – X Y
    Jul 12 at 9:25
  • $\begingroup$ The 'before' picture is just a single object names 'Parts' $\endgroup$
    – Cornivius
    Jul 12 at 10:56

1 Answer 1

2
$\begingroup$

First get the scene to test

import bpy

def get_scene(): # make sure in object mode and have a active object
    objects = bpy.data.objects
    for ob in objects: # clear objects
        objects.remove(ob)

    bpy.ops.mesh.primitive_cube_add()
    ob = bpy.context.object
    modifiers = ob.modifiers
    for r in range(3):
        md = modifiers.new(name=f"Array {r}", type="ARRAY")
        md.relative_offset_displace = 0,0,0
        md.relative_offset_displace[r] = 1.5
        md.count = 4
        bpy.ops.object.modifier_apply(modifier=md.name)

    collections = bpy.data.collections
    for collection in collections:
        collections.remove(collection)

get_scene()

Next, separate and rename based on position

import bpy

# put the object to a new collection
obj = bpy.context.object
my_collection = bpy.data.collections.new("My collection")
bpy.context.scene.collection.children.link(my_collection)
old_collections = obj.users_collection
my_collection.objects.link(obj)
for collection in old_collections:
    collection.objects.unlink(obj)

# separate by loose part and set origin
bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.mesh.separate(type="LOOSE")
bpy.ops.object.mode_set(mode='OBJECT')
bpy.ops.object.origin_set(type='ORIGIN_GEOMETRY', center='MEDIAN')
for ob in my_collection.objects:
    ob.show_name = True

# Rename them based on the position (YZX order)
objs = sorted([ob for ob in my_collection.objects], key=lambda x: (x.location.y, x.location.z, x.location.x))

name = "Cube"
objs[0].name = name
for r in range(1, len(objs)):
    objs[r].name = name + "{:03d}".format(r)

enter image description here

$\endgroup$
4
  • $\begingroup$ Doesn't seem to work when you use it with a different object. The names are still random for some reason $\endgroup$
    – Cornivius
    Jul 14 at 11:01
  • $\begingroup$ Is work when line 21 changed to objs = sorted([ob for ob in my_collection.objects], key=lambda x: (x.location.z, x.location.x))? if does't, you can show a simple example that doesn't work. $\endgroup$
    – X Y
    Jul 14 at 11:50
  • $\begingroup$ It doesn't seem to work. This is the object I'm using as an example: files.catbox.moe/fvbei0.stl I'm not knowledgeable on python so maybe I'm doing something wrong. I create a new file on the text editor, paste the first code and run it. Then import the object, create another text file, paste the second code and run it. It does split the object but the names are still not consistent $\endgroup$
    – Cornivius
    Jul 14 at 15:38
  • $\begingroup$ If you test with other object, just select the one you want in UI interface, and run the second script. $\endgroup$
    – X Y
    Jul 14 at 16:36

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .