0
$\begingroup$

I wrote a simple script to make some spheres and combine them into a single mesh using boolean operators, but I don't understand how it works:

import bpy
import math

# Can't run this in edit mode
if bpy.context.active_object is not None:
    bpy.ops.object.mode_set(mode='OBJECT')

# Make sure nothing is selected
for object in bpy.context.selected_objects:
    object.select_set(False)

# Remove old object. Old meshes remain in memory, but won't be saved
if 'Sad Scorpion Attempt' in bpy.data.objects:
    bpy.data.objects['Sad Scorpion Attempt'].select_set(True)
    bpy.ops.object.delete()

# Actual mesh building goes here
bpy.ops.mesh.primitive_uv_sphere_add(radius=1, location=(0, 30, 0), scale=(1.5, 2, 
1))
base = bpy.context.active_object
base.name = 'Sad Scorpion Attempt' # Object name
base.data.name = 'Sad Scorpion Attempt' # Mesh name
for i in range(6):
    bpy.ops.mesh.primitive_uv_sphere_add(radius=1, location=(-4*math.sin(math.pi*i/6), 30, 4 + 4*math.cos(math.pi*i/6)), scale=(1.5, 1.4 + 0.1*i, 1))
    new_object = bpy.context.active_object
    
    # Sets bpy.context.active_object
    bpy.context.view_layer.objects.active = base
    
    booly = base.modifiers.new(name='booly', type='BOOLEAN')
    booly.object = new_object
    booly.operation = 'UNION'
    bpy.ops.object.modifier_apply(modifier='booly')
    
    # .delete() doesn't use the current value of bpy.context.active_object, so
    # it deletes new_object instead of base
    bpy.ops.object.delete()

In particular:

  • Why is bpy.context.active_object set by assigning to bpy.context.view_layer.objects.active, instead of just assigning to bpy.context.active_object normally?
  • Why does bpy.ops.object.delete() use the previous value of bpy.context.active_object, while bpy.ops.object.modifier_apply() uses the current one?

I've tried to find an explanation of how it works in the Blender docs, but the only documentation for bpy.context I found is https://docs.blender.org/api/current/bpy.context.html, which doesn't even list `bpy.context.active_object at all!

$\endgroup$
3
  • 2
    $\begingroup$ Hello. From a quick glance I think you need to understand two linked but independant concepts : Selected and active objects. An object can be selected without being active. You can have 0 or more selected objects, but you can only have zero or one active object. You can have a bunch of selected objects but no active object. Selecting an object with the API doesn't make it active. In fact if you click drag over objects in the viewport, they will get selected (orange outline) but no object will be set as active (yellow outline) $\endgroup$
    – Gorgious
    Apr 30, 2023 at 19:24
  • $\begingroup$ Thank you, that explains the behavior of bpy.ops.object.delete(). However, I'm still mystified by bpy.context.active_object (and its absence from the documentation). $\endgroup$
    – Densaugeo
    May 1, 2023 at 22:50
  • $\begingroup$ In the context of the 3D viewport, the active object is the current view layer's active object (view_layer.objects.active) $\endgroup$
    – Gorgious
    May 2, 2023 at 18:36

0

You must log in to answer this question.

Browse other questions tagged .