nx_nxa_texbake_region_gate.nx source
↩ module page · 359 lines · 20724 B
1// nx_nxa_texbake_region_gate.nx -- GATE for the per-region skin atlas + periodic micro-relief tile (TEXR),
2// /compare/graphics GR29 gpe_skin_microsurface asset half (2026-08-30).
3//
4// WHAT IT PROVES, and the operator's bar it answers ("make sure we aren't just doing more smooth surface
5// painting"): the relief is GEOMETRY. Every relief tooth below measures a HEIGHT field in microns or a
6// normal DERIVED from one, never a colour. In-process over the SAME implementation the CLI ships
7// (nx_nxa_texbake_region_lib), on the SHIPPED asset (gv_need), with runtime fixtures in /tmp/<gate>/.
8// structural (res 256, all regions): TEXR appended additively, TEXM byte-identical, every prior section
9// carried with its wordlen, 4 sets, adequacy predicate, idempotent, deterministic, seed-grain live,
10// neg-control: sets disabled FAILS adequacy.
11// geometry-not-paint (the micro tile, 480 px = 24mm): mean slope of the full-band tile exceeds the
12// primary-only SMOOTH CONTROL by a factor derived from the band law; the dominant pore period measured
13// on the height field equals the law's 800um pitch within one texel, and the smooth control has NO pits;
14// the tile is exactly periodic; the normal map re-derives byte-for-byte from the height.
15// anatomy (torso set at 2048 through the lib's probes): albedo at the mesh-derived apex darker than the
16// skin ring by the ledger's lightness step; the estate's own nx_areola_pigment referee returns MATCH on
17// the baked disc; height relief inside the areola exceeds the control ring outside.
18// tension: no stretch field exists in the asset -- named as the next contract, not faked.
19// license_tier: ORIGINAL No hw writes (Rule 26).
20import "nx_syscalls.nx"
21import "nx_nxa_texbake_region_lib.nx"
22import "nx_gate_verdict.nx"
23import "nx_image.nx"
24import "nx_areola_pigment.nx"
25
26const RG_DIR: *u8 = "/tmp/nx_nxa_texbake_region_gate"
27const RG_OUT_A: *u8 = "/tmp/nx_nxa_texbake_region_gate/a.nxa"
28const RG_OUT_A2: *u8 = "/tmp/nx_nxa_texbake_region_gate/a2.nxa"
29const RG_OUT_B: *u8 = "/tmp/nx_nxa_texbake_region_gate/b.nxa"
30const RG_OUT_C: *u8 = "/tmp/nx_nxa_texbake_region_gate/c.nxa"
31const RG_OUT_T: *u8 = "/tmp/nx_nxa_texbake_region_gate/t.nxa"
32const RG_ASSET: *u8 = "sites/nishifamily/world/ref9d.nxa"
33const RG_MODEDIR: i64 = 493
34const RG_RES_STRUCT: i64 = 256
35const RG_RES_PROBE: i64 = 2048
36const RG_SEED_A: i64 = 7
37const RG_SEED_B: i64 = 8
38const RG_HDR: i64 = 32
39const RG_TOCE: i64 = 32
40const RG_WORD: i64 = 8
41const RG_E3: i64 = 1000
42// the geometry-not-paint bar: HALF the nominal peak-tilt ratio of (primary+secondary) to primary. The
43// mean slope of a value-noise band sits below its peak tilt, but the RATIO of two bands' mean slopes
44// tracks the ratio of their peak tilts; half admits finite-difference attenuation and the sparse pore
45// term. Derived in code from the band law, printed beside the measurement.
46const RG_TILT_BAR_NUM: i64 = 1
47const RG_TILT_BAR_DEN: i64 = 2
48// the areola lightness tooth admits the outer soft edge: three quarters of the ledger step at the apex
49const RG_DL_NUM: i64 = 3
50const RG_DL_DEN: i64 = 4
51// the relief-inside-vs-outside bar: inside must exceed the outside control ring by this factor
52const RG_RELIEF_FACTOR: i64 = 2
53// control ring for the areola teeth, in areola radii
54const RG_RING_LO: i64 = 3
55const RG_RING_HI: i64 = 6
56
57func rg_flen(path: *u8, bout: *i64) -> i64 {
58 let lp: *i64 = sys_mmap(16) as *i64
59 let b: *u8 = sys_read_file(path, lp)
60 bout[0] = b as i64
61 if (b as i64) == 0 { return 0 - 1 }
62 return lp[0]
63}
64func rg_exists(path: *u8) -> i64 {
65 let fd: i64 = sys_openat_rd(path)
66 if fd < 0 { return 0 }
67 sys_close(fd)
68 return 1
69}
70func rg_nsec(b: *u8) -> i64 { return nt_rd64(b, 16) }
71// TOC index of a tag, or -1
72func rg_toc(b: *u8, tag: *u8) -> i64 {
73 let ns: i64 = rg_nsec(b)
74 var s: i64 = 0
75 while s < ns { if nt_tageq(b, RG_HDR + s*RG_TOCE, tag) == 1 { return s } s = s + 1 }
76 return 0 - 1
77}
78func rg_wl(b: *u8, s: i64) -> i64 { return nt_rd64(b, RG_HDR + s*RG_TOCE + 16) }
79func rg_off(b: *u8, s: i64) -> i64 { return nt_rd64(b, RG_HDR + s*RG_TOCE + 8) }
80// payload bytes of section `tag` identical in two files (same wordlen AND same bytes); 0 if absent in either
81func rg_payload_eq(b1: *u8, b2: *u8, tag: *u8) -> i64 {
82 let s1: i64 = rg_toc(b1, tag)
83 let s2: i64 = rg_toc(b2, tag)
84 if s1 < 0 { return 0 }
85 if s2 < 0 { return 0 }
86 let n1: i64 = rg_wl(b1, s1)
87 if n1 != rg_wl(b2, s2) { return 0 }
88 let o1: i64 = rg_off(b1, s1)
89 let o2: i64 = rg_off(b2, s2)
90 var i: i64 = 0
91 while i < n1*RG_WORD { if b1[o1 + i] != b2[o2 + i] { return 0 } i = i + 1 }
92 return 1
93}
94func rg_texr_nsets(b: *u8, flen: i64) -> i64 {
95 let o: i64 = ntr_texr_find(b, flen)
96 if o < 0 { return 0 - 1 }
97 let w: *i64 = b as *i64
98 return w[o + NTR_W_NSETS]
99}
100
101func main() -> i64 {
102 let ctr: *i64 = gv_ctr()
103 gv_head("nx_nxa_texbake_region_gate -- per-region atlas + periodic micro-relief tile: relief is GEOMETRY, measured (GR29 asset half)" as *u8)
104 sys_mkdir(RG_DIR, RG_MODEDIR)
105 sys_unlinkat(RG_OUT_A)
106 sys_unlinkat(RG_OUT_A2)
107 sys_unlinkat(RG_OUT_B)
108 sys_unlinkat(RG_OUT_C)
109 sys_unlinkat(RG_OUT_T)
110 var clean: i64 = 1
111 if rg_exists(RG_OUT_A) == 1 { clean = 0 }
112 if rg_exists(RG_OUT_B) == 1 { clean = 0 }
113 if rg_exists(RG_OUT_C) == 1 { clean = 0 }
114 if rg_exists(RG_OUT_T) == 1 { clean = 0 }
115 gv_check("T0 setup-outputs-absent-before-measuring (gate is idempotent)" as *u8, clean, ctr)
116
117 if gv_need(RG_ASSET, rg_exists(RG_ASSET), ctr) == 0 {
118 let rc0: i64 = gv_verdict("NXA-TEXBAKE-REGION" as *u8, ctr, "the shipped asset is the subject; without it nothing is measured" as *u8)
119 sys_exit(rc0)
120 return rc0
121 }
122 let bo: *i64 = sys_mmap(16) as *i64
123 let flen0: i64 = rg_flen(RG_ASSET, bo)
124 let b0: *u8 = bo[0] as *u8
125 let ns_in: i64 = rg_nsec(b0)
126 let texr_before: i64 = ntr_texr_find(b0, flen0)
127 gv_puts(" input sections=" as *u8); gv_num(ns_in); gv_puts(" bytes=" as *u8); gv_num(flen0)
128 gv_puts(" texr_before=" as *u8); gv_num(texr_before); gv_puts("\n" as *u8)
129
130 // ---- structural run A ----
131 let rcA: i64 = ntr_apply(RG_ASSET, RG_OUT_A, RG_RES_STRUCT, RG_SEED_A, NTB_DEFAULT_HUE)
132 gv_check("T1 apply runs clean on the shipped asset (res 256, all regions)" as *u8, rcA == 0, ctr)
133 let boA: *i64 = sys_mmap(16) as *i64
134 let flenA: i64 = rg_flen(RG_OUT_A, boA)
135 let bA: *u8 = boA[0] as *u8
136 var texr_after: i64 = 0
137 if flenA > 0 { if ntr_texr_find(bA, flenA) >= 0 { texr_after = 1 } }
138 var before_present: i64 = 0
139 if texr_before >= 0 { before_present = 1 }
140 gv_bite("T2 neg-control-TEXR-absent-before-and-present-after" as *u8, texr_after, before_present, ctr)
141 // every prior section carried with identical wordlen
142 var kept: i64 = 0
143 var si: i64 = 0
144 while si < ns_in {
145 if flenA > 0 {
146 let tagp: *u8 = ((b0 as i64) + RG_HDR + si*RG_TOCE) as *u8
147 let s2: i64 = rg_toc(bA, tagp)
148 if s2 >= 0 { if rg_wl(bA, s2) == rg_wl(b0, si) { kept = kept + 1 } }
149 }
150 si = si + 1
151 }
152 gv_puts(" carried with identical wordlen=" as *u8); gv_num(kept); gv_puts(" of " as *u8); gv_num(ns_in); gv_puts("\n" as *u8)
153 var t3: i64 = 0
154 if ns_in > 0 { if kept == ns_in { t3 = 1 } }
155 gv_check("T3 additive-only-every-prior-section-survives-with-its-wordlen (denominator = input count)" as *u8, t3, ctr)
156 var t4: i64 = 0
157 if flenA > 0 { t4 = rg_payload_eq(b0, bA, "TEXM" as *u8) }
158 gv_check("T4 map-set-0-TEXM-payload-byte-identical-to-the-incumbent (the live page's +144 read is untouched)" as *u8, t4, ctr)
159 var nsA: i64 = 0 - 1
160 if flenA > 0 { nsA = rg_texr_nsets(bA, flenA) }
161 gv_puts(" TEXR nsets=" as *u8); gv_num(nsA); gv_puts("\n" as *u8)
162 gv_check("T5 four-region-sets-present (face torso limbs gens, bound to NTR_REGIONS)" as *u8, nsA == NTR_REGIONS, ctr)
163 var adeqA: i64 = 0
164 if flenA > 0 { adeqA = ntr_texr_adequate(bA, flenA) }
165 gv_check("T6 per-region-adequacy: every set carries primary+secondary+pore-grid on its micro layer (carried=1 x3 x4 regions)" as *u8, adeqA, ctr)
166 // neg-control C: sets disabled
167 let rcC: i64 = ntr_apply_ctl(RG_ASSET, RG_OUT_C, RG_RES_STRUCT, RG_SEED_A, NTB_DEFAULT_HUE, NTR_CTL_ALL - NTR_CTL_SETS)
168 let boC: *i64 = sys_mmap(16) as *i64
169 let flenC: i64 = rg_flen(RG_OUT_C, boC)
170 let bC: *u8 = boC[0] as *u8
171 var adeqC: i64 = 1
172 var nsC: i64 = 0 - 1
173 if rcC == 0 { if flenC > 0 { adeqC = ntr_texr_adequate(bC, flenC); nsC = rg_texr_nsets(bC, flenC) } }
174 gv_puts(" control (sets disabled): rc=" as *u8); gv_num(rcC); gv_puts(" nsets=" as *u8); gv_num(nsC); gv_puts(" adequate=" as *u8); gv_num(adeqC); gv_puts("\n" as *u8)
175 gv_bite("T7 neg-control-region-sets-disabled-FAILS-the-adequacy-tooth" as *u8, 1 - adeqC, 1 - adeqA, ctr)
176 // idempotency + determinism
177 let rcA2: i64 = ntr_apply(RG_OUT_A, RG_OUT_A2, RG_RES_STRUCT, RG_SEED_A, NTB_DEFAULT_HUE)
178 let boA2: *i64 = sys_mmap(16) as *i64
179 let flenA2: i64 = rg_flen(RG_OUT_A2, boA2)
180 let bA2: *u8 = boA2[0] as *u8
181 var t8: i64 = 0
182 if rcA2 == 0 { if flenA2 > 0 { if rg_nsec(bA2) == rg_nsec(bA) { t8 = 1 } } }
183 gv_check("T8 idempotent-second-apply-replaces-rather-than-appends (section count must not move)" as *u8, t8, ctr)
184 var t9: i64 = 0
185 if rcA2 == 0 { if flenA2 > 0 { t9 = rg_payload_eq(bA, bA2, "TEXR" as *u8) } }
186 gv_check("T9 deterministic: same seed -> byte-identical TEXR payload" as *u8, t9, ctr)
187 let rcB: i64 = ntr_apply(RG_ASSET, RG_OUT_B, RG_RES_STRUCT, RG_SEED_B, NTB_DEFAULT_HUE)
188 let boB: *i64 = sys_mmap(16) as *i64
189 let flenB: i64 = rg_flen(RG_OUT_B, boB)
190 let bB: *u8 = boB[0] as *u8
191 var t10: i64 = 0
192 if rcB == 0 { if flenB > 0 { t10 = 1 - rg_payload_eq(bA, bB, "TEXR" as *u8) } }
193 gv_check("T10 seed grain is LIVE: different seed -> different TEXR payload" as *u8, t10, ctr)
194
195 // ---- geometry-not-paint on the micro tile ----
196 let mpx: i64 = rlf_tile_px()
197 let tex: i64 = rlf_tile_texel_um()
198 let hqS: *i64 = sys_mmap(mpx*mpx*RG_WORD + 64) as *i64
199 let hqC: *i64 = sys_mmap(mpx*mpx*RG_WORD + 64) as *i64
200 let nS: *u8 = sys_mmap(mpx*mpx*3 + 64)
201 let dS: *u8 = sys_mmap(mpx*mpx*3 + 64)
202 let nC: *u8 = sys_mmap(mpx*mpx*3 + 64)
203 let dC: *u8 = sys_mmap(mpx*mpx*3 + 64)
204 ntr_bake_tile(RG_SEED_A, RLF_BAND_ALL, hqS, nS, dS)
205 ntr_bake_tile(RG_SEED_A, RLF_BAND_PRIMARY, hqC, nC, dC)
206 let slS: i64 = ntr_mean_slope_e3(hqS, mpx, 2*tex, 1)
207 let slC: i64 = ntr_mean_slope_e3(hqC, mpx, 2*tex, 1)
208 let t0: i64 = rlf_band_tilt_full(RG_E3, RLF_RELIEF_UM, RLF_RELIEF_LAMBDA_UM)
209 let t1: i64 = rlf_band_tilt_full(RG_E3, RLF_SEC_UM, RLF_SEC_LAMBDA_UM)
210 var nominal: i64 = 0
211 if t0 > 0 { nominal = (t0 + t1) * RG_E3 / t0 }
212 let bar: i64 = nominal * RG_TILT_BAR_NUM / RG_TILT_BAR_DEN
213 var ratio: i64 = 0
214 if slC > 0 { ratio = slS * RG_E3 / slC }
215 gv_puts(" micro tile px=" as *u8); gv_num(mpx); gv_puts(" texel_um=" as *u8); gv_num(tex)
216 gv_puts(" mean_slope subject=" as *u8); gv_num(slS); gv_puts(" control(primary only)=" as *u8); gv_num(slC)
217 gv_puts(" ratio_permil=" as *u8); gv_num(ratio); gv_puts(" nominal_tilt_ratio=" as *u8); gv_num(nominal); gv_puts(" bar=" as *u8); gv_num(bar); gv_puts("\n" as *u8)
218 var t11: i64 = 0
219 if slC > 0 { if ratio >= bar { t11 = 1 } }
220 gv_check("T11 geometry-not-paint: full-band tile mean slope exceeds the smooth control by the derived factor" as *u8, t11, ctr)
221 let ppS: *i64 = sys_mmap(2*RG_WORD) as *i64
222 let ppC: *i64 = sys_mmap(2*RG_WORD) as *i64
223 ntr_pore_period(hqS, mpx, rlf_tile_repeat_um(), ppS)
224 ntr_pore_period(hqC, mpx, rlf_tile_repeat_um(), ppC)
225 let cells: i64 = mpx / rlf_tile_lat(RLF_PORE_PITCH_UM)
226 gv_puts(" pore pits subject=" as *u8); gv_num(ppS[0]); gv_puts(" (law cells^2=" as *u8); gv_num(cells*cells)
227 gv_puts(") period_um=" as *u8); gv_num(ppS[1]); gv_puts(" law_pitch=" as *u8); gv_num(RLF_PORE_PITCH_UM)
228 gv_puts(" tolerance_um=" as *u8); gv_num(tex); gv_puts(" | control pits=" as *u8); gv_num(ppC[0]); gv_puts("\n" as *u8)
229 var perS: i64 = 0
230 if ppS[0] > 0 { if ntr_abs(ppS[1] - RLF_PORE_PITCH_UM) <= tex { perS = 1 } }
231 var perC: i64 = 0
232 if ppC[0] > 0 { if ntr_abs(ppC[1] - RLF_PORE_PITCH_UM) <= tex { perC = 1 } }
233 gv_check("T12 pore band spatial frequency: dominant period on the height field = 800um +- one texel" as *u8, perS, ctr)
234 gv_bite("T13 neg-control-smooth-control-has-no-pore-period" as *u8, perS, perC, ctr)
235 // exact periodicity
236 var per_ok: i64 = 1
237 var yy: i64 = 0
238 while yy < mpx {
239 if rlf_relief_um2_tile(0, yy, RG_SEED_A) != rlf_relief_um2_tile(mpx, yy, RG_SEED_A) { per_ok = 0 }
240 if rlf_relief_um2_tile(yy, 0, RG_SEED_A) != rlf_relief_um2_tile(yy, mpx, RG_SEED_A) { per_ok = 0 }
241 yy = yy + 1
242 }
243 gv_check("T14 tile is EXACTLY periodic (texel at x and x+tile are the same microns, both axes)" as *u8, per_ok, ctr)
244 // normal re-derives from height
245 let n3: *i64 = sys_mmap(3*RG_WORD) as *i64
246 var nd_ok: i64 = 1
247 var y2: i64 = 0
248 while y2 < mpx {
249 var x2: i64 = 0
250 while x2 < mpx {
251 ntb_encode_normal_um(hqS[y2*mpx + rlf_wrap(x2+1, mpx)] - hqS[y2*mpx + rlf_wrap(x2-1, mpx)], hqS[rlf_wrap(y2+1, mpx)*mpx + x2] - hqS[rlf_wrap(y2-1, mpx)*mpx + x2], 2*tex, n3)
252 let o: i64 = (y2*mpx + x2)*3
253 if (nS[o] as i64) != n3[0] { nd_ok = 0 }
254 if (nS[o+1] as i64) != n3[1] { nd_ok = 0 }
255 if (nS[o+2] as i64) != n3[2] { nd_ok = 0 }
256 x2 = x2 + 1
257 }
258 y2 = y2 + 1
259 }
260 gv_check("T15 micro-normal is DERIVED from the height (re-derivation byte-identical, not a painted normal)" as *u8, nd_ok, ctr)
261
262 // ---- anatomy on the torso set at 2048, through the lib's probes ----
263 let have_ledger: i64 = rg_exists("knowledge/areola_relief.conf" as *u8)
264 if gv_need("knowledge/areola_relief.conf (the cited anatomy ledger)" as *u8, have_ledger, ctr) == 1 {
265 NTR_PROBE_ON = 1
266 let rcT: i64 = ntr_apply_ctl(RG_ASSET, RG_OUT_T, RG_RES_PROBE, RG_SEED_A, NTB_DEFAULT_HUE, NTR_CTL_ALL + NTR_CTL_ONLY_TORSO)
267 var probed: i64 = 0
268 if rcT == 0 { if NTR_PROBE_RGB != 0 { if NTR_PROBE_HQ != 0 { if NTR_PROBE_META != 0 { probed = 1 } } } }
269 gv_check("T16 torso probe run at 2048 (torso-only control bit) produced the raw maps" as *u8, probed, ctr)
270 if probed == 1 {
271 let res: i64 = NTR_PROBE_RES
272 let prgb: *u8 = NTR_PROBE_RGB as *u8
273 let phq: *i64 = NTR_PROBE_HQ as *i64
274 let pcov: *u8 = NTR_PROBE_COV as *u8
275 let pfa: *i64 = NTR_PROBE_FA as *i64
276 let pfb: *i64 = NTR_PROBE_FB as *i64
277 let pmeta: *i64 = NTR_PROBE_META as *i64
278 let ra: i64 = ntr_conf("areola_dia_um" as *u8) / 2
279 let dl: i64 = ntr_conf("areola_dl_e3" as *u8)
280 let fmean: i64 = pmeta[NTR_S_FMEAN]
281 let ax: i64 = pmeta[NTR_S_ALX]
282 let ay: i64 = pmeta[NTR_S_ALY]
283 gv_puts(" torso footprint_mean_um=" as *u8); gv_num(fmean); gv_puts(" apex_px=" as *u8); gv_num(ax); gv_puts("," as *u8); gv_num(ay)
284 gv_puts(" areola_r_um=" as *u8); gv_num(ra); gv_puts(" areola_r_px=" as *u8); gv_num(pmeta[NTR_S_ARPX]); gv_puts(" dl_e3=" as *u8); gv_num(dl); gv_puts("\n" as *u8)
285 var apex_found: i64 = 0
286 if ax >= 0 { if ay >= 0 { apex_found = 1 } }
287 gv_check("T17 mesh-derived bust apex landed inside a covered torso texel" as *u8, apex_found, ctr)
288 if apex_found == 1 {
289 // selections: disc (d <= ra) and control ring (3ra..6ra), covered only
290 let npx: i64 = res*res
291 let selin: *u8 = sys_mmap(npx + 64)
292 let selout: *u8 = sys_mmap(npx + 64)
293 var nin: i64 = 0
294 var nout: i64 = 0
295 var lin: i64 = 0
296 var lout: i64 = 0
297 var q: i64 = 0
298 while q < npx {
299 if pcov[q] != (0 as u8) {
300 let d2: i64 = pfa[q]*pfa[q] + pfb[q]*pfb[q]
301 if d2 <= ra*ra { selin[q] = 1 as u8; nin = nin + 1; lin = lin + si_lstar_of_byte(prgb[q*3] as i64, prgb[q*3+1] as i64, prgb[q*3+2] as i64) }
302 if d2 >= RG_RING_LO*RG_RING_LO*ra*ra { if d2 <= RG_RING_HI*RG_RING_HI*ra*ra { selout[q] = 1 as u8; nout = nout + 1; lout = lout + si_lstar_of_byte(prgb[q*3] as i64, prgb[q*3+1] as i64, prgb[q*3+2] as i64) } }
303 }
304 q = q + 1
305 }
306 var lmi: i64 = 0
307 var lmo: i64 = 0
308 if nin > 0 { lmi = lin / nin }
309 if nout > 0 { lmo = lout / nout }
310 gv_puts(" disc texels=" as *u8); gv_num(nin); gv_puts(" ring texels=" as *u8); gv_num(nout)
311 gv_puts(" L*_disc_e3=" as *u8); gv_num(lmi); gv_puts(" L*_ring_e3=" as *u8); gv_num(lmo); gv_puts(" step_e3=" as *u8); gv_num(lmo - lmi)
312 gv_puts(" bar_e3=" as *u8); gv_num(dl*RG_DL_NUM/RG_DL_DEN); gv_puts("\n" as *u8)
313 var t18: i64 = 0
314 if nin > 0 { if nout > 0 { if lmo - lmi >= dl*RG_DL_NUM/RG_DL_DEN { t18 = 1 } } }
315 gv_check("T18 areola albedo darker than the skin ring by the ledger's lightness step (disc and ring both non-empty)" as *u8, t18, ctr)
316 // the estate's own referee on the baked disc
317 let img: *Image = nx_image_alloc(res, res, 3)
318 let msk: *Image = nx_image_alloc(res, res, 1)
319 var yy3: i64 = 0
320 while yy3 < res {
321 var xx3: i64 = 0
322 while xx3 < res {
323 let o3: i64 = yy3*res + xx3
324 nx_image_set(img, xx3, yy3, 0, prgb[o3*3] as i64)
325 nx_image_set(img, xx3, yy3, 1, prgb[o3*3+1] as i64)
326 nx_image_set(img, xx3, yy3, 2, prgb[o3*3+2] as i64)
327 var mv: i64 = 0
328 if selin[o3] != (0 as u8) { mv = 255 }
329 nx_image_set(msk, xx3, yy3, 0, mv)
330 xx3 = xx3 + 1
331 }
332 yy3 = yy3 + 1
333 }
334 let ares: *i64 = sys_mmap(NX_AREOLA_RES_FIELDS*RG_WORD + 64) as *i64
335 nx_areola_pigment(img, msk, NX_REPRO_NULLIPAROUS_YOUNG, ares)
336 gv_puts(" nx_areola_pigment referee: mean_rgb=" as *u8); gv_num(ares[NX_AREOLA_RES_MEAN_R]); gv_puts("," as *u8); gv_num(ares[NX_AREOLA_RES_MEAN_G]); gv_puts("," as *u8); gv_num(ares[NX_AREOLA_RES_MEAN_B])
337 gv_puts(" pigment=" as *u8); gv_num(ares[NX_AREOLA_RES_PIGMENT]); gv_puts(" warmth=" as *u8); gv_num(ares[NX_AREOLA_RES_WARMTH])
338 gv_puts(" composite_q10=" as *u8); gv_num(ares[NX_AREOLA_RES_COMPOSITE]); gv_puts(" verdict=" as *u8); gv_num(ares[NX_AREOLA_RES_VERDICT]); gv_puts(" (2=MATCH)\n" as *u8)
339 gv_check("T19 independent referee nx_areola_pigment returns MATCH for a nulliparous-young areola on the baked disc" as *u8, ares[NX_AREOLA_RES_VERDICT] == NX_AREOLA_VERDICT_MATCH, ctr)
340 // relief: inside the areola vs the control ring, on the HEIGHT field
341 let sin2: i64 = ntr_mean_slope_sel_e3(phq, res, 2*fmean, selin)
342 let sout2: i64 = ntr_mean_slope_sel_e3(phq, res, 2*fmean, selout)
343 gv_puts(" height mean slope permil inside areola=" as *u8); gv_num(sin2); gv_puts(" control ring=" as *u8); gv_num(sout2); gv_puts("\n" as *u8)
344 var t20: i64 = 0
345 if sin2 > 0 { if sout2 >= 0 { if sin2 >= RG_RELIEF_FACTOR*sout2 { t20 = 1 } } }
346 gv_check("T20 areola is GEOMETRIC relief: height slope inside the disc exceeds the flat control ring outside (nipple dome + Montgomery domes)" as *u8, t20, ctr)
347 }
348 }
349 }
350 // ---- tension response: named, not faked ----
351 var has_strn: i64 = 0
352 if rg_toc(b0, "STRN" as *u8) >= 0 { has_strn = 1 }
353 gv_puts(" tension response: asset carries a stretch-field section=" as *u8); gv_num(has_strn)
354 gv_puts(" -- NEXT CONTRACT ntr_tension_attenuate (relief smooths under stretch, roughens under compression; Nagano 2015); not asserted here because no stretch field exists to attenuate against\n" as *u8)
355
356 let rc: i64 = gv_verdict("NXA-TEXBAKE-REGION" as *u8, ctr, "per-region atlas + periodic micro-relief tile: additive, adequate on every region, relief measured as geometry, areola as anatomy" as *u8)
357 sys_exit(rc)
358 return rc
359}