code wiki / _hdl_build / nx_bodyparts.nx

nx_bodyparts.nx source

↩ module page · 405 lines · 17128 B

1// nx_bodyparts.nx -- L0 TAXON + STRUCTURE CENSUS of the SEMANTIC TWIN LADDER (debt 1785954089; 2// operator 2026-08-05: "it is a human, female, has a head, then eyes... a clay blob is not the same 3// object as a girl"). Metric distance alone ranked an ARMLESS body first (nx_bodybench 278 vs 232) -- 4// because no instrument could say WHAT the thing is. This organ answers the first question: 5// IS IT A HUMANOID, AND WHICH PARTS EXIST? 6// 7// METHOD (structural, no rig required so it works on ANY mesh soup): slice the mesh into y-bands; in 8// each band build an x-histogram and count CLUSTERS (occupied runs separated by >=BP_GAP empty bins). 9// A standing humanoid has a signature no blob can fake: 3 clusters where the arms are clear of the 10// torso, 2 clusters where the legs separate, and a NECK (a width minimum) below a head mass. A pawn 11// silhouette is 1 cluster everywhere and is REFUSED as a humanoid -- semantically, not by score. 12// Bone-weight-driven NAMED segmentation (L2, VRM's 51 humanoid bones = free parts for rigged donors) 13// is the next rung and rides the same output rows. 14// 15// nx_bodyparts <mesh.nxmesh> [bands] | selftest 16// Emits JSON: per-region cluster maxima, neck/head findings, part census, VERDICT=HUMANOID|NOT-HUMANOID 17// with the MISSING part named. license_tier: ORIGINAL expect_exit: 0 18import "nx_syscalls.nx" 19const BP_MAGIC_65536: i64 = 65536 20const BP_MAGIC_1600: i64 = 1600 21const BP_MAGIC_262144: i64 = 262144 22const BP_MAGIC_1350: i64 = 1350 23const BP_MAGIC_1300: i64 = 1300 24const BP_MAGIC_1430: i64 = 1430 25 26const BP_CAP: i64 = 33554432 27const BP_MAXTRI: i64 = 400000 28const BP_MAXBAND: i64 = 256 29const BP_XBINS: i64 = 128 30const BP_GAP: i64 = 2 31const BP_M8388607: i64 = 8388607 32const BP_M8388608: i64 = 8388608 33const BP_BIG: i64 = 4611686018427387903 34// region limits as per-mille of stature -- ANATOMY, not tuning (mirrors nx_profile_fit's banded canon) 35const BP_ARM_LO: i64 = 550 36const BP_ARM_HI: i64 = 800 37const BP_LEG_LO: i64 = 80 38const BP_LEG_HI: i64 = 420 39const BP_NECK_LO: i64 = 800 40const BP_NECK_HI: i64 = 920 41// a neck is a width MINIMUM: narrower than this fraction (per-mille) of the shoulder width 42const BP_NECK_FRAC: i64 = 600 43// a head must carry at least this per-mille of the neck's own width above the neck 44const BP_HEAD_FRAC: i64 = 900 45 46func hw(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } 47func pn(v: i64) -> i64 { let b: *u8=sys_mmap(32) as *u8; var x: i64=v; var ng: i64=0; if x<0{ng=1;x=0-x} var i: i64=31; if x==0{b[i]=48 as u8;i=i-1} while x>0{b[i]=(48+x%10) as u8;x=x/10;i=i-1} if ng==1{b[i]=45 as u8;i=i-1} sys_write(1,(b as i64+i+1) as *u8,31-i); return 0 } 48func bp_u32(b: *u8, o: i64) -> i64 { return (b[o] as i64) + ((b[o+1] as i64)<<8) + ((b[o+2] as i64)<<16) + ((b[o+3] as i64)<<24) } 49// IEEE754 f32 millimetres -> integer 10um quanta 50func bp_f32q(w: i64) -> i64 { 51 let sign: i64 = (w >> 31) & 1 52 let expo: i64 = (w >> 23) & 255 53 if expo == 0 { return 0 } 54 var mant: i64 = (w & BP_M8388607) | BP_M8388608 55 let sh: i64 = expo - 127 56 var v: i64 = 0 57 if sh >= 23 { if sh - 23 > 30 { return 0 } } 58 if sh >= 23 { v = mant * 100 * (1 << (sh - 23)) } 59 if sh < 23 { if 23 - sh > 62 { return 0 } } 60 if sh < 23 { v = (mant * 100) >> (23 - sh) } 61 if sign == 1 { return 0 - v } 62 return v 63} 64func bp_refuse(reason: *u8) -> i64 { hw("BODYPARTS REFUSED: " as *u8); hw(reason); hw("\n" as *u8); return 0 } 65 66// load NXMSH2 -> vx (9 per tri). returns ntris or -1 67func bp_load(path: *u8, vx: *i64) -> i64 { 68 let fd: i64 = sys_openat_rd(path) 69 if fd < 0 { return 0 - 1 } 70 let b: *u8 = sys_mmap(BP_CAP + 64) 71 var n: i64 = 0 72 var go: i64 = 1 73 while go == 1 { 74 let r: i64 = sys_read(fd, ((b as i64) + n) as *u8, BP_CAP - n) 75 if r <= 0 { go = 0 } else { n = n + r } 76 if n >= BP_CAP { go = 0 } 77 } 78 sys_close(fd) 79 if n < 44 { return 0 - 1 } 80 if b[0] != (78 as u8) { return 0 - 1 } 81 if b[5] != (50 as u8) { return 0 - 1 } 82 let nlay: i64 = bp_u32(b, 8) 83 let nt: i64 = bp_u32(b, 12) 84 if nt <= 0 { return 0 - 1 } 85 if nt > BP_MAXTRI { return 0 - 1 } 86 let hdr: i64 = 16 + nlay*24 87 if hdr + nt*84 > n { return 0 - 1 } 88 var t: i64 = 0 89 while t < nt { 90 var c: i64 = 0 91 while c < 9 { vx[t*9+c] = bp_f32q(bp_u32(b, hdr + t*84 + c*4)); c = c + 1 } 92 t = t + 1 93 } 94 return nt 95} 96 97// count occupied runs (clusters) in an occupancy row of BP_XBINS, runs split by >=BP_GAP empty bins 98func bp_clusters(occ: *i64) -> i64 { 99 var runs: i64 = 0 100 var inrun: i64 = 0 101 var empty: i64 = 0 102 var i: i64 = 0 103 while i < BP_XBINS { 104 if occ[i] > 0 { 105 if inrun == 0 { runs = runs + 1; inrun = 1 } 106 empty = 0 107 } else { 108 empty = empty + 1 109 if empty >= BP_GAP { inrun = 0 } 110 } 111 i = i + 1 112 } 113 return runs 114} 115// width of the occupied span in bins 116func bp_width(occ: *i64) -> i64 { 117 var lo: i64 = 0 - 1 118 var hi: i64 = 0 - 1 119 var i: i64 = 0 120 while i < BP_XBINS { 121 if occ[i] > 0 { if lo < 0 { lo = i } hi = i } 122 i = i + 1 123 } 124 if lo < 0 { return 0 } 125 return hi - lo + 1 126} 127 128func bp_run(path: *u8, nband: i64) -> i64 { 129 let vx: *i64 = sys_mmap(BP_MAXTRI*9*8 + 64) as *i64 130 let nt: i64 = bp_load(path, vx) 131 if nt < 0 { bp_refuse("mesh unreadable or not NXMSH2" as *u8); return 3 } 132 var mny: i64 = BP_BIG 133 var mxy: i64 = 0-BP_BIG 134 var mnx: i64 = BP_BIG 135 var mxx: i64 = 0-BP_BIG 136 var t: i64 = 0 137 while t < nt { 138 var c: i64 = 0 139 while c < 3 { 140 let x: i64 = vx[t*9+c*3] 141 let y: i64 = vx[t*9+c*3+1] 142 if y < mny { mny = y } 143 if y > mxy { mxy = y } 144 if x < mnx { mnx = x } 145 if x > mxx { mxx = x } 146 c = c + 1 147 } 148 t = t + 1 149 } 150 var hgt: i64 = mxy - mny 151 if hgt < 1 { bp_refuse("degenerate height" as *u8); return 4 } 152 var wid: i64 = mxx - mnx 153 if wid < 1 { wid = 1 } 154 // occupancy grid: nband rows x BP_XBINS 155 let grid: *i64 = sys_mmap(BP_MAXBAND*BP_XBINS*8 + 64) as *i64 156 var g: i64 = 0 157 while g < nband*BP_XBINS { grid[g] = 0; g = g + 1 } 158 // ★SPAN RASTERISATION, NOT VERTEX BINNING (caught by the box fixture 2026-08-05: a 12-tri box has 159 // vertices only at its corners, so mid-height bands read EMPTY and the refusal was vacuous -- it 160 // refused an absence, not a shape). Marking each triangle's AABB cells makes a coarse box occupy 161 // every band it spans, so the census measures STRUCTURE at any tessellation density. 162 t = 0 163 while t < nt { 164 var tlo: i64 = vx[t*9+1] 165 var thi: i64 = tlo 166 var xlo: i64 = vx[t*9] 167 var xhi: i64 = xlo 168 var c: i64 = 1 169 while c < 3 { 170 let yy: i64 = vx[t*9+c*3+1] 171 let xx: i64 = vx[t*9+c*3] 172 if yy < tlo { tlo = yy } 173 if yy > thi { thi = yy } 174 if xx < xlo { xlo = xx } 175 if xx > xhi { xhi = xx } 176 c = c + 1 177 } 178 var b0: i64 = (tlo - mny)*nband/hgt 179 var b1: i64 = (thi - mny)*nband/hgt 180 if b0 < 0 { b0 = 0 } 181 if b1 >= nband { b1 = nband-1 } 182 var i0: i64 = (xlo - mnx)*BP_XBINS/wid 183 var i1: i64 = (xhi - mnx)*BP_XBINS/wid 184 if i0 < 0 { i0 = 0 } 185 if i1 >= BP_XBINS { i1 = BP_XBINS-1 } 186 var bb: i64 = b0 187 while bb <= b1 { 188 var ii: i64 = i0 189 while ii <= i1 { 190 grid[bb*BP_XBINS + ii] = grid[bb*BP_XBINS + ii] + 1 191 ii = ii + 1 192 } 193 bb = bb + 1 194 } 195 t = t + 1 196 } 197 // per-band clusters + widths; region maxima 198 let cl: *i64 = sys_mmap(BP_MAXBAND*8) as *i64 199 let wd: *i64 = sys_mmap(BP_MAXBAND*8) as *i64 200 var arm_max: i64 = 0 201 var arm_band: i64 = 0 - 1 202 var leg_max: i64 = 0 203 var leg_band: i64 = 0 - 1 204 var sh_w: i64 = 0 205 var b2: i64 = 0 206 while b2 < nband { 207 cl[b2] = bp_clusters(((grid as i64) + b2*BP_XBINS*8) as *i64) 208 wd[b2] = bp_width(((grid as i64) + b2*BP_XBINS*8) as *i64) 209 let permil: i64 = b2*1000/nband 210 if permil >= BP_ARM_LO { if permil <= BP_ARM_HI { 211 if cl[b2] > arm_max { arm_max = cl[b2]; arm_band = b2 } 212 if wd[b2] > sh_w { sh_w = wd[b2] } 213 } } 214 if permil >= BP_LEG_LO { if permil <= BP_LEG_HI { 215 if cl[b2] > leg_max { leg_max = cl[b2]; leg_band = b2 } 216 } } 217 b2 = b2 + 1 218 } 219 // neck: the narrowest band in the neck window; head: mass above it at >= BP_HEAD_FRAC of neck width 220 var neck_w: i64 = BP_BIG 221 var neck_band: i64 = 0 - 1 222 b2 = 0 223 while b2 < nband { 224 let permil2: i64 = b2*1000/nband 225 if permil2 >= BP_NECK_LO { if permil2 <= BP_NECK_HI { 226 if wd[b2] > 0 { if wd[b2] < neck_w { neck_w = wd[b2]; neck_band = b2 } } 227 } } 228 b2 = b2 + 1 229 } 230 var head_w: i64 = 0 231 if neck_band >= 0 { 232 b2 = neck_band + 1 233 while b2 < nband { if wd[b2] > head_w { head_w = wd[b2] } b2 = b2 + 1 } 234 } 235 var arms: i64 = 0 236 if arm_max >= 3 { arms = 2 } 237 if arm_max == 2 { arms = 1 } 238 var legs: i64 = 0 239 if leg_max >= 2 { legs = 2 } 240 if leg_max == 1 { legs = 1 } 241 var neck_ok: i64 = 0 242 if neck_band >= 0 { if sh_w > 0 { if neck_w*1000 <= sh_w*BP_NECK_FRAC { neck_ok = 1 } } } 243 var head_ok: i64 = 0 244 if neck_ok == 1 { if head_w*1000 >= neck_w*BP_HEAD_FRAC { head_ok = 1 } } 245 hw("{\x22organ\x22:\x22nx_bodyparts\x22,\x22level\x22:\x22L0-taxon\x22,\x22tris\x22:" as *u8); pn(nt) 246 hw(",\x22bands\x22:" as *u8); pn(nband) 247 hw(",\x22height_mm\x22:" as *u8); pn(hgt/100) 248 hw(",\x22arm_clusters_max\x22:" as *u8); pn(arm_max) 249 hw(",\x22arm_band_permil\x22:" as *u8); pn(arm_band*1000/nband) 250 hw(",\x22leg_clusters_max\x22:" as *u8); pn(leg_max) 251 hw(",\x22shoulder_w_bins\x22:" as *u8); pn(sh_w) 252 hw(",\x22neck_w_bins\x22:" as *u8); pn(neck_w) 253 hw(",\x22head_w_bins\x22:" as *u8); pn(head_w) 254 hw(",\x22census\x22:{\x22arms\x22:" as *u8); pn(arms) 255 hw(",\x22legs\x22:" as *u8); pn(legs) 256 hw(",\x22neck\x22:" as *u8); pn(neck_ok) 257 hw(",\x22head\x22:" as *u8); pn(head_ok) 258 hw("}" as *u8) 259 var missing: i64 = 0 260 if arms < 2 { missing = missing + 1 } 261 if legs < 2 { missing = missing + 1 } 262 if head_ok == 0 { missing = missing + 1 } 263 hw(",\x22missing_parts\x22:" as *u8); pn(missing) 264 if missing == 0 { hw(",\x22verdict\x22:\x22HUMANOID\x22" as *u8) } else { hw(",\x22verdict\x22:\x22NOT-HUMANOID\x22,\x22missing\x22:\x22" as *u8) 265 if arms < 2 { hw("arms " as *u8) } 266 if legs < 2 { hw("legs " as *u8) } 267 if head_ok == 0 { hw("head " as *u8) } 268 hw("\x22" as *u8) } 269 hw(",\x22note\x22:\x22structural band-cluster census; L2 named parts via skinning weights = next rung\x22}\n" as *u8) 270 if missing == 0 { return 0 } 271 return 1 272} 273 274// ---- fixtures: axis-aligned boxes written as 12 tris (literal-arg style, nx_cc slot bug 1785936860) ---- 275func bp_encf(v: i64, scale: i64) -> i64 { 276 if v == 0 { return 0 } 277 var neg: i64 = 0 278 var m: i64 = v 279 if m < 0 { neg = 1; m = 0-m } 280 var e: i64 = 0 281 var num: i64 = m 282 var den: i64 = scale 283 while num >= den*2 { den = den*2; e = e+1 } 284 while num < den { num = num*2; e = e-1 } 285 let frac: i64 = ((num - den)*BP_M8388608)/den 286 var bits: i64 = ((e+127) << 23) | (frac & BP_M8388607) 287 if neg == 1 { bits = bits | (1<<31) } 288 return bits 289} 290func bp_w32(b: *u8, o: i64, v: i64) -> i64 { 291 b[o]=(v&255) as u8; b[o+1]=((v>>8)&255) as u8; b[o+2]=((v>>16)&255) as u8; b[o+3]=((v>>24)&255) as u8 292 return 0 293} 294// write one triangle record (84B geometry+colour) at off; coords are mm 295func bp_tri(b: *u8, off: i64, x0: i64, y0: i64, z0: i64, x1: i64, y1: i64, z1: i64, x2: i64, y2: i64, z2: i64) -> i64 { 296 bp_w32(b, off, bp_encf(x0,1)); bp_w32(b, off+4, bp_encf(y0,1)); bp_w32(b, off+8, bp_encf(z0,1)) 297 bp_w32(b, off+12, bp_encf(x1,1)); bp_w32(b, off+16, bp_encf(y1,1)); bp_w32(b, off+20, bp_encf(z1,1)) 298 bp_w32(b, off+24, bp_encf(x2,1)); bp_w32(b, off+28, bp_encf(y2,1)); bp_w32(b, off+32, bp_encf(z2,1)) 299 var q: i64 = 36 300 while q < 84 { b[off+q] = 0 as u8; q = q + 1 } 301 return 0 302} 303// append a box (2 tris per face, 12 tris) -> returns tris written 304func bp_box(b: *u8, off: i64, xlo: i64, xhi: i64, ylo: i64, yhi: i64, zlo: i64, zhi: i64) -> i64 { 305 var o: i64 = off 306 bp_tri(b, o, xlo,ylo,zlo, xhi,ylo,zlo, xhi,yhi,zlo); o = o + 84 307 bp_tri(b, o, xlo,ylo,zlo, xhi,yhi,zlo, xlo,yhi,zlo); o = o + 84 308 bp_tri(b, o, xlo,ylo,zhi, xhi,ylo,zhi, xhi,yhi,zhi); o = o + 84 309 bp_tri(b, o, xlo,ylo,zhi, xhi,yhi,zhi, xlo,yhi,zhi); o = o + 84 310 bp_tri(b, o, xlo,ylo,zlo, xlo,yhi,zlo, xlo,yhi,zhi); o = o + 84 311 bp_tri(b, o, xlo,ylo,zlo, xlo,yhi,zhi, xlo,ylo,zhi); o = o + 84 312 bp_tri(b, o, xhi,ylo,zlo, xhi,yhi,zlo, xhi,yhi,zhi); o = o + 84 313 bp_tri(b, o, xhi,ylo,zlo, xhi,yhi,zhi, xhi,ylo,zhi); o = o + 84 314 bp_tri(b, o, xlo,ylo,zlo, xhi,ylo,zlo, xhi,ylo,zhi); o = o + 84 315 bp_tri(b, o, xlo,ylo,zlo, xhi,ylo,zhi, xlo,ylo,zhi); o = o + 84 316 bp_tri(b, o, xlo,yhi,zlo, xhi,yhi,zlo, xhi,yhi,zhi); o = o + 84 317 bp_tri(b, o, xlo,yhi,zhi, xhi,yhi,zlo, xlo,yhi,zhi); o = o + 84 318 return 12 319} 320func bp_hdr(b: *u8, ntri: i64) -> i64 { 321 b[0]=78 as u8; b[1]=88 as u8; b[2]=77 as u8; b[3]=83 as u8 322 b[4]=72 as u8; b[5]=50 as u8; b[6]=0 as u8; b[7]=0 as u8 323 bp_w32(b, 8, 1); bp_w32(b, 12, ntri) 324 var q: i64 = 0 325 while q < 16 { b[16+q] = 0 as u8; q = q + 1 } 326 b[16]=115 as u8; b[17]=107 as u8; b[18]=105 as u8; b[19]=110 as u8 327 bp_w32(b, 32, 0); bp_w32(b, 36, ntri) 328 return 40 329} 330func bp_save(path: *u8, b: *u8, ntri: i64) -> i64 { 331 var z: i64 = 0 332 while z < ntri { bp_w32(b, 40 + ntri*84 + z*4, 0); z = z + 1 } 333 let fd: i64 = sys_openat_wr(path, 420) 334 if fd < 0 { return 0 - 1 } 335 sys_write(fd, b, 40 + ntri*84 + ntri*4) 336 sys_close(fd) 337 return 0 338} 339// a PAWN: one tall box (1 cluster everywhere) -- must be REFUSED 340func bp_fix_pawn(path: *u8) -> i64 { 341 let b: *u8 = sys_mmap(BP_MAGIC_65536) 342 bp_hdr(b, 12) 343 bp_box(b, 40, 0-150, 150, 0, BP_MAGIC_1600, 0-100, 100) 344 return bp_save(path, b, 12) 345} 346// a HUMANOID: torso + 2 arms clear of it + 2 legs + a narrow neck + a wide head 347func bp_fix_human(path: *u8) -> i64 { 348 let b: *u8 = sys_mmap(BP_MAGIC_262144) 349 var o: i64 = 40 350 var n: i64 = 0 351 n = n + bp_box(b, o, 0-150, 150, 700, BP_MAGIC_1350, 0-100, 100); o = o + 12*84 // torso 352 n = n + bp_box(b, o, 0-450, 0-250, 1000, BP_MAGIC_1300, 0-60, 60); o = o + 12*84 // L arm (gap 100mm) 353 n = n + bp_box(b, o, 250, 450, 1000, BP_MAGIC_1300, 0-60, 60); o = o + 12*84 // R arm 354 n = n + bp_box(b, o, 0-140, 0-40, 60, 700, 0-80, 80); o = o + 12*84 // L leg (gap 80mm) 355 n = n + bp_box(b, o, 40, 140, 60, 700, 0-80, 80); o = o + 12*84 // R leg 356 n = n + bp_box(b, o, 0-60, 60, BP_MAGIC_1350, BP_MAGIC_1430, 0-60, 60); o = o + 12*84 // neck (narrow) 357 n = n + bp_box(b, o, 0-110, 110, BP_MAGIC_1430, BP_MAGIC_1600, 0-110, 110); o = o + 12*84 // head (wider than neck) 358 bp_hdr(b, n) 359 return bp_save(path, b, n) 360} 361func bp_selftest() -> i64 { 362 var fails: i64 = 0 363 bp_fix_pawn("/tmp/bp_pawn.nxmesh" as *u8) 364 bp_fix_human("/tmp/bp_human.nxmesh" as *u8) 365 hw("T0 pawn fixture (one box) must be NOT-HUMANOID:\n" as *u8) 366 if bp_run("/tmp/bp_pawn.nxmesh" as *u8, 64) == 0 { fails = fails + 1; hw("T0 FAIL a box passed as humanoid\n" as *u8) } else { hw("T0 PASS box refused\n" as *u8) } 367 hw("T1 humanoid fixture (torso+2 arms+2 legs+neck+head) must be HUMANOID:\n" as *u8) 368 if bp_run("/tmp/bp_human.nxmesh" as *u8, 64) != 0 { fails = fails + 1; hw("T1 FAIL humanoid rejected\n" as *u8) } else { hw("T1 PASS humanoid recognised\n" as *u8) } 369 if bp_run("/tmp/bp_absent_zz.nxmesh" as *u8, 64) == 0 { fails = fails + 1; hw("T2 FAIL absent accepted\n" as *u8) } else { hw("T2 PASS absent refused\n" as *u8) } 370 if fails == 0 { hw("BODYPARTS-SELFTEST GREEN 3/3\n" as *u8); return 0 } 371 hw("BODYPARTS-SELFTEST RED fails=" as *u8); pn(fails); hw("\n" as *u8) 372 return 1 373} 374 375func main(argc: i64, argv: *i64) -> i64 { 376 if argc >= 2 { 377 let a1: *u8 = argv[1] as *u8 378 var m: i64 = 0 379 while a1[m] != (0 as u8) { m = m + 1 } 380 if m == 8 { 381 var ok: i64 = 1 382 let lit: *u8 = "selftest" as *u8 383 var i: i64 = 0 384 while i < 8 { if a1[i] != lit[i] { ok = 0; i = 8 } else { i = i + 1 } } 385 if ok == 1 { let rc: i64 = bp_selftest(); sys_exit(rc); return rc } 386 } 387 } 388 if argc < 2 { 389 hw("usage: nx_bodyparts <mesh.nxmesh> [bands] | selftest\n" as *u8) 390 sys_exit(2) 391 return 2 392 } 393 var nb: i64 = 64 394 if argc >= 3 { 395 let a2: *u8 = argv[2] as *u8 396 nb = 0 397 var q: i64 = 0 398 while a2[q] != (0 as u8) { nb = nb*10 + ((a2[q] as i64) - 48); q = q + 1 } 399 if nb < 16 { nb = 16 } 400 if nb > BP_MAXBAND { nb = BP_MAXBAND } 401 } 402 let rc2: i64 = bp_run(argv[1] as *u8, nb) 403 sys_exit(rc2) 404 return rc2 405}