code wiki / (root) / nx_meshcheck_gate.nx

nx_meshcheck_gate.nx source

↩ module page · 202 lines · 11846 B

1// nx_meshcheck_gate.nx -- proves the mesh integrity sweep, in BOTH directions, per defect class. 2// 3// THE POSITIVE CONTROL IS A TETRAHEDRON, and it is chosen because it is the smallest object for which 4// every property under test is simultaneously non-trivial: 4 vertices, 4 faces, 6 edges each shared by 5// exactly two faces traversing it in OPPOSITE directions, no loose vertices, no degeneracies, and an 6// Euler characteristic of exactly 2. A cube would work too and would hide a winding bug behind more 7// symmetry; a single triangle would pass most teeth vacuously because it has no shared edge at all. 8// 9// EVERY DEFECT CLASS GETS ITS OWN PLANTED MUTANT, because the classes have DIFFERENT REMEDIES and a 10// detector that fires on all of them identically is one counter wearing six names. Each mutant is 11// built at runtime from the same clean tetrahedron, so a tooth that fires is firing on exactly one 12// injected difference. 13import "nx_syscalls.nx" 14import "nx_gate_verdict.nx" 15import "nx_meshcheck.nx" 16 17const MG_U: i64 = 1000 // one millimetre in the micrometre units this fixture uses 18const MG_SCRATCH: i64 = 64 19 20func mg_out() -> *i64 { return sys_mmap(MC_O_SLOTS * MC_I64) as *i64 } 21func mg_list() -> *i64 { return sys_mmap(mc_list_slots() * MC_I64) as *i64 } 22 23// the clean tetrahedron: verts (0,0,0) (u,0,0) (0,u,0) (0,0,u) 24func mg_tet_verts(extra: i64) -> *i64 { 25 let v: *i64 = sys_mmap((4 + extra) * 3 * MC_I64) as *i64 26 v[0]=0; v[1]=0; v[2]=0 27 v[3]=MG_U; v[4]=0; v[5]=0 28 v[6]=0; v[7]=MG_U; v[8]=0 29 v[9]=0; v[10]=0; v[11]=MG_U 30 var i: i64 = 0 31 while i < extra * 3 { v[12 + i] = MG_U + MG_U; i = i + 1 } 32 return v 33} 34// faces wound consistently outward: every edge appears twice, in opposite directions 35func mg_tet_tris(extra: i64) -> *i64 { 36 let t: *i64 = sys_mmap((4 + extra) * 3 * MC_I64) as *i64 37 t[0]=0; t[1]=2; t[2]=1 38 t[3]=0; t[4]=1; t[5]=3 39 t[6]=0; t[7]=3; t[8]=2 40 t[9]=1; t[10]=2; t[11]=3 41 return t 42} 43 44func mg_eq(a: i64, b: i64) -> i64 { if a == b { return 1 } return 0 } 45func mg_pos(a: i64) -> i64 { if a > 0 { return 1 } return 0 } 46func mg_zero(a: i64) -> i64 { if a == 0 { return 1 } return 0 } 47func mg_eq2(a: i64, b: i64, c: i64, d: i64) -> i64 { if a == b { if c == d { return 1 } } return 0 } 48func mg_eq3(a: i64, b: i64, c: i64, d: i64, e: i64, f: i64) -> i64 { 49 if a == b { if c == d { if e == f { return 1 } } } return 0 50} 51 52func main() -> i64 { 53 let ctr: *i64 = gv_ctr() 54 gv_head("nx_meshcheck_gate -- mesh integrity: non-manifold edges, winding, loose vertices, degeneracy, duplicates" as *u8) 55 56 // ---- POSITIVE CONTROL -------------------------------------------------------------------------- 57 let o: *i64 = mg_out() 58 let l: *i64 = mg_list() 59 let tv: *i64 = mg_tet_verts(0) 60 let tt: *i64 = mg_tet_tris(0) 61 let clean: i64 = mc_check(tv, 4, tt, 4, o, l) 62 gv_subjects("triangles in the clean control" as *u8, o[MC_O_TRIS], ctr) 63 gv_check("T1 a correctly wound closed tetrahedron reads CLEAN with zero defects of every class" as *u8, 64 mg_eq2(clean, MC_CLEAN, mc_defect_total(o), 0), ctr) 65 gv_check("T2 its six edges are each shared by exactly two faces -- zero boundary, zero non-manifold" as *u8, 66 mg_eq3(o[MC_O_EDGES], 6, o[MC_O_BOUNDARY], 0, o[MC_O_NONMANIFOLD], 0), ctr) 67 gv_check("T3 it is WATERTIGHT, and Euler is REPORTED as 2 rather than used as the verdict" as *u8, 68 mg_eq2(mc_watertight(o), 1, o[MC_O_EULER], 2), ctr) 69 70 // ---- THE EMPTY SET ----------------------------------------------------------------------------- 71 let oe: *i64 = mg_out() 72 let le: *i64 = mg_list() 73 let empty: i64 = mc_check(tv, 4, tt, 0, oe, le) 74 gv_check("neg-control-a-mesh-with-ZERO-faces-is-UNMEASURABLE-never-CLEAN" as *u8, 75 mg_eq(empty, MC_UNMEASURABLE), ctr) 76 77 // ---- AN INDEX THAT CANNOT BE DEREFERENCED ------------------------------------------------------ 78 // Checked FIRST inside the organ, because every later pass reads through these indices: validating 79 // them afterwards would mean reading out of bounds to discover they were out of bounds. 80 let ob: *i64 = mg_out() 81 let lb: *i64 = mg_list() 82 let bt: *i64 = mg_tet_tris(0) 83 bt[11] = 99 84 let badv: i64 = mc_check(tv, 4, bt, 4, ob, lb) 85 gv_check("neg-control-an-out-of-range-vertex-index-returns-INVALID-and-NAMES-the-offending-triangle" as *u8, 86 mg_eq3(badv, MC_INVALID, ob[MC_O_BADINDEX], 1, mc_list_get(lb, MC_L_BADINDEX, 0), 3), ctr) 87 88 // ---- NON-MANIFOLD: a third face on an existing edge --------------------------------------------- 89 let ov: *i64 = mg_out() 90 let lv: *i64 = mg_list() 91 let nv5: *i64 = mg_tet_verts(1) 92 let nt5: *i64 = mg_tet_tris(1) 93 nt5[12]=0; nt5[13]=1; nt5[14]=4 94 let nm: i64 = mc_check(nv5, 5, nt5, 5, ov, lv) 95 gv_check("T6 a third face on edge 0-1 is counted as exactly ONE non-manifold edge, not as three" as *u8, 96 mg_eq2(nm, MC_DEFECTS, ov[MC_O_NONMANIFOLD], 1), ctr) 97 gv_bite("T7 non-manifold edge detection" as *u8, mg_pos(ov[MC_O_NONMANIFOLD]), mg_pos(o[MC_O_NONMANIFOLD]), ctr) 98 // the same mutant opens two boundary edges, and boundary is DELIBERATELY not a defect 99 gv_check("T8 the same mutant opens two BOUNDARY edges, reported on their own axis and not as defects" as *u8, 100 mg_eq(ov[MC_O_BOUNDARY], 2), ctr) 101 102 // ---- WINDING: one face reversed ------------------------------------------------------------------ 103 // The deepest of the classes: the mesh stays closed and manifold, every edge still has exactly two 104 // faces, and a deviation ruler comparing it to a reference would report perfect agreement. Only the 105 // traversal direction disagrees, and it renders as an inside-out patch. 106 let ow: *i64 = mg_out() 107 let lw: *i64 = mg_list() 108 let wt: *i64 = mg_tet_tris(0) 109 wt[9]=1; wt[10]=3; wt[11]=2 110 let wd: i64 = mc_check(tv, 4, wt, 4, ow, lw) 111 gv_check("T9 reversing ONE face leaves the mesh closed and manifold but flags its three shared edges" as *u8, 112 mg_eq3(wd, MC_DEFECTS, ow[MC_O_WINDING], 3, ow[MC_O_NONMANIFOLD], 0), ctr) 113 gv_check("T10 a wound-wrong mesh is NOT watertight even though it has zero boundary edges" as *u8, 114 mg_eq2(mc_watertight(ow), 0, ow[MC_O_BOUNDARY], 0), ctr) 115 gv_bite("T11 winding-consistency detection" as *u8, mg_pos(ow[MC_O_WINDING]), mg_pos(o[MC_O_WINDING]), ctr) 116 117 // ---- LOOSE VERTICES ------------------------------------------------------------------------------ 118 let ol: *i64 = mg_out() 119 let ll: *i64 = mg_list() 120 let lv5: *i64 = mg_tet_verts(1) 121 let lt4: *i64 = mg_tet_tris(1) 122 let lo: i64 = mc_check(lv5, 5, lt4, 4, ol, ll) 123 gv_check("T12 a vertex no triangle references is found and NAMED by index, not merely counted" as *u8, 124 mg_eq3(lo, MC_DEFECTS, ol[MC_O_LOOSE], 1, mc_list_get(ll, MC_L_LOOSE, 0), 4), ctr) 125 gv_bite("T13 loose-vertex detection" as *u8, mg_pos(ol[MC_O_LOOSE]), mg_pos(o[MC_O_LOOSE]), ctr) 126 127 // ---- THE TWO DEGENERACIES ARE DIFFERENT DEFECTS -------------------------------------------------- 128 // A triangle naming one vertex twice is BAD DATA. Three distinct vertices that are collinear is 129 // GOOD DATA describing a zero-area shape. Same black nothing on screen, different repair -- so a 130 // single degenerate counter would send half the readers to fix the wrong thing. 131 let od: *i64 = mg_out() 132 let ld: *i64 = mg_list() 133 let dt: *i64 = mg_tet_tris(0) 134 dt[0]=0; dt[1]=0; dt[2]=1 135 let dg: i64 = mc_check(tv, 4, dt, 4, od, ld) 136 gv_check("T14 a triangle naming one vertex twice counts as TOPOLOGICAL degeneracy only" as *u8, 137 mg_eq3(dg, MC_DEFECTS, od[MC_O_DEGEN_TOPO], 1, od[MC_O_DEGEN_AREA], 0), ctr) 138 139 // three DISTINCT but collinear vertices: exact integer cross product, no epsilon anywhere 140 let ca: *i64 = sys_mmap(3 * 3 * MC_I64) as *i64 141 ca[0]=0; ca[1]=0; ca[2]=0 142 ca[3]=MG_U; ca[4]=0; ca[5]=0 143 ca[6]=MG_U+MG_U; ca[7]=0; ca[8]=0 144 let ct: *i64 = sys_mmap(3 * MC_I64) as *i64 145 ct[0]=0; ct[1]=1; ct[2]=2 146 let oa: *i64 = mg_out() 147 let la: *i64 = mg_list() 148 let ar: i64 = mc_check(ca, 3, ct, 1, oa, la) 149 gv_check("T15 three DISTINCT collinear vertices count as AREA degeneracy only -- proven by exact integer cross product, no epsilon" as *u8, 150 mg_eq3(ar, MC_DEFECTS, oa[MC_O_DEGEN_AREA], 1, oa[MC_O_DEGEN_TOPO], 0), ctr) 151 gv_bite("T16 the two degeneracy classes discriminate" as *u8, 152 mg_eq2(od[MC_O_DEGEN_TOPO], 1, oa[MC_O_DEGEN_AREA], 1), 153 mg_pos(o[MC_O_DEGEN_TOPO] + o[MC_O_DEGEN_AREA]), ctr) 154 155 // ---- DUPLICATE FACES ----------------------------------------------------------------------------- 156 let op: *i64 = mg_out() 157 let lp: *i64 = mg_list() 158 let pt: *i64 = mg_tet_tris(1) 159 pt[12]=1; pt[13]=0; pt[14]=2 160 let du: i64 = mc_check(tv, 4, pt, 5, op, lp) 161 gv_check("T17 two triangles over the same three vertices in a different ORDER are still duplicates" as *u8, 162 mg_eq2(op[MC_O_DUPFACE], 1, op[MC_O_DUPCHECKED], 1), ctr) 163 gv_bite("T18 duplicate-face detection" as *u8, mg_pos(op[MC_O_DUPFACE]), mg_pos(o[MC_O_DUPFACE]), ctr) 164 165 // ---- AN OPEN SURFACE IS NOT A BROKEN ONE --------------------------------------------------------- 166 // The deliberate non-defect, and the tooth that stops this organ becoming a false-positive machine. 167 // A plane, a cloth patch and a cut-away anatomical section are all legitimately open. Watertightness 168 // is a SEPARATE question asked separately, so a caller who needs it opts in rather than having a 169 // whole class of valid geometry condemned by default. 170 let pv: *i64 = sys_mmap(4 * 3 * MC_I64) as *i64 171 pv[0]=0; pv[1]=0; pv[2]=0 172 pv[3]=MG_U; pv[4]=0; pv[5]=0 173 pv[6]=MG_U; pv[7]=MG_U; pv[8]=0 174 pv[9]=0; pv[10]=MG_U; pv[11]=0 175 let ptr2: *i64 = sys_mmap(2 * 3 * MC_I64) as *i64 176 ptr2[0]=0; ptr2[1]=1; ptr2[2]=2 177 ptr2[3]=0; ptr2[4]=2; ptr2[5]=3 178 let opl: *i64 = mg_out() 179 let lpl: *i64 = mg_list() 180 let pl: i64 = mc_check(pv, 4, ptr2, 2, opl, lpl) 181 gv_check("neg-control-an-OPEN-square-is-CLEAN-with-four-boundary-edges-because-open-is-not-broken" as *u8, 182 mg_eq3(pl, MC_CLEAN, opl[MC_O_BOUNDARY], 4, mc_defect_total(opl), 0), ctr) 183 gv_check("T20 the same open square is correctly NOT watertight -- the two questions stay separate" as *u8, 184 mg_eq(mc_watertight(opl), 0), ctr) 185 186 // ---- COVERAGE IS ON THE RECORD ------------------------------------------------------------------- 187 // The duplicate-face check is bounded by an i64 cube root and REFUSES above it rather than silently 188 // skipping. That refusal path is NOT exercised here and I am saying so rather than implying it is: 189 // reaching it needs over two million vertices, and manufacturing that to score a tooth would cost 190 // more than the tooth is worth. What IS asserted is that the flag reads 1 on every fixture above, 191 // so a future zero is visible as a refusal rather than passing as a clean result. 192 gv_check("T21 the duplicate-face check REPORTS that it ran on every fixture -- a skip could not pass as a pass" as *u8, 193 mg_eq3(o[MC_O_DUPCHECKED], 1, op[MC_O_DUPCHECKED], 1, opl[MC_O_DUPCHECKED], 1), ctr) 194 gv_check("T22 no worklist above overflowed, so every count published here is a whole set and not a prefix" as *u8, 195 mg_eq3(o[MC_O_LIST_PREFIX], 0, ov[MC_O_LIST_PREFIX], 0, ow[MC_O_LIST_PREFIX], 0), ctr) 196 197 let rc: i64 = gv_verdict("MESHCHECK-GATE" as *u8, ctr, 198 "every defect class fires on its own planted mutant and stays silent on the clean control, the two degeneracies discriminate, an open surface is correctly not a defect, and the empty mesh abstains rather than passing" as *u8) 199 gv_journal("nx_meshcheck_gate" as *u8, ctr[0], ctr[1], mg_zero(rc)) 200 sys_exit(rc) 201 return rc 202}