2
$\begingroup$

I am trying to cut a hole through a mesh-cube with a mesh-cylinder by adding a boolean modifier with a 'DIFFERENCE' value. what I have is =>

objkts = bpy.data.objects
cube = objkts['cube']
cylinder = objkts['cylinder']
bool = cube.modifiers.new(type='BOOLEAN',name='booly')
bool.object = cylinder
bool.operation = 'DIFFERENCE'
bpy.ops.object.modifier_apply(apply_as='DATA',modifier='booly')
sc = bpy.context.scene
sc.objects.unlink(cylinder)

but it does nothing when I run the script, I mean the objects are still visible until I manually click apply @ the cube's modifier pane from the blender GUI

$\endgroup$

1 Answer 1

5
$\begingroup$

2.8 example

enter image description here code run with camera (or any object) as the context object and neither the cube nor the cylinder selected. Notice I've made the cylinder a little taller, doing with default cube and cylinder of same height same location can be dodgy with booleans

Since I have my nose in 2.8 here is an advanced-ish example for that version. If you have just started then scripting 2.8 is a good idea going forward

  • Recommend using a collections get method to find objects. If there is no object named "Cube" in scene, scene.objects.get("Cube") will be None.

  • Quite likely your cube and cylinder have names with a capital C. There is a bpy.data.objects.get("Cube") not bpy.data.objects.get("cube") Look for errors in the system console when writing scripts. [Find Link]

  • Operators are designed to work on context. In this case the context.object. If cube is last selected and is active, then there is no need to get the cube object, it is implied. This is known as the operator context paradigm. Doing it this way would result in changing code below such that

    cube = context.object
    # add modifiers etc
    
    bool = cube.modifiers.new(...
    ...
    bpy.ops.object.modifier_apply(modifier=bool.name)
    

make an object active: run the script, no need to edit for a different objects.

  • To get around this (at times) can override context, 2.8 is proving far easier than prior to do this. Simply pass a dictionary with the required context properties, in this case "object" to the operator as first argument. See poll() failed, context incorrect? - Example: bpy.ops.view3d.background_image_add()

  • Even though the modifier is given the name "booly" .. if another is added with the same name somehow, it will be given the name "booly.001". If the reference is used then bool.name will always be the name of the newly added modifier.

The code:

import bpy

context = bpy.context
scene = context.scene
cube = scene.objects.get("Cube")
cyl = scene.objects.get("Cylinder")
if cube and cyl:
    bool = cube.modifiers.new(name='booly', type='BOOLEAN')
    bool.object = cyl
    bool.operation = 'DIFFERENCE'
    bpy.ops.object.modifier_apply(
            {"object": cube},
            apply_as='DATA',
            modifier=bool.name)

Some similar examples using 2.79

Boolean difference not making any diiference (Python scripting)

$\endgroup$
1
  • $\begingroup$ With Blender 3.x you don't need "apply_as='DATA'," anymore. $\endgroup$
    – dirkk0
    Mar 14, 2023 at 14:46

You must log in to answer this question.

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