| name | build123d |
| description | This skill should be used when the user asks to "create a 3D model with build123d", "design parametric parts", "use builder mode", "use algebra mode", "select faces or edges", "export STEP or STL", or works with build123d CAD programming. |
| compatibility | opencode |
| license | Apache-2.0 |
| metadata | {"category":"cad","version":"1.0.0"} |
build123d Development
When to Use This Skill
Primary Triggers (Explicit)
Use this skill when the user says:
- "create a 3D model with build123d"
- "design a parametric part in build123d"
- "use builder mode in build123d"
- "use algebra mode in build123d"
- "select faces/edges/vertices in build123d"
- "export to STEP/STL/DXF"
- "work with build123d"
Contextual Triggers (Implicit)
Use this skill when:
- Working with Python CAD programming
- Creating parametric 3D models
- Developing mechanical parts or assemblies
- Need to manipulate geometric shapes programmatically
- Working with boundary representation (BREP) modeling
Overview
build123d is a Python-based parametric CAD library built on OpenCascade. It provides two distinct programming modes:
- Algebra Mode - Stateless, explicit object manipulation using operators
- Builder Mode - Stateful contexts with implicit state tracking
Core principle: Choose the mode that matches the modeling pattern. Use Algebra Mode for simple, direct construction. Use Builder Mode for complex, context-aware workflows.
Quick Reference
Import Pattern
from build123d import *
Note: While wildcard imports are generally discouraged, build123d scripts are typically self-contained and this is the standard pattern.
Common Objects by Dimension
| Dimension | Objects | Operations |
|---|
| 1D | Line, Arc, Spline, Helix, Bezier | add(), offset(), mirror(), split() |
| 2D | Circle, Rectangle, Polygon, Ellipse | fillet(), chamfer(), offset(), extrude() |
| 3D | Box, Cylinder, Sphere, Cone, Torus | fillet(), chamfer(), loft(), revolve() |
Mode Comparison
| Aspect | Algebra Mode | Builder Mode |
|---|
| State | Stateless | Stateful contexts |
| Syntax | obj += part | with BuildPart(): |
| Objects | Explicit tracking | Implicit tracking |
| Locations | Manual transforms | Context-aware |
| Best for | Simple models | Complex workflows |
For detailed comparison, see references/mode-comparison.md.
Algebra Mode Fundamentals
Basic Pattern
from build123d import *
sketch = Circle(5)
sketch -= Pos(2, 0) * Circle(1)
part = extrude(sketch, amount=10)
part += Pos(0, 0, 10) * Cylinder(3, 5)
Key Operators
+= - Add/union
-= - Subtract/difference
* - Transform (Location * Shape)
@ - Position along Edge/Wire (0.0 to 1.0)
% - Tangent along Edge/Wire (0.0 to 1.0)
^ - Location along Edge/Wire (0.0 to 1.0)
Selectors
Access shape topology with selectors that return ShapeLists:
faces = part.faces()
top_face = part.faces().sort_by(Axis.Z)[-1]
cylinders = part.faces().filter_by(GeomType.CYLINDER)
edges = part.edges().filter_by(lambda e: e.length > 5).sort_by(Axis.X)
Builder Mode Fundamentals
Context Structure
from build123d import *
with BuildPart() as part_context:
with BuildSketch() as sketch:
Rectangle(10, 10)
with Locations((3, 3)):
Circle(2, mode=Mode.SUBTRACT)
extrude(amount=5)
fillet(edges().filter_by(Axis.Z), radius=0.5)
final_part = part_context.part
Context Types
BuildLine - 1D curves and wires
BuildSketch - 2D faces and sketches
BuildPart - 3D solids and parts
Locations - Position multiple objects
GridLocations, PolarLocations, HexLocations - Pattern locations
Mode Parameter
Control how objects combine with context:
Circle(5, mode=Mode.ADD)
Circle(2, mode=Mode.SUBTRACT)
Circle(3, mode=Mode.INTERSECT)
Circle(4, mode=Mode.REPLACE)
Circle(1, mode=Mode.PRIVATE)
Selectors and Filtering
Selectors return ShapeLists with powerful filtering methods:
vertices = part.vertices()
edges = part.edges()
faces = part.faces()
solids = part.solids()
circles = faces.filter_by(GeomType.CIRCLE)
planes = faces.filter_by(GeomType.PLANE)
long_edges = edges.filter_by(lambda e: e.length > 10)
large_faces = faces.filter_by(lambda f: f.area > 50)
sorted_faces = faces.sort_by(Axis.Z)
by_area = faces.sort_by(Face.area)
grouped = faces.group_by(Axis.Z)
top_group = grouped[-1]
bottom_group = grouped[0]
top_faces = faces >> Axis.Z
bottom_faces = faces << Axis.Z
max_faces = faces > Axis.Z
min_faces = faces < Axis.Z
planar = faces | GeomType.PLANE
Common Operations
2D to 3D Conversion
solid = extrude(sketch, amount=10)
solid = extrude(sketch, amount=10, both=True)
solid = extrude(sketch, amount=10, taper=5)
solid = revolve(sketch, axis=Axis.X, angle=360)
solid = loft([sketch1, sketch2, sketch3])
solid = sweep(profile, path)
Filleting and Chamfering
part = fillet(part.edges().filter_by(Axis.Z), radius=1)
part = chamfer(part.edges(), length=0.5)
sketch = full_round(sketch.edges(), radius=2)
Boolean Operations (Algebra Mode)
result = part1 + part2
result = part1 - part2
result = part1 & part2
Positioning and Transformation
Locations
loc = Pos(10, 0, 5)
loc = Rot(45, 0, 0)
loc = Pos(10, 5) * Rot(45)
moved = loc * Circle(5)
plane = Plane.XY
plane = Plane.XZ * Pos(10, 0, 0)
Location Contexts (Builder Mode)
with BuildPart():
with Locations((0, 0, 0), (10, 0, 0), (0, 10, 0)):
Cylinder(2, 10)
with GridLocations(5, 5, 4, 4):
Hole(1)
with PolarLocations(radius=10, count=6):
Box(2, 2, 5)
Data Import/Export
Export Formats
export_step(part, "model.step")
export_stl(part, "model.stl")
export_stl(part, "model.stl", tolerance=0.01)
export_dxf(sketch, "profile.dxf")
export_svg(sketch, "outline.svg")
Import Formats
imported = import_step("existing.step")
svg_sketch = import_svg("logo.svg")
dxf_sketch = import_dxf("profile.dxf")
Extending with Custom Objects
Create reusable parametric objects:
class CustomBracket(BasePartObject):
def __init__(
self,
width: float,
height: float,
thickness: float,
hole_dia: float,
mode: Mode = Mode.ADD,
):
with BuildPart() as bracket:
with BuildSketch():
Rectangle(width, height)
extrude(amount=thickness)
with Locations(Plane.XY.offset(thickness)):
with GridLocations(width-10, height-10, 2, 2):
CounterSinkHole(hole_dia, hole_dia*1.5)
super().__init__(part=bracket.part, mode=mode)
part = CustomBracket(50, 30, 5, 4)
Common Patterns
Parametric Design
def create_gear(teeth: int, module: float, thickness: float):
"""Create parametric gear"""
pitch_radius = teeth * module / 2
with BuildPart() as gear:
with BuildSketch():
Circle(pitch_radius)
extrude(amount=thickness)
return gear.part
Alignment Control
Most objects support align parameter:
Rectangle(10, 5, align=(Align.CENTER, Align.CENTER))
Box(10, 10, 10, align=(Align.MIN, Align.MIN, Align.MIN))
Cylinder(5, 10, align=(Align.CENTER, Align.CENTER, Align.MIN))
Working with Assemblies
from build123d import *
assy = Assembly()
assy.add(base_part, name="base")
assy.add(arm_part, name="arm", loc=Pos(10, 0, 20) * Rot(0, 45, 0))
base = assy["base"]
arm = assy["arm"]
Debugging and Visualization
Interactive Development
Use ocp_vscode for live visualization:
- Install:
pip install ocp-vscode
- In VS Code, install "OCP CAD Viewer" extension
- Use
show() or show_object() to display shapes
from build123d import *
from ocp_vscode import show
part = Box(10, 10, 10)
show(part)
Inspection
print(f"Volume: {part.volume}")
print(f"Area: {face.area}")
print(f"Length: {edge.length}")
bbox = part.bounding_box()
print(f"Size: {bbox.size}")
print(f"Faces: {len(part.faces())}")
print(f"Edges: {len(part.edges())}")
Common Mistakes
Forgetting to assign operations
❌ Wrong:
fillet(part.edges(), 1)
✅ Correct:
part = fillet(part.edges(), 1)
Mixing modes incorrectly
❌ Wrong:
with BuildPart():
box = Box(10, 10, 10)
result = box + Cylinder(5, 15)
✅ Correct:
with BuildPart():
Box(10, 10, 10)
Cylinder(5, 15, mode=Mode.ADD)
Not understanding selector returns
❌ Wrong:
face = part.faces()
fillet(face, 1)
✅ Correct:
faces = part.faces()
top_face = faces.sort_by(Axis.Z)[-1]
edges = top_face.edges()
Incorrect import organization
build123d scripts commonly use wildcard imports:
✅ Correct:
from build123d import *
This is standard practice for build123d despite general Python conventions.
Performance Considerations
- Use appropriate tolerance for export (smaller = slower)
- Avoid excessive boolean operations (combine where possible)
- Use
make_hull() instead of multiple boolean unions when applicable
- Cache complex computed shapes
- Consider
make_face() for complex 2D profiles vs many boolean operations
Additional Resources
Reference Files
references/api-quick-reference.md - Comprehensive object and operation reference
references/mode-comparison.md - Detailed comparison of Builder vs Algebra modes
Examples
examples/algebra-mode-example.py - Complete parametric part in Algebra mode
examples/builder-mode-example.py - Complex assembly in Builder mode
External Documentation
Quick Workflow
To develop with build123d:
- Import:
from build123d import *
- Choose mode: Algebra for simple, Builder for complex
- Create geometry: Use dimension-appropriate objects (1D/2D/3D)
- Apply operations: Extrude, fillet, chamfer, boolean ops
- Select topology: Use selectors with filtering/sorting
- Export:
export_step(), export_stl(), etc.
- Visualize: Use ocp_vscode for interactive development
Focus on understanding the two modes, mastering selectors, and leveraging the operator-based syntax for clean, readable parametric CAD code.