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
@@ -0,0 +1,193 @@
1
+ # Direct Open Case With Solid Bottom
2
+
3
+ Use this pattern for prompts such as "100x100mm, height 50mm case, bottom is solid fill" when no STL model is involved.
4
+
5
+ Key points:
6
+
7
+ - Direct walls use `pathLayer().polygon("outerWall" | "innerWall", ...)`.
8
+ - `exportScene.items` is only for STL/model placements; direct path geometry appears in the toolpath stage.
9
+ - Bottom floor uses a stack of `pathRegion()` entries only for the solid bottom layers.
10
+ - Standard bottom solid is generated by `fillRegionLayer()`, not a custom raster loop.
11
+ - Solid line fill defaults to alternating `45` / `-45` degrees, but expose the angle as a parameter when customization is useful.
12
+ - Add layers with `graph.addLayer({ plane, distance, layerIndex, paths })`.
13
+
14
+ ```js
15
+ const machine = printer({
16
+ name: "Generic FDM 220",
17
+ buildArea: { x: [0, 220], y: [0, 220], z: [0, 250] },
18
+ machineFrame: {
19
+ origin: [0, 0, 0],
20
+ xAxis: [1, 0, 0],
21
+ yAxis: [0, 1, 0],
22
+ zAxis: [0, 0, 1],
23
+ bounds: { x: [0, 220], y: [0, 220], z: [0, 250] },
24
+ },
25
+ nozzle: 0.4,
26
+ filament: 1.75,
27
+ gcodeFlavor: "marlin",
28
+ })
29
+
30
+ const nozzle = Param.number("Nozzle Diameter", 0.4, {
31
+ group: "Printer",
32
+ description: "Nominal nozzle diameter used by toolpath defaults.",
33
+ min: 0.2,
34
+ max: 1.2,
35
+ step: 0.05,
36
+ unit: "mm",
37
+ })
38
+
39
+ const sizeX = Param.number("Width", 100, {
40
+ group: "Case",
41
+ description: "Outer case width.",
42
+ min: 20,
43
+ max: 180,
44
+ step: 1,
45
+ unit: "mm",
46
+ })
47
+
48
+ const sizeY = Param.number("Depth", 100, {
49
+ group: "Case",
50
+ description: "Outer case depth.",
51
+ min: 20,
52
+ max: 180,
53
+ step: 1,
54
+ unit: "mm",
55
+ })
56
+
57
+ const height = Param.number("Height", 50, {
58
+ group: "Case",
59
+ description: "Case height.",
60
+ min: 5,
61
+ max: 180,
62
+ step: 1,
63
+ unit: "mm",
64
+ })
65
+
66
+ const layerHeight = Param.number("Layer Height", 0.2, {
67
+ group: "Slicing",
68
+ description: "Distance between generated layers.",
69
+ min: 0.08,
70
+ max: 0.4,
71
+ step: 0.02,
72
+ unit: "mm",
73
+ })
74
+
75
+ const lineWidth = Param.number("Line Width", nozzle * 1.1, {
76
+ group: "Toolpath",
77
+ description: "Extrusion path width used for walls and generated paths.",
78
+ min: nozzle * 0.8,
79
+ max: nozzle * 1.6,
80
+ step: 0.02,
81
+ unit: "mm",
82
+ })
83
+
84
+ const wallCount = Param.number("Wall Count", 3, {
85
+ group: "Toolpath",
86
+ description: "Number of inset outline loops per layer.",
87
+ min: 1,
88
+ max: 6,
89
+ step: 1,
90
+ })
91
+
92
+ const bottomLayers = Param.number("Bottom Layers", 6, {
93
+ group: "Toolpath",
94
+ description: "Number of solid bottom layers.",
95
+ min: 1,
96
+ max: 12,
97
+ step: 1,
98
+ })
99
+
100
+ const solidFillAngle = Param.number("Solid Fill Angle", 45, {
101
+ group: "Infill",
102
+ description: "Base angle for solid bottom fill lines. Adjacent layers use the opposite angle.",
103
+ min: -90,
104
+ max: 90,
105
+ step: 5,
106
+ unit: "deg",
107
+ })
108
+
109
+ const center = [110, 110]
110
+
111
+ const rectangle = (inset = 0) => {
112
+ const minX = center[0] - sizeX / 2 + inset
113
+ const maxX = center[0] + sizeX / 2 - inset
114
+ const minY = center[1] - sizeY / 2 + inset
115
+ const maxY = center[1] + sizeY / 2 - inset
116
+ return [[minX, minY], [maxX, minY], [maxX, maxY], [minX, maxY]]
117
+ }
118
+
119
+ // ignite-fuse:placements:start
120
+ const igniteFusePlacedItems = [
121
+ ]
122
+ // ignite-fuse:placements:end
123
+
124
+ exportScene({
125
+ printer: machine,
126
+ items: igniteFusePlacedItems,
127
+ })
128
+
129
+ exportToolpath(async () => {
130
+ const graph = toolpath({ printer: machine, layerHeight })
131
+ const layerCount = Math.max(1, Math.ceil(height / layerHeight))
132
+ const walls = Math.max(1, Math.round(wallCount))
133
+ const solidBottomLayers = Math.min(layerCount, Math.max(1, Math.round(bottomLayers)))
134
+ const fillInset = walls * lineWidth + lineWidth * 0.5
135
+
136
+ const bottomRegions = Array.from({ length: solidBottomLayers }, (_, index) => {
137
+ const z = Number(((index + 1) * layerHeight).toFixed(3))
138
+ return pathRegion(z).polygon(rectangle(fillInset))
139
+ })
140
+
141
+ for (let layerIndex = 0; layerIndex < layerCount; layerIndex += 1) {
142
+ const z = Number(((layerIndex + 1) * layerHeight).toFixed(3))
143
+ const plane = Plane.z(z)
144
+ const layer = pathLayer(0, { layerIndex, layerHeight, lineWidth })
145
+
146
+ for (let wall = 0; wall < walls; wall += 1) {
147
+ const role = wall === 0 ? "outerWall" : "innerWall"
148
+ layer.polygon(role, rectangle(wall * lineWidth))
149
+ }
150
+
151
+ const layerPathGroups = [layer.paths]
152
+
153
+ if (layerIndex < bottomRegions.length) {
154
+ const bottomFill = fillRegionLayer(bottomRegions, layerIndex, {
155
+ solidLayers: bottomRegions.length,
156
+ bottomAngle: layerIndex % 2 === 0 ? solidFillAngle : -solidFillAngle,
157
+ bottomPattern: "monotonic",
158
+ topAngle: layerIndex % 2 === 0 ? solidFillAngle : -solidFillAngle,
159
+ topPattern: "monotonicLine",
160
+ sparsePattern: "rectilinear",
161
+ density: 0,
162
+ lineWidth,
163
+ layerHeight,
164
+ })
165
+
166
+ layerPathGroups.push(bottomFill.bottom, bottomFill.top)
167
+ }
168
+
169
+ graph.addLayer({
170
+ plane,
171
+ distance: z,
172
+ layerIndex,
173
+ paths: planLayerPaths(layerPathGroups, {
174
+ roleOrder: ["outerWall", "innerWall", "bottom", "top"],
175
+ travel: true,
176
+ }),
177
+ })
178
+ }
179
+
180
+ return graph
181
+ })
182
+
183
+ onExportGcode(({ graph, generateGcode, editGcode }) => {
184
+ return editGcode(generateGcode(graph, {
185
+ filament: { nozzleTemp: 210, bedTemp: 60 },
186
+ output: { flavor: "marlin", style: "orca" },
187
+ start: { mode: "standard" },
188
+ end: { mode: "standard" },
189
+ }))
190
+ .insertBeforeEnd("M107")
191
+ .toString()
192
+ })
193
+ ```
@@ -0,0 +1,34 @@
1
+ # Direct Region Fill Rules
2
+
3
+ Use `pathRegion()` when the geometry is code-defined rather than sliced from an STL.
4
+
5
+ Preferred APIs:
6
+
7
+ - `fillRegion(region, options)`: one explicit region fill, with a deliberate role and pattern.
8
+ - `fillRegionLayer(regionStack, layerIndex, options)`: standard layered bottom/top/sparse classification for direct regions.
9
+
10
+ For standard solid bottom/top behavior, delegate to `fillRegionLayer()` so holes, margins, field anchoring, and role semantics stay shared with normal fill.
11
+
12
+ Valid fill patterns are `rectilinear`, `lines`, `monotonicLine`, `monotonic`, `grid`, `triangles`, and `concentric`. Sparse infill defaults to `rectilinear`: one optimized line direction per layer, rotated 90 degrees across adjacent layers. `grid` means two directions in the same layer. Bottom solid fill defaults to `monotonic`, which connects adjacent scan lines into as few strokes as possible to reduce travel. Top solid fill defaults to `monotonicLine`, the ordered independent-line solid pattern.
13
+
14
+ Valid roles are:
15
+
16
+ ```txt
17
+ outerWall, innerWall, infill, solidInfill, top, bottom, support, travel
18
+ ```
19
+
20
+ Prefer builders over raw path objects for normal programs, and keep roles in the IgniteFuse semantic role set.
21
+
22
+ Hole semantics:
23
+
24
+ ```js
25
+ const region = pathRegion(z)
26
+ .polygon(outer)
27
+ .hole(hole)
28
+
29
+ const equivalent = pathRegion(z)
30
+ .polygon(outer)
31
+ .polygon(hole, { hole: true })
32
+ ```
33
+
34
+ Explicit holes are winding-independent.
@@ -0,0 +1,137 @@
1
+ # `.fuse.js` Function Implementation Rules
2
+
3
+ Use this reference when writing helper functions or deciding where code belongs in a `.fuse.js` file.
4
+
5
+ ## Stage Boundaries
6
+
7
+ - Scene phase is declaration only: `printer(...)`, `model(...)`, placement block, and `exportScene(...)`.
8
+ - Toolpath phase builds manufacturing paths inside `exportToolpath(async () => ...)`.
9
+ - G-code export phase lowers an already-built graph inside `onExportGcode(...)`.
10
+ - Do not slice, load meshes, build region stacks, create fill, or generate G-code at top level.
11
+ - Do not put direct path geometry in `exportScene.items`; direct geometry belongs in the toolpath phase.
12
+
13
+ ## Top-Level Helpers
14
+
15
+ Top-level helper functions are allowed and preferred when they make geometry readable.
16
+
17
+ Good helper functions:
18
+
19
+ ```js
20
+ const rectangle = (inset = 0) => {
21
+ const minX = center[0] - sizeX / 2 + inset
22
+ const maxX = center[0] + sizeX / 2 - inset
23
+ const minY = center[1] - sizeY / 2 + inset
24
+ const maxY = center[1] + sizeY / 2 - inset
25
+ return [[minX, minY], [maxX, minY], [maxX, maxY], [minX, maxY]]
26
+ }
27
+ ```
28
+
29
+ ```js
30
+ const makeSolidFillOptions = (layerIndex) => ({
31
+ bottomAngle: layerIndex % 2 === 0 ? solidFillAngle : -solidFillAngle,
32
+ bottomPattern: "monotonic",
33
+ topAngle: layerIndex % 2 === 0 ? solidFillAngle : -solidFillAngle,
34
+ topPattern: "monotonicLine",
35
+ sparsePattern: "rectilinear",
36
+ density: 0,
37
+ lineWidth,
38
+ layerHeight,
39
+ })
40
+ ```
41
+
42
+ Keep helpers deterministic. They may read top-level Params and constants, but they should not mutate global state, call `graph.addLayer(...)`, call `generateGcode(...)`, or perform stage registration.
43
+
44
+ ## Direct Path Helpers
45
+
46
+ For direct paths, helpers should return points, regions, paths, or path groups.
47
+
48
+ Preferred pattern:
49
+
50
+ ```js
51
+ const makeWalls = (layerIndex) => {
52
+ const layer = pathLayer(0, { layerIndex, layerHeight, lineWidth })
53
+
54
+ for (let wall = 0; wall < wallCount; wall += 1) {
55
+ const role = wall === 0 ? "outerWall" : "innerWall"
56
+ layer.polygon(role, rectangle(wall * lineWidth))
57
+ }
58
+
59
+ return layer.paths
60
+ }
61
+ ```
62
+
63
+ Then add the result inside `exportToolpath(...)`:
64
+
65
+ ```js
66
+ const layerPathGroups = [makeWalls(layerIndex)]
67
+ graph.addLayer({ plane, distance: z, layerIndex, paths: planLayerPaths(layerPathGroups, options) })
68
+ ```
69
+
70
+ Avoid helpers that return raw JSON path objects for normal toolpaths. Use `pathLayer()`, `pathRegion()`, `fillRegion()`, `fillRegionLayer()`, `perimeters()`, or `fillLayer()`.
71
+
72
+ ## Region And Fill Helpers
73
+
74
+ Use `pathRegion(z)` for code-defined printable areas. Build a stack when the fill needs bottom/top/sparse classification:
75
+
76
+ ```js
77
+ const regions = Array.from({ length: solidLayers }, (_, index) => {
78
+ const z = Number(((index + 1) * layerHeight).toFixed(3))
79
+ return pathRegion(z).polygon(rectangle(fillInset))
80
+ })
81
+ ```
82
+
83
+ Use explicit holes:
84
+
85
+ ```js
86
+ pathRegion(z)
87
+ .polygon(outer)
88
+ .hole(inner)
89
+ ```
90
+
91
+ or:
92
+
93
+ ```js
94
+ pathRegion(z)
95
+ .polygon(outer)
96
+ .polygon(inner, { hole: true })
97
+ ```
98
+
99
+ For standard solid bottom/top behavior, call `fillRegionLayer(...)`. Use custom internal fill only when the user explicitly wants a custom pattern or nonstandard path behavior.
100
+
101
+ ## `exportToolpath` Implementation
102
+
103
+ `exportToolpath(async () => { ... })` should:
104
+
105
+ - create `const graph = toolpath({ printer: machine, layerHeight })`
106
+ - compute planes, sections, regions, and paths
107
+ - add layers with `graph.addLayer({ plane, distance, layerIndex, paths })`
108
+ - return `graph`
109
+
110
+ Use `pathLayer(0, ...)` with an explicit `Plane` for direct paths. The layer paths are plane-local at insertion; the graph stores Build-space paths after insertion.
111
+
112
+ For STL programs, call `modelItem.mesh()` only inside `exportToolpath(...)`, then slice with `Plane.zStack(...)` or `Plane.stack(...)`.
113
+
114
+ For mixed programs or multiple placed STL models, do not call `graph.addLayer(...)` immediately for every part if those layers belong to the same job plane. Accumulate generated layer objects, merge by identical Build-space plane (`origin`, `normal`, `xAxis`, `yAxis`), and flush the merged layers to the graph in plane distance order. Keep a `Merge Coplanar Layers` boolean when users may need intentionally separate layers on the same plane.
115
+
116
+ ## `onExportGcode` Implementation
117
+
118
+ `onExportGcode(fn)` should only register a function. It should not run during scene or toolpath preview.
119
+
120
+ Canonical shape:
121
+
122
+ ```js
123
+ function makeGcode({ graph, generateGcode, editGcode }) {
124
+ return editGcode(generateGcode(graph, {
125
+ filament: { nozzleTemp: 210, bedTemp: 60 },
126
+ output: { flavor: "marlin", style: "orca" },
127
+ start: { mode: "standard" },
128
+ end: { mode: "standard" },
129
+ }))
130
+ .insertBeforeEnd("M107")
131
+ .toString()
132
+ }
133
+
134
+ onExportGcode(makeGcode)
135
+ ```
136
+
137
+ Do not mutate `graph` into machine coordinates. G-code lowering applies `printer.machineFrame`.
@@ -0,0 +1,50 @@
1
+ # STL Standard FDM Pattern
2
+
3
+ For STL-backed programs:
4
+
5
+ - Declare `model(...)` in the scene.
6
+ - Call `part.mesh()` only inside `exportToolpath(async () => ...)`.
7
+ - Generate planes with `Plane.zStack(...)`.
8
+ - Slice with `sliceStackParallel(mesh, planes, { workerPool: true })`.
9
+ - Use `perimeters(section, ...)` for walls.
10
+ - Use `fillLayer(sections, layerIndex, ...)` for bottom/top/sparse fill.
11
+ - Solid line fill defaults to `45` / `-45` degrees, but pass a named angle value when the program should expose customization.
12
+ - Use `parallelLayers(...)` for heavy per-layer work.
13
+
14
+ For multiple placed STL models in one G-code job, build one shared plane stack from the combined model bounds, slice each mesh with that same `Plane[]`, and merge generated paths by identical Build-space plane. Do not merge by `z` alone; tilted or non-horizontal stacks can share neither Z nor horizontal semantics. If the program intentionally needs separate layers on the same plane, expose a boolean parameter such as `Merge Coplanar Layers`.
15
+
16
+ Minimal layer callback shape:
17
+
18
+ ```js
19
+ const layers = await parallelLayers(
20
+ sections,
21
+ { lineWidth, layerHeight, wallCount, solidLayers, infillDensity, solidFillAngle },
22
+ ({ section, sections, layerIndex, plane, distance, z }) => {
23
+ const walls = perimeters(section, { count: wallCount, lineWidth, layerHeight })
24
+ const fill = fillLayer(sections, layerIndex, {
25
+ bottomAngle: solidFillAngle,
26
+ bottomPattern: "monotonic",
27
+ topAngle: -solidFillAngle,
28
+ topPattern: "monotonicLine",
29
+ sparseAngle: solidFillAngle,
30
+ sparsePattern: "rectilinear",
31
+ density: infillDensity,
32
+ lineWidth,
33
+ layerHeight,
34
+ margin: wallCount * lineWidth,
35
+ solidLayers,
36
+ })
37
+
38
+ return {
39
+ plane,
40
+ distance,
41
+ z,
42
+ paths: planLayerPaths([walls, fill.bottom, fill.top, fill.sparse], {
43
+ roleOrder: ["outerWall", "innerWall", "bottom", "top", "infill"],
44
+ travel: true,
45
+ }),
46
+ }
47
+ },
48
+ { sectionWindow: solidLayers, workerPool: true },
49
+ )
50
+ ```
@@ -0,0 +1,24 @@
1
+ ---
2
+ name: ignitefuse-params
3
+ description: Use when defining IgniteFuse Param.number, Param.boolean, Param.select, or Param.text controls for generated UI, slicer/toolpath settings, printer dimensions, case dimensions, layer settings, fill settings, or when converting hard-coded .fuse.js constants into user-editable parameters.
4
+ ---
5
+
6
+ # IgniteFuse Params
7
+
8
+ Use this skill for generated UI parameters in `.fuse.js`.
9
+
10
+ ## Rules
11
+
12
+ - Manufacturing behavior belongs in `.fuse.js`; use `Param.*` for user-editable values instead of GUI-owned slicer settings.
13
+ - Give every parameter a clear `group`.
14
+ - Prefer `description`, `min`, `max`, `step`, and `unit` for numeric controls.
15
+ - Use `Param.number` for dimensions, counts, density, angles, speeds, and widths.
16
+ - Use `Param.select` for discrete pattern or mode choices.
17
+ - Use `Param.boolean` for toggles.
18
+ - Use `Param.text` only for user-facing names or simple string inputs.
19
+ - Use integer steps for counts such as wall count, solid layers, and bottom layers.
20
+ - Use dependent defaults for related manufacturing values, such as `lineWidth` derived from `nozzle`.
21
+
22
+ ## References
23
+
24
+ - For canonical parameter snippets and ranges, read `references/param-patterns.md`.
@@ -0,0 +1,153 @@
1
+ # IgniteFuse Parameter Patterns
2
+
3
+ Use these patterns when creating complete `.fuse.js` programs from an empty source.
4
+
5
+ ## Printer And Slicing
6
+
7
+ ```js
8
+ const nozzle = Param.number("Nozzle Diameter", 0.4, {
9
+ group: "Printer",
10
+ description: "Nominal nozzle diameter used by toolpath defaults.",
11
+ min: 0.2,
12
+ max: 1.2,
13
+ step: 0.05,
14
+ unit: "mm",
15
+ })
16
+
17
+ const layerHeight = Param.number("Layer Height", 0.2, {
18
+ group: "Slicing",
19
+ description: "Distance between generated layers.",
20
+ min: 0.08,
21
+ max: 0.4,
22
+ step: 0.02,
23
+ unit: "mm",
24
+ })
25
+
26
+ const lineWidth = Param.number("Line Width", nozzle * 1.1, {
27
+ group: "Toolpath",
28
+ description: "Extrusion path width used for walls and generated paths.",
29
+ min: nozzle * 0.8,
30
+ max: nozzle * 1.6,
31
+ step: 0.02,
32
+ unit: "mm",
33
+ })
34
+ ```
35
+
36
+ ## Direct Case Dimensions
37
+
38
+ ```js
39
+ const sizeX = Param.number("Width", 100, {
40
+ group: "Case",
41
+ description: "Outer case width.",
42
+ min: 20,
43
+ max: 180,
44
+ step: 1,
45
+ unit: "mm",
46
+ })
47
+
48
+ const sizeY = Param.number("Depth", 100, {
49
+ group: "Case",
50
+ description: "Outer case depth.",
51
+ min: 20,
52
+ max: 180,
53
+ step: 1,
54
+ unit: "mm",
55
+ })
56
+
57
+ const height = Param.number("Height", 50, {
58
+ group: "Case",
59
+ description: "Case height.",
60
+ min: 5,
61
+ max: 180,
62
+ step: 1,
63
+ unit: "mm",
64
+ })
65
+ ```
66
+
67
+ ## Walls And Solid Layers
68
+
69
+ ```js
70
+ const wallCount = Param.number("Wall Count", 3, {
71
+ group: "Toolpath",
72
+ description: "Number of inset outline loops per layer.",
73
+ min: 1,
74
+ max: 6,
75
+ step: 1,
76
+ })
77
+
78
+ const bottomLayers = Param.number("Bottom Layers", 6, {
79
+ group: "Toolpath",
80
+ description: "Number of solid bottom layers.",
81
+ min: 1,
82
+ max: 12,
83
+ step: 1,
84
+ })
85
+
86
+ const solidLayers = Param.number("Solid Layers", 3, {
87
+ group: "Toolpath",
88
+ description: "Number of top and bottom solid layers for sliced models.",
89
+ min: 1,
90
+ max: 8,
91
+ step: 1,
92
+ })
93
+ ```
94
+
95
+ ## Fill And Pattern Controls
96
+
97
+ ```js
98
+ const infillDensity = Param.number("Infill Density", 0.18, {
99
+ group: "Infill",
100
+ description: "Sparse infill density from 0 to 1.",
101
+ min: 0,
102
+ max: 1,
103
+ step: 0.02,
104
+ })
105
+
106
+ const sparsePattern = Param.select("Sparse Pattern", ["rectilinear", "lines", "grid", "triangles", "concentric"], "rectilinear", {
107
+ group: "Infill",
108
+ description: "Pattern used for sparse infill.",
109
+ })
110
+
111
+ const bottomPattern = Param.select("Bottom Pattern", ["monotonic", "monotonicLine", "rectilinear", "lines", "grid", "triangles", "concentric"], "monotonic", {
112
+ group: "Infill",
113
+ description: "Pattern used for solid bottom fill.",
114
+ })
115
+
116
+ const topPattern = Param.select("Top Pattern", ["monotonicLine", "rectilinear", "lines", "grid", "triangles", "concentric", "monotonic"], "monotonicLine", {
117
+ group: "Infill",
118
+ description: "Pattern used for solid top fill.",
119
+ })
120
+
121
+ const solidFillAngle = Param.number("Solid Fill Angle", 45, {
122
+ group: "Infill",
123
+ description: "Base angle for solid line fill. Adjacent layers can use the opposite angle.",
124
+ min: -90,
125
+ max: 90,
126
+ step: 5,
127
+ unit: "deg",
128
+ })
129
+ ```
130
+
131
+ ## Path Effects
132
+
133
+ Use effect parameters only when the program actually applies modifiers.
134
+
135
+ ```js
136
+ const pathNoise = Param.number("Path Noise", 0.04, {
137
+ group: "Path Effects",
138
+ description: "Sine-wave perturbation applied to generated paths.",
139
+ min: 0,
140
+ max: 0.3,
141
+ step: 0.01,
142
+ unit: "mm",
143
+ })
144
+ ```
145
+
146
+ ## Naming
147
+
148
+ - Labels should be short and human-readable: `"Layer Height"`, `"Line Width"`, `"Wall Count"`.
149
+ - Use `group: "Printer"` for nozzle and filament-related defaults.
150
+ - Use `group: "Slicing"` for layer pitch/height.
151
+ - Use `group: "Toolpath"` for wall and path construction values.
152
+ - Use `group: "Infill"` for density and pattern controls.
153
+ - Use a domain group such as `"Case"` for part dimensions.
@@ -0,0 +1,26 @@
1
+ ---
2
+ name: ignitefuse-printer-scene
3
+ description: Use when defining IgniteFuse printer profiles, build areas, machine frames, exportScene metadata, STL/model placements, or scene construction.
4
+ ---
5
+
6
+ # IgniteFuse Printer And Scene
7
+
8
+ Use this skill for canonical printer and scene definitions in `.fuse.js`.
9
+
10
+ ## Rules
11
+
12
+ - New programs must define work area with `buildArea { x, y, z }`.
13
+ - New programs must define machine coordinates with top-level `machineFrame`.
14
+ - Put optional machine-space ranges under `machineFrame.bounds`.
15
+ - Represent belt-like or skewed machines with `machineFrame` and optional `process`, not a printer `type`.
16
+ - `exportScene(...)` declares the printer and model placement items; it does not own slicer settings.
17
+ - `exportScene.items` should contain STL/model placement items from `model(...)` or `igniteFusePlacedItems`.
18
+ - For model-less direct path programs, keep scene items empty or use the standard empty placement block.
19
+
20
+ ## Canonical Shape
21
+
22
+ Keep work-area dimensions in `printer.buildArea`; `exportScene(...)` should reference the printer and placed model items.
23
+
24
+ ## References
25
+
26
+ - For canonical printer and scene snippets, read `references/canonical-printer-scene.md`.