Blender | PY

Scene

Cached mesh operations for Blender add-ons.

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_post handler to clear cache on file load
  • depsgraph_update_post handler 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:

ParameterTypeDescription
objbpy.types.ObjectMesh object in the active scene

Returns: tf.Mesh shared view with obj.matrix_world applied.

Raises:

  • TypeError if object is not a mesh
  • ValueError if object is not tracked by the depsgraph
Only works for objects linked to the active scene/view layer. For objects not in the scene, use 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):

ParameterTypeDefaultDescription
obj_abpy.types.ObjectFirst mesh object
obj_bbpy.types.ObjectSecond mesh object
namestr"Boolean"Name for result object(s)
return_curvesboolFalseAlso 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.

Caching Behavior

The scene module uses lazy evaluation:

  1. On geometry change: Mesh is marked dirty (not rebuilt)
  2. On get() call: If dirty, mesh is rebuilt; otherwise cached version is returned
  3. 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'}
For standalone scripts without caching, use Convert directly with tf.* functions. For an example add-on, see Boolean Plugin.