# How to Create Assemblies with build123d Joints in the Text-to-CAD Library

> Learn to create sophisticated assemblies using build123d joints with the Text-to-CAD library. Effortlessly define frames, connect parts, and export to STEP.

- Repository: [earthtojake/text-to-cad](https://github.com/earthtojake/text-to-cad)
- Tags: how-to-guide
- Published: 2026-07-22

---

**The Text-to-CAD library wraps native build123d joint functionality through the `AssemblyHelper` class, allowing you to define datum frames, connect parts with rigid, revolute, and linear joints, and export complete assemblies to STEP format without directly manipulating build123d APIs.**

The earthtojake/text-to-cad repository provides a high-level Python interface for programmatic CAD assembly creation. By leveraging the `AssemblyHelper` class in [`viewer/packages/cadpy/src/cadpy/assembly.py`](https://github.com/earthtojake/text-to-cad/blob/main/viewer/packages/cadpy/src/cadpy/assembly.py), engineers can create complex mechanical assemblies using build123d joints while abstracting away low-level geometric constraints.

## Understanding the AssemblyHelper Architecture

The `AssemblyHelper` class serves as the central orchestrator for assembly creation. It manages part registration, joint definition, and relationship mapping through a declarative API that internally constructs native build123d joint objects.

### Core Joint Frame Methods

To establish connection points on individual parts, the helper provides specialized frame methods that return `MateTarget` objects. These include `rigid_frame()`, `revolute_frame()`, `linear_frame()`, `cylindrical_frame()`, and `ball_frame()`, each creating the appropriate build123d joint type at a specified location and orientation.

### Connection Utilities

Once frames are defined, methods like `connect()`, `face_to_face()`, `coaxial()`, `revolute()`, and `linear()` establish relationships between fixed and moving targets. These utilities automatically invoke `_normalize_target` to process `(part, frame_name)` tuples and `_joint_for_target` to retrieve underlying build123d joint instances from the part's `joints` mapping, storing the result as a `MateRelation`.

## Step-by-Step: Creating Your First Assembly

Begin by importing the necessary modules and instantiating `AssemblyHelper` with a unique assembly name.

```python
import build123d
from cadpy.assembly import AssemblyHelper, target

# Initialize the assembly container

assy = AssemblyHelper("my_assembly")

# Add primitive shapes as parts

part_a = assy.add(build123d.Box(20, 10, 5).wrapped, "base")
part_b = assy.add(build123d.Cylinder(5, 30).wrapped, "shaft")

```

Next, define datum frames on each part where mechanical connections will occur.

```python

# Create a rigid datum at the center of the base

rigid_a = assy.rigid_frame(part_a, "origin", build123d.Location((0, 0, 0)))

# Create a revolute datum aligned with the cylinder's central axis

revolute_b = assy.revolute_frame(
    part_b,
    "axis",
    axis=build123d.Location((0, 0, 1)),
    axis_offset=build123d.Location((0, 0, 0))
)

```

Finally, connect the frames using the appropriate joint type and positional offset.

```python

# Rigidly attach the shaft to the base with a 5mm vertical offset

assy.connect(
    fixed=rigid_a,
    moving=revolute_b,
    relation="rigid",
    offset=build123d.Location((0, 0, 5))
)

```

## Advanced Joint Types and Relationships

Beyond basic rigid connections, the library supports sophisticated mechanical relationships through specialized mating methods.

### Rigid and Revolute Connections

Use `assy.connect()` with `relation="rigid"` for fixed attachments where no relative motion occurs. For rotational degrees of freedom, first declare a `revolute_frame()` on the part to establish the axis of rotation, then use `assy.revolute()` to constrain the motion between two mating frames.

### Linear and Coaxial Mating

For prismatic sliding motion, `linear_frame()` creates the translational axis on a part, while `assy.linear()` sets the specific travel position between two frames. The `coaxial()` convenience method automatically aligns cylindrical features, making it ideal for shaft-and-bearing assemblies without manual axis alignment.

```python

# Define sliding axes on both parts

linear_a = assy.linear_frame(part_a, "slide_a", axis=build123d.Location((1, 0, 0)))
linear_b = assy.linear_frame(part_b, "slide_b", axis=build123d.Location((1, 0, 0)))

# Connect with 10mm of travel

assy.linear(fixed=linear_a, moving=linear_b, position=10.0)

# Or use coaxial alignment for cylindrical features

assy.coaxial(fixed=target(part_a, "axis"), moving=target(part_b, "axis"))

```

## Exporting Assemblies to STEP

The `build()` method aggregates all child shapes into a `build123d.Compound`. When no explicit children are supplied, the helper automatically injects `assembly_mates` metadata—serialized via the private `_mate_endpoint_payload` utility—into the resulting geometry. This metadata captures each joint's position, orientation, and axis data.

Use `export_build123d_step_scene()` from [`viewer/packages/cadpy/src/cadpy/step_export.py`](https://github.com/earthtojake/text-to-cad/blob/main/viewer/packages/cadpy/src/cadpy/step_export.py) to generate the final STEP file containing the assembly structure.

```python

# Generate the compound with embedded joint metadata

final_assembly = assy.build()

# Export to STEP format

from cadpy.step_export import export_build123d_step_scene
export_build123d_step_scene(final_assembly, "my_assembly.step")

```

The resulting STEP file contains an `assemblyMates` section that lists each defined joint, its type, and full location data—ready for downstream tools such as CAD viewers or robot simulation pipelines.

## Summary

- The `AssemblyHelper` class in [`viewer/packages/cadpy/src/cadpy/assembly.py`](https://github.com/earthtojake/text-to-cad/blob/main/viewer/packages/cadpy/src/cadpy/assembly.py) provides a high-level wrapper around native build123d joints.
- Frame declaration methods like `rigid_frame()` and `revolute_frame()` create local datum references that return `MateTarget` objects.
- Connection utilities establish mechanical relationships without requiring direct build123d API calls.
- The internal `_joint_for_target` and `_mate_endpoint_payload` methods handle joint retrieval and serialization.
- Assemblies export to STEP format with embedded joint metadata via `export_build123d_step_scene()`.

## Frequently Asked Questions

### What is the AssemblyHelper class in text-to-cad?

The `AssemblyHelper` class is the primary interface in [`viewer/packages/cadpy/src/cadpy/assembly.py`](https://github.com/earthtojake/text-to-cad/blob/main/viewer/packages/cadpy/src/cadpy/assembly.py) that abstracts build123d's native joint system. It provides methods to label parts via `label_shape`, define joint frames, connect components using `connect()` or `face_to_face()`, and export complete assemblies, eliminating the need to manually manage build123d's lower-level joint APIs.

### How does text-to-cad handle build123d joint serialization?

The library uses the private utility `_mate_endpoint_payload` to serialize each joint's position, orientation, and axis data into a structured format. When `build()` is called, this metadata populates the `assembly_mates` attribute of the resulting `Compound`, which `export_build123d_step_scene()` then embeds into the STEP file's `assemblyMates` section for external compatibility.

### Can I use raw build123d joints with AssemblyHelper?

While the helper is designed to abstract build123d joints, you can access the underlying joint objects through the `joints` dictionary stored on individual parts. The `_joint_for_target` method retrieves these native objects when establishing connections, ensuring compatibility with the broader build123d ecosystem while maintaining the helper's simplified declarative workflow.

### Where are assembly definitions stored in the exported files?

Joint definitions and mate relationships are stored in the `assemblyMates` metadata section of exported STEP files. This section lists each joint type, its associated parts, and full transformation data including position vectors and rotation matrices, making the assemblies compatible with mechanical CAD viewers and robotic simulation pipelines that parse STEP assembly structures.