Skip to content

Commit 94153c7

Browse files
TMHSDigitalclaude
andcommitted
docs(examples): coincident-vert-weld README states who hits it and what catches it, re-verified on 5.1
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Signed-off-by: TMHSDigital <154358121+TMHSDigital@users.noreply.github.com>
1 parent da9bc29 commit 94153c7

1 file changed

Lines changed: 51 additions & 12 deletions

File tree

‎examples/coincident-vert-weld/README.md‎

Lines changed: 51 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,23 +8,62 @@ Inverse of [`degenerate-bevel-weld`](../degenerate-bevel-weld/)
88
solid). Neighbor of [`gltf-export-roundtrip`](../gltf-export-roundtrip/)
99
(kit-bash face-plane welds on export).
1010

11-
**Why this pathology:** coincident shells are still manifold (every
12-
edge borders 2 faces). Hygiene can pass. The engine trap is extra
13-
triangles on disk.
11+
## The contract
12+
13+
A mesh holding two coincident shells is still **manifold**: every edge
14+
borders exactly two faces, because each shell is closed on its own. A
15+
hygiene check that only counts non-manifold edges reports 0 and passes.
16+
The glTF exporter then writes both shells: nothing in
17+
`bpy.ops.export_scene.gltf` welds coincident vertices, so the file
18+
carries twice the triangles of the visible solid.
19+
20+
**Who hits this:** kit-bash and boolean-cleanup pipelines, duplicated
21+
objects joined back onto themselves, and generators that emit a part
22+
twice. The asset looks like one cube in Blender and in the engine: the
23+
two shells are identical triangles, so the depth test hides the second
24+
without flicker. The cost is invisible in the viewport and real on disk
25+
and at runtime: double the draw triangles, a collider built from the mesh
26+
twice as heavy, and overlapping lightmap UVs if the shells were unwrapped.
27+
28+
**What catches it:** a coincident-vertex check, not a manifold check.
29+
`bmesh.ops.find_doubles(dist=1e-5)` reports **8** doubles on this mesh
30+
while the non-manifold count stays **0**. That is why the showcase
31+
hygiene budgets count doubles separately from non-manifold edges. The
32+
fix is `bmesh.ops.remove_doubles` before export.
33+
34+
## What the check asserts
1435

1536
**Pre-assertion (pathology exists):** **16** verts, **8** unique
16-
positions, **12** faces, **24** edges, valence all 2. `--no-duplicate`
17-
exits 3.
37+
positions, **12** faces, **24** edges, valence 2 on every edge.
38+
`--no-duplicate` builds a single cube and exits 3. Vert count 16 alone is
39+
not enough, since any 16-vert mesh has it. Unique positions = 8 is the
40+
construction witness.
41+
42+
**Handling (second axis):** read back from the written `.gltf` and its
43+
`.bin`: **48** loop-split positions, **24** triangles, **8** unique
44+
positions. `--weld` runs `remove_doubles` after the pre-assertion, the
45+
file then carries 24 positions and 12 triangles, and the check exits 4.
46+
47+
`remove_doubles` collapses the pair to one cube: 8 verts, 12 edges,
48+
6 faces, valence 2. That is identical in every count to a cube built
49+
once. It does not leave a 4-faces-per-edge mesh.
50+
51+
## Versions
52+
53+
Re-verified on Blender 4.5.11 LTS, 5.1.2 and 5.2.1 LTS. Every count
54+
above is the same on all three, including the `find_doubles` and
55+
non-manifold figures and both falsifier exits. Not a version split.
1856

19-
**Handling (second axis):** glTF ships **48** loop-split positions,
20-
**24** tris, **8** unique. Vert count 16 is not enough; unique=8 is
21-
the construction axis; 24 tris vs 12 after `remove_doubles` is the
22-
export axis. `--weld` after the pre-assert exits 4.
57+
No gallery still. Two coincident cubes look like one cube; the defect
58+
is only in the counts.
2359

24-
`remove_doubles` collapses to one cube (8/12/6), still manifold — not
25-
a 4-face-per-edge mesh. Same on 4.5 LTS and 5.2 LTS.
60+
## API reference
2661

27-
No gallery still. Two coincident cubes look like one cube.
62+
- [`bmesh.ops.find_doubles`](https://docs.blender.org/api/current/bmesh.ops.html#bmesh.ops.find_doubles)
63+
and [`bmesh.ops.remove_doubles`](https://docs.blender.org/api/current/bmesh.ops.html#bmesh.ops.remove_doubles)
64+
([4.5 LTS](https://docs.blender.org/api/4.5/bmesh.ops.html#bmesh.ops.remove_doubles))
65+
- [`bpy.ops.export_scene.gltf`](https://docs.blender.org/api/current/bpy.ops.export_scene.html#bpy.ops.export_scene.gltf)
66+
([4.5 LTS](https://docs.blender.org/api/4.5/bpy.ops.export_scene.html#bpy.ops.export_scene.gltf))
2867

2968
## Run
3069

0 commit comments

Comments
 (0)