4

I wrote a script that can detect similar objects based on the selected objects but can't put them in a collection named after selected objects.

It's not working.


import bpy

selected_objects = bpy.context.selected_objects

for selected_object in selected_objects: name = selected_object.name collections = bpy.data.collections.new(name) bpy.context.scene.collection.children.link(collections) bpy.ops.object.select_pattern(pattern=f"{name}") objs = bpy.context.selected_objects coll = bpy.data.collections[name]

for obj in objs:
    cols = obj.users_collection
    coll.objects.link(obj)
    for col in cols:
    col.objects.unlink(obj)

I want from:

enter image description here

To:

enter image description here

Karan
  • 1,984
  • 5
  • 21

3 Answers3

6

I would do the same in python that I could do in the UI, which is to use Select Pattern, and then move these selected items to a Collection.

In python:

bpy.ops.object.select_all( action='DESELECT' ) # Deselect all objects
bpy.ops.object.select_pattern(pattern="Sphere*")

if collection Sphere does not yet exist:

bpy.ops.object.move_to_collection( collection_index=0, is_new=True, new_collection_name='Sphere' ) # new collection

else if collection Sphere does exist:

bpy.ops.object.move_to_collection( collection_index=2 ) # need collection index

james_t
  • 5,446
  • 8
  • 29
  • Somewhat related, joining instead of adding to collection. https://blender.stackexchange.com/a/166446/15543 – batFINGER May 07 '21 at 19:49
  • 1
    i wish the select pattern would be there in the open file menu.... :( – Chris May 08 '21 at 06:42
  • @Chris, if you mean Append or Link or File Open.... someone recently pointed out to me, it exists in a rather crude way in Append or Link. To the right of the File View, Directory Path, is a search text box labeled in the helptext as search filter. I think it's inferior but usable. screencap for Append, filename, Objects at https://www.dropbox.com/s/pimmjg9yy7fda5p/blenderNameFilter.png – james_t May 08 '21 at 18:28
3

Here is another script where Collection names are used, with link and unlink:

bpy.ops.object.select_all( action='DESELECT' ) # Deselect all objects
bpy.ops.object.select_pattern(pattern="Sphere*")
objs = bpy.context.selected_objects

sphColl = bpy.data.collections['Spheres']

for obj in objs: print(obj) cols = obj.users_collection # ptr to current collection sphColl.objects.link(obj) # link into 'Spheres' collection print(cols) for col in cols: col.objects.unlink( obj ) # unline from original collection

james_t
  • 5,446
  • 8
  • 29
3

Object to collection by name.

Similarly to https://blender.stackexchange.com/a/166446/15543 can do this with API methods.

  • Sort all objects in scene by name (could change this to selected objects if desired)

  • Get the name up to the ".", eg for "Cube.022" this is "Cube", and all objects that start with this name

  • Move to collection of same name. Make a new collection and link to scene collection if need be. This will ensure can run this again and again and again without moving "Cube" to collection named "Cube.001" then "Cube.002" etc

  • Repeat until all objects moved.

  • Optionally remove any collections left with zero objects.

Test script.

import bpy

context = bpy.context scene = context.scene obs = scene.objects[:] obs.sort(key=lambda o: o.name)

def move(name, obs): # unlink from old collections for o in obs: for c in o.users_collection: c.objects.unlink(o) # make a new collection and link to it coll = bpy.data.collections.get(name) if not coll: coll = bpy.data.collections.new(name) scene.collection.children.link(coll) for o in obs: coll.objects.link(o)

while obs: name = obs[0].name.split(".")[0] x = [o for o in obs if o.name.startswith(name)] move(name, x) obs = obs[len(x):]

remove any now empty collections

empty_colls = [c for c in bpy.data.collections if not len(c.all_objects)]

while empty_colls: bpy.data.collections.remove(empty_colls.pop())

batFINGER
  • 84,216
  • 10
  • 108
  • 233