The tbpy.scene module provides cached mesh access and high-level operations for Blender add-ons. It maintains tf.Mesh instances per mesh datablock with lazy updates via depsgraph tracking.
Register scene handlers in your add-on's register() function:
from trueform import bpy as tbpy
def register():
tbpy.register() # Register depsgraph handlers
def unregister():
tbpy.unregister() # Clean up handlers and cache
This sets up:
load_post handler to clear cache on file loaddepsgraph_update_post handler to track geometry changesGet a cached tf.Mesh for a Blender object with world transform applied:
mesh = tbpy.scene.get(obj)
Parameters:
| Parameter | Type | Description |
|---|---|---|
obj | bpy.types.Object | Mesh object in the active scene |
Returns: tf.Mesh shared view with obj.matrix_world applied.
Raises:
TypeError if object is not a meshValueError if object is not tracked by the depsgraphtbpy.convert.from_blender() instead.High-level boolean functions that take Blender objects and return new Blender objects:
Compute boolean difference (A - B):
result = tbpy.scene.boolean_difference(obj_a, obj_b, name="Difference")
# With intersection curves
result, curves = tbpy.scene.boolean_difference(obj_a, obj_b, return_curves=True)
Compute boolean union (A ∪ B):
result = tbpy.scene.boolean_union(obj_a, obj_b, name="Union")
# With intersection curves
result, curves = tbpy.scene.boolean_union(obj_a, obj_b, return_curves=True)
Compute boolean intersection (A ∩ B):
result = tbpy.scene.boolean_intersection(obj_a, obj_b, name="Intersection")
# With intersection curves
result, curves = tbpy.scene.boolean_intersection(obj_a, obj_b, return_curves=True)
Parameters (all boolean functions):
| Parameter | Type | Default | Description |
|---|---|---|---|
obj_a | bpy.types.Object | First mesh object | |
obj_b | bpy.types.Object | Second mesh object | |
name | str | "Boolean" | Name for result object(s) |
return_curves | bool | False | Also return intersection curves |
Returns:
return_curves=False: bpy.types.Object (mesh)return_curves=True: Tuple[bpy.types.Object, bpy.types.Object] (mesh, curves)Check if two mesh objects intersect:
if tbpy.scene.intersects(obj_a, obj_b):
print("Objects intersect!")
Returns: bool
Compute intersection curves between two meshes:
curves_obj = tbpy.scene.intersection_curves(obj_a, obj_b, name="Curves")
Returns: bpy.types.Object with curve data.
The scene module uses lazy evaluation:
get() call: If dirty, mesh is rebuilt; otherwise cached version is returnedThis approach minimizes rebuilds during interactive editing where geometry changes frequently but may not be queried immediately.
get() only allows access to meshes in the current scene/view layerEnable logging to debug cache behavior:
tbpy.scene.set_verbose(True)
# [TrueformScene] building: Cube (mesh='Cube')
# [TrueformScene] hit: Cube (mesh='Cube')
# [TrueformScene] marking dirty (datablock changed): 'Cube'
# [TrueformScene] rebuilding (dirty): Cube (mesh='Cube')
import bpy as blender_bpy
from trueform import bpy as tbpy
class MESH_OT_boolean_preview(blender_bpy.types.Operator):
bl_idname = "mesh.boolean_preview"
bl_label = "Boolean Preview"
def execute(self, context):
obj_a = context.scene.my_addon.target_a
obj_b = context.scene.my_addon.target_b
if not obj_a or not obj_b:
self.report({'WARNING'}, "Select two objects")
return {'CANCELLED'}
# Uses cached meshes - fast for repeated calls
result = tbpy.scene.boolean_difference(obj_a, obj_b)
self.report({'INFO'}, f"Created {result.name}")
return {'FINISHED'}
tf.* functions. For an example add-on, see Boolean Plugin.