Fretwire is a dependency-free command-line tool that converts a small guitar or bass specification into deterministic layout data for a parametric Fusion 360 workflow. It calculates fret locations, applies bounded scaling rules to instrument proportions, resolves reusable body and headstock point profiles, and emits JSON, a readable parameter list, or Fusion-compatible CSV.
This repository is a portfolio project focused on traceable calculations, repeatable outputs, cross-runtime behavior, and practical quality controls—not just producing a shape that looks plausible.
- Deterministic domain math, including equal-temperament fret placement.
- Configuration-driven design using version-controlled JSON presets and profiles.
- Controlled scaling: functional dimensions remain exact while visual proportions use weighted, damped growth.
- Equivalent Python and PowerShell entry points with no third-party packages.
- Contract and regression testing across math, configuration integrity, CLI precedence, CSV schema, and runtime parity.
- CI checks on Linux and Windows, including an execution-policy-safe Windows PowerShell path.
- Honest separation between generated starting geometry and the human judgment required for a finished physical design.
Fretwire requires either Python 3.9+ or Windows PowerShell 5.1+/PowerShell 7. No package installation, network connection, CAD API, or account is required.
Generate readable Fusion parameters from a built-in preset:
python .\guitar_builder.py --preset strat --format fusionResolve a complete JSON specification:
python .\guitar_builder.py --spec .\examples\strat_to_bass.json --format jsonCreate an importable CSV:
python .\guitar_builder.py --spec .\examples\strat_to_bass.json --format csv |
Set-Content -Encoding utf8 .\fusion_params.csvThis explicit command works even when the machine's default policy blocks direct .ps1 execution:
powershell.exe -NoProfile -ExecutionPolicy Bypass -File .\guitar_builder.ps1 -Preset strat -Format fusionGenerate a CSV from a specification:
powershell.exe -NoProfile -ExecutionPolicy Bypass -File .\guitar_builder.ps1 -Spec .\examples\tele_strat_hybrid.json -Format csv |
Set-Content -Encoding utf8 .\fusion_params.csvWith PowerShell 7 on macOS or Linux:
pwsh -NoProfile -File ./guitar_builder.ps1 -Spec ./examples/strat_to_bass.json -Format jsonStart with a built-in family—strat, tele, offset, p_bass, or j_bass—or provide a JSON spec. Common inputs include:
scale_length_innut_width_inbridge_string_spacing_instringsfret_countneck_joint_fretbody_profileheadstock_profile
A spec inherits missing values from its selected preset. An explicitly supplied command-line value wins over the same value in the spec. If neither a spec nor --preset/-Preset chooses a preset, Fretwire defaults to strat.
Advanced specs can override base body/neck dimensions and their scaling weights. See the files in examples for working requests and presets for the version-controlled source data.
Fretwire rejects invalid geometry before doing layout math. Scale length, nut width, bridge string spacing, and all base/resolved dimensions must be positive finite numbers. String count must be an integer from 1 through 24, fret count from 1 through 48, and the neck-joint fret from 0 through the selected fret count. Scaling weights are bounded from 0 through 1. Profile references must be positive, coordinates must be finite, and rounded fret positions must remain distinct. Validation failures identify the offending field and exit nonzero in both runtimes.
| Format | Purpose |
|---|---|
json |
Full resolved request, dimensions, ratios, profile points, notes, and named Fusion parameters. |
fusion |
Compact, readable name = value parameter list for inspection. |
csv |
Fusion 360 user-parameter import schema with units, expressions, values, comments, and favorite flags. |
For a standard 25.5-inch scale, the twelfth-fret position resolves to exactly 12.75 inches from the nut. Fretwire calculates any fret n using:
position(n) = scaleLength - scaleLength / 2^(n / 12)
Resolved dimensions and profile points are rounded to four decimal places so results remain stable and reviewable. PowerShell uses invariant-culture numeric serialization, so CSV and Fusion output retain dot decimals regardless of the machine's locale.
flowchart LR
A["CLI overrides"] --> D["Deterministic resolver"]
B["Instrument presets"] --> D
C["Body/headstock profiles"] --> D
S["Optional JSON spec"] --> D
D --> M["Fret and scaling math"]
M --> V["Resolved model + QC notes"]
V --> J["JSON"]
V --> F["Fusion parameter text"]
V --> X["Fusion import CSV"]
The resolver first performs a non-mutating deep merge, then calculates scale ratios and fret locations, applies separately weighted body and neck scaling, maps normalized profile points to the resolved dimensions, and finally formats one shared model. Both entry points implement the same pipeline; the test suite compares their complete JSON contracts.
Run the dependency-free suite:
python -m unittest discover -s tests -vOn Windows, the parity tests launch PowerShell with -NoProfile -ExecutionPolicy Bypass. On systems without PowerShell, cross-runtime cases are skipped while the Python-only tests continue.
The suite checks:
- the mathematical twelfth-fret invariant and scale damping boundary;
- non-mutating nested configuration merges;
- successful resolution of every built-in preset against its referenced shape profiles;
- rejection of an unknown profile with an actionable error;
- actionable, nonzero failures for non-finite, non-positive, out-of-range, and physically invalid inputs in both runtimes;
- default, spec, and explicit CLI precedence behavior;
- the Fusion CSV column contract and dot-decimal output under a non-English locale; and
- complete JSON equivalence between Python and PowerShell.
GitHub Actions repeats the tests on Python 3.9 and 3.13 under Linux, then runs the full cross-runtime suite and PowerShell smoke checks on Windows.
.
|-- guitar_builder.py # Python CLI and resolver
|-- guitar_builder.ps1 # PowerShell CLI and resolver
|-- presets/
| |-- instruments.json # baseline dimensions and scaling weights
| `-- shape_profiles.json # reusable body/headstock point sets
|-- examples/ # complete input specifications
|-- docs/fusion_workflow.md # recommended CAD workflow
|-- tests/test_fretwire.py # regression and parity suite
`-- .github/workflows/ci.yml # Linux and Windows quality gates
Fretwire produces a controlled starting layout, not a manufacturing-ready instrument. Its point profiles are sparse spline guides, its baseline dimensions are design references rather than certified replicas, and a luthier or designer must still evaluate ergonomics, balance, hardware clearances, structural requirements, and manufacturability. The current model uses inches and does not create or modify a Fusion document directly.
The family names Strat, Tele, P-Bass, and J-Bass are used descriptively to communicate familiar instrument proportions. This project is independent and is not affiliated with or endorsed by Fender Musical Instruments Corporation.
Fretwire was built through human-directed, AI-assisted collaboration. The project uses that collaboration transparently: requirements and design decisions were translated into inspectable source code, deterministic data, executable examples, and regression tests rather than presented as unaudited generated output. The repository is intended to show the resulting engineering and quality practices, including where limitations remain.
For the CAD-side process, continue with the Fusion 360 workflow.
This portfolio repository is shared for review. No open-source license has been granted.