Scene
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.
Registration
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_posthandler to clear cache on file loaddepsgraph_update_posthandler to track geometry changes
Mesh Access
get
Get 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:
TypeErrorif object is not a meshValueErrorif object is not tracked by the depsgraph
tbpy.convert.from_blender() instead.Boolean Operations
High-level boolean functions that take Blender objects and return new Blender objects:
boolean_difference
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)
boolean_union
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)
boolean_intersection
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:
- If
return_curves=False:bpy.types.Object(mesh) - If
return_curves=True:Tuple[bpy.types.Object, bpy.types.Object](mesh, curves)
Intersection Queries
intersects
Check if two mesh objects intersect:
if tbpy.scene.intersects(obj_a, obj_b):
print("Objects intersect!")
Returns: bool
intersection_curves
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.
Raw Boolean Operations
For efficient live updates, use these variants that return tf.Mesh directly without creating Blender objects:
boolean_difference_mesh
result_mesh = tbpy.scene.boolean_difference_mesh(obj_a, obj_b)
boolean_union_mesh
result_mesh = tbpy.scene.boolean_union_mesh(obj_a, obj_b)
boolean_intersection_mesh
result_mesh = tbpy.scene.boolean_intersection_mesh(obj_a, obj_b)
Parameters:
| Parameter | Type | Description |
|---|---|---|
obj_a | bpy.types.Object | First mesh object |
obj_b | bpy.types.Object | Second mesh object |
Returns: tf.Mesh (no Blender object created)
Use with tbpy.convert.update_blender() for efficient in-place geometry updates in live preview systems:
result_mesh = tbpy.scene.boolean_difference_mesh(obj_a, obj_b)
tbpy.convert.update_blender(result_mesh, existing_obj)
Caching Behavior
The scene module uses lazy evaluation:
- On geometry change: Mesh is marked dirty (not rebuilt)
- On
get()call: If dirty, mesh is rebuilt; otherwise cached version is returned - On object deletion: Cache entry is purged
This approach minimizes rebuilds during interactive editing where geometry changes frequently but may not be queried immediately.
Cache Scope
- Cache persists across scene switches (meshes from other scenes stay cached)
get()only allows access to meshes in the current scene/view layer- Cache is cleared on file load
Verbose Logging
Enable 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')
Example: Live Preview Operator
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.