ignitefuse 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +37 -0
  3. package/THIRD_PARTY_NOTICES.md +37 -0
  4. package/dist/index.js +9954 -0
  5. package/dist/index.js.map +7 -0
  6. package/package.json +51 -0
  7. package/skills/ignitefuse/SKILL.md +75 -0
  8. package/skills/ignitefuse/references/full-api-and-architecture.md +93 -0
  9. package/skills/ignitefuse-dev/SKILL.md +22 -0
  10. package/skills/ignitefuse-dev/references/implementation-map.md +18 -0
  11. package/skills/ignitefuse-dev/references/task-recipes.md +32 -0
  12. package/skills/ignitefuse-make-toolpath/SKILL.md +48 -0
  13. package/skills/ignitefuse-make-toolpath/references/api-shape.md +211 -0
  14. package/skills/ignitefuse-make-toolpath/references/direct-open-case-solid-bottom.md +193 -0
  15. package/skills/ignitefuse-make-toolpath/references/direct-region-fill.md +34 -0
  16. package/skills/ignitefuse-make-toolpath/references/function-implementation.md +137 -0
  17. package/skills/ignitefuse-make-toolpath/references/stl-standard-fdm.md +50 -0
  18. package/skills/ignitefuse-params/SKILL.md +24 -0
  19. package/skills/ignitefuse-params/references/param-patterns.md +153 -0
  20. package/skills/ignitefuse-printer-scene/SKILL.md +26 -0
  21. package/skills/ignitefuse-printer-scene/references/canonical-printer-scene.md +110 -0
  22. package/skills/ignitefuse-studio-mcp/SKILL.md +29 -0
  23. package/skills/ignitefuse-studio-mcp/references/mcp-tools.md +205 -0
  24. package/web/_app/env.js +1 -0
  25. package/web/_app/immutable/assets/0.7gMbBLNl.css +1 -0
  26. package/web/_app/immutable/assets/2.DUefECe3.css +1 -0
  27. package/web/_app/immutable/chunks/BLxuUouR.js +1 -0
  28. package/web/_app/immutable/chunks/BYlkGUYK.js +2 -0
  29. package/web/_app/immutable/chunks/ByZS5AaA.js +1 -0
  30. package/web/_app/immutable/chunks/C8-ejoe7.js +1 -0
  31. package/web/_app/immutable/chunks/CH8BOpuN.js +1 -0
  32. package/web/_app/immutable/chunks/Crm9Js9u.js +1 -0
  33. package/web/_app/immutable/chunks/D2Rdy9P1.js +1 -0
  34. package/web/_app/immutable/chunks/DwxNakxI.js +1 -0
  35. package/web/_app/immutable/entry/app.CUixVVde.js +2 -0
  36. package/web/_app/immutable/entry/start.DLVy4bB7.js +1 -0
  37. package/web/_app/immutable/nodes/0.Dgd1b1QE.js +1 -0
  38. package/web/_app/immutable/nodes/1.D_VGAzop.js +1 -0
  39. package/web/_app/immutable/nodes/2.CajHQkWG.js +5344 -0
  40. package/web/_app/immutable/workers/assets/clipper2z-bvMLVKp3.wasm +0 -0
  41. package/web/_app/immutable/workers/fuseRuntime.worker-DXbd4CFC.js +22 -0
  42. package/web/_app/immutable/workers/layerToolpath.worker-5A0bN0Cv.js +15 -0
  43. package/web/_app/immutable/workers/sectionConnect.worker-D4w8efrj.js +1 -0
  44. package/web/_app/version.json +1 -0
  45. package/web/favicon.png +0 -0
  46. package/web/icon.png +0 -0
  47. package/web/index.html +43 -0
  48. package/web/logo.png +0 -0
package/package.json ADDED
@@ -0,0 +1,51 @@
1
+ {
2
+ "name": "ignitefuse",
3
+ "version": "0.1.0",
4
+ "description": "CLI and local studio host for programmable IgniteFuse 3D-print toolpaths.",
5
+ "type": "module",
6
+ "bin": {
7
+ "ignitefuse": "dist/index.js"
8
+ },
9
+ "files": [
10
+ "dist",
11
+ "LICENSE",
12
+ "README.md",
13
+ "THIRD_PARTY_NOTICES.md",
14
+ "skills",
15
+ "web"
16
+ ],
17
+ "keywords": [
18
+ "3d-printing",
19
+ "gcode",
20
+ "manufacturing",
21
+ "slicer",
22
+ "toolpath"
23
+ ],
24
+ "repository": {
25
+ "type": "git",
26
+ "url": "git+https://github.com/tokoshie3d/IgniteFuse.git",
27
+ "directory": "apps/cli"
28
+ },
29
+ "bugs": {
30
+ "url": "https://github.com/tokoshie3d/IgniteFuse/issues"
31
+ },
32
+ "homepage": "https://github.com/tokoshie3d/IgniteFuse#readme",
33
+ "scripts": {
34
+ "build": "node ../../scripts/build-cli.mjs",
35
+ "check": "tsc --noEmit -p tsconfig.json",
36
+ "dev": "node --import tsx src/index.ts",
37
+ "prepack": "pnpm -w build:cli"
38
+ },
39
+ "dependencies": {
40
+ "clipper2-wasm": "^0.2.1"
41
+ },
42
+ "devDependencies": {
43
+ "@types/node": "^22.15.3",
44
+ "tsx": "^4.20.6",
45
+ "typescript": "~5.6.2"
46
+ },
47
+ "engines": {
48
+ "node": ">=18"
49
+ },
50
+ "license": "Apache-2.0"
51
+ }
@@ -0,0 +1,75 @@
1
+ ---
2
+ name: ignitefuse
3
+ description: Use for general IgniteFuse concepts, .fuse.js API orientation, runtime stages, coordinates, toolpath roles, and when no narrower IgniteFuse skill applies. For active project editing use ignitefuse-make-toolpath and ignitefuse-studio-mcp when available.
4
+ ---
5
+
6
+ # IgniteFuse Core
7
+
8
+ IgniteFuse is a code-first manufacturing studio for programmable 3D-print toolpaths. Treat `.fuse.js` as the source of truth: printer, scene, toolpath, and G-code export are code-defined artifacts.
9
+
10
+ ## Core Rules
11
+
12
+ - Use `printer(...)`, `exportScene(...)`, lazy `exportToolpath(async () => graph)`, and `onExportGcode(...)`.
13
+ - Read the Core API group in the Source Map before authoring unfamiliar `.fuse.js` code.
14
+ - Use generated params (`Param.number`, `Param.boolean`, `Param.select`, `Param.text`) instead of GUI-owned slicer settings.
15
+ - Use `buildArea { x, y, z }` and top-level `machineFrame`.
16
+ - Keep `ToolpathGraph` coordinates in Build Coordinates. Apply `machineFrame` only during G-code lowering and G-code preview parsing.
17
+ - Use semantic roles only: `outerWall`, `innerWall`, `infill`, `solidInfill`, `top`, `bottom`, `support`, `travel`.
18
+ - For normal `.fuse.js` programs, prefer `pathLayer()`, `pathRegion()`, `perimeters()`, `fillLayer()`, `fillRegion()`, or `fillRegionLayer()` over raw `ToolpathPath` objects.
19
+
20
+ ## Source Map
21
+
22
+ Load references top-to-bottom, stopping when you have what the task needs.
23
+
24
+ ### 1. Core API (always read first for `.fuse.js` authoring)
25
+
26
+ Execution model, three phases, canonical API shape, coordinates, direct paths, regions, STL slicing, and G-code export.
27
+
28
+ - `references/full-api-and-architecture.md`
29
+ - `../ignitefuse-make-toolpath/references/api-shape.md`
30
+
31
+ ### 2. Active Studio MCP workflow
32
+
33
+ Use when the user refers to the currently open IgniteFuse project, wants Studio to run, wants tabs switched, or asks for toolpath summaries.
34
+
35
+ - `../ignitefuse-studio-mcp/references/mcp-tools.md`
36
+
37
+ ### 3. Printer, build area, scene, and placements
38
+
39
+ Use for printer profiles, `buildArea`, `machineFrame`, belt-like frames, placement blocks, and `exportScene(...)`.
40
+
41
+ - `../ignitefuse-printer-scene/references/canonical-printer-scene.md`
42
+
43
+ ### 4. Generated parameters
44
+
45
+ Use when defining user-editable dimensions, layer settings, walls, density, patterns, or fill angles.
46
+
47
+ - `../ignitefuse-params/references/param-patterns.md`
48
+
49
+ ### 5. Direct path and direct region toolpaths
50
+
51
+ Use for model-less procedural toolpaths, direct solid bottom/top fill, holes, and code-defined regions.
52
+
53
+ - `../ignitefuse-make-toolpath/references/direct-region-fill.md`
54
+ - `../ignitefuse-make-toolpath/references/direct-open-case-solid-bottom.md`
55
+
56
+ ### 6. STL slicing
57
+
58
+ Use for imported STL models, `model(...).mesh()`, plane stacks, perimeters, `fillLayer(...)`, and `parallelLayers(...)`.
59
+
60
+ - `../ignitefuse-make-toolpath/references/stl-standard-fdm.md`
61
+
62
+ ### 7. Helper function implementation
63
+
64
+ Use when writing `.fuse.js` helper functions, geometry builders, fill option builders, or G-code callbacks.
65
+
66
+ - `../ignitefuse-make-toolpath/references/function-implementation.md`
67
+
68
+ ## References
69
+
70
+ - For full API and architecture background, read `references/full-api-and-architecture.md`.
71
+ - For printer profile and scene definitions, prefer the `ignitefuse-printer-scene` skill.
72
+ - For generated UI parameters, prefer the `ignitefuse-params` skill.
73
+ - For creating or editing active `.fuse.js` projects, prefer the `ignitefuse-make-toolpath` skill.
74
+ - For Studio MCP workflows, prefer the `ignitefuse-studio-mcp` skill.
75
+ - For repository implementation work, prefer the `ignitefuse-dev` skill.
@@ -0,0 +1,93 @@
1
+ # IgniteFuse Current API And Architecture
2
+
3
+ This reference is current-only. Use it for general orientation when a narrower skill does not apply.
4
+
5
+ ## Manufacturing Document Shape
6
+
7
+ Every complete `.fuse.js` manufacturing document should be structured in three explicit phases:
8
+
9
+ 1. Scene: declare `printer(...)`, optional `model(...)` placement block, and `exportScene(...)`.
10
+ 2. Toolpath: build and return `ToolpathGraph` inside lazy `exportToolpath(async () => graph)`.
11
+ 3. G-code export: register `onExportGcode(...)`; do not generate G-code during scene or toolpath preview.
12
+
13
+ Top-level code should stay lightweight. Mesh loading, slicing, region stacks, fill, offsets, path planning, and G-code-specific work belong inside lazy callbacks.
14
+
15
+ ## Printer And Scene
16
+
17
+ Use canonical printer definitions from `ignitefuse-printer-scene`.
18
+
19
+ ```js
20
+ const machine = printer({
21
+ name: "Generic FDM 220",
22
+ buildArea: { x: [0, 220], y: [0, 220], z: [0, 250] },
23
+ machineFrame: {
24
+ origin: [0, 0, 0],
25
+ xAxis: [1, 0, 0],
26
+ yAxis: [0, 1, 0],
27
+ zAxis: [0, 0, 1],
28
+ bounds: { x: [0, 220], y: [0, 220], z: [0, 250] },
29
+ },
30
+ nozzle: 0.4,
31
+ filament: 1.75,
32
+ gcodeFlavor: "marlin",
33
+ })
34
+ ```
35
+
36
+ `exportScene(...)` describes the printer and scene items. It should not execute slicing or heavy toolpath work.
37
+
38
+ ## Coordinates And Layers
39
+
40
+ Toolpath generation operates in Build Coordinates. G-code text is lowered into Machine Coordinates by `machineFrame`, and G-code preview maps parsed machine XYZ back into Build Coordinates.
41
+
42
+ Layers are identified by their Build-space plane, not by Z alone. `ToolpathLayer.z` is compatibility metadata for horizontal views. IgniteFuse G-code includes `;LAYER:<index>` and `;IF_LAYER_PLANE ...` comments so preview parsing can reconstruct arbitrary layer frames after machine-coordinate parsing.
43
+
44
+ For direct paths, use a plane plus plane-local paths:
45
+
46
+ ```js
47
+ const z = 0.2
48
+ const plane = Plane.z(z)
49
+ const layer = pathLayer(0, { layerIndex: 0, layerHeight: z, lineWidth: 0.44 })
50
+
51
+ layer.polygon("outerWall", [[20, 20], [80, 20], [80, 80], [20, 80]])
52
+
53
+ graph.addLayer({ plane, distance: z, layerIndex: 0, paths: layer.paths })
54
+ ```
55
+
56
+ ## Direct Paths And Regions
57
+
58
+ Use `pathLayer()` for explicit paths and `pathRegion()` for code-defined fill regions.
59
+
60
+ For a direct-path stack that needs standard bottom/top/sparse classification, build one `pathRegion()` per relevant layer and call `fillRegionLayer(regions, layerIndex, options)`.
61
+
62
+ Use `fillRegion(region, options)` for a deliberately single-region fill role and pattern.
63
+
64
+ ## STL Slicing
65
+
66
+ For STL-backed programs:
67
+
68
+ - Declare `model(...)` in `exportScene(...)`.
69
+ - Call `part.mesh()` inside `exportToolpath(async () => ...)`.
70
+ - Generate planes with `Plane.zStack(...)` or `Plane.stack(...)`.
71
+ - Slice with `sliceStackParallel(mesh, planes, { workerPool: true })`.
72
+ - Use `perimeters(section, ...)` for walls.
73
+ - Use `fillLayer(sections, layerIndex, ...)` for bottom/top/sparse fill.
74
+ - Use `parallelLayers(...)` for heavy per-layer work.
75
+
76
+ When combining multiple placed STL models or mixing STL and direct paths, assemble one job-level graph. Use shared planes for STL meshes in the same job and merge generated paths by identical Build-space plane (`origin`, `normal`, `xAxis`, `yAxis`), not by horizontal `z` alone. Default templates expose `Merge Coplanar Layers`; turning it off intentionally keeps same-plane layers separate.
77
+
78
+ ## G-code
79
+
80
+ Register G-code generation with `onExportGcode(fn)`. Toolpath preview should not generate G-code.
81
+
82
+ ```js
83
+ onExportGcode(({ graph, generateGcode, editGcode }) => {
84
+ return editGcode(generateGcode(graph, {
85
+ filament: { nozzleTemp: 210, bedTemp: 60 },
86
+ output: { flavor: "marlin", style: "orca" },
87
+ start: { mode: "standard" },
88
+ end: { mode: "standard" },
89
+ }))
90
+ .insertBeforeEnd("M107")
91
+ .toString()
92
+ })
93
+ ```
@@ -0,0 +1,22 @@
1
+ ---
2
+ name: ignitefuse-dev
3
+ description: Use when modifying the IgniteFuse repository implementation itself: runtime APIs, Svelte Studio UI, Tauri MCP bridge, toolpath kernel, infill, sectioning, geometry, G-code exporter, viewer, tests, or docs.
4
+ ---
5
+
6
+ # IgniteFuse Dev
7
+
8
+ Use this for repository implementation work, not for ordinary active-project `.fuse.js` generation.
9
+
10
+ ## Workflow
11
+
12
+ - Repository implementation tasks may confirm the repo root with `pwd` or `git rev-parse --show-toplevel`; active Studio project edits should use the MCP skills instead.
13
+ - Read the smallest relevant implementation files first using `references/implementation-map.md`.
14
+ - Follow task-specific touch points in `references/task-recipes.md`.
15
+ - Keep core slicing/toolpath logic in the SlicerQuery-style library layer, not in Tauri or UI.
16
+ - Preserve `.fuse.js` as source of truth.
17
+ - Validate with focused tests first, then `npm run check`, `cargo check` in `src-tauri`, and `npm run build` when UI/runtime behavior changed.
18
+
19
+ ## References
20
+
21
+ - `references/implementation-map.md`
22
+ - `references/task-recipes.md`
@@ -0,0 +1,18 @@
1
+ # Implementation Map
2
+
3
+ Use this map before broad repository searches. Read the smallest relevant file set first; use `rg` only when the map is stale or the task crosses boundaries.
4
+
5
+ - Studio shell and UI state: `src/routes/+page.svelte`
6
+ - Tauri project API types and commands: `src/app/projectApi.ts`
7
+ - Rust/Tauri project file I/O and MCP bridge: `src-tauri/src/lib.rs`
8
+ - Runtime execution and `.fuse.js` API surface: `src/runtime/fuseScriptRuntime.ts`, `src/runtime/fuseRunner.ts`, `src/runtime/types.ts`
9
+ - Worker-side mirrored runtime helpers: `src/runtime/layerToolpath.worker.ts`, `src/runtime/fuseRuntime.worker.ts`
10
+ - Toolpath graph and path builders: `src/toolpath/types.ts`, `src/toolpath/builder.ts`
11
+ - Direct regions and infill/fill helpers: `src/toolpath/infill.ts`, `src/toolpath/validate.ts`
12
+ - Perimeters, section conversion, planning, modifiers: `src/toolpath/perimeters.ts`, `src/toolpath/fromSection.ts`, `src/toolpath/planning.ts`, `src/toolpath/modifiers.ts`
13
+ - Section planes, slicing, connection, classification: `src/section/plane.ts`, `src/section/slice.ts`, `src/section/connect.ts`, `src/section/classify.ts`, `src/section/types.ts`
14
+ - Polygon kernel operations: `src/geometry/kernel/clipper.ts`, `src/geometry/kernel/lineClip.ts`, `src/geometry/kernel/offset.ts`, `src/geometry/kernel/boolean.ts`, `src/geometry/kernel/validate.ts`
15
+ - G-code lowering, parser preview, text edits: `src/gcode/exporter.ts`, `src/gcode/parser.ts`, `src/gcode/editor.ts`
16
+ - Generated parameter controls: `src/ui/GeneratedParams.svelte`
17
+ - Toolpath and scene preview: `src/viewer/ToolpathGraphViewer.svelte`, `src/viewer/ToolpathLayer.svelte`, `src/viewer/SceneModelMesh.svelte`
18
+ - User-facing MCP docs: `README.md`, `AGENTS.md`, `skills/*/SKILL.md`
@@ -0,0 +1,32 @@
1
+ # Task Recipes
2
+
3
+ ## MCP Or Studio-Agent Workflow Changes
4
+
5
+ - Start with `src-tauri/src/lib.rs`: update `mcp_tools()` schema and `mcp_call_tool()` dispatch.
6
+ - Then update `src/app/projectApi.ts` event payload types.
7
+ - Then update `src/routes/+page.svelte` listeners and UI state reflection.
8
+ - Sync `README.md`, `AGENTS.md`, and relevant skills.
9
+ - Validate with `npm run check`, `cargo check` in `src-tauri`, and `npm run build` when UI/runtime behavior changed.
10
+
11
+ ## `.fuse.js` Public API Changes
12
+
13
+ - Start with `src/runtime/fuseScriptRuntime.ts`.
14
+ - Mirror worker-callable helpers in `src/runtime/layerToolpath.worker.ts` when parallel layer execution should support the API.
15
+ - Add or update core implementation in `src/toolpath/*`, `src/section/*`, or `src/geometry/kernel/*` depending on the layer.
16
+ - Update examples or docs only after the runtime surface is stable.
17
+ - Validate with focused fixtures such as `src/toolpath/validate.ts`, then `npm run check` and `npm run build`.
18
+
19
+ ## Direct Path, Region, Fill, Or Infill Behavior
20
+
21
+ - Start with `src/toolpath/infill.ts` and `src/toolpath/builder.ts`.
22
+ - Keep direct-path helpers backed by shared region/fill code where possible.
23
+ - Prefer shared `fillRegion()` or `fillRegionLayer()` behavior over one-off raster or concentric examples.
24
+ - Keep hole semantics explicit through `pathRegion().hole(...)` or `{ hole: true }` and validate both winding directions.
25
+ - Update runtime exposure in `src/runtime/fuseScriptRuntime.ts` and worker exposure in `src/runtime/layerToolpath.worker.ts`.
26
+
27
+ ## Coordinate, Plane, Or G-code Behavior
28
+
29
+ - Start with `src/toolpath/coordinates.ts`, `src/gcode/exporter.ts`, and `src/gcode/parser.ts`.
30
+ - Keep `ToolpathGraph` in Build Coordinates.
31
+ - Apply `machineFrame` only during G-code lowering and G-code preview parsing.
32
+ - For arbitrary planes, check `src/section/plane.ts`, `src/runtime/fuseScriptRuntime.ts`, and graph layer materialization together.
@@ -0,0 +1,48 @@
1
+ ---
2
+ name: ignitefuse-make-toolpath
3
+ description: Use when creating or editing an IgniteFuse .fuse.js manufacturing program from a user prompt, especially active Studio projects, direct paths, procedural cases, solid bottom/top fill, STL slicing, toolpath generation, or G-code hooks. If Studio MCP is available, use read_source/write_source rather than editing the project file path directly.
4
+ ---
5
+
6
+ # IgniteFuse Make Toolpath
7
+
8
+ Use this skill to produce valid `.fuse.js` programs, not generic toolpath JSON.
9
+
10
+ ## Required Workflow
11
+
12
+ - Load the `ignitefuse` core skill guidance first when authoring unfamiliar `.fuse.js`; read at minimum its Core API Source Map entries.
13
+ - Structure complete `.fuse.js` programs in three explicit phases:
14
+ 1. Scene: declare `printer(...)`, optional `model(...)` placement block, and `exportScene(...)`.
15
+ 2. Toolpath: build and return `ToolpathGraph` inside lazy `exportToolpath(async () => ...)`.
16
+ 3. G-code export: register `onExportGcode(...)`; do not generate G-code during scene or toolpath preview.
17
+ - If the user refers to the currently open IgniteFuse project and MCP is available, use MCP `read_source` and `write_source`; do not use `get_project` only to obtain a path and bypass MCP.
18
+ - For active Studio project edits, do not run shell commands to discover `pwd`, cwd, shell, or project file paths. Shell cwd checks are for repository implementation tasks, not MCP-mediated active project edits.
19
+ - If the active source is empty or only boilerplate, replace it with a complete `.fuse.js` manufacturing document rather than returning a fragment.
20
+ - Keep top-level code lightweight. Put slicing, region stacks, fill, offsets, and planning inside lazy `exportToolpath(async () => ...)`.
21
+ - Always include `printer(...)`, `exportScene(...)`, `exportToolpath(...)`, and `onExportGcode(...)` unless the user explicitly asks for a partial snippet.
22
+ - For multiple placed STL models or mixed STL + direct paths, assemble job layers first and merge by identical Build-space `plane`; do not use `z` alone as the merge key. Expose a `Merge Coplanar Layers` boolean when keeping same-plane layers separate is useful.
23
+ - When API shape is uncertain, read `references/api-shape.md` before writing code.
24
+ - When defining helper functions in `.fuse.js`, read `references/function-implementation.md`.
25
+ - Do not write temporary `.fuse.js` programs that probe runtime globals such as `globalThis`, `Object.keys(...)`, or API discovery logs. Use `references/api-shape.md`, `ignitefuse://skill-guide`, and MCP resources instead.
26
+ - Use canonical printer/scene definitions from `ignitefuse-printer-scene`: `buildArea` plus top-level `machineFrame`.
27
+ - Use generated parameter patterns from `ignitefuse-params` for dimensions, layer settings, walls, and fill controls.
28
+ - Use `pathLayer()` and `pathRegion()` for model-less direct geometry.
29
+ - Use `fillRegionLayer()` for standard direct bottom/top solid and sparse classification across a stack.
30
+ - Use `fillRegion()` only for a deliberately single-region fill with an explicit role/pattern.
31
+
32
+ ## Preferred Defaults
33
+
34
+ - Prefer path builders (`pathLayer`, `pathRegion`, `perimeters`, `fillLayer`, `fillRegion`, `fillRegionLayer`) over raw path objects.
35
+ - Prefer IgniteFuse semantic roles: `outerWall`, `innerWall`, `infill`, `solidInfill`, `top`, `bottom`, `support`, `travel`.
36
+ - Prefer `fillRegionLayer()` for standard direct solid bottom/top behavior.
37
+ - Prefer `toolpath({ printer, layerHeight })`.
38
+ - Prefer canonical printer shapes from `ignitefuse-printer-scene`.
39
+ - For standard solid line fill, default to alternating `45` / `-45` degree angles, but treat the angle as customizable. If the prompt implies shape-specific direction, load direction, surface quality, or user control, expose a Param and pass `bottomAngle`, `topAngle`, or `sparseAngle` explicitly.
40
+ - For open-top cases, build the bottom floor region stack only for the bottom layers unless the user asks for top solid near the final layers.
41
+
42
+ ## References
43
+
44
+ - For complete `.fuse.js` API shape and minimal examples, read `references/api-shape.md`.
45
+ - For function implementation rules inside `.fuse.js`, read `references/function-implementation.md`.
46
+ - For a canonical 100 x 100 x 50 mm open-top case with solid bottom, read `references/direct-open-case-solid-bottom.md`.
47
+ - For direct region fill rules and invalid patterns, read `references/direct-region-fill.md`.
48
+ - For STL slicing with walls and fill, read `references/stl-standard-fdm.md`.
@@ -0,0 +1,211 @@
1
+ # IgniteFuse `.fuse.js` API Shape
2
+
3
+ Use this reference when local API shape is uncertain. A complete `.fuse.js` manufacturing document has three explicit phases.
4
+
5
+ ## Complete File Order
6
+
7
+ ```txt
8
+ 1. Printer and scene declarations
9
+ printer(...)
10
+ // ignite-fuse:placements:start
11
+ const igniteFusePlacedItems = [...]
12
+ // ignite-fuse:placements:end
13
+ exportScene({ printer: machine, items: igniteFusePlacedItems })
14
+
15
+ 2. Generated UI parameters
16
+ Param.number(...)
17
+ Param.boolean(...)
18
+ Param.select(...)
19
+ Param.text(...)
20
+
21
+ 3. Pure helper functions
22
+ geometry point builders, bounds helpers, role helpers
23
+
24
+ 4. Toolpath phase
25
+ exportToolpath(async () => {
26
+ const graph = toolpath({ printer: machine, layerHeight })
27
+ ...
28
+ graph.addLayer({ plane, distance, layerIndex, paths })
29
+ return graph
30
+ })
31
+
32
+ 5. G-code export phase
33
+ onExportGcode(({ graph, generateGcode, editGcode }) => string)
34
+ ```
35
+
36
+ Do not replace this with raw `ToolpathPath` JSON. Normal programs should use IgniteFuse builders.
37
+
38
+ ## Core API Map
39
+
40
+ - `printer(profile)`: defines build area, machine frame, nozzle, filament, and output flavor.
41
+ - `model(path, placement)`: declares an STL/model scene item.
42
+ - `exportScene({ printer, items })`: scene metadata only. `items` should be `model(...)` placements, not direct path previews.
43
+ - `Param.number(...)`, `Param.select(...)`, `Param.boolean(...)`, `Param.text(...)`: declare generated controls. Parameters are normal JS values when used later.
44
+ - `toolpath({ printer, layerHeight })`: creates a graph builder.
45
+ - `Plane.z(z)`, `Plane.zStack(...)`, `Plane.stack(...)`: create layer/section planes.
46
+ - `pathLayer(0, options)`: creates plane-local direct paths for a graph layer.
47
+ - `pathRegion(z)`: creates code-defined fill regions.
48
+ - `fillRegion(region, options)`: fills one explicit region with a deliberate role/pattern.
49
+ - `fillRegionLayer(regions, layerIndex, options)`: classifies direct region stacks into bottom/top/sparse fill.
50
+ - `perimeters(section, options)`: creates walls from sliced STL sections.
51
+ - `fillLayer(sections, layerIndex, options)`: creates bottom/top/sparse fill from sliced STL sections.
52
+ - `planLayerPaths(groups, options)`: orders path groups and can insert travel.
53
+ - `graph.addLayer({ plane, distance, layerIndex, paths })`: adds one layer; paths are plane-local at insertion.
54
+ - `onExportGcode(fn)`: registers G-code generation for the export phase only.
55
+
56
+ ## Job Layer Assembly
57
+
58
+ When a program combines multiple placed STL models, or mixes STL slicing with direct paths, collect generated layer results before calling `graph.addLayer(...)`.
59
+
60
+ - Use a shared `Plane[]` stack for all placed STL meshes in the same G-code job.
61
+ - Merge paths by identical Build-space `plane`, not by `z` alone.
62
+ - Plane identity is `origin`, `normal`, `xAxis`, and `yAxis` after normalization/rounding.
63
+ - Expose a generated control such as `Param.boolean("Merge Coplanar Layers", true, ...)` when users may want to keep layers separate for ordering, diagnostics, or custom post-processing.
64
+ - Apply G-code options such as `align` only once at job export, not per placed model.
65
+ - G-code preview is layer-first as well: exported G-code should preserve `;LAYER:<index>` and `;IF_LAYER_PLANE ...` comments so parsed machine moves can be assigned back to Build-space layer frames.
66
+
67
+ ## Minimal Model-Less Direct Program
68
+
69
+ ```js
70
+ const machine = printer({
71
+ name: "Generic FDM 220",
72
+ buildArea: { x: [0, 220], y: [0, 220], z: [0, 250] },
73
+ machineFrame: {
74
+ origin: [0, 0, 0],
75
+ xAxis: [1, 0, 0],
76
+ yAxis: [0, 1, 0],
77
+ zAxis: [0, 0, 1],
78
+ bounds: { x: [0, 220], y: [0, 220], z: [0, 250] },
79
+ },
80
+ nozzle: 0.4,
81
+ filament: 1.75,
82
+ gcodeFlavor: "marlin",
83
+ })
84
+
85
+ // ignite-fuse:placements:start
86
+ const igniteFusePlacedItems = [
87
+ ]
88
+ // ignite-fuse:placements:end
89
+
90
+ exportScene({
91
+ printer: machine,
92
+ items: igniteFusePlacedItems,
93
+ })
94
+
95
+ const layerHeight = Param.number("Layer Height", 0.2, {
96
+ group: "Slicing",
97
+ min: 0.08,
98
+ max: 0.4,
99
+ step: 0.02,
100
+ unit: "mm",
101
+ })
102
+
103
+ const lineWidth = Param.number("Line Width", 0.44, {
104
+ group: "Toolpath",
105
+ min: 0.3,
106
+ max: 0.8,
107
+ step: 0.01,
108
+ unit: "mm",
109
+ })
110
+
111
+ exportToolpath(async () => {
112
+ const z = layerHeight
113
+ const plane = Plane.z(z)
114
+ const graph = toolpath({ printer: machine, layerHeight })
115
+ const layer = pathLayer(0, { layerIndex: 0, layerHeight, lineWidth })
116
+
117
+ layer.polygon("outerWall", [[20, 20], [80, 20], [80, 80], [20, 80]])
118
+
119
+ graph.addLayer({
120
+ plane,
121
+ distance: z,
122
+ layerIndex: 0,
123
+ paths: layer.paths,
124
+ })
125
+
126
+ return graph
127
+ })
128
+
129
+ onExportGcode(({ graph, generateGcode, editGcode }) => {
130
+ return editGcode(generateGcode(graph, {
131
+ filament: { nozzleTemp: 210, bedTemp: 60 },
132
+ output: { flavor: "marlin", style: "orca" },
133
+ start: { mode: "standard" },
134
+ end: { mode: "standard" },
135
+ }))
136
+ .insertBeforeEnd("M107")
137
+ .toString()
138
+ })
139
+ ```
140
+
141
+ ## STL-Backed Program Shape
142
+
143
+ ```js
144
+ const part = model("part.stl", {
145
+ id: "placed_part_1",
146
+ name: "part 1",
147
+ position: [20, 20, 0],
148
+ rotation: [0, 0, 0],
149
+ scale: [1, 1, 1],
150
+ })
151
+
152
+ const igniteFusePlacedItems = [
153
+ part,
154
+ ]
155
+
156
+ exportScene({
157
+ printer: machine,
158
+ items: igniteFusePlacedItems,
159
+ })
160
+
161
+ exportToolpath(async () => {
162
+ const mesh = part.mesh()
163
+ const bounds = mesh.bounds()
164
+ const planes = Plane.zStack({ min: bounds.min.z, max: bounds.max.z, pitch: layerHeight })
165
+ const sections = await sliceStackParallel(mesh, planes, { workerPool: true })
166
+ const layers = await parallelLayers(
167
+ sections,
168
+ {
169
+ infillDensity,
170
+ layerHeight,
171
+ lineWidth,
172
+ solidFillAngle,
173
+ solidLayers,
174
+ sparsePattern,
175
+ wallCount,
176
+ },
177
+ ({ section, sections, layerIndex, plane, distance, z }) => {
178
+ const walls = perimeters(section, { count: wallCount, lineWidth, layerHeight })
179
+ const fill = fillLayer(sections, layerIndex, {
180
+ bottomAngle: solidFillAngle,
181
+ bottomPattern: "monotonic",
182
+ topAngle: -solidFillAngle,
183
+ topPattern: "monotonicLine",
184
+ sparseAngle: solidFillAngle,
185
+ sparsePattern,
186
+ density: infillDensity,
187
+ lineWidth,
188
+ layerHeight,
189
+ margin: wallCount * lineWidth,
190
+ solidLayers,
191
+ })
192
+
193
+ return {
194
+ plane,
195
+ distance,
196
+ z,
197
+ paths: planLayerPaths([walls, fill.bottom, fill.top, fill.sparse], {
198
+ roleOrder: ["outerWall", "innerWall", "bottom", "top", "infill"],
199
+ travel: true,
200
+ }),
201
+ }
202
+ },
203
+ { sectionWindow: solidLayers, workerPool: true },
204
+ )
205
+
206
+ const graph = toolpath({ printer: machine, layerHeight })
207
+ for (const layer of layers) graph.addLayer(layer)
208
+
209
+ return graph
210
+ })
211
+ ```