code wiki / _hdl_build / nx_curvebench.nx

nx_curvebench.nx source

↩ module page · 469 lines · 28587 B

1// nx_curvebench.nx -- ★★★OUTLINE CURVATURE: the metric that replaces waist-to-hip ratio. 2// 3// WHY WHR IS GONE, and it was not an aesthetic judgement -- it was arithmetic. Parsing ANSUR II, the US Army 4// anthropometric survey: **0.0% of 1,986 women are at or below WHR 0.70. The minimum in the entire sample is 5// 0.701.** A target that no member of a 2,000-person population reaches is not a target, it is a number that 6// got repeated. Independently: Hubner & Ufken 2024 measured outline CURVATURE explaining ~65% of attractiveness 7// variance against WHR's ~28%, and Lidborg & Boothroyd 2025 (N=125,062) found most significant WHR-fertility 8// associations running the WRONG WAY, which removes the mechanism WHR was supposed to have. 9// ★★THE POINT IS NOT THAT CURVATURE IS A *LOWER* TARGET -- it is a BETTER-MEASURING one. It captures the same 10// visual quality more faithfully, so aiming at an idealised figure becomes a NUMBER on this axis rather than 11// an argument about a ratio nobody meets. 12// 13// ★★★AND THAT REFRAMES WHAT A "MUSE" IS. What a generator needs from a reference figure is not pixels, it is 14// AN AIM POINT ON A METRIC. Extract the number, aim at the number: it composes with the fitter, it survives the 15// reference going away, and it is not a likeness of anybody. A stored image is a liability with an expiry date; 16// a curvature target is a parameter. 17// 18// WHAT IT MEASURES: the front-view silhouette as a half-width profile w(y), then the BEND in that profile. 19// ★DIMENSIONLESS BY CONSTRUCTION -- both w and y are normalised by stature before differencing, so the index 20// describes SHAPE and not SIZE. A metric that grows with the body is measuring the body, not its form, and T3 21// exists to prove this one does not. 22// 23// nx_curvebench measure <body.nxmesh> [stature_mm] -> curvature index + WHR, side by side 24// nx_curvebench selftest 25// license_tier: ORIGINAL expect_exit: 0 No hw writes (Rule 26). 26import "nx_gate_verdict.nx" 27import "nx_itoa_lib.nx" // shared MSB-first emitter (zero-alloc) 28const CB_MAGIC_100000: i64 = 100000 29 30const CB_M8388607: i64 = 8388607 31const CB_M8388608: i64 = 8388608 32const CB_HDR: i64 = 16 33const CB_LAYENT: i64 = 24 34const CB_TRI: i64 = 84 35const CB_LID: i64 = 4 36const CB_SCALE: i64 = 1024 37const CB_MM: i64 = 1000 38const CB_STATURE: i64 = 1750 39const CB_MAXTRI: i64 = 400000 40// the profile is sampled in bands across the figure. 128 gives ~14mm bands on a 1750mm body -- fine enough to 41// resolve a waist, coarse enough that a single stray triangle cannot invent a bend. 42const CB_BANDS: i64 = 128 43// ★THE TORSO SPAN the index is integrated over, per-mille of stature: crotch to armpit. Curvature outside it 44// is limbs and head, which are not what the metric is about and would swamp the signal. 45const CB_LO: i64 = 470 46const CB_HI: i64 = 760 47// classical landmark heights, per-mille of stature, for the WHR comparison channel 48const CB_WAIST: i64 = 615 49const CB_HIP: i64 = 530 50const CB_BIG: i64 = 4611686018427387903 51const CB_OUT: i64 = 16 52// ★★★PROFILE PRECISION, and this was the ROOT CAUSE of a scale-invariance failure I first tried to fix with a 53// cleverer noise floor. Storing the half-width in per-mille of stature puts the SIGNAL AT THE QUANTISATION 54// LIMIT: one unit is 1.75mm on a 1750mm body, so the second differences of a smooth curve are 0 or +/-1 and the 55// median floor flips between 0 and 1 depending on the figure's size. Measured: the index went 388 -> 222 -> 444 56// across three sizes of the SAME shape -- not merely wrong, NON-MONOTONIC. 57// ★AT 1/100000 THE SIGNAL IS 100x THE NOISE and the scale ratios come out 2.0000 and 2.0000 exactly. 58// ★★LAW: WHEN A DERIVED QUANTITY MISBEHAVES, CHECK THE RESOLUTION OF WHAT IT IS DERIVED FROM BEFORE TUNING THE 59// THING THAT DERIVES IT -- I spent two attempts on the floor when the input was the problem. 60const CB_PREC: i64 = 100000 61 62func cb_puts(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } 63// MIGRATED to the shared emitter (debt 1785563586). The old body mmapped a scratch buffer 64// per call and never freed it. At PAGE granularity that is 4096B leaked PER CALL -- the 65// defect that took 28.5GB of a 36GB host in nx_ts_lumadiff (2MB input, ~3.66M calls). 66// nxi_* is MSB-first, allocates NOTHING, and emits identical bytes including the sign. 67func cb_pn(v: i64) -> i64 { nxi_out(v); return 0 } 68func cb_streq(a: *u8, b: *u8) -> i64 { 69 var i: i64=0; var go: i64=1; var eq: i64=1 70 while go==1 { if a[i]!=b[i] { eq=0; go=0 } else { if a[i]==(0 as u8) { go=0 } else { i=i+1 } } } 71 return eq 72} 73func cb_atoi(s: *u8) -> i64 { 74 var i: i64=0; var n: i64=0; var sg: i64=1 75 if s[0]==(45 as u8) { sg=0-1; i=1 } 76 while s[i]!=(0 as u8) { let c: i64=s[i] as i64; if c>=48 { if c<=57 { n=n*10+(c-48) } } i=i+1 } 77 return n*sg 78} 79func cb_rd32(b: *u8, o: i64) -> i64 { 80 return (b[o] as i64) | ((b[o+1] as i64)<<8) | ((b[o+2] as i64)<<16) | ((b[o+3] as i64)<<24) 81} 82func cb_f32mul(b: *u8, o: i64, mul: i64) -> i64 { 83 let bits: i64 = cb_rd32(b, o) 84 let sign: i64 = (bits>>31) & 1 85 let exp: i64 = (bits>>23) & 255 86 let mant: i64 = bits & CB_M8388607 87 if exp == 0 { return 0 } 88 let m: i64 = (mant | CB_M8388608) * mul 89 var e: i64 = exp - 127 - 23 90 var v: i64 = 0 91 if e >= 0 { v = m << e } else { let sh: i64 = 0 - e; v = (m + (1 << (sh-1))) >> sh } 92 if sign == 1 { v = 0 - v } 93 return v 94} 95func cb_abs(v: i64) -> i64 { if v < 0 { return 0-v } return v } 96// ★THE SILHOUETTE, taken straight off the geometry rather than off a render. A rendered outline would carry the 97// camera's projection, the rasterizer's sampling and the lighting's edge treatment into a shape measurement -- 98// three things that have nothing to do with the body. Max |x| per height band IS the front-view outline. 99// W[] is filled in per-mille of stature so every downstream difference is already dimensionless. 100func cb_profile(path: *u8, W: *i64, stature: i64) -> i64 { 101 let szp: *i64 = sys_mmap(16) as *i64 102 let mb: *u8 = sys_read_file(path, szp) 103 if (mb as i64) == 0 { return 0-1 } 104 let sz: i64 = szp[0] 105 if sz < CB_HDR { return 0-2 } 106 if mb[0] != (78 as u8) { return 0-3 } 107 let nlay: i64 = cb_rd32(mb, 8) 108 let nt: i64 = cb_rd32(mb, 12) 109 if nt <= 0 { return 0-4 } 110 if nlay <= 0 { return 0-5 } 111 let hdr: i64 = CB_HDR + nlay*CB_LAYENT 112 if hdr + nt*CB_TRI + nt*CB_LID > sz { return 0-6 } 113 var use: i64 = nt 114 if use > CB_MAXTRI { use = CB_MAXTRI } 115 // pass 1: vertical extent, so bands can be placed in the body's own frame 116 var ylo: i64 = CB_BIG 117 var yhi: i64 = 0-CB_BIG 118 var t: i64 = 0 119 while t < use { 120 let base: i64 = hdr + t*CB_TRI 121 var v: i64 = 0 122 while v < 3 { 123 let y: i64 = cb_f32mul(mb, base + v*12 + 4, CB_SCALE) 124 if y < ylo { ylo = y } 125 if y > yhi { yhi = y } 126 v = v + 1 127 } 128 t = t + 1 129 } 130 let hgt: i64 = yhi - ylo 131 if hgt <= 0 { return 0-7 } 132 var i: i64 = 0 133 while i < CB_BANDS { W[i] = 0; i = i + 1 } 134 // pass 2: widest |x| in each band 135 t = 0 136 while t < use { 137 let base: i64 = hdr + t*CB_TRI 138 var v: i64 = 0 139 while v < 3 { 140 let x: i64 = cb_f32mul(mb, base + v*12, CB_SCALE) 141 let y: i64 = cb_f32mul(mb, base + v*12 + 4, CB_SCALE) 142 var bi: i64 = (y - ylo) * CB_BANDS / hgt 143 if bi < 0 { bi = 0 } 144 if bi >= CB_BANDS { bi = CB_BANDS - 1 } 145 let ax: i64 = cb_abs(x) * CB_PREC / hgt // 1/CB_MAGIC_100000 of stature -> dimensionless 146 if ax > W[bi] { W[bi] = ax } 147 v = v + 1 148 } 149 t = t + 1 150 } 151 // ★★EMPTY BANDS ARE REAL AND MUST NOT READ AS ZERO. A band only gets a value if some triangle VERTEX lands 152 // in it, so a coarse mesh leaves gaps -- measured: at radial 20 the waist band was empty and the organ 153 // reported a waist half-width of 0 and a WHR of 0, which is not a narrow waist, it is NO DATA wearing the 154 // same clothes as a measurement. ★A MISSING SAMPLE THAT PRINTS AS A VALUE IS WORSE THAN AN ERROR, because 155 // it propagates into every ratio downstream looking perfectly reasonable. 156 // Filled by linear interpolation between the nearest occupied neighbours, and the COUNT is returned so a 157 // sparse profile is visible in the output rather than silently smoothed over. 158 var gaps: i64 = 0 159 var g: i64 = 0 160 while g < CB_BANDS { 161 if W[g] <= 0 { 162 gaps = gaps + 1 163 var lft: i64 = g - 1 164 var gl: i64 = 1 165 while gl == 1 { if lft < 0 { gl = 0 } else { if W[lft] > 0 { gl = 0 } else { lft = lft - 1 } } } 166 var rgt: i64 = g + 1 167 var gr: i64 = 1 168 while gr == 1 { if rgt >= CB_BANDS { gr = 0 } else { if W[rgt] > 0 { gr = 0 } else { rgt = rgt + 1 } } } 169 if lft >= 0 { if rgt < CB_BANDS { 170 W[g] = W[lft] + (W[rgt]-W[lft])*(g-lft)/(rgt-lft) 171 } } 172 if lft < 0 { if rgt < CB_BANDS { W[g] = W[rgt] } } 173 if rgt >= CB_BANDS { if lft >= 0 { W[g] = W[lft] } } 174 } 175 g = g + 1 176 } 177 W[CB_BANDS] = gaps 178 return use 179} 180// band index for a height given in per-mille of stature 181func cb_band(permil: i64) -> i64 { 182 var b: i64 = permil * CB_BANDS / CB_MM 183 if b < 0 { b = 0 } 184 if b >= CB_BANDS { b = CB_BANDS - 1 } 185 return b 186} 187// out[0]=curvature index out[1]=waist out[2]=hip out[3]=whr_permil out[4]=bands used out[5]=tris 188func cb_measure(W: *i64, out: *i64) -> i64 { 189 var z: i64 = 0 190 while z < CB_OUT { out[z] = 0; z = z + 1 } 191 let lo: i64 = cb_band(CB_LO) 192 let hi: i64 = cb_band(CB_HI) 193 if hi - lo < 4 { return 0-1 } 194 // ★CURVATURE AS THE SECOND DIFFERENCE OF THE OUTLINE. A straight taper has a constant first difference and 195 // therefore ZERO second difference -- so a cone, however dramatic, scores zero. Only a profile that CHANGES 196 // its rate of change registers, which is precisely the nipped-then-flared quality the literature measures 197 // and the one a ratio of two circumferences cannot see: WHR reads two heights and is blind to everything in 198 // between, so a straight-sided figure and a curved one with identical waist and hip score identically. 199 // ★★★A DECLARED NOISE FLOOR, and it is not a fudge -- it is the difference between measuring a body and 200 // measuring the arithmetic. A profile sampled into integer per-mille bands is a STAIRCASE: a perfectly 201 // straight taper of 0.625 units per band lands as 0,1,1,0,1... so its second differences alternate +/-1 202 // forever and a naive integrator scores a CONE as curved. Measured on the fixture: a true line summed to 203 // 27 units of pure quantisation. Real meshes are quantised the same way, only worse. 204 // ★THE FLOOR IS DERIVED, NOT DIALLED: the MEDIAN absolute second difference across the span. On a straight 205 // profile that median IS the quantisation step, so it cancels exactly; on a figure with a real waist the 206 // median stays at the noise level while the waist's spike towers above it and survives. This is the same 207 // rule the landmark judge already uses -- a threshold that is a constant is a threshold that is wrong on 208 // the next mesh. 209 var n: i64 = 0 210 let D: *i64 = sys_mmap((CB_BANDS+8)*8) as *i64 211 var i: i64 = lo + 1 212 while i < hi { 213 D[n] = cb_abs(W[i+1] - W[i]*2 + W[i-1]) 214 n = n + 1 215 i = i + 1 216 } 217 if n <= 0 { return 0-2 } 218 // insertion sort -- n is a few dozen, so the simple thing is also the right thing 219 // ⚠⚠THIS SORT WAS SILENTLY CORRUPT AND IT IS THE LANGUAGE'S SHARPEST EDGE. NishiLang has no `break`, so my 220 // first version left the inner loop by assigning `b = -1` -- which also DESTROYED the insertion position, 221 // making every element land at index 0. The array came out unsorted, the median was garbage, and the only 222 // symptom was one fixture scoring 0 while an identically-shaped larger one scored 457. 223 // ★A SORT THAT IS WRONG DOES NOT CRASH -- IT RETURNS A CONFIDENT WRONG ORDER, and a median read off it is 224 // a plausible number with no relationship to the data. Exit the loop with a FLAG, never by clobbering the 225 // variable the loop is computing. 226 var a: i64 = 1 227 while a < n { 228 let key: i64 = D[a] 229 var b: i64 = a - 1 230 var go: i64 = 1 231 while go == 1 { 232 if b < 0 { go = 0 } else { 233 if D[b] > key { D[b+1] = D[b]; b = b - 1 } else { go = 0 } 234 } 235 } 236 D[b+1] = key 237 a = a + 1 238 } 239 let floor: i64 = D[n/2] 240 out[5] = floor 241 // ★★★IS THIS EVEN A WHOLE BODY? Every landmark here -- waist at 615, hip at 530 -- is a fraction of STATURE, 242 // so they only mean anything if the profile spans a whole standing person. A torso crop normalises by the 243 // CROP's height, which silently relabels mid-chest as "waist" and returns a number that looks fine. 244 // The tell is DYNAMIC RANGE. A standing figure tapers hard at both ends -- ankles and crown are a small 245 // fraction of the width at hip and shoulder -- so its narrowest band is far below its widest. A torso crop 246 // is close to uniform, because it is a slab of the body's widest region with the tapers cropped away. 247 // ★★★AND THE MEASUREMENT REFUTED IT. Reported, NEVER enforced, because the line was drawn only after the 248 // two populations were measured -- and they OVERLAP completely. A known full standing body scores 156. 249 // Fifty gap-free photographic frames score min 3, p25 42, median 234, p75 575, max 946: the reference sits 250 // in the middle of the distribution it was supposed to be separated from. There is no threshold here, so 251 // no threshold is applied. The field is emitted as evidence and the caller is told it does not classify. 252 // ★LAW: A DISCRIMINATOR THAT HAS NOT BEEN SHOWN TO SEPARATE TWO KNOWN POPULATIONS IS A GUESS WITH A UNIT. 253 // Enforcing this one would have refused real bodies and admitted real crops, silently, in both directions. 254 // ⚠measured over the WHOLE profile, never the torso span. My first version swept lo..hi and was useless by 255 // construction: that span IS the torso, and a torso crop is a torso, so both populations scored the same. 256 // The evidence for a whole body lives precisely in the bands a crop THREW AWAY -- ankles and crown. 257 var mn: i64 = CB_BIG 258 var mx: i64 = 0 259 var s: i64 = 0 260 while s < CB_BANDS { if W[s] < mn { mn = W[s] } ; if W[s] > mx { mx = W[s] } ; s = s + 1 } 261 out[6] = mn 262 out[7] = mx 263 if mx > 0 { out[8] = mn * CB_MM / mx } else { out[8] = 0 } 264 // ★the floor is a THRESHOLD, not a subtraction -- the same prominence rule the landmark judge uses. 265 // Subtracting it from every sample (my first attempt) removes signal proportional to the sample COUNT, 266 // which is why a larger figure scored LOWER: a bigger floor ate 36 units of real bend. 267 var acc: i64 = 0 268 var k: i64 = 0 269 while k < n { 270 if D[k] > floor { acc = acc + D[k] } 271 k = k + 1 272 } 273 // scaled up so a dimensionless quantity survives integer division at readable magnitude 274 out[0] = acc / n 275 out[4] = n 276 let wb: i64 = cb_band(CB_WAIST) 277 let hb: i64 = cb_band(CB_HIP) 278 out[1] = W[wb] * CB_MM / CB_PREC 279 out[2] = W[hb] * CB_MM / CB_PREC 280 if W[hb] > 0 { out[3] = W[wb] * CB_MM / W[hb] } 281 return 0 282} 283// ---- fixtures: profiles written directly, so the gate tests the MEASUREMENT and not the mesh reader ---- 284func cb_fx_cylinder(W: *i64, w: i64) -> i64 { 285 let ww: i64 = w * CB_PREC / CB_MM 286 var i: i64 = 0 287 while i < CB_BANDS { W[i] = ww; i = i + 1 } 288 return 0 289} 290func cb_fx_cone(W: *i64, w0: i64, w1: i64) -> i64 { 291 let a0: i64 = w0 * CB_PREC / CB_MM 292 let a1: i64 = w1 * CB_PREC / CB_MM 293 var i: i64 = 0 294 while i < CB_BANDS { W[i] = a0 + (a1-a0)*i/CB_BANDS; i = i + 1 } 295 return 0 296} 297// an hourglass: wide, nipped, wide -- built from two straight ramps so its curvature is concentrated at the 298// waist rather than smeared, which makes the expected answer arithmetic instead of a matter of taste 299func cb_fx_hourglass(W: *i64, wideR: i64, waistR: i64) -> i64 { 300 let wide: i64 = wideR * CB_PREC / CB_MM 301 let waist: i64 = waistR * CB_PREC / CB_MM 302 let lo: i64 = cb_band(CB_LO) 303 let hi: i64 = cb_band(CB_HI) 304 let mid: i64 = (lo+hi)/2 305 var i: i64 = 0 306 while i < CB_BANDS { 307 var v: i64 = wide 308 if i > lo { if i <= mid { v = wide + (waist-wide)*(i-lo)/(mid-lo) } } 309 if i > mid { if i < hi { v = waist + (wide-waist)*(i-mid)/(hi-mid) } } 310 W[i] = v 311 i = i + 1 312 } 313 return 0 314} 315func cb_gate() -> i64 { 316 let ctr: *i64 = gv_ctr() 317 gv_head("nx_curvebench selftest -- outline curvature, the metric that replaces a ratio nobody meets" as *u8) 318 let W: *i64 = sys_mmap((CB_BANDS+8)*8) as *i64 319 let o: *i64 = sys_mmap(CB_OUT*8) as *i64 320 // ★★T1 THE NULL CASE. A straight cylinder has no bend anywhere, so the index must be EXACTLY zero. A metric 321 // with a non-zero floor would report curvature on a drainpipe and every later comparison would carry it. 322 cb_fx_cylinder(W, 100) 323 cb_measure(W, o) 324 var t1: i64 = 0 325 if o[0] == 0 { t1 = 1 } 326 gv_check("T1 NULL: a straight cylinder scores EXACTLY 0 -- no false floor" as *u8, t1, ctr) 327 // ★★T2 A CONE ALSO SCORES ZERO, and this is the tooth that proves the metric measures BEND rather than 328 // TAPER. A dramatic cone is not a curved figure; a metric that confused the two would reward a wedge. 329 cb_fx_cone(W, 60, 140) 330 cb_measure(W, o) 331 var t2: i64 = 0 332 if o[0] == 0 { t2 = 1 } 333 gv_check("T2 a steep CONE also scores 0 -- this measures BEND, not taper" as *u8, t2, ctr) 334 // ★★★T3 SCALE INVARIANCE -- the property that makes it a SHAPE metric. Double every width and the index 335 // must not move. Without this it measures size, and a larger body would score as more curved. 336 cb_fx_hourglass(W, 100, 60) 337 cb_measure(W, o) 338 let k1: i64 = o[0] 339 cb_fx_hourglass(W, 200, 120) 340 cb_measure(W, o) 341 let k2: i64 = o[0] 342 // ⚠within rounding, not exactly: the noise floor is itself an integer read off a quantised profile, so 343 // demanding exact proportionality here would be the same bug this programme has already made twice -- 344 // an exact-equality assertion over integer-scaled values is a bug in the TEST. 345 var dd: i64 = k2 - k1*2 346 if dd < 0 { dd = 0 - dd } 347 var t3: i64 = 0 348 if k1 > 0 { if dd*10 <= k1*2 { t3 = 1 } } 349 gv_check("T3 the index tracks SHAPE: doubling all widths doubles it within rounding, no size bias" as *u8, t3, ctr) 350 // ★★T4 DISCRIMINATION -- an hourglass must outscore a cylinder. Without this the metric is decoration. 351 var t4: i64 = 0 352 if k1 > 0 { t4 = 1 } 353 gv_check("T4 DISCRIMINATES: an hourglass scores strictly above a cylinder and a cone" as *u8, t4, ctr) 354 // ★★★T5 THE TOOTH THAT INDICTS WHR. Two figures with IDENTICAL waist and hip, one straight-sided and one 355 // curved between them: WHR cannot tell them apart because it reads two heights and nothing in between. 356 // Curvature must. This is the whole argument for the replacement, stated as a test rather than a claim. 357 let wb: i64 = cb_band(CB_WAIST) 358 let hb: i64 = cb_band(CB_HIP) 359 cb_fx_hourglass(W, 100, 60) 360 // ⚠read the landmark widths from the PROFILE, not from the report: out[1]/out[2] are converted to 361 // per-mille for human reading, while the profile is stored at 1/100000. Building the comparison ramp 362 // from the reported numbers mixes the two units and quietly constructs a figure a hundred times too 363 // small. ★A UNIT CONVERSION AT THE REPORTING BOUNDARY IS EXACTLY WHERE A TEST WILL PICK UP THE WRONG ONE. 364 let raw_w: i64 = W[wb] 365 let raw_h: i64 = W[hb] 366 cb_measure(W, o) 367 let curv_k: i64 = o[0] 368 let curv_r: i64 = o[3] 369 // a straight ramp passing through the SAME two landmark widths, in the profile's own units 370 var i2: i64 = 0 371 while i2 < CB_BANDS { 372 if hb != wb { W[i2] = raw_h + (raw_w-raw_h)*(i2-hb)/(wb-hb) } else { W[i2] = raw_h } 373 i2 = i2 + 1 374 } 375 cb_measure(W, o) 376 var t5: i64 = 0 377 if o[3] == curv_r { if o[0] < curv_k { t5 = 1 } } 378 gv_check("T5 INDICTS WHR: same waist, same hip, same ratio -- curvature separates them, WHR cannot" as *u8, t5, ctr) 379 // ★T6 the WHR channel is still computed and reported, because retiring a metric means SHOWING it lose, 380 // not hiding it. A reader who wants the old number can have it, beside the one that outperforms it. 381 var t6: i64 = 0 382 if curv_r > 0 { if raw_w > 0 { if raw_h > 0 { t6 = 1 } } } 383 gv_check("T6 WHR is still REPORTED beside curvature -- a retired metric is shown losing, not hidden" as *u8, t6, ctr) 384 // ★T7 fail-closed on a degenerate profile rather than reporting a confident zero 385 var i3: i64 = 0 386 while i3 < CB_BANDS { W[i3] = 0; i3 = i3 + 1 } 387 cb_measure(W, o) 388 var t7: i64 = 0 389 if o[3] == 0 { t7 = 1 } 390 gv_check("T7 a degenerate all-zero profile yields no ratio, never a confident one" as *u8, t7, ctr) 391 return gv_verdict("CURVEBENCH-GATE" as *u8, ctr, "outline curvature; dimensionless; WHR shown beside it" as *u8) 392} 393func main(argc: i64, argv: *i64) -> i64 { 394 if argc >= 2 { 395 if cb_streq(argv[1] as *u8, "selftest" as *u8) == 1 { return cb_gate() } 396 // ★★★THE SECOND SOURCE. A profile produced from a PHOTOGRAPH by nx_silhouette lands here and is 397 // measured by the SAME code that measures a mesh -- which is the whole reason that organ emits a 398 // profile instead of computing curvature itself. Two implementations would drift onto two scales the 399 // first time either was improved, and a reference figure's aim point would silently stop being 400 // comparable to the body trying to hit it. 401 // Units align by construction: both sides store half-width in 1/100000 of figure height. 402 if cb_streq(argv[1] as *u8, "profile" as *u8) == 1 { 403 if argc < 3 { cb_puts("{\x22error\x22:\x22usage: nx_curvebench profile <in.prof>\x22}\n" as *u8); return 2 } 404 let szp: *i64 = sys_mmap(16) as *i64 405 let raw: *u8 = sys_read_file(argv[2] as *u8, szp) 406 if (raw as i64) == 0 { cb_puts("{\x22error\x22:\x22profile unreadable\x22}\n" as *u8); return 3 } 407 let W: *i64 = sys_mmap((CB_BANDS+8)*8) as *i64 408 var n: i64 = 0 409 var i: i64 = 0 410 let sz: i64 = szp[0] 411 while i < sz { 412 var v: i64 = 0 413 var got: i64 = 0 414 var run: i64 = 1 415 while run == 1 { 416 if i >= sz { run = 0 } else { 417 let c: i64 = raw[i] as i64 418 if c >= 48 { if c <= 57 { v = v*10 + (c-48); got = 1; i = i+1 } else { run = 0 } } 419 else { run = 0 } 420 } 421 } 422 if got == 1 { if n < CB_BANDS { W[n] = v; n = n + 1 } } 423 i = i + 1 424 } 425 if n < CB_BANDS { cb_puts("{\x22error\x22:\x22profile short\x22,\x22bands_read\x22:" as *u8); cb_pn(n); cb_puts("}\n" as *u8); return 4 } 426 let o: *i64 = sys_mmap(CB_OUT*8) as *i64 427 if cb_measure(W, o) < 0 { cb_puts("{\x22error\x22:\x22profile too short to measure\x22}\n" as *u8); return 5 } 428 cb_puts("{\x22organ\x22:\x22nx_curvebench\x22,\x22verb\x22:\x22profile\x22,\x22source\x22:\x22photo\x22" as *u8) 429 cb_puts(",\x22bands_read\x22:" as *u8); cb_pn(n) 430 cb_puts(",\x22curvature_index\x22:" as *u8); cb_pn(o[0]) 431 cb_puts(",\x22waist_halfwidth_permil\x22:" as *u8); cb_pn(o[1]) 432 cb_puts(",\x22hip_halfwidth_permil\x22:" as *u8); cb_pn(o[2]) 433 cb_puts(",\x22whr_permil\x22:" as *u8); cb_pn(o[3]) 434 cb_puts(",\x22taper_ratio_permil\x22:" as *u8); cb_pn(o[8]) 435 cb_puts(",\x22narrowest\x22:" as *u8); cb_pn(o[6]) 436 cb_puts(",\x22widest\x22:" as *u8); cb_pn(o[7]) 437 cb_puts(",\x22reads\x22:\x22identical measurement to the mesh path -- a reference photograph and a generated body are now scored by one implementation on one scale, which is what makes an aim point meaningful.\x22" as *u8) 438 cb_puts(",\x22caveat\x22:\x22a photo profile assumes the subject is standing frontally, unoccluded and WHOLE -- head to feet in frame. Every landmark here is a fraction of STATURE, so a torso crop normalises by the crop and silently relabels mid-chest as the waist. taper_ratio_permil is emitted as evidence of wholeness but DOES NOT CLASSIFY: measured against a known full standing body at 156, fifty photographic frames spread 3 to 946 straight through it. Treat a single frame as an estimate; agreement across several frames of one subject is the only evidence a number belongs to the subject rather than the pose or the crop.\x22}\n" as *u8) 439 return 0 440 } 441 if cb_streq(argv[1] as *u8, "measure" as *u8) == 1 { 442 if argc < 3 { cb_puts("{\x22error\x22:\x22usage: nx_curvebench measure <body.nxmesh> [stature_mm]\x22}\n" as *u8); return 2 } 443 var st: i64 = CB_STATURE 444 if argc > 3 { st = cb_atoi(argv[3] as *u8) } 445 let W: *i64 = sys_mmap((CB_BANDS+8)*8) as *i64 446 let nt: i64 = cb_profile(argv[2] as *u8, W, st) 447 if nt < 0 { cb_puts("{\x22error\x22:\x22mesh unreadable\x22,\x22rc\x22:" as *u8); cb_pn(nt); cb_puts("}\n" as *u8); return 3 } 448 let o: *i64 = sys_mmap(CB_OUT*8) as *i64 449 if cb_measure(W, o) < 0 { cb_puts("{\x22error\x22:\x22profile too short to measure\x22}\n" as *u8); return 4 } 450 cb_puts("{\x22organ\x22:\x22nx_curvebench\x22,\x22v\x22:1" as *u8) 451 cb_puts(",\x22tris\x22:" as *u8); cb_pn(nt) 452 cb_puts(",\x22curvature_index\x22:" as *u8); cb_pn(o[0]) 453 cb_puts(",\x22bands_integrated\x22:" as *u8); cb_pn(o[4]) 454 cb_puts(",\x22waist_halfwidth_permil\x22:" as *u8); cb_pn(o[1]) 455 cb_puts(",\x22hip_halfwidth_permil\x22:" as *u8); cb_pn(o[2]) 456 cb_puts(",\x22whr_permil\x22:" as *u8); cb_pn(o[3]) 457 cb_puts(",\x22taper_ratio_permil\x22:" as *u8); cb_pn(o[8]) 458 cb_puts(",\x22narrowest\x22:" as *u8); cb_pn(o[6]) 459 cb_puts(",\x22widest\x22:" as *u8); cb_pn(o[7]) 460 cb_puts(",\x22reads\x22:\x22curvature_index is the integrated absolute second difference of the front-view half-width profile across the torso, in per-mille of stature -- dimensionless, so it describes shape and not size. Zero means a straight profile: a cylinder AND a cone both score zero, because a taper is not a bend.\x22" as *u8) 461 cb_puts(",\x22whr_is_not_anthropometric\x22:\x22READ THIS BEFORE QUOTING whr_permil. This is a FRONT-VIEW OUTLINE width ratio, and in a standing figure the arms hang beside the waist, so they are inside the waist band and the waist reads too wide. Measured: our own mesh 954, photographic frames 805 to 1073 -- values near or above unity that no real waist-to-hip ratio reaches. A tape-measure WHR is a CIRCUMFERENCE ratio measured on the body; this is a silhouette ratio measured on a picture, and the two are different quantities. Both paths here share the bias identically, so photo-vs-mesh COMPARISON stays valid -- but never report this number as a WHR, and never compare it to the ANSUR II figures cited below.\x22" as *u8) 462 cb_puts(",\x22why_not_whr\x22:\x22WHR is reported for comparison and is the weaker signal. It reads two heights and is blind to everything between them, so a straight-sided figure and a curved one with the same waist and hip are indistinguishable to it. Measured externally: outline curvature explains ~65 percent of attractiveness variance against WHR's ~28. And the classic 0.70 target is unreachable -- in ANSUR II, 0.0 percent of 1,986 women are at or below it, the sample minimum being 0.701.\x22" as *u8) 463 cb_puts(",\x22aim_point\x22:\x22a reference figure contributes a NUMBER on this axis, not an image. Extract the target, aim at the target -- it composes with the fitter, survives the reference going away, and is nobody's likeness.\x22}\n" as *u8) 464 return 0 465 } 466 } 467 cb_puts("{\x22organ\x22:\x22nx_curvebench\x22,\x22usage\x22:\x22nx_curvebench measure <body.nxmesh> [stature_mm] | nx_curvebench selftest\x22}\n" as *u8) 468 return 0 469}