Version: Current Difficulty: Beginner Time: 30 minutes Status: Stable getting-started guide
This tutorial will teach you how to create 3D models using YAML. No programming experience required!
By the end, you'll create a professional mounting plate with bolt holes and rounded edges.
- Installation
- Your First Model
- Adding Parameters
- Creating Holes
- Making a Bolt Circle
- Professional Finishing
- Next Steps
You'll need Python 3.11+ installed on your system (CadQuery 2.8 requires 3.11+).
# Navigate to the TiaCAD repository
cd /path/to/tiacad
# Install dependencies
pip install -r requirements.txt
# Verify installation by running tests
pytest tiacad_core/tests/ -vLet's create a simple box!
Create a new file called my_first_box.yaml in the examples/ directory:
metadata:
name: My First Box
description: A simple 100x100x10mm box
parts:
box:
primitive: box
size: [100, 100, 10]
origin: center
export:
default_part: boxtiacad build examples/my_first_box.yamlls -lh
# You should see: my_first_box.3mf (modern 3D printing format)Congratulations! You just created your first 3D model in YAML! 🎉
- metadata: Documentation (optional but helpful)
- parts: Define a box 100x100x10mm centered at origin
- export: Tell TiaCAD what part to export
- CLI:
tiacad builddefaults to 3MF (modern format for 3D printing)
Hard-coded numbers are bad. Let's make our box parametric!
Update your YAML file:
metadata:
name: Parametric Box
description: A box with configurable dimensions
parameters:
width: 100
height: 100
thickness: 10
parts:
box:
primitive: box
size: ['${width}', '${height}', '${thickness}']
origin: center
export:
default_part: boxtiacad build examples/my_first_box.yamlSame result, but now you can change all three dimensions by editing one place!
Parameters can do math:
parameters:
base_size: 100
double_size: '${base_size * 2}'
half_size: '${base_size / 2}'Note: Put expressions in quotes: '${...}'
Let's add a hole to our box.
metadata:
name: Box with Hole
description: A box with a center hole
parameters:
box_width: 100
box_height: 100
box_thickness: 10
hole_diameter: 20
parts:
box:
primitive: box
size: ['${box_width}', '${box_height}', '${box_thickness}']
origin: center
hole:
primitive: cylinder
radius: '${hole_diameter / 2}'
height: '${box_thickness + 2}' # Slightly taller for clean cut
origin: center
export:
default_part: boxAdd an operations section:
metadata:
name: Box with Hole
description: A box with a center hole
parameters:
box_width: 100
box_height: 100
box_thickness: 10
hole_diameter: 20
parts:
box:
primitive: box
size: ['${box_width}', '${box_height}', '${box_thickness}']
origin: center
hole:
primitive: cylinder
radius: '${hole_diameter / 2}'
height: '${box_thickness + 2}'
origin: center
operations:
box_with_hole:
type: boolean
operation: difference
base: box
subtract:
- hole
export:
default_part: box # Note: operations modify parts in-place for finishingtiacad build examples/my_first_box.yamlYou now have a box with a hole in the center!
- difference: Subtract parts (make holes)
- union: Combine parts (join them)
- intersection: Keep only overlap
One of TiaCAD's most powerful features is automatic anchors - predefined attachment points on every part.
Think of anchors as marked spots on a workbench where things can be attached. Instead of calculating coordinates manually, you say "put this on top of that".
parameters:
base_width: 100
base_height: 20
tower_width: 30
tower_height: 60
parts:
base:
primitive: box
parameters:
width: '${base_width}'
height: '${base_height}'
depth: 50
origin: center
tower:
primitive: box
parameters:
width: '${tower_width}'
height: '${tower_height}'
depth: 30
origin: center
translate:
to: base.face_top # Anchor at top of base!What just happened?
base.face_topis an automatic anchor at the center of the base's top facetranslate: to: base.face_toppositions the tower at that anchor- No manual coordinate calculation needed!
Every part automatically provides these anchors:
| Anchor | Description |
|---|---|
{part}.center |
Center of the part |
{part}.face_top |
Top face center |
{part}.face_bottom |
Bottom face center |
{part}.face_left |
Left face center |
{part}.face_right |
Right face center |
{part}.face_front |
Front face center |
{part}.face_back |
Back face center |
You can add offsets to anchors:
cap:
primitive: cylinder
parameters:
radius: 5
height: 3
translate:
from: tower.face_top
offset: [0, 0, 5] # 5 units above tower's topThink of it as: "Start at the tower's top face anchor, then go 5 units up"
- No coordinate math:
to: base.face_topinstead of[50, 50, 20] - Self-updating: If you change
base_width, anchors update automatically - Readable: Code clearly shows intent ("on top of base")
- Less error-prone: No manual calculation mistakes
See also: AUTO_REFERENCES_GUIDE.md for complete anchor documentation
Now let's create a mounting plate with 6 bolt holes in a circle.
Create my_mounting_plate.yaml:
metadata:
name: My Mounting Plate
description: Circular bolt pattern mounting plate
parameters:
# Plate dimensions
plate_diameter: 150
plate_thickness: 8
# Bolt circle
bolt_count: 6
bolt_circle_diameter: 100
bolt_diameter: 6.5 # M6 bolts
parts:
plate:
primitive: cylinder
radius: '${plate_diameter / 2}'
height: '${plate_thickness}'
origin: center
bolt_hole:
primitive: cylinder
radius: '${bolt_diameter / 2}'
height: '${plate_thickness + 2}'
origin: center
operations:
# Create circular pattern of bolt holes
bolt_circle:
type: pattern
pattern: circular
input: bolt_hole
count: '${bolt_count}'
radius: '${bolt_circle_diameter / 2}'
axis: Z
center: [0, 0, 0]
# Subtract all bolt holes from plate
finished_plate:
type: boolean
operation: difference
base: plate
subtract:
- bolt_circle_0
- bolt_circle_1
- bolt_circle_2
- bolt_circle_3
- bolt_circle_4
- bolt_circle_5
export:
default_part: platetiacad build examples/my_mounting_plate.yamlThe bolt_circle operation creates 6 copies of bolt_hole:
bolt_circle_0bolt_circle_1bolt_circle_2bolt_circle_3bolt_circle_4bolt_circle_5
Then we subtract all 6 from the plate.
Circular Pattern (what we just used):
type: pattern
pattern: circular
count: 6 # How many
radius: 50 # Circle radius
axis: Z # Rotation axis
center: [0, 0, 0] # Circle centerLinear Pattern (line or grid):
type: pattern
pattern: linear
count: 5 # How many
spacing: [20, 0, 0] # [dx, dy, dz] spacing vectorGrid Pattern (2D array):
type: pattern
pattern: grid
count_x: 4 # Columns
count_y: 3 # Rows
spacing_x: 20 # Column spacing
spacing_y: 25 # Row spacingLet's add rounded edges for safety and aesthetics.
Update your mounting plate YAML:
metadata:
name: Rounded Mounting Plate
description: Professional mounting plate with filleted edges
parameters:
plate_diameter: 150
plate_thickness: 8
bolt_count: 6
bolt_circle_diameter: 100
bolt_diameter: 6.5
edge_fillet_radius: 2.0 # NEW!
parts:
plate:
primitive: cylinder
radius: '${plate_diameter / 2}'
height: '${plate_thickness}'
origin: center
bolt_hole:
primitive: cylinder
radius: '${bolt_diameter / 2}'
height: '${plate_thickness + 2}'
origin: center
operations:
bolt_circle:
type: pattern
pattern: circular
input: bolt_hole
count: '${bolt_count}'
radius: '${bolt_circle_diameter / 2}'
axis: Z
center: [0, 0, 0]
finished_plate:
type: boolean
operation: difference
base: plate
subtract:
- bolt_circle_0
- bolt_circle_1
- bolt_circle_2
- bolt_circle_3
- bolt_circle_4
- bolt_circle_5
# NEW: Round the top edges
rounded_plate:
type: finishing
finish: fillet
input: plate # Note: finishing modifies the part in-place
radius: '${edge_fillet_radius}'
edges:
direction: Z # Only top/bottom edges
export:
default_part: platetiacad build examples/my_mounting_plate.yamlThe top edges are now beautifully rounded!
Fillet (round edges):
type: finishing
finish: fillet
input: my_part
radius: 2.0
edges: all # or selective edgesChamfer (bevel edges):
type: finishing
finish: chamfer
input: my_part
length: 1.5
edges: allEdge Selection:
edges: all # All edges
edges: {direction: Z} # Edges aligned with Z
edges: {parallel_to: X} # Edges parallel to X
edges: {perpendicular_to: Y} # Edges perpendicular to YError:
rotate:
axis: Z
angle: 45Fix: Always specify origin:
rotate:
axis: Z
angle: 45
origin: [0, 0, 0] # REQUIRED!Error:
size: [${width}, ${height}, ${thickness}] # Missing quotes!Fix: Quote expressions:
size: ['${width}', '${height}', '${thickness}']Error:
operations:
my_pattern:
type: pattern
count: 3
# Tries to use "my_pattern" as a part
result:
base: plate
subtract: [my_pattern] # WRONG!Fix: Use numbered pattern parts:
subtract:
- my_pattern_0
- my_pattern_1
- my_pattern_2Transforms apply top-to-bottom:
# Move THEN rotate (usually what you want)
transforms:
- translate: [10, 0, 0]
- rotate: {axis: Z, angle: 90, origin: [0,0,0]}
# Rotate THEN move (different result!)
transforms:
- rotate: {axis: Z, angle: 90, origin: [0,0,0]}
- translate: [10, 0, 0]metadata:
name: My Design
parameters:
size: 100
parts:
my_part:
primitive: box
size: [...]
operations:
my_operation:
type: boolean
...
export:
default_part: final_partbox: size: [x, y, z]
cylinder: radius: r, height: h
sphere: radius: r
cone: radius: r, height: h# Boolean
type: boolean
operation: union | difference | intersection
# Pattern
type: pattern
pattern: linear | circular | grid
# Finishing
type: finishing
finish: fillet | chamferX or [1, 0, 0]
Y or [0, 1, 0]
Z or [0, 0, 1]Try building these on your own:
Create an L-shaped bracket (two boxes joined at 90 degrees).
Hints:
- Create two box parts
- Use
translateto position the vertical part - Use
boolean unionto join them
Create a plate with a 4x4 grid of evenly spaced holes.
Hints:
- Use
pattern: grid count_x: 4, count_y: 4- Subtract all 16 holes (hole_grid_0_0 through hole_grid_3_3)
Create a box with all edges chamfered (beveled).
Hints:
- Create a box
- Use
type: finishing, finish: chamfer edges: all
Let's analyze one of the included examples: rounded_mounting_plate.yaml
A professional 150x150mm mounting plate with:
- 6 bolt holes in a 100mm diameter circle (M6 size)
- Center hole (40mm diameter)
- Rounded top edges (2mm radius) for safety
metadata: # Documentation
name: Rounded Mounting Plate with Filleted Edges
...
parameters: # Configurable values
plate_width: 150
bolt_count: 6
edge_fillet_radius: 2.0
...
parts: # Basic building blocks
plate: # Main plate
primitive: box
...
bolt_hole: # Hole template (will be patterned)
primitive: cylinder
...
center_hole: # Center hole
primitive: cylinder
...
operations: # Combine and modify
bolt_circle: # Pattern: 6 holes in circle
type: pattern
pattern: circular
...
plate_with_holes: # Boolean: subtract holes
type: boolean
operation: difference
...
finished_plate: # Finishing: round edges
type: finishing
finish: fillet
...
export: # Output
default_part: plate_with_holes- Parametric: Change any dimension easily
- Reusable: Template for similar plates
- Professional: Rounded edges prevent injuries
- Manufacturable: Exports to STL for CNC or 3D printing
tiacad build examples/my_file.yaml --verboseExport intermediate parts to see what's happening:
export:
default_part: intermediate_part # Before the final operationBuild complex models incrementally:
- Create basic parts → export → verify
- Add one operation → export → verify
- Add next operation → export → verify
- Continue until complete
TiaCAD provides helpful errors:
Error: Part 'unknown_part' not found in operation 'my_operation'
Available parts: plate, hole, bracket
This tells you:
- What went wrong
- Where it happened
- What's actually available
- YAML_REFERENCE.md - Complete language reference
- EXAMPLES_GUIDE.md - Detailed example walkthroughs
- README.md - Project overview and architecture
# Simple box
tiacad build examples/simple_box.yaml
# Guitar hanger (transforms)
tiacad build examples/simple_guitar_hanger.yaml
# Mounting plate (patterns)
tiacad build examples/mounting_plate_with_bolt_circle.yaml
# Rounded plate (finishing)
tiacad build examples/rounded_mounting_plate.yaml
# L-bracket (chamfer)
tiacad build examples/chamfered_bracket.yamlUse TiaCAD for:
- 3D printer parts
- CNC projects
- Prototyping
- Mechanical assemblies
- Enclosures and brackets
- Custom mounting hardware
- Review test files in
tiacad_core/tests/test_parser/for usage examples - Check session summaries in
/home/scottsen/src/tia/sessions/for development history - Read the comprehensive test suite for edge cases and patterns
You've learned:
- ✅ How to create YAML CAD files
- ✅ How to use parameters and expressions
- ✅ How to create holes with boolean operations
- ✅ How to make patterns (linear, circular, grid)
- ✅ How to add professional finishing (fillet, chamfer)
You're now ready to create professional parametric CAD models in YAML!
Happy Modeling! 🎨
Version: Current Status: Stable getting-started guide Next: Try the practice exercises or explore the real examples!