kwabs22 Claude Opus 5.5 commited on
Commit
3de3640
Β·
1 Parent(s): af80e6b

Stop the ladder when a rung collapses in space, not just in faces

Browse files

QA round 3: a 384-face cat rung had 0.0017 m2 of area against 0.2233 on the
1000-face rung, and passed because the guard only counted faces. A rung now
also ends the ladder when it is under half the original's size, or under
half the previous decimated rung's area (the original is left out of the
area test: welding away double-sided faces can halve area legitimately).

Also archives verification round 3.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

feedback/vli-qa-feedback-2026-10-30.md CHANGED
@@ -124,3 +124,19 @@ Seed-0 baseline reproduced bit-identically from the first session: uid `4459b90d
124
  1. **Decimate floor:** weld between passes β€” `out.merge_vertices()` then re-run `simplify_quadric_decimation` in a loop until the target or no further progress (Objaverse GLBs split vertices; the decimator starves on unshared edges). If a floor persists, surface it in the page (`"faces": n, "budget": 400, "floor": true`) instead of silently exceeding.
125
  2. **Ladder duplicate rungs:** the rung guard compares against the requested level, so a stalled decimation still appends lower rungs (1000/250/60 all rendered as the same 1,141-face mesh). Stop descending when a rung fails to actually reduce.
126
  3. Still open: `use` back-swap after a skip shifts indices; live `skip`-mode; the UI visual click-test (mode radio + preview-from-file β€” code verified, needs eyes).
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
124
  1. **Decimate floor:** weld between passes β€” `out.merge_vertices()` then re-run `simplify_quadric_decimation` in a loop until the target or no further progress (Objaverse GLBs split vertices; the decimator starves on unshared edges). If a floor persists, surface it in the page (`"faces": n, "budget": 400, "floor": true`) instead of silently exceeding.
125
  2. **Ladder duplicate rungs:** the rung guard compares against the requested level, so a stalled decimation still appends lower rungs (1000/250/60 all rendered as the same 1,141-face mesh). Stop descending when a rung fails to actually reduce.
126
  3. Still open: `use` back-swap after a skip shifts indices; live `skip`-mode; the UI visual click-test (mode radio + preview-from-file β€” code verified, needs eyes).
127
+
128
+ ---
129
+
130
+ ## 6. Verification round 3 (2026-10-30, after the decimate/ladder push) β€” all pass
131
+
132
+ | Item | Live result |
133
+ |---|---|
134
+ | Decimate floor (weld-and-repeat) | βœ“ same cat that floored at 1,141 now descends 135,934 β†’ 20,000 β†’ 5,000 β†’ 1,000 β†’ **384**; most rungs now `watertight: true` β€” welding genuinely unlocked the collapsed-edge structure |
135
+ | Ladder stall guard | βœ“ no duplicate rungs; labels show actual counts (`384 faces`), and the ladder stops before hull when a rung stalls |
136
+ | Page budget (closes P2-5) | βœ“ inline cat page: `"faces": 400, "budget": 400, "floor": false` β€” the inline payload dropped from ~30,000 numbers to ~1,600 |
137
+ | `budget`/`floor` flags | βœ“ present in every page mesh object |
138
+ | `skip` mode | βœ“ live: 4th output is `None`, no page text; ledger/PNG/GLB unaffected |
139
+
140
+ **One new observation for round 4:** deep rungs can *spatially collapse*. The 384-face rung's `surface_area_m2` is 0.0017 vs 0.2233 on the 1,000 rung (~130Γ— area loss) β€” the stall guard checks face count only, so a degenerate blob can pass as a legitimate rung, which misleads the papercraft/materialization use-case. Suggested guard addition: stop (or keep the previous rung) when a rung's area drops sharply, e.g. below ~50% of the previous rung's area. Page budgets look unaffected β€” the 400-face page cat keeps a normal ~0.3 m vertex spread β€” so this is a ladder-quality issue, not a page issue.
141
+
142
+ Still open: `use` back-swap after a skip shifts indices; the UI visual click-test; P2-7 dictionary drift (now applies to the ForgeCAD SimReady source too).
vli/simplify.py CHANGED
@@ -142,6 +142,16 @@ def rings(mesh, count=8, samples=16):
142
  return out, profile
143
 
144
 
 
 
 
 
 
 
 
 
 
 
145
  def ladder(mesh, ring_count=8, ring_samples=16):
146
  color = base_color(mesh)
147
  rungs = [("original", mesh)]
@@ -152,6 +162,8 @@ def ladder(mesh, ring_count=8, ring_samples=16):
152
  rung = decimate(mesh, n)
153
  if len(rung.faces) > 0.8 * prev:
154
  break # decimation stalled: lower levels would repeat this mesh
 
 
155
  rungs.append((f"{len(rung.faces)} faces", rung))
156
  ringed, profile = rings(mesh, ring_count, ring_samples)
157
  if ringed is not None:
 
142
  return out, profile
143
 
144
 
145
+ def _collapsed(rung, original, prev):
146
+ """A rung that shrank in space, not just in faces: under half the original's size,
147
+ or under half the previous decimated rung's area. The original is left out of the
148
+ area test, since welding away double-sided faces can halve area legitimately.
149
+ """
150
+ if rung.extents.max() < 0.5 * original.extents.max():
151
+ return True
152
+ return prev is not None and rung.area < 0.5 * prev.area
153
+
154
+
155
  def ladder(mesh, ring_count=8, ring_samples=16):
156
  color = base_color(mesh)
157
  rungs = [("original", mesh)]
 
162
  rung = decimate(mesh, n)
163
  if len(rung.faces) > 0.8 * prev:
164
  break # decimation stalled: lower levels would repeat this mesh
165
+ if _collapsed(rung, mesh, rungs[-1][1] if len(rungs) > 1 else None):
166
+ break # a degenerate blob would pass for a rung; lower levels only get worse
167
  rungs.append((f"{len(rung.faces)} faces", rung))
168
  ringed, profile = rings(mesh, ring_count, ring_samples)
169
  if ringed is not None: