Extending the Simulator¶
While the BlenderService API, as typically accessed through a BlenderClient instance, provides a streamlined way to interact with Blender and facilitates most common operations, sometimes more fine-grained control is needed. For this, you can subclass BlenderService to access Blender’s internal bpy API.
Here we create a custom ExtendedService which allows for axis-aligned bounding box (AABB) calculations, and listing out any missing textures:
from pathlib import Path
import bpy
import numpy as np
from mathutils import Vector
from visionsim.simulate.blender import BlenderServer, BlenderService
class ExtendedService(BlenderService):
def exposed_scene_aabb(self):
aabb_min = np.array([np.inf, np.inf, np.inf])
aabb_max = -np.array([np.inf, np.inf, np.inf])
for obj in self.scene.objects:
bbox = np.array(obj.bound_box)
bbox_min = obj.matrix_world @ Vector(np.min(bbox, axis=0))
bbox_max = obj.matrix_world @ Vector(np.max(bbox, axis=0))
aabb_min = np.minimum(aabb_min, bbox_min)
aabb_max = np.maximum(aabb_max, bbox_max)
return aabb_min, aabb_max
def exposed_missing_textures(self):
paths = []
for image in bpy.data.images.values():
if image.source == "FILE":
if not (path := Path(image.filepath_from_user()).resolve()).exists():
paths.append(path)
return paths
if __name__ == "__main__":
server = BlenderServer(service=ExtendedService, port=0)
server.start()
Currently, in order to use this new rendering service, the user must spin it up manually (as opposed to using BlenderClient.spawn):
$ blender --background --python-use-system-env --python examples/blender/extended_service.py
And then connect to that render service, either directly using the appropriate connection settings, or using the BlenderClient.auto_connect:
with BlenderClient.auto_connect(timeout=30) as client:
client.initialize("cube.blend", "renders/")
print(client.scene_aabb())