code wiki / (root) / nx_meshgap.nx

nx_meshgap.nx source

↩ module page · 193 lines · 8068 B

1// nx_meshgap.nx -- SPATIAL COHERENCE OF A MESH: does the figure hold together, or have parts 2// flown off into empty space? 3// 4// WHY THIS EXISTS (measured 2026-08-23, by eye on a live page). The models page card FEMALE DARK 5// KNIGHT renders as FRAGMENTED GEOMETRY -- the hair/helmet floats detached far above the body and 6// stray blobs hang below it -- while EVERY NUMBER ON ITS CARD IS GREEN: 33 geometry nodes merged, 7// rig 113 joints, 3729 clusters = 33 x 113, albedo carried, 6-chart atlas. The arithmetic closes 8// perfectly and the picture is broken. That is the third time in one day the eye beat the teeth 9// (a donor rendering lying flat; a 30-pixel dark blob at the horizon; now this), and the reason is 10// always the same: every existing tooth measured a COUNT or a SUM, and no tooth measured whether 11// the thing HOLDS TOGETHER IN SPACE. 12// 13// WHY MESH SPACE AND NOT PIXELS. The obvious instrument is connected-component analysis on the 14// render. It cannot be built cheaply here -- the estate has PNG WRITERS but no decoder with an 15// unfilter stage -- and it would be the weaker measurement anyway: a pixel silhouette depends on 16// the camera, the renderer tier and the auto-framing, so a coherent mesh photographed badly and a 17// fragmented mesh photographed well are indistinguishable. The mesh is the SUBJECT; the render is 18// a projection of it. Measuring the subject is exact, load-independent, camera-independent, and 19// catches the defect AT INGEST rather than after it reaches a page. 20// 21// THE MEASURE IS PARAMETER-FREE, WHICH IS THE WHOLE POINT ON A DAY WHEN AN ESTATE CENSUS MEASURED 22// ONLY 2.56 PERCENT OF CAPACITY BOUNDS AS DERIVED. A coherent figure is spatially CONTIGUOUS: walk 23// along any axis and you never cross a large empty void before reaching the far side. A fragmented 24// figure has a VOID between the body and whatever flew off. So the measurement is the LARGEST 25// INTERIOR EMPTY GAP along each axis, expressed in permil of that axis's own span -- a ratio of the 26// mesh to itself, with no constant to pick and no units to get wrong. 27// 28// The bin width is DERIVED FROM THE DATA, not chosen: one bin per vertex (binwidth = span/nv, at 29// least 1 unit), so resolution follows the mesh's own density. A void spanning thousands of bins 30// cannot be confused with the one- or two-bin holes that ordinary sampling produces. 31// 32// ALL THREE AXES ARE REPORTED AND THE VERDICT TAKES THE WORST. Deliberately NOT stature-only: this 33// organ must not inherit the axis-identification problem that has bitten three lanes today, and a 34// part can fly off along any axis. Largest-extent-is-stature is ALSO wrong for these donors -- a 35// T-posed rig's arm span can exceed its height -- so no axis is privileged here at all. 36// 37// THE BOUND IS NOT BAKED IN. With no second argument this organ MEASURES ONLY and exits 0. The 38// caller supplies the bound, so it can be derived from a measured population (coherent donors vs 39// fragmented ones) and live in a conf with its derivation beside it, rather than being frozen into 40// a binary where nobody can see it. 41// 42// usage: nx_meshgap <asset.nxa> [max_gap_permil] 43// exit: 0 COHERENT or measure-only . 1 FRAGMENTED . 2 usage . 3 unreadable 44 45import "nx_syscalls.nx" 46import "nx_nxa.nx" 47 48const MG_EXIT_FRAG: i64 = 1 49const MG_EXIT_USAGE: i64 = 2 50const MG_EXIT_UNREADABLE: i64 = 3 51const MG_PERMIL: i64 = 1000 52const MG_AXES: i64 = 3 53const MG_WV: i64 = 3 // words per vertex in a VERT section (x,y,z), per the NXA v1 spec 54 55func mgw(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } 56func mgerr(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(2, s, n); return 0 } 57 58func mgn(v: i64) -> i64 { 59 let b: *u8 = sys_mmap(64) as *u8 60 var x: i64 = v 61 var neg: i64 = 0 62 if x < 0 { neg = 1; x = 0 - x } 63 var i: i64 = 40 64 b[i] = 0 as u8 65 if x == 0 { i = i - 1; b[i] = 48 as u8 } 66 while x > 0 { 67 i = i - 1 68 b[i] = ((x % 10) + 48) as u8 69 x = x / 10 70 } 71 if neg == 1 { i = i - 1; b[i] = 45 as u8 } 72 var n: i64 = 0 73 while b[i+n] != (0 as u8) { n = n + 1 } 74 sys_write(1, ((b as i64) + i) as *u8, n) 75 return 0 76} 77 78func mg_atoi(s: *u8) -> i64 { 79 var v: i64 = 0 80 var i: i64 = 0 81 while s[i] != (0 as u8) { 82 let c: i64 = s[i] as i64 83 if c >= 48 { if c <= 57 { v = v * 10 + (c - 48) } } 84 i = i + 1 85 } 86 return v 87} 88 89// Largest INTERIOR empty gap along one axis, in permil of that axis's span. 90// Interior only: leading and trailing empty bins are not gaps, they are the ends of the object. 91func mg_axis_gap(vb: *i64, nv: i64, k: i64, out: *i64) -> i64 { 92 var mn: i64 = vb[k] 93 var mx: i64 = mn 94 var i: i64 = 1 95 while i < nv { 96 let v: i64 = vb[i*MG_WV+k] 97 if v < mn { mn = v } 98 if v > mx { mx = v } 99 i = i + 1 100 } 101 let span: i64 = mx - mn 102 out[0] = span 103 out[1] = 0 104 out[2] = 0 105 if span < 1 { return 0 } 106 // one bin per vertex: resolution follows the mesh's own density, nothing is picked 107 var bw: i64 = span / nv 108 if bw < 1 { bw = 1 } 109 let nb: i64 = span / bw + 1 110 let bins: *u8 = sys_mmap(nb) as *u8 111 i = 0 112 while i < nv { 113 var idx: i64 = (vb[i*MG_WV+k] - mn) / bw 114 if idx < 0 { idx = 0 } 115 if idx >= nb { idx = nb - 1 } 116 bins[idx] = 1 as u8 117 i = i + 1 118 } 119 var occ: i64 = 0 120 var run: i64 = 0 121 var best: i64 = 0 122 var seen: i64 = 0 123 i = 0 124 while i < nb { 125 if bins[i] == (1 as u8) { 126 occ = occ + 1 127 seen = 1 128 if run > best { best = run } 129 run = 0 130 } 131 if bins[i] == (0 as u8) { if seen == 1 { run = run + 1 } } 132 i = i + 1 133 } 134 // a trailing run is beyond the last vertex -- an end, not a gap -- so it is deliberately dropped 135 out[1] = best * bw 136 out[2] = occ 137 return best * bw * MG_PERMIL / span 138} 139 140func main(argc: i64, argv: *i64) -> i64 { 141 if argc < 2 { 142 mgerr("usage: nx_meshgap <asset.nxa> [max_gap_permil]\n" as *u8) 143 return MG_EXIT_USAGE 144 } 145 let path: *u8 = argv[1] as *u8 146 var bound: i64 = 0 - 1 147 if argc >= 3 { bound = mg_atoi(argv[2] as *u8) } 148 149 let lp: *i64 = sys_mmap(64) 150 let b: *u8 = sys_read_file(path, lp) 151 if b as i64 == 0 { mgerr("MESHGAP-REFUSE cannot read asset\n" as *u8); return MG_EXIT_UNREADABLE } 152 let flen: i64 = lp[0] 153 let w: *i64 = b as *i64 154 let vwo: i64 = nxa_find(b, flen, nxa_tag4("VERT" as *u8)) 155 if vwo < 0 { mgerr("MESHGAP-REFUSE no VERT section\n" as *u8); return MG_EXIT_UNREADABLE } 156 let nv: i64 = w[vwo] 157 if nv < 2 { mgerr("MESHGAP-REFUSE VERT holds fewer than two vertices\n" as *u8); return MG_EXIT_UNREADABLE } 158 let vb: *i64 = ((w as i64) + (vwo + 1) * 8) as *i64 159 160 mgw("NX-MESHGAP " as *u8); mgw(path); mgw("\n" as *u8) 161 mgw(" verts=" as *u8); mgn(nv); mgw("\n" as *u8) 162 163 let out: *i64 = sys_mmap(64) 164 var worst: i64 = 0 165 var worst_ax: i64 = 0 166 var k: i64 = 0 167 while k < MG_AXES { 168 let g: i64 = mg_axis_gap(vb, nv, k, out) 169 mgw(" axis=" as *u8); mgn(k) 170 mgw(" span=" as *u8); mgn(out[0]) 171 mgw(" occupied_bins=" as *u8); mgn(out[2]) 172 mgw(" largest_interior_gap=" as *u8); mgn(out[1]) 173 mgw(" gap_permil=" as *u8); mgn(g) 174 mgw("\n" as *u8) 175 if g > worst { worst = g; worst_ax = k } 176 k = k + 1 177 } 178 mgw(" max_gap_permil=" as *u8); mgn(worst) 179 mgw(" on_axis=" as *u8); mgn(worst_ax) 180 mgw("\n" as *u8) 181 182 if bound < 0 { 183 mgw("NX-MESHGAP verdict=MEASURED (no bound supplied -- the caller owns the bound so it can be derived from a population and kept where it is visible)\n" as *u8) 184 return 0 185 } 186 mgw(" bound_max_gap_permil=" as *u8); mgn(bound); mgw("\n" as *u8) 187 if worst > bound { 188 mgw("NX-MESHGAP verdict=FRAGMENTED (a part of this mesh sits across an empty void from the rest)\n" as *u8) 189 return MG_EXIT_FRAG 190 } 191 mgw("NX-MESHGAP verdict=COHERENT\n" as *u8) 192 return 0 193}