FA-88761 / Mesh topology invariants / Open access
UV face lists of the wrong length are paired silently · case 01
A short UV list is wrapped around the face and invents seams.
ROOT CAUSE
The length check between face and UV face is missing.
VERIFIED REPAIR
Return ["uv-mismatch", i] when lengths differ.
Unsuccessful approach: Comparing only the number of faces misses per-face length mismatches.
Case contract
Input [faces, uvfaces]: each face has a parallel list of UV indices. A face whose UV list length differs returns ["uv-mismatch", face index]. A geometric edge is a seam when a later face assigns a different UV index to either endpoint than the first face did. Return sorted seam edges [min,max].
Why this case matters
Mesh processing pipelines (remeshing, export, simulation, printing) trust these topological counts and adjacency answers; a wrong invariant silently accepts broken meshes or rejects valid ones.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(x):
faces,uvf=x
seen={}
seams=set()
for fi,(f,t) in enumerate(zip(faces,uvf)):
n=len(f)
for i in range(n):
a,b=f[i],f[(i+1)%n]
ua,ub=t[i],t[(i+1)%n]
k=(min(a,b),max(a,b))
m={a:ua,b:ub}
if k in seen:
if seen[k]!=m: seams.add(k)
else: seen[k]=m
return sorted([list(k) for k in seams])
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['shared uv no seam', [[[[0, 1, 2], [2, 1, 3]], [[0, 1, 2], [2, 1, 3]]]], []], ['one endpoint split', [[[[0, 1, 2], [2, 1, 3]], [[0, 1, 2], [4, 1, 3]]]], [[1, 2]]], ['both endpoints split', [[[[0, 1, 2], [2, 1, 3]], [[0, 1, 2], [5, 4, 3]]]], [[1, 2]]], ['swapped uv indices', [[[[0, 1, 2], [2, 1, 3]], [[0, 1, 2], [1, 2, 3]]]], [[1, 2]]], ['cube with seams', [[[[0, 3, 2, 1], [4, 5, 6, 7], [0, 1, 5, 4], [1, 2, 6, 5], [2, 3, 7, 6], [3, 0, 4, 7]], [[0, 3, 2, 1], [4, 5, 6, 7], [0, 1, 9, 8], [1, 2, 10, 9], [2, 3, 11, 10], [3, 0, 8, 11]]]], [[4, 5], [4, 7], [5, 6], [6, 7]]], ['extra uv corner', [[[[0, 1, 2], [2, 1, 3]], [[0, 1, 2, 7], [2, 1, 3]]]], ['uv-mismatch', 0]], ['quad strip', [[[[0, 1, 4, 3], [1, 2, 5, 4]], [[0, 1, 4, 3], [1, 2, 5, 4]]]], []]], [['swapped uv indices', [[[[0, 1, 2], [2, 1, 3]], [[0, 1, 2], [1, 2, 3]]]], [[1, 2]]], ['cube with seams', [[[[0, 3, 2, 1], [4, 5, 6, 7], [0, 1, 5, 4], [1, 2, 6, 5], [2, 3, 7, 6], [3, 0, 4, 7]], [[0, 3, 2, 1], [4, 5, 6, 7], [0, 1, 9, 8], [1, 2, 10, 9], [2, 3, 11, 10], [3, 0, 8, 11]]]], [[4, 5], [4, 7], [5, 6], [6, 7]]], ['extra uv corner', [[[[0, 1, 2], [2, 1, 3]], [[0, 1, 2, 7], [2, 1, 3]]]], ['uv-mismatch', 0]], ['quad strip', [[[[0, 1, 4, 3], [1, 2, 5, 4]], [[0, 1, 4, 3], [1, 2, 5, 4]]]], []], ['quad strip split', [[[[0, 1, 4, 3], [1, 2, 5, 4]], [[0, 1, 4, 3], [6, 2, 5, 7]]]], [[1, 4]]], ['disk atlas', [[[[0, 1, 2], [0, 2, 3], [0, 3, 4], [0, 4, 5], [0, 5, 1]], [[0, 1, 2], [0, 2, 3], [0, 3, 4], [0, 4, 5], [6, 5, 1]]]], [[0, 1], [0, 5]]], ['same uv sum collision', [[[[0, 3, 1], [1, 3, 2]], [[0, 3, 1], [1, 3, 2]]]], []]], [['shared uv no seam', [[[[0, 1, 2], [2, 1, 3]], [[0, 1, 2], [2, 1, 3]]]], []], ['one endpoint split', [[[[0, 1, 2], [2, 1, 3]], [[0, 1, 2], [4, 1, 3]]]], [[1, 2]]], ['both endpoints split', [[[[0, 1, 2], [2, 1, 3]], [[0, 1, 2], [5, 4, 3]]]], [[1, 2]]], ['extra uv corner', [[[[0, 1, 2], [2, 1, 3]], [[0, 1, 2, 7], [2, 1, 3]]]], ['uv-mismatch', 0]], ['quad strip split', [[[[0, 1, 4, 3], [1, 2, 5, 4]], [[0, 1, 4, 3], [6, 2, 5, 7]]]], [[1, 4]]], ['disk atlas', [[[[0, 1, 2], [0, 2, 3], [0, 3, 4], [0, 4, 5], [0, 5, 1]], [[0, 1, 2], [0, 2, 3], [0, 3, 4], [0, 4, 5], [6, 5, 1]]]], [[0, 1], [0, 5]]], ['same uv sum collision', [[[[0, 3, 1], [1, 3, 2]], [[0, 3, 1], [1, 3, 2]]]], []]], [['shared uv no seam', [[[[0, 1, 2], [2, 1, 3]], [[0, 1, 2], [2, 1, 3]]]], []], ['one endpoint split', [[[[0, 1, 2], [2, 1, 3]], [[0, 1, 2], [4, 1, 3]]]], [[1, 2]]], ['both endpoints split', [[[[0, 1, 2], [2, 1, 3]], [[0, 1, 2], [5, 4, 3]]]], [[1, 2]]], ['swapped uv indices', [[[[0, 1, 2], [2, 1, 3]], [[0, 1, 2], [1, 2, 3]]]], [[1, 2]]], ['cube with seams', [[[[0, 3, 2, 1], [4, 5, 6, 7], [0, 1, 5, 4], [1, 2, 6, 5], [2, 3, 7, 6], [3, 0, 4, 7]], [[0, 3, 2, 1], [4, 5, 6, 7], [0, 1, 9, 8], [1, 2, 10, 9], [2, 3, 11, 10], [3, 0, 8, 11]]]], [[4, 5], [4, 7], [5, 6], [6, 7]]], ['extra uv corner', [[[[0, 1, 2], [2, 1, 3]], [[0, 1, 2, 7], [2, 1, 3]]]], ['uv-mismatch', 0]], ['quad strip', [[[[0, 1, 4, 3], [1, 2, 5, 4]], [[0, 1, 4, 3], [1, 2, 5, 4]]]], []]], [['swapped uv indices', [[[[0, 1, 2], [2, 1, 3]], [[0, 1, 2], [1, 2, 3]]]], [[1, 2]]], ['cube with seams', [[[[0, 3, 2, 1], [4, 5, 6, 7], [0, 1, 5, 4], [1, 2, 6, 5], [2, 3, 7, 6], [3, 0, 4, 7]], [[0, 3, 2, 1], [4, 5, 6, 7], [0, 1, 9, 8], [1, 2, 10, 9], [2, 3, 11, 10], [3, 0, 8, 11]]]], [[4, 5], [4, 7], [5, 6], [6, 7]]], ['extra uv corner', [[[[0, 1, 2], [2, 1, 3]], [[0, 1, 2, 7], [2, 1, 3]]]], ['uv-mismatch', 0]], ['quad strip', [[[[0, 1, 4, 3], [1, 2, 5, 4]], [[0, 1, 4, 3], [1, 2, 5, 4]]]], []], ['quad strip split', [[[[0, 1, 4, 3], [1, 2, 5, 4]], [[0, 1, 4, 3], [6, 2, 5, 7]]]], [[1, 4]]], ['disk atlas', [[[[0, 1, 2], [0, 2, 3], [0, 3, 4], [0, 4, 5], [0, 5, 1]], [[0, 1, 2], [0, 2, 3], [0, 3, 4], [0, 4, 5], [6, 5, 1]]]], [[0, 1], [0, 5]]], ['same uv sum collision', [[[[0, 3, 1], [1, 3, 2]], [[0, 3, 1], [1, 3, 2]]]], []]]]
for label, args, expected in fixtures[N-1]:
check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| shared uv no seam | [] | [] | Passed |
| one endpoint split | [[1, 2]] | [[1, 2]] | Passed |
| both endpoints split | [[1, 2]] | [[1, 2]] | Passed |
| swapped uv indices | [[1, 2]] | [[1, 2]] | Passed |
| cube with seams | [[4, 5], [4, 7], [5, 6], [6, 7]] | [[4, 5], [4, 7], [5, 6], [6, 7]] | Passed |
| extra uv corner | [] | ['uv-mismatch', 0] | Failed |
| quad strip | [] | [] | Passed |
SHA-256 / 82f7f7fa387b4758f9b395054c9a2f3649a9af0b3345938d2abf73fe41a45963
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(x):
faces,uvf=x
seen={}
if len(faces)!=len(uvf): return ['uv-mismatch',0]
seams=set()
for fi,(f,t) in enumerate(zip(faces,uvf)):
n=len(f)
for i in range(n):
a,b=f[i],f[(i+1)%n]
ua,ub=t[i],t[(i+1)%n]
k=(min(a,b),max(a,b))
m={a:ua,b:ub}
if k in seen:
if seen[k]!=m: seams.add(k)
else: seen[k]=m
return sorted([list(k) for k in seams])
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['shared uv no seam', [[[[0, 1, 2], [2, 1, 3]], [[0, 1, 2], [2, 1, 3]]]], []], ['one endpoint split', [[[[0, 1, 2], [2, 1, 3]], [[0, 1, 2], [4, 1, 3]]]], [[1, 2]]], ['both endpoints split', [[[[0, 1, 2], [2, 1, 3]], [[0, 1, 2], [5, 4, 3]]]], [[1, 2]]], ['swapped uv indices', [[[[0, 1, 2], [2, 1, 3]], [[0, 1, 2], [1, 2, 3]]]], [[1, 2]]], ['cube with seams', [[[[0, 3, 2, 1], [4, 5, 6, 7], [0, 1, 5, 4], [1, 2, 6, 5], [2, 3, 7, 6], [3, 0, 4, 7]], [[0, 3, 2, 1], [4, 5, 6, 7], [0, 1, 9, 8], [1, 2, 10, 9], [2, 3, 11, 10], [3, 0, 8, 11]]]], [[4, 5], [4, 7], [5, 6], [6, 7]]], ['extra uv corner', [[[[0, 1, 2], [2, 1, 3]], [[0, 1, 2, 7], [2, 1, 3]]]], ['uv-mismatch', 0]], ['quad strip', [[[[0, 1, 4, 3], [1, 2, 5, 4]], [[0, 1, 4, 3], [1, 2, 5, 4]]]], []]], [['swapped uv indices', [[[[0, 1, 2], [2, 1, 3]], [[0, 1, 2], [1, 2, 3]]]], [[1, 2]]], ['cube with seams', [[[[0, 3, 2, 1], [4, 5, 6, 7], [0, 1, 5, 4], [1, 2, 6, 5], [2, 3, 7, 6], [3, 0, 4, 7]], [[0, 3, 2, 1], [4, 5, 6, 7], [0, 1, 9, 8], [1, 2, 10, 9], [2, 3, 11, 10], [3, 0, 8, 11]]]], [[4, 5], [4, 7], [5, 6], [6, 7]]], ['extra uv corner', [[[[0, 1, 2], [2, 1, 3]], [[0, 1, 2, 7], [2, 1, 3]]]], ['uv-mismatch', 0]], ['quad strip', [[[[0, 1, 4, 3], [1, 2, 5, 4]], [[0, 1, 4, 3], [1, 2, 5, 4]]]], []], ['quad strip split', [[[[0, 1, 4, 3], [1, 2, 5, 4]], [[0, 1, 4, 3], [6, 2, 5, 7]]]], [[1, 4]]], ['disk atlas', [[[[0, 1, 2], [0, 2, 3], [0, 3, 4], [0, 4, 5], [0, 5, 1]], [[0, 1, 2], [0, 2, 3], [0, 3, 4], [0, 4, 5], [6, 5, 1]]]], [[0, 1], [0, 5]]], ['same uv sum collision', [[[[0, 3, 1], [1, 3, 2]], [[0, 3, 1], [1, 3, 2]]]], []]], [['shared uv no seam', [[[[0, 1, 2], [2, 1, 3]], [[0, 1, 2], [2, 1, 3]]]], []], ['one endpoint split', [[[[0, 1, 2], [2, 1, 3]], [[0, 1, 2], [4, 1, 3]]]], [[1, 2]]], ['both endpoints split', [[[[0, 1, 2], [2, 1, 3]], [[0, 1, 2], [5, 4, 3]]]], [[1, 2]]], ['extra uv corner', [[[[0, 1, 2], [2, 1, 3]], [[0, 1, 2, 7], [2, 1, 3]]]], ['uv-mismatch', 0]], ['quad strip split', [[[[0, 1, 4, 3], [1, 2, 5, 4]], [[0, 1, 4, 3], [6, 2, 5, 7]]]], [[1, 4]]], ['disk atlas', [[[[0, 1, 2], [0, 2, 3], [0, 3, 4], [0, 4, 5], [0, 5, 1]], [[0, 1, 2], [0, 2, 3], [0, 3, 4], [0, 4, 5], [6, 5, 1]]]], [[0, 1], [0, 5]]], ['same uv sum collision', [[[[0, 3, 1], [1, 3, 2]], [[0, 3, 1], [1, 3, 2]]]], []]], [['shared uv no seam', [[[[0, 1, 2], [2, 1, 3]], [[0, 1, 2], [2, 1, 3]]]], []], ['one endpoint split', [[[[0, 1, 2], [2, 1, 3]], [[0, 1, 2], [4, 1, 3]]]], [[1, 2]]], ['both endpoints split', [[[[0, 1, 2], [2, 1, 3]], [[0, 1, 2], [5, 4, 3]]]], [[1, 2]]], ['swapped uv indices', [[[[0, 1, 2], [2, 1, 3]], [[0, 1, 2], [1, 2, 3]]]], [[1, 2]]], ['cube with seams', [[[[0, 3, 2, 1], [4, 5, 6, 7], [0, 1, 5, 4], [1, 2, 6, 5], [2, 3, 7, 6], [3, 0, 4, 7]], [[0, 3, 2, 1], [4, 5, 6, 7], [0, 1, 9, 8], [1, 2, 10, 9], [2, 3, 11, 10], [3, 0, 8, 11]]]], [[4, 5], [4, 7], [5, 6], [6, 7]]], ['extra uv corner', [[[[0, 1, 2], [2, 1, 3]], [[0, 1, 2, 7], [2, 1, 3]]]], ['uv-mismatch', 0]], ['quad strip', [[[[0, 1, 4, 3], [1, 2, 5, 4]], [[0, 1, 4, 3], [1, 2, 5, 4]]]], []]], [['swapped uv indices', [[[[0, 1, 2], [2, 1, 3]], [[0, 1, 2], [1, 2, 3]]]], [[1, 2]]], ['cube with seams', [[[[0, 3, 2, 1], [4, 5, 6, 7], [0, 1, 5, 4], [1, 2, 6, 5], [2, 3, 7, 6], [3, 0, 4, 7]], [[0, 3, 2, 1], [4, 5, 6, 7], [0, 1, 9, 8], [1, 2, 10, 9], [2, 3, 11, 10], [3, 0, 8, 11]]]], [[4, 5], [4, 7], [5, 6], [6, 7]]], ['extra uv corner', [[[[0, 1, 2], [2, 1, 3]], [[0, 1, 2, 7], [2, 1, 3]]]], ['uv-mismatch', 0]], ['quad strip', [[[[0, 1, 4, 3], [1, 2, 5, 4]], [[0, 1, 4, 3], [1, 2, 5, 4]]]], []], ['quad strip split', [[[[0, 1, 4, 3], [1, 2, 5, 4]], [[0, 1, 4, 3], [6, 2, 5, 7]]]], [[1, 4]]], ['disk atlas', [[[[0, 1, 2], [0, 2, 3], [0, 3, 4], [0, 4, 5], [0, 5, 1]], [[0, 1, 2], [0, 2, 3], [0, 3, 4], [0, 4, 5], [6, 5, 1]]]], [[0, 1], [0, 5]]], ['same uv sum collision', [[[[0, 3, 1], [1, 3, 2]], [[0, 3, 1], [1, 3, 2]]]], []]]]
for label, args, expected in fixtures[N-1]:
check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| shared uv no seam | [] | [] | Passed |
| one endpoint split | [[1, 2]] | [[1, 2]] | Passed |
| both endpoints split | [[1, 2]] | [[1, 2]] | Passed |
| swapped uv indices | [[1, 2]] | [[1, 2]] | Passed |
| cube with seams | [[4, 5], [4, 7], [5, 6], [6, 7]] | [[4, 5], [4, 7], [5, 6], [6, 7]] | Passed |
| extra uv corner | [] | ['uv-mismatch', 0] | Failed |
| quad strip | [] | [] | Passed |
SHA-256 / 48a0ba895208d4ac432fe1c960f3f0dea968509c0c0a42fb0471972980f4e3c5
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(x):
faces,uvf=x
seen={}
seams=set()
for fi,(f,t) in enumerate(zip(faces,uvf)):
if len(f)!=len(t): return ['uv-mismatch',fi]
n=len(f)
for i in range(n):
a,b=f[i],f[(i+1)%n]
ua,ub=t[i],t[(i+1)%n]
k=(min(a,b),max(a,b))
m={a:ua,b:ub}
if k in seen:
if seen[k]!=m: seams.add(k)
else: seen[k]=m
return sorted([list(k) for k in seams])
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['shared uv no seam', [[[[0, 1, 2], [2, 1, 3]], [[0, 1, 2], [2, 1, 3]]]], []], ['one endpoint split', [[[[0, 1, 2], [2, 1, 3]], [[0, 1, 2], [4, 1, 3]]]], [[1, 2]]], ['both endpoints split', [[[[0, 1, 2], [2, 1, 3]], [[0, 1, 2], [5, 4, 3]]]], [[1, 2]]], ['swapped uv indices', [[[[0, 1, 2], [2, 1, 3]], [[0, 1, 2], [1, 2, 3]]]], [[1, 2]]], ['cube with seams', [[[[0, 3, 2, 1], [4, 5, 6, 7], [0, 1, 5, 4], [1, 2, 6, 5], [2, 3, 7, 6], [3, 0, 4, 7]], [[0, 3, 2, 1], [4, 5, 6, 7], [0, 1, 9, 8], [1, 2, 10, 9], [2, 3, 11, 10], [3, 0, 8, 11]]]], [[4, 5], [4, 7], [5, 6], [6, 7]]], ['extra uv corner', [[[[0, 1, 2], [2, 1, 3]], [[0, 1, 2, 7], [2, 1, 3]]]], ['uv-mismatch', 0]], ['quad strip', [[[[0, 1, 4, 3], [1, 2, 5, 4]], [[0, 1, 4, 3], [1, 2, 5, 4]]]], []]], [['swapped uv indices', [[[[0, 1, 2], [2, 1, 3]], [[0, 1, 2], [1, 2, 3]]]], [[1, 2]]], ['cube with seams', [[[[0, 3, 2, 1], [4, 5, 6, 7], [0, 1, 5, 4], [1, 2, 6, 5], [2, 3, 7, 6], [3, 0, 4, 7]], [[0, 3, 2, 1], [4, 5, 6, 7], [0, 1, 9, 8], [1, 2, 10, 9], [2, 3, 11, 10], [3, 0, 8, 11]]]], [[4, 5], [4, 7], [5, 6], [6, 7]]], ['extra uv corner', [[[[0, 1, 2], [2, 1, 3]], [[0, 1, 2, 7], [2, 1, 3]]]], ['uv-mismatch', 0]], ['quad strip', [[[[0, 1, 4, 3], [1, 2, 5, 4]], [[0, 1, 4, 3], [1, 2, 5, 4]]]], []], ['quad strip split', [[[[0, 1, 4, 3], [1, 2, 5, 4]], [[0, 1, 4, 3], [6, 2, 5, 7]]]], [[1, 4]]], ['disk atlas', [[[[0, 1, 2], [0, 2, 3], [0, 3, 4], [0, 4, 5], [0, 5, 1]], [[0, 1, 2], [0, 2, 3], [0, 3, 4], [0, 4, 5], [6, 5, 1]]]], [[0, 1], [0, 5]]], ['same uv sum collision', [[[[0, 3, 1], [1, 3, 2]], [[0, 3, 1], [1, 3, 2]]]], []]], [['shared uv no seam', [[[[0, 1, 2], [2, 1, 3]], [[0, 1, 2], [2, 1, 3]]]], []], ['one endpoint split', [[[[0, 1, 2], [2, 1, 3]], [[0, 1, 2], [4, 1, 3]]]], [[1, 2]]], ['both endpoints split', [[[[0, 1, 2], [2, 1, 3]], [[0, 1, 2], [5, 4, 3]]]], [[1, 2]]], ['extra uv corner', [[[[0, 1, 2], [2, 1, 3]], [[0, 1, 2, 7], [2, 1, 3]]]], ['uv-mismatch', 0]], ['quad strip split', [[[[0, 1, 4, 3], [1, 2, 5, 4]], [[0, 1, 4, 3], [6, 2, 5, 7]]]], [[1, 4]]], ['disk atlas', [[[[0, 1, 2], [0, 2, 3], [0, 3, 4], [0, 4, 5], [0, 5, 1]], [[0, 1, 2], [0, 2, 3], [0, 3, 4], [0, 4, 5], [6, 5, 1]]]], [[0, 1], [0, 5]]], ['same uv sum collision', [[[[0, 3, 1], [1, 3, 2]], [[0, 3, 1], [1, 3, 2]]]], []]], [['shared uv no seam', [[[[0, 1, 2], [2, 1, 3]], [[0, 1, 2], [2, 1, 3]]]], []], ['one endpoint split', [[[[0, 1, 2], [2, 1, 3]], [[0, 1, 2], [4, 1, 3]]]], [[1, 2]]], ['both endpoints split', [[[[0, 1, 2], [2, 1, 3]], [[0, 1, 2], [5, 4, 3]]]], [[1, 2]]], ['swapped uv indices', [[[[0, 1, 2], [2, 1, 3]], [[0, 1, 2], [1, 2, 3]]]], [[1, 2]]], ['cube with seams', [[[[0, 3, 2, 1], [4, 5, 6, 7], [0, 1, 5, 4], [1, 2, 6, 5], [2, 3, 7, 6], [3, 0, 4, 7]], [[0, 3, 2, 1], [4, 5, 6, 7], [0, 1, 9, 8], [1, 2, 10, 9], [2, 3, 11, 10], [3, 0, 8, 11]]]], [[4, 5], [4, 7], [5, 6], [6, 7]]], ['extra uv corner', [[[[0, 1, 2], [2, 1, 3]], [[0, 1, 2, 7], [2, 1, 3]]]], ['uv-mismatch', 0]], ['quad strip', [[[[0, 1, 4, 3], [1, 2, 5, 4]], [[0, 1, 4, 3], [1, 2, 5, 4]]]], []]], [['swapped uv indices', [[[[0, 1, 2], [2, 1, 3]], [[0, 1, 2], [1, 2, 3]]]], [[1, 2]]], ['cube with seams', [[[[0, 3, 2, 1], [4, 5, 6, 7], [0, 1, 5, 4], [1, 2, 6, 5], [2, 3, 7, 6], [3, 0, 4, 7]], [[0, 3, 2, 1], [4, 5, 6, 7], [0, 1, 9, 8], [1, 2, 10, 9], [2, 3, 11, 10], [3, 0, 8, 11]]]], [[4, 5], [4, 7], [5, 6], [6, 7]]], ['extra uv corner', [[[[0, 1, 2], [2, 1, 3]], [[0, 1, 2, 7], [2, 1, 3]]]], ['uv-mismatch', 0]], ['quad strip', [[[[0, 1, 4, 3], [1, 2, 5, 4]], [[0, 1, 4, 3], [1, 2, 5, 4]]]], []], ['quad strip split', [[[[0, 1, 4, 3], [1, 2, 5, 4]], [[0, 1, 4, 3], [6, 2, 5, 7]]]], [[1, 4]]], ['disk atlas', [[[[0, 1, 2], [0, 2, 3], [0, 3, 4], [0, 4, 5], [0, 5, 1]], [[0, 1, 2], [0, 2, 3], [0, 3, 4], [0, 4, 5], [6, 5, 1]]]], [[0, 1], [0, 5]]], ['same uv sum collision', [[[[0, 3, 1], [1, 3, 2]], [[0, 3, 1], [1, 3, 2]]]], []]]]
for label, args, expected in fixtures[N-1]:
check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| shared uv no seam | [] | [] | Passed |
| one endpoint split | [[1, 2]] | [[1, 2]] | Passed |
| both endpoints split | [[1, 2]] | [[1, 2]] | Passed |
| swapped uv indices | [[1, 2]] | [[1, 2]] | Passed |
| cube with seams | [[4, 5], [4, 7], [5, 6], [6, 7]] | [[4, 5], [4, 7], [5, 6], [6, 7]] | Passed |
| extra uv corner | ['uv-mismatch', 0] | ['uv-mismatch', 0] | Passed |
| quad strip | [] | [] | Passed |
SHA-256 / 6c5c18306fddcb7b0183a97d23aee59e85ec5e503b59367f2049292f7a739f6c
Verification & scope
Pure combinatorial teaching model over integer face lists with a stipulated contract; no geometry kernel or file format is implied. This reproducer isolates one failure mechanism. Results cover the supplied fixtures. Variants within a family share a test contract and should remain grouped when constructing evaluation splits. Related mechanisms with a shared evaluation_group must also remain together; these controlled models are not independent production incidents.
Observations recorded using Python 3.12.14 at 2026-09-29T14:51:11.032691+00:00.
Case digest / 051c421c92e61fb0554ce658048e775561f2a724321da9b1154f3cd7f3ecbde3