0
$\begingroup$

Using bpy, how do I remove an object from a collection without also removing it from other places?

I have an object that is both part of a collection and at the same time a child of another object. I try to unlink it from the collection:

collection.objects.unlink(obj)

But it also disappears from the other object.

Even in the GUI I can't seem to remove it from only one place in the outliner. How do I do this right?

EDIT: The reason why I got here: I have this structure:

 - Collection1
 -   Collection2
 -     Object1
 -       ObjectToBeMoved
 -   Object3

I want to move Object2 from Object1 to Object3. So I do:

ObjectToBeMoved.parent = Object3

I end up with this:

 - Collection1
 -   Collection2
 -     ObjectToBeMoved
 -     Object1
 -   Object3
 -     ObjectToBeMoved

It gets the new parent (Object3) but it also moves up in the hierarchy to become sibling with its former parent, under Collection2. That's why I want to delete it from Collection2. But when I do that it also disappears from Object3.

Is there another, better, way to move an object?

$\endgroup$
2
  • $\begingroup$ have you explicitly linked ObjectToBeMoved to Collection1 somewhere? I can't see that step in your description. Keep in mind that parenting does not move the object to the other collection, it only sets the parent. $\endgroup$
    – aliasguru
    Commented Sep 2 at 7:50
  • $\begingroup$ No, they are not explicitly linked. But I suppose that when I change the parent for ObjectToBeMoved, it is no longer a child of Object1, so it somehow "floats up" to the nearest collection. So if I also make it belong to Collection1 it would disappear from Collection2(?). Can be worth to try at least. $\endgroup$
    – lurvas
    Commented Sep 2 at 10:46

1 Answer 1

1
$\begingroup$

When you unlink an object that is only linked to 1 collection it will become "orphaned", it will still exist in your data but will not be referenced by anything.
You need to link it against at least 1 collection to make it accessible in your Scene.

bpy.data.collections['Defaults'].objects.unlink(bpy.data.objects['Cube.001'])
will remove the object from the collection and make it an orphan which you can see in the "Unused Data" tab.
unused data tab

bpy.data.collections['New_Coll'].objects.link(bpy.data.objects['Cube.001'])
will once again link it to another collection.

I wrote a small operator to help me move objects between collections for this exact reason. It's part of a much bigger addon but you can link it to a button in the "n" menu easily.

from bpy.types import Operator


class CAD_VIEW_OT_move_to_coll(Operator):
    bl_idname = "cad_view.move_to_coll"
    bl_label = "Move Objects to Collection"
    bl_description = "Moves the selected objects to the active objects collection"
    bl_space_type = "VIEW_3D"
    bl_region_type = "UI"

    @classmethod
    def poll(cls, context):
        return context.area.type == "VIEW_3D" and len(context.selected_objects) > 0

    def invoke(self, context, event):
        active_object = context.active_object
        coll_target = active_object.users_collection[0]
        selected_objects = [obj for obj in context.selected_objects]

        for obj in selected_objects:
            if obj is not active_object:
                for coll in obj.users_collection:
                    coll.objects.unlink(obj)
                coll_target.objects.link(obj)

        return {"FINISHED"}
$\endgroup$
0

You must log in to answer this question.

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