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}