Blender Integration

Blender-specific modules for UI and scene integration.

Note: These modules require Blender to run and are not available in standalone Python environments.

Operators

User actions and commands.

Blender Operators for exporting robot models.

This module implements the user-facing operators that handle the export of robot models from Blender to supported description formats.

linkforge.blender.operators.export_ops.working_directory(path)[source]

Context manager for temporarily changing the working directory.

Parameters:

path (Path)

Return type:

Iterator[Path]

class linkforge.blender.operators.export_ops.LINKFORGE_OT_export_robot_model(*args, **kwargs)[source]

Bases: Operator, ExportHelper

Export robot to robot model file

Parameters:
bl_idname = 'linkforge.export_robot_model'
bl_label = 'Export Robot Model'
bl_description = 'Export robot to supported description formats'
filepath: bpy.props.StringProperty
filter_glob: bpy.props.StringProperty
check(context)[source]

Verify if export can proceed based on current scene state.

Parameters:

context (Context)

Return type:

Any

invoke(context, event)[source]

Invoked before the file browser opens.

Parameters:
  • context (Context)

  • event (Event)

Return type:

Any

execute(context)[source]

Execute the export.

Parameters:

context (Context)

Return type:

set[Literal['RUNNING_MODAL', 'CANCELLED', 'FINISHED', 'PASS_THROUGH', 'INTERFACE']]

class linkforge.blender.operators.export_ops.LINKFORGE_OT_validate_robot(*args, **kwargs)[source]

Bases: Operator

Validate robot structure

Parameters:
bl_idname = 'linkforge.validate_robot'
bl_label = 'Validate Robot'
bl_description = 'Validate the robot structure for errors'
execute(context)[source]

Execute validation.

Parameters:

context (Context)

Return type:

set[Literal['RUNNING_MODAL', 'CANCELLED', 'FINISHED', 'PASS_THROUGH', 'INTERFACE']]

linkforge.blender.operators.export_ops.register()[source]

Register operators.

Return type:

None

linkforge.blender.operators.export_ops.unregister()[source]

Unregister operators.

Return type:

None

Operators for managing robot joints.

class linkforge.blender.operators.joint_ops.LINKFORGE_OT_create_joint(*args, **kwargs)[source]

Bases: Operator

Create a new robot joint at selected link’s location.

This operator initializes a joint (Blender Empty with colored axes) at the world location of the currently selected link object, setting up default joint properties and hierarchy hints.

Parameters:
bl_idname = 'linkforge.create_joint'
bl_label = 'Create Joint'
bl_description = "Create a new robot joint at the selected link's location and orientation"
bl_options = {'REGISTER', 'UNDO'}
classmethod poll(context)[source]

Check if operator can run.

Parameters:

context (Context)

Return type:

bool

execute(context)[source]

Execute the operator.

Parameters:

context (Context)

Return type:

set[Literal['RUNNING_MODAL', 'CANCELLED', 'FINISHED', 'PASS_THROUGH', 'INTERFACE']]

class linkforge.blender.operators.joint_ops.LINKFORGE_OT_delete_joint(*args, **kwargs)[source]

Bases: Operator

Delete the selected joint Empty.

This operator removes the selected joint object from the scene and cleans up any associated references in the ROS 2 control system to maintain architectural consistency.

Parameters:
bl_idname = 'linkforge.delete_joint'
bl_label = 'Remove Joint'
bl_description = 'Remove the selected joint from the robot structure'
bl_options = {'REGISTER', 'UNDO'}
classmethod poll(context)[source]

Check if operator can run.

Parameters:

context (Context)

Return type:

bool

execute(context)[source]

Execute the operator.

Parameters:

context (Context)

Return type:

set[Literal['RUNNING_MODAL', 'CANCELLED', 'FINISHED', 'PASS_THROUGH', 'INTERFACE']]

class linkforge.blender.operators.joint_ops.LINKFORGE_OT_auto_detect_parent_child(*args, **kwargs)[source]

Bases: Operator

Auto-detect parent and child links based on hierarchy.

This operator uses proximity heuristics and world transform analysis to automatically assign parent and child link references to the currently selected joint.

Parameters:
bl_idname = 'linkforge.auto_detect_parent_child'
bl_label = 'Auto-Detect Links'
bl_description = 'Automatically detect parent and child links from object hierarchy'
bl_options = {'REGISTER', 'UNDO'}
classmethod poll(context)[source]

Check if operator can run.

Parameters:

context (Context)

Return type:

bool

execute(context)[source]

Execute the operator.

Parameters:

context (Context)

Return type:

set[Literal['RUNNING_MODAL', 'CANCELLED', 'FINISHED', 'PASS_THROUGH', 'INTERFACE']]

linkforge.blender.operators.joint_ops.register()[source]

Register operators.

Return type:

None

linkforge.blender.operators.joint_ops.unregister()[source]

Unregister operators.

Return type:

None

Add a joint to the ros2_control system.

This operator allows users to select a joint from the robot’s kinematic tree and include it in the ROS 2 control configuration, setting up default command and state interfaces.

class linkforge.blender.operators.control_ops.LINKFORGE_OT_add_ros2_control_joint(*args, **kwargs)[source]

Bases: Operator

Parameters:
bl_idname = 'linkforge.add_ros2_control_joint'
bl_label = 'Add Joint'
bl_description = "Add a joint from the robot's kinematic tree to the control system"
bl_options = {'REGISTER', 'UNDO'}
joint_name: bpy.props.StringProperty
classmethod poll(context)[source]

Check if operators can run.

Parameters:

context (Context) – The current Blender context.

Return type:

bool

Returns:

True if the scene has LinkForge properties initialized.

execute(context)[source]

Execute the operator.

Parameters:

context (Context) – The execution context.

Return type:

set[Literal['RUNNING_MODAL', 'CANCELLED', 'FINISHED', 'PASS_THROUGH', 'INTERFACE']]

Returns:

Set containing the execution state (e.g., {β€˜FINISHED’}).

class linkforge.blender.operators.control_ops.LINKFORGE_OT_remove_ros2_control_joint(*args, **kwargs)[source]

Bases: Operator

Remove a joint from the ros2_control system.

This operator removes the currently selected joint from the ROS 2 control configuration list.

Parameters:
bl_idname = 'linkforge.remove_ros2_control_joint'
bl_label = 'Remove Joint'
bl_description = 'Remove the selected joint from the control system'
bl_options = {'REGISTER', 'UNDO'}
classmethod poll(context)[source]

Check if operators can run.

Parameters:

context (Context) – The current Blender context.

Return type:

bool

Returns:

True if there are joints in the control system.

execute(context)[source]

Execute the operator.

Parameters:

context (Context) – The execution context.

Return type:

set[Literal['RUNNING_MODAL', 'CANCELLED', 'FINISHED', 'PASS_THROUGH', 'INTERFACE']]

Returns:

Set containing the execution state.

class linkforge.blender.operators.control_ops.LINKFORGE_OT_move_ros2_control_joint(*args, **kwargs)[source]

Bases: Operator

Move a joint up or down in the control interface list.

This is a UI helper operator to reorder how joints appear in the LinkForge control panel.

Parameters:
bl_idname = 'linkforge.move_ros2_control_joint'
bl_label = 'Move Joint'
bl_description = 'Move joint up or down in the list (cosmetic only)'
bl_options = {'REGISTER', 'UNDO'}
direction: bpy.props.StringProperty
classmethod poll(context)[source]

Check if operators can run.

Parameters:

context (Context) – The current Blender context.

Return type:

bool

Returns:

True if there are multiple joints to move.

execute(context)[source]

Execute the operator.

Parameters:

context (Context) – The execution context.

Return type:

set[Literal['RUNNING_MODAL', 'CANCELLED', 'FINISHED', 'PASS_THROUGH', 'INTERFACE']]

Returns:

Set containing the execution state.

class linkforge.blender.operators.control_ops.LINKFORGE_OT_add_ros2_control_parameter(*args, **kwargs)[source]

Bases: Operator

Add a parameter to ros2_control (global or joint).

This operator adds a new key-value pair to either the global hardware parameters or the parameters of the currently selected joint.

Parameters:
bl_idname = 'linkforge.add_ros2_control_parameter'
bl_label = 'Add Parameter'
bl_description = 'Add a key-value parameter to the control system'
bl_options = {'REGISTER', 'UNDO'}
target: bpy.props.StringProperty
classmethod poll(context)[source]

Check if the operator can be executed.

Parameters:

context (Context) – The current Blender context.

Return type:

bool

Returns:

True if LinkForge properties are initialized in the scene.

execute(context)[source]

Execute the addition of a parameter.

Parameters:

context (Context) – The execution context.

Return type:

set[Literal['RUNNING_MODAL', 'CANCELLED', 'FINISHED', 'PASS_THROUGH', 'INTERFACE']]

Returns:

Set containing the execution state.

class linkforge.blender.operators.control_ops.LINKFORGE_OT_remove_ros2_control_parameter(*args, **kwargs)[source]

Bases: Operator

Remove a parameter from ros2_control.

This operator deletes a key-value pair from either the global hardware parameters or a specific joint’s parameter list.

Parameters:
bl_idname = 'linkforge.remove_ros2_control_parameter'
bl_label = 'Remove Parameter'
bl_description = 'Remove a hardware or joint parameter'
bl_options = {'REGISTER', 'UNDO'}
target: bpy.props.StringProperty
index: bpy.props.IntProperty
classmethod poll(context)[source]

Check if the operator can be executed.

Parameters:

context (Context) – The current Blender context.

Return type:

bool

Returns:

True if LinkForge properties are initialized.

execute(context)[source]

Execute the removal of a parameter.

Parameters:

context (Context) – The execution context.

Return type:

set[Literal['RUNNING_MODAL', 'CANCELLED', 'FINISHED', 'PASS_THROUGH', 'INTERFACE']]

Returns:

Set containing the execution state.

class linkforge.blender.operators.control_ops.LINKFORGE_OT_purge_ros2_control_data(*args, **kwargs)[source]

Bases: Operator

Clear all joints and parameters from the ros2_control configuration.

Parameters:
bl_idname = 'linkforge.purge_ros2_control_data'
bl_label = 'Purge Control Data'
bl_description = 'Clear all joints and parameters from the control system'
bl_options = {'REGISTER', 'UNDO'}
classmethod poll(context)[source]

Check if operators can run.

Parameters:

context (Context)

Return type:

bool

execute(context)[source]

Execute the purge.

Parameters:

context (Context)

Return type:

set[Literal['RUNNING_MODAL', 'CANCELLED', 'FINISHED', 'PASS_THROUGH', 'INTERFACE']]

linkforge.blender.operators.control_ops.register()[source]

Register operators.

Return type:

None

linkforge.blender.operators.control_ops.unregister()[source]

Unregister operators.

Return type:

None

Panels

UI Panels for managing robot data.

Properties

Blender scene properties for storing robot data.

Blender Property Groups for robot-level configuration.

This module defines the property groups used to store robot-level metadata and export settings directly within the Blender Scene. These properties drive the UI panels and provide the configuration parameters for the URDF and XACRO generators, including:

  • Robot Metadata: Name and global settings.

  • Export Configuration: Target formats (URDF/XACRO) and validation toggles.

  • Advanced XACRO Settings: Toggles for property extraction, macro generation, and modular file splitting.

linkforge.blender.properties.robot_props.update_collision_visibility(self, context)[source]

Update visibility of all collision meshes in the scene.

Parameters:
Return type:

None

class linkforge.blender.properties.robot_props.RobotPropertyGroup(*args, **kwargs)[source]

Bases: PropertyGroup

Global robot properties stored on the Scene.

Parameters:
robot_name: bpy.props.StringProperty
export_format: bpy.props.EnumProperty
use_ros2_control: bpy.props.BoolProperty
ros2_control_name: bpy.props.StringProperty
ros2_control_type: bpy.props.EnumProperty
hardware_plugin: bpy.props.StringProperty
gazebo_plugin_name: bpy.props.StringProperty
controllers_yaml_path: bpy.props.StringProperty
ros2_control_joints: bpy.props.CollectionProperty
ros2_control_active_joint_index: bpy.props.IntProperty
ros2_control_parameters: bpy.props.CollectionProperty
show_ros2_control_parameters: bpy.props.BoolProperty
export_meshes: bpy.props.BoolProperty
mesh_format: bpy.props.EnumProperty
mesh_directory_name: bpy.props.StringProperty
validate_before_export: bpy.props.BoolProperty
strict_mode: bpy.props.BoolProperty
xacro_advanced_mode: bpy.props.BoolProperty
xacro_extract_materials: bpy.props.BoolProperty
xacro_extract_dimensions: bpy.props.BoolProperty
xacro_generate_macros: bpy.props.BoolProperty
xacro_split_files: bpy.props.BoolProperty
show_kinematic_tree: bpy.props.BoolProperty
show_collisions: bpy.props.BoolProperty
is_importing: bpy.props.BoolProperty
abort_import: bpy.props.BoolProperty
import_status: bpy.props.StringProperty
linkforge.blender.properties.robot_props.register()[source]

Register property group.

Return type:

None

linkforge.blender.properties.robot_props.unregister()[source]

Unregister property group.

Return type:

None

These properties are stored on Blender objects and define link characteristics.

Bases: PropertyGroup

Properties for a robot link stored on a Blender object.

Parameters:

Register property group.

Return type:

None

Unregister property group.

Return type:

None

Sanitize a name for robot model and Python identifier compatibility.

Replaces invalid characters with underscores and ensures it doesn’t start with a digit.

Parameters:
  • name (str | None) – Original name

  • allow_hyphen (bool) – Whether to allow hyphens (valid in many formats like URDF/SDF, invalid in Python)

Return type:

str

Returns:

Sanitized name

Blender Property Groups for robot joints.

These properties are stored on Empty objects and define joint characteristics.

linkforge.blender.properties.joint_props.get_joint_name(self)[source]

Getter for joint_name - returns the persistent source identity.

Parameters:

self (JointPropertyGroup) – The JointPropertyGroup instance.

Return type:

str

Returns:

The sanitized robot model name.

linkforge.blender.properties.joint_props.set_joint_name(self, value)[source]

Setter for joint_name - updates persistent identity and object name.

Parameters:
  • self (JointPropertyGroup) – The JointPropertyGroup instance.

  • value (str) – The new name value to set.

Return type:

None

linkforge.blender.properties.joint_props.update_joint_hierarchy(self, context)[source]

Update Blender object hierarchy when parent/child links change.

Establishes hierarchy: parent_link β†’ joint β†’ child_link This matches import behavior and shows kinematic tree in outliner.

Parameters:
Return type:

None

Filter to only allow robot link objects in pointer selection.

Parameters:
Return type:

bool

linkforge.blender.properties.joint_props.poll_robot_joint(self, obj)[source]

Filter to only allow other robot joint objects in pointer selection.

Parameters:
Return type:

bool

class linkforge.blender.properties.joint_props.JointPropertyGroup(*args, **kwargs)[source]

Bases: PropertyGroup

Properties for a robot joint stored on an Empty object.

Parameters:
is_robot_joint: bpy.props.BoolProperty
source_name_stored: bpy.props.StringProperty
joint_name: bpy.props.StringProperty
joint_type: bpy.props.EnumProperty
axis: bpy.props.EnumProperty
custom_axis_x: bpy.props.FloatProperty
custom_axis_y: bpy.props.FloatProperty
custom_axis_z: bpy.props.FloatProperty
use_limits: bpy.props.BoolProperty
limit_lower: bpy.props.FloatProperty
limit_upper: bpy.props.FloatProperty
limit_effort: bpy.props.FloatProperty
limit_velocity: bpy.props.FloatProperty
use_dynamics: bpy.props.BoolProperty
dynamics_damping: bpy.props.FloatProperty
dynamics_friction: bpy.props.FloatProperty
use_mimic: bpy.props.BoolProperty
mimic_joint: bpy.props.PointerProperty
mimic_multiplier: bpy.props.FloatProperty
mimic_offset: bpy.props.FloatProperty
use_safety_controller: bpy.props.BoolProperty
safety_soft_lower_limit: bpy.props.FloatProperty
safety_soft_upper_limit: bpy.props.FloatProperty
safety_k_position: bpy.props.FloatProperty
safety_k_velocity: bpy.props.FloatProperty
use_calibration: bpy.props.BoolProperty
calibration_rising: bpy.props.FloatProperty
use_calibration_rising: bpy.props.BoolProperty
calibration_falling: bpy.props.FloatProperty
use_calibration_falling: bpy.props.BoolProperty
linkforge.blender.properties.joint_props.register()[source]

Register property group.

Return type:

None

linkforge.blender.properties.joint_props.unregister()[source]

Unregister property group.

Return type:

None

Blender Property Groups for robot sensors.

These properties are stored on Empty objects and define sensor characteristics.

linkforge.blender.properties.sensor_props.get_sensor_name(self)[source]

Getter for sensor_name - returns the persistent robot model identity.

Parameters:

self (SensorPropertyGroup) – The SensorPropertyGroup instance.

Return type:

str

Returns:

The sanitized robot model name.

linkforge.blender.properties.sensor_props.set_sensor_name(self, value)[source]

Setter for sensor_name - updates persistent identity and object name.

Parameters:
  • self (SensorPropertyGroup) – The SensorPropertyGroup instance.

  • value (str) – The new name value to set.

Return type:

None

linkforge.blender.properties.sensor_props.update_sensor_hierarchy(self, context)[source]

Update Blender object hierarchy when attached link changes.

Automatically reparents sensor to new link and moves to link’s collection. This ensures visual hierarchy matches logical structure.

Parameters:
Return type:

None

Filter to only allow robot link objects in pointer selection.

Parameters:
Return type:

bool

class linkforge.blender.properties.sensor_props.SensorPropertyGroup(*args, **kwargs)[source]

Bases: PropertyGroup

Properties for a robot sensor stored on an Empty object.

Parameters:
is_robot_sensor: bpy.props.BoolProperty
source_name_stored: bpy.props.StringProperty
sensor_name: bpy.props.StringProperty
sensor_type: bpy.props.EnumProperty
update_rate: bpy.props.FloatProperty
always_on: bpy.props.BoolProperty
visualize: bpy.props.BoolProperty
topic_name: bpy.props.StringProperty
camera_horizontal_fov: bpy.props.FloatProperty
camera_width: bpy.props.IntProperty
camera_height: bpy.props.IntProperty
camera_near_clip: bpy.props.FloatProperty
camera_far_clip: bpy.props.FloatProperty
camera_format: bpy.props.EnumProperty
lidar_horizontal_samples: bpy.props.IntProperty
lidar_horizontal_min_angle: bpy.props.FloatProperty
lidar_horizontal_max_angle: bpy.props.FloatProperty
lidar_vertical_samples: bpy.props.IntProperty
lidar_vertical_min_angle: bpy.props.FloatProperty
lidar_vertical_max_angle: bpy.props.FloatProperty
lidar_range_min: bpy.props.FloatProperty
lidar_range_max: bpy.props.FloatProperty
lidar_range_resolution: bpy.props.FloatProperty
contact_collision: bpy.props.StringProperty
use_noise: bpy.props.BoolProperty
noise_type: bpy.props.EnumProperty
noise_mean: bpy.props.FloatProperty
noise_stddev: bpy.props.FloatProperty
use_gazebo_plugin: bpy.props.BoolProperty
plugin_filename: bpy.props.StringProperty
plugin_raw_xml: bpy.props.StringProperty
linkforge.blender.properties.sensor_props.register()[source]

Register property group.

Return type:

None

linkforge.blender.properties.sensor_props.unregister()[source]

Unregister property group.

Return type:

None

Blender Property Groups for centralized ros2_control configuration.

These properties are stored on the Scene and define the mapping between robot joints and ros2_control interfaces (command and state).

class linkforge.blender.properties.control_props.Ros2ControlParameterProperty(*args, **kwargs)[source]

Bases: PropertyGroup

Key-value pair for ros2_control parameters.

Parameters:
name: bpy.props.StringProperty
value: bpy.props.StringProperty
class linkforge.blender.properties.control_props.Ros2ControlInterfaceProperty(*args, **kwargs)[source]

Bases: PropertyGroup

Property group for a single ros2_control interface.

Parameters:
name: bpy.props.EnumProperty
parameters: bpy.props.CollectionProperty
class linkforge.blender.properties.control_props.Ros2ControlJointProperty(*args, **kwargs)[source]

Bases: PropertyGroup

Property group for a joint’s ros2_control mapping.

Parameters:
name: bpy.props.StringProperty
joint_obj: bpy.props.PointerProperty
cmd_position: bpy.props.BoolProperty
cmd_velocity: bpy.props.BoolProperty
cmd_effort: bpy.props.BoolProperty
state_position: bpy.props.BoolProperty
state_velocity: bpy.props.BoolProperty
state_effort: bpy.props.BoolProperty
show_parameters: bpy.props.BoolProperty
parameters: bpy.props.CollectionProperty
linkforge.blender.properties.control_props.register()[source]

Register property groups.

Return type:

None

linkforge.blender.properties.control_props.unregister()[source]

Unregister property groups.

Return type:

None

Blender Property Groups for robot transmissions.

These properties are stored on Empty objects and define transmission characteristics for ros2_control integration.

linkforge.blender.properties.transmission_props.get_transmission_name(self)[source]

Getter for transmission_name - returns the persistent robot model identity.

Parameters:

self (TransmissionPropertyGroup) – The TransmissionPropertyGroup instance.

Return type:

str

Returns:

The sanitized robot model name.

linkforge.blender.properties.transmission_props.set_transmission_name(self, value)[source]

Setter for transmission_name - updates persistent identity and object name.

Parameters:
Return type:

None

linkforge.blender.properties.transmission_props.update_transmission_hierarchy(self, context)[source]

Update Blender object hierarchy when joint changes.

Automatically reparents transmission to new joint and moves to joint’s collection. This ensures visual hierarchy matches logical structure.

Parameters:
Return type:

None

linkforge.blender.properties.transmission_props.poll_robot_joint(_self, obj)[source]

Filter to only allow robot joint objects in pointer selection.

Parameters:
Return type:

bool

Returns:

True if the object is a valid robot joint.

class linkforge.blender.properties.transmission_props.TransmissionPropertyGroup(*args, **kwargs)[source]

Bases: PropertyGroup

Properties for a robot transmission stored on an Empty object.

Parameters:
is_robot_transmission: bpy.props.BoolProperty
source_name_stored: bpy.props.StringProperty
transmission_name: bpy.props.StringProperty
transmission_type: bpy.props.EnumProperty
custom_type: bpy.props.StringProperty
joint_name: bpy.props.PointerProperty
joint1_name: bpy.props.PointerProperty
joint2_name: bpy.props.PointerProperty
hardware_interface: bpy.props.EnumProperty
mechanical_reduction: bpy.props.FloatProperty
offset: bpy.props.FloatProperty
use_custom_actuator_name: bpy.props.BoolProperty
actuator_name: bpy.props.StringProperty
actuator1_name: bpy.props.StringProperty
actuator2_name: bpy.props.StringProperty
linkforge.blender.properties.transmission_props.register()[source]

Register property group.

Return type:

None

linkforge.blender.properties.transmission_props.unregister()[source]

Unregister property group.

Return type:

None

Blender Property Groups for validation results.

These properties store the last validation result for display in the UI.

class linkforge.blender.properties.validation_props.ValidationIssueProperty(*args, **kwargs)[source]

Bases: PropertyGroup

A single validation issue (error or warning).

Parameters:
title: bpy.props.StringProperty
message: bpy.props.StringProperty
suggestion: bpy.props.StringProperty
affected_objects: bpy.props.StringProperty
error_code: bpy.props.StringProperty
property has_suggestion: bool

Check if this issue has a suggestion.

property has_objects: bool

Check if this issue has affected objects.

property objects_str: str

Get affected objects as a formatted string.

property message_lines: list[str]

Split message into lines for display (max 60 chars per line).

property suggestion_lines: list[str]

Split suggestion into lines for display (max 58 chars per line).

class linkforge.blender.properties.validation_props.ValidationResultProperty(*args, **kwargs)[source]

Bases: PropertyGroup

Validation result stored in window manager.

Parameters:
has_results: bpy.props.BoolProperty
is_valid: bpy.props.BoolProperty
error_count: bpy.props.IntProperty
warning_count: bpy.props.IntProperty
joint_count: bpy.props.IntProperty
dof_count: bpy.props.IntProperty
errors: bpy.props.CollectionProperty
warnings: bpy.props.CollectionProperty
show_errors: bpy.props.BoolProperty
show_warnings: bpy.props.BoolProperty
clear()[source]

Clear all validation results.

Return type:

None

get_error(index)[source]

Get error by index.

Parameters:

index (int)

Return type:

ValidationIssueProperty

get_warning(index)[source]

Get warning by index.

Parameters:

index (int)

Return type:

ValidationIssueProperty

linkforge.blender.properties.validation_props.register()[source]

Register property groups.

Return type:

None

linkforge.blender.properties.validation_props.unregister()[source]

Unregister property groups.

Return type:

None

Adapters

Conversion between Blender and core models.

Converters between Blender properties and Core models.

These functions bridge the gap between Blender’s property system and LinkForge’s core data models.

linkforge.blender.adapters.blender_to_core.detect_primitive_type(obj)[source]

Detect if a Blender mesh object matches a standard primitive shape.

Analyzes topology and dimensions to determine if the object can be exported as a URDF primitive (BOX, CYLINDER, or SPHERE). This function is critical for optimizing exports and ensuring compatibility with physics simulators.

Parameters:

obj (bpy.types.Object | None) – The Blender mesh object to analyze.

Return type:

str | None

Returns:

β€œbox”, β€œcylinder”, or β€œsphere” if a match is detected, else None.

linkforge.blender.adapters.blender_to_core.get_object_geometry(obj, geometry_type='auto', link_name=None, geom_purpose='visual', meshes_dir=None, mesh_format='STL', simplify=False, decimation_ratio=0.5, dry_run=False, suffix='', depsgraph=None)[source]

Extract geometry from Blender object.

Parameters:
  • obj (bpy.types.Object | None) – Blender Object

  • geometry_type (str) – Type of geometry to extract - β€œauto”: Auto-detect (primitives for simple shapes, mesh for complex) - β€œmesh”: Force mesh export - β€œbox”, β€œcylinder”, β€œsphere”: Force specific primitive

  • link_name (str | None) – Name of the link (for mesh filename)

  • geom_purpose (str) – β€œvisual” or β€œcollision” (use PURPOSE_VISUAL, PURPOSE_COLLISION)

  • meshes_dir (Path | None) – Directory to export mesh files to

  • mesh_format (str) – β€œSTL”, β€œOBJ”, or β€œGLB” (use FORMAT_STL, etc.)

  • simplify (bool) – Whether to simplify mesh (for collision)

  • decimation_ratio (float) – Simplification ratio if simplify=True

  • dry_run (bool) – If True, generate mesh paths but don’t write files

  • suffix (str) – Optional unique suffix (e.g., index or name)

  • depsgraph (Any | None)

Return type:

tuple[Geometry | None, Matrix]

Returns:

tuple of (Core Geometry or None, geometry_world_matrix)

linkforge.blender.adapters.blender_to_core.extract_mesh_triangles(obj, depsgraph=None, as_numpy=False)[source]

Extract triangle mesh data from Blender object.

Parameters:
  • obj (bpy.types.Object | None) – Blender mesh object

  • depsgraph (Any | None) – Optional evaluated dependency graph

  • as_numpy (bool) – If True, return NumPy arrays instead of Python lists

Returns:

  • vertices: List of (x, y, z) coordinates or (N, 3) NumPy array

  • triangles: List of (v0, v1, v2) vertex indices or (M, 3) NumPy array

Return type:

tuple[Any, Any] | None

linkforge.blender.adapters.blender_to_core.get_object_material(obj, props)[source]

Extract material from Blender object.

Parameters:
  • obj (Any) – Blender Object

  • props (Any) – LinkPropertyGroup with material settings

Return type:

Material | None

Returns:

Core Material or None

class linkforge.blender.adapters.blender_to_core.SceneToRobotTranslator(context, meshes_dir=None, dry_run=False, depsgraph=None)[source]

Bases: object

Orchestrates the conversion of a Blender scene to a Core Robot model.

This class follows the SOLID principles by encapsulating the translation logic and leveraging the RobotBuilder (Composer) API for structural integrity.

Parameters:
__init__(context, meshes_dir=None, dry_run=False, depsgraph=None)[source]
Parameters:
translate()[source]

Perform the translation and return the built Robot model.

Return type:

tuple[Robot, ValidationResult]

linkforge.blender.adapters.blender_to_core.scene_to_robot(context, meshes_dir=None, dry_run=False)[source]

Convert entire Blender scene to Core Robot using the Translator orchestrator.

Parameters:
  • context (IBlenderContext | bpy.types.Context)

  • meshes_dir (Path | None)

  • dry_run (bool)

Return type:

tuple[Robot, ValidationResult]

Scene Builder utilities for creating Blender objects from generic Robot models.

linkforge.blender.adapters.core_to_blender.create_material_from_color(context, color, name)[source]

Create Blender material from Color model.

Parameters:
  • context (IBlenderContext) – Blender context adapter

  • color (Color) – Color model

  • name (str) – Material name

Return type:

bpy.types.Material | None

Returns:

Blender Material or None

linkforge.blender.adapters.core_to_blender.create_primitive_mesh(context, geometry, name)[source]

Create a Blender mesh object from primitive geometry.

This function generates native Blender mesh primitives (Cube, Cylinder, Sphere) based on the Core geometry model and applies the correct dimensions and format-specific metadata tags.

Parameters:
  • context (IBlenderContext) – Blender context adapter

  • geometry (Box | Cylinder | Sphere) – One of Box, Cylinder, or Sphere models.

  • name (str) – Name to assign to the created Blender object.

Return type:

bpy.types.Object | None

Returns:

The created Blender Object or None if creation failed.

linkforge.blender.adapters.core_to_blender.import_mesh_file(context, mesh_path, name)[source]

Import an external mesh file into the Blender scene.

Supported formats include STL, OBJ, and GLB. This function utilizes modern Blender WM operators for improved performance and stability.

Parameters:
  • context (IBlenderContext) – Blender context adapter

  • mesh_path (Path) – Absolute path to the mesh file.

  • name (str) – Name to assign to the imported object.

Return type:

bpy.types.Object | None

Returns:

The imported Blender Object or None if import failed.

linkforge.blender.adapters.core_to_blender.normalize_and_consolidate_imported_objects(context, objects, name)[source]

Consolidation logic that processes all supplied objects (meshes β†’ join, others β†’ delete).

Parameters:
  • context (IBlenderContext)

  • objects (typing.Iterable[bpy.types.Object])

  • name (str)

Return type:

bpy.types.Object | None

Create Blender object from Link model with support for multiple visual/collision elements.

Parameters:
  • context (IBlenderContext) – Blender context adapter

  • link (Link) – Link model

  • robot (Robot) – Robot model (for resolving resources)

  • source_directory (Path) – Directory containing source file (for resolving relative paths)

  • collection (bpy.types.Collection | None) – Blender Collection to add object to

Return type:

bpy.types.Object | None

Returns:

Blender Object or None (returns the link Empty object with properties)

linkforge.blender.adapters.core_to_blender.create_joint_object(context, joint, link_objects, collection=None)[source]

Create Empty object from Joint model.

Parameters:
  • context (IBlenderContext) – Blender context adapter

  • joint (Joint) – Joint model

  • link_objects (dict[str, bpy.types.Object]) – Dictionary mapping link names to Blender objects

  • collection (bpy.types.Collection | None) – Blender Collection to add object to

Return type:

bpy.types.Object | None

Returns:

Blender Empty object or None

linkforge.blender.adapters.core_to_blender.create_sensor_object(context, sensor, link_objects, collection=None)[source]

Create Empty object from Sensor model.

Parameters:
  • context (IBlenderContext) – Blender context adapter

  • sensor (typing.Any) – Sensor model from core

  • link_objects (dict[str, bpy.types.Object]) – Dictionary mapping link names to Blender objects

  • collection (bpy.types.Collection | None) – Blender Collection to add object to

Return type:

bpy.types.Object | None

Returns:

Blender Empty object or None

linkforge.blender.adapters.core_to_blender.setup_scene_for_robot(context, robot)[source]

Initialize scene properties for a robot model.

This populates the Centralized Control Dashboard, Gazebo settings, and metadata based on the robot model.

Parameters:
  • context (IBlenderContext) – Blender context adapter

  • robot (Robot) – Robot model to extract settings from

Return type:

None

linkforge.blender.adapters.core_to_blender.import_robot_to_scene(robot, source_path, context)[source]

Import Robot model to Blender scene.

Parameters:
  • robot (Robot) – Robot model

  • source_path (Path) – Path to source file

  • context (IBlenderContext | bpy.types.Context) – Blender context (real or adapter)

Return type:

bool

Mesh export utilities for LinkForge.

Export Blender mesh objects to STL, OBJ, and GLB files for URDF.

linkforge.blender.adapters.mesh_io.export_mesh_stl(obj, filepath)[source]

Export a Blender object to an STL file.

This function utilizes the modern Blender WM STL exporter, ensuring correct axis orientations (Y-forward, Z-up) for ROS 2 compatibility.

Parameters:
  • obj (Any) – The Blender mesh object to export.

  • filepath (Path) – Target filesystem path for the STL file.

Return type:

bool

Returns:

True if the export completed successfully, False otherwise.

linkforge.blender.adapters.mesh_io.export_mesh_obj(obj, filepath)[source]

Export a Blender object to an OBJ file with associated MTL materials.

This function ensures that materials are correctly exported alongside the geometry, maintaining visual fidelity in the target URDF.

Parameters:
  • obj (Any) – The Blender mesh object to export.

  • filepath (Path) – Target filesystem path for the OBJ file.

Return type:

bool

Returns:

True if the export completed successfully, False otherwise.

linkforge.blender.adapters.mesh_io.create_simplified_mesh(obj, decimation_ratio)[source]

Create a simplified mesh copy using Blender’s Decimate modifier.

This function is primarily used to generate lightweight collision geometry from high-fidelity visual meshes, reducing physics computation overhead.

Parameters:
  • obj (Any) – The source Blender mesh object.

  • decimation_ratio (float) – The target triangle count ratio (0.0 to 1.0).

Return type:

Any | None

Returns:

A new Blender object with the simplified mesh, or None if failed.

linkforge.blender.adapters.mesh_io.get_mesh_filename(link_name, geometry_type, mesh_format, suffix='')[source]

Generate mesh filename based on link and geometry type.

Parameters:
  • link_name (str) – Name of the robot link

  • geometry_type (str) – β€œvisual” or β€œcollision” (use PURPOSE_VISUAL, PURPOSE_COLLISION)

  • mesh_format (str) – β€œSTL”, β€œOBJ”, or β€œGLB” (use FORMAT_STL, etc.)

  • suffix (str) – Optional unique suffix (e.g., index or name)

Return type:

str

Returns:

Filename string (e.g., β€œbase_link_visual_0.stl”).

linkforge.blender.adapters.mesh_io.export_mesh_glb(obj, filepath)[source]

Export Blender object to GLB (glTF Binary) file.

Parameters:
  • obj (Any) – Blender Object to export

  • filepath (Path) – Path where GLB file should be saved

Return type:

bool

Returns:

True if export succeeded, False otherwise

Export mesh for a robot link.

CRITICAL: Exports mesh geometry centered at origin (0,0,0) with no transforms. The visual origin in URDF will handle all positioning. This prevents double-offset issues when the mesh is re-imported.

Parameters:
  • obj (Any) – Blender Object to export

  • link_name (str) – Name of the robot link

  • geometry_type (str) – β€œvisual” or β€œcollision” (PURPOSE_VISUAL, PURPOSE_COLLISION)

  • mesh_format (str) – β€œSTL”, β€œOBJ”, or β€œGLB” (FORMAT_STL, etc.)

  • meshes_dir (Path) – Directory where mesh files should be saved

  • simplify (bool) – Whether to simplify mesh (for collision)

  • decimation_ratio (float) – Simplification ratio if simplify=True

  • dry_run (bool) – If True, return expected path without exporting

  • suffix (str)

  • depsgraph (Any | None)

Return type:

tuple[Path | None, Matrix]

Returns:

tuple of (Path to exported mesh file or None, geometric_offset)

Utilities

Blender-specific helpers.

Helper utilities for Blender property groups.

This module provides optimized helper functions for property update callbacks.

linkforge.blender.utils.property_helpers.find_property_owner(context, property_group, property_attr)[source]

Find the Blender object that owns a given property group instance.

This is an optimized helper for property update callbacks that need to find their owning object. It tries multiple strategies from fastest to slowest: 1. Check id_data (most reliable and fastest) 2. Check context.object (active object) first 3. Check context.selected_objects 4. Fall back to full scene search as last resort

Parameters:
  • context (Context) – Blender context

  • property_group (Any) – The property group instance (self in update callback)

  • property_attr (str) – The attribute name on objects (e.g., β€œlinkforge_sensor”)

Return type:

Any | None

Returns:

The object that owns this property group, or None if not found

Type-safe access to LinkForge link properties on a Blender object.

Parameters:

obj (bpy.types.Object | None)

Return type:

LinkPropertyGroup | None

linkforge.blender.utils.property_helpers.get_joint_props(obj)[source]

Type-safe access to LinkForge joint properties on a Blender object.

Parameters:

obj (bpy.types.Object | None)

Return type:

JointPropertyGroup | None

linkforge.blender.utils.property_helpers.get_sensor_props(obj)[source]

Type-safe access to LinkForge sensor properties on a Blender object.

Parameters:

obj (bpy.types.Object | None)

Return type:

SensorPropertyGroup | None

linkforge.blender.utils.property_helpers.get_transmission_props(obj)[source]

Type-safe access to LinkForge transmission properties on a Blender object.

Parameters:

obj (bpy.types.Object | None)

Return type:

TransmissionPropertyGroup | None

linkforge.blender.utils.property_helpers.get_robot_props(scene)[source]

Type-safe access to LinkForge robot properties on a Blender scene.

Parameters:

scene (bpy.types.Scene | None)

Return type:

RobotPropertyGroup | None

Utilities for managing object transforms and parenting.

linkforge.blender.utils.transform_utils.matrix_to_transform(matrix)[source]

Convert a Blender 4x4 matrix to a Core Transform.

Parameters:

matrix (Any) – Blender mathutils.Matrix (4x4)

Return type:

Transform

Returns:

Core Transform with XYZ position and RPY rotation.

linkforge.blender.utils.transform_utils.set_parent_keep_transform(child_obj, parent_obj)[source]

Set object parent while preserving its world transform (visual location/rotation).

This matches standard Blender β€˜Object (Keep Transform)’ behavior by setting matrix_parent_inverse to the inverse of the parent’s world matrix.

Parameters:
  • child_obj (Any) – The Blender object to be parented

  • parent_obj (Any) – The Blender object to become the parent

Return type:

None

linkforge.blender.utils.transform_utils.clear_parent_keep_transform(child_obj)[source]

Clear object parent while preserving its world transform.

Parameters:

child_obj (Any) – The Blender object to unparent

Return type:

None

Context

class linkforge.blender.adapters.context.IBlenderContext(*args, **kwargs)[source]

Bases: Protocol

Protocol defining the necessary Blender environment access.

property scene: Any

Active Blender scene.

property data: Any

Access to bpy.data.

property ops: Any

Access to bpy.ops.

property view_layer: Any

Active Blender view layer.

property active_object: Any | None

Currently active Blender object.

property preferences: Any

Blender user preferences.

property window_manager: Any

Blender window manager.

get_objects()[source]

Retrieve all objects relevant for the current context.

Return type:

Iterable[Any]

get_active_object()[source]

Retrieve the currently active object.

Return type:

Any | None

__init__(*args, **kwargs)

Usage in Blender

Accessing from Blender Python Console

import bpy
from linkforge.blender.adapters.blender_to_core import scene_to_robot

# Convert current scene to robot model
robot = scene_to_robot(bpy.context)

# Access robot data
print(f"Robot: {robot.name}")
for link in robot.links:
    print(f"  Link: {link.name}")

Creating Custom Operators

import bpy
from linkforge.blender.utils.decorators import safe_execute

class LINKFORGE_OT_my_custom_op(bpy.types.Operator):
    bl_idname = "linkforge.my_custom_op"
    bl_label = "My Custom Operation"

    @safe_execute
    def execute(self, context):
        # Your code here
        self.report({'INFO'}, "Operation complete!")
        return {'FINISHED'}