3dMake and OpenSCAD Appendices — Complete Reference
Comprehensive reference materials for the 3dMake Foundation and OpenSCAD curriculum, including makerspace locators, tool references, slicing guides, material science, quality assurance procedures, and advanced design concepts.
Contents
| Appendix | Title |
|---|---|
| Makerspace Index: Utah | Utah Makerspace Index (By County) |
| Makerspace Index: United States | National Makerspace Guide — State-by-State Index |
| Appendix A | 3DMake CLI Cheat Sheet |
| Appendix B | Comprehensive Slicing Guide — All Major Slicers |
| Appendix C | Material Properties and Selection Guide |
| Appendix D | Tolerance Testing and Quality Assurance Matrix |
| Appendix E | Advanced OpenSCAD Concepts |
Makerspace Index: Utah (By County)
Beaver County
(No makerspace info discovered.)
Box Elder County
(No makerspace info discovered.)
Cache County
Logan Library – Cytiva STEM Makerspace
Bambu 3D printers, mini printers, vinyl cutter, sublimation printer, laser engraver, heat presses, craft cutters, and media digitization tools.1
Carbon County
Southeast Education Service Center (SESC)
STEM kits with coaching, curriculum, and project materials for regional schools.2
Iron County
Southern Utah University – Thunderworks Makerspace
Campus/community fabrication lab with CNC tools, 3D printers, and electronics benches.2
Salt Lake County
Salt Lake City Public Library – Creative Lab
3D printers, Cricut cutters, photography/film tools, Adobe Creative Cloud, recording booth.3
Salt Lake County Library – Create Spaces
3D printers, VR, robotics, A/V studios, DIY repair tools across six branches.4
Make Salt Lake
Community makerspace with woodshop, metal shop, laser cutters, electronics benches, and 3D printer lab.2
University of Utah – Marriott Library ProtoSpace
Prusa MK4/XL 3D printers, 3D scanning, prototyping tools.5
Washington County
Washington County Library – Sid Atkin Makerspace
3D printers, CNC cutter, sewing machines, woodworking tools, electronics kits, VR.6
Utah Tech University – Jr. Makerspace
K–12 and community maker training and fabrication tools.2
Weber County
Weber County Library Makerspaces
Laser cutters, vinyl cutters, laminators, embroidery machines, scanners, and design software stations.7
Endnotes
National Makerspace Guide (United States) — State-by-State Index
A comprehensive state‑by‑state index of ways to locate makerspaces, hackerspaces, Fab Labs, library labs, and community workshops across the U.S., including national directories and state‑level aggregators.
National Directories (Best Starting Points)
Nation of Makers – U.S. Maker Organization Map
Crowdsourced map of U.S.-based maker organizations including makerspaces, hackerspaces, DIY bio labs, Fab Labs, school labs, library spaces, and maker events.8
Makerspace.com – Global & U.S. Makerspace Directory
Large, continuously updated worldwide directory with city/state filters.9
Makerspacedir.com – Makerspace Directory
U.S.-focused listing of makerspaces, hackerspaces, Fab Labs, coworking/maker hybrids, and creative community spaces.10
POIData Makerspace Industry Report (2026)
Lists 1,046 makerspaces in the U.S., with counts by state (e.g., CA 84, FL 45, CO 37, OR 35). Useful for statistical and geographical reference.11
WorkMakeCreate – Public & Free-to-Use Makerspace Finder
Locates community workshops, tool libraries, and free/low‑cost makerspaces by ZIP code.12
GlobalSpec Makerspace Provider List
Allows filtering of makerspaces by U.S. state with business profiles and categories.13
State-by-State Makerspace Index (United States)
Below is a national omnibus index generated from directories that explicitly list makerspaces by state. States not listed did not appear in any verified directory results.
Alabama
- 2 makerspaces listed on GlobalSpec.13
Arizona
- Makerspaces listed on Makerspace Directory and GlobalSpec. Example: Coco‑Op (Flagstaff).14
California
- 84 makerspaces (highest nationwide).11
- Multiple listings in Makerspace.com, GlobalSpec, and WorkMakeCreate.
Colorado
Connecticut
- 2 makerspaces listed on GlobalSpec (e.g., CT Hackerspace).13
District of Columbia
Florida
Georgia
Hawaii
- 2 makerspaces listed on GlobalSpec.13
Idaho
- 5 makerspaces statewide (from POIData).11
Illinois
- 4 makerspaces listed on GlobalSpec (e.g., mHUB Chicago).13
Indiana
- 3 makerspaces listed on GlobalSpec; 22 statewide per POIData.11
Iowa
Kansas
- 14 statewide makerspaces.11
Kentucky
- 6 statewide makerspaces.11
Louisiana
- 3 statewide makerspaces.11
Maine
- 11 statewide makerspaces.11
Maryland
Massachusetts
Michigan
Minnesota
- 27 statewide makerspaces.11
Mississippi
- 3 statewide makerspaces.11
Missouri
Montana
- 9 statewide makerspaces.11
Nebraska
- 7 statewide makerspaces.11
Nevada
- 6 statewide makerspaces.11
New Hampshire
- 4 statewide makerspaces.11
New Jersey
- 12 statewide makerspaces.11
New Mexico
- 8 statewide makerspaces.11
New York
North Carolina
- 28 statewide makerspaces.11
North Dakota
- (No verified listings in sources)
Ohio
Oklahoma
- 8 statewide makerspaces.11
Oregon
- 35 statewide makerspaces.11
Pennsylvania
- 15 statewide makerspaces.11
Rhode Island
South Carolina
- 15 statewide makerspaces.11
South Dakota
- 2 statewide makerspaces.11
Tennessee
- 16 statewide makerspaces; GlobalSpec lists 3 (e.g., CBI Maker Space).13
Texas
Utah
- 9 statewide makerspaces.11
Vermont
- 6 statewide makerspaces.11
Virginia
Washington
West Virginia
- 2 statewide makerspaces.11
Wisconsin
- 17 statewide makerspaces.11
Wyoming
- 6 statewide makerspaces.11
Endnotes
Appendix A: 3DMake CLI Cheat Sheet
A comprehensive reference for the
3dmcommand-line tool used alongside OpenSCAD for 3D printing.
Basic Syntax
3dm ACTIONS... [OPTIONS]... [INPUT_FILE]
You can combine multiple actions in a single command, and most single-letter options can be used with a single dash (e.g. -s 1.5 instead of --scale 1.5).
Quick Examples
3dm build # Build the default model
3dm build orient slice # Build, auto-orient, then slice
3dm build orient slice -m cover -o supports # With a specific model and overlay
3dm info alpaca.stl # Get info about an STL file
3dm preview alpaca.stl # Preview an STL file
3dm slice print alpaca.stl # Slice and send an STL to printer
3dm image --angle top --angle front # Export rendered images
All Actions
Project Setup & Management
| Action | Description |
|---|---|
setup | Set up 3DMake for the first time, or overwrite/upgrade existing settings (printer profile, Gemini AI key, OctoPrint connection) |
new | Interactively create a new 3DMake project directory structure (src/, build/, 3dmake.toml, starter .scad file) |
3dm setup # First-time setup or re-configure
3dm new # Create a new project (prompts for directory name)
Build Pipeline
These actions can be chained together in sequence:
| Action | Description |
|---|---|
build | Compile the OpenSCAD .scad source file into a .stl model |
orient | Auto-orient the model to minimize the need for supports (uses Tweaker3) |
slice | Slice the model into printer-ready G-code using PrusaSlicer |
print | Send the sliced G-code to the printer (OctoPrint, Bambu LAN, or Bambu Connect) |
3dm build # Just compile OpenSCAD -> STL
3dm build orient # Compile then auto-orient
3dm build orient slice # Compile, orient, then slice
3dm build orient slice print # Full pipeline: compile -> orient -> slice -> print
3dm slice print # Slice an already-built model and print it
3dm print # Send an already-sliced file to the printer
Note: Actions automatically trigger their dependencies. For example,
slicewill implybuildif needed.
Inspection & Visualization
| Action | Description |
|---|---|
info | Display mesh dimensions and center point; optionally get an AI description of the model (requires Gemini or OpenRouter API key configured) |
preview | Produce a 2D silhouette projection of the model (outputs a flat STL for quick reference) |
image | Export one or more rendered PNG images of the model from specified viewpoints |
3dm info # Show mesh size/center info
3dm info --interactive # Info + start AI chat session about the model
3dm info model.stl # Info on a specific STL file
3dm preview # Generate 3-silhouette projection (default view)
3dm preview --view topsil # Generate top-only silhouette
3dm image --angle top # Render image from top viewpoint
3dm image --angle top --angle front --angle left # Multiple viewpoints
3dm image --colorscheme slicer_dark --image-size 1920x1080
Available --view options for preview:
| View Name | Description |
|---|---|
3sil | Three-view silhouette (top, left, front) — default |
topsil | Top-down silhouette only |
leftsil | Left-side silhouette only |
rightsil | Right-side silhouette only |
frontsil | Front silhouette only |
backsil | Back silhouette only |
Available --colorscheme options for image:
| Scheme Name | Description |
|---|---|
slicer_light | Orange model on light gray background |
slicer_dark | Orange model on dark background |
light_on_dark | Floral white model on dark background |
Available --angle options for image:above_front_left, above_front_right, above_back_left, above_back_right, top, bottom
Configuration Editors
These are all isolated actions (cannot be combined with other actions):
| Action | Description |
|---|---|
edit-model | Open the current model’s .scad source file in your configured editor |
edit-profile | Open the current printer profile .ini file in your editor |
edit-overlay | Open (or create) a slicer settings overlay file in your editor |
edit-profile-gcode | Interactively select and edit a G-code script embedded in the printer profile |
edit-prompt | Edit the AI prompt used by the info command |
edit-global-config | Edit the global defaults.toml settings file (printer, API keys, etc.) |
3dm edit-model # Edit the default model's .scad file
3dm edit-model -m lid # Edit a specific model (lid.scad)
3dm edit-profile # Edit the current printer profile
3dm edit-profile -p prusa_mk4 # Edit a specific profile
3dm edit-overlay # Prompted to choose/create an overlay
3dm edit-overlay -o supports # Edit the "supports" overlay directly
3dm edit-profile-gcode # Choose and edit a G-code script in the profile
3dm edit-prompt # Edit the AI description prompt
3dm edit-global-config # Edit global settings (defaults.toml)
Library Management
| Action | Description |
|---|---|
list-libraries | List all available OpenSCAD libraries in the catalog, showing which are installed and their versions |
install-libraries | Download and install any libraries required by the current project (as specified in 3dmake.toml) |
3dm list-libraries # See available and installed libraries
3dm install-libraries # Install missing project libraries
Listing Configuration
| Action | Description |
|---|---|
list-profiles | List all available printer profiles |
list-overlays | List all available slicer setting overlays |
3dm list-profiles # See all printer profiles
3dm list-overlays # See all overlays (with profile restrictions if any)
Diagnostics & Info
| Action | Description |
|---|---|
test-connect | Test the connection to the configured print server (OctoPrint or Bambu LAN) |
help | Display the help message with all actions and options |
version | Print the 3DMake version, program location, and config directory |
3dm test-connect # Test printer connection
3dm help # Show help
3dm version # Show version info
All Options
| Option | Short | Type | Description |
|---|---|---|---|
--scale | -s | float or auto | Scale the model by a decimal factor (e.g. 1.5 for 150%, 0.5 for 50%) |
--model | -m | string | Select a specific model by name in a multi-model project (omit .scad extension) |
--profile | -p | string | Select a printer profile by name |
--overlay | -o | string | Apply a slicer settings overlay; can be used multiple times |
--view | -v | string | Select the preview view type (see view options above) |
--angle | -a | string | Set a viewpoint for image export; can be used multiple times |
--copies | -c | int | Number of copies to slice/print (default: 1) |
--interactive | -i | flag | Start an interactive AI chat after the info command |
--colorscheme | — | string | Color scheme name for image export |
--image-size | — | WxH | Image dimensions in pixels (e.g. 1920x1080, default: 1080x720) |
--debug | — | flag | Enable debug output (shows full subprocess logs, raises exceptions) |
--help / --h | -h | flag | Display help and exit |
Input Files
You can pass an .stl or .scad file directly instead of running inside a project directory:
3dm info model.stl # Inspect a standalone STL
3dm preview model.stl # Preview a standalone STL
3dm slice print model.stl # Slice and print a standalone STL
3dm build model.scad # Build a standalone SCAD file -> STL
3dm image model.stl --angle top # Render image from standalone STL
When passing a
.scadfile,buildis automatically added to the action list.
Project File (3dmake.toml) & Global Config (defaults.toml)
Both files use identical TOML keys. defaults.toml lives in the config directory and sets machine-wide defaults. 3dmake.toml lives in your project root and overrides the global defaults for that project only.
Run
3dm edit-global-configto opendefaults.tomlin your editor.
Settings set via CLI flags (e.g.--scale,--profile) override both files at runtime.
General / Project Settings
| Key | Type | Default | Description |
|---|---|---|---|
model_name | string | "main" | The default model name. Maps to src/<name>.scad and build/<name>.stl |
project_name | string | (folder name) | Project name used as a prefix on output filenames. Auto-detected from directory name if not set |
scale | float | 1.0 | Scale factor applied during slicing. 1.0 = 100%, 1.5 = 150%, 0.5 = 50% |
copies | int | 1 | Number of copies to slice/print in one run |
strict_warnings | bool | false | Pass --hardwarnings to OpenSCAD — treat all warnings as errors during build |
min_3dmake_version | string | (none) | Minimum required 3DMake version to run this project. Prevents running with outdated installs |
interactive | bool | false | Default to interactive AI chat mode after info |
debug | bool | false | Enable debug/verbose output globally |
# General project settings
model_name = "main"
project_name = "my-widget"
scale = 1.0
copies = 1
strict_warnings = true
min_3dmake_version = "1.2.0"
interactive = false
debug = false
OpenSCAD / Build Settings
| Key | Type | Default | Description |
|---|---|---|---|
libraries | list of strings | [] | OpenSCAD libraries required by this project. Names must be lowercase and match entries in the library catalog. Install with 3dm install-libraries |
local_libraries | list of strings | [] | Paths to local library directories (absolute or relative to project root) to add to OPENSCADPATH during build |
# OpenSCAD library dependencies
libraries = ["openscad-threads", "bosl2"]
# Local/custom libraries not in the catalog
local_libraries = ["./lib/my-custom-parts", "/home/user/shared-scad-libs"]
Printer & Slicer Settings
| Key | Type | Default | Description |
|---|---|---|---|
printer_profile | string | (required) | Name of the printer profile .ini file to use (without the .ini extension). Set during 3dm setup |
overlays | list of strings | [] | Default slicer setting overlays to apply on every slice. Profile-specific versions are preferred over default ones when available |
view | string | "3sil" | Default preview view type used by the preview action |
image_angles | list of strings | [] | Default viewpoint angles for the image action |
colorscheme | string | "slicer_light" | Default color scheme for the image action |
image_size | string | "1080x720" | Default image export dimensions in WIDTHxHEIGHT pixels |
# Slicer configuration
printer_profile = "prusa_mk4"
overlays = ["fast-draft"]
# Preview and image defaults
view = "3sil"
image_angles = ["above_front_left", "top"]
colorscheme = "slicer_light"
image_size = "1920x1080"
Print Sending Settings
| Key | Type | Default | Description |
|---|---|---|---|
print_mode | string | (required to print) | How to send prints to the printer. One of: "octoprint", "bambu_lan", "bambu_connect" |
auto_start_prints | bool | true | When using OctoPrint, automatically start the print after uploading the file |
# Print sending mode
print_mode = "octoprint" # Options: "octoprint", "bambu_lan", "bambu_connect"
auto_start_prints = true
OctoPrint Connection
Used when print_mode = "octoprint". Test with 3dm test-connect.
| Key | Type | Default | Description |
|---|---|---|---|
octoprint_host | string | (none) | Full URL to your OctoPrint server, including protocol (e.g. "http://octopi.local" or "http://192.168.1.50") |
octoprint_key | string | (none) | OctoPrint Application API key. Generate in OctoPrint > Settings > Application Keys |
# OctoPrint connection (set in defaults.toml, not project toml)
octoprint_host = "http://octopi.local"
octoprint_key = "ABC123DEF456..."
Bambu Labs Connection
Used when print_mode = "bambu_lan". Test with 3dm test-connect.
| Key | Type | Default | Description |
|---|---|---|---|
bambu_host | string | (none) | Local IP address of your Bambu printer on your network (e.g. "192.168.1.42") |
bambu_serial_number | string | (none) | Printer serial number (found in the printer’s settings screen or Bambu Studio) |
bambu_access_code | string | (none) | Local network access code shown on the printer screen (Settings > WLAN) |
# Bambu Labs LAN connection (set in defaults.toml, not project toml)
bambu_host = "192.168.1.42"
bambu_serial_number = "01S00C123456789"
bambu_access_code = "12345678"
AI Description Settings
Used by the info action. Set up during 3dm setup or via 3dm edit-global-config.
| Key | Type | Default | Description |
|---|---|---|---|
gemini_key | string | (none) | Google Gemini API key for AI model descriptions. Free tier allows ~50 requests/day. Get one at aistudio.google.com/app/apikey |
openrouter_key | string | (none) | OpenRouter API key (alternative to Gemini for AI descriptions, supports many LLM providers) |
llm_name | string | (provider default) | Specific LLM model name to use with Gemini or OpenRouter (e.g. "gemini-1.5-flash", "google/gemini-pro-vision") |
# AI description keys (set in defaults.toml only — keep out of project toml!)
gemini_key = "AIzaSy..."
openrouter_key = "sk-or-..."
llm_name = "gemini-1.5-flash"
Editor Settings
| Key | Type | Default | Description |
|---|---|---|---|
editor | string | (system default) | Command used to open files for editing (e.g. "code", "vim", "notepad", "subl"). Used by all edit-* actions |
edit_in_background | bool | false | Launch the editor as a background process (non-blocking). Set to true on Windows where GUI editors are common |
# Editor configuration (typically set in defaults.toml)
editor = "code" # VS Code
edit_in_background = true # Don't block the terminal while editing
# Other common editor values:
# editor = "vim"
# editor = "nano"
# editor = "subl" # Sublime Text
# editor = "notepad" # Windows Notepad
Complete Annotated Example
A fully commented 3dmake.toml for a real project:
# ── Project identity ──────────────────────────────────────────────
model_name = "enclosure" # src/enclosure.scad -> build/enclosure.stl
project_name = "pi-case" # Output files named pi-case-enclosure.gcode etc.
min_3dmake_version = "1.2.0" # Fail loudly if tool is out of date
# ── Build ─────────────────────────────────────────────────────────
strict_warnings = true # Treat OpenSCAD warnings as errors
libraries = ["openscad-threads"] # Needs thread library (run: 3dm install-libraries)
local_libraries = ["./lib"] # Also include project-local ./lib/ directory
# ── Slicing ───────────────────────────────────────────────────────
printer_profile = "prusa_mk4" # Use profiles/prusa_mk4.ini
scale = 1.0 # No scaling
copies = 1
overlays = ["fast-draft"] # Always slice with fast-draft settings
# ── Images & Preview ──────────────────────────────────────────────
view = "3sil"
image_angles = ["above_front_left", "top"]
colorscheme = "slicer_light"
image_size = "1920x1080"
# ── Printing ──────────────────────────────────────────────────────
# (Print connection settings like octoprint_host belong in defaults.toml,
# not here, since they are machine-specific not project-specific)
print_mode = "octoprint"
auto_start_prints = true
A fully commented defaults.toml for a machine-wide config:
# ── Machine-wide defaults (in ~/.config/3dmake/defaults.toml) ────
# General defaults
model_name = "main"
view = "3sil"
auto_start_prints = true
# Editor
editor = "code"
edit_in_background = true # For GUI editors that return immediately
# Printer
printer_profile = "prusa_mk4"
# OctoPrint connection
print_mode = "octoprint"
octoprint_host = "http://octopi.local"
octoprint_key = "ABC123DEF456GHI789..."
# AI descriptions (keep sensitive keys here, not in project toml)
gemini_key = "AIzaSyABC123..."
llm_name = "gemini-1.5-flash"
Typical Workflows
New Project from Scratch
3dm new # Create project structure
cd my-project
3dm edit-model # Write your OpenSCAD model
3dm build # Verify it compiles
3dm info # Check dimensions
3dm build orient slice print # Full pipeline
Iterate on an Existing Model
3dm edit-model # Edit the .scad source
3dm build # Recompile
3dm preview # Quick visual check
3dm slice -o supports # Slice with supports overlay
3dm print # Send to printer
Working with a Standalone STL
3dm info my-model.stl
3dm preview my-model.stl
3dm image my-model.stl --angle above_front_left --angle top
3dm slice print my-model.stl
Export Images for Documentation
3dm image \
--angle above_front_left \
--angle above_front_right \
--angle top \
--colorscheme slicer_light \
--image-size 1920x1080
Environment Variables
| Variable | Description |
|---|---|
3DMAKE_CONFIG_DIR | Override the default configuration directory path |
Configuration Directory Structure
~/.config/3dmake/ (or $3DMAKE_CONFIG_DIR)
├── defaults.toml Global settings (printer, API keys, etc.)
├── profiles/
│ └── my_printer.ini Printer profiles (slicer settings)
├── overlays/
│ ├── default/
│ │ └── supports.ini Default overlays (apply to all printers)
│ └── my_printer/
│ └── supports.ini Printer-specific overlay overrides
├── libraries/ Installed OpenSCAD libraries
└── templates/ Starter templates for new projects/overlays
Overlays
Overlays are partial PrusaSlicer .ini files that override specific slicer settings without replacing the entire printer profile. They are the primary way to switch between print quality modes, enable supports, adjust strength, or any other per-print tuning — without touching your base printer profile.
How Overlays Work
- When slicing, 3DMake loads your base printer profile first, then applies each overlay in order, with later overlays winning over earlier ones.
- Overlay files only need to contain the keys you want to change — all other profile settings are preserved.
- 3DMake looks for overlays in two places, preferring the printer-specific version if it exists:
overlays/<printer_profile>/<name>.ini← preferredoverlays/default/<name>.ini← fallback
Creating and Editing Overlays
3dm edit-overlay # Prompted to pick or create an overlay
3dm edit-overlay -o strong # Open (or create) the "strong" overlay directly
3dm list-overlays # See all available overlays
When creating a new overlay via 3dm edit-overlay, you can optionally lock it to a specific printer profile. A locked overlay lives under overlays/<profile>/ and only applies when that profile is active.
Using Overlays
# Apply a single overlay
3dm slice -o strong
# Apply multiple overlays (stacked in order, last wins on conflicts)
3dm slice -o fine -o supports
# Set a default overlay for a project in 3dmake.toml
overlays = ["strong"]
# CLI overlay replaces (not adds to) the toml default
3dm slice -o draft # Uses only "draft", ignores toml default
Overlay File Format
Overlay .ini files use the same key=value format as PrusaSlicer profiles. You only need to include the keys you want to override.
# overlays/default/strong.ini
# Keys and values are identical to PrusaSlicer's config export format.
# Lines starting with # are comments and are ignored.
perimeters = 4
top_solid_layers = 6
bottom_solid_layers = 6
fill_density = 40%
fill_pattern = grid
Key PrusaSlicer INI Settings Reference
The most useful keys for overlay tuning, with types and sample values:
Shell / Wall Strength
| Key | Description | Sample Values |
|---|---|---|
perimeters | Number of outer wall loops | 2 (draft) · 3 (normal) · 5 (strong) |
top_solid_layers | Solid layers on the top surface | 3 (draft) · 5 (normal) · 8 (strong) |
bottom_solid_layers | Solid layers on the bottom surface | 3 (draft) · 4 (normal) · 6 (strong) |
top_solid_min_thickness | Minimum top skin thickness in mm (overrides layer count if larger) | 0.5 · 0.8 · 1.0 |
bottom_solid_min_thickness | Minimum bottom skin thickness in mm | 0.5 · 0.8 · 1.0 |
external_perimeters_first | Print outer walls before inner walls (better surface quality) | 0 · 1 |
thin_walls | Detect and print thin walls that would otherwise be missed | 0 · 1 |
Infill
| Key | Description | Sample Values |
|---|---|---|
fill_density | Infill percentage | 5% · 15% · 20% · 40% · 60% |
fill_pattern | Infill pattern | grid · gyroid · honeycomb · cubic · rectilinear · lightning · triangles |
top_fill_pattern | Pattern for top solid layers | rectilinear · monotonic · concentric · smooth |
bottom_fill_pattern | Pattern for bottom solid layers | rectilinear · monotonic · concentric |
infill_every_layers | Only infill every N layers (speeds up print, reduces strength) | 1 · 2 · 3 |
solid_infill_every_layers | Force solid infill every N layers | 0 (off) · 5 |
infill_overlap | How much infill overlaps with perimeters (%) | 15% · 25% |
Layer Height & Speed
| Key | Description | Sample Values |
|---|---|---|
layer_height | Standard layer height in mm | 0.1 · 0.15 · 0.2 · 0.3 |
first_layer_height | Height of the first layer (absolute mm or %) | 0.2 · 0.25 · 75% |
perimeter_speed | Speed for perimeter walls (mm/s) | 40 · 60 · 80 |
external_perimeter_speed | Speed for outermost wall only (slower = better quality) | 25 · 35 · 50% |
infill_speed | Speed for infill (mm/s) | 60 · 80 · 120 |
solid_infill_speed | Speed for solid infill layers (mm/s) | 50 · 70 |
top_solid_infill_speed | Speed for top surface layers (slower = smoother) | 30 · 40 · 50 |
travel_speed | Non-extrusion travel speed (mm/s) | 130 · 180 · 250 |
first_layer_speed | First layer speed (mm/s or %) | 20 · 30 · 50% |
Supports
| Key | Description | Sample Values |
|---|---|---|
support_material | Enable support structures | 0 · 1 |
support_material_auto | Auto-detect where supports are needed | 0 · 1 |
support_material_threshold | Overhang angle above which supports are added (degrees) | 40 · 45 · 55 |
support_material_pattern | Support infill pattern | rectilinear · honeycomb · lightning |
support_material_spacing | Distance between support lines (mm) | 2 · 2.5 · 3 |
support_material_contact_distance | Z gap between support and part (mm) | 0.1 · 0.2 · 0.25 |
support_material_interface_layers | Dense interface layers between support and part | 0 · 2 · 3 |
Cooling & Bridging
| Key | Description | Sample Values |
|---|---|---|
cooling | Enable fan cooling | 0 · 1 |
min_fan_speed | Minimum fan speed % | 20 · 35 · 50 |
max_fan_speed | Maximum fan speed % | 50 · 80 · 100 |
bridge_fan_speed | Fan speed during bridges % | 80 · 100 |
bridge_speed | Extrusion speed for bridges (mm/s) | 20 · 30 · 40 |
bridge_flow_ratio | Flow rate multiplier for bridges | 0.8 · 0.9 · 1.0 |
Skirt, Brim & Raft
| Key | Description | Sample Values |
|---|---|---|
skirts | Number of skirt loops | 0 · 1 · 3 |
skirt_distance | Distance from part to skirt (mm) | 3 · 5 · 6 |
brim_width | Brim width in mm (0 = disabled) | 0 · 3 · 5 · 8 |
raft_layers | Number of raft layers (0 = disabled) | 0 · 2 · 3 |
Temperature
| Key | Description | Sample Values |
|---|---|---|
temperature | Hotend temperature for all layers (°C) | 200 · 215 · 230 |
first_layer_temperature | Hotend temperature for first layer only | 215 · 225 · 235 |
bed_temperature | Bed temperature for all layers (°C) | 0 · 55 · 60 · 80 |
first_layer_bed_temperature | Bed temperature for first layer only | 60 · 65 · 85 |
Sample Overlay: strong.ini
For functional parts, mechanical components, or anything that needs to survive stress. Heavier walls, more solid layers, higher infill, slower outer perimeters.
# overlays/default/strong.ini
# Heavy-duty print — maximizes strength at the cost of time and filament.
# Shell: thick walls and solid layers
perimeters = 5
top_solid_layers = 7
bottom_solid_layers = 6
top_solid_min_thickness = 1.2
bottom_solid_min_thickness = 1.0
external_perimeters_first = 1
# Infill: dense cubic for near-isotropic strength
fill_density = 50%
fill_pattern = cubic
infill_overlap = 25%
# Speed: slower outer wall for better layer adhesion
external_perimeter_speed = 25
perimeter_speed = 45
top_solid_infill_speed = 30
# First layer: slower for bed adhesion
first_layer_speed = 20
# Cooling: slightly reduced to improve layer bonding on perimeters
max_fan_speed = 70
Sample Overlay: draft.ini
For quick test fits, rough prototypes, or checking dimensions before committing to a full print. Faster speeds, minimal walls, low infill, thicker layers.
# overlays/default/draft.ini
# Fast draft print — sacrifices surface quality and strength for speed.
# Shell: minimum viable walls
perimeters = 2
top_solid_layers = 3
bottom_solid_layers = 3
# Infill: low density, fast pattern
fill_density = 10%
fill_pattern = grid
# Layer height: thick layers = fewer passes = faster print
# NOTE: layer_height must be <= 75% of nozzle diameter.
# For a 0.4mm nozzle, max is 0.3mm.
layer_height = 0.3
# Speed: push everything faster
perimeter_speed = 80
external_perimeter_speed = 60
infill_speed = 120
solid_infill_speed = 90
top_solid_infill_speed = 60
travel_speed = 200
first_layer_speed = 30
# Cooling: full fan to keep up with fast extrusion
min_fan_speed = 50
max_fan_speed = 100
Sample Overlay: fine.ini
For display models, miniatures, parts with fine surface detail, or anything where appearance matters more than speed. Thin layers, many perimeters, slow outer walls, smooth top surfaces.
# overlays/default/fine.ini
# Fine detail print — maximizes surface quality and dimensional accuracy.
# Shell: many perimeters for crisp edges and thick solid skins
perimeters = 4
top_solid_layers = 8
bottom_solid_layers = 5
top_solid_min_thickness = 1.0
external_perimeters_first = 1
thin_walls = 1
# Infill: moderate density with monotonic top for smooth finish
fill_density = 20%
fill_pattern = gyroid
top_fill_pattern = monotonic
bottom_fill_pattern = monotonic
# Layer height: thin layers for fine Z resolution
# NOTE: must be >= 25% of nozzle diameter to ensure reliable extrusion.
# For a 0.4mm nozzle, minimum is ~0.08mm; 0.1mm is safe.
layer_height = 0.1
first_layer_height = 0.2
# Speed: slow everything down for precision
perimeter_speed = 40
external_perimeter_speed = 20
infill_speed = 60
solid_infill_speed = 40
top_solid_infill_speed = 25
bridge_speed = 20
first_layer_speed = 15
# Cooling: strong cooling for clean overhangs and bridges
min_fan_speed = 50
max_fan_speed = 100
bridge_fan_speed = 100
bridge_flow_ratio = 0.85
# Brim: small brim helps adhesion for tall fine parts
brim_width = 3
Sample Overlay: supports.ini
Enable automatic support structures for models with steep overhangs. Stack with other quality overlays.
# overlays/default/supports.ini
# Enable automatic supports for overhangs > 45 degrees.
support_material = 1
support_material_auto = 1
support_material_threshold = 45
support_material_pattern = lightning
support_material_spacing = 2.5
support_material_contact_distance = 0.2
support_material_interface_layers = 2
Sample Overlay: no-supports.ini
Explicitly disable supports — useful when your base profile has them on by default.
# overlays/default/no-supports.ini
support_material = 0
support_material_auto = 0
Stacking Overlays
Overlays are applied left to right, so later overlays win on any conflicting keys. This lets you compose print settings modularly:
# Fine quality WITH supports
3dm slice -o fine -o supports
# Strong walls but fast draft speed (fine conflicts: perimeter_speed in draft wins)
3dm slice -o strong -o draft
# Strong structural settings + supports, no brim (add a tiny no-brim override)
3dm slice -o strong -o supports -o no-brim
You can also set permanent default overlays for a project in 3dmake.toml, while adding extra ones at the CLI:
# 3dmake.toml — always use strong as the base for this project
overlays = ["strong"]
# At CLI: strong (from toml) is REPLACED by the CLI overlay list
3dm slice -o strong -o supports # Both applied
3dm slice -o fine # Only fine — replaces toml default entirely
Tip: Name your overlays by intent (
strong,draft,fine,supports,vase-mode,no-brim) rather than by settings (40pct-infill). This keeps the CLI readable and lets you tune the overlay file without renaming references everywhere.
Action Dependency & Chain Rules
Implied Action Dependencies
Some actions automatically trigger prerequisite actions. You never need to spell these out manually — 3DMake inserts them for you.
print
└── slice (implied)
└── build (implied, if scad source exists)
image
└── load-mesh (internal, implied)
info
└── measure-mesh (internal, implied)
└── load-mesh (internal, implied)
preview
└── measure-mesh (internal, implied)
└── load-mesh (internal, implied)
orient
(no implied actions — operates on an already-built STL)
So running 3dm print on a project with OpenSCAD source will automatically run build -> slice -> print in order. You only need to be explicit when you want to stop partway through (e.g. 3dm build to just check compilation without slicing).
last_in_chain — Actions That Must Come Last
Three actions are marked last_in_chain, meaning no other pipeline actions can follow them in the same command. Attempting to do so is an error.
| Action | Why it’s last |
|---|---|
image | Produces image files; nothing meaningful can follow a render |
info | Terminal inspection command; no build artifact is produced |
preview | Produces a projection STL; slicing a silhouette is not useful |
# ✅ Valid — last_in_chain actions used alone or at the end
3dm build image
3dm build orient image
3dm info
3dm build preview
# ❌ Invalid — actions after a last_in_chain action
3dm image slice # ERROR: 'image' cannot be followed by 'slice'
3dm info build # ERROR: 'info' cannot be followed by 'build'
3dm preview print # ERROR: 'preview' cannot be followed by 'print'
Isolated Actions
A separate category called isolated means the action cannot be combined with any other action at all — it must be the only verb on the command line. All edit-* actions, setup, new, version, help, test-connect, list-profiles, list-overlays, list-libraries, and install-libraries are isolated.
# ✅ Valid
3dm edit-model
3dm setup
3dm list-profiles
# ❌ Invalid
3dm edit-model build # ERROR: edit-model is isolated
3dm setup new # ERROR: setup is isolated
Full Action Execution Order
When you request multiple actions, they always execute in this fixed internal order regardless of how you type them on the command line:
setup -> new -> build -> load-mesh* -> measure-mesh* -> info -> orient ->
image -> preview -> slice -> print -> list-profiles -> list-overlays ->
edit-model -> edit-overlay -> edit-profile -> edit-profile-gcode ->
edit-prompt -> edit-global-config -> list-libraries -> install-libraries ->
test-connect -> help -> version
_(Actions marked _ are internal and cannot be requested directly.)*
This means 3dm slice build and 3dm build slice are identical — order of verbs on the command line does not matter.
Multi-Model Projects
A single 3DMake project can contain multiple OpenSCAD models. Each model is a separate .scad file in the src/ directory.
Directory Layout
my-project/
├── 3dmake.toml
├── src/
│ ├── main.scad ← default model (model_name = "main")
│ ├── lid.scad
│ ├── bracket.scad
│ └── insert.scad
└── build/ ← generated STLs and GCode land here
├── main.stl
├── lid.stl
└── my-project-main.gcode
Selecting a Model
# Uses model_name from 3dmake.toml (default: "main")
3dm build slice
# Override at the CLI with --model / -m
3dm build slice -m lid
3dm build slice -m bracket
3dm info -m insert
# edit-model also respects -m
3dm edit-model -m lid
Setting a Per-Model Default in 3dmake.toml
# 3dmake.toml
model_name = "bracket" # Everyone on this project defaults to the bracket model
Output File Naming
Output G-code files are named using the pattern:
<project_name>-<model_name>.gcode # 1 copy
<project_name>-<model_name>-x3.gcode # 3 copies (--copies 3)
For example, a project named pi-case building the lid model with 2 copies produces:
build/pi-case-lid-x2.gcode
If project_name is not set in 3dmake.toml, it is auto-detected from the directory name.
Tip: Shared Parameters Across Models
A common OpenSCAD pattern is a shared params.scad file included by all models:
src/
├── params.scad ← shared dimensions, tolerances, material choices
├── main.scad ← include <params.scad>
├── lid.scad ← include <params.scad>
└── bracket.scad ← include <params.scad>
This way changing one dimension in params.scad propagates to every model, and you can rebuild all variants with a shell loop:
for model in main lid bracket; do
3dm build slice -m $model
done
Special INI Keys
3dm_bed_center
This is a 3DMake-specific key (not a standard PrusaSlicer key) that you can add to a printer profile or overlay. It works around a PrusaSlicer CLI bug where models are not correctly centered on non-rectangular or offset build volumes.
# In a printer profile .ini or overlay .ini
# Value is "X,Y" coordinates of the bed center in mm
3dm_bed_center = 117.5,117.5 # Prusa MK3/MK4 (235x235mm bed)
3dm_bed_center = 110,110 # 220x220mm bed
3dm_bed_center = 150,150 # 300x300mm bed
3dm_bed_center = 175,162.5 # Prusa XL (350x325mm bed)
When this key is present, 3DMake passes --center X,Y to the PrusaSlicer CLI automatically. You should set this in your printer profile rather than an overlay, since it is specific to the physical printer’s bed geometry.
AI Prompt Customization
The info action sends rendered images of your model to an AI (Gemini or OpenRouter) along with a text prompt. The default prompt asks for a general physical description of the object. You can customize this prompt to get more targeted or useful output.
Editing the Prompt
3dm edit-prompt # Opens the prompt file in your configured editor
The prompt file lives at:
~/.config/3dmake/prompt.txt (or $3DMAKE_CONFIG_DIR/prompt.txt)
If the file does not exist when you run 3dm edit-prompt, 3DMake creates it from a built-in default automatically.
What the Prompt Receives
The AI receives your prompt text plus six rendered PNG images of the model taken from these fixed viewpoints: above_front_left, above_front_right, above_back_left, above_back_right, top, and bottom. Each image is 768×768 pixels.
Sample Prompts
Default-style — general physical description:
You are analyzing a 3D model for 3D printing. Describe the object's physical
shape, identifying any notable geometric features, symmetry, overhangs, thin
walls, or small details that might affect printability. Be concise and factual.
Printability review — focused on print problems:
You are a 3D printing expert reviewing a model before printing. Examine these
views and identify:
1. Any overhangs greater than 45 degrees that will need supports
2. Thin walls or small features that may not print reliably at 0.4mm nozzle diameter
3. The best orientation for printing (which face should be on the bed)
4. Any other potential print quality issues
Be specific about locations (e.g. "the underside of the lip on the left side").
Dimensional estimation — for sanity-checking scale:
Based on the shape and proportions of this 3D model, estimate what real-world
object it most resembles and what its approximate dimensions might be in
millimeters. Note any features that suggest a specific scale (screw holes,
finger clearances, standard hardware interfaces, etc.).
Design feedback — for iterating on a model:
You are reviewing a 3D model for functional and aesthetic design quality.
Comment on: whether the design looks structurally sound, any places where
the geometry looks unintentional or messy, whether any features look like
they might be too fragile, and one specific improvement suggestion.
Interactive mode (3dm info --interactive) lets you follow up with specific questions after the initial AI response, such as asking it to focus on a particular feature or compare proportions.
Troubleshooting
Setup & Configuration
3DMake settings and print options have not been set up on this machine.
Run 3dm setup before any other command. This creates the config directory, copies default profiles, and walks you through initial configuration.
Printer profile 'X' does not exist.
Run 3dm list-profiles to see valid profile names. Profile names are case-sensitive and must match the .ini filename exactly (without the extension). Set the correct one with 3dm setup or by editing defaults.toml with 3dm edit-global-config.
This project requires 3DMake version X or newer.
The min_3dmake_version key in 3dmake.toml is higher than your installed version. Run 3dm version to check your version, then update 3DMake. If you are the project author, lower min_3dmake_version if the feature requirement does not actually apply.
Build Errors
Source file src/main.scad does not exist.
Either you are not in a 3DMake project directory, or model_name in your 3dmake.toml does not match an actual .scad file in src/. Run 3dm edit-model to create the file, or correct model_name.
Some needed libraries are not installed: <name>
Run 3dm install-libraries to download and install the missing libraries listed in your 3dmake.toml libraries key. Run 3dm list-libraries to verify the library name is spelled correctly (names are lowercase).
OpenSCAD prints warnings but does not fail.
Add strict_warnings = true to your 3dmake.toml to treat warnings as errors. This is recommended for all projects to catch issues like undefined variables and deprecated syntax early.
Build succeeds but STL looks wrong / has missing geometry.
Run with --debug to see the full OpenSCAD output including all warnings:
3dm build --debug
Slicing Errors
Could not find overlay 'X' for profile 'Y'.
The overlay file does not exist at overlays/Y/X.ini or overlays/default/X.ini. Run 3dm list-overlays to see what is available, or 3dm edit-overlay -o X to create it.
Could not fit the object outline on the build surface.
The model is larger than the printer’s bed, or is being placed off-center. Check your model dimensions with 3dm info, verify your printer_profile is correct for your actual printer, and confirm 3dm_bed_center is set correctly in your profile if you have a non-standard bed.
Slicer produces unexpected print warnings.
Run with --debug to see the full PrusaSlicer stdout output:
3dm slice --debug
Print / Connection Errors
Unknown print mode 'X'.
print_mode in your config must be exactly one of: octoprint, bambu_lan, or bambu_connect. Check spelling in defaults.toml.
OctoPrint: ERROR: Authentication failed (401)
Your octoprint_key is wrong or expired. In OctoPrint, go to Settings > Application Keys and generate a new key, then update defaults.toml via 3dm edit-global-config.
OctoPrint: ERROR: Could not connect to server
Check that octoprint_host is correct and includes the protocol (http:// or https://). Verify OctoPrint is running and the machine running 3DMake is on the same network. Run 3dm test-connect for a detailed diagnosis.
Bambu: FTP or MQTT connection fails.
Verify bambu_host is the printer’s current local IP (it may change if your router assigns IPs dynamically — consider setting a static IP for the printer). Check bambu_access_code on the printer screen under Settings > WLAN. Run 3dm test-connect for step-by-step diagnosis.
Bambu Connect mode: 3dm print with print_mode = "bambu_connect" does not connect directly to the printer. It packages your G-code into a .3mf file and opens the Bambu Connect desktop application via a URI handoff. Bambu Connect must be installed and running on your machine. 3dm test-connect will report that it cannot test this mode — this is expected.
General
Unknown action 'X'
Action names are lowercase and use hyphens, not underscores (e.g. edit-model, not edit_model). Run 3dm help for the full list.
The action 'X' can only be used on its own
You combined an isolated action with other actions. Isolated actions (edit-*, setup, new, version, help, test-connect, list-*, install-libraries) must be run alone.
Action 'X' cannot be followed by other actions
You placed a last_in_chain action (image, info, preview) before other pipeline actions. These must be the final (or only) action in your command.
Cannot select a model name when using an input file
--model / -m and a direct input file path are mutually exclusive. Use one or the other.
Multiple inputs not supported yet
Only one input file can be passed per invocation. To process multiple files, use a shell loop.
OpenSCAD Tips & Conventions for 3DMake
Project Conventions
3DMake expects OpenSCAD source files in src/<model_name>.scad and writes STL output to build/<model_name>.stl. As long as you follow this layout (created automatically by 3dm new), everything works without extra configuration.
Parameterized Models
The most powerful pattern for 3DMake projects is a fully parameterized model where all key dimensions are defined as variables at the top of the file. This makes it trivial to create variants without duplicating code.
// src/box.scad
// All tunable parameters at the top
length = 80; // mm
width = 50; // mm
height = 30; // mm
wall = 2.5; // mm — wall thickness
tolerance = 0.2; // mm — fit clearance for mating parts
fillet_r = 1.5; // mm — corner radius
// Model below uses only the variables above
module box_shell() {
difference() {
rounded_rect([length, width, height], r=fillet_r);
translate([wall, wall, wall])
cube([length-wall*2, width-wall*2, height]);
}
}
box_shell();
Multi-Model Shared Parameters
For projects with multiple related models (e.g. a box and its lid), put shared dimensions in a separate include file:
// src/params.scad — shared across all models
outer_length = 80;
outer_width = 50;
wall = 2.5;
tolerance = 0.2;
lid_height = 8;
body_height = 35;
// src/body.scad
include <params.scad>
difference() {
cube([outer_length, outer_width, body_height]);
translate([wall, wall, wall])
cube([outer_length-wall*2, outer_width-wall*2, body_height]);
}
// src/lid.scad
include <params.scad>
cube([outer_length - tolerance*2, outer_width - tolerance*2, lid_height]);
Useful OpenSCAD Modules for 3D Printing
// Rounded rectangle (better bed adhesion, less stress concentration)
module rounded_rect(size, r=1) {
hull() {
for (x=[r, size[0]-r], y=[r, size[1]-r])
translate([x, y, 0]) cylinder(r=r, h=size[2], $fn=32);
}
}
// Countersunk screw hole (M3 example)
module m3_hole(depth=10, countersink=true) {
cylinder(d=3.4, h=depth, $fn=24);
if (countersink)
translate([0, 0, depth-3.2])
cylinder(d1=3.4, d2=6.5, h=3.2, $fn=24);
}
// Snap-fit clip tab
module snap_tab(length=10, width=4, height=3, overhang=0.8) {
union() {
cube([length, width, height]);
translate([0, 0, height])
linear_extrude(overhang, scale=[1, 1, 0])
square([length, width]);
}
}
$fn, $fa, $fs — Circle Resolution
OpenSCAD renders circles and cylinders as polygons. Control resolution with these special variables:
| Variable | Meaning | Recommended |
|---|---|---|
$fn | Fixed number of fragments | 32 for small circles, 64+ for large |
$fa | Minimum angle per fragment (degrees) | 1 for smooth curves |
$fs | Minimum fragment size (mm) | 0.5 for print resolution |
// Set globally at top of file for consistent quality
$fa = 1;
$fs = 0.4; // Match your nozzle diameter
// Or set per-object for performance (preview fast, export high quality)
cylinder(r=10, h=5, $fn=64);
Tip: Use
$fn=16or$fn=24during development for fast preview renders, then raise it to$fn=64or higher before your final3dm buildfor export.
Designing for Printability
Avoid overhangs steeper than 45° without supports. Use chamfers instead of horizontal overhangs where possible:
// ❌ Horizontal lip — needs supports
translate([0, 0, 10]) cube([20, 5, 2]);
// ✅ 45° chamfer — self-supporting
hull() {
cube([20, 2, 10]);
translate([0, 5, 8]) cube([20, 0.01, 2]);
}
Minimum feature sizes at 0.4mm nozzle:
| Feature | Minimum |
|---|---|
| Wall thickness | 0.8mm (2× nozzle) — ideally 1.2mm+ |
| Hole diameter | 2mm (smaller holes tend to close up) |
| Gap / clearance between parts | 0.2–0.3mm for sliding fit, 0.1mm for press fit |
| Text / embossed detail | 0.5mm depth, 4pt font minimum |
| Pin diameter | 2mm minimum for structural pins |
Orientation matters. Layer lines are weakest in tension perpendicular to the print direction. Design critical stress paths to run parallel to layer lines, or use the orient action to auto-optimize placement.
Tolerance for fits. PLA typically needs 0.2–0.3mm clearance for a sliding fit between printed parts. PETG and ABS may need slightly more. Build a quick tolerance test into your workflow:
// Tolerance test — print this and measure which gap fits your printer
for (i=[0:4])
translate([i*15, 0, 0])
difference() {
cube([12, 12, 5]);
translate([6, 6, 0])
cylinder(d=5 + i*0.1, h=5, $fn=32);
}
Using OpenSCAD Libraries with 3DMake
Declare library dependencies in 3dmake.toml, then install them:
# 3dmake.toml
libraries = ["openscad-threads", "bosl2"]
3dm install-libraries # Downloads and installs to config dir
3dm list-libraries # Verify installation
Then use them in your .scad files normally:
// BOSL2 example
include <BOSL2/std.scad>
cuboid([20, 20, 10], rounding=2, edges="Z");
// openscad-threads example
use <threads.scad>
metric_thread(diameter=8, pitch=1.25, length=20);
Appendix B: Comprehensive Slicing Guide — All Major Slicers
This appendix covers settings, workflows, and troubleshooting for 7 major 3D printer slicers. Each slicer is represented with:
- Recommended settings for beginners
- Screen-reader-accessible settings explanation
- Common troubleshooting
- Accessibility features built-in
- Command-line usage (for PowerShell integration)
Referenced in: Lessons 5 (Safety), 8 (Design), 10 (Verification)
Overview: What is Slicing?
Slicing converts a 3D model into printer instructions:
SCAD Design (bracelet_holder.scad)
v
Export to STL (3D shape file)
v
Load into Slicer
v
Apply settings (temperature, speed, supports, etc.)
v
Generate G-code (printer instructions)
v
Send to Printer
v
Physical part
Core Slicing Parameters (All Slicers Share These)
| Parameter | What It Does | Typical Range | Impact |
|---|---|---|---|
| Nozzle Temp | Filament melting heat | 200-250C | Too cold -> weak; too hot -> oozing |
| Bed Temp | Build plate heat | 50-110C | Helps adhesion; prevents warping |
| Layer Height | Z-axis precision | 0.1-0.4mm | Finer = slower, better detail |
| Print Speed | Movement velocity | 30-150 mm/s | Faster = worse quality; slower = stronger |
| Infill % | Interior density | 10-100% | Higher = stronger + heavier |
| Support | Temporary scaffolding | On/Off | Required for overhangs >45 |
| Bed Adhesion | First layer stickiness | Brim/Raft/Skirt | Prevents parts lifting mid-print |
1. PrusaSlicer (Prusa)
Overview
- Developer: Prusa Research (Czech company)
- Platforms: Windows, Mac, Linux (open-source)
- Best For: Beginner-friendly, excellent support, strong community
- Download: https://www.prusa3d.com/page/prusaslicer_410/
- Accessibility: Good font sizes, text-based profiles
Quick Setup for Beginners
Step 1: Install & Select Your Printer
1. Open PrusaSlicer
2. Go to "Help" -> "Check for Updates"
3. When prompted, select your printer model
4. Choose default profile (matches printer exactly)
Step 2: Load Your STL
1. Click "File" -> "Open STL Model"
2. Select your bracelet_holder.stl
3. Model appears in 3D view
Step 3: Essential Settings
These are the most important adjustments:
| Setting | Location | Beginner Value | Why |
|---|---|---|---|
| Layer Height | Print Settings | 0.15mm | Balance speed & quality |
| Infill | Print Settings | 20% | Enough strength; fast print |
| Support | Print Settings | Yes (if needed) | For overhangs >45 |
| Nozzle Temp | Filament Settings | 210C | Default for PLA |
| Bed Temp | Filament Settings | 60C | Standard PLA adhesion |
| Print Speed | Print Settings | 150 mm/s | Balanced quality |
Step 4: Preview & Export
1. Click "Slice now" (or G-code icon)
2. Left panel shows preview of each layer
3. Look for issues:
- Supports covering entire model? (OK)
- Model floating in air? (Not OK-likely error)
- Top surface quality acceptable?
4. If satisfied, click "Export G-code"
5. Save to USB or send to printer
Accessible Parameter Explanations
When adjusting settings, use these descriptions to understand what each does:
Layer Height (0.1-0.4mm)
- Lower (0.1mm): Smoother surface, more layers, slower (best for detail)
- Higher (0.4mm): Faster, rougher surface (best for speed)
- Recommendation: 0.15mm for balanced quality
Infill Percentage (10-100%)
- 10%: Fast, uses less filament, weaker (good for prototypes)
- 20%: Good balance (recommended for most prints)
- 50%: Stronger, slower, heavier
- 100%: Solid interior, strongest, slowest (waste of plastic)
Support Type
- None: Fast, good surface finish, but risky if overhangs exist
- Linear (Default): Good balance-easy to remove, provides support
- Grid: Extra strong support, takes longer to remove
First Layer
- Brim: Adds border to help adhesion (recommended for beginners)
- Raft: Sacrificial platform (good if bed isn’t level)
- Skirt: Just outline, doesn’t help adhesion (fastest)
Command-Line Usage (PowerShell Integration)
# Slice a model automatically with PrusaSlicer
$model = "C:\Models\bracelet_holder.stl"
$output = "C:\GCode\bracelet_holder.gcode"
$config = "default" # Use default printer profile
# Run PrusaSlicer in batch mode
& "C:\Program Files\Prusa3D\PrusaSlicer\prusa-slicer.exe" `
--load-config-file "$config" `
--export-gcode "$output" `
"$model"
Write-Host "Slicing complete: $output"
Troubleshooting
| Problem | Cause | Solution |
|---|---|---|
| First layer not sticking | Bed not level | Bed leveling procedure in printer manual |
| Supports everywhere | No support type selected | Change to “Linear” or “Grid” |
| Nozzle drags through model | Z-offset too low | Raise Z-offset +0.1mm |
| Oozing strings between parts | Temp too high | Lower nozzle temp 5-10C |
| Print breaks mid-way | Adhesion problem | Add brim; check bed level |
2. Bambu Studio (Bambu Lab)
Overview
- Developer: Bambu Lab (printer manufacturer)
- Platforms: Windows, Mac, Linux
- Best For: Modern X1-series printers, excellent speed, AMS support
- Download: https://bambulab.com/en/download/studio
- Accessibility: Good contrast, keyboard navigation
Quick Setup
Step 1: Create Account & Connect Printer
- Launch Bambu Studio
- Sign in with Bambu Lab account
- Select printer from network
- Studio auto-detects printer settings
Step 2: Load Model & Configure
- Drag STL into workspace
- Auto-arranges on bed plate
- Default profile applied automatically
Step 3: Key Settings (Bambu-Specific)
| Setting | Default | Adjustment | Why |
|---|---|---|---|
| AMS Multi-Color | Off | On (if AMS attached) | Auto-switch filament |
| Auto-Leveling | Enabled | Keep On | Bambu feature-very reliable |
| Nozzle Temp | 220C | Keep unless specified | Bambu-optimized |
| Layer Height | 0.2mm | 0.15mm for detail | Balance speed/quality |
| Bed Temp | 65C | 60C for PLA | Standard adhesion |
Step 4: Send to Printer
- Click “Prepare” (bottom right)
- Review preview
- Click “Send to Device”
- Printer receives over WiFi
- Start print from printer screen
Accessible Parameter Explanations
Auto-Leveling
- Bambu printers automatically level the nozzle before every print
- Explanation: Saves manual calibration; extremely reliable
- For VI users: Provides confidence that bed is properly prepared
Filament Calibration
- Before first use of new filament color, run “Filament Calibration”
- This optimizes temperature and speed for that specific filament
- Explanation: Ensures consistent color and strength
Multi-Material (AMS)
- If you have Auto Material System (AMS):
- Load up to 4 filament colors
- Studio auto-switches during print
- Explanation: Multi-color prints without manual intervention
Command-Line Usage (PowerShell)
# Slice with Bambu Studio (command-line interface)
$model = "C:\Models\bracelet_holder.stl"
$output = "C:\GCode\bracelet_holder.3mf" # Bambu uses .3mf format
# Bambu Studio CLI
& "C:\Program Files\BambuStudio\bambu-studio.exe" `
--output "$output" `
"$model"
Write-Host "Slice saved: $output"
# Send to printer directly
# (Requires API key-see Bambu documentation)
Troubleshooting
| Problem | Cause | Solution |
|---|---|---|
| WiFi not connecting | Network issue | Restart printer WiFi; check SSID |
| AMS not switching | Filament not detected | Load filament into AMS; recalibrate |
| Print quality inconsistent | Wrong filament type | Run filament calibration |
| Nozzle crashes on first layer | Auto-level failed | Manually check nozzle height |
3. Cura (Ultimaker)
Overview
- Developer: Ultimaker (Dutch company, open-source)
- Platforms: Windows, Mac, Linux
- Best For: Broad printer support, user-friendly, good documentation
- Download: https://ultimaker.com/software/ultimaker-cura
- Accessibility: Clear UI, good contrast
Quick Setup
Step 1: Add Your Printer
- Launch Cura
- Go to “Settings” (top-right)
- Click “Printers” -> “Add Printer”
- Select your printer model from list
- Confirm network connection
Step 2: Load & Prepare Model
- Drag STL into workspace
- Model auto-scales if needed (confirm size)
- Right-click -> “Support” (if overhangs need support)
Step 3: Recommended Settings
| Setting | Value | Notes |
|---|---|---|
| Profile | Standard | Good balance for most prints |
| Layer Height | 0.2mm | Default; change to 0.15mm for detail |
| Infill | 20% | 100% waste for solid parts |
| Support Angle | 50 | Auto-generates support for overhangs |
| Build Plate Adhesion | Brim | Helps first layer stick |
| Nozzle Temp | 200C | Standard PLA |
| Bed Temp | 60C | Standard PLA |
Step 4: Print
- Click “Slice” (bottom right)
- Review layer-by-layer preview
- Click “Print Over Network” or “Print to File”
- Model sends to printer or saves as .gcode
Accessible Settings Explanation
Combing Mode
- Off: Nozzle retracts on every travel (quality)
- All: Never retracts (faster, possible stringing)
- Not in Skin: Smart compromise
- For VI users: Retraction prevents nozzle oozing on visible surfaces
Z-Offset (Z Clearance)
- Adjusts first-layer distance
- Too low -> nozzle scrapes bed (bad)
- Too high -> filament doesn’t stick (bad)
- Correct -> thin line of plastic sticks to bed
Gradual Infill
- Automatically reduces infill strength away from surface
- Saves filament while maintaining strength
- Explanation: The core doesn’t need to be solid
Command-Line Usage (PowerShell)
# Cura engine CLI (CuraEngine)
$model = "C:\Models\bracelet_holder.stl"
$output = "C:\GCode\bracelet_holder.gcode"
$config = "default.cfg"
# Requires Cura to be installed; command-line slicing
& "C:\Program Files\Ultimaker Cura\CuraEngine.exe" `
-c "$config" `
-o "$output" `
"$model"
Write-Host "Sliced: $output"
Troubleshooting
| Problem | Cause | Solution |
|---|---|---|
| Model appears too small on bed | Scale wrong | Right-click -> Scale to fit |
| Stringing between parts | Retraction disabled | Enable retraction in settings |
| Support doesn’t generate | Auto-support off | Enable “Generate Support” |
| Printer not found | Network/USB issue | Check connection; restart Cura |
4. SuperSlicer (Modification of Prusa)
Overview
- Developer: Community fork of PrusaSlicer
- Platforms: Windows, Mac, Linux
- Best For: Advanced users wanting more control than Prusa offers
- Download: https://github.com/supermerill/SuperSlicer
- Accessibility: Similar to Prusa, more advanced options
Key Differences from Prusa
| Feature | PrusaSlicer | SuperSlicer |
|---|---|---|
| Arachne Engine | No | Yes-better edges |
| Seam Position | Limited options | Full control |
| Pressure Equalization | No | Yes-better bridging |
| Stealth Mode | No | Yes-quieter/higher quality |
When to Use SuperSlicer
- Printing challenging geometries with tight tolerances
- Need advanced surface finish control
- Familiar with PrusaSlicer already and want more power
Quick Start
- Download SuperSlicer from GitHub
- Export profile from PrusaSlicer (if you have it)
- Import into SuperSlicer
- All settings are compatible with PrusaSlicer
Advanced Settings for SuperSlicer
Arachne Engine
- Enables finer edges on walls
- Results in cleaner, more accurate prints
- Takes slightly longer to slice but worth it
Seam Positioning
- Random: Hides seams (good for aesthetic)
- Aligned: Consistent location (good for debugging)
- Rear: Always at back (recommended)
Pressure Equalization
- Helps with bridging (printing across gaps)
- Reduces sagging on overhangs
- Recommended: Enable for complex designs
5. OrcaSlicer (Modern Bamboo Alternative)
Overview
- Developer: Community (independent open-source)
- Platforms: Windows, Mac, Linux
- Best For: Users who want Bambu features without Bambu printer
- Download: https://github.com/SoftFever/OrcaSlicer
- Accessibility: Modern UI, good keyboard support
Why Orca?
OrcaSlicer brings Bambu Studio’s best features to any printer:
- Excellent defaults
- Fast slicing
- Good preview
- Modern interface
Quick Setup
- Download OrcaSlicer
- Select your printer (not just Bambu models)
- Load STL
- Uses good defaults-usually ready to print
Key Settings
| Setting | Value | Why |
|---|---|---|
| Wall Loops | 2 | Strong walls, visible detail |
| Internal Solid Layer | 4 | Strength for brackets/connectors |
| Infill Pattern | Grid | Balanced strength |
| Line Width | Auto | Matches nozzle diameter |
| Speed | 80 mm/s | Balanced quality/speed |
Accessible Features
Filament Manager
- Track filament type, color, weight used
- Explanation: Know when to buy new filament
Print Time Estimation
- Accurate prediction of print duration
- Updates during slicing
Material Presets
- Pre-configured settings for common filaments
- Just select material type; settings auto-apply
6. IdeaMaker (Raise3D)
Overview
- Developer: Raise3D
- Platforms: Windows, Mac, Linux
- Best For: Raise3D printer users; advanced features
- Download: https://www.raise3d.com/ideamaker
- Accessibility: Professional UI, detailed settings
When to Use
- Using a Raise3D printer (excellent multi-nozzle support)
- Need industrial-strength slicing
- Want dual-extrusion (2-color) printing
Quick Start
- Launch IdeaMaker
- Add printer (Raise3D models have built-in profiles)
- Load STL
- Adjust layer height and infill
- Slice and send to printer
Key Features
Dual Extrusion
- Two nozzles = two colors in one print
- Useful for: Bracelets (core + colored rim)
- Requires: Coordinating two materials
Advanced Support
- Tree support (uses less material)
- Grid support (stronger for larger parts)
Print Balancing
- Optimizes nozzle movement for efficiency
- Reduces print time without sacrificing quality
7. Fusion 360 (CAD + Slicer)
Overview
- Developer: Autodesk
- Platforms: Windows, Mac
- Best For: If you already use Fusion 360 for CAD
- Download: https://www.autodesk.com/products/fusion-360
- Accessibility: Integrated environment; good for learning CAD+Slicing together
Why Integrate CAD + Slicing?
Traditional workflow:
Design in CAD -> Export to STL -> Open in Slicer -> Slice -> Print
Fusion 360 workflow:
Design in Fusion -> Run Print Preparation -> Slice -> Print
Advantage: Stay in one program; no format conversion
Quick Start
- Design in Fusion 360 (or import STL)
- Select part
- Go to “3D Print” tab
- Click “Print Preparation”
- View auto-generated support and alignment
- Adjust layer height, infill, etc.
- Slice and export G-code
Integration with 3dMake
If using Fusion 360 for CAD:
- Export SCAD design to STL
- 3dm export-stl src/main.scad output/main.stl
- Then import into Fusion 360
- For more complex designs that need refinement
Universal Troubleshooting Guide
| Problem | Diagnosis | Solution |
|---|---|---|
| Print won’t stick to bed | Bed temperature too low | Raise bed temp +5C; check bed level |
| Bed not level | Manual leveling procedure (printer manual) | |
| Build plate dirty | Clean with isopropyl alcohol | |
| Nozzle hits model mid-print | Z-offset wrong | Adjust Z-offset; re-level bed |
| Model placed too low on bed | Use “Arrange on Bed” tool in slicer | |
| Supports won’t remove | Too much support generated | Reduce support density or angle |
| Support too strong | Reduce support material percentage | |
| Stringy/Oozing | Nozzle too hot | Reduce temp by 5-10C |
| Retraction disabled | Enable retraction in settings | |
| Travel speed too fast | Reduce travel speed | |
| Layer shifting (X/Y) | Belt tension off | Check belt tension (printer manual) |
| Stepper motor power issue | Firmware issue-check printer logs | |
| Model prints poorly but slices look good | Filament quality issue | Try different filament batch |
| Nozzle clogged | Unclog nozzle (heat -> purge -> clean) |
Recommended Slicer for Each Situation
| Scenario | Best Slicer | Why |
|---|---|---|
| I’m a beginner | PrusaSlicer | Clear defaults, excellent UI |
| I have a Bambu printer | Bambu Studio | Native, best features |
| I have an Ultimaker | Cura | Official support, broad compatibility |
| I have a Raise3D | IdeaMaker | Official, dual-extrusion support |
| I want advanced control | SuperSlicer | Maximum customization |
| I want modern/fast slicing | OrcaSlicer | Great defaults, any printer |
| I use Fusion 360 for CAD | Fusion 360 Print Prep | Integrated workflow |
PowerShell Integration: Batch Slicing
Slice Multiple Files Automatically
# Batch slice all SCAD designs in a project
$scadDir = "C:\Projects\3dMake\src"
$slicerConfig = "default.cfg"
$outputDir = "C:\Projects\3dMake\gcode"
# Find all SCAD files
$scadFiles = Get-ChildItem -Path $scadDir -Filter "*.scad" -Recurse
foreach ($scadFile in $scadFiles) {
$stlFile = $scadFile.FullName -replace ".scad$", ".stl"
$gcodeFile = Join-Path $outputDir ($scadFile.BaseName + ".gcode")
# Export SCAD to STL
Write-Host "Exporting: $($scadFile.Name)"
& "C:\Program Files\OpenSCAD\openscad.exe" -o "$stlFile" "$($scadFile.FullName)"
# Slice STL
Write-Host "Slicing: $($scadFile.Name)"
& "C:\Program Files\Prusa3D\PrusaSlicer\prusa-slicer.exe" `
--load-config-file "$slicerConfig" `
--export-gcode "$gcodeFile" `
"$stlFile"
Write-Host "Complete: $gcodeFile"
}
Write-Host "Batch slicing finished."
Monitor Printing Progress
# Connect to printer API and monitor print status
# (Requires printer to support API-check documentation)
$printerIP = "192.168.1.100" # Your printer's IP
$printerPort = 8080 # Typical API port
# Get current print status
$status = Invoke-WebRequest -Uri "https://yourdolphin.com/supernova/" `
-UseBasicParsing | ConvertFrom-Json
Write-Host "State: $($status.state.text)"
Write-Host "Progress: $($status.progress.completion)%"
Write-Host "Time remaining: $($status.progress.printTimeLeft) seconds"
Accessibility Best Practices for Slicing
Describing Sliced Models
# Use 3dm info to understand the slicer's output
# (Best practice: describe after slicing to verify settings)
3dm info output/bracelet_holder.stl
# Output includes:
# - Number of parts
# - Dimensions
# - Surface area
# - Volume
Testing Sliced Parts
-
Weight Check:
- Calculate expected weight from volume + material density
- Compare to actual printed weight
- Indicates if infill is correct
-
Dimensional Check:
- Use calipers to verify critical dimensions
- Compare to SCAD parameters
- Check tolerance stack-up
-
Functional Test:
- Assemble with other parts
- Test strength by loading with known weight
- Verify support removal didn’t damage part
Summary
This appendix provides:
- [YES] 7 slicer workflows, settings, and troubleshooting
- [YES] Accessible parameter explanations
- [YES] Command-line integration for PowerShell
- [YES] Comparison table for choosing a slicer
- [YES] Batch processing automation examples
- [YES] Accessibility best practices
Use this guide whenever you:
- Start a new print
- Switch slicers
- Encounter quality issues
- Want to automate slicing workflows
- Need troubleshooting help
Appendix C: Material Properties and Selection Guide
This appendix covers material properties, characteristics, and selection criteria for 3D printing filaments. Each material includes:
- Physical properties (strength, flexibility, temperature tolerance)
- Printing parameters (nozzle temp, bed temp, speed)
- Suitability for different projects
- Accessibility considerations (measurement-based verification)
- Cost/availability comparison
Referenced in: Lessons 5 (Safety), 6-10 (Projects), 11 (Customer Requirements)
Overview: Why Material Matters
The material you choose affects:
- Strength: Can the part hold weight?
- Flexibility: Will it bend or break?
- Temperature: Can it withstand heat?
- Durability: Will it last months or years?
- Cost: Budget constraints?
- Printability: Ease of use for beginners?
- Appearance: Texture, color, finish?
The Material Selection Flowchart
What's the primary requirement?
+-- Strength & Detail?
+-- PLA (best for beginners, detail)
or PETG (stronger, tougher)
+-- Flexibility?
+-- TPU/TPE (rubber-like)
+-- Heat Resistance?
+-- ABS or Polycarbonate
+-- Transparency?
+-- PETG or Polycarbonate
+-- Food Contact?
+-- FDA-approved PETG or PLA
+-- Cost-Conscious?
+-- PLA (cheapest, easiest)
1. PLA (Polylactic Acid)
Properties at a Glance
| Property | Rating | Notes |
|---|---|---|
| Strength | [3/5] | Good for most projects; not for dynamic loads |
| Flexibility | [1/5] | Brittle; will snap under stress |
| Temperature Resistance | [2/5] | Softens around 60C; bad for hot environments |
| Ease of Printing | [5/5] | Most forgiving; best for beginners |
| Cost | [5/5] | Cheapest option (~$20/kg) |
| Appearance | [5/5] | Excellent surface finish; many colors |
| Availability | [5/5] | Available everywhere |
Ideal Projects
- [YES] Decorative pieces (jewelry, miniatures)
- [YES] Enclosures/shells (light loads)
- [YES] Prototype/mockups
- [YES] Low-stress connector clips
- [YES] Educational demonstrations
- [NO] Load-bearing brackets
- [NO] Hinges or flexing parts
- [NO] Heat-resistant applications
Printing Parameters
| Parameter | Value | Tolerance |
|---|---|---|
| Nozzle Temp | 200C | 190-210C (varies by brand) |
| Bed Temp | 60C | 50-65C |
| Print Speed | 50 mm/s | 40-60 mm/s |
| Retraction | 5mm @ 40 mm/s | Yes, prevents stringing |
| Cooling Fan | 100% | High cooling improves quality |
| First Layer | Slower (25 mm/s) | Ensures adhesion |
| Layer Height | 0.2mm | 0.1-0.3mm depending on detail |
PLA Variants
Standard PLA
- Most common, reliable
- Best for beginners
PLA Pro / Enhanced PLA
- Slightly stronger than standard PLA
- Same temperature parameters
- ~10% cost premium
Silk PLA
- Glossy finish instead of matte
- Same strength as standard PLA
- Slightly slower to print
Marble or Color-Changing PLA
- Visual effects
- Same printing parameters
- Mostly for aesthetics
Common Issues & Solutions
| Problem | Cause | Solution |
|---|---|---|
| Warping on corners | Bed too hot or cooling too fast | Reduce bed temp to 50C; disable cooling for first layer |
| Stringing | Temp too high | Lower nozzle temp 5C |
| Poor layer adhesion | Nozzle too high | Lower Z-offset 0.1mm |
| Brittleness after print | Normal for PLA | Not a problem; expected behavior |
| Nozzle clogs on retraction | Temperature inconsistency | Ensure stable nozzle temp +/- 5C |
Why PLA for This Course
PLA is recommended for all Lessons 1-11 because:
- Beginner-friendly: Most forgiving material
- Predictable: Consistent across different printers
- Cost-effective: Maximize printing volume on student budget
- Accessibility: Easier to troubleshoot for new users
- Safe: Non-toxic, low fume emission
- Available: Found at any 3D printing supplier
2. PETG (Polyethylene Terephthalate Glycol)
Properties at a Glance
| Property | Rating | Notes |
|---|---|---|
| Strength | [4/5] | Tougher than PLA; better for load-bearing |
| Flexibility | [2/5] | Better than PLA but still primarily rigid |
| Temperature Resistance | [3/5] | Softens around 85C; better than PLA |
| Ease of Printing | [4/5] | Slightly more challenging than PLA |
| Cost | [4/5] | ~$25/kg (slightly more than PLA) |
| Appearance | [4/5] | Good surface finish; slightly glossier than PLA |
| Availability | [5/5] | Widely available |
When to Use PETG Instead of PLA
- Functional brackets or mounts (where strength matters)
- Parts that may be load-bearing (shelves, holders)
- Outdoors/higher temperature environments
- Parts requiring transparency (clear PETG available)
- Better moisture resistance (vs. PLA)
Printing Parameters
| Parameter | Value | Tolerance |
|---|---|---|
| Nozzle Temp | 235C | 230-245C |
| Bed Temp | 80C | 75-85C |
| Print Speed | 50 mm/s | 40-60 mm/s (same as PLA) |
| Retraction | 4mm @ 40 mm/s | Slightly less than PLA |
| Cooling Fan | 30-50% | Less cooling than PLA |
| First Layer | Normal (50 mm/s) | Harder to adjust than PLA |
| Layer Height | 0.2mm | 0.1-0.3mm |
Comparison: PETG vs. PLA
| Aspect | PLA | PETG |
|---|---|---|
| Nozzle Temp | 200C | 235C |
| Bed Temp | 60C | 80C |
| Strength | Good | Better (20% stronger) |
| Flexibility | Brittle | More resilient |
| Heat Tolerance | 60C | 85C |
| Ease | Very easy | Easy (needs tweaking) |
| Cost | $20/kg | $25/kg |
| Outdoor Use | Not ideal | Better |
Projects for PETG
- [YES] Phone stand (needs strength)
- [YES] Bracket or shelf support
- [YES] Flexible clip (needs resilience)
- [YES] Outdoor item
- [YES] Clear enclosure (if using clear PETG)
- [NO] Fine detail work (slightly courser finish)
- [NO] Food-contact items (not food-safe unless specified)
3. ABS (Acrylonitrile Butadiene Styrene)
Properties at a Glance
| Property | Rating | Notes |
|---|---|---|
| Strength | [4/5] | Similar to PETG; good impact resistance |
| Flexibility | [3/5] | More flexible than PETG |
| Temperature Resistance | [5/5] | Softens around 105C; best of common materials |
| Ease of Printing | [2/5] | Requires enclosure/heated bed; challenging |
| Cost | [4/5] | ~$25-30/kg |
| Appearance | [3/5] | Rougher than PLA; requires post-processing |
| Availability | [4/5] | Good availability; not as universal as PLA |
When to Use ABS
- High-temperature environments (near heat sources)
- Mechanical parts (gears, bearings)
- Durability (parts lasting years)
- Post-processing (can be sanded, glued, vapor-smoothed)
- Professional applications (not toys/decorative)
Why ABS is Challenging
ABS requires:
- Enclosed environment: Minimize temperature fluctuations
- Heated bed: 100C+ (much higher than PLA)
- Controlled cooling: Too-fast cooling causes warping
- Ventilation: ABS emits fumes (acetone-like smell)
Printing Parameters
| Parameter | Value | Tolerance |
|---|---|---|
| Nozzle Temp | 240C | 230-250C |
| Bed Temp | 100C | 95-105C |
| Enclosure | Required | Maintains heat (reduces warping) |
| Print Speed | 40 mm/s | Slower than PLA |
| Retraction | 3mm @ 30 mm/s | Very short |
| Cooling Fan | 0% | OFF (causes warping) |
| First Layer | Slow (30 mm/s) | Critical for adhesion |
Projects for ABS
- [YES] Mechanical components
- [YES] Heat-resistant enclosure
- [YES] Durable outdoor item
- [YES] Professional prototypes
- [NO] Beginner projects (too challenging)
- [NO] Decorative/aesthetic work (not recommended)
- [NO] Flexible parts
Accessibility Note
ABS is not recommended for this course because:
- Requires enclosed printer (expensive for beginners)
- High failure rate for inexperienced users
- Strong odor (ventilation concerns for some users)
- Requires extra equipment (acetone for post-processing)
4. TPU / TPE (Thermoplastic Polyurethane / Elastomer)
Properties at a Glance
| Property | Rating | Notes |
|---|---|---|
| Strength | [3/5] | Good; impact-resistant |
| Flexibility | [5/5] | Very flexible; rubber-like |
| Temperature Resistance | [3/5] | Softens around 80C; moderate |
| Ease of Printing | [3/5] | Needs tweaking; flexible materials are tricky |
| Cost | [3/5] | ~$30-40/kg (expensive) |
| Appearance | [4/5] | Smooth; feels good tactilely |
| Availability | [4/5] | Growing availability |
What is TPU?
TPU is a flexible rubber-like plastic that:
- Doesn’t crack when bent
- Absorbs impact
- Returns to original shape
- Bridges the gap between plastic and rubber
Printing Parameters
| Parameter | Value | Tolerance |
|---|---|---|
| Nozzle Temp | 215C | 210-225C |
| Bed Temp | 60C | 50-70C |
| Print Speed | 20-30 mm/s | VERY SLOW (flexibility needs time) |
| Retraction | Minimal or Off | 0-1mm (flexible material doesn’t retract well) |
| Cooling Fan | 0% | Off (material needs heat) |
| Line Width | 0.5mm | Wider than normal (flexible material bridges) |
Projects for TPU
- [YES] Phone case (needs flexibility + protection)
- [YES] Flex joints / hinges
- [YES] Gasket or seal
- [YES] Shoe insert or orthotic
- [YES] Tactile button (for accessibility)
- [NO] Fine detail work (too stretchy)
- [NO] Decorative items (usually not aesthetic)
- [NO] Precision parts
Challenges with TPU
- Very slow printing: 5-10x slower than PLA
- Stringing: Flexible material tends to ooze
- Flexible bed needed: Standard beds may not work
- Post-processing difficult: Hard to sand/glue
Why TPU for Accessibility
TPU is excellent for accessibility because:
- Can create tactile buttons/indicators
- Flexible grips for ergonomic handles
- Gaskets that don’t damage delicate equipment
- Accessible because: Achievable by all users if given proper guidance
5. Polycarbonate (PC)
Properties at a Glance
| Property | Rating | Notes |
|---|---|---|
| Strength | [5/5] | Extremely strong; impact-resistant |
| Flexibility | [2/5] | Rigid; similar to PETG |
| Temperature Resistance | [5/5] | Best; softens around 130C |
| Ease of Printing | [2/5] | Difficult; prone to warping |
| Cost | [2/5] | Most expensive (~$50+/kg) |
| Appearance | [4/5] | Transparent/translucent options |
| Availability | [2/5] | Limited; specialty supply |
When to Use Polycarbonate
- Highest strength required
- Transparent/bullet-proof enclosure needed
- Extreme temperature environment
- Professional/industrial applications
Why Polycarbonate is Not for This Course
- Extreme difficulty (high failure rate)
- Very expensive (3-5x cost of PLA)
- Requires industrial-grade printer
- Post-processing complex
6. Nylon (PA)
Properties at a Glance
| Property | Rating | Notes |
|---|---|---|
| Strength | [5/5] | Very strong; can be flexible |
| Flexibility | [4/5] | More flexible than ABS |
| Temperature Resistance | [4/5] | Good; softens around 120C |
| Ease of Printing | [2/5] | Difficult; very temperature-sensitive |
| Cost | [3/5] | ~$30-40/kg |
| Appearance | [3/5] | Matte finish; less aesthetic than PLA |
| Availability | [3/5] | Growing but limited |
Nylon Use Cases
- [YES] Mechanical parts (gears, hinges)
- [YES] Flexible connectors
- [YES] Threads/screws
- [YES] High-stress applications
- [NO] Not for beginners
Material Comparison Table
| Material | Nozzle | Bed | Strength | Flexibility | Heat | Ease | Cost | Best For |
|---|---|---|---|---|---|---|---|---|
| PLA | 200C | 60C | [3/5] | [1/5] | [2/5] | [5/5] | $ | Beginners, detail |
| PETG | 235C | 80C | [4/5] | [2/5] | [3/5] | [4/5] | $$ | Functional parts |
| ABS | 240C | 100C | [4/5] | [3/5] | [5/5] | [2/5] | $$ | High-temp/mechanical |
| TPU | 215C | 60C | [3/5] | [5/5] | [3/5] | [3/5] | $$$ | Flexibility/tactile |
| PC | 280C | 110C | [5/5] | [2/5] | [5/5] | [1/5] | $$$$ | Extreme strength |
| Nylon | 250C | 85C | [5/5] | [4/5] | [4/5] | [2/5] | $$$ | Mechanical/flexible |
Filament Quality Factors
Why Not All PLA is the Same
Diameter Tolerance
- Good filament: +/- 0.03mm
- Poor filament: +/- 0.1mm or worse
- Impact: Inconsistent extrusion, layer quality varies
Dryness
- PLA absorbs moisture from air
- Wet filament = weak prints + bubbles
- Solution: Store in sealed container with desiccant
Color Consistency
- Good brands: Same color throughout
- Poor brands: Color varies spool-to-spool
Impurities
- Good: Minimal impurities
- Poor: Visible specs/contaminants -> possible clogs
How to Check Filament Quality (Non-Visually)
-
Weight Check
Known: 1kg spool Weigh spool + filament Calculate remaining filament Should match spool markings -
Diameter Check
Use caliper to measure multiple points Should be consistent +/- 0.03mm If varying, likely lower quality -
Dryness Test
Feel texture: Should be smooth, not tacky Smell: Should be neutral (not musty) If wet, store in sealed container with desiccant -
Print Test
Print small cube (20mm x 20mm x 20mm) Inspect surface: Smooth or bubbly? Weight: Does it match expected weight?
Storage & Maintenance
Proper Filament Storage
Temperature
- Store between 15-25C
- Avoid direct sunlight (fades color, degrades material)
Humidity
- Keep below 40% humidity
- Use desiccant packets in sealed containers
- Change desiccant every 2-3 months
Organization
- Label spools with: Material, color, date opened, approx. remaining
- Store vertically or on spindle (prevents kinking)
Filament Degradation Signs
| Sign | Cause | Solution |
|---|---|---|
| Weak prints / breaking easily | Filament aged or wet | Replace with fresh filament |
| Discoloration or spots | Oxidation or contamination | Not usable; discard safely |
| Brittle or crumbly | Overheated or UV damage | Not usable; discard |
| Slight fading (color) | UV exposure | Still usable; just faded |
Cost Analysis
Cost per Project
Material cost = (Filament weight used) x (Cost per kg)
Example: Bracelet holder
- Weight: 25 grams
- Material: PLA at $20/kg
- Cost: (25g / 1000g) x $20 = $0.50
vs. PETG at $25/kg: $0.625
vs. ABS at $30/kg: $0.75
Budget Tips
- Buy bulk: 5kg spool is cheaper per gram than 1kg
- Buy sales: 30-40% discounts common during sales
- Brand matters: Premium brands slightly more but more reliable
- Generic brands: Often acceptable if reviews are good
Recommended Brands (Ranked by Beginner-Friendliness)
| Rank | Brand | Known For | Cost | Notes |
|---|---|---|---|---|
| 1 | Prusament | Reliability, Prusa compatibility | $$$ | Best; excellent support |
| 2 | MatterHackers | Quality, variety | $$ | Very good; educational focus |
| 3 | Fillamentum | European quality | $$ | Excellent; eco-friendly |
| 4 | Overture | Value, consistency | $ | Good budget option |
| 5 | eSUN | Variety, affordable | $ | Decent; variable quality |
Material Selection Decision Tree
START HERE: What's most important?
GOAL: Beginner success?
YES - PLA (best choice)
NO - Next question
GOAL: Strength matters?
YES - PETG or Nylon
NO - Next question
GOAL: Flexibility needed?
YES - TPU (rubber-like)
NO - Next question
GOAL: High temperature?
YES - ABS or Polycarbonate
NO - Next question
GOAL: Transparent?
YES - Clear PETG or Polycarbonate
NO - Use PLA
FINAL CHOICE:
- If unsure, use PLA
- If needs strength, use PETG
- If needs flexibility, use TPU
- If needs heat, use ABS
PowerShell Integration: Track Material Usage
# Track filament usage across all projects
$materialLog = @"
ProjectName,Material,ColorName,WeightUsed(g),DatePrinted,Notes
"@
# Example entries
$materialLog += "`nBraceletHolder,PLA,NaturalWhite,25.3,2024-01-15,Final design"
$materialLog += "`nPhoneStand,PETG,Black,47.2,2024-01-16,Needs strength"
$materialLog += "`nKeycap,PLA,Red,12.5,2024-01-17,Prototype"
# Save to CSV
$materialLog | Out-File "C:\Projects\material-log.csv"
# Analyze usage
$materials = Import-Csv "C:\Projects\material-log.csv"
$totalWeight = ($materials | Measure-Object -Property "WeightUsed(g)" -Sum).Sum
$avgWeight = ($materials | Measure-Object -Property "WeightUsed(g)" -Average).Average
Write-Host "Total weight used: $totalWeight grams"
Write-Host "Average per project: $avgWeight grams"
# Calculate cost (PLA at $20/kg)
$costPerKg = 20
$totalCost = ($totalWeight / 1000) * $costPerKm
Write-Host "Estimated cost: $$($totalCost.ToString("F2"))"
Summary
Key Takeaways:
- Start with PLA: Best for learning; most forgiving
- Understand the tradeoffs: Strength vs. ease, cost vs. quality
- Match material to project: Decorative = PLA; functional = PETG
- Store properly: Desiccant, cool, dark location
- Track usage: Know what works for future projects
- Test before committing: Print small test on new filament
Recommended Progression:
- Lessons 6-7: PLA (simplest)
- Lessons 8-9: PLA or PETG (functional parts)
- Lesson 10: PETG or TPU (testing materials)
- Lesson 11: Student choice (depends on stakeholder requirements)
Appendix D: Tolerance Testing and Quality Assurance Matrix
This appendix provides measurement-based testing methodology for verifying that 3D-printed parts meet design specifications. It’s designed to be used non-visually-focusing on calipers, scales, and functional tests rather than visual inspection.
Referenced in: Lessons 8-10 (Complex Design, Troubleshooting, Mastery)
Overview: What is Tolerance?
Tolerance is the acceptable range of variation in dimensions:
Design spec: Hole diameter = 6mm
Tolerance: +/-0.5mm
Acceptable range: 5.5mm to 6.5mm
Actual print: 5.8mm [YES] (within tolerance)
or 7.2mm [NO] (exceeds tolerance)
Why Tolerance Matters
- Assembly: Parts must fit together
- Function: Fit too tight = stuck; too loose = falls apart
- Safety: Wrong tolerance = part failure
- Cost: Tight tolerance = slower, more waste
Essential Measurement Tools
1. Digital Calipers
What they measure:
- Outside diameter (part width)
- Inside diameter (hole width)
- Depth
How to use non-visually:
- Gently close calipers until they barely touch the part
- Feel the resistance (should be light, not forced)
- Read digital display with audio feedback or manually
- Record three measurements at different locations
- Average the three measurements
Accuracy: +/-0.05mm (very precise for 3D printing)
2. Digital Scale (Kitchen Scale)
What it measures:
- Part weight (indicates infill, material type)
How to use non-visually:
- Place part on scale
- Wait for reading to stabilize (1-2 seconds)
- Read digital display (in grams)
- Compare to expected weight
Accuracy: +/-1g (good enough for verification)
Why it matters:
- Too light = infill too low or void inside part
- Expected weight = indicates proper slicing
3. Test Jig / Go/No-Go Gauge
What it measures:
- Pass/fail tolerance testing without calipers
How to make:
// Go/No-Go gauge for bracelet peg holes
// Tests if hole is within acceptable range
pegdiameter = 6; // Design spec
tolerance = 0.5; // Tolerance
godiameter = pegdiameter - tolerance; // Min acceptable (5.5)
nogodiameter = pegdiameter + tolerance; // Max acceptable (6.5)
module gogauge() {
// Part should fit through this easily
cylinder(h=10, r=godiameter/2);
}
module nogogauge() {
// Part should NOT fit through this
cylinder(h=10, r=nogodiameter/2);
}
// Test jig with both gauges
union() {
translate([0, 0, 0]) gogauge();
translate([0, 15, 0]) nogogauge();
}
Use non-visually:
- Try inserting peg into go-gauge -> Should slide easily
- Try inserting peg into no-go-gauge -> Should NOT fit
- If both tests pass = tolerance correct
Quality Assurance Testing Matrix
Critical Dimensions to Test
Create a Test Plan before printing:
| Part | Dimension | Spec | Tolerance | How to Test |
|---|---|---|---|---|
| Bracelet Holder | Base width | 127mm | +/-2mm | Measure with calipers (multiple points) |
| Peg diameter | 6mm | +/-0.5mm | Test fit with go/no-go gauge | |
| Peg spacing | 8mm | +/-1mm | Measure distance between pegs | |
| Back wall height | 120mm | +/-2mm | Measure with calipers | |
| Phone Stand | Slope angle | 20 | +/-3 | Calculate from height/depth ratio |
| Weight capacity | 200g | 150-250g | Load test (see below) | |
| Stability | N/A | Pass/fail | 1-hour load test without tipping |
Pre-Print Planning
Before slicing, define:
- Critical dimensions: Which measurements matter most?
- Acceptable range: What tolerance is realistic?
- Test method: How will you verify?
- Pass/fail criteria: What does “success” look like?
Example Plan for Phone Stand:
# Phone Stand - Quality Assurance Plan
## Critical Dimensions
1. Slope angle: 20 +/-3
2. Base width: 80mm +/-1mm
3. Stand height: 60mm +/-2mm
## Functional Tests
1. Stability: Hold 200g for 1 hour without tipping
2. Grip: Phone doesn't slide during tilt
3. Assembly: Back brace attaches without force
## Pass/Fail Criteria
[YES] PASS if:
- All dimensions within tolerance
- Phone holds weight for 1 hour
- No cracks or layer separation
[NO] FAIL if:
- Any dimension >2mm off spec
- Phone slides or part tips
- Visible cracks
Measurement Procedures
Procedure 1: Linear Dimension (Width, Height, Depth)
Equipment needed: Digital calipers
Steps:
- Place part on flat surface
- Position caliper jaws perpendicular to surface
- Gently close jaws until they just touch part
- Feel for light resistance (not forced)
- Read digital display
- Record measurement
- Repeat at 3 different locations
- Average the three readings
- Compare to design spec +/- tolerance
Example:
Design spec: 127mm (bracelet holder width)
Tolerance: +/-2mm (acceptable: 125-129mm)
Measurements:
Location 1: 126.8mm
Location 2: 127.1mm
Location 3: 126.5mm
Average: 126.8mm [YES] (within tolerance)
Procedure 2: Hole or Peg Diameter
Equipment needed: Digital calipers, Go/No-Go gauges (optional)
Method A: Direct Measurement
- Insert caliper jaws into hole/around peg
- Adjust jaws to gently touch surfaces
- Feel for light resistance on both sides
- Read digital display (inside measurement mode)
- Record three measurements
- Average the readings
Method B: Go/No-Go Gauge
- Print test jigs (go & no-go gauges)
- Attempt to insert peg/hole into go-gauge -> Should slide through easily with light resistance
- Attempt to insert peg/hole into no-go-gauge -> Should NOT fit or fit with visible resistance
- If both pass -> dimension is acceptable
Example: Peg Diameter
Design spec: 6.0mm Tolerance: +/-0.5mm (acceptable: 5.5-6.5mm) Method A (Direct): Measurement 1: 5.9mm Measurement 2: 6.0mm Measurement 3: 5.8mm Average: 5.9mm [YES] Method B (Go/No-Go): Slides through go-gauge (5.5mm) -> [YES] Doesn’t fit no-go-gauge (6.5mm) -> [YES] Result: PASS
Procedure 3: Surface Finish / Layer Quality
Equipment needed: Caliper, ruler, touch/texture assessment
Step 1: Surface Texture
Run fingers/hand over surface: [YES] Smooth -> Good quality Slightly rough -> Acceptable [NO] Very rough/bumpy -> Quality issue
Step 2: Layer Line Visibility
Feel horizontal ridges (layer lines): [YES] Barely perceptible -> Good (0.2mm layers) Noticeable but even -> OK (0.25mm layers) [NO] Very pronounced -> Quality issue
Step 3: Dimensional Consistency
Measure thickness at multiple points:
Design spec: 3mm wall thickness
Measure at 5 locations
Record all measurements
All should be within +/-0.2mm of each other
Example:
Pt 1: 3.0mm
Pt 2: 3.1mm
Pt 3: 3.0mm
Pt 4: 2.9mm
Pt 5: 3.1mm
Std Dev: 0.08mm [YES] (very consistent)
Procedure 4: Weight Verification (Confirms Infill)
Equipment needed: Digital scale
Step 1: Calculate Expected Weight
Expected weight = Volume x Density x Infill% For bracelet holder (PLA): Volume = 127mm x 80mm x 120mm = 1,219,200 mm = 1,219.2 cm PLA density = 1.24 g/cm Infill = 20% Expected weight = 1,219.2 x 1.24 x 0.20 = 302.4g Acceptable range: 290-315g (+/-5%)
Step 2: Measure Actual Weight
- Place part on digital scale
- Wait for reading to stabilize (1-2 seconds)
- Read display in grams
- Compare to expected weight
Step 3: Interpret Result
| Actual Weight | Interpretation |
|---|---|
| 290-315g | [YES] Correct infill, no internal voids |
| <280g | Infill too low or significant voids |
| >320g | Infill too high (was it supposed to be 20%?) |
Functional Testing
Test 1: Load Testing (Strength)
Purpose: Verify part can hold weight without failure
Equipment needed:
- Digital scale
- Test weights (or books, water jugs)
- Calipers (to check for deflection)
Procedure:
- Measure baseline dimensions (part unloaded) Baseline height: 60mm
- Place test weight on part Added weight: 200g
- Wait 5 minutes (allow part to settle)
- Measure dimensions again New height: 59.8mm Deflection: 0.2mm (acceptable)
- Observe for cracks (visual or tactile) No cracks: [YES]
- Remove weight and wait 5 minutes
- Measure dimensions again (should return to baseline) Height after unload: 60.0mm Recovery: Complete [YES] Result: PASS (part handles load without permanent deformation)
Acceptance Criteria for Phone Stand:
[YES] PASS if:
- Deflection <0.5mm under 200g load
- No cracks visible/felt
- Full recovery after load removed [NO] FAIL if:
- Deflection >1mm
- Visible cracks
- Permanent deformation after unload
Test 2: Assembly Testing
Purpose: Verify parts fit together as designed
Equipment needed:
- Calipers
- Go/No-Go gauges
Procedure for Multi-Part Assembly (e.g., Stackable Bins):
Part A (Bin body) dimensions:
- Top opening: 50mm x 50mm +/-1mm
- Wall thickness: 2mm +/-0.2mm Part B (Stacking rim) dimensions:
- Base diameter: 50mm +/-0.5mm
- Should nest inside Part A Test procedure:
- Measure Part A opening: 50.1mm [YES]
- Measure Part B base: 49.8mm [YES]
- Attempt to nest Part B into Part A -> Should fit with light resistance -> Feel for smooth insertion (no catching)
- Check for rocking (part should sit stable)
- Apply 500g load (simulate stacking) -> Should hold without slipping
Test 3: Durability Testing (Repeated Use)
Purpose: Verify part doesn’t fail after repeated cycles
Example: Phone Stand Tilt Cycles
- Record baseline dimensions
- Cycle 1: Place phone, tilt to max angle, remove
- Inspect for cracks or damage
- Repeat cycle 10 times
- Measure dimensions again
- Compare to baseline: Should be <0.1mm change If no damage after 10 cycles -> Durable [YES]
Tolerance Stack-Up (Multi-Part Designs)
When multiple parts are assembled, tolerances add:
Design: Part A opening: 50mm +/-0.5mm Part B base: 50mm +/-0.5mm Worst-case fit: Part A minimum: 49.5mm Part B maximum: 50.5mm Difference: 1.0mm (VERY TIGHT or won’t fit!) Solution: Increase tolerance on Part B to +/-0.3mm Part B minimum: 49.7mm Part B maximum: 50.3mm Now fits inside Part A: 49.5-50.5mm [YES]
Tolerance Stack-Up Calculation
For N parts in assembly:
Total tolerance = (tolerance + tolerance + ... + tolerance)
Example with 3 parts (each +/-0.5mm):
Total = (0.5 + 0.5 + 0.5)
= 0.75
= 0.87mm
Common Dimensional Problems & Fixes
| Problem | Typical Cause | How to Fix | Prevent Next Time |
|---|---|---|---|
| Part too small (all dimensions off) | Scale wrong in slicer | Scale STL up in CAD or slicer | Verify scale before slicing |
| Holes too small | Compensation shrinkage | Increase hole diameter +0.5mm | Add shrinkage factor to design |
| Walls too thin | Layer squishing | Check first layer height; may need recalibration | Measure first layer thickness |
| Infill showing through (loose fill) | Infill too low | Increase infill % to 25-30% | Recalculate for part type |
| Inconsistent across print | Nozzle clogging mid-print | Clean nozzle; check filament quality | Use quality filament; monitor print |
| Z-axis dimensions off | Z-axis uncalibrated | Run Z-calibration procedure | Calibrate before critical prints |
| Dimensions change between prints | Thermal drift | Print in stable temperature | Use enclosed printer if possible |
Testing Checklist Template
Print this checklist before starting a new project:
# Quality Assurance Checklist: [Project Name]
## Design Specs
- [ ] Part A width: mm +/- mm
- [ ] Part B height: mm +/- mm
- [ ] Hole diameter: mm +/- mm
- [ ] Assembly fit tolerance: mm
## Pre-Print
- [ ] STL exported correctly
- [ ] Scale verified
- [ ] Supports configured
- [ ] Slice file reviewed
## Post-Print (Dimensional)
- [ ] Part A width measured (3 points): mm, mm, mm
- [ ] Within tolerance? YES/NO
- [ ] Part B height measured (3 points): mm, mm, mm
- [ ] Within tolerance? YES/NO
- [ ] Hole diameter measured (go/no-go): PASS/FAIL
- [ ] Part weight measured: g (expected: g +/-g)
- [ ] Within expected weight? YES/NO
## Post-Print (Functional)
- [ ] Load test (if applicable): PASS/FAIL
- [ ] Assembly test: PASS/FAIL
- [ ] Surface quality acceptable: YES/NO
- [ ] No cracks or voids: YES/NO
## Result
- [ ] ACCEPT (all tests pass)
- [ ] REWORK (minor issue, can fix)
- [ ] REJECT (major issue, reprint)
## Notes
[Space for observations]
PowerShell Integration: Track Quality Metrics
# Track print quality across multiple projects
$qualityLog = @"
ProjectName,Date,Material,PartCount,DimensionsPass,FunctionalPass,Weight(g),Notes
"@
# Log entries
$qualityLog += "`nBraceletHolder,2024-01-15,PLA,1,PASS,PASS,302.1,Perfect fit"
$qualityLog += "`nPhoneStand,2024-01-16,PETG,2,PASS,PASS,487.3,Strong joints"
$qualityLog += "`nStackableBins,2024-01-17,PLA,3,FAIL,N/A,N/A,Holes too small reprint"
# Save to CSV
$qualityLog | Out-File "C:\Projects\quality-log.csv"
# Analyze pass/fail rate
$log = Import-Csv "C:\Projects\quality-log.csv"
$passCount = ($log | Where-Object { $.DimensionsPass -eq "PASS" }).Count
$totalCount = $log.Count
$passRate = ($passCount / $totalCount) * 100
Write-Host "Print success rate: $passRate%"
# Show recent failures
Write-Host "`nRecent issues:"
$log | Where-Object { $.DimensionsPass -eq "FAIL" } | Select-Object ProjectName, Notes
Accessibility-Focused QA Best Practices
Why Measurement-Based Testing Matters
Traditional visual QA (looking at surface finish, checking dimensions by eye) is inherently inaccessible. This appendix prioritizes:
- Caliper measurements: Objective, quantifiable
- Weight verification: Numerical result
- Functional testing: Pass/fail criteria
- Go/No-Go gauges: Tactile pass/fail
- Test jigs: Can be shared/standardized
Screen Reader Integration
When documenting QA results:
[YES] GOOD: "Bracket width measured 49.8mm (spec 50+/-1mm)"
[NO] AVOID: "Bracket looks good" (not measurable)
[YES] GOOD: "Part weighs 298g (spec 300+/-10g)"
[NO] AVOID: "Feels about right" (subjective)
[YES] GOOD: "Slides through go-gauge, blocks no-go-gauge"
[NO] AVOID: "Hole looks the right size" (visual only)
Documentation Template (Accessible)
## Part: Bracelet Holder Peg (Test Date: Jan 15, 2024)
### Dimensional Verification
| Dimension | Specification | Measurement 1 | Measurement 2 | Measurement 3 | Average | Result |
|--------------|----------------|---------------|---------------|---------------|---------|------------|
| Peg Diameter | 6.0 +/- 0.5mm | 5.9mm | 6.0mm | 5.8mm | 5.9mm | [YES] PASS |
| Peg Length | 25.0 +/- 0.5mm | 25.1mm | 25.0mm | 25.0mm | 25.03mm | [YES] PASS |
### Functional Test
- [x] Slides into bracelet loop easily (no forcing)
- [x] No cracks visible or felt
- [x] Survives 1-hour load test with 20 bracelets
- [x] No permanent deformation after load removed
### Overall Result
[YES] PASS - All dimensions within tolerance; functionally sound
Summary
Key Principles:
- Plan before printing: Define tolerances and test methods
- Measure precisely: Use calibrated tools (digital calipers, scale)
- Test functionally: Will parts assemble and work?
- Document quantitatively: Use numbers, not adjectives
- Iterate based on data: If test fails, adjust design or process
When to Use Each Test:
| Situation | Recommended Test |
|---|---|
| Prototype/mockup | Linear dimensions only |
| Assembly with other parts | Tolerance stack-up analysis |
| Load-bearing part | Functional load test |
| Repeated-use item | Durability cycling test |
| Multi-part design | Assembly fit test |
Accessibility Reminder:
All QA testing in this appendix is measurement-based and non-visual, making it equally accessible to all users. The goal is objective, quantifiable verification-not subjective assessment.
Appendix E: Advanced OpenSCAD Concepts
This appendix covers specialized topics for experienced users seeking to tackle complex parametric designs. These are optional topics not required for foundational mastery but valuable for professional application development.
Topic 1: Gears and Mechanical Components
Gears are one of the most challenging parametric designs, requiring careful calculation of tooth geometry. Understanding gear mathematics enables creation of mechanical systems-power transmission, speed reduction, or precise positioning.
Gear Terminology
- Pitch Diameter (PD): The reference diameter for meshing calculations
- Module: PD divided by tooth count; determines tooth size
- Pressure Angle: Typically 20deg or 14.5deg; affects tooth shape and strength
- Clearance: Space between teeth to allow smooth meshing
- Backlash: Intentional gap to prevent binding at tolerance extremes
Simple Involute Gear Algorithm
// Simplified gear with circular teeth (adequate for most 3D prints)
function gear_module(pitch_diameter, teeth_count) = pitch_diameter / teeth_count;
module simple_gear(pitch_diameter, teeth_count, bore_diameter, thickness) {
module_m = gear_module(pitch_diameter, teeth_count);
outer_diameter = pitch_diameter + 2 * module_m;
tooth_angle = 360 / teeth_count;
difference() {
// Main gear body
cylinder(r=outer_diameter/2, h=thickness, $fn=teeth_count*4);
// Center bore
cylinder(r=bore_diameter/2, h=thickness + 2);
}
// Add teeth as small protrusions
for (i = [0:teeth_count-1]) {
angle = i * tooth_angle;
translate([
(pitch_diameter/2 + module_m/2) * cos(angle),
(pitch_diameter/2 + module_m/2) * sin(angle),
0
])
rotate([0, 0, angle])
cube([module_m * 0.8, module_m, thickness], center=true);
}
}
// Create meshing gear pair
module gear_pair_demo() {
// Gear 1: 20 teeth, 40mm pitch diameter
simple_gear(40, 20, 8, 10);
// Gear 2: 30 teeth, positioned to mesh
center_distance = (40 + 60) / 4; // Sum of radii
translate([center_distance, 0, 0])
simple_gear(60, 30, 8, 10);
}
gear_pair_demo();
Practical Application: Servo Gearbox
// Parametric servo gearbox with 3:1 reduction
module servo_gearbox(motor_torque, reduction_ratio, bore_size) {
// Input gear (motor)
input_teeth = 12;
input_pd = 30;
// Output gear (load)
output_teeth = input_teeth * reduction_ratio;
output_pd = input_pd * reduction_ratio;
// Gearbox housing
housing_size = output_pd + 40;
difference() {
// Main box
cube([housing_size, housing_size, 30]);
// Interior chamber
translate([20, 20, 5])
cube([housing_size - 40, housing_size - 40, 25]);
}
// Mount input gear
translate([housing_size/4, housing_size/2, 15]) {
simple_gear(input_pd, input_teeth, bore_size, 15);
// Motor coupling
cylinder(r=bore_size/2, h=5);
}
// Mount output gear
translate([3*housing_size/4, housing_size/2, 15])
simple_gear(output_pd, output_teeth, bore_size, 15);
}
servo_gearbox(10, 3, 5);
Belt and Pulley Systems
// Timing pulley with tooth grooves
module timing_pulley(bore_diameter, pitch_diameter, teeth_count, width) {
module_m = pitch_diameter / teeth_count;
tooth_height = module_m * 0.3;
difference() {
// Main pulley body
cylinder(r=pitch_diameter/2 + tooth_height/2, h=width);
// Center bore
cylinder(r=bore_diameter/2, h=width + 2);
// Tooth grooves
for (i = [0:teeth_count-1]) {
angle = i * (360 / teeth_count);
rotate([0, 0, angle])
translate([pitch_diameter/2, -module_m*0.3, 0])
cube([module_m * 0.6, module_m * 0.6, width], center=true);
}
}
}
// Belt drive demonstration
module belt_drive_system() {
// Motor pulley (input)
timing_pulley(5, 20, 16, 10);
// Load pulley (output) - positioned for belt routing
translate([80, 0, 0])
timing_pulley(5, 40, 32, 10);
}
belt_drive_system();
Topic 2: Batch Processing and Statistical Analysis
Professional applications often generate many variants and need to analyze results. Batch processing enables systematic exploration of parameter spaces.
Parameter Sweep Generation
// Generate models with all combinations of parameters
// Define parameter ranges
wall_thicknesses = [1, 1.5, 2, 2.5, 3];
part_sizes = [20, 30, 40, 50];
materials = ["pla", "petg", "nylon"];
// Theory: Generate 5 x 4 x 3 = 60 variants automatically
// In practice, export each to separate STL for analysis
Statistical Summary Generation Script
@echo off
rem analyze_batch.bat - Analyze batch results (CMD / Batch)
setlocal enableextensions enabledelayedexpansion
set "OUTPUT_DIR=batch_results"
set "REPORT_FILE=batch_analysis.csv"
echo Part,Wall,Size,File_Size_KB,Est_Print_Time_min,Est_Weight_g > "%REPORT_FILE%"
for %%w in (1 2 3) do (
for %%s in (20 30 40 50) do (
set "SCAD_FILE=part_%%s_wall%%w.scad"
set "STL_FILE=%OUTPUT_DIR%\%%~nSCAD_FILE.stl"
"C:\Program Files\OpenSCAD\openscad.exe" -D "part_size=%%s" -D "wall=%%w" -o "%OUTPUT_DIR%\part_%%s_wall%%w.stl" src\main.scad
if exist "%OUTPUT_DIR%\part_%%s_wall%%w.stl" (
for /f "usebackq" %%F in (`powershell -NoProfile -Command "(Get-Item -Path '%OUTPUT_DIR%\part_%%s_wall%%w.stl').Length"`) do set FILE_BYTES=%%F
set /a FILE_KB=FILE_BYTES / 1024
set /a EST_TIME=(FILE_KB / 1024) * 60
set /a EST_WEIGHT=FILE_KB / 1024
) else (
set FILE_KB=0
set EST_TIME=0
set EST_WEIGHT=0
)
echo part_%%s_wall%%w,%%w,%%s,!FILE_KB!,!EST_TIME!,!EST_WEIGHT!>>"%REPORT_FILE%"
)
)
endlocal
echo Analysis complete. Results in %REPORT_FILE%
# analyze_batch.ps1 - Analyze batch results (PowerShell)
$OutputDir = "batch_results"
$ReportFile = "batch_analysis.csv"
"Part,Wall,Size,File_Size_KB,Est_Print_Time_min,Est_Weight_g" | Out-File -FilePath $ReportFile -Encoding utf8
foreach ($wall in @(1.0,1.5,2.0,2.5,3.0)) {
foreach ($size in @(20,30,40,50)) {
$scad = "part_${size}_wall${wall}.scad"
$stl = Join-Path $OutputDir ("{0}.stl" -f ([System.IO.Path]::GetFileNameWithoutExtension($scad)))
& "C:\Program Files\OpenSCAD\openscad.exe" -D ("part_size={0}" -f $size) -D ("wall={0}" -f $wall) -o $stl src\main.scad
if (Test-Path $stl) {
$bytes = (Get-Item $stl).Length
$kb = [math]::Round($bytes / 1KB, 2)
$est_time = [math]::Round(($kb / 1024) * 60, 2)
$est_weight = [math]::Round($kb / 1024, 2)
} else {
$kb = 0; $est_time = 0; $est_weight = 0
}
"{0},{1},{2},{3},{4},{5}" -f ("part_{0}_wall{1}" -f $size,$wall), $wall, $size, $kb, $est_time, $est_weight | Out-File -FilePath $ReportFile -Append -Encoding utf8
}
}
Write-Host "Analysis complete. Results in $ReportFile"
#!/bin/bash
# analyze_batch.sh - Analyze batch results statistically
OUTPUT_DIR="batch_results"
REPORT_FILE="batch_analysis.csv"
echo "Part,Wall,Size,File_Size_KB,Est_Print_Time_min,Est_Weight_g" > "$REPORT_FILE"
for wall in 1.0 1.5 2.0 2.5 3.0; do
for size in 20 30 40 50; do
# Generate model
SCAD_FILE="part_${size}_wall${wall}.scad"
STL_FILE="$OUTPUT_DIR/${SCAD_FILE%.scad}.stl"
# Export to STL
openscad -D "part_size=$size" -D "wall=$wall" \
-o "$STL_FILE" src/main.scad
# Get file size
FILE_SIZE=$(stat -c%s "$STL_FILE" 2>/dev/null | awk '{print $1/1024}')
# Estimate print time (rough: 1 hour per MB)
EST_TIME=$((FILE_SIZE / 1024 * 60))
# Estimate weight (rough: 1g per MB for PLA)
EST_WEIGHT=$((FILE_SIZE / 1024))
# Log results
echo "part_${size}_wall${wall},$wall,$size,$FILE_SIZE,$EST_TIME,$EST_WEIGHT" >> "$REPORT_FILE"
done
done
echo "Analysis complete. Results in $REPORT_FILE"
Data-Driven Design Selection
// Load results and select optimal configuration
// wall=2.0mm gives best balance of strength/weight for most sizes
function optimal_configuration(target_size, priority) =
priority == "strength" ? 3.0 :
priority == "speed" ? 1.0 :
priority == "balanced" ? 2.0 :
2.0; // Default
module batch_optimized_part(size, priority) {
wall = optimal_configuration(size, priority);
echo(str("Generating optimized part: size=", size, " wall=", wall, " priority=", priority));
// Create part with optimal parameters
difference() {
cube([size, size, size]);
translate([wall, wall, wall])
cube([size - 2*wall, size - 2*wall, size]);
}
}
// Generate three variants with different priorities
batch_optimized_part(40, "strength"); // thickest walls
translate([60, 0, 0]) batch_optimized_part(40, "speed"); // thinnest walls
translate([120, 0, 0]) batch_optimized_part(40, "balanced"); // medium walls
Topic 3: Performance Optimization
Complex models can take hours to render. Strategic optimization keeps iteration cycles fast.
Measuring Render Performance
# Time how long rendering takes
time openscad -o output.stl -D "quality=32" src/main.scad
# Output: real 5m 32s, user 5m 28s, sys 0m 2s
Resolution Parameter Strategy
// Use lower resolution during development, high during export
quality = $preview ? 16 : 64; // 16 segments in preview, 64 in export
module efficient_sphere(radius) {
sphere(r=radius, $fn=quality);
}
// In array operations, efficiency matters most
module circular_array(radius, count) {
for (i = [0:count-1]) {
angle = (360 / count) * i;
x = radius * cos(angle);
y = radius * sin(angle);
translate([x, y, 0])
efficient_sphere(5); // Uses quality parameter
}
}
circular_array(30, 100); // 100 spheres: slow with quality=64!
Cache Complex Calculations
// Pre-compute expensive calculations outside loops
// SLOW: Recalculates sin/cos for every iteration
module slow_spiral() {
for (i = [0:200]) {
angle = i * 2;
x = 40 * cos(angle);
y = 40 * sin(angle);
z = i * 0.5;
translate([x, y, z])
sphere(r=1);
}
}
// FAST: Pre-compute positions, then use them
spiral_positions = [for (i = [0:200]) [
40 * cos(i * 2),
40 * sin(i * 2),
i * 0.5
]];
module fast_spiral() {
for (pos = spiral_positions)
translate(pos)
sphere(r=1);
}
// Use the fast version
fast_spiral();
Simplification During Preview
// Complex model that simplifies in preview mode
module detailed_model() {
if ($preview) {
// Simplified version for fast preview
cube([100, 100, 50]);
} else {
// Detailed version for export
difference() {
cube([100, 100, 50]);
// Complex inner geometry
for (x = [10:10:90])
for (y = [10:10:90])
translate([x, y, 20])
cylinder(h=15, d=3, $fn=32);
}
}
}
detailed_model();
Profile-Driven Optimization
#!/bin/bash
# profile_render.sh - Identify slow rendering hotspots
echo "Profiling render performance..."
for fn_value in 8 16 32 64 128; do
echo ""
echo "Testing with \$fn=$fn_value..."
/usr/bin/time -v openscad -D "fn=$fn_value" \
-o test_$fn_value.stl src/main.scad 2>&1 | \
grep "Maximum resident set size"
done
Topic 4: Print Orientation and Support Structure Algorithms
Strategic orientation dramatically affects support material, print time, and surface quality.
Strength Orientation Analysis
// Different orientations affect strength differently
// SCENARIO: Bracket with cantilever load
module bracket() {
difference() {
cube([50, 100, 10]);
translate([25, 50, 5]) cylinder(r=5, h=10);
}
}
// Orientation A: Lay flat (XY plane) - WEAK for cantilever
echo("Orientation A: Flat - Low strength for cantilever");
bracket();
// Orientation B: Stand tall (Z axis) - STRONG for cantilever
translate([70, 0, 0]) {
echo("Orientation B: Tall - High strength for cantilever");
rotate([90, 0, 0]) bracket();
}
// Orientation C: Diagonal - MODERATE strength
translate([0, 150, 0]) {
echo("Orientation C: Diagonal - Moderate strength");
rotate([45, 0, 0]) bracket();
}
Support Material Minimization
// Design features to reduce supports needed
// POOR: Overhanging feature needs extensive supports
module poor_design() {
cube([50, 50, 50]);
translate([25, 25, 50])
cube([30, 30, 10]); // 30mm overhang!
}
// GOOD: Bridge angle keeps overhang under 45deg
module good_design() {
cube([50, 50, 50]);
// Add ramp instead of overhang
translate([20, 20, 50])
rotate([20, 0, 0])
cube([30, 30, 10]);
}
// Compare
poor_design();
translate([80, 0, 0])
good_design();
Bridge Span Calculation
// Calculate maximum unsupported span for given material/settings
function max_bridge_span(material) =
material == "pla" ? 10 :
material == "petg" ? 12 :
material == "nylon" ? 15 :
material == "abs" ? 8 :
10; // Default
module bridged_connector(material, gap_width) {
max_span = max_bridge_span(material);
if (gap_width <= max_span) {
echo(str("Bridge OK: gap ", gap_width, "mm fits within ", max_span, "mm limit"));
// Create part with bridge
union() {
cube([50, 10, 10]); // Side A
translate([gap_width, 0, 0])
cube([50, 10, 10]); // Side B
// Bridge connecting them
translate([0, 5, 10])
cube([gap_width + 100, 2, 1]);
}
} else {
echo(str("ERROR: gap ", gap_width, "mm exceeds ", max_span, "mm max bridge span"));
}
}
bridged_connector("pla", 8); // OK: 8 < 10
// bridged_connector("pla", 15); // ERROR: 15 > 10
Slicing Parameter Calculation
// Calculate optimal slicing parameters based on geometry
function recommended_layer_height(nozzle_diameter, quality_priority) =
quality_priority == "fast" ? nozzle_diameter * 0.75 :
quality_priority == "balanced" ? nozzle_diameter * 0.5 :
quality_priority == "detailed" ? nozzle_diameter * 0.25 :
nozzle_diameter * 0.5;
function recommended_infill(structural_load, safety_factor) =
structural_load < 1 ? 10 : // Decorative: minimal fill
structural_load < 5 ? 20 : // Light duty: low fill
structural_load < 20 ? 50 : // Medium duty: standard fill
100; // High duty: solid
module optimized_part(
nozzle_0p4,
quality_priority,
structural_load,
safety_factor
) {
layer_h = recommended_layer_height(nozzle_0p4, quality_priority);
infill_pct = recommended_infill(structural_load, safety_factor);
echo(str("Recommended layer height: ", layer_h, "mm"));
echo(str("Recommended infill: ", infill_pct, "%"));
// Create part
cube([50, 50, 30]);
}
optimized_part(0.4, "detailed", 15, 2);
Topic 5: Recursive Function Patterns
Recursion enables elegant solutions to problems with self-similar structure: trees, fractals, nested components.
Basic Recursive Pattern
// Tree structure: branches recursively smaller
function tree_depth(level) = level > 0 ? level + tree_depth(level - 1) : 0;
// Calculate: tree_depth(5) = 5 + 4 + 3 + 2 + 1 = 15
result = tree_depth(5);
echo(result); // Prints: 15
// Recursive tree drawing
module tree_branch(length, angle, recursion_depth) {
if (recursion_depth > 0) {
// Draw this branch
rotate([angle, 0, 0])
cube([2, 2, length]);
// Recursively draw sub-branches
translate([0, 0, length])
rotate([-angle/2, 0, 0])
tree_branch(length * 0.7, angle, recursion_depth - 1);
translate([0, 0, length])
rotate([angle/2, 0, 0])
tree_branch(length * 0.7, angle, recursion_depth - 1);
}
}
tree_branch(30, 25, 4); // Tree with 4 levels of recursion
Fractal Generation
// Sierpinski Triangle fractal
function sierpinski_triangle(size, depth) =
depth == 0 ?
[[0, 0], [size, 0], [size/2, size * sqrt(3)/2]] :
// Recursive case: three smaller triangles at corners
concat(
sierpinski_triangle(size/2, depth - 1),
sierpinski_triangle(size/2, depth - 1),
sierpinski_triangle(size/2, depth - 1)
);
// Create 3D fractal structure
module fractal_spiral(base_size, depth, height_per_level) {
if (depth > 0) {
// Create current level
cube([base_size, base_size, 5], center=true);
// Recursively create smaller level on top
translate([0, 0, height_per_level])
scale([0.6, 0.6, 1])
fractal_spiral(base_size, depth - 1, height_per_level);
}
}
fractal_spiral(40, 5, 10); // 5-level spiral
Nested Component Assembly
// Russian doll boxes: each box contains a smaller copy
module russian_doll(size, wall, nesting_depth) {
if (nesting_depth > 0) {
// Current level: hollow box
difference() {
cube([size, size, size]);
translate([wall, wall, wall])
cube([size - 2*wall, size - 2*wall, size - wall]);
}
// Recursively place next smaller doll inside
interior_size = size - 4*wall;
translate([2*wall, 2*wall, wall])
russian_doll(interior_size, wall, nesting_depth - 1);
} else {
// Smallest doll (solid)
cube([size, size, size]);
}
}
russian_doll(60, 2, 4); // 4 nested boxes
Performance Considerations
// Recursion can be expensive - monitor depth
// EFFICIENT: Tail recursion (result computed immediately)
function sum_to(n, accumulator) =
n == 0 ? accumulator :
sum_to(n - 1, accumulator + n);
result = sum_to(100, 0); // Computes: 5050
// INEFFICIENT: Deep recursion without optimization
function fibonacci(n) =
n <= 1 ? n :
fibonacci(n-1) + fibonacci(n-2);
// fibonacci(20) recalculates sub-problems thousands of times
// Don't use for depth > 20 without memoization
// BETTER: Use iteration where possible
function fibonacci_iter(n) =
let(
fib = [for (i = [0:n])
i <= 1 ? i :
let(prev = [for (j = [0:i-1]) i==j ? 1 : i==j+1 ? 0 : 0])
1 // Placeholder
]
) fib[n];
Practical Example: Cable Management
// Recursive cable tray with branching paths
module cable_tray(width, depth, height, levels, branch_angle) {
if (levels > 0) {
// Main tray section
difference() {
cube([width, depth, height]);
translate([2, 2, 2])
cube([width - 4, depth - 4, height - 2]);
}
// Left branch (recursively smaller)
translate([-width/2, 0, height])
rotate([0, 0, -branch_angle])
cable_tray(width * 0.6, depth, height, levels - 1, branch_angle);
// Right branch
translate([width/2, 0, height])
rotate([0, 0, branch_angle])
cable_tray(width * 0.6, depth, height, levels - 1, branch_angle);
}
}
cable_tray(40, 10, 5, 3, 30); // 3-level branching cable tray
Summary: When to Use Each Advanced Technique
| Technique | Use Case | Complexity | Performance |
|---|---|---|---|
| Gears | Mechanical power transmission | High | Medium |
| Batch Processing | Design space exploration | Medium | Depends on scope |
| Performance Optimization | Reducing render time | Medium | High payoff |
| Orientation Analysis | Strength optimization | Medium | Simulation cost |
| Recursion | Fractal/nested structures | High | Can be expensive |
References and Further Learning
- OpenSCAD Documentation - Advanced Features: https://en.wikibooks.org/wiki/OpenSCAD_User_Manual
- Gear Design Theory: https://www.mekanizmalar.com/
- 3D Print Orientation Optimization: https://stratasys.com/
- Fractal Geometry: https://en.wikipedia.org/wiki/Fractal
- Recursive Algorithms: https://www.khanacademy.org/computing/computer-science/algorithms
For Educators and Students
These advanced topics are intended for:
- Experienced users tackling professional applications
- Specialized problem domains (robotics, mechanical design, etc.)
- Research and optimization work
- Custom library and framework development
For accessibility:
- All recursive examples include base cases clearly marked
- Each section provides simplified versions before advanced variants
- Code comments explain both “what” and “why”
- Practical examples show real-world applications
- Performance considerations documented to prevent frustration
-
Logan Library Cytiva STEM Makerspace. ↩
-
Utah STEM Action Center – Innovation Hub Network. ↩ ↩2 ↩3 ↩4
-
Salt Lake City Public Library Creative Lab. ↩
-
Salt Lake County Library Create Spaces. ↩
-
University of Utah – Marriott Library ProtoSpace & 3D Printing. ↩
-
Washington County Library – Sid Atkin Makerspace. ↩
-
Weber County Library Makerspaces. ↩
-
https://www.nationofmakers.us/find-a-maker-organization ↩
-
https://makerspacedir.com/ ↩
-
https://www.poidata.io/report/makerspace/united-states ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 ↩8 ↩9 ↩10 ↩11 ↩12 ↩13 ↩14 ↩15 ↩16 ↩17 ↩18 ↩19 ↩20 ↩21 ↩22 ↩23 ↩24 ↩25 ↩26 ↩27 ↩28 ↩29 ↩30 ↩31 ↩32 ↩33 ↩34 ↩35 ↩36 ↩37 ↩38 ↩39 ↩40 ↩41 ↩42 ↩43
-
https://www.globalspec.com/local/6383/C_US ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 ↩8 ↩9 ↩10 ↩11 ↩12
-
https://www.makerdirectory.com/makerspace-directory/ ↩
-
https://www.maker-works.com/local-makerspaces ↩