How do I 'Apply' the Boolean Difference operation? I've written some Python that creates a hollow object visually, but in fact is not hollow. Visually I get the right thing:

Exporting to STL still has both objects (not an empty shell). I can manually complete the application of the Boolean operation by "Applying"

and deleting the inner object. Then the export to STL file is correct.
Here is the code I wrote, can someone let me know what calls I can make to apply the boolean modifier action and delete the object I used to cut into the other object with?
import sys
import bpy
D = bpy.data
C = bpy.context
from mathutils import *
import math
bpy.app.debug=True
########################################################################
Stitch together vertices to create a face in the arc
def face(column, row, columns, rows):
v3 = ((column + 1) * rows) + row
v3 = (((v3 // 4) * 4) + (v3 + 1) % 4)
v4 = (column * rows + 1) + row
v4a = (((v4 // 4) * 4) + (v4) % 4)
if v4a == v3:
v4 = v4a - 4
return (column* rows + row,
(column + 1) * rows + row,
v3,
v4)
########################################################################
Create an arc, start and eng angle, a scale to convert units, inner/outer size, height and the number of segments
def arc_segment(nme, start_ang, end_ang, scale, outer_size, inner_size, height, segs):
Assuming arguments are in centimeters and in degrees, adjust o meters and radians.
Change from degrees to radians
start_ang = (math.tau / 360.0) * start_ang
end_ang = (math.tau / 360.0) * end_ang
if start_ang > end_ang:
start_ang, end_ang = end_ang, start_ang
Change from meters (unit of measure in Blender) to centimeters
outer_size = scale * outer_size
inner_size = scale * inner_size
We're creating the arc, beginning with the newmericly smaller angle.
if outer_size < inner_size:
outer_size, inner_size = inner_size, outer_size
Arc will be created withe center at 0, 1/2 infront and 1/2 behing X/Y plane
height = scale * height
Use z for "height", center is 0, so 1/2 height away (plus), and 1/2 height close (minus)
p_height = (height * 0.5)
m_height = (height * -0.5)
Think of the arc as a tube. This loop connects the faces to create the tube.
verts = []
for seg in range(0, segs + 1):
verts.append((math.cos(start_ang + (end_ang - start_ang) * (seg / segs)) * inner_size,
math.sin(start_ang + (end_ang - start_ang) * (seg / segs)) * inner_size, p_height))
verts.append((math.cos(start_ang + (end_ang - start_ang) * (seg / segs)) * inner_size,
math.sin(start_ang + (end_ang - start_ang) * (seg / segs)) * inner_size, m_height))
verts.append((math.cos(start_ang + (end_ang - start_ang) * (seg / segs)) * outer_size,
math.sin(start_ang + (end_ang - start_ang) * (seg / segs)) * outer_size, m_height))
verts.append((math.cos(start_ang + (end_ang - start_ang) * (seg / segs)) * outer_size,
math.sin(start_ang + (end_ang - start_ang) * (seg / segs)) * outer_size, p_height))
sides = 4
args = (segs, sides)
faces = [face(x, y, segs, sides) for x in range(segs) for y in range(sides)]
Now cap the ends of the tube
faces.append((0, 1, 2, 3))
vbase = segs * sides
faces.append((vbase + 3, vbase + 2, vbase + 1, vbase))
Create object, link it into the scene, make it 'active'.
mesh_data = bpy.data.meshes.new(nme)
mesh_data.from_pydata(verts, [], faces)
mesh_data.update() # (calc_edges=True) not needed here
cube_object = bpy.data.objects.new(nme, mesh_data)
scene = bpy.context.scene
bpy.context.collection.objects.link(cube_object)
cube_object.select_set(state=True)
########################################################################
Solids modeling (CSG) take away coliding parts of one shape from another.
def csg(prim, cut, new_name, objects, operation):
o_prim = objects[prim]
o_cut = objects[cut]
cut_work = o_prim.modifiers.new(type="BOOLEAN", name=new_name)
cut_work.object = o_cut
cut_work.operation = 'DIFFERENCE'
o_cut.hide_set(True) # Hidden--But will still exist in an STL export.
-- -- -- -- -- -- -- -- -- -- -- -- --
What calls do I add here to "apply" the "difference" and delete the o_cut object?
-- -- -- -- -- -- -- -- -- -- -- -- --
########################################################################
objects = bpy.data.objects
set_scale = 2.54 * 2
Create some arcs
arc_segment("big_display_hull", 5.0, 90.0, set_scale, 11.5, 8.0, 4.5, 34)
arc_segment("big_hollow_hull", 6.5, 88.5, set_scale, 11.6, 7.7, 4.1, 34)
csg("big_display_hull", "big_hollow_hull", "o1", objects, 'DIFFERENCE')
arc_segment("attach_hulls", 360 + 110, 360 - 110.0, set_scale, 9.0, 8.0, 4.9, 120)
arc_segment("attach_hollow_hulls", 360 + 113, 360 - 113.0, set_scale, 9.2, 7.9, 4.1, 120)
csg("attach_hulls", "attach_hollow_hulls", "o3", objects, 'DIFFERENCE')
arc_segment("small_display_hull", 360 - 10, 360 - 65, set_scale, 11.5, 8.0, 4.5, 22)
arc_segment("small_hollow_hull", 360 - 11.5, 360 - 63.5, set_scale, 11.6, 7.7, 4.1, 22)
csg("small_display_hull", "small_hollow_hull", "o3", objects, 'DIFFERENCE')
I did try a suggested solution Scripting:How to correctly add a boolean modifer to an object? , after fixing a "'apply_as' unrecognized" issue, it ran. However I see that the boolean is still not applied. Given that blender 2.90.1 is so different than v 2.79, can someone post a complete python Boolean (CSG) example where the resulting meshes are the 'finished' objects? -- Also, I saw that 2.91 (beta) has something called 'exact solver', could someone post similar code to use the "exact solver"?


Also, I saw that 2.91 (beta) has something called 'exact solver', could someone post the code to use the "exact solver"?
– Toby Baden Nov 01 '20 at 02:10