code wiki / (root) / nx_boneheat_gate.nx

nx_boneheat_gate.nx source

↩ module page · 329 lines · 17639 B

1// nx_boneheat_gate.nx -- THE REFEREE FOR THE SOVEREIGN AUTO-WEIGHTS: a geodesic solve must BLEND at a joint, must NOT 2// bleed across air, must announce an unsealed mesh instead of refusing it, must refuse a mesh with no skeleton BY 3// NAME, and must be byte-deterministic -- while the nearest-joint control (modding MD4's own accept-rule control) 4// is shown to do exactly what the geodesic solve exists to stop. 5// Fixtures are BUILT AT RUN TIME under /tmp/nx_boneheat_gate (a detector that scans source must never meet its own 6// fixture) and are AXIS-ALIGNED SQUARE PRISMS on purpose: their four walls and two caps lie on coordinate planes, 7// so the voxeliser seals them without depending on the tilted-face dilation (that dilation stays in the lib for 8// real meshes; the fixture must isolate the WEIGHT solve, not the seam heuristic). A closed prism with a 9// three-joint chain; the same prism open at both ends; two prisms separated by 12 mm of air where one shell's 10// joint is Euclidean-nearer to the other shell's vertices than that shell's own joint. Every solve is IN-PROCESS 11// through nx_boneheat_lib, so a mutant of the lib is reached. 12// license_tier: ORIGINAL expect_exit: 0 13import "nx_syscalls.nx" 14import "nx_gate_verdict.nx" 15import "nx_nxa.nx" 16import "nx_boneheat_lib.nx" 17 18const BHG_DIR: *u8 = "/tmp/nx_boneheat_gate" 19const BHG_MODE_DIR: i64 = 493 // 0755 20const BHG_AROUND: i64 = 4 // square cross-section: 4 axis-aligned corners -> 4 axis-aligned faces 21const BHG_R: i64 = 400 // 4 mm half-width in 0.01 mm units 22const BHG_LEN: i64 = 4000 // 40 mm prism 23const BHG_RINGS: i64 = 41 // one ring per mm 24const BHG_MID: i64 = 2000 25const BHG_SHELL_LEN: i64 = 2000 26const BHG_SHELL_RINGS: i64 = 21 27const BHG_SHELL_DX: i64 = 2000 // second shell centre: 12 mm of air between the surfaces 28const BHG_CELLS: i64 = 64 // fixture grid, passed explicitly so the gate never depends on the conf file 29const BHG_VERT_CAP: i64 = 1024 30const BHG_TRI_CAP: i64 = 4096 31const BHG_JOINT_CAP: i64 = 8 32const BHG_RING_ROOT: i64 = 5 // z = 5 mm 33const BHG_RING_MID: i64 = 20 // z = 20 mm, the middle joint 34const BHG_RING_FAR: i64 = 35 // z = 35 mm 35const BHG_ROOT: i64 = 0 - 1 36 37func hw(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } 38// the four axis-aligned corners of the square cross-section, going around 39func bhg_ring_xy(k: i64, out: *i64) -> i64 { 40 if k == 0 { out[0] = BHG_R; out[1] = 0 - BHG_R } 41 if k == 1 { out[0] = BHG_R; out[1] = BHG_R } 42 if k == 2 { out[0] = 0 - BHG_R; out[1] = BHG_R } 43 if k == 3 { out[0] = 0 - BHG_R; out[1] = 0 - BHG_R } 44 return 0 45} 46func bhg_tri(tris: *i64, st: *i64, a: i64, b: i64, c: i64) -> i64 { 47 let t: i64 = st[1] 48 tris[1 + t * 3] = a; tris[1 + t * 3 + 1] = b; tris[1 + t * 3 + 2] = c 49 st[1] = t + 1 50 return 0 51} 52// append an axis-aligned square prism along z (centre cx) to the vert/tris arrays; st[0]=nv st[1]=nt advance 53func bhg_prism(vert: *i64, tris: *i64, st: *i64, cx: i64, z0: i64, z1: i64, rings: i64, caps: i64) -> i64 { 54 let v0: i64 = st[0] 55 let xy: *i64 = sys_mmap(16) as *i64 56 var r: i64 = 0 57 while r < rings { 58 var k: i64 = 0 59 while k < BHG_AROUND { 60 bhg_ring_xy(k, xy) 61 let idx: i64 = v0 + r * BHG_AROUND + k 62 vert[1 + idx * 3] = cx + xy[0] 63 vert[1 + idx * 3 + 1] = xy[1] 64 vert[1 + idx * 3 + 2] = z0 + (z1 - z0) * r / (rings - 1) 65 k = k + 1 66 } 67 r = r + 1 68 } 69 st[0] = v0 + rings * BHG_AROUND 70 r = 0 71 while r < rings - 1 { 72 var k: i64 = 0 73 while k < BHG_AROUND { 74 let a: i64 = v0 + r * BHG_AROUND + k 75 let b: i64 = v0 + r * BHG_AROUND + (k + 1) % BHG_AROUND 76 let c: i64 = v0 + (r + 1) * BHG_AROUND + (k + 1) % BHG_AROUND 77 let d: i64 = v0 + (r + 1) * BHG_AROUND + k 78 bhg_tri(tris, st, a, b, c) 79 bhg_tri(tris, st, a, c, d) 80 k = k + 1 81 } 82 r = r + 1 83 } 84 if caps == 1 { 85 let cb: i64 = st[0] 86 vert[1 + cb * 3] = cx; vert[1 + cb * 3 + 1] = 0; vert[1 + cb * 3 + 2] = z0 87 let ct: i64 = st[0] + 1 88 vert[1 + ct * 3] = cx; vert[1 + ct * 3 + 1] = 0; vert[1 + ct * 3 + 2] = z1 89 st[0] = st[0] + 2 90 var k: i64 = 0 91 while k < BHG_AROUND { 92 bhg_tri(tris, st, cb, v0 + (k + 1) % BHG_AROUND, v0 + k) 93 let top: i64 = v0 + (rings - 1) * BHG_AROUND 94 bhg_tri(tris, st, ct, top + k, top + (k + 1) % BHG_AROUND) 95 k = k + 1 96 } 97 } 98 return st[0] - v0 99} 100func bhg_joint(skel: *i64, j: i64, parent: i64, x: i64, y: i64, z: i64) -> i64 { 101 let o: i64 = 1 + j * BH_JOINT_WORDS 102 skel[o] = parent; skel[o + 1] = x; skel[o + 2] = y; skel[o + 3] = z 103 skel[o + 4] = 0; skel[o + 5] = 0; skel[o + 6] = 0; skel[o + 7] = BH_Q12 104 return 0 105} 106func bhg_write(path: *u8, vert: *i64, tris: *i64, st: *i64, skel: *i64, nj: i64) -> i64 { 107 vert[0] = st[0]; tris[0] = st[1]; skel[0] = nj 108 let tags: *i64 = sys_mmap(64) as *i64 109 let ptrs: *i64 = sys_mmap(64) as *i64 110 let wls: *i64 = sys_mmap(64) as *i64 111 tags[0] = nxa_tag4("VERT" as *u8); ptrs[0] = vert as i64; wls[0] = 1 + st[0] * 3 112 tags[1] = nxa_tag4("TRIS" as *u8); ptrs[1] = tris as i64; wls[1] = 1 + st[1] * 3 113 var ns: i64 = 2 114 if nj > 0 { tags[2] = nxa_tag4("SKEL" as *u8); ptrs[2] = skel as i64; wls[2] = 1 + nj * BH_JOINT_WORDS; ns = 3 } 115 return bh_nxa_write(path, ns, tags, ptrs, wls) 116} 117func bhg_open(path: *u8, lp: *i64) -> i64 { 118 let b: *u8 = sys_read_file(path, lp) 119 if (b as i64) == 0 { return 0 } 120 return b as i64 121} 122func bhg_w(b: *u8, flen: i64, v: i64, j: i64) -> i64 { 123 let kwo: i64 = nxa_find(b, flen, nxa_tag4("SKIN" as *u8)) 124 if kwo < 0 { return 0 - 1 } 125 let w: *i64 = b as *i64 126 let row: i64 = kwo + 1 + v * BH_SKIN_WORDS 127 var s: i64 = 0 128 var k: i64 = 0 129 while k < BH_INF_SLOTS { if w[row + k] == j { s = s + w[row + BH_INF_SLOTS + k] } k = k + 1 } 130 return s 131} 132func bhg_wsum(b: *u8, flen: i64, v: i64) -> i64 { 133 let kwo: i64 = nxa_find(b, flen, nxa_tag4("SKIN" as *u8)) 134 if kwo < 0 { return 0 - 1 } 135 let w: *i64 = b as *i64 136 let row: i64 = kwo + 1 + v * BH_SKIN_WORDS 137 var s: i64 = 0 138 var k: i64 = 0 139 while k < BH_INF_SLOTS { s = s + w[row + BH_INF_SLOTS + k]; k = k + 1 } 140 return s 141} 142func bhg_wmax(b: *u8, flen: i64, v: i64) -> i64 { 143 let kwo: i64 = nxa_find(b, flen, nxa_tag4("SKIN" as *u8)) 144 if kwo < 0 { return 0 - 1 } 145 let w: *i64 = b as *i64 146 let row: i64 = kwo + 1 + v * BH_SKIN_WORDS 147 var m: i64 = 0 148 var k: i64 = 0 149 while k < BH_INF_SLOTS { if w[row + BH_INF_SLOTS + k] > m { m = w[row + BH_INF_SLOTS + k] } k = k + 1 } 150 return m 151} 152func bhg_files_equal(pa: *u8, pb: *u8) -> i64 { 153 let la: *i64 = sys_mmap(16) as *i64 154 let lb: *i64 = sys_mmap(16) as *i64 155 let a: *u8 = sys_read_file(pa, la) 156 let b: *u8 = sys_read_file(pb, lb) 157 if (a as i64) == 0 { return 0 } 158 if (b as i64) == 0 { return 0 } 159 if la[0] != lb[0] { return 0 } 160 var i: i64 = 0 161 while i < la[0] { if a[i] != b[i] { return 0 } i = i + 1 } 162 return 1 163} 164 165func main() -> i64 { 166 let ctr: *i64 = gv_ctr() 167 gv_head("nx_boneheat_gate -- the geodesic auto-weights are asked to blend at a joint, to refuse to cross air, to announce an open mesh and to refuse a missing skeleton by name" as *u8) 168 sys_mkdir(BHG_DIR, BHG_MODE_DIR) 169 let vert: *i64 = sys_mmap((1 + BHG_VERT_CAP * 3) * 8) as *i64 170 let tris: *i64 = sys_mmap((1 + BHG_TRI_CAP * 3) * 8) as *i64 171 let skel: *i64 = sys_mmap((1 + BHG_JOINT_CAP * BH_JOINT_WORDS) * 8) as *i64 172 let st: *i64 = sys_mmap(16) as *i64 173 let rep: *i64 = sys_mmap(BR_WORDS * 8) as *i64 174 let lp: *i64 = sys_mmap(16) as *i64 175 176 // ---- fixture A: one closed prism, three joints along its axis ---- 177 st[0] = 0; st[1] = 0 178 bhg_prism(vert, tris, st, 0, 0, BHG_LEN, BHG_RINGS, 1) 179 bhg_joint(skel, 0, BHG_ROOT, 0, 0, 0) 180 bhg_joint(skel, 1, 0, 0, 0, BHG_MID) 181 bhg_joint(skel, 2, 1, 0, 0, BHG_LEN) 182 let pa: *u8 = "/tmp/nx_boneheat_gate/prism.nxa" 183 let pao: *u8 = "/tmp/nx_boneheat_gate/prism_geo.nxa" 184 let pao2: *u8 = "/tmp/nx_boneheat_gate/prism_geo2.nxa" 185 let pan: *u8 = "/tmp/nx_boneheat_gate/prism_near.nxa" 186 let wrote: i64 = bhg_write(pa, vert, tris, st, skel, 3) 187 let nvA: i64 = st[0] 188 gv_check("T1 fixture-reached-the-condition: the closed prism was written as an NXA with VERT TRIS and SKEL (166 vertices, 328 triangles, 3 joints)" as *u8, ((wrote > 0) as i64) * ((nvA == BHG_RINGS * BHG_AROUND + 2) as i64) * ((st[1] == (BHG_RINGS - 1) * BHG_AROUND * 2 + BHG_AROUND * 2) as i64), ctr) 189 var k: i64 = 0 190 while k < BR_WORDS { rep[k] = 0; k = k + 1 } 191 let rcA: i64 = bh_run(pa, pao, BH_MODE_GEODESIC, BHG_CELLS, rep) 192 bh_report(BH_MODE_GEODESIC, rep, pa, pao) 193 let sealedA: i64 = rep[BR_SEALED] 194 let cellsA: i64 = rep[BR_CELLS] 195 let surfA: i64 = rep[BR_SURF] 196 let extA: i64 = rep[BR_EXT] 197 let intA: i64 = rep[BR_INT] 198 let gnx: i64 = rep[BR_NX] 199 let gny: i64 = rep[BR_NY] 200 let gnz: i64 = rep[BR_NZ] 201 let gcell: i64 = rep[BR_CELL] 202 gv_check("T2 the geodesic solve on a sealed prism exits 0 and writes a SKIN section for every vertex" as *u8, ((rcA == BH_EXIT_OK) as i64) * ((rep[BR_BYTES] > wrote) as i64), ctr) 203 gv_check("T3 the voxel partition SUMS: exterior + surface + interior == cells, printed not assumed" as *u8, ((extA + surfA + intA == cellsA) as i64) * ((cellsA > 0) as i64), ctr) 204 gv_check("T4 a closed prism is SEALED: the exterior flood was stopped by the surface shell and interior cells exist" as *u8, ((sealedA == 1) as i64) * ((intA > 0) as i64), ctr) 205 let bA: i64 = bhg_open(pao, lp) 206 let fA: i64 = lp[0] 207 var bad_sum: i64 = 0 208 var v: i64 = 0 209 while v < nvA { if bhg_wsum(bA as *u8, fA, v) != BH_Q12 { bad_sum = bad_sum + 1 } v = v + 1 } 210 gv_check("T5 every vertex's four weights sum to EXACTLY 4096 (the NXA spec, residual folded into the largest) -- bound to the vertex count" as *u8, ((bad_sum == 0) as i64) * ((nvA > 0) as i64), ctr) 211 var mixed_mid: i64 = 0 212 var root_wins: i64 = 0 213 var far_wins: i64 = 0 214 k = 0 215 while k < BHG_AROUND { 216 let vm: i64 = BHG_RING_MID * BHG_AROUND + k 217 if bhg_w(bA as *u8, fA, vm, 0) > 0 { if bhg_w(bA as *u8, fA, vm, 1) > 0 { mixed_mid = mixed_mid + 1 } } 218 let vr: i64 = BHG_RING_ROOT * BHG_AROUND + k 219 if bhg_w(bA as *u8, fA, vr, 0) > bhg_w(bA as *u8, fA, vr, 1) { root_wins = root_wins + 1 } 220 let vf: i64 = BHG_RING_FAR * BHG_AROUND + k 221 if bhg_w(bA as *u8, fA, vf, 1) + bhg_w(bA as *u8, fA, vf, 2) > bhg_w(bA as *u8, fA, vf, 0) { far_wins = far_wins + 1 } 222 k = k + 1 223 } 224 gv_check("T6 anti-vacuity BLEND: all 4 corner vertices on the ring AT the middle joint carry weight from BOTH joint 0 and joint 1 -- a hard nearest boundary cannot produce this" as *u8, (mixed_mid == BHG_AROUND) as i64, ctr) 225 gv_check("T7 the falloff is monotone toward the root: all 4 corner vertices at 5 mm weigh joint 0 above joint 1" as *u8, (root_wins == BHG_AROUND) as i64, ctr) 226 gv_check("T8 the falloff is monotone toward the tip: all 4 corner vertices at 35 mm weigh joints 1 plus 2 above joint 0" as *u8, (far_wins == BHG_AROUND) as i64, ctr) 227 k = 0 228 while k < BR_WORDS { rep[k] = 0; k = k + 1 } 229 let rcN: i64 = bh_run(pa, pan, BH_MODE_NEAREST, BHG_CELLS, rep) 230 bh_report(BH_MODE_NEAREST, rep, pa, pan) 231 let bN: i64 = bhg_open(pan, lp) 232 let fN: i64 = lp[0] 233 var hard_mid: i64 = 0 234 k = 0 235 while k < BHG_AROUND { if bhg_wmax(bN as *u8, fN, BHG_RING_MID * BHG_AROUND + k) == BH_Q12 { hard_mid = hard_mid + 1 } k = k + 1 } 236 let nearMixed: i64 = rep[BR_MIXED] 237 gv_check("T9 neg-control-nearest-mode-cannot-blend: the control MD4 names gives every middle-ring vertex ONE joint at 4096 and reports mixed_verts=0 -- the discriminator between the two modes is real" as *u8, ((rcN == BH_EXIT_OK) as i64) * ((hard_mid == BHG_AROUND) as i64) * ((nearMixed == 0) as i64), ctr) 238 239 // ---- fixture B: the same prism with OPEN ends -- announced as unsealed, still solved over its shell ---- 240 st[0] = 0; st[1] = 0 241 bhg_prism(vert, tris, st, 0, 0, BHG_LEN, BHG_RINGS, 0) 242 let pb: *u8 = "/tmp/nx_boneheat_gate/open.nxa" 243 let pbo: *u8 = "/tmp/nx_boneheat_gate/open_geo.nxa" 244 bhg_write(pb, vert, tris, st, skel, 3) 245 let nvB: i64 = st[0] 246 k = 0 247 while k < BR_WORDS { rep[k] = 0; k = k + 1 } 248 let rcB: i64 = bh_run(pb, pbo, BH_MODE_GEODESIC, BHG_CELLS, rep) 249 bh_report(BH_MODE_GEODESIC, rep, pb, pbo) 250 let sealedB: i64 = rep[BR_SEALED] 251 let intB: i64 = rep[BR_INT] 252 gv_check("T10 the seal detector DISCRIMINATES: the open-ended prism floods through (sealed=0, interior=0) while the closed one sealed (sealed=1, interior>0) -- one measurement is not the other" as *u8, ((sealedB == 0) as i64) * ((intB == 0) as i64) * ((sealedA == 1) as i64) * ((intA > 0) as i64), ctr) 253 let bB: i64 = bhg_open(pbo, lp) 254 let fB: i64 = lp[0] 255 var bad_sum_b: i64 = 0 256 v = 0 257 while v < nvB { if bhg_wsum(bB as *u8, fB, v) != BH_Q12 { bad_sum_b = bad_sum_b + 1 } v = v + 1 } 258 gv_check("T11 an UNSEALED mesh is announced and still weighted over its shell -- exit 0, every vertex sums to 4096 -- never refused (Blender bone heat needs a manifold; ours does not)" as *u8, ((rcB == BH_EXIT_OK) as i64) * ((bad_sum_b == 0) as i64) * ((nvB > 0) as i64), ctr) 259 260 // ---- fixture C: two shells, 12 mm of air; shell B's only joint sits at its far end ---- 261 st[0] = 0; st[1] = 0 262 bhg_prism(vert, tris, st, 0, 0, BHG_SHELL_LEN, BHG_SHELL_RINGS, 1) 263 let nvShellA: i64 = st[0] 264 bhg_prism(vert, tris, st, BHG_SHELL_DX, 0, BHG_SHELL_LEN, BHG_SHELL_RINGS, 1) 265 let nvC: i64 = st[0] 266 bhg_joint(skel, 0, BHG_ROOT, 0, 0, 0) 267 bhg_joint(skel, 1, 0, 0, 0, BHG_SHELL_LEN) 268 bhg_joint(skel, 2, BHG_ROOT, BHG_SHELL_DX, 0, BHG_SHELL_LEN) 269 let pc: *u8 = "/tmp/nx_boneheat_gate/shells.nxa" 270 let pco: *u8 = "/tmp/nx_boneheat_gate/shells_geo.nxa" 271 let pcn: *u8 = "/tmp/nx_boneheat_gate/shells_near.nxa" 272 bhg_write(pc, vert, tris, st, skel, 3) 273 k = 0 274 while k < BR_WORDS { rep[k] = 0; k = k + 1 } 275 let rcC: i64 = bh_run(pc, pco, BH_MODE_GEODESIC, BHG_CELLS, rep) 276 bh_report(BH_MODE_GEODESIC, rep, pc, pco) 277 let unreachedC: i64 = rep[BR_UNREACH_V] 278 let bC: i64 = bhg_open(pco, lp) 279 let fC: i64 = lp[0] 280 var bleed_geo: i64 = 0 281 v = nvShellA 282 while v < nvC { if bhg_w(bC as *u8, fC, v, 0) + bhg_w(bC as *u8, fC, v, 1) > 0 { bleed_geo = bleed_geo + 1 } v = v + 1 } 283 gv_check("T12 anti-bleed EXCEED: across 12 mm of air NO vertex of shell B takes weight from shell A's joints (0 of 84), and every B vertex was reached through B's own volume (verts_unreached=0)" as *u8, ((rcC == BH_EXIT_OK) as i64) * ((bleed_geo == 0) as i64) * ((nvC - nvShellA > 0) as i64) * ((unreachedC == 0) as i64), ctr) 284 k = 0 285 while k < BR_WORDS { rep[k] = 0; k = k + 1 } 286 let rcCN: i64 = bh_run(pc, pcn, BH_MODE_NEAREST, BHG_CELLS, rep) 287 let bCN: i64 = bhg_open(pcn, lp) 288 let fCN: i64 = lp[0] 289 var bleed_near: i64 = 0 290 v = nvShellA 291 while v < nvC { if bhg_w(bCN as *u8, fCN, v, 0) + bhg_w(bCN as *u8, fCN, v, 1) > 0 { bleed_near = bleed_near + 1 } v = v + 1 } 292 gv_check("T13 neg-control-nearest-bleeds-across-air: the Euclidean control hands shell A's joints to shell B vertices (measured count above 0) -- the failure the geodesic solve exists to remove is real on this fixture" as *u8, ((rcCN == BH_EXIT_OK) as i64) * ((bleed_near > 0) as i64), ctr) 293 294 // ---- determinism and the named refusal ---- 295 k = 0 296 while k < BR_WORDS { rep[k] = 0; k = k + 1 } 297 bh_run(pa, pao2, BH_MODE_GEODESIC, BHG_CELLS, rep) 298 gv_check("T14 two geodesic solves of the same asset are BYTE-IDENTICAL (integer Dial buckets, deterministic scan order)" as *u8, bhg_files_equal(pao, pao2), ctr) 299 st[0] = 0; st[1] = 0 300 bhg_prism(vert, tris, st, 0, 0, BHG_LEN, BHG_RINGS, 1) 301 let pd: *u8 = "/tmp/nx_boneheat_gate/noskel.nxa" 302 let pdo: *u8 = "/tmp/nx_boneheat_gate/noskel_geo.nxa" 303 bhg_write(pd, vert, tris, st, skel, 0) 304 k = 0 305 while k < BR_WORDS { rep[k] = 0; k = k + 1 } 306 let rcD: i64 = bh_run(pd, pdo, BH_MODE_GEODESIC, BHG_CELLS, rep) 307 gv_check("T15 neg-control-refuses-without-skeleton: an NXA carrying VERT and TRIS but no SKEL is refused BY NAME with exit 3, never weighted against nothing" as *u8, (rcD == BH_EXIT_REFUSE) as i64, ctr) 308 309 gv_values_head() 310 gv_kv("closed_cells" as *u8, cellsA) 311 gv_kv("closed_grid_nx" as *u8, gnx) 312 gv_kv("closed_grid_ny" as *u8, gny) 313 gv_kv("closed_grid_nz" as *u8, gnz) 314 gv_kv("closed_cell_units" as *u8, gcell) 315 gv_kv("closed_exterior" as *u8, extA) 316 gv_kv("closed_surface" as *u8, surfA) 317 gv_kv("closed_interior" as *u8, intA) 318 gv_kv("closed_sealed" as *u8, sealedA) 319 gv_kv("open_sealed" as *u8, sealedB) 320 gv_kv("open_interior" as *u8, intB) 321 gv_kv("mixed_ring_verts" as *u8, mixed_mid) 322 gv_kv("root_ring_wins" as *u8, root_wins) 323 gv_kv("far_ring_wins" as *u8, far_wins) 324 gv_kv("nearest_mixed_verts" as *u8, nearMixed) 325 gv_kv("shells_bleed_geodesic" as *u8, bleed_geo) 326 gv_kv("shells_bleed_nearest" as *u8, bleed_near) 327 gv_kv("shells_verts_unreached" as *u8, unreachedC) 328 return gv_verdict("nx_boneheat_gate" as *u8, ctr, "geodesic bone-heat auto-weights: blends at joints, never crosses air, announces an open mesh, refuses a missing skeleton by name" as *u8) 329}