Implementation:Google deepmind Dm control Blender Scene
| Knowledge Sources | |
|---|---|
| Domains | Robotics Simulation, 3D Modeling |
| Last Updated | 2026-02-15 04:00 GMT |
Overview
This module provides the abstraction layer for parsing and representing Blender scene objects in a unified way that the MuJoCo exporter can consume.
Description
The blender_scene module implements the foundational data model for the Blender-to-MuJoCo export pipeline. Its central class, ObjectRef, wraps either a Blender Object or a Bone (within an armature) into a hashable, comparable reference. ObjectRef provides properties to determine the object type (is_mesh, is_bone, is_light, is_armature, is_camera, is_empty), compute local affine transforms via get_local_transform(), and extract rotation degrees of freedom from IK chain constraints via get_rotation_dofs().
Two supporting dataclasses are provided: AffineTransform (holding position and rotation quaternion) and Dof (describing a degree of freedom with name, axis, limits, and limited flag). The module also includes utility functions: map_blender_tree performs a breadth-first traversal of the entire Blender scene hierarchy (both objects and armature bones), ensuring parents are processed before children. get_material_mesh_pair_name and is_material_mesh_pair_valid support multi-material mesh splitting, and map_materials applies a callback to a collection of materials.
This module decouples the exporter logic from raw Blender API calls by providing a clean abstraction over heterogeneous Blender objects, making it possible for downstream components like mujoco_scene.py and mujoco_assets.py to work with a uniform interface.
Usage
Use this module when building or extending the Blender-to-MuJoCo export pipeline. It is used to traverse Blender scenes, access object transforms, extract joint degrees of freedom from armature bones, and handle material/mesh relationships for geometry export.
Code Reference
Source Location
- Repository: Google_deepmind_Dm_control
- File: dm_control/blender/mujoco_exporter/blender_scene.py
- Lines: 1-428
Signature
@dataclasses.dataclass(frozen=True)
class AffineTransform:
pos: mathutils.Vector
rot: mathutils.Quaternion
@dataclasses.dataclass(frozen=True)
class Dof:
name: str
axis: mathutils.Vector
limited: bool = False
limits: Tuple[float, float] = (0, 0)
@dataclasses.dataclass(frozen=True)
class ObjectRef:
native_obj: bpy.types.Object | None
native_bone: bpy.types.Bone | None = None
# Properties
is_none -> bool
is_armature -> bool
is_bone -> bool
is_mesh -> bool
is_light -> bool
is_camera -> bool
is_empty -> bool
name -> str
is_visible -> bool
parent -> ObjectRef
mesh -> bpy.types.Mesh
materials -> Sequence[bpy.types.Material]
# Methods
def get_local_transform(self) -> AffineTransform: ...
def get_rotation_dofs(self) -> Sequence[Dof]: ...
def get_modified_mesh(self) -> bpy.types.Mesh | None: ...
# Class methods
@classmethod
def new_object(cls, obj: bpy.types.Object) -> ObjectRef: ...
@classmethod
def new_bone(cls, armature: bpy.types.Object, bone: bpy.types.Bone | None) -> ObjectRef: ...
NoneRef = ObjectRef(None, None)
def map_blender_tree(context: bpy.types.Context, callback: Callable[[ObjectRef], Any]) -> Sequence[Any]: ...
def get_material_mesh_pair_name(mesh_name: str, mat_name: str) -> str: ...
def is_material_mesh_pair_valid(mesh: bpy.types.Mesh, mat_idx: int) -> bool: ...
def map_materials(func: Callable, materials: Sequence[bpy.types.Material]) -> Sequence[Any]: ...
Import
from dm_control.blender.mujoco_exporter.blender_scene import ObjectRef, map_blender_tree
I/O Contract
Inputs
| Name | Type | Required | Description |
|---|---|---|---|
| native_obj | bpy.types.Object or None | Yes | A Blender scene object (mesh, armature, light, camera, empty) or None |
| native_bone | bpy.types.Bone or None | No | A Blender bone within an armature; None for non-bone references |
| context | bpy.types.Context | Yes (for map_blender_tree) | The Blender scene context containing all objects |
| callback | Callable[[ObjectRef], Any] | Yes (for map_blender_tree) | Function applied to each ObjectRef in breadth-first order |
Outputs
| Name | Type | Description |
|---|---|---|
| ObjectRef | ObjectRef | A hashable, comparable reference to a Blender object or bone |
| AffineTransform | AffineTransform | Position and rotation quaternion in local frame |
| dofs | Sequence[Dof] | Rotation degrees of freedom extracted from IK chain constraints |
| tree results | Sequence[Any] | Results of applying the callback to each node in the scene tree |
Usage Examples
Basic Usage
from dm_control.blender.mujoco_exporter.blender_scene import (
ObjectRef, map_blender_tree, NoneRef
)
# Create an ObjectRef from a Blender object
obj_ref = ObjectRef.new_object(bpy_object)
print(obj_ref.name)
print(obj_ref.is_mesh)
# Get the local transform
transform = obj_ref.get_local_transform()
print(transform.pos, transform.rot)
# For a bone reference
bone_ref = ObjectRef.new_bone(armature_obj, bone)
dofs = bone_ref.get_rotation_dofs()
for dof in dofs:
print(dof.name, dof.axis, dof.limited, dof.limits)
# Traverse the entire scene
def process_node(obj_ref):
return obj_ref.name, obj_ref.get_local_transform()
results = map_blender_tree(bpy.context, process_node)