three-slicer 0.1.6 → 0.2.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 (43) hide show
  1. package/CHANGELOG.md +35 -0
  2. package/README.md +310 -22
  3. package/THIRD-PARTY-NOTICES.md +37 -0
  4. package/components/README.md +2 -0
  5. package/components/dist/SettingsPanel.js +92 -92
  6. package/data/config-schema.json +698 -0
  7. package/data/filaments.js +1 -1
  8. package/data/preset-keys.json +1 -0
  9. package/data/printers.json +1 -1
  10. package/data/processes.js +1 -1
  11. package/data/ui-tree.json +342 -0
  12. package/engine/README.md +279 -3
  13. package/engine/examples/sla_headless.mjs +51 -0
  14. package/engine/index.d.ts +77 -5
  15. package/engine/index.js +15 -4
  16. package/engine/src/client.js +165 -0
  17. package/engine/src/data.js +3 -0
  18. package/engine/src/preset_file.js +99 -0
  19. package/engine/src/settings.js +232 -0
  20. package/engine/src/sla_core.js +188 -0
  21. package/engine/src/sla_request.js +185 -0
  22. package/engine/src/slicer.worker.js +76 -4
  23. package/engine/src/slicer_core.js +0 -0
  24. package/engine/src/slicer_core.mt.js +0 -0
  25. package/package.json +26 -11
  26. package/types/client.d.ts +88 -0
  27. package/types/components.d.ts +10 -0
  28. package/types/data/preset-keys.json.d.ts +20 -0
  29. package/types/data/printers.json.d.ts +2 -2
  30. package/types/data.d.ts +4 -0
  31. package/types/settings-keys.d.ts +107 -1
  32. package/types/settings.d.ts +116 -1
  33. package/types/sla.d.ts +167 -0
  34. package/types/viewer.d.ts +59 -1
  35. package/types/worker.d.ts +95 -0
  36. package/viewer/README.md +163 -3
  37. package/viewer/dist/Viewport.js +3633 -3137
  38. package/viewer/dist/model_loaders.js +1 -1
  39. package/viewer/dist/parse_3mf-C2X_W442.js +300 -0
  40. package/viewer/dist/parse_3mf.worker.js +1 -1
  41. package/viewer/styles.css +5 -0
  42. package/types/gen_settings_types.mjs +0 -70
  43. package/viewer/dist/parse_3mf-8oCnCJNK.js +0 -216
package/data/ui-tree.json CHANGED
@@ -1277,5 +1277,347 @@
1277
1277
  }
1278
1278
  ]
1279
1279
  }
1280
+ ],
1281
+ "TabPrinter::build_sla": [
1282
+ {
1283
+ "page": "General",
1284
+ "icon": "printer",
1285
+ "line": 3016,
1286
+ "groups": [
1287
+ {
1288
+ "group": "Size and coordinates",
1289
+ "line": 3017,
1290
+ "options": [
1291
+ "max_print_height"
1292
+ ]
1293
+ },
1294
+ {
1295
+ "group": "Display",
1296
+ "line": 3024,
1297
+ "options": [
1298
+ "display_width",
1299
+ "display_height",
1300
+ "<custom-widget line:3032>",
1301
+ "display_orientation",
1302
+ "display_mirror_x",
1303
+ "display_mirror_y"
1304
+ ]
1305
+ },
1306
+ {
1307
+ "group": "Tilt",
1308
+ "line": 3039,
1309
+ "options": [
1310
+ "<custom-widget line:3044>"
1311
+ ]
1312
+ },
1313
+ {
1314
+ "group": "Corrections",
1315
+ "line": 3046,
1316
+ "options": [
1317
+ "<custom-widget line:3053>",
1318
+ "absolute_correction",
1319
+ "elefant_foot_compensation",
1320
+ "elefant_foot_min_width",
1321
+ "gamma_correction"
1322
+ ]
1323
+ },
1324
+ {
1325
+ "group": "Exposure",
1326
+ "line": 3059,
1327
+ "options": [
1328
+ "min_exposure_time",
1329
+ "max_exposure_time",
1330
+ "min_initial_exposure_time",
1331
+ "max_initial_exposure_time"
1332
+ ]
1333
+ },
1334
+ {
1335
+ "group": "Output",
1336
+ "line": 3066,
1337
+ "options": [
1338
+ "sla_archive_format",
1339
+ "sla_output_precision"
1340
+ ]
1341
+ }
1342
+ ]
1343
+ },
1344
+ {
1345
+ "page": "Notes",
1346
+ "icon": "note",
1347
+ "line": 3074,
1348
+ "groups": [
1349
+ {
1350
+ "group": "Notes",
1351
+ "line": 3075,
1352
+ "options": []
1353
+ }
1354
+ ]
1355
+ },
1356
+ {
1357
+ "page": "Dependencies",
1358
+ "icon": "wrench",
1359
+ "line": 3081,
1360
+ "groups": [
1361
+ {
1362
+ "group": "Profile dependencies",
1363
+ "line": 3082,
1364
+ "options": []
1365
+ }
1366
+ ]
1367
+ }
1368
+ ],
1369
+ "TabSLAMaterial::build": [
1370
+ {
1371
+ "page": "Material",
1372
+ "icon": "resin",
1373
+ "line": 5437,
1374
+ "groups": [
1375
+ {
1376
+ "group": "Material",
1377
+ "line": 5439,
1378
+ "options": [
1379
+ "material_colour",
1380
+ "bottle_cost",
1381
+ "bottle_volume",
1382
+ "bottle_weight",
1383
+ "material_density"
1384
+ ]
1385
+ },
1386
+ {
1387
+ "group": "Layers",
1388
+ "line": 5478,
1389
+ "options": [
1390
+ "initial_layer_height"
1391
+ ]
1392
+ },
1393
+ {
1394
+ "group": "Exposure",
1395
+ "line": 5481,
1396
+ "options": [
1397
+ "exposure_time",
1398
+ "initial_exposure_time"
1399
+ ]
1400
+ },
1401
+ {
1402
+ "group": "Corrections",
1403
+ "line": 5485,
1404
+ "options": [
1405
+ "<custom-widget line:5492>",
1406
+ "zcorrection_layers",
1407
+ "<custom-widget line:5502>"
1408
+ ]
1409
+ }
1410
+ ]
1411
+ },
1412
+ {
1413
+ "page": "Notes",
1414
+ "icon": "note",
1415
+ "line": 5506,
1416
+ "groups": [
1417
+ {
1418
+ "group": "Notes",
1419
+ "line": 5507,
1420
+ "options": []
1421
+ }
1422
+ ]
1423
+ },
1424
+ {
1425
+ "page": "Dependencies",
1426
+ "icon": "wrench",
1427
+ "line": 5514,
1428
+ "groups": [
1429
+ {
1430
+ "group": "Profile dependencies",
1431
+ "line": 5515,
1432
+ "options": []
1433
+ }
1434
+ ]
1435
+ },
1436
+ {
1437
+ "page": "Material printing profile",
1438
+ "icon": "note",
1439
+ "line": 5535,
1440
+ "groups": [
1441
+ {
1442
+ "group": "Material printing profile",
1443
+ "line": 5537,
1444
+ "options": [
1445
+ "material_print_speed"
1446
+ ]
1447
+ },
1448
+ {
1449
+ "group": "Tilt",
1450
+ "line": 5540,
1451
+ "options": [
1452
+ "area_fill"
1453
+ ]
1454
+ },
1455
+ {
1456
+ "group": "Temperature",
1457
+ "line": 5543,
1458
+ "options": [
1459
+ "<custom-widget line:5560>",
1460
+ "<custom-widget line:5590>"
1461
+ ]
1462
+ }
1463
+ ]
1464
+ }
1465
+ ],
1466
+ "TabSLAPrint::build": [
1467
+ {
1468
+ "page": "Layers and perimeters",
1469
+ "icon": "layers",
1470
+ "line": 6066,
1471
+ "groups": [
1472
+ {
1473
+ "group": "Layers",
1474
+ "line": 6068,
1475
+ "options": [
1476
+ "layer_height",
1477
+ "faded_layers"
1478
+ ]
1479
+ }
1480
+ ]
1481
+ },
1482
+ {
1483
+ "page": "Supports",
1484
+ "icon": "support",
1485
+ "line": 6072,
1486
+ "groups": [
1487
+ {
1488
+ "group": "Supports",
1489
+ "line": 6074,
1490
+ "options": [
1491
+ "supports_enable",
1492
+ "support_tree_type",
1493
+ "support_enforcers_only"
1494
+ ]
1495
+ },
1496
+ {
1497
+ "group": "Automatic generation",
1498
+ "line": 6081,
1499
+ "options": [
1500
+ "support_points_density_relative"
1501
+ ]
1502
+ },
1503
+ {
1504
+ "group": "Support head",
1505
+ "line": 5864,
1506
+ "options": [
1507
+ "support_head_front_diameter",
1508
+ "support_head_penetration",
1509
+ "support_head_width"
1510
+ ]
1511
+ },
1512
+ {
1513
+ "group": "Support pillar",
1514
+ "line": 5869,
1515
+ "options": [
1516
+ "support_pillar_diameter",
1517
+ "support_small_pillar_diameter_percent",
1518
+ "support_max_bridges_on_pillar",
1519
+ "support_pillar_connection_mode",
1520
+ "support_buildplate_only",
1521
+ "support_pillar_widening_factor",
1522
+ "support_max_weight_on_model",
1523
+ "support_base_diameter",
1524
+ "support_base_height",
1525
+ "support_base_safety_distance",
1526
+ "support_object_elevation",
1527
+ "<custom-widget line:5890>"
1528
+ ]
1529
+ },
1530
+ {
1531
+ "group": "Connection of the support sticks and junctions",
1532
+ "line": 5892,
1533
+ "options": [
1534
+ "support_critical_angle",
1535
+ "support_max_bridge_length",
1536
+ "support_max_pillar_link_distance"
1537
+ ]
1538
+ }
1539
+ ]
1540
+ },
1541
+ {
1542
+ "page": "Pad",
1543
+ "icon": "pad",
1544
+ "line": 6084,
1545
+ "groups": [
1546
+ {
1547
+ "group": "Pad",
1548
+ "line": 6085,
1549
+ "options": [
1550
+ "pad_enable",
1551
+ "pad_wall_thickness",
1552
+ "pad_wall_height",
1553
+ "pad_brim_size",
1554
+ "pad_max_merge_distance",
1555
+ "pad_wall_slope",
1556
+ "pad_around_object",
1557
+ "pad_around_object_everywhere",
1558
+ "pad_object_gap",
1559
+ "pad_object_connector_stride",
1560
+ "pad_object_connector_width",
1561
+ "pad_object_connector_penetration"
1562
+ ]
1563
+ }
1564
+ ]
1565
+ },
1566
+ {
1567
+ "page": "Hollowing",
1568
+ "icon": "hollowing",
1569
+ "line": 6102,
1570
+ "groups": [
1571
+ {
1572
+ "group": "Hollowing",
1573
+ "line": 6103,
1574
+ "options": [
1575
+ "hollowing_enable",
1576
+ "hollowing_min_thickness",
1577
+ "hollowing_quality",
1578
+ "hollowing_closing_distance"
1579
+ ]
1580
+ }
1581
+ ]
1582
+ },
1583
+ {
1584
+ "page": "Advanced",
1585
+ "icon": "wrench",
1586
+ "line": 6109,
1587
+ "groups": [
1588
+ {
1589
+ "group": "Slicing",
1590
+ "line": 6110,
1591
+ "options": [
1592
+ "slice_closing_radius",
1593
+ "slicing_mode"
1594
+ ]
1595
+ }
1596
+ ]
1597
+ },
1598
+ {
1599
+ "page": "Output options",
1600
+ "icon": "output+page_white",
1601
+ "line": 6114,
1602
+ "groups": [
1603
+ {
1604
+ "group": "Output file",
1605
+ "line": 6115,
1606
+ "options": []
1607
+ }
1608
+ ]
1609
+ },
1610
+ {
1611
+ "page": "Dependencies",
1612
+ "icon": "wrench",
1613
+ "line": 6120,
1614
+ "groups": [
1615
+ {
1616
+ "group": "Profile dependencies",
1617
+ "line": 6121,
1618
+ "options": []
1619
+ }
1620
+ ]
1621
+ }
1280
1622
  ]
1281
1623
  }
package/engine/README.md CHANGED
@@ -37,7 +37,7 @@ Off-main-thread (browser): `new Worker(engineWorkerURL(), { type: 'module' })`
37
37
 
38
38
  Two levels — use whichever fits:
39
39
 
40
- 1. **Kernel params (this package's native contract)** — a flat JSON object of ~90 keys (`layer_height`, `wall_loops`, `infill_density` 0–1, `sparse_infill_pattern`, `enable_support`, `wall_generator: 'classic' | 'arachne'`, …). See `src/settings.js` for the full shape.
40
+ 1. **Kernel params (this package's native contract)** — a flat JSON object (`layer_height`, `wall_loops`, `infill_density` 0–1, `sparse_infill_pattern`, `enable_support`, `wall_generator: 'classic' | 'arachne'`, …). Every accepted key is listed under [Kernel parameter reference](#kernel-parameter-reference) below.
41
41
  2. **OrcaSlicer settings map** — a sparse `{schemaKey: value}` map using original OrcaSlicer option keys (923 defined in `three-slicer/data`); unset keys fall back to schema defaults:
42
42
 
43
43
  ```js
@@ -45,7 +45,253 @@ import { deriveKernelParams } from 'three-slicer/settings'
45
45
  slicer.slice(stl, deriveKernelParams({ layer_height: 0.25, sparse_infill_density: 15 }))
46
46
  ```
47
47
 
48
- **Known limit:** `deriveKernelParams` maps a curated whitelist of 92 schema keys to kernel params. Editing other schema keys has no slicing effect (they exist for UI/metadata). Scalar options use their first element only; the filament options listed under *Materials* below are the exception — those keep every extruder's entry.
48
+ **Known limit:** `deriveKernelParams` maps a curated subset of schema keys to kernel params. Editing other schema keys has no slicing effect (they exist for UI/metadata). Scalar options use their first element only; the filament options listed under *Materials* below are the exception — those keep every extruder's entry. Kernel parameters with no schema key behind them are reachable only by writing the params object yourself — the reference table marks which those are.
49
+
50
+ ## Kernel parameter reference
51
+
52
+ Generated from the kernel's own reader (`params.cpp`) — it is the definition of the accepted key set, so this table
53
+ cannot drift from what `slice()` actually honours. Regenerate with `node types/gen_kernel_params.mjs`.
54
+
55
+ <!-- KERNEL-PARAMS:BEGIN — generated by types/gen_kernel_params.mjs, do not edit by hand -->
56
+
57
+ The kernel accepts **159 parameters**. `deriveKernelParams()` produces 131 of them from the
58
+ OrcaSlicer settings map; the remaining 28 have no schema key behind them and can only be set by writing
59
+ the params object directly — those rows show `—` in the *From setting* column.
60
+
61
+ A parameter left out of the object keeps the default listed here, so sending a partial object is normal and is
62
+ what `deriveKernelParams()` itself does.
63
+
64
+ *From setting* names the schema key the value is read from, which is often **not** the same name and not the
65
+ same unit — `first_layer_height` comes from `initial_layer_print_height`, and `infill_density` is
66
+ `sparse_infill_density` divided by 100 (a settings map holding `20` produces `0.2` here).
67
+
68
+ ### Geometry and walls
69
+
70
+ | Kernel param | Type | Default | From setting | Notes |
71
+ | --- | --- | --- | --- | --- |
72
+ | `auto_center` | `boolean` | `false` | — | stage 28: true = realign the combined bbox to the origin (stage-3 legacy). false (default) = trust the viewer coordinates (no realignment, only Z seating) -> the toolpath overlaps the on-screen model exactly. Upstream = only the plate origin offset (GCode.cpp:932). |
73
+ | `first_layer_height` | `number` | `0.2` | `initial_layer_print_height` | |
74
+ | `gcode_resolution` | `number` | `0.01` | `resolution` | resolution (mm): path simplification tolerance. Upstream PrintConfig default 0.01 |
75
+ | `initial_layer_line_width` | `number` | `0` | `initial_layer_line_width` | |
76
+ | `inner_wall_line_width` | `number` | `0` | `inner_wall_line_width` | |
77
+ | `internal_solid_infill_line_width` | `number` | `0` | `internal_solid_infill_line_width` | |
78
+ | `layer_height` | `number` | `0.2` | `layer_height` | |
79
+ | `line_width` | `number` | `0.42` | `line_width` | |
80
+ | `outer_wall_line_width` | `number` | `0` | `outer_wall_line_width` | |
81
+ | `sparse_infill_line_width` | `number` | `0` | `sparse_infill_line_width` | |
82
+ | `spiral_mode` | `boolean` | `false` | `spiral_mode` | spiral_mode (vase) |
83
+ | `support_line_width` | `number` | `0.0` | `support_line_width` | support_line_width (0=auto; the real tree support extrusion width) |
84
+ | `top_surface_line_width` | `number` | `0` | `top_surface_line_width` | |
85
+ | `wall_generator` | `string` | `'classic'` | `wall_generator` | classic\|arachne (arachne = the real ported WallToolPaths) |
86
+ | `wall_loops` | `number` | `2` | `wall_loops` | |
87
+
88
+ ### Infill
89
+
90
+ | Kernel param | Type | Default | From setting | Notes |
91
+ | --- | --- | --- | --- | --- |
92
+ | `bottom_shell_layers` | `number` | `3` | `bottom_shell_layers` | top_shell_layers/bottom_shell_layers |
93
+ | `infill_angle` | `number` | `45.0` | `infill_direction` | infill_direction |
94
+ | `infill_density` | `number` | `0.15` | `sparse_infill_density` | |
95
+ | `ironing_flow` | `number` | `10.0` | `ironing_flow` | ironing flow (%) |
96
+ | `ironing_spacing` | `number` | `0.1` | `ironing_spacing` | ironing line spacing (mm) |
97
+ | `ironing_speed` | `number` | `30.0` | `ironing_speed` | ironing speed (mm/s) |
98
+ | `ironing_type` | `string` | `'none'` | `ironing_type` | none\|top\|topmost\|solid (the top family = on) |
99
+ | `sparse_infill_filament_id` | `number` | `0` | `sparse_infill_filament_id` | |
100
+ | `sparse_infill_pattern` | `string` | `'rectilinear'` | `sparse_infill_pattern` | rectilinear\|grid\|triangles\|zigzag\|gyroid |
101
+ | `top_shell_layers` | `number` | `4` | `top_shell_layers` | top_shell_layers/bottom_shell_layers |
102
+
103
+ ### Speeds, flow and temperature
104
+
105
+ | Kernel param | Type | Default | From setting | Notes |
106
+ | --- | --- | --- | --- | --- |
107
+ | `bed_temp` | `number` | `60` | `hot_plate_temp` | |
108
+ | `bridge_speed` | `number` | `25.0` | `bridge_speed` | bridge_speed[0] (slowdown for unsupported bottoms) |
109
+ | `close_fan_the_first_x_layers` | `number` | `1` | `close_fan_the_first_x_layers` | close_fan_the_first_x_layers |
110
+ | `enable_pressure_advance` | `boolean` | `false` | `enable_pressure_advance` | enable_pressure_advance[0] |
111
+ | `fan_speed` | `number` | `100.0` | `fan_max_speed` | fan_speed (%) |
112
+ | `filament_diameter` | `number` | `1.75` | `filament_diameter` | |
113
+ | `first_layer_speed` | `number` | `20` | `initial_layer_speed` | |
114
+ | `flow_ratio` | `number` | `1.0` | `filament_flow_ratio` | |
115
+ | `full_fan_speed_layer` | `number` | `3` | `full_fan_speed_layer` | full_fan_speed_layer |
116
+ | `machine_accel_print` | `number` | `5000` | `default_acceleration` | mm/s² |
117
+ | `machine_accel_retract` | `number` | `5000` | `machine_max_acceleration_retracting` | mm/s² |
118
+ | `machine_accel_travel` | `number` | `5000` | `travel_acceleration` | mm/s² |
119
+ | `machine_jerk_e` | `number` | `2.5` | `machine_max_jerk_e` | mm/s |
120
+ | `machine_jerk_xy` | `number` | `9.0` | `machine_max_jerk_x` | mm/s |
121
+ | `machine_jerk_z` | `number` | `0.4` | `machine_max_jerk_z` | mm/s |
122
+ | `machine_max_accel_e` | `number` | `5000` | `machine_max_acceleration_e` | mm/s² (machine_max_acceleration_*) — per-axis ceiling, distinct from the accel_* feedrates above |
123
+ | `machine_max_accel_xy` | `number` | `5000` | `machine_max_acceleration_x` | mm/s² (machine_max_acceleration_*) — per-axis ceiling, distinct from the accel_* feedrates above |
124
+ | `machine_max_accel_z` | `number` | `500` | `machine_max_acceleration_z` | mm/s² (machine_max_acceleration_*) — per-axis ceiling, distinct from the accel_* feedrates above |
125
+ | `machine_max_speed_e` | `number` | `30` | `machine_max_speed_e` | mm/s |
126
+ | `machine_max_speed_xy` | `number` | `500` | `machine_max_speed_x` | mm/s |
127
+ | `machine_max_speed_z` | `number` | `12` | `machine_max_speed_z` | mm/s |
128
+ | `max_volumetric_extrusion_rate_slope` | `number` | `0.0` | `max_volumetric_extrusion_rate_slope` | PE-lite flow change rate limit (mm³/s², 0=off) |
129
+ | `nozzle_diameter` | `number` | `0.4` | `nozzle_diameter` | |
130
+ | `nozzle_temp` | `number` | `210` | `nozzle_temperature` | |
131
+ | `pressure_advance` | `number` | `0.02` | `pressure_advance` | pressure_advance[0] |
132
+ | `print_speed` | `number` | `60` | `outer_wall_speed` | |
133
+ | `slow_down_layer_time` | `number` | `8.0` | `slow_down_layer_time` | slow_down_layer_time (s) |
134
+ | `travel_speed` | `number` | `150` | `travel_speed` | |
135
+
136
+ ### Retraction and seams
137
+
138
+ | Kernel param | Type | Default | From setting | Notes |
139
+ | --- | --- | --- | --- | --- |
140
+ | `retract_length` | `number` | `0.8` | `filament_retraction_length`, `retraction_length` | retraction_length/speed[0], z_hop[0] |
141
+ | `retract_speed` | `number` | `30.0` | `filament_retraction_speed`, `retraction_speed` | retraction_length/speed[0], z_hop[0] |
142
+ | `retraction_minimum_travel` | `number` | `2.0` | `filament_retraction_minimum_travel`, `retraction_minimum_travel` | retraction_minimum_travel (mm): minimum travel that triggers a retraction |
143
+ | `scarf_length` | `number` | `10.0` | — | length of the scarf z/flow ramp (mm) |
144
+ | `seam_position` | `string` | `'back'` | `seam_position` | nearest\|aligned\|back\|random |
145
+ | `seam_slope_type` | `string` | `'none'` | `seam_slope_type` | none\|external\|all -> scarf seam (external/all = on) |
146
+ | `z_hop` | `number` | `0.4` | `filament_z_hop`, `z_hop` | retraction_length/speed[0], z_hop[0] |
147
+
148
+ ### Adhesion (skirt, brim, raft)
149
+
150
+ | Kernel param | Type | Default | From setting | Notes |
151
+ | --- | --- | --- | --- | --- |
152
+ | `brim_object_gap` | `number` | `0.0` | `brim_object_gap` | brim_object_gap (mm): gap between brim and object |
153
+ | `brim_width` | `number` | `0.0` | `brim_width` | skirt_distance / brim_width |
154
+ | `raft_contact_distance` | `number` | `0.1` | `raft_contact_distance` | raft_contact_distance (mm) |
155
+ | `raft_expansion` | `number` | `1.5` | `raft_expansion` | raft_expansion (mm). Upstream default 1.5 (previously hardcoded to 3.0) |
156
+ | `raft_first_layer_height` | `number` | `0.30` | — | raft first layer height (mm) |
157
+ | `raft_layers` | `number` | `0` | `raft_layers` | raft_layers |
158
+ | `skirt_distance` | `number` | `2.0` | `skirt_distance` | skirt_distance / brim_width |
159
+ | `skirt_height` | `number` | `1` | `skirt_height` | skirt_height: how many layers the skirt is drawn on |
160
+ | `skirt_loops` | `number` | `1` | `skirt_loops` | skirt_loops |
161
+
162
+ ### Support
163
+
164
+ | Kernel param | Type | Default | From setting | Notes |
165
+ | --- | --- | --- | --- | --- |
166
+ | `bridge_no_support` | `boolean` | `false` | `bridge_no_support` | bridge_no_support: no support under bridge regions |
167
+ | `enable_support` | `boolean` | `false` | `enable_support` | enable_support |
168
+ | `support_angle` | `number` | `0.0` | `support_angle` | support_angle: base angle of the support body (°). Upstream SupportParameters::base_angle |
169
+ | `support_auto` | `boolean` | `true` | — | stage 20: true = automatic overhang detection, false = manual (painted enforcers only) |
170
+ | `support_base_pattern` | `string` | `'default'` | `support_base_pattern` | support_base_pattern: default\|rectilinear\|rectilinear-grid\|honeycomb\|... |
171
+ | `support_base_pattern_spacing` | `number` | `2.5` | `support_base_pattern_spacing` | support_base_pattern_spacing (mm). Determines spacing together with density |
172
+ | `support_bottom_z_distance` | `number` | `0.2` | `support_bottom_z_distance` | stage 32: z gap under support resting on a model top surface (default 0.2 = equivalent to today's 1 layer -> default behavior and golden unchanged) |
173
+ | `support_density` | `number` | `0.15` | — | density of the support body |
174
+ | `support_expansion` | `number` | `0.0` | `support_expansion` | support_expansion (mm): expands the overhang region |
175
+ | `support_filament` | `number` | `0` | `support_filament` | filament for the support base (and, upstream, the raft) |
176
+ | `support_grid_snap` | `boolean` | `true` | — | equivalent of the upstream SupportGridPattern (default behavior of the grid style) |
177
+ | `support_interface_bottom_layers` | `number` | `0` | `support_interface_bottom_layers` | support_interface_bottom_layers (0 = none) |
178
+ | `support_interface_filament` | `number` | `0` | `support_interface_filament` | filament for the support interface |
179
+ | `support_interface_pattern` | `string` | `'auto'` | `support_interface_pattern` | support_interface_pattern: auto\|rectilinear\|concentric\|rectilinear_interlaced\|grid |
180
+ | `support_interface_spacing` | `number` | `0.5` | `support_interface_spacing` | support_interface_spacing (mm, 0=solid). Upstream default 0.5 |
181
+ | `support_interface_top_layers` | `number` | `2` | `support_interface_top_layers` | support_interface_top_layers |
182
+ | `support_object_first_layer_gap` | `number` | `0.2` | `support_object_first_layer_gap` | support_object_first_layer_gap (mm) |
183
+ | `support_on_build_plate_only` | `boolean` | `false` | `support_on_build_plate_only` | support_on_build_plate_only: only support reaching the bed |
184
+ | `support_overhang_min_area` | `number` | `0.0` | — | minimum overhang area (mm², 0 = auto w²). Replaces the morphological opening filter |
185
+ | `support_remove_small_overhang` | `boolean` | `true` | `support_remove_small_overhang` | support_remove_small_overhang (upstream default true) |
186
+ | `support_style` | `string` | `'grid'` | `support_style` | grid\|tree_lite |
187
+ | `support_threshold_angle` | `number` | `30.0` | `support_threshold_angle` | support_threshold_angle |
188
+ | `support_threshold_overlap` | `number` | `0.5` | `support_threshold_overlap` | support_threshold_overlap: the overlap criterion when θ=0 (as a fraction of extrusion width) |
189
+ | `support_top_z_distance` | `number` | `0.2` | `support_top_z_distance` | support_top_z_distance |
190
+ | `support_xy_distance` | `number` | `0.35` | `support_object_xy_distance` | support_object_xy_distance |
191
+ | `tree_lite_min_radius` | `number` | `1.5` | — | tree_lite taper constants (our own approximation — no matching upstream key) |
192
+ | `tree_lite_shrink` | `number` | `0.5` | — | tree_lite taper constants (our own approximation — no matching upstream key) |
193
+ | `tree_style` | `string` | `'organic'` | — | organic\|slim\|strong\|hybrid (upstream support_style smsTree*) |
194
+ | `tree_support_angle_slow` | `number` | `25.0` | `tree_support_angle_slow` | tree_support_angle_slow (deg) |
195
+ | `tree_support_branch_angle` | `number` | `40.0` | `tree_support_branch_angle` | fallback spelling — `tree_support_branch_angle_organic` wins when both are sent |
196
+ | `tree_support_branch_angle_organic` | `number` | `40.0` | `tree_support_branch_angle_organic` | tree_support_branch_angle_organic (deg) |
197
+ | `tree_support_branch_diameter` | `number` | `2.0` | `tree_support_branch_diameter` | fallback spelling — `tree_support_branch_diameter_organic` wins when both are sent |
198
+ | `tree_support_branch_diameter_angle` | `number` | `5.0` | `tree_support_branch_diameter_angle` | tree_support_branch_diameter_angle (deg) |
199
+ | `tree_support_branch_diameter_organic` | `number` | `2.0` | `tree_support_branch_diameter_organic` | tree_support_branch_diameter_organic (mm) |
200
+ | `tree_support_branch_distance` | `number` | `1.0` | `tree_support_branch_distance` | fallback spelling — `tree_support_branch_distance_organic` wins when both are sent |
201
+ | `tree_support_branch_distance_organic` | `number` | `1.0` | `tree_support_branch_distance_organic` | tree_support_branch_distance_organic (mm) |
202
+ | `tree_support_tip_diameter` | `number` | `0.8` | `tree_support_tip_diameter` | tree_support_tip_diameter (mm) |
203
+ | `tree_support_top_rate` | `number` | `30.0` | `tree_support_top_rate` | tree_support_top_rate (%) |
204
+ | `tree_support_wall_count` | `number` | `0` | `tree_support_wall_count` | tree_support_wall_count (organic applies max(1,·) internally) |
205
+
206
+ ### Multi-material and prime tower
207
+
208
+ | Kernel param | Type | Default | From setting | Notes |
209
+ | --- | --- | --- | --- | --- |
210
+ | `bottom_surface_filament_id` | `number` | `0` | `bottom_surface_filament_id` | |
211
+ | `enable_prime_tower` | `boolean` | `true` | `enable_prime_tower` | |
212
+ | `filament_cost` | `number[]` | `[]` | `filament_cost` | currency per kg, per filament |
213
+ | `filament_density` | `number[]` | `[]` | `filament_density` | g/cm3, per filament |
214
+ | `filament_map` | `number[]` | `[]` | `filament_map` | |
215
+ | `filament_settings_id` | `vector<std::string>` | `[]` | `filament_settings_id` | |
216
+ | `filament_type` | `vector<std::string>` | `[]` | `filament_type` | |
217
+ | `inner_wall_filament_id` | `number` | `0` | `inner_wall_filament_id` | |
218
+ | `internal_solid_filament_id` | `number` | `0` | `internal_solid_filament_id` | |
219
+ | `outer_wall_filament_id` | `number` | `0` | `outer_wall_filament_id` | |
220
+ | `top_surface_filament_id` | `number` | `0` | `top_surface_filament_id` | |
221
+ | `wipe_tower_real` | `boolean` | `false` | — | stage 12: use the real WipeTower.generate() on MM changes instead of the stage-6 square ring |
222
+
223
+ ### Bed and machine G-code
224
+
225
+ | Kernel param | Type | Default | From setting | Notes |
226
+ | --- | --- | --- | --- | --- |
227
+ | `bed_depth` | `number` | `256.0` | `printable_area` | bed size (offset = bed/2) |
228
+ | `bed_height` | `number` | `0.0` | `printable_height` | printable_height (mm). 0 = no ceiling (backwards compatible) |
229
+ | `bed_width` | `number` | `256.0` | `printable_area` | bed size (offset = bed/2) |
230
+ | `enable_arc_fitting` | `boolean` | `false` | `enable_arc_fitting` | enable_arc_fitting |
231
+ | `machine_end_gcode` | `string` | — | `machine_end_gcode` | printer profile custom G-code. Empty = the mini-kernel's own preamble/footer only |
232
+ | `machine_start_gcode` | `string` | — | `machine_start_gcode` | printer profile custom G-code. Empty = the mini-kernel's own preamble/footer only |
233
+ | `printable_height` | `number` | `250.0` | `printable_height` | printable_height (mm) — the tree BuildVolume height |
234
+
235
+ ### Engine, streaming and diagnostics
236
+
237
+ | Kernel param | Type | Default | From setting | Notes |
238
+ | --- | --- | --- | --- | --- |
239
+ | `arachne_dump` | `boolean` | `false` | — | temporary diagnostic: dump the PASS1 arachne input polygons to stderr |
240
+ | `economy` | `boolean` | `false` | — | |
241
+ | `emit_pe_tags` | `boolean` | `false` | — | emit PE tags on extrusion runs (enabled automatically when the real PE is used). Default false (backwards compatible) |
242
+ | `extruder_count` | `number` | `1` | — | multi-material: how many extruders are used (1\|2) |
243
+ | `extruder_filament_diameter` | `number[]` | `[]` | `filament_diameter` | |
244
+ | `extruder_flow_ratio` | `number[]` | `[]` | `filament_flow_ratio` | |
245
+ | `extruder_nozzle_temp` | `number[]` | `[]` | `nozzle_temperature` | |
246
+ | `extruder_retract_length` | `?` | `[]` | `filament_retraction_length` | undefined |
247
+ | `extruder_retract_speed` | `?` | `[]` | `filament_retraction_speed` | undefined |
248
+ | `extruder_z_hop` | `?` | `[]` | `filament_z_hop` | undefined |
249
+ | `extrusion_rate_slope_segment_length` | `number` | `1.0` | — | segment split length for the real PE (mm) |
250
+ | `flush_into_infill` | `boolean` | `false` | `flush_into_infill` | |
251
+ | `flush_multiplier` | `number` | `1.0` | `flush_multiplier` | upstream scales the whole table by this |
252
+ | `flush_volumes_matrix` | `number[]` | `[]` | `flush_volumes_matrix` | |
253
+ | `gcode_config_block` | `boolean` | `false` | — | ; CONFIG_BLOCK_START … the parameters this slice ran with … END |
254
+ | `gcode_stats_block` | `boolean` | `false` | — | ; filament used [mm]/[cm3]/[g], cost, total filament change |
255
+ | `independent_support_layer_height` | `boolean` | `false` | `independent_support_layer_height` | false by default because of the kernel z grid constraint (gap quantized to layers) |
256
+ | `keep_stages` | `boolean` | `false` | — | keep the stages cached after slicing (skips the early release — a memory trade-off) |
257
+ | `mm_group_split` | `number` | `0` | — | triangle group boundary index ([0,split)=T0, [split,N)=T1) |
258
+ | `mm_group_splits` | `number[]` | `[]` | — | |
259
+ | `mm_group_tools` | `number[]` | `[]` | — | |
260
+ | `pe_external_perimeter_only` | `boolean` | `false` | — | real PE: smooth outer walls only |
261
+ | `pe_lite` | `boolean` | `true` | — | true = the effective PE-lite (default), false = the ported real PE (tagged g-code) |
262
+ | `pe_strip_tags` | `boolean` | `true` | — | strip the tags from the final output after real PE post-processing |
263
+ | `prime_tower_ring_size` | `number` | `15.0` | — | side length of the fallback square ring (mm) |
264
+ | `prime_tower_width` | `number` | `30.0` | `prime_tower_width` | width of the real WipeTower (mm). Separate from the square ring width (15). |
265
+ | `prime_tower_x` | `number` | `10.0` | `wipe_tower_x` | |
266
+ | `prime_tower_y` | `number` | `10.0` | `wipe_tower_y` | |
267
+ | `prime_volume` | `number` | `0.0` | `prime_volume` | extra volume primed on every change, on top of the pair's |
268
+ | `reduce_crossing_wall` | `boolean` | `false` | `reduce_crossing_wall` | wall-avoiding travel |
269
+ | `reuse_stages` | `number` | `0` | — | |
270
+ | `time_engine` | `string` | `'full'` | — | |
271
+
272
+ <!-- KERNEL-PARAMS:END -->
273
+
274
+ ### The parameters no setting reaches
275
+
276
+ A `—` in *From setting* means there is no OrcaSlicer option behind that parameter, so it exists only if you put it
277
+ in the params object yourself. They are not one kind of thing, and the difference matters before you reach for one:
278
+
279
+ - **Host runtime flags** — `economy`, `keep_stages`, `reuse_stages`, `time_engine`, `wipe_tower_real`,
280
+ `gcode_stats_block`, `gcode_config_block`. Decisions the *caller* makes about a particular run, not properties of
281
+ the print. `economy` is the last rung of an out-of-memory retry: it streams G-code and skips the preview
282
+ toolpaths and the time estimate, so a model that cannot finish any other way still finishes.
283
+ - **Values the viewer computes** — `extruder_count`, `mm_group_split`, `mm_group_splits`, `mm_group_tools`,
284
+ `auto_center`. These come from the scene (how many extruders are loaded, which triangle ranges belong to which
285
+ tool), so there is nothing for a settings map to hold. `<Viewport/>` fills them in at slice time.
286
+ - **Kernel-only tuning** — `support_density`, `support_auto`, `support_grid_snap`, `support_overhang_min_area`,
287
+ `tree_style`, `tree_lite_shrink`, `tree_lite_min_radius`, `scarf_length`, `prime_tower_ring_size`,
288
+ `raft_first_layer_height`, `extrusion_rate_slope_segment_length`. Real knobs with no upstream option of the same
289
+ name — some are this kernel's own approximations (the `tree_lite_*` taper), others are upstream behaviour that
290
+ upstream never exposed as a setting.
291
+ - **Diagnostics** — `arachne_dump`, `pe_lite`, `pe_strip_tags`, `pe_external_perimeter_only`, `emit_pe_tags`. Left
292
+ at their defaults unless you are working on the kernel itself. `pe_lite` in particular defaults to `true` because
293
+ the real pressure equalizer only acts on G-code carrying OrcaSlicer's `;_EXTRUDE_SET_SPEED` tags, which this
294
+ kernel emits only when asked.
49
295
 
50
296
  ## Materials and multi-material
51
297
 
@@ -57,7 +303,17 @@ import { filamentPresets, deriveKernelParams } from 'three-slicer/settings'
57
303
  const filaments = await filamentPresets() // lazy — the artifact loads on first call
58
304
  filaments.listFor('Bambu Lab X1 Carbon 0.4 nozzle') // [{name, type, vendor}, …]
59
305
  filaments.recommendedFor('Bambu Lab X1 Carbon 0.4 nozzle') // the vendor's shortlist, filtered to the compatible set
60
- Object.assign(settings, filaments.settingsFor('Bambu PLA Basic @BBL X1C'))
306
+
307
+ // Applying one: CLEAR the preset's key set first. A preset carries only the keys it sets, so a plain merge leaves
308
+ // behind whatever the previous material set and this one does not — a PLA pick after an ABS pick keeps ABS's
309
+ // chamber temperature. `keys` is the exact set to clear, and the filament and process key sets are disjoint, so
310
+ // clearing one never disturbs the other.
311
+ function applyPreset(settings, preset, keys) {
312
+ const next = { ...settings }
313
+ for (const key of keys) delete next[key]
314
+ return Object.assign(next, preset)
315
+ }
316
+ settings = applyPreset(settings, filaments.settingsFor('Bambu PLA Basic @BBL X1C'), filaments.keys)
61
317
  ```
62
318
 
63
319
  **One material per extruder.** Upstream stores every filament option as one entry per extruder, so a multi-material settings map writes each extruder's material at its own index:
@@ -99,6 +355,26 @@ Two consequences worth knowing before you build on this:
99
355
 
100
356
  Results carry the split: `stats.filament_mm_by_tool` (indexed by tool number, one slot per extruder, sums to `filament_mm`) and `stats.filament_mm_purge` (the prime/wipe tower share, already included in the per-tool figures). In the streamed toolpath, `paths[k+3]` encodes `role + tool * 16` — mask with `& 15` for the role and `>>> 4` for the tool.
101
357
 
358
+ ## SLA parameters
359
+
360
+ The table above is the FFF kernel's reader. The SLA entry (`slice_sla`) reads its own parameter set, produced
361
+ by `deriveSlaParams(settings)` — unlike `deriveKernelParams` it always emits every key (49 today), filling
362
+ schema/reference-machine defaults, because the SLA keys are not shared with another technology whose defaults
363
+ could disagree. The groups:
364
+
365
+ | Group | Keys |
366
+ | --- | --- |
367
+ | Layers and exposure | `layer_height`, `initial_layer_height`, `exposure_time`, `initial_exposure_time`, `faded_layers` |
368
+ | Display (doubles as the bed) | `display_width/height`, `display_pixels_x/y`, `display_orientation` (portrait default), `display_mirror_x/y`, `bed_width/depth` |
369
+ | Archive identity (config.ini) | `printer_model`, `printer_variant`, `printer_settings_id`, `sla_print_settings_id`, `sla_material_settings_id`, `material_print_speed` |
370
+ | Supports (upstream `SupportTreeConfig`) | `supports_enable`, `support_tree_type`, `support_pillar_diameter`, `support_head_*`, `support_points_density_relative`, `support_critical_angle`, `support_max_bridge_length`, `support_max_pillar_link_distance`, `support_base_*`, `support_small_pillar_diameter_percent`, `support_pillar_widening_factor`, `support_max_bridges_on_pillar`, `support_max_weight_on_model`, `support_object_elevation`, `support_pillar_connection_mode`, `support_buildplate_only`, `slice_closing_radius` |
371
+ | Pad (upstream `PadConfig`) | `pad_enable`, `pad_brim_size`, `pad_wall_thickness`, `pad_wall_height`, `pad_wall_slope`, `pad_max_merge_distance`, `pad_around_object` (typed error) |
372
+ | Capability gate | `hollowing_enable` — `true` is refused with `SLA_UNSUPPORTED_HOLLOWING`, never sliced solid |
373
+
374
+ The result has no G-code: `stats.sla` is `true`, layers carry the same stride-8 segment stream, `support_mesh`
375
+ and `pad_mesh` are triangle soups for the preview, and `stats.lift_layers` (pad + elevation) is what a preview
376
+ must lift the model by.
377
+
102
378
  ## License
103
379
 
104
380
  AGPL-3.0-or-later (derived from OrcaSlicer). A web app embedding this package must comply with AGPL — including offering its source to network users.