1
$\begingroup$

so i am trying to cut holes (a lot if them) into a tabletop and i am trying to use a script which cuts each hole one by one, because blender cant handle doing the boolean for this many objects at once.

So i have implemented a loop which calls the following function:

def boolean_difference(obj, subtract_obj):
bool_mod = obj.modifiers.new(name="Boolean", type='BOOLEAN')
bool_mod.operation = 'DIFFERENCE'
bool_mod.use_self = True
bool_mod.object = subtract_obj    
bpy.ops.object.modifier_apply(modifier="Boolean")

obj is the table and subtract_obj is a cylinder which i want to cut out of it. In the main loop i then do this:

if main_obj and subtract_obj:
for axis in move_axes:
    for i in range(num_iterations[axis]):
        boolean_difference(main_obj, subtract_obj)

        copied_obj = subtract_obj.copy()
        bpy.context.collection.objects.link(copied_obj)

        if axis == 'X':
            copied_obj.location.x += move_amounts[axis]
        elif axis == 'Y':
            copied_obj.location.y += move_amounts[axis]
        elif axis == 'Z':
            copied_obj.location.z += move_amounts[axis]
        
        # Delete the original subtracted object
        bpy.data.objects.remove(subtract_obj)

        # Update the subtracted object for the next iteration
        subtract_obj = copied_obj

I debugged it and i noticed that i get an error for incorrerct context on only the second iteration. This is the error:

RuntimeError: Operator bpy.ops.object.modifier_apply.poll() failed, context is incorrect

So i am thinking that i do not properly copy the object or have to set something regarding the context of the object, but i unfortunately dont know what and so far i was not successfull in my search for an answer.

If you have any questions i will provide more info. thank you in advance!

$\endgroup$

2 Answers 2

3
$\begingroup$

bpy.ops.object.modifier_apply() work on an active object,

use context.view_layer.objects.active = obj before modifier_apply()

def boolean_difference(obj, subtract_obj):
    bool_mod = obj.modifiers.new(name="Boolean", type='BOOLEAN')
    bool_mod.operation = 'DIFFERENCE'
    bool_mod.use_self = True
    bool_mod.object = subtract_obj    
    bpy.context.view_layer.objects.active = obj
    bpy.ops.object.modifier_apply(modifier="Boolean")
$\endgroup$
3
$\begingroup$

You can use a context override so you don't have to mess with selection state :

def boolean_difference(obj, subtract_obj):
    bool_mod = obj.modifiers.new(name="Boolean", type='BOOLEAN')
    bool_mod.operation = 'DIFFERENCE'
    bool_mod.use_self = True
    bool_mod.object = subtract_obj    
    with bpy.context.temp_override(object=obj):
        bpy.ops.object.modifier_apply(modifier="Boolean")
$\endgroup$

You must log in to answer this question.

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