Skip to content

kernel: panic "Normals/vertices mismatch: N normals vs 2N vertices" on octagonal flange tessellation #162

@ecto

Description

@ecto

Summary

Boolean output for an octagon-shaped flange (intersection of two boxes, then differenced with eight cylindrical bolt holes) panics during tessellation/normals build with:

kernel panic: Normals/vertices mismatch: 792 normals vs 1584 vertices

The 1:2 ratio (vertices == 2 × normals) is a tell — somewhere the vertex array is being expanded (probably to give per-face crease normals) without the normal array following along, or a mesh-merge step concatenates vertices but reuses a shared normals slice.

Reproduction

This is the IR submitted by gpt-5-mini for mecheval/tasks/a3-octagonal-flange-01.json — full .vcad saved at mecheval/runs/a3-octagonal-flange-01/openai-direct-gpt-5-mini/20260429T000804Z-28c7.vcad. Skeleton:

{
  "version": "0.1",
  "nodes": {
    "box_a":  { "op": {"type": "Cube", "size": {"x": 60, "y": 40, "z": 8}} },
    "box_b":  { "op": {"type": "Rotate", "child": "box_a_centered", "angles": {"x": 0, "y": 0, "z": 45}} },
    "octagon":{ "op": {"type": "Intersection", "left": "box_a_centered", "right": "box_b"} },
    "holes":  { "op": {"type": "Union", ...8 cylinders r=2.5 on bolt circle r=15...} },
    "result": { "op": {"type": "Difference", "left": "octagon", "right": "holes"} }
  }
}

(The reproduction blob in the runs/ dir uses the right shape but with the IDs/keys still string-typed; replace those with numeric keys/values to bypass the parser. The kernel panic happens after parse succeeds.)

Where to look

  • crates/vcad-kernel-tessellate/src/lib.rs — wherever the assertion normals.len() == vertices.len() fires.
  • The 2× ratio suggests a vertex-doubling step (e.g. crease-aware tessellation that emits two copies of a vertex along a sharp edge) that's not paralleled in the normal stream.
  • Try minimizing the repro: it's likely the Difference over the 45°-rotated-box intersection produces a face structure that the tessellator's normal pass doesn't expect.

Affected mecheval tasks

  • a3-octagonal-flange-01 — 2 of 32 runs panic with this exact message; the other 30 produce wrong-shape outputs (model output bug, separate from this).

Acceptance

  • Tessellator either succeeds or returns a non-panicking error.
  • Add a regression test in vcad-kernel-tessellate covering Difference(Intersection(box, rotated-box), Union(cylinders)).

Refs

  • Diagnosed during 2026-04-29 mecheval failure triage

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingkernelRust kernel cratesrobustnessEdge cases / numerical robustness

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions