7
$\begingroup$

I am wondering if following statements are true:

  • active_object is always identical to object.
  • active_object(or object if previous statement is true) is always the first one of selected_objects. (This seems to be a false statement since if I use bpy.ops.object.select_all(action='DESELECT') the active_object and object is not changed while selected_objects is empty.)
$\endgroup$
7
$\begingroup$

I am fairly sure the first is true, but the second isn't.

The list of selected_objects is expanded as new objects are added, new selections are added to the end of the list, while manually selecting the last addition will be the active object, so active_object is rarely the first in the selected_objects list.

There are some conditions that may catch you out.

  • When deselecting all objects, the last active object remains active even though it may no longer be selected.
  • When setting items as selected with python the active object does not automatically change.
  • Select all does not alter the active object.
  • Deleting the active object leaves you with no active object.
$\endgroup$
  • $\begingroup$ Thank you very much for extra information on these three attributes. But I failed to find the source evidence of "while manually selecting the last addition will be the active object". Can you give me some directions? $\endgroup$ – TheBusyTypist Mar 20 '15 at 7:41
  • $\begingroup$ In the 3dview select an object and in the python console enter bpy.context.selected_objects, select another object and repeat in console. You will see that the newly selected object will have the lighter outline of the active object and be the last in the selected list. shift select an already select object and it will be active but the list doesn't change. I expect the source is in source/blender/editors/space_view3d/view3d_select.c $\endgroup$ – sambler Mar 21 '15 at 4:36
2
$\begingroup$

After I post this question I think I can have a look at the implementation(f51a3aedc9540e0bcda4f16deec22e9aa722ef24) for answer.

Firstly, active_object and object refer to the same object when you try to access either one of them.

The attribute retrieving happens in the function ed_screen_context(file screen_context.c). This function performs string matching on the attribute names. For active_object and object you can see both of their implementations return obact(It is scene->basact actually) as result.

Secondly, when you set an active object through scene.active = ..., active_object and object are assigned by that object.

The call chain of this process is SceneObjects_active_set(file rna_scene_gen.c) -> rna_Scene_active_object_set(file rna_scene.c). In the function rna_Scene_active_object_set you can see the active object is assigned to scene->basact.

Finally, selected_objects seems to be a totally different thing from active_object and object.

The selecting of an object happens in function Object_select_set(file rna_object_gen.c). But I failed to find the relation between active_object and selected_objects as @sambler said.


EDIT: The relation between selected_objects and active_object/object is confirmed.

as @sambler said

while manually selecting the last addition will be the active object, so active_object is rarely the first in the selected_objects list

A selecting triggered by manual action happen in a space operator, rather than in a Python script binding. So I search this operator in view3d space. I found the operator VIEW3D_OT_select in file view3d_select.c. And there is a call chain of view3d_select_exec -> mouse_select -> ED_base_object_activate. I see the object activation happens in ED_base_object_activate:

if ((oldbasact != basact) && (is_obedit == false)) { ED_base_object_activate(C, basact); /* adds notifier */ }

Therefore the last selection will be the new active object.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.