forgecad 0.9.7 → 0.9.9

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 (47) hide show
  1. package/README.md +1 -0
  2. package/dist/assets/{AdminPage-DX0mpSZT.js → AdminPage-CNEvQM7c.js} +1 -1
  3. package/dist/assets/{BlogPage-CI_P0_Pf.js → BlogPage-Cc41PP4d.js} +1 -1
  4. package/dist/assets/{DocsPage-DLhIIZyJ.js → DocsPage-9U1hGjrg.js} +2 -2
  5. package/dist/assets/{EditorApp-DfFT2Dn8.css → EditorApp-D11wL4Qn.css} +51 -0
  6. package/dist/assets/{EditorApp-BujZvuwX.js → EditorApp-DnddQvBt.js} +151 -9
  7. package/dist/assets/{EmbedViewer-0S0qXKog.js → EmbedViewer-B2lhWTcd.js} +2 -2
  8. package/dist/assets/{LandingPageProofDriven-O_yMtAri.js → LandingPageProofDriven-CFet-l3o.js} +1 -1
  9. package/dist/assets/{PricingPage-DGkX3Ahr.js → PricingPage-CPm8mQx3.js} +1 -1
  10. package/dist/assets/{SettingsPage-DBsqTB_y.js → SettingsPage-BarZonVZ.js} +1 -1
  11. package/dist/assets/__vite-browser-external-Dhvy_jtL.js +4 -0
  12. package/dist/assets/{app-BE2nD6Yz.js → app-BjSEB4sY.js} +1006 -526
  13. package/dist/assets/cli/{render-iP9qh475.js → render-CXVrHY8q.js} +647 -481
  14. package/dist/assets/constructionHistoryWorker-z9_LGiRd.js +42984 -0
  15. package/dist/assets/{evalWorker-Ds5U4xtN.js → evalWorker-CtO7GsJR.js} +42 -9
  16. package/dist/assets/{inspectWorker-Dll4eVyD.js → inspectWorker-BZ2CkQZr.js} +785 -111
  17. package/dist/assets/{manifold-DjYsd7A_.js → manifold-BRdhoQy5.js} +2 -2
  18. package/dist/assets/{manifold-sJ-axdXM.js → manifold-BVi4_OeB.js} +1 -1
  19. package/dist/assets/manifold-Cp_dCC7i.js +3018 -0
  20. package/dist/assets/{manifold-Bk26ViCr.js → manifold-DAzn2Fsa.js} +1 -1
  21. package/dist/assets/{renderSceneState-Bngp5MrQ.js → renderSceneState-CWO8rHlt.js} +1 -1
  22. package/dist/assets/{reportWorker-CU8RZ4O0.js → reportWorker-Bz9tGiHb.js} +42 -9
  23. package/dist/assets/{sectionPlaneMath-BdTjyVfs.js → scalar-sampling-budget-Bmewod18.js} +1339 -215
  24. package/dist/cli/render.html +1 -1
  25. package/dist/docs/index.html +1 -1
  26. package/dist/docs-raw/CLI.md +10 -10
  27. package/dist/docs-raw/coding-best-practices.md +1 -1
  28. package/dist/docs-raw/guides/inspection-bundles.md +77 -19
  29. package/dist/docs-raw/guides/skill-maintenance.md +1 -1
  30. package/dist/docs-raw/runbook.md +2 -2
  31. package/dist/docs-raw/skills/forgecad-make-a-model.md +11 -0
  32. package/dist/docs-raw/skills/forgecad-render-inspect.md +12 -6
  33. package/dist/docs-raw/skills/index.md +1 -1
  34. package/dist/index.html +1 -1
  35. package/dist/sitemap.xml +6 -6
  36. package/dist-cli/forgecad.js +596 -354
  37. package/dist-cli/forgecad.js.map +1 -1
  38. package/dist-skill/CONTEXT.md +77 -19
  39. package/dist-skill/docs/CLI.md +10 -10
  40. package/dist-skill/docs/guides/inspection-bundles.md +77 -19
  41. package/dist-skill/docs-dev/CLI.md +10 -10
  42. package/dist-skill/docs-dev/coding-best-practices.md +1 -1
  43. package/dist-skill/docs-dev/guides/inspection-bundles.md +77 -19
  44. package/dist-skill/docs-dev/guides/skill-maintenance.md +1 -1
  45. package/dist-skill/library/forgecad-make-a-model/SKILL.md +11 -0
  46. package/dist-skill/library/forgecad-render-inspect/SKILL.md +12 -6
  47. package/package.json +6 -3
@@ -9425,9 +9425,9 @@ Setting `KNUCK_R = H / 2` exactly makes the body cross-section a stadium that pe
9425
9425
 
9426
9426
  `forgecad render inspect` writes a deterministic directory bundle for agents,
9427
9427
  tests, and automation. Use it when a single shaded PNG is too ambiguous and the
9428
- consumer needs geometry-aware signals such as depth, normals, surface roughness,
9429
- part identity, physical connected components, collisions, local thickness, or
9430
- cross-sections.
9428
+ consumer needs geometry-aware signals such as depth, normals, Zebra stripes,
9429
+ surface roughness, part identity, physical connected components, collisions,
9430
+ local thickness, or cross-sections.
9431
9431
 
9432
9432
  ## When To Use It
9433
9433
 
@@ -9467,7 +9467,7 @@ with patterns such as `Bench.*`.
9467
9467
 
9468
9468
  ## Bundle Layout
9469
9469
 
9470
- A bundle that asks for `--channels rgb,depth,normals,mask,section` has this
9470
+ A bundle that asks for `--channels rgb,depth,normals,zebra,mask,section` has this
9471
9471
  layout:
9472
9472
 
9473
9473
  ```text
@@ -9489,6 +9489,11 @@ model-inspect/
9489
9489
  right.png
9490
9490
  top.png
9491
9491
  iso.png
9492
+ zebra/
9493
+ front.png
9494
+ right.png
9495
+ top.png
9496
+ iso.png
9492
9497
  mask/
9493
9498
  front.png
9494
9499
  right.png
@@ -9514,13 +9519,15 @@ implemented channel in one bundle:
9514
9519
 
9515
9520
  ```bash
9516
9521
  forgecad render inspect model.forge.js --channels depth,normals
9522
+ forgecad render inspect model.forge.js --channels rgb,zebra,normals
9517
9523
  forgecad render inspect model.forge.js --channels rgb,roughness
9518
9524
  forgecad render inspect model.forge.js --channels rgb,mask,collisions
9519
9525
  forgecad render inspect model.forge.js --channels rgb,section,thickness
9520
9526
  ```
9521
9527
 
9522
- Supported channels are `rgb`, `depth`, `normals`, `roughness`, `mask`,
9523
- `connectivity`, `distance`, `collisions`, `thickness`, and `section`.
9528
+ Supported channels are `rgb`, `depth`, `normals`, `zebra`, `roughness`, `mask`,
9529
+ `connectivity`, `floating`, `distance`, `collisions`, `thickness`, and
9530
+ `section`.
9524
9531
 
9525
9532
  ## Channel Semantics
9526
9533
 
@@ -9547,6 +9554,17 @@ normal = normalize((rgb / 255) * 2 - 1)
9547
9554
 
9548
9555
  Background pixels are black and should be treated as `null`.
9549
9556
 
9557
+ `zebra` emits reflective black-and-white stripe renders for visual
9558
+ surface-continuity inspection. Stripes are generated from the visible
9559
+ camera-view normal and simulated reflection direction, so smooth surfaces show
9560
+ smooth flowing bands while normal discontinuities, faceting, and unexpected
9561
+ creases kink or break the bands.
9562
+
9563
+ Use Zebra with `rgb` and `normals` when judging lofts, fillets, swept surfaces,
9564
+ and skin-like forms. It is a human-readable shader diagnostic, not an exact
9565
+ curvature-continuity proof; mesh tessellation quality and available smooth
9566
+ normals determine how faithfully it represents the underlying surface.
9567
+
9550
9568
  `roughness` emits a mesh-dihedral surface-quality heatmap. Smooth and gently
9551
9569
  curved triangles render as a faint translucent shadow over black, while
9552
9570
  triangles adjacent to sharp, harsh, boundary, or non-manifold mesh edges render
@@ -9588,21 +9606,58 @@ Connectivity is computed from visible scene objects:
9588
9606
 
9589
9607
  ```text
9590
9608
  bbox candidate = bbox interiors overlap or bbox contact gap <= 0.05 model units
9591
- overlap edge = exact boolean intersection volume > 0.1 model units^3
9592
- component = transitive closure over exact overlap edges
9609
+ mesh contact edge = minimum mesh-surface distance <= contactTolerance
9610
+ overlap edge = exact boolean intersection volume > 0.1 model units^3 for positive-volume overlap
9611
+ component = transitive closure over mesh contact and exact overlap edges
9593
9612
  ```
9594
9613
 
9595
9614
  The manifest stores the edge list, component list, per-object body counts, and
9596
- warnings. Component colors group scene objects; if one scene object contains
9597
- multiple disconnected kernel bodies and the caller supplied a body count, the
9598
- manifest reports `bodyCount > 1` but the PNG cannot color those internal bodies
9599
- separately yet.
9615
+ warnings. Component colors group scene objects and mesh body entries. If one
9616
+ scene object contains multiple disconnected mesh islands, those islands are
9617
+ reported and colored separately as entries such as `Part body 1` and
9618
+ `Part body 2`.
9619
+
9620
+ Connectivity uses bbox only as a broadphase. Bbox contact alone is not enough to
9621
+ merge separate scene objects by default, but mesh surfaces within contact
9622
+ tolerance count as physically connected. This keeps concave assemblies such as
9623
+ cages and captive balls from being falsely colored as one component while still
9624
+ allowing stacked or nearly touching parts to share a component. Use the
9625
+ `collisions` channel when you need positive-volume overlap evidence as a defect
9626
+ report rather than a component grouping.
9627
+
9628
+ `floating` emits one disconnected-body highlight image per view. Black is
9629
+ background or ground-reachable geometry. The highlight color marks physical
9630
+ components that have no contact path to the ground plane.
9631
+
9632
+ Floating body detection splits visible meshes into disconnected body islands,
9633
+ links bodies only when their minimum mesh-surface distance is within contact
9634
+ tolerance (or exact positive-volume overlap when only shape evidence is
9635
+ available), treats any connected component whose lower Z reaches the viewport
9636
+ ground plane plus bed tolerance as grounded, then highlights every ungrounded
9637
+ component. The default ground plane is the visible model's minimum Z;
9638
+ `scene({ ground: { offset } })` moves it below that by the configured offset.
9600
9639
 
9601
- Connectivity uses bbox only as a broadphase. Bbox contact is not enough to merge
9602
- separate scene objects, which keeps concave assemblies such as cages and captive
9603
- balls from being falsely colored as one component. Use the `collisions` channel
9604
- when you need positive-volume overlap evidence as a defect report rather than a
9605
- component grouping.
9640
+ ```text
9641
+ grounded = component bbox minZ <= groundZ + bedTolerance
9642
+ floating body = !grounded
9643
+ ```
9644
+
9645
+ This means a `union()` result with two disconnected mesh islands is inspected as
9646
+ two separate bodies instead of being treated as one safe object. Bbox overlap or
9647
+ bbox face contact alone is not support evidence. Use `connectivity`, `distance`,
9648
+ or `collisions` when you need the full physical graph, rooted gap distances, or
9649
+ collision defects.
9650
+
9651
+ `thickness` emits one local wall-thickness heatmap per view. Black is
9652
+ background. Red/orange pixels are below the configured critical/warning
9653
+ thresholds, green-to-blue pixels are acceptable/thick, and gray means the local
9654
+ raycast could not resolve an opposite surface.
9655
+
9656
+ Thickness uses the same physical-contact edges as `connectivity` and `floating`.
9657
+ When a ray crosses from one object to a direct physical-contact neighbor, hits
9658
+ within `contactTolerance` are treated as contact seams and the ray continues to
9659
+ the next surface. This prevents a tiny modeled gap between touching parts from
9660
+ being reported as a paper-thin wall.
9606
9661
 
9607
9662
  `distance` emits one rooted physical-component-distance heatmap per view. Black
9608
9663
  is background. Non-black pixels resolve through
@@ -9651,6 +9706,10 @@ with the ghosted source geometry. If `--focus PartA,PartB` is used, everything
9651
9706
  except those objects is hidden, `PartA` and `PartB` are ghosted, and their
9652
9707
  overlap volume is highlighted if present.
9653
9708
 
9709
+ Collision broadphase prunes exact boolean checks when the bbox intersection
9710
+ volume is already below the overlap threshold. This does not change findings:
9711
+ the real intersection volume cannot exceed the bbox intersection volume.
9712
+
9654
9713
  `thickness` emits one local wall-thickness heatmap per view. The renderer places
9655
9714
  deterministic area-weighted point samples across visible mesh surfaces, casts
9656
9715
  through the object along each sample normal, and colors each point by the first
@@ -9734,8 +9793,7 @@ per-view depth ranges, and object-mask mappings live.
9734
9793
  guarantee. Open meshes, concave geometry, very coarse tessellation, or low
9735
9794
  `--thickness-samples` values can leave gray/unresolved or approximate regions.
9736
9795
  - Section atlases use five default interior slices today.
9737
- - Zebra/reflection-line inspection is a follow-up channel, not part of the v1
9738
- bundle.
9796
+ - Zebra is a shader-based visual continuity aid, not exact curvature analysis.
9739
9797
 
9740
9798
  ---
9741
9799
 
@@ -191,7 +191,7 @@ forgecad render views model.forge.js --json
191
191
 
192
192
  Render a machine-readable inspection bundle with geometry channels and a manifest.
193
193
 
194
- Launches the headless viewport renderer and writes a directory bundle for agent and automation workflows. Every channel is opt-in with `--channels`; there is no default bundle. Selected channels emit canonical `front`, `right`, `top`, and `iso` views for RGB, depth, normals, surface roughness, object masks, physical connectivity, rooted component distance, collisions, and wall thickness, or a principal-plane section atlas, plus a root `manifest.json` with scene metadata, filters, object visibility, and relative file paths.
194
+ Launches the headless viewport renderer and writes a directory bundle for agent and automation workflows. Every channel is opt-in with `--channels`; there is no default bundle. Selected channels emit canonical `front`, `right`, `top`, and `iso` views for RGB, depth, normals, Zebra surface-continuity stripes, surface roughness, object masks, physical connectivity, floating body highlights, rooted component distance, collisions, and wall thickness, or a principal-plane section atlas, plus a root `manifest.json` with scene metadata, filters, object visibility, and relative file paths.
195
195
 
196
196
  Use `--focus` to isolate specific parts or hide mocks, and `--hide` to remove named clutter. Output defaults to `<script-name>-inspect/` next to the input file.
197
197
 
@@ -199,6 +199,7 @@ For bundle layout, channel encodings, and manifest semantics, see [Inspection Bu
199
199
 
200
200
  ```bash
201
201
  forgecad render inspect examples/api/static-assembly-connectors.forge.js --channels rgb,mask
202
+ forgecad render inspect examples/api/static-assembly-connectors.forge.js --channels rgb,zebra,normals
202
203
  forgecad render inspect examples/api/static-assembly-connectors.forge.js out/bench-inspect --channels collisions --focus "Bench.*"
203
204
  forgecad render inspect examples/api/static-assembly-connectors.forge.js --channels rgb,mask,collisions --hide "Bench.Slat0" --force
204
205
  ```
@@ -299,21 +300,21 @@ forgecad render section examples/furniture/01-table.forge.js out/bold.svg --edge
299
300
  | `--background <color>` | Canvas background override |
300
301
  | `--render-mode <solid\|wireframe>` | Shaded solid (default) or wireframe only |
301
302
  | `--edges <off\|thin\|bold>` | Edge overlay preset in solid mode (default: off) |
302
- | `--render-style <classic\|studio\|fast\|glass>` | Visual render style (default: classic) |
303
+ | `--render-style <classic\|studio\|fast\|glass\|precision\|hybrid>` | Visual render style (default: classic) |
303
304
  | `--port <n>` | Vite dev server port |
304
305
  | `--fresh-server` | Start a fresh renderer instead of reusing an existing one |
305
306
  | `--chrome-path <path>` | Chrome or Chromium executable path |
306
307
  | `--output <path>` | Output file path |
307
308
  | `--json` | Print machine-readable JSON |
308
309
  | `--quality <default\|live\|high>` | Mesh quality preset |
309
- | `--backend <manifold\|occt\|truck>` | Geometry backend |
310
- | `--channels <rgb,depth,normals,roughness,mask,connectivity,distance,collisions,thickness,section>` | Required inspection channels to emit; no default |
310
+ | `--backend <manifold\|occt\|truck>` | Geometry backend (default: manifold) |
311
+ | `--channels <rgb,depth,normals,zebra,roughness,mask,connectivity,floating,distance,collisions,thickness,section>` | Required inspection channels to emit; no default |
311
312
  | `--force` | Replace an existing bundle directory |
312
313
  | `--min-thickness <mm>` | Critical thickness threshold in model units |
313
314
  | `--warn-thickness <mm>` | Warning thickness threshold in model units |
314
315
  | `--max-thickness <mm>` | Thick/blue heatmap threshold in model units |
315
- | `--thickness-samples <n>` | Maximum thickness point samples per object |
316
- | `--roughness-samples <n>` | Maximum roughness point samples per object |
316
+ | `--thickness-samples <n>` | Override default scene budget with max thickness point samples per object |
317
+ | `--roughness-samples <n>` | Override default scene budget with max roughness point samples per object |
317
318
  | `--preset <name>` | Material/lighting preset |
318
319
  | `--width <px>` | Output width in pixels |
319
320
  | `--height <px>` | Output height in pixels |
@@ -400,7 +401,7 @@ forgecad export sdf rover.forge.js --output out/forge_scout
400
401
  |--------|-------------|
401
402
  | `--output <path>` | Output STEP path |
402
403
  | `--quality <default\|live\|high>` | Forge quality preset |
403
- | `--backend <manifold\|occt\|truck>` | Geometry backend |
404
+ | `--backend <manifold\|occt\|truck>` | Geometry backend (default: manifold) |
404
405
  | `-o <path>` | Output file path |
405
406
  | `--dim-angle-tol <deg>` | Dimension routing tolerance in degrees |
406
407
  | `--sheet-width <mm>` | Stock sheet width in mm |
@@ -548,7 +549,7 @@ forgecad skill flattened-files ~/Desktop/forgecad-skills
548
549
 
549
550
  ## Validation
550
551
 
551
- Check printability, test parameter ranges, and run invariant suites.
552
+ Check printability, test parameter ranges, and run focused model invariants.
552
553
 
553
554
  ### `forgecad check print`
554
555
 
@@ -601,7 +602,6 @@ forgecad check params path/to/model.forge.js --samples 12
601
602
 
602
603
  | Command | Description |
603
604
  |---------|-------------|
604
- | `check suite` | Run the repo invariant suite, with smoke and full profiles for the fast merge lane vs the broader regression sweep. |
605
605
  | `inspect mechanical-integrity` | Inspect generated ForgeCAD models for mechanical integrity failures. |
606
606
  | `check runtime-globals` | Ensure the script sandbox does not add new lowercase injected globals. |
607
607
  | `check transforms` | Run transform and assembly invariants. |
@@ -646,7 +646,7 @@ The CLI is free for core workflows and exports. Production outputs are free to r
646
646
 
647
647
  | Free | Production outputs | Pro |
648
648
  |------|--------------------|-----|
649
- | `run`, `dev`, `studio`, `render 3d`, `export stl`, `export 3mf`, `export svg`, `check print`, `check params`, `inspect mechanical-integrity`, `check suite` | `cut-list`, `export sketch-pdf`, `export step`, `export brep`, `export gcode`, `export sdf`, `export urdf`, `export report`, `export cutting-layout` are free to run; Pro covers commercial use. | `render hq`, `capture gif`, `capture mp4` |
649
+ | `run`, `dev`, `studio`, `render 3d`, `export stl`, `export 3mf`, `export svg`, `check print`, `check params`, `inspect mechanical-integrity` | `cut-list`, `export sketch-pdf`, `export step`, `export brep`, `export gcode`, `export sdf`, `export urdf`, `export report`, `export cutting-layout` are free to run; Pro covers commercial use. | `render hq`, `capture gif`, `capture mp4` |
650
650
 
651
651
  ```bash
652
652
  forgecad license # Check signed-in account status
@@ -7,9 +7,9 @@ skill-order: 2
7
7
 
8
8
  `forgecad render inspect` writes a deterministic directory bundle for agents,
9
9
  tests, and automation. Use it when a single shaded PNG is too ambiguous and the
10
- consumer needs geometry-aware signals such as depth, normals, surface roughness,
11
- part identity, physical connected components, collisions, local thickness, or
12
- cross-sections.
10
+ consumer needs geometry-aware signals such as depth, normals, Zebra stripes,
11
+ surface roughness, part identity, physical connected components, collisions,
12
+ local thickness, or cross-sections.
13
13
 
14
14
  ## When To Use It
15
15
 
@@ -49,7 +49,7 @@ with patterns such as `Bench.*`.
49
49
 
50
50
  ## Bundle Layout
51
51
 
52
- A bundle that asks for `--channels rgb,depth,normals,mask,section` has this
52
+ A bundle that asks for `--channels rgb,depth,normals,zebra,mask,section` has this
53
53
  layout:
54
54
 
55
55
  ```text
@@ -71,6 +71,11 @@ model-inspect/
71
71
  right.png
72
72
  top.png
73
73
  iso.png
74
+ zebra/
75
+ front.png
76
+ right.png
77
+ top.png
78
+ iso.png
74
79
  mask/
75
80
  front.png
76
81
  right.png
@@ -96,13 +101,15 @@ implemented channel in one bundle:
96
101
 
97
102
  ```bash
98
103
  forgecad render inspect model.forge.js --channels depth,normals
104
+ forgecad render inspect model.forge.js --channels rgb,zebra,normals
99
105
  forgecad render inspect model.forge.js --channels rgb,roughness
100
106
  forgecad render inspect model.forge.js --channels rgb,mask,collisions
101
107
  forgecad render inspect model.forge.js --channels rgb,section,thickness
102
108
  ```
103
109
 
104
- Supported channels are `rgb`, `depth`, `normals`, `roughness`, `mask`,
105
- `connectivity`, `distance`, `collisions`, `thickness`, and `section`.
110
+ Supported channels are `rgb`, `depth`, `normals`, `zebra`, `roughness`, `mask`,
111
+ `connectivity`, `floating`, `distance`, `collisions`, `thickness`, and
112
+ `section`.
106
113
 
107
114
  ## Channel Semantics
108
115
 
@@ -129,6 +136,17 @@ normal = normalize((rgb / 255) * 2 - 1)
129
136
 
130
137
  Background pixels are black and should be treated as `null`.
131
138
 
139
+ `zebra` emits reflective black-and-white stripe renders for visual
140
+ surface-continuity inspection. Stripes are generated from the visible
141
+ camera-view normal and simulated reflection direction, so smooth surfaces show
142
+ smooth flowing bands while normal discontinuities, faceting, and unexpected
143
+ creases kink or break the bands.
144
+
145
+ Use Zebra with `rgb` and `normals` when judging lofts, fillets, swept surfaces,
146
+ and skin-like forms. It is a human-readable shader diagnostic, not an exact
147
+ curvature-continuity proof; mesh tessellation quality and available smooth
148
+ normals determine how faithfully it represents the underlying surface.
149
+
132
150
  `roughness` emits a mesh-dihedral surface-quality heatmap. Smooth and gently
133
151
  curved triangles render as a faint translucent shadow over black, while
134
152
  triangles adjacent to sharp, harsh, boundary, or non-manifold mesh edges render
@@ -170,21 +188,58 @@ Connectivity is computed from visible scene objects:
170
188
 
171
189
  ```text
172
190
  bbox candidate = bbox interiors overlap or bbox contact gap <= 0.05 model units
173
- overlap edge = exact boolean intersection volume > 0.1 model units^3
174
- component = transitive closure over exact overlap edges
191
+ mesh contact edge = minimum mesh-surface distance <= contactTolerance
192
+ overlap edge = exact boolean intersection volume > 0.1 model units^3 for positive-volume overlap
193
+ component = transitive closure over mesh contact and exact overlap edges
175
194
  ```
176
195
 
177
196
  The manifest stores the edge list, component list, per-object body counts, and
178
- warnings. Component colors group scene objects; if one scene object contains
179
- multiple disconnected kernel bodies and the caller supplied a body count, the
180
- manifest reports `bodyCount > 1` but the PNG cannot color those internal bodies
181
- separately yet.
197
+ warnings. Component colors group scene objects and mesh body entries. If one
198
+ scene object contains multiple disconnected mesh islands, those islands are
199
+ reported and colored separately as entries such as `Part body 1` and
200
+ `Part body 2`.
201
+
202
+ Connectivity uses bbox only as a broadphase. Bbox contact alone is not enough to
203
+ merge separate scene objects by default, but mesh surfaces within contact
204
+ tolerance count as physically connected. This keeps concave assemblies such as
205
+ cages and captive balls from being falsely colored as one component while still
206
+ allowing stacked or nearly touching parts to share a component. Use the
207
+ `collisions` channel when you need positive-volume overlap evidence as a defect
208
+ report rather than a component grouping.
209
+
210
+ `floating` emits one disconnected-body highlight image per view. Black is
211
+ background or ground-reachable geometry. The highlight color marks physical
212
+ components that have no contact path to the ground plane.
213
+
214
+ Floating body detection splits visible meshes into disconnected body islands,
215
+ links bodies only when their minimum mesh-surface distance is within contact
216
+ tolerance (or exact positive-volume overlap when only shape evidence is
217
+ available), treats any connected component whose lower Z reaches the viewport
218
+ ground plane plus bed tolerance as grounded, then highlights every ungrounded
219
+ component. The default ground plane is the visible model's minimum Z;
220
+ `scene({ ground: { offset } })` moves it below that by the configured offset.
182
221
 
183
- Connectivity uses bbox only as a broadphase. Bbox contact is not enough to merge
184
- separate scene objects, which keeps concave assemblies such as cages and captive
185
- balls from being falsely colored as one component. Use the `collisions` channel
186
- when you need positive-volume overlap evidence as a defect report rather than a
187
- component grouping.
222
+ ```text
223
+ grounded = component bbox minZ <= groundZ + bedTolerance
224
+ floating body = !grounded
225
+ ```
226
+
227
+ This means a `union()` result with two disconnected mesh islands is inspected as
228
+ two separate bodies instead of being treated as one safe object. Bbox overlap or
229
+ bbox face contact alone is not support evidence. Use `connectivity`, `distance`,
230
+ or `collisions` when you need the full physical graph, rooted gap distances, or
231
+ collision defects.
232
+
233
+ `thickness` emits one local wall-thickness heatmap per view. Black is
234
+ background. Red/orange pixels are below the configured critical/warning
235
+ thresholds, green-to-blue pixels are acceptable/thick, and gray means the local
236
+ raycast could not resolve an opposite surface.
237
+
238
+ Thickness uses the same physical-contact edges as `connectivity` and `floating`.
239
+ When a ray crosses from one object to a direct physical-contact neighbor, hits
240
+ within `contactTolerance` are treated as contact seams and the ray continues to
241
+ the next surface. This prevents a tiny modeled gap between touching parts from
242
+ being reported as a paper-thin wall.
188
243
 
189
244
  `distance` emits one rooted physical-component-distance heatmap per view. Black
190
245
  is background. Non-black pixels resolve through
@@ -233,6 +288,10 @@ with the ghosted source geometry. If `--focus PartA,PartB` is used, everything
233
288
  except those objects is hidden, `PartA` and `PartB` are ghosted, and their
234
289
  overlap volume is highlighted if present.
235
290
 
291
+ Collision broadphase prunes exact boolean checks when the bbox intersection
292
+ volume is already below the overlap threshold. This does not change findings:
293
+ the real intersection volume cannot exceed the bbox intersection volume.
294
+
236
295
  `thickness` emits one local wall-thickness heatmap per view. The renderer places
237
296
  deterministic area-weighted point samples across visible mesh surfaces, casts
238
297
  through the object along each sample normal, and colors each point by the first
@@ -316,5 +375,4 @@ per-view depth ranges, and object-mask mappings live.
316
375
  guarantee. Open meshes, concave geometry, very coarse tessellation, or low
317
376
  `--thickness-samples` values can leave gray/unresolved or approximate regions.
318
377
  - Section atlases use five default interior slices today.
319
- - Zebra/reflection-line inspection is a follow-up channel, not part of the v1
320
- bundle.
378
+ - Zebra is a shader-based visual continuity aid, not exact curvature analysis.
@@ -191,7 +191,7 @@ forgecad render views model.forge.js --json
191
191
 
192
192
  Render a machine-readable inspection bundle with geometry channels and a manifest.
193
193
 
194
- Launches the headless viewport renderer and writes a directory bundle for agent and automation workflows. Every channel is opt-in with `--channels`; there is no default bundle. Selected channels emit canonical `front`, `right`, `top`, and `iso` views for RGB, depth, normals, surface roughness, object masks, physical connectivity, rooted component distance, collisions, and wall thickness, or a principal-plane section atlas, plus a root `manifest.json` with scene metadata, filters, object visibility, and relative file paths.
194
+ Launches the headless viewport renderer and writes a directory bundle for agent and automation workflows. Every channel is opt-in with `--channels`; there is no default bundle. Selected channels emit canonical `front`, `right`, `top`, and `iso` views for RGB, depth, normals, Zebra surface-continuity stripes, surface roughness, object masks, physical connectivity, floating body highlights, rooted component distance, collisions, and wall thickness, or a principal-plane section atlas, plus a root `manifest.json` with scene metadata, filters, object visibility, and relative file paths.
195
195
 
196
196
  Use `--focus` to isolate specific parts or hide mocks, and `--hide` to remove named clutter. Output defaults to `<script-name>-inspect/` next to the input file.
197
197
 
@@ -199,6 +199,7 @@ For bundle layout, channel encodings, and manifest semantics, see [Inspection Bu
199
199
 
200
200
  ```bash
201
201
  forgecad render inspect examples/api/static-assembly-connectors.forge.js --channels rgb,mask
202
+ forgecad render inspect examples/api/static-assembly-connectors.forge.js --channels rgb,zebra,normals
202
203
  forgecad render inspect examples/api/static-assembly-connectors.forge.js out/bench-inspect --channels collisions --focus "Bench.*"
203
204
  forgecad render inspect examples/api/static-assembly-connectors.forge.js --channels rgb,mask,collisions --hide "Bench.Slat0" --force
204
205
  ```
@@ -299,21 +300,21 @@ forgecad render section examples/furniture/01-table.forge.js out/bold.svg --edge
299
300
  | `--background <color>` | Canvas background override |
300
301
  | `--render-mode <solid\|wireframe>` | Shaded solid (default) or wireframe only |
301
302
  | `--edges <off\|thin\|bold>` | Edge overlay preset in solid mode (default: off) |
302
- | `--render-style <classic\|studio\|fast\|glass>` | Visual render style (default: classic) |
303
+ | `--render-style <classic\|studio\|fast\|glass\|precision\|hybrid>` | Visual render style (default: classic) |
303
304
  | `--port <n>` | Vite dev server port |
304
305
  | `--fresh-server` | Start a fresh renderer instead of reusing an existing one |
305
306
  | `--chrome-path <path>` | Chrome or Chromium executable path |
306
307
  | `--output <path>` | Output file path |
307
308
  | `--json` | Print machine-readable JSON |
308
309
  | `--quality <default\|live\|high>` | Mesh quality preset |
309
- | `--backend <manifold\|occt\|truck>` | Geometry backend |
310
- | `--channels <rgb,depth,normals,roughness,mask,connectivity,distance,collisions,thickness,section>` | Required inspection channels to emit; no default |
310
+ | `--backend <manifold\|occt\|truck>` | Geometry backend (default: manifold) |
311
+ | `--channels <rgb,depth,normals,zebra,roughness,mask,connectivity,floating,distance,collisions,thickness,section>` | Required inspection channels to emit; no default |
311
312
  | `--force` | Replace an existing bundle directory |
312
313
  | `--min-thickness <mm>` | Critical thickness threshold in model units |
313
314
  | `--warn-thickness <mm>` | Warning thickness threshold in model units |
314
315
  | `--max-thickness <mm>` | Thick/blue heatmap threshold in model units |
315
- | `--thickness-samples <n>` | Maximum thickness point samples per object |
316
- | `--roughness-samples <n>` | Maximum roughness point samples per object |
316
+ | `--thickness-samples <n>` | Override default scene budget with max thickness point samples per object |
317
+ | `--roughness-samples <n>` | Override default scene budget with max roughness point samples per object |
317
318
  | `--preset <name>` | Material/lighting preset |
318
319
  | `--width <px>` | Output width in pixels |
319
320
  | `--height <px>` | Output height in pixels |
@@ -400,7 +401,7 @@ forgecad export sdf rover.forge.js --output out/forge_scout
400
401
  |--------|-------------|
401
402
  | `--output <path>` | Output STEP path |
402
403
  | `--quality <default\|live\|high>` | Forge quality preset |
403
- | `--backend <manifold\|occt\|truck>` | Geometry backend |
404
+ | `--backend <manifold\|occt\|truck>` | Geometry backend (default: manifold) |
404
405
  | `-o <path>` | Output file path |
405
406
  | `--dim-angle-tol <deg>` | Dimension routing tolerance in degrees |
406
407
  | `--sheet-width <mm>` | Stock sheet width in mm |
@@ -548,7 +549,7 @@ forgecad skill flattened-files ~/Desktop/forgecad-skills
548
549
 
549
550
  ## Validation
550
551
 
551
- Check printability, test parameter ranges, and run invariant suites.
552
+ Check printability, test parameter ranges, and run focused model invariants.
552
553
 
553
554
  ### `forgecad check print`
554
555
 
@@ -601,7 +602,6 @@ forgecad check params path/to/model.forge.js --samples 12
601
602
 
602
603
  | Command | Description |
603
604
  |---------|-------------|
604
- | `check suite` | Run the repo invariant suite, with smoke and full profiles for the fast merge lane vs the broader regression sweep. |
605
605
  | `inspect mechanical-integrity` | Inspect generated ForgeCAD models for mechanical integrity failures. |
606
606
  | `check runtime-globals` | Ensure the script sandbox does not add new lowercase injected globals. |
607
607
  | `check transforms` | Run transform and assembly invariants. |
@@ -646,7 +646,7 @@ The CLI is free for core workflows and exports. Production outputs are free to r
646
646
 
647
647
  | Free | Production outputs | Pro |
648
648
  |------|--------------------|-----|
649
- | `run`, `dev`, `studio`, `render 3d`, `export stl`, `export 3mf`, `export svg`, `check print`, `check params`, `inspect mechanical-integrity`, `check suite` | `cut-list`, `export sketch-pdf`, `export step`, `export brep`, `export gcode`, `export sdf`, `export urdf`, `export report`, `export cutting-layout` are free to run; Pro covers commercial use. | `render hq`, `capture gif`, `capture mp4` |
649
+ | `run`, `dev`, `studio`, `render 3d`, `export stl`, `export 3mf`, `export svg`, `check print`, `check params`, `inspect mechanical-integrity` | `cut-list`, `export sketch-pdf`, `export step`, `export brep`, `export gcode`, `export sdf`, `export urdf`, `export report`, `export cutting-layout` are free to run; Pro covers commercial use. | `render hq`, `capture gif`, `capture mp4` |
650
650
 
651
651
  ```bash
652
652
  forgecad license # Check signed-in account status
@@ -65,7 +65,7 @@ npm run lint:fix # auto-fix lint issues
65
65
  npm run format # auto-format all files
66
66
  ```
67
67
 
68
- Biome runs as part of `forgecad check suite`. Configuration lives in `biome.json` at the repo root.
68
+ Biome runs as part of `npm run check:suite`. Configuration lives in `biome.json` at the repo root.
69
69
 
70
70
  ## Self-Review Before Commit
71
71
 
@@ -7,9 +7,9 @@ skill-order: 2
7
7
 
8
8
  `forgecad render inspect` writes a deterministic directory bundle for agents,
9
9
  tests, and automation. Use it when a single shaded PNG is too ambiguous and the
10
- consumer needs geometry-aware signals such as depth, normals, surface roughness,
11
- part identity, physical connected components, collisions, local thickness, or
12
- cross-sections.
10
+ consumer needs geometry-aware signals such as depth, normals, Zebra stripes,
11
+ surface roughness, part identity, physical connected components, collisions,
12
+ local thickness, or cross-sections.
13
13
 
14
14
  ## When To Use It
15
15
 
@@ -49,7 +49,7 @@ with patterns such as `Bench.*`.
49
49
 
50
50
  ## Bundle Layout
51
51
 
52
- A bundle that asks for `--channels rgb,depth,normals,mask,section` has this
52
+ A bundle that asks for `--channels rgb,depth,normals,zebra,mask,section` has this
53
53
  layout:
54
54
 
55
55
  ```text
@@ -71,6 +71,11 @@ model-inspect/
71
71
  right.png
72
72
  top.png
73
73
  iso.png
74
+ zebra/
75
+ front.png
76
+ right.png
77
+ top.png
78
+ iso.png
74
79
  mask/
75
80
  front.png
76
81
  right.png
@@ -96,13 +101,15 @@ implemented channel in one bundle:
96
101
 
97
102
  ```bash
98
103
  forgecad render inspect model.forge.js --channels depth,normals
104
+ forgecad render inspect model.forge.js --channels rgb,zebra,normals
99
105
  forgecad render inspect model.forge.js --channels rgb,roughness
100
106
  forgecad render inspect model.forge.js --channels rgb,mask,collisions
101
107
  forgecad render inspect model.forge.js --channels rgb,section,thickness
102
108
  ```
103
109
 
104
- Supported channels are `rgb`, `depth`, `normals`, `roughness`, `mask`,
105
- `connectivity`, `distance`, `collisions`, `thickness`, and `section`.
110
+ Supported channels are `rgb`, `depth`, `normals`, `zebra`, `roughness`, `mask`,
111
+ `connectivity`, `floating`, `distance`, `collisions`, `thickness`, and
112
+ `section`.
106
113
 
107
114
  ## Channel Semantics
108
115
 
@@ -129,6 +136,17 @@ normal = normalize((rgb / 255) * 2 - 1)
129
136
 
130
137
  Background pixels are black and should be treated as `null`.
131
138
 
139
+ `zebra` emits reflective black-and-white stripe renders for visual
140
+ surface-continuity inspection. Stripes are generated from the visible
141
+ camera-view normal and simulated reflection direction, so smooth surfaces show
142
+ smooth flowing bands while normal discontinuities, faceting, and unexpected
143
+ creases kink or break the bands.
144
+
145
+ Use Zebra with `rgb` and `normals` when judging lofts, fillets, swept surfaces,
146
+ and skin-like forms. It is a human-readable shader diagnostic, not an exact
147
+ curvature-continuity proof; mesh tessellation quality and available smooth
148
+ normals determine how faithfully it represents the underlying surface.
149
+
132
150
  `roughness` emits a mesh-dihedral surface-quality heatmap. Smooth and gently
133
151
  curved triangles render as a faint translucent shadow over black, while
134
152
  triangles adjacent to sharp, harsh, boundary, or non-manifold mesh edges render
@@ -170,21 +188,58 @@ Connectivity is computed from visible scene objects:
170
188
 
171
189
  ```text
172
190
  bbox candidate = bbox interiors overlap or bbox contact gap <= 0.05 model units
173
- overlap edge = exact boolean intersection volume > 0.1 model units^3
174
- component = transitive closure over exact overlap edges
191
+ mesh contact edge = minimum mesh-surface distance <= contactTolerance
192
+ overlap edge = exact boolean intersection volume > 0.1 model units^3 for positive-volume overlap
193
+ component = transitive closure over mesh contact and exact overlap edges
175
194
  ```
176
195
 
177
196
  The manifest stores the edge list, component list, per-object body counts, and
178
- warnings. Component colors group scene objects; if one scene object contains
179
- multiple disconnected kernel bodies and the caller supplied a body count, the
180
- manifest reports `bodyCount > 1` but the PNG cannot color those internal bodies
181
- separately yet.
197
+ warnings. Component colors group scene objects and mesh body entries. If one
198
+ scene object contains multiple disconnected mesh islands, those islands are
199
+ reported and colored separately as entries such as `Part body 1` and
200
+ `Part body 2`.
201
+
202
+ Connectivity uses bbox only as a broadphase. Bbox contact alone is not enough to
203
+ merge separate scene objects by default, but mesh surfaces within contact
204
+ tolerance count as physically connected. This keeps concave assemblies such as
205
+ cages and captive balls from being falsely colored as one component while still
206
+ allowing stacked or nearly touching parts to share a component. Use the
207
+ `collisions` channel when you need positive-volume overlap evidence as a defect
208
+ report rather than a component grouping.
209
+
210
+ `floating` emits one disconnected-body highlight image per view. Black is
211
+ background or ground-reachable geometry. The highlight color marks physical
212
+ components that have no contact path to the ground plane.
213
+
214
+ Floating body detection splits visible meshes into disconnected body islands,
215
+ links bodies only when their minimum mesh-surface distance is within contact
216
+ tolerance (or exact positive-volume overlap when only shape evidence is
217
+ available), treats any connected component whose lower Z reaches the viewport
218
+ ground plane plus bed tolerance as grounded, then highlights every ungrounded
219
+ component. The default ground plane is the visible model's minimum Z;
220
+ `scene({ ground: { offset } })` moves it below that by the configured offset.
182
221
 
183
- Connectivity uses bbox only as a broadphase. Bbox contact is not enough to merge
184
- separate scene objects, which keeps concave assemblies such as cages and captive
185
- balls from being falsely colored as one component. Use the `collisions` channel
186
- when you need positive-volume overlap evidence as a defect report rather than a
187
- component grouping.
222
+ ```text
223
+ grounded = component bbox minZ <= groundZ + bedTolerance
224
+ floating body = !grounded
225
+ ```
226
+
227
+ This means a `union()` result with two disconnected mesh islands is inspected as
228
+ two separate bodies instead of being treated as one safe object. Bbox overlap or
229
+ bbox face contact alone is not support evidence. Use `connectivity`, `distance`,
230
+ or `collisions` when you need the full physical graph, rooted gap distances, or
231
+ collision defects.
232
+
233
+ `thickness` emits one local wall-thickness heatmap per view. Black is
234
+ background. Red/orange pixels are below the configured critical/warning
235
+ thresholds, green-to-blue pixels are acceptable/thick, and gray means the local
236
+ raycast could not resolve an opposite surface.
237
+
238
+ Thickness uses the same physical-contact edges as `connectivity` and `floating`.
239
+ When a ray crosses from one object to a direct physical-contact neighbor, hits
240
+ within `contactTolerance` are treated as contact seams and the ray continues to
241
+ the next surface. This prevents a tiny modeled gap between touching parts from
242
+ being reported as a paper-thin wall.
188
243
 
189
244
  `distance` emits one rooted physical-component-distance heatmap per view. Black
190
245
  is background. Non-black pixels resolve through
@@ -233,6 +288,10 @@ with the ghosted source geometry. If `--focus PartA,PartB` is used, everything
233
288
  except those objects is hidden, `PartA` and `PartB` are ghosted, and their
234
289
  overlap volume is highlighted if present.
235
290
 
291
+ Collision broadphase prunes exact boolean checks when the bbox intersection
292
+ volume is already below the overlap threshold. This does not change findings:
293
+ the real intersection volume cannot exceed the bbox intersection volume.
294
+
236
295
  `thickness` emits one local wall-thickness heatmap per view. The renderer places
237
296
  deterministic area-weighted point samples across visible mesh surfaces, casts
238
297
  through the object along each sample normal, and colors each point by the first
@@ -316,5 +375,4 @@ per-view depth ranges, and object-mask mappings live.
316
375
  guarantee. Open meshes, concave geometry, very coarse tessellation, or low
317
376
  `--thickness-samples` values can leave gray/unresolved or approximate regions.
318
377
  - Section atlases use five default interior slices today.
319
- - Zebra/reflection-line inspection is a follow-up channel, not part of the v1
320
- bundle.
378
+ - Zebra is a shader-based visual continuity aid, not exact curvature analysis.