nx_faceanat.nx source
↩ module page · 1142 lines · 71980 B
1// nx_faceanat.nx -- ★INSIDE-OUT face (operator 2026-07-08: "get the skeleton then muscles then skin, not
2// outside-in"; nx_anatomy_census verdict: build the SKULL+TISSUE-DEPTH rung FIRST). Instead of placing ellipsoids
3// by eyeball, DERIVE the face:
4// (1) POSITIONS from the anthropometric FACIAL CANONS -- rule of THIRDS (hairline->brow->subnasale->chin, equal)
5// + rule of FIFTHS (face width = 5 eye-widths; eyes are fifths 2 & 4; nose = 1 fifth; mouth ~1.5 eye-widths).
6// (2) Z-RELIEF from FORENSIC SOFT-TISSUE-DEPTH tables (Rhine/De Greef-class, adult female, mm): the skin sits
7// proud of the bony skull by a MEASURED amount per landmark -- brow ridge proud, nasal root shallow,
8// cheekbone proud, temple recessed. = anatomically DERIVED form, not sculpted.
9// Fills the SAME nx_sdfrender arena as sdf_face (parts/mats/ops/blend) so it renders + PROJECTS + is measured by
10// the identical pipeline (the shared eye-line@178 / mouth@-390 frame keeps the A-R2 projection constants valid).
11// license_tier: ORIGINAL (data-driven per CLAUDE #2/#11: every number is a canon ratio or a tissue-depth value)
12import "nx_syscalls.nx"
13import "nx_sdfrender.nx"
14
15// model scale: skull half-width ~150mm -> 525u => ~3.5 u/mm. Depth args are passed as mm*10 (45 = 4.5mm),
16// MMU = u/mm * 10 = 35, so relief = depth_mm10 * MMU / 100 = mm * 3.5 u/mm (CORRECT). (v0 used /10 = 10x too
17// proud -> a bulgy caricature that fit the reference WORSE; the gate's rs_err measurement caught it.)
18const MMU: i64 = 35
19// AT17 (2026-09-02): the MEASUREMENT scale is DERIVED, never typed. knowledge/faceanat_scale.conf carries four witnesses of the
20// model's own landmarks against ANSUR II female means (n=1986, nx_ansur_regress mean): their median is 7.8 u/mm, band 7.0..8.7,
21// so the typed 3.5 above was 2.2x low (a 150 mm HALF-width taken for a skull about 145 mm WIDE). MMU stays ONLY for the tissue-
22// relief depth arithmetic (fa_tissue_z), which was tuned against reference renders under it; re-baselining that relief is a
23// visual-acceptance rung, not a constant edit. nx_faceanat_scale_gate holds MMU_X10_DERIVED to the conf's recomputed median.
24const MMU_X10_DERIVED: i64 = 78
25func fa_mmu_x10() -> i64 { return MMU_X10_DERIVED }
26func fa_mmu_relief_legacy_x10() -> i64 { return MMU }
27// shared landmark frame (identical to sdf_face so projection reuses): eye line y=+178, subnasale ~ y=-150,
28// stomion (mouth) y=-390, gnathion (chin bottom) y=-676, glabella (brow) y=+322, trichion (hairline) y=+760.
29// rule of THIRDS check: brow322 -> subnasale-150 = 472 ; subnasale-150 -> chin-676 = 526 ~ within canon band.
30// rule of FIFTHS: face half-width 525 = 2.5 eye-widths -> eye width 210 (half 105); eye centers at +-258
31// (outer fifth boundary); nose half-width ~64 (1 fifth/2); mouth half-width ~150 (~1.4 eye-widths).
32
33func fa_tissue_z(base_z: i64, depth_mm10: i64) -> i64 { return base_z - depth_mm10 * MMU / 100 } // proud toward -z (camera); mm*10 in
34// ---- THE EYE UNIT (aesthetictwin AT39, 2026-09-17): ONE PIECE, BUILT AT ITS OWN SCALE, THEN SEATED IN THE FACE --------------
35// Four ellipsoid lids could not make an eye: an ellipsoid has no margin, so its edge curves away behind the globe and the
36// opening between two of them is not a recess. The generator's own fissure scan read NO-APERTURE on the canon face and on every
37// morphed genome, the fissure gate read 1 of 8, and the photo ruler could pair the eyes on 6 of 21 renders. The lids are now
38// ONE SHELL per eye (renderer op SDF_OP_LIDSHELL) about the globe centre with an almond opening whose two corners ARE the
39// canthi, so the canthi exist by construction AND are still found from the surface by the scan below: two readings of one
40// landmark that must agree. Every number is a canon row or is derived from the globe it wraps:
41// half-width 110 : knowledge/facecanon.conf intercanthal_index 400 (380..420) with the eye centres at 258 gives
42// (258-110)/(258+110) = 402 permil; fifth_fissure 200 permil of a 1050 bizygomatic is 210, this is 220
43// up 50, low 36 : palpebral_fissure_height 11.0 mm (10..12) at the derived 7.8 u/mm is 86 units, split upper-heavy as the
44// upper lid arcs higher over the cornea than the lower lid drops below it
45// tilt 5 degrees : the twin card axis canthal_tilt is positive when the lateral canthus is above the medial one; five degrees
46// is the canon default and the first gene the fit loop could not reach before this unit existed
47// inner radius : the globe's largest radius (104) plus 2, so the shell clears the globe everywhere
48// thickness 20 : about 2.6 mm of lid margin at 7.8 u/mm; it is the step every aperture scan and every ruler needs
49const FA_EYE_CX: i64 = 258
50const FA_EYE_CY: i64 = 178
51const FA_EYE_CZ: i64 = 0 - 560
52const FA_GLOBE_L: i64 = 18
53const FA_GLOBE_R: i64 = 19
54const FA_LID_L: i64 = 27
55const FA_LID_R: i64 = 28
56const FA_LID_RIN: i64 = 106
57const FA_LID_T: i64 = 20
58const FA_LID_CAP: i64 = 126
59const FA_LID_HALFW: i64 = 110
60const FA_LID_UP: i64 = 50
61const FA_LID_LOW: i64 = 36
62const FA_LID_K: i64 = 6 // a crisp margin: the face default (18) would fillet most of a 20-unit step away
63// ---- THE LIP UNIT (aesthetictwin AT43, 2026-09-18): two SWEPT half tubes meeting at the stomion, seated on a perioral mound ----
64// Two blended ellipsoids could not make a mouth: an ellipsoid has no vermilion border, no seam and no commissure, so the mouth
65// rendered as one swollen two-lobe blob and the photo ruler lost it. Each lip is now the renderer's SDF_OP_LIPSWEEP: six part
66// numbers = the stomion at the midline (cx, cy, cz = the tube axis) and (half-width, vermilion height, projection depth), the
67// shape in its primitive slots. The vermilion border, the seam and the commissures therefore exist BY CONSTRUCTION, and the
68// generator can STATE its lip landmarks. Every number is a canon row, this frame's landmark, or derived:
69// stomion y -390 : this frame's landmark (the header's shared landmark frame)
70// half-width 150 / 140 : the frame's mouth half-width (~1.4 eye-widths); the lower lip a little narrower than the upper
71// lower height 78 : a 10 mm lower vermilion (stomion to labrale inferius) at the derived 7.8 u/mm
72// upper height DERIVED : knowledge/facecanon.conf upper_over_lower_lip is labrale-superius-to-stomion over stomion-to-
73// labrale-inferius, 625 permil, and labrale superius is the midpoint of the upper vermilion line --
74// the BOTTOM of the cupid's bow dip, not its peaks. So the MIDLINE height must be 78 * 625 / 1000 =
75// 49, and the peaks stand the bow's dip above it. MEASURED 2026-09-18: the first cut typed 49 at the
76// PEAKS, which put the stated midline at 39 and the stated ratio at 500 permil, outside the canon's
77// own 625..1000 band -- a hand-computed number beside the canon it was computed from, drifting from
78// it by the one term nobody wrote down
79// depths 62 / 66, axis z : the fronts sit where the AT16 ellipsoid lips put them (-712 upper, -706 lower), so the profile
80// and E-line rulers see the same projection and only the SHAPE changes
81// arch 90, taper 350 : the commissure sits back on the dental arch; its thickness is a third of the midline's
82// bow 170 at 180 permil : cupid's bow, a dip of 170 permil of the upper height (about 1.2 mm) between the philtral columns,
83// stated as a FRACTION so every morph and every scale carries it with the height it belongs to
84const FA_LIP_U: i64 = 10
85const FA_LIP_L: i64 = 11
86const FA_MOUTH_SLIT: i64 = 20
87const FA_PERIORAL_UP: i64 = 33
88const FA_PERIORAL_LOW: i64 = 34
89const FA_STOMION_Y: i64 = 0 - 390
90const FA_LIP_HALFW_U: i64 = 150
91const FA_LIP_HALFW_L: i64 = 140
92const FA_LIP_H_L: i64 = 78
93const FA_LIP_UL_CANON_PERMIL: i64 = 625 // knowledge/facecanon.conf upper_over_lower_lip target
94const FA_LIP_BOW_PERMIL: i64 = 170
95const FA_LIP_H_U: i64 = FA_LIP_H_L * FA_LIP_UL_CANON_PERMIL / (SDF_PERMIL - FA_LIP_BOW_PERMIL)
96const FA_LIP_D_U: i64 = 62
97const FA_LIP_D_L: i64 = 66
98const FA_LIP_AXIS_Z_U: i64 = 0 - 650
99const FA_LIP_AXIS_Z_L: i64 = 0 - 640
100const FA_LIP_ARCH: i64 = 90
101const FA_LIP_TAPER: i64 = 350
102const FA_LIP_BOW_HW: i64 = 180
103const FA_LIP_UP_SIDE: i64 = 1
104const FA_LIP_DOWN_SIDE: i64 = 0 - 1
105const FA_LIP_K: i64 = 8 // the vermilion border is crisp; the mound below it blends softly at the face default
106const FA_NPARTS: i64 = 35
107const FA_FILL_UP_L: i64 = 29
108const FA_FILL_UP_R: i64 = 30
109const FA_FILL_LOW_L: i64 = 31
110const FA_FILL_LOW_R: i64 = 32
111const FA_FILL_K_UP: i64 = 30
112const FA_FILL_K_LOW: i64 = 40
113const FA_PART_FIELDS: i64 = 6
114const FA_F_CX: i64 = 0
115const FA_F_CY: i64 = 1
116const FA_F_CZ: i64 = 2
117const FA_F_RX: i64 = 3
118const FA_F_RY: i64 = 4
119const FA_F_RZ: i64 = 5
120// 1 when part i belongs to an eye unit (globe or lid shell): a face that grows wider or longer MOVES its eyes and does not
121// stretch them, so the width and length morphs shift these parts and leave their size to the eyes morph alone
122func fa_is_eye_unit(i: i64) -> i64 {
123 if i == FA_GLOBE_L { return 1 }
124 if i == FA_GLOBE_R { return 1 }
125 if i == FA_LID_L { return 1 }
126 if i == FA_LID_R { return 1 }
127 return 0
128}
129
130// scale the opening of a lid shell (half-width, upper rise, lower drop) about its own centre: v' = v*pct/100
131func fa_scale_prim(base: i64, idx: i64, pct: i64) -> i64 {
132 sdf_set_prim(base, idx, SDF_PR_HALFW, sdf_get_prim(base, idx, SDF_PR_HALFW) * pct / 100)
133 sdf_set_prim(base, idx, SDF_PR_UP, sdf_get_prim(base, idx, SDF_PR_UP) * pct / 100)
134 sdf_set_prim(base, idx, SDF_PR_LOW, sdf_get_prim(base, idx, SDF_PR_LOW) * pct / 100)
135 return 0
136}
137// ---- EYE GENES (AT39): the eye unit's procedural degrees of freedom, declared ONCE ------------------------------------------
138// A generator that draws seven face morphs and one eye shape emits one pair of eyes for every person. These six genes are the
139// eye unit's own parameters with their ranges, read by the person generator (which SAMPLES them per seed) and by the twin fit
140// (which SWEEPS them to learn what a render can reach), so the two can never disagree about what an eye may be. The ranges are
141// a FIRST DECLARATION from general periocular anthropometry and carry no fetched citation yet: the refs rung owes one, and
142// until it lands these are generator bounds, never a published norm. Symmetry is a gene too: a living face is close to
143// mirrored and never exactly mirrored, so the left-right differences are small, centred on zero, and drawn per person.
144const FA_EG_TILT: i64 = 0 // canthal tilt in deg10, positive when the lateral canthus sits above the medial
145const FA_EG_OPEN: i64 = 1 // opening height, percent of the canon height
146const FA_EG_WIDTH: i64 = 2 // opening width, percent of the canon width
147const FA_EG_UPSHARE: i64 = 3 // the upper arc's share of the opening height, permil
148const FA_EG_DTILT: i64 = 4 // right-minus-left tilt difference, deg10
149const FA_EG_DOPEN: i64 = 5 // right-minus-left opening height difference, percent points
150const FA_EG_N: i64 = 6
151const FA_EG_TILT_LO: i64 = 0 - 20
152const FA_EG_TILT_HI: i64 = 100
153const FA_EG_TILT_CANON: i64 = 50
154const FA_EG_OPEN_LO: i64 = 80
155const FA_EG_OPEN_HI: i64 = 120
156const FA_EG_WIDTH_LO: i64 = 92
157const FA_EG_WIDTH_HI: i64 = 108
158const FA_EG_PCT_CANON: i64 = 100
159const FA_EG_UPSHARE_LO: i64 = 540
160const FA_EG_UPSHARE_HI: i64 = 640
161const FA_EG_DTILT_LO: i64 = 0 - 10
162const FA_EG_DTILT_HI: i64 = 10
163const FA_EG_DOPEN_LO: i64 = 0 - 4
164const FA_EG_DOPEN_HI: i64 = 4
165const FA_EG_PERMIL: i64 = 1000
166const FA_EG_DEG10_HALF_TURN: i64 = 1800 // deg10 in half a turn: rad4096 = deg10 * IT_PI / 1800
167func fa_eye_gene_name(k: i64) -> *u8 {
168 if k == FA_EG_TILT { return "eye_tilt" as *u8 }
169 if k == FA_EG_OPEN { return "eye_open" as *u8 }
170 if k == FA_EG_WIDTH { return "eye_width" as *u8 }
171 if k == FA_EG_UPSHARE { return "eye_upshare" as *u8 }
172 if k == FA_EG_DTILT { return "eye_dtilt" as *u8 }
173 return "eye_dopen" as *u8
174}
175func fa_eye_gene_lo(k: i64) -> i64 {
176 if k == FA_EG_TILT { return FA_EG_TILT_LO }
177 if k == FA_EG_OPEN { return FA_EG_OPEN_LO }
178 if k == FA_EG_WIDTH { return FA_EG_WIDTH_LO }
179 if k == FA_EG_UPSHARE { return FA_EG_UPSHARE_LO }
180 if k == FA_EG_DTILT { return FA_EG_DTILT_LO }
181 return FA_EG_DOPEN_LO
182}
183func fa_eye_gene_hi(k: i64) -> i64 {
184 if k == FA_EG_TILT { return FA_EG_TILT_HI }
185 if k == FA_EG_OPEN { return FA_EG_OPEN_HI }
186 if k == FA_EG_WIDTH { return FA_EG_WIDTH_HI }
187 if k == FA_EG_UPSHARE { return FA_EG_UPSHARE_HI }
188 if k == FA_EG_DTILT { return FA_EG_DTILT_HI }
189 return FA_EG_DOPEN_HI
190}
191// the canon value of each gene: what faceanat_build already emits, so applying the canon vector changes nothing
192func fa_eye_gene_canon(k: i64) -> i64 {
193 if k == FA_EG_TILT { return FA_EG_TILT_CANON }
194 if k == FA_EG_OPEN { return FA_EG_PCT_CANON }
195 if k == FA_EG_WIDTH { return FA_EG_PCT_CANON }
196 if k == FA_EG_UPSHARE { return FA_LID_UP * FA_EG_PERMIL / (FA_LID_UP + FA_LID_LOW) }
197 return 0
198}
199// one lid shell: opening width and height by percent of what it carries now (so a size morph applied before or after
200// composes), the upper share of that height, and its roll from a tilt in deg10 (sign is the caller's: positive raises +x)
201func fa_eye_apply(base: i64, idx: i64, roll_deg10: i64, open_pct: i64, width_pct: i64, upshare: i64) -> i64 {
202 let halfw: i64 = sdf_get_prim(base, idx, SDF_PR_HALFW) * width_pct / FA_EG_PCT_CANON
203 let h: i64 = (sdf_get_prim(base, idx, SDF_PR_UP) + sdf_get_prim(base, idx, SDF_PR_LOW)) * open_pct / FA_EG_PCT_CANON
204 let up: i64 = (h * upshare + FA_EG_PERMIL / 2) / FA_EG_PERMIL // rounded: the canon share must give the canon rise back exactly
205 sdf_set_prim(base, idx, SDF_PR_HALFW, halfw)
206 sdf_set_prim(base, idx, SDF_PR_UP, up)
207 sdf_set_prim(base, idx, SDF_PR_LOW, h - up)
208 sdf_set_roll(base, idx, roll_deg10 * IT_PI / FA_EG_DEG10_HALF_TURN)
209 return 0
210}
211// all six genes onto both eyes. The differences split around the shared value (right takes the larger half, so the pair
212// always sums to the gene), and the left eye's roll is mirrored because its lateral end is its -x end
213func faceanat_eye_genes(base: i64, eg: *i64) -> i64 {
214 let dt_r: i64 = eg[FA_EG_DTILT] - eg[FA_EG_DTILT] / 2
215 let dt_l: i64 = eg[FA_EG_DTILT] / 2
216 let do_r: i64 = eg[FA_EG_DOPEN] - eg[FA_EG_DOPEN] / 2
217 let do_l: i64 = eg[FA_EG_DOPEN] / 2
218 fa_eye_apply(base, FA_LID_R, eg[FA_EG_TILT] + dt_r, eg[FA_EG_OPEN] + do_r, eg[FA_EG_WIDTH], eg[FA_EG_UPSHARE])
219 fa_eye_apply(base, FA_LID_L, 0 - (eg[FA_EG_TILT] - dt_l), eg[FA_EG_OPEN] - do_l, eg[FA_EG_WIDTH], eg[FA_EG_UPSHARE])
220 return 0
221}
222// one lip sweep's primitive slots: the arch, the taper, the cupid's bow (a dip and its half-width; zero on a lower lip), the
223// seam's curve at the commissure and which side of the seam this lip keeps
224func fa_lip_prims(base: i64, idx: i64, bow: i64, bow_hw: i64, side: i64) -> i64 {
225 sdf_set_prim(base, idx, SDF_PL_ARCH, FA_LIP_ARCH)
226 sdf_set_prim(base, idx, SDF_PL_TAPER, FA_LIP_TAPER)
227 sdf_set_prim(base, idx, SDF_PL_NOTCH, bow)
228 sdf_set_prim(base, idx, SDF_PL_NOTCH_HW, bow_hw)
229 sdf_set_prim(base, idx, SDF_PL_CURVE, 0)
230 sdf_set_prim(base, idx, SDF_PL_SIDE, side)
231 return 0
232}
233// the lip prims that are LENGTHS scale with the face; the permil ones (taper, the bow's dip and half-width) and the side do not
234func fa_scale_lip_prims(base: i64, idx: i64, pct: i64) -> i64 {
235 sdf_set_prim(base, idx, SDF_PL_ARCH, sdf_get_prim(base, idx, SDF_PL_ARCH) * pct / 100)
236 sdf_set_prim(base, idx, SDF_PL_CURVE, sdf_get_prim(base, idx, SDF_PL_CURVE) * pct / 100)
237 return 0
238}
239func faceanat_build(base: i64) -> i64 {
240 let p: *i64 = (base + O_PARTS) as *i64
241 let kb: *i64 = (base + O_KBLEND) as *i64; kb[0] = 18
242 // 27 -> 33: the two lid shells and the four orbital fills below. PARTS_CAP is 48, so this is inside the arena and no
243 // offset moves; the parts were written BEFORE this count was raised so no intermediate state ever
244 // declared a part it had not filled -- an unwritten slot is a zero-radius ellipsoid, not a no-op.
245 let nb: *i64 = (base + O_NPART) as *i64; nb[0] = FA_NPARTS
246 sdf_clear_ops(base, FA_NPARTS)
247 sdf_set_floor(base, 0)
248 sdf_set_mtx_amp(base, 0)
249 var i: i64 = 0
250 // 0 CRANIUM: the bony skull mass (widest at the parietal/temporal). Fifths width -> half 525.
251 p[i]=0; p[i+1]=120; p[i+2]=0; p[i+3]=520; p[i+4]=760; p[i+5]=615; i=i+6
252 // 1 FOREHEAD (frontal bone; tissue ~4.5mm, shallow -> follows bone). Upper third.
253 p[i]=0; p[i+1]=425; p[i+2]=fa_tissue_z(0-360, 45); p[i+3]=420; p[i+4]=285; p[i+5]=315; i=i+6
254 // 2 JAW (mandible body; gonial tissue ~14mm but the body is narrow in a female). Lower third, fifths-narrow.
255 p[i]=0; p[i+1]=0-375; p[i+2]=fa_tissue_z(0-150, 90); p[i+3]=315; p[i+4]=335; p[i+5]=380; i=i+6
256 // 3 CHIN (mental eminence; tissue ~11mm). Gnathion at y-676.
257 p[i]=0; p[i+1]=0-540; p[i+2]=fa_tissue_z(0-300, 110); p[i+3]=175; p[i+4]=170; p[i+5]=245; i=i+6
258 // 4 NASAL BRIDGE (nasion/rhinion; tissue VERY shallow ~2.5-4mm -> the skin hugs bone = the nose ridge).
259 p[i]=0; p[i+1]=105; p[i+2]=fa_tissue_z(0-600, 30); p[i+3]=80; p[i+4]=205; p[i+5]=225; i=i+6
260 // 5 NASAL TIP (pronasale; cartilage, projects most). Subnasale y~-150.
261 p[i]=0; p[i+1]=0-120; p[i+2]=fa_tissue_z(0-660, 60); p[i+3]=86; p[i+4]=100; p[i+5]=150; i=i+6
262 // 6/7 CHEEKBONE (zygomatic; bone-point tissue ~10mm but SURFACE-EFFECTIVE malar relief ~7mm once the soft
263 // tissue smooths the bony point; rule-of-fifths puts the prominence narrower than the face edge). Below+lateral.
264 p[i]=0-315; p[i+1]=15; p[i+2]=fa_tissue_z(0-400, 70); p[i+3]=175; p[i+4]=250; p[i+5]=180; i=i+6
265 p[i]=315; p[i+1]=15; p[i+2]=fa_tissue_z(0-400, 70); p[i+3]=175; p[i+4]=250; p[i+5]=180; i=i+6
266 // 8/9 BROW RIDGE (supraorbital; tissue ~7mm over the ridge, female = LOW ridge). At glabella line.
267 p[i]=0-250; p[i+1]=322; p[i+2]=fa_tissue_z(0-560, 70); p[i+3]=225; p[i+4]=42; p[i+5]=86; i=i+6
268 p[i]=250; p[i+1]=322; p[i+2]=fa_tissue_z(0-560, 70); p[i+3]=225; p[i+4]=42; p[i+5]=86; i=i+6
269 // 10/11 LIPS (AT43): the upper and the lower LIP SWEEP, both at the stomion (the unit's constants above)
270 p[i]=0; p[i+1]=FA_STOMION_Y; p[i+2]=FA_LIP_AXIS_Z_U; p[i+3]=FA_LIP_HALFW_U; p[i+4]=FA_LIP_H_U; p[i+5]=FA_LIP_D_U; i=i+6
271 p[i]=0; p[i+1]=FA_STOMION_Y; p[i+2]=FA_LIP_AXIS_Z_L; p[i+3]=FA_LIP_HALFW_L; p[i+4]=FA_LIP_H_L; p[i+5]=FA_LIP_D_L; i=i+6
272 // 12/13 EARS (external; at the skull side, y ~ eye line, z ~ mid). Fifths: ears frame fifths 1 & 5.
273 p[i]=0-545; p[i+1]=20; p[i+2]=40; p[i+3]=75; p[i+4]=235; p[i+5]=130; i=i+6
274 p[i]=545; p[i+1]=20; p[i+2]=40; p[i+3]=75; p[i+4]=235; p[i+5]=130; i=i+6
275 // 14/15 TEMPLE (temporal fossa; tissue THIN + bone RECESSED -> the temples sit BACK, not proud). +z (back).
276 p[i]=0-505; p[i+1]=320; p[i+2]=fa_tissue_z(0-200, 30); p[i+3]=150; p[i+4]=300; p[i+5]=260; i=i+6
277 p[i]=505; p[i+1]=320; p[i+2]=fa_tissue_z(0-200, 30); p[i+3]=150; p[i+4]=300; p[i+5]=260; i=i+6
278 // 16/17 CARVE eye sockets (orbits; the eye SITS IN a bony hole -> concavity). Fifths 2 & 4, eye line.
279 p[i]=0-258; p[i+1]=180; p[i+2]=0-650; p[i+3]=148; p[i+4]=118; p[i+5]=235; i=i+6
280 p[i]=258; p[i+1]=180; p[i+2]=0-650; p[i+3]=148; p[i+4]=118; p[i+5]=235; i=i+6
281 // 18/19 EYEBALLS (globe seated in the orbit; sclera/iris/pupil material).
282 p[i]=0-258; p[i+1]=178; p[i+2]=0-560; p[i+3]=94; p[i+4]=94; p[i+5]=104; i=i+6
283 p[i]=258; p[i+1]=178; p[i+2]=0-560; p[i+3]=94; p[i+4]=94; p[i+5]=104; i=i+6
284 // 20 CARVE the oral fissure: since AT43 a thin SEAM between the two sweeps (they meet flat at the stomion; the carve gives
285 // the line its shadow), no longer the slot that had to separate two overlapping ellipsoids. 21/22 CARVE nostrils.
286 // Its DEPTH is the AT16 carve's (back at z -490): the stomion must stay the most recessed midline point between the nose and
287 // the chin, which is what the lip-ratio ruler anchors on; only its HEIGHT shrinks (34 -> 8) to a seam.
288 p[i]=0; p[i+1]=FA_STOMION_Y; p[i+2]=0-600; p[i+3]=FA_LIP_HALFW_L; p[i+4]=8; p[i+5]=110; i=i+6
289 p[i]=0-64; p[i+1]=0-210; p[i+2]=0-745; p[i+3]=46; p[i+4]=52; p[i+5]=80; i=i+6
290 p[i]=64; p[i+1]=0-210; p[i+2]=0-745; p[i+3]=46; p[i+4]=52; p[i+5]=80; i=i+6
291 // 23 HAIR crown cap. 24 nape.
292 p[i]=0; p[i+1]=438; p[i+2]=180; p[i+3]=665; p[i+4]=700; p[i+5]=700; i=i+6
293 p[i]=0; p[i+1]=0-80; p[i+2]=430; p[i+3]=520; p[i+4]=430; p[i+5]=330; i=i+6
294 // 25/26 RESERVED. These were the upper lash BARS: a dark ellipsoid floating 40 units in front of each lid, which read as a
295 // visor and gave every dark-pixel eye finder a false upper edge. The lash line is now the upper lid margin's own material
296 // band (sdf_lid_lash in the renderer). The slots stay so no later part index moves; they sit inside the cranium, unseen.
297 p[i]=0-60; p[i+1]=120; p[i+2]=0; p[i+3]=10; p[i+4]=10; p[i+5]=10; i=i+6
298 p[i]=60; p[i+1]=120; p[i+2]=0; p[i+3]=10; p[i+4]=10; p[i+5]=10; i=i+6
299 // 27/28 THE LID SHELLS (AT39): centre = the globe centre, fields = inner radius, thickness, cap reach. The opening, its
300 // tilt and the crisp margin blend are set below with the ops. They replace the four ellipsoid lids of AT16.
301 p[i]=0-FA_EYE_CX; p[i+1]=FA_EYE_CY; p[i+2]=FA_EYE_CZ; p[i+3]=FA_LID_RIN; p[i+4]=FA_LID_T; p[i+5]=FA_LID_CAP; i=i+6
302 p[i]=FA_EYE_CX; p[i+1]=FA_EYE_CY; p[i+2]=FA_EYE_CZ; p[i+3]=FA_LID_RIN; p[i+4]=FA_LID_T; p[i+5]=FA_LID_CAP; i=i+6
303 // 29/30 UPPER and 31/32 LOWER ORBITAL FILLS: the soft tissue that carries the lid skin up to the brow and down to the cheek.
304 // They are the AT16 lid ellipsoids moved clear of the opening (upper lower-edge 292-60=232 above the opening top 228, lower
305 // upper-edge 72+68=140 below the opening bottom 142), set back behind the lid front so the surround slopes to the brow and the
306 // cheek instead of bulging, and they never define the aperture.
307 p[i]=0-250; p[i+1]=292; p[i+2]=0-600; p[i+3]=132; p[i+4]=60; p[i+5]=66; i=i+6
308 p[i]=250; p[i+1]=292; p[i+2]=0-600; p[i+3]=132; p[i+4]=60; p[i+5]=66; i=i+6
309 p[i]=0-266; p[i+1]=72; p[i+2]=0-596; p[i+3]=150; p[i+4]=68; p[i+5]=64; i=i+6
310 p[i]=266; p[i+1]=72; p[i+2]=0-596; p[i+3]=150; p[i+4]=68; p[i+5]=64; i=i+6
311 // 33/34 PERIORAL MOUND (AT43): the orbicularis oris and the alveolar process the lips sit on -- the UPPER part carries the
312 // cutaneous upper lip (the philtrum) from the subnasale down to the vermilion, the LOWER part the skin below the lower lip,
313 // so each vermilion stands a little proud of skin instead of being a ridge on a cliff. TWO parts with a GAP at the seam, and
314 // that gap is load-bearing: parts apply in index order, so any union appended after the mouth-slit carve (part 20) REFILLS
315 // the slit -- MEASURED on the first cut, a single mound put the stomion at z -654 instead of behind -490 and the lip-ratio
316 // ruler could find no stomion at all. Appended: no earlier part index moves.
317 p[i]=0; p[i+1]=0-297; p[i+2]=0-510; p[i+3]=190; p[i+4]=78; p[i+5]=150; i=i+6
318 p[i]=0; p[i+1]=0-470; p[i+2]=0-505; p[i+3]=165; p[i+4]=55; p[i+5]=135; i=i+6
319 // the lip unit's ops and shape (AT43)
320 sdf_set_op(base, FA_LIP_U, SDF_OP_LIPSWEEP)
321 sdf_set_op(base, FA_LIP_L, SDF_OP_LIPSWEEP)
322 fa_lip_prims(base, FA_LIP_U, FA_LIP_BOW_PERMIL, FA_LIP_BOW_HW, FA_LIP_UP_SIDE)
323 fa_lip_prims(base, FA_LIP_L, 0, 0, FA_LIP_DOWN_SIDE)
324 sdf_set_kb(base, FA_LIP_U, FA_LIP_K)
325 sdf_set_kb(base, FA_LIP_L, FA_LIP_K)
326 sdf_set_op(base, 16, 1)
327 sdf_set_op(base, 17, 1)
328 sdf_set_op(base, 20, 1)
329 sdf_set_op(base, 21, 1)
330 sdf_set_op(base, 22, 1)
331 sdf_set_mat(base, 18, 1)
332 sdf_set_mat(base, 19, 1)
333 sdf_set_mat(base, 23, 2)
334 sdf_set_mat(base, 24, 2)
335 sdf_set_mat(base, 8, 3)
336 sdf_set_mat(base, 9, 3)
337 sdf_set_mat(base, 25, 4)
338 sdf_set_mat(base, 26, 4)
339 sdf_set_rot(base, 4, 0 - 300) // nasal bridge slopes forward-down (a real ridge)
340 // the eye units: op, opening, tilt (mirrored: positive roll raises the +x end, and the lateral end of the left eye is -x)
341 sdf_set_op(base, FA_LID_L, SDF_OP_LIDSHELL)
342 sdf_set_op(base, FA_LID_R, SDF_OP_LIDSHELL)
343 sdf_set_prim(base, FA_LID_L, SDF_PR_HALFW, FA_LID_HALFW); sdf_set_prim(base, FA_LID_L, SDF_PR_UP, FA_LID_UP); sdf_set_prim(base, FA_LID_L, SDF_PR_LOW, FA_LID_LOW)
344 sdf_set_prim(base, FA_LID_R, SDF_PR_HALFW, FA_LID_HALFW); sdf_set_prim(base, FA_LID_R, SDF_PR_UP, FA_LID_UP); sdf_set_prim(base, FA_LID_R, SDF_PR_LOW, FA_LID_LOW)
345 sdf_set_roll(base, FA_LID_L, 0 - FA_EG_TILT_CANON * IT_PI / FA_EG_DEG10_HALF_TURN)
346 sdf_set_roll(base, FA_LID_R, FA_EG_TILT_CANON * IT_PI / FA_EG_DEG10_HALF_TURN)
347 sdf_set_kb(base, FA_LID_L, FA_LID_K)
348 sdf_set_kb(base, FA_LID_R, FA_LID_K)
349 // the fills blend SOFTLY (the lid margin is crisp, the lid-to-cheek and lid-to-brow transitions are not)
350 sdf_set_kb(base, FA_FILL_UP_L, FA_FILL_K_UP); sdf_set_kb(base, FA_FILL_UP_R, FA_FILL_K_UP)
351 sdf_set_kb(base, FA_FILL_LOW_L, FA_FILL_K_LOW); sdf_set_kb(base, FA_FILL_LOW_R, FA_FILL_K_LOW)
352 return 0
353}
354
355// ★B-R6 PARAMETRIC MORPH BASIS (operator: our own base mesh better than DAZ). Because the face is DERIVED from
356// numbers, a "morph" is a DELTA on those numbers -- the FLAME/SMPL 'learned basis' built PARAMETRICALLY from
357// anatomy. Each morph mutates the emitted parts AFTER faceanat_build; pct=100 is neutral; they COMPOSE. These
358// are real anthropometric axes (unlike DAZ's fixed artist-sculpt morphs, these are adjustable + measured).
359// ★UNIFORM SCALE of the whole face (all 6 fields per part + the global blend radius). Used by the hi-res mesh
360// rung: scale the object UP to fill the fixed meshgen grid -> many more surface-nets cells across it -> a
361// denser mesh at the SAME grid resolution (then scale the verts back down). Free resolution, no meshgen change.
362func faceanat_scale(base: i64, pct: i64) -> i64 {
363 let p: *i64 = (base + O_PARTS) as *i64
364 let nb: *i64 = (base + O_NPART) as *i64
365 var i: i64 = 0
366 while i < nb[0] {
367 p[i*6] = p[i*6] * pct / 100; p[i*6+1] = p[i*6+1] * pct / 100; p[i*6+2] = p[i*6+2] * pct / 100
368 p[i*6+3] = p[i*6+3] * pct / 100; p[i*6+4] = p[i*6+4] * pct / 100; p[i*6+5] = p[i*6+5] * pct / 100
369 i = i + 1
370 }
371 let kb: *i64 = (base + O_KBLEND) as *i64
372 if kb[0] > 0 { kb[0] = kb[0] * pct / 100 }
373 fa_scale_prim(base, FA_LID_L, pct)
374 fa_scale_prim(base, FA_LID_R, pct)
375 fa_scale_lip_prims(base, FA_LIP_U, pct)
376 fa_scale_lip_prims(base, FA_LIP_L, pct)
377 return 0
378}
379// scale field f of part idx about pivot 0 (symmetric-safe): v' = v*pct/100
380func fa_scale(base: i64, idx: i64, field: i64, pct: i64) -> i64 {
381 let p: *i64 = (base + O_PARTS) as *i64
382 p[idx*6+field] = p[idx*6+field] * pct / 100
383 return 0
384}
385// FACE WIDTH: scale every part's cx (position) AND rx (feature width) about x=0 -> a genuinely wider/narrower
386// face (wider-set AND wider features), symmetry preserved.
387func faceanat_morph_width(base: i64, pct: i64) -> i64 {
388 let p: *i64 = (base + O_PARTS) as *i64
389 let nb: *i64 = (base + O_NPART) as *i64
390 var i: i64 = 0
391 // an eye unit MOVES with the face and keeps its size (AT39): a wider face sets its eyes wider apart, it does not stretch
392 // the globe into an ellipse or the lid shell off the globe it wraps
393 while i < nb[0] { p[i*6] = p[i*6] * pct / 100; if fa_is_eye_unit(i) == 0 { p[i*6+3] = p[i*6+3] * pct / 100 } i = i + 1 }
394 return 0
395}
396// FACE LENGTH: scale every part's cy (position) AND ry (feature height) about y=0 -> longer/shorter face.
397func faceanat_morph_length(base: i64, pct: i64) -> i64 {
398 let p: *i64 = (base + O_PARTS) as *i64
399 let nb: *i64 = (base + O_NPART) as *i64
400 var i: i64 = 0
401 while i < nb[0] { p[i*6+1] = p[i*6+1] * pct / 100; if fa_is_eye_unit(i) == 0 { p[i*6+4] = p[i*6+4] * pct / 100 } i = i + 1 }
402 return 0
403}
404// JAW/CHIN width (parts 2 jaw, 3 chin rx) -> strong vs soft jaw.
405func faceanat_morph_jaw(base: i64, pct: i64) -> i64 { fa_scale(base,2,3,pct); fa_scale(base,3,3,pct); return 0 }
406// EYE size: eyeballs 18/19 + sockets 16/17 + lashes 25/26 (rx,ry,rz) -> bigger/smaller eyes (youthful axis).
407func faceanat_morph_eyes(base: i64, pct: i64) -> i64 {
408 fa_scale(base,16,3,pct); fa_scale(base,16,4,pct); fa_scale(base,17,3,pct); fa_scale(base,17,4,pct)
409 fa_scale(base,18,3,pct); fa_scale(base,18,4,pct); fa_scale(base,18,5,pct)
410 fa_scale(base,19,3,pct); fa_scale(base,19,4,pct); fa_scale(base,19,5,pct)
411 fa_scale(base,25,3,pct); fa_scale(base,26,3,pct)
412 // the lid shells are part of the eye: inner radius, thickness, cap reach and the opening all scale with the globe they wrap
413 fa_scale(base,FA_LID_L,3,pct); fa_scale(base,FA_LID_L,4,pct); fa_scale(base,FA_LID_L,5,pct)
414 fa_scale(base,FA_LID_R,3,pct); fa_scale(base,FA_LID_R,4,pct); fa_scale(base,FA_LID_R,5,pct)
415 fa_scale_prim(base, FA_LID_L, pct)
416 fa_scale_prim(base, FA_LID_R, pct)
417 return 0
418}
419// LIP fullness (parts 10 upper, 11 lower ry).
420func faceanat_morph_lips(base: i64, pct: i64) -> i64 { fa_scale(base,10,4,pct); fa_scale(base,11,4,pct); return 0 }
421// LIP RATIO -- the DIFFERENTIAL morph faceanat_morph_lips structurally cannot be (measured 2026-08-29:
422// it applies ONE pct to both parts, so the upper:lower ratio is INVARIANT under it, and the canon's own
423// lip_upper_over_lower target row was unexpressible by the only lips morph that existed -- a steering
424// axis the generator could not steer). This one scales the two vermilions in OPPOSITE directions about
425// the same total: upper by pct, lower by its reciprocal about 100, so fullness stays roughly constant
426// while the RATIO moves -- one knob per canon row, orthogonal to the fullness knob beside it, which is
427// what lets a sampler draw the two independently. ADDITIVE on purpose: faceanat_morph_lips keeps its
428// exact incumbent semantics because the morph gate's banked baselines compose it.
429func faceanat_morph_lipratio(base: i64, pct: i64) -> i64 {
430 if pct <= 0 { return 0 - 1 }
431 fa_scale(base, 10, 4, pct)
432 fa_scale(base, 11, 4, 100 * 100 / pct)
433 return 0
434}
435// NOSE length (bridge 4 ry + tip 5 cy toward the tip).
436func faceanat_morph_nose(base: i64, pct: i64) -> i64 { fa_scale(base,4,4,pct); fa_scale(base,5,4,pct); return 0 }
437// CHEEKBONE prominence (parts 6/7 rz depth = how proud the malar reads).
438func faceanat_morph_cheek(base: i64, pct: i64) -> i64 { fa_scale(base,6,5,pct); fa_scale(base,7,5,pct); return 0 }
439
440// ---------------------------------------------------------------------------------------------
441// fa_expr_morph -- THE ONE NAMED ENTRY POINT for expression morphing, dispatching on the SAME
442// channel indices the NXA MORF section declares (nx_nxa_morf: 0 WIDT, 1 LENG, 2 EYES, 3 NOSE,
443// 4 CHEK, 5 LIPS, 6 JAW). Before this, a caller wanting an expression had to know which of seven
444// differently-named functions to reach for, and the mesh path and the SDF path numbered their
445// channels independently -- two vocabularies for one set of morphs, which is how they drift.
446// One meaning, one number: this function IS the shared channel vocabulary.
447//
448// WARNING, AND IT IS NOT UNIFIED ON PURPOSE: pct here is the faceanat PERCENT convention, where
449// 100 means UNCHANGED (fa_scale multiplies by pct/100). The MORF section uses the estate's PERMIL
450// weight convention, where 0 means unchanged and 1000 applies the full stored displacement. These
451// are different quantities with different identities, so they are NOT silently merged: a caller
452// converting between them must do it deliberately. Collapsing them would make 0 mean "unchanged"
453// in one path and "collapse the face to a point" in the other.
454// Returns 0 on success, -1 for an unknown channel (never a silent no-op).
455func fa_expr_morph(base: i64, chan: i64, pct: i64) -> i64 {
456 if chan == 0 { return faceanat_morph_width(base, pct) }
457 if chan == 1 { return faceanat_morph_length(base, pct) }
458 if chan == 2 { return faceanat_morph_eyes(base, pct) }
459 if chan == 3 { return faceanat_morph_nose(base, pct) }
460 if chan == 4 { return faceanat_morph_cheek(base, pct) }
461 if chan == 5 { return faceanat_morph_lips(base, pct) }
462 if chan == 6 { return faceanat_morph_jaw(base, pct) }
463 return 0 - 1
464}
465
466// ============================================================================
467// AT4 (aesthetictwin rung), THE HALF THAT IS BUILDABLE TODAY: LIP VERMILION
468// HEIGHTS AND THE UPPER-TO-LOWER RATIO, READ FROM THE BLENDED SURFACE.
469//
470// THE DONE-RULE SAYS "read from mesh landmarks and NOT from slider positions",
471// and that distinction is the whole rung. The estate's existing
472// nx_faceprofile_gate reads lip depth as p[10*6+2] -- straight out of the part
473// table -- which is a SLIDER READ-BACK: it returns whatever was dialled in and
474// can never disagree with it, so it cannot see a lip the blend has swallowed, a
475// lip buried under a neighbouring part, or a carve that ate the vermilion. This
476// function marches the SDF along the facial midline and measures the surface
477// that is actually there, so a geometry that does not match its own parameters
478// is a difference this can report and that one cannot.
479//
480// THE PROFILE LANDMARKS ARE TURNING POINTS. Walking the midline from the nose
481// base to the chin, the surface profile z(y) alternates between protruding and
482// receding, and these are EXTREMA of that profile rather than level crossings:
483// stomion -- the deepest recession between nose and chin: the oral fissure
484// upper peak -- the proudest point above it: the front of the upper lip
485// lower peak -- the proudest point below it: the front of the lower lip
486// upper sulcus -- the recession above the upper peak (superior labial sulcus)
487// lower sulcus -- the recession below the lower peak: the mentolabial sulcus
488//
489// THE BORDERS ARE NOT TURNING POINTS, AND THE FIRST DRAFT SAID THEY WERE. The
490// canon's ratio (knowledge/facecanon.conf upper_over_lower_lip) is labrale-
491// superius-to-stomion over stomion-to-labrale-inferius, and labrale superius /
492// inferius are the midpoints of the VERMILION LINES -- where the red lip meets
493// the skin. In a real profile the first recession below the lower lip is the
494// mentolabial sulcus, several millimetres BELOW labrale inferius, so a ruler
495// that read the lower border as a turning point measured a different landmark
496// than the canon it was compared with, and on a face without a chin it read
497// nothing at all (MEASURED 2026-09-18: the midline recedes monotonically from
498// the lower lip to -692, reason NO_SULCUS_IN_BAND on every build). The borders
499// are therefore read as the VERMILION EDGE AT THE SURFACE: at each surface point
500// the march found, the renderer's own vermilion field (sdf_lip_vermilion, the
501// function that colours those pixels) says whether that point is lip, and the
502// border is where that answer changes. Its level is the fade's own midpoint
503// (SDF_LIP_FULL / 2), the definition of an edge in a fade, not a tuned depth.
504// The sulci stay published beside it: they are real landmarks with a canon of
505// their own (mentolabial_sulcus_depth), measured and reported, never used as a
506// vermilion border.
507//
508// VERMILION HEIGHTS are border-to-stomion on each side; the ratio is upper to
509// lower in permil (canon 625, band 625..1000).
510//
511// UNMEASURED IS A REAL ANSWER AND IT IS NOT ZERO -- and here it is REACHABLE
512// rather than decorative: flatten the lips and the profile has no interior
513// protrusion peak, the search lands on a band edge, and this refuses. That is
514// exactly the negative control the rung asks for, and it is why the peaks are
515// checked against the edges instead of being trusted.
516// ============================================================================
517const FA_LIP_UNMEASURED: i64 = 0 - 1
518const FA_LIP_Y_TOP: i64 = 0 - 180
519// THE BAND BOTTOM IS -640 BECAUSE THAT IS WHERE THE EXTRACTION IS VERIFIED, and
520// not because it is anatomically generous. Widening it to -692, to try to bring
521// the mentolabial sulcus inside the window, made the whole measure refuse --
522// and the profile dump then showed BOTH candidate causes are real, which is why
523// the wider band cannot be rescued. MEASURED down the midline: z reads -706 at
524// y=-440, then -698, -672, -590, -568, -514 and -450 at y=-692 -- MONOTONICALLY
525// RECEDING from the lower lip peak with no turning point anywhere, so (1) this
526// geometry HAS NO MENTOLABIAL SULCUS and no band would ever find one, and (2) at
527// -692 the surface sits at -450, more receded than the stomion's -492, so the
528// extra rows also capture the stomion search, which WAS a global maximum over the
529// band (since 2026-09-18 it takes the deepest INTERIOR recession, so an edge can
530// no longer win it -- see fa_lip_ratio). The narrower band is therefore not a compromise but the correct window:
531// its landmarks ARE verified, the stomion it finds agreeing to 2 units with the
532// carve parameter that created it, by an independent route. THE CONSEQUENCE IS DECLARED RATHER THAN HIDDEN: the lower border can
533// legitimately fall below this window, and when it does the lower vermilion
534// height is reported UNMEASURED with a named reason instead of being silently
535// measured against the window edge -- which is exactly what the first draft did.
536const FA_LIP_Y_BOT: i64 = 0 - 640
537const FA_LIP_YSTEP: i64 = 4
538const FA_LIP_N: i64 = 116
539const FA_LIP_Z_START: i64 = 0 - 1000
540const FA_LIP_Z_END: i64 = 200
541const FA_LIP_ZSTEP: i64 = 2
542const FA_LIP_NOSURF: i64 = 999999
543const FA_LIP_PERMIL: i64 = 1000
544const FA_LIP_O_RATIO: i64 = 0
545const FA_LIP_O_UPPER_H: i64 = 1
546const FA_LIP_O_LOWER_H: i64 = 2
547const FA_LIP_O_STOMION: i64 = 3
548const FA_LIP_O_UPBORDER: i64 = 4
549const FA_LIP_O_LOBORDER: i64 = 5
550const FA_LIP_O_UPPEAK: i64 = 6
551const FA_LIP_O_LOPEAK: i64 = 7
552// A REFUSAL THAT CANNOT NAME WHICH LANDMARK WAS MISSING WILL BE READ AS THE MOST
553// ALARMING ONE AVAILABLE. These make the abstention specific, so a caller can tell
554// "this face has no lips" from "this face is not in the sampled band" from "the
555// crease that bounds this vermilion is out of the window" -- three states with
556// three different remedies that a bare -1 collapses into one.
557const FA_LIP_O_REASON: i64 = 8
558// the two profile sulci (turning points beyond each peak), published beside the borders and never used as one; -1 = the
559// profile does not turn inside the band on that side
560const FA_LIP_O_UPSULCUS: i64 = 9
561const FA_LIP_O_LOSULCUS: i64 = 10
562const FA_LIP_O_FIELDS: i64 = 11
563const FA_LIP_R_OK: i64 = 0
564const FA_LIP_R_NOSURF: i64 = 1
565const FA_LIP_R_NO_STOMION: i64 = 2
566const FA_LIP_R_NO_UPPER_PEAK: i64 = 3
567const FA_LIP_R_NO_LOWER_PEAK: i64 = 4
568// 5 and 6 named the turning-point borders of the first draft; kept so no reader's number changes meaning, no longer emitted
569const FA_LIP_R_NO_PHILTRAL_CREASE: i64 = 5
570const FA_LIP_R_NO_SULCUS_IN_BAND: i64 = 6
571const FA_LIP_R_NO_VERMILION_FIELD: i64 = 7 // the body declares no lip sweep, so there is no vermilion line to find
572const FA_LIP_R_NO_UPPER_VERMILION: i64 = 8 // walking up from the stomion the surface never enters the upper vermilion
573const FA_LIP_R_NO_LOWER_VERMILION: i64 = 9 // walking down from the stomion the surface never enters the lower vermilion
574const FA_LIP_R_VERMILION_PAST_BAND: i64 = 10 // a vermilion runs off the sampled band: its border is the window, not a landmark
575const FA_LIP_SLACK: i64 = 16
576
577// March the midline (x = 0) from in front of the face inward and return the z of
578// the first surface crossing. -z is toward the camera, so a SMALLER z is MORE
579// proud. Returns FA_LIP_NOSURF when the ray never enters the body: that is a
580// real answer and a caller must not read it as a very recessed surface.
581// GENERALISED OFF THE MIDLINE FOR AT16. The palpebral fissure is an OFF-MIDLINE feature, so a
582// marcher hard-coded to x=0 structurally cannot see it. The march is EXTRACTED here rather than
583// re-typed beside it, so this file keeps exactly ONE ray-marcher and the two entry points can never
584// drift apart -- a bug fixed by rewriting a line instead of extracting it is a bug you write again.
585func fa_surface_z(base: i64, x: i64, y: i64) -> i64 {
586 var z: i64 = FA_LIP_Z_START
587 while z < FA_LIP_Z_END {
588 if sdf_eval(base, x, y, z) <= 0 { return z }
589 z = z + FA_LIP_ZSTEP
590 }
591 return FA_LIP_NOSURF
592}
593
594func fa_midline_z(base: i64, y: i64) -> i64 { return fa_surface_z(base, 0, y) }
595
596// THE VERMILION EDGE ON ONE SIDE OF THE STOMION. Walk the surface samples from the stomion in direction dir (-1 up the face, +1
597// down), first INTO the vermilion and then to where it ends. The stomion sample itself is NOT lip -- it is the bottom of the slit,
598// behind both lips -- so a walk that stopped at the first non-lip sample would stop where it started. Returns the band index of the
599// last sample inside the vermilion, FA_LIP_EDGE_NEVER when the walk never entered it, FA_LIP_EDGE_PAST when it ran off the band
600// still inside (the border would then be the window, not a landmark).
601// THE LEVEL IS "ANY VERMILION", NOT THE FADE'S MIDPOINT, AND THE FIRST CUT HAD IT WRONG. The renderer fades the lip colour over
602// SDF_LIP_EDGE units lying wholly INSIDE the outline, so its half level sits half a fade inside the vermilion line; MEASURED
603// 2026-09-18, the half level read the canon face's upper border 3 units inside the stated line and, with the stomion's own
604// half-step offset, reported 589 permil for a face built at 628 -- below the canon's 625 floor, a false alarm manufactured by the
605// ruler's choice of level. The vermilion line is where the field ENDS; the fade is rendering, not anatomy.
606const FA_LIP_EDGE_NEVER: i64 = 0 - 1
607const FA_LIP_EDGE_PAST: i64 = 0 - 2
608const FA_LIP_REFINE_STEP: i64 = 1 // one model unit: the landmarks are refined to the grid the part numbers themselves live on
609func fa_lip_vermilion_edge(base: i64, ys: *i64, zs: *i64, si: i64, dir: i64) -> i64 {
610 var k: i64 = si
611 var inside: i64 = 0
612 var last: i64 = FA_LIP_EDGE_NEVER
613 var go: i64 = 1
614 while go == 1 {
615 if k < 0 { go = 0 }
616 if k >= FA_LIP_N { go = 0 }
617 if go == 1 {
618 if sdf_lip_vermilion(base, 0, ys[k], zs[k]) > 0 { inside = 1; last = k }
619 else { if inside == 1 { return last } }
620 k = k + dir
621 }
622 }
623 if inside == 1 { return FA_LIP_EDGE_PAST }
624 return FA_LIP_EDGE_NEVER
625}
626// the border at unit resolution: from the last coarse sample inside the vermilion, step one unit at a time outward (dir -1 walks UP
627// the face, i.e. toward +y) to the first surface point the vermilion field does not reach -- the outline itself
628func fa_lip_border_refine(base: i64, y_in: i64, dir: i64) -> i64 {
629 var s: i64 = FA_LIP_REFINE_STEP
630 while s < FA_LIP_YSTEP {
631 let y: i64 = y_in - dir * s
632 let z: i64 = fa_midline_z(base, y)
633 if z == FA_LIP_NOSURF { return y }
634 if sdf_lip_vermilion(base, 0, y, z) <= 0 { return y }
635 s = s + FA_LIP_REFINE_STEP
636 }
637 return y_in - dir * FA_LIP_YSTEP // the coarse sample beyond, which the walk already saw outside
638}
639// the stomion at unit resolution: the deepest surface within one coarse step of the coarse stomion, and the CENTRE of that deepest
640// run -- a symmetric slit sampled on a coarse grid has two equal samples straddling its floor, and taking the first of them put the
641// stomion half a step off the floor on every build
642func fa_lip_stomion_refine(base: i64, y0: i64) -> i64 {
643 var zmax: i64 = FA_LIP_Z_START
644 var ytop: i64 = y0
645 var ybot: i64 = y0
646 var y: i64 = y0 + FA_LIP_YSTEP - FA_LIP_REFINE_STEP
647 while y > y0 - FA_LIP_YSTEP {
648 let z: i64 = fa_midline_z(base, y)
649 if z != FA_LIP_NOSURF {
650 if z > zmax { zmax = z; ytop = y; ybot = y } else { if z == zmax { ybot = y } }
651 }
652 y = y - FA_LIP_REFINE_STEP
653 }
654 return (ytop + ybot) / 2
655}
656
657func fa_lip_ratio(base: i64, out: *i64) -> i64 {
658 var f: i64 = 0
659 while f < FA_LIP_O_FIELDS { out[f] = FA_LIP_UNMEASURED; f = f + 1 }
660 let zs: *i64 = (sys_mmap(FA_LIP_N * 8 + FA_LIP_SLACK)) as *i64
661 let ys: *i64 = (sys_mmap(FA_LIP_N * 8 + FA_LIP_SLACK)) as *i64
662 var i: i64 = 0
663 while i < FA_LIP_N {
664 let y: i64 = FA_LIP_Y_TOP - i * FA_LIP_YSTEP
665 ys[i] = y
666 let z: i64 = fa_midline_z(base, y)
667 if z == FA_LIP_NOSURF { out[FA_LIP_O_REASON] = FA_LIP_R_NOSURF; return FA_LIP_UNMEASURED }
668 zs[i] = z
669 i = i + 1
670 }
671 // THE STOMION IS THE DEEPEST INTERIOR RECESSION, NOT THE DEEPEST SAMPLE. A global maximum over the band is won by the band's
672 // bottom edge on any face whose chin sits higher than the canon's -- MEASURED 2026-09-18 on the twin's seed-42 identity (length
673 // morph 96 percent): the under-chin recession at the window edge outranked the oral fissure and the ruler refused NO_STOMION on
674 // a face with a perfectly good mouth. A sample on the band edge is the window, never a landmark -- the law this ruler already
675 // applied to its peaks -- so only samples with a neighbour on each side compete; plateaus count, and the first deepest wins.
676 var si: i64 = 0 - 1
677 i = 1
678 while i < FA_LIP_N - 1 {
679 if zs[i] >= zs[i - 1] { if zs[i] >= zs[i + 1] {
680 if si < 0 { si = i } else { if zs[i] > zs[si] { si = i } }
681 } }
682 i = i + 1
683 }
684 if si < 0 { out[FA_LIP_O_REASON] = FA_LIP_R_NO_STOMION; return FA_LIP_UNMEASURED }
685 // THE LIP PEAKS ARE LOCAL EXTREMA AND A GLOBAL SEARCH FINDS THE WRONG FEATURE.
686 // A first draft took the most-proud point anywhere above the stomion and it
687 // landed on the NOSE, at the very top of the band, every time -- MEASURED: the
688 // midline reads z=-802 at y=-180 against z=-492 at the mouth, so the nose
689 // outranks the upper lip by 310 units and wins any global comparison. The
690 // profile then refused, correctly, because its peak sat on the window edge.
691 // Anatomically the vermilion peak is the FIRST turning point out from the
692 // stomion, not the biggest one in the neighbourhood, so these walk outward and
693 // stop where the profile turns. Plateaus are walked THROUGH (the comparison is
694 // non-strict) because an integer surface sampled every few units is flat over
695 // short runs, and a strict test would halt on the first repeated value and call
696 // it a landmark.
697 var ui: i64 = si
698 var walk: i64 = 1
699 while walk == 1 {
700 walk = 0
701 if ui > 0 { if zs[ui - 1] <= zs[ui] { ui = ui - 1; walk = 1 } }
702 }
703 var li: i64 = si
704 walk = 1
705 while walk == 1 {
706 walk = 0
707 if li < FA_LIP_N - 1 { if zs[li + 1] <= zs[li] { li = li + 1; walk = 1 } }
708 }
709 // A peak that reached the band edge means the profile never turned around inside
710 // the window, so there is no lip there to measure; a peak that never left the
711 // stomion means there was no protrusion at all. Refusing on both is what makes
712 // the absent-face control able to fail, and it is why the window's own boundary
713 // is never reported as an anatomical landmark.
714 if ui <= 0 { out[FA_LIP_O_REASON] = FA_LIP_R_NO_UPPER_PEAK; return FA_LIP_UNMEASURED }
715 if ui >= si { out[FA_LIP_O_REASON] = FA_LIP_R_NO_UPPER_PEAK; return FA_LIP_UNMEASURED }
716 if li >= FA_LIP_N - 1 { out[FA_LIP_O_REASON] = FA_LIP_R_NO_LOWER_PEAK; return FA_LIP_UNMEASURED }
717 if li <= si { out[FA_LIP_O_REASON] = FA_LIP_R_NO_LOWER_PEAK; return FA_LIP_UNMEASURED }
718 // PUBLISH WHAT WAS FOUND BEFORE DECIDING WHAT COULD NOT BE: the stomion and both peaks are measured, whatever happens next.
719 let sto: i64 = fa_lip_stomion_refine(base, ys[si])
720 out[FA_LIP_O_STOMION] = sto
721 out[FA_LIP_O_UPPEAK] = ys[ui]
722 out[FA_LIP_O_LOPEAK] = ys[li]
723 // THE SULCI: walk on past each peak while the profile keeps receding. A walk that reached the band edge found the window,
724 // not a sulcus, so it is published only when it turned inside the band -- the lower one on a face without a projecting chin
725 // does not, and that is a measurement about the chin, never a reason to refuse the lips.
726 var ubi: i64 = ui
727 walk = 1
728 while walk == 1 {
729 walk = 0
730 if ubi > 0 { if zs[ubi - 1] >= zs[ubi] { ubi = ubi - 1; walk = 1 } }
731 }
732 var lbi: i64 = li
733 walk = 1
734 while walk == 1 {
735 walk = 0
736 if lbi < FA_LIP_N - 1 { if zs[lbi + 1] >= zs[lbi] { lbi = lbi + 1; walk = 1 } }
737 }
738 if ubi > 0 { if ubi < ui { out[FA_LIP_O_UPSULCUS] = ys[ubi] } }
739 if lbi < FA_LIP_N - 1 { if lbi > li { out[FA_LIP_O_LOSULCUS] = ys[lbi] } }
740 // THE BORDERS: the vermilion edge at the surface, on each side of the stomion -- found on the coarse samples, then refined to
741 // the unit grid between the last coarse sample inside and the first outside.
742 if sdf_lip_vermilion(base, 0, ys[si], zs[si]) < 0 { out[FA_LIP_O_REASON] = FA_LIP_R_NO_VERMILION_FIELD; return FA_LIP_UNMEASURED }
743 let ue: i64 = fa_lip_vermilion_edge(base, ys, zs, si, 0 - 1)
744 let le: i64 = fa_lip_vermilion_edge(base, ys, zs, si, 1)
745 if ue >= 0 {
746 out[FA_LIP_O_UPBORDER] = fa_lip_border_refine(base, ys[ue], 0 - 1)
747 out[FA_LIP_O_UPPER_H] = out[FA_LIP_O_UPBORDER] - sto
748 }
749 if le >= 0 {
750 out[FA_LIP_O_LOBORDER] = fa_lip_border_refine(base, ys[le], 1)
751 out[FA_LIP_O_LOWER_H] = sto - out[FA_LIP_O_LOBORDER]
752 }
753 // A ratio missing one of its two terms is not a smaller number, it is no number: whichever half WAS measured stays published.
754 if ue == FA_LIP_EDGE_NEVER { out[FA_LIP_O_REASON] = FA_LIP_R_NO_UPPER_VERMILION; return FA_LIP_UNMEASURED }
755 if le == FA_LIP_EDGE_NEVER { out[FA_LIP_O_REASON] = FA_LIP_R_NO_LOWER_VERMILION; return FA_LIP_UNMEASURED }
756 if ue == FA_LIP_EDGE_PAST { out[FA_LIP_O_REASON] = FA_LIP_R_VERMILION_PAST_BAND; return FA_LIP_UNMEASURED }
757 if le == FA_LIP_EDGE_PAST { out[FA_LIP_O_REASON] = FA_LIP_R_VERMILION_PAST_BAND; return FA_LIP_UNMEASURED }
758 if out[FA_LIP_O_LOWER_H] <= 0 { out[FA_LIP_O_REASON] = FA_LIP_R_NO_LOWER_VERMILION; return FA_LIP_UNMEASURED }
759 out[FA_LIP_O_REASON] = FA_LIP_R_OK
760 let r: i64 = out[FA_LIP_O_UPPER_H] * FA_LIP_PERMIL / out[FA_LIP_O_LOWER_H]
761 out[FA_LIP_O_RATIO] = r
762 return r
763}
764
765// ---- AT43: THE LIP UNIT STATES ITS LANDMARKS -------------------------------------------------------------------------------------
766// Construction truth for the mouth, the lip unit's counterpart of the eye unit's stated canthi: every value is a closed form of the
767// two sweeps' part numbers and primitive slots, through the renderer's OWN outline function (sdf_lip_h), so the statement and the
768// pixels the renderer colours cannot disagree by construction. The surface ruler above and the photo ruler on a render are then
769// JUDGED against this -- two independent routes to one landmark, whose agreement is the audit. All in model units.
770const FA_LS_O_STOMION: i64 = 0
771const FA_LS_O_LS: i64 = 1 // labrale superius: the upper vermilion line at the midline (the bottom of the bow)
772const FA_LS_O_LI: i64 = 2 // labrale inferius: the lower vermilion line at the midline
773const FA_LS_O_UPPER_H: i64 = 3
774const FA_LS_O_LOWER_H: i64 = 4
775const FA_LS_O_RATIO: i64 = 5 // upper over lower, permil: the canon row upper_over_lower_lip
776const FA_LS_O_CHEILION_X: i64 = 6 // the commissure's half-width (each cheilion at +- this x)
777const FA_LS_O_CHEILION_Y: i64 = 7 // the seam's height at the commissure
778const FA_LS_O_FIELDS: i64 = 8
779func fa_lip_stated(base: i64, out: *i64) -> i64 {
780 let p: *i64 = (base + O_PARTS) as *i64
781 let u: i64 = FA_LIP_U * FA_PART_FIELDS
782 let l: i64 = FA_LIP_L * FA_PART_FIELDS
783 let seam: i64 = p[u + FA_F_CY]
784 let hu: i64 = sdf_lip_h(p[u + FA_F_RY], sdf_get_prim(base, FA_LIP_U, SDF_PL_TAPER), sdf_get_prim(base, FA_LIP_U, SDF_PL_NOTCH), sdf_get_prim(base, FA_LIP_U, SDF_PL_NOTCH_HW), FA_LIP_UP_SIDE, 0)
785 let hl: i64 = sdf_lip_h(p[l + FA_F_RY], sdf_get_prim(base, FA_LIP_L, SDF_PL_TAPER), sdf_get_prim(base, FA_LIP_L, SDF_PL_NOTCH), sdf_get_prim(base, FA_LIP_L, SDF_PL_NOTCH_HW), FA_LIP_DOWN_SIDE, 0)
786 out[FA_LS_O_STOMION] = seam
787 out[FA_LS_O_LS] = seam + hu
788 out[FA_LS_O_LI] = seam - hl
789 out[FA_LS_O_UPPER_H] = hu
790 out[FA_LS_O_LOWER_H] = hl
791 out[FA_LS_O_RATIO] = hu * FA_LIP_PERMIL / hl // sdf_lip_h never returns below 1, so this cannot divide by zero
792 out[FA_LS_O_CHEILION_X] = p[u + FA_F_RX]
793 out[FA_LS_O_CHEILION_Y] = seam + sdf_get_prim(base, FA_LIP_U, SDF_PL_CURVE)
794 return out[FA_LS_O_RATIO]
795}
796
797// ---- AT15: THE RICKETTS E-LINE PROFILE RULER --------------------------------
798// (Labelled AT5 when first written, which was wrong -- AT5 on that board is the neoteny axis.)
799// Ricketts' esthetic plane runs pronasale -> soft-tissue pogonion; in a balanced adult profile the
800// vermilion of BOTH lips sits BEHIND that line. This measures the RENDERED SURFACE through
801// fa_midline_z, never the part table: reading cz back out of the sliders would report the numbers
802// somebody typed, not the shape the blend actually produces, and the blend is what a viewer sees.
803// It reports NUMBERS ONLY. The accept band is canon data (knowledge/aesthetic_canon.conf), because an
804// uncalibrated classifier must report numbers, never verdicts -- and because "how far behind the
805// E-line should a lip sit" is an evidence-graded question, not a constant this file gets to invent.
806//
807// SIGN: protrusion is POSITIVE when the lip is IN FRONT of the line (the abnormal direction), so the
808// defect reads as a positive number in every consumer. -z is proud, hence line_z - lip_z.
809//
810// THE STATUS IS NOT THE VALUE. A protrusion of -0.1mm rounds to -1, which is exactly
811// FA_LIP_UNMEASURED, so returning the measurement as the return code would make one legitimate
812// reading indistinguishable from a refusal. The value lives in out[]; the return carries status only.
813const FA_EL_YSTEP: i64 = 4
814// Bands come from the landmark frame at the head of this file, and each is chosen to EXCLUDE its
815// neighbour's ellipsoid rather than to be generously wide:
816const FA_EL_NOSE_Y0: i64 = 0 - 40
817const FA_EL_NOSE_Y1: i64 = 0 - 240
818// THE POGONION BAND STARTS BELOW -556 ON PURPOSE. The lower-lip ellipsoid is centred y=-442 with
819// ry=114, so it REACHES y=-556; a chin band opened at -470 would find the lip's own bulge and report
820// it as pogonion -- the ruler would then measure the lower lip against itself and read ~0 protrusion,
821// which is the flattering direction and the one nobody audits.
822const FA_EL_POG_Y0: i64 = 0 - 560
823const FA_EL_POG_Y1: i64 = 0 - 660
824const FA_EL_ULIP_Y0: i64 = 0 - 260
825const FA_EL_ULIP_Y1: i64 = 0 - 370
826const FA_EL_LLIP_Y0: i64 = 0 - 400
827const FA_EL_LLIP_Y1: i64 = 0 - 500
828const FA_EL_O_ULIP: i64 = 0
829const FA_EL_O_LLIP: i64 = 1
830const FA_EL_O_PRN_Y: i64 = 2
831const FA_EL_O_PRN_Z: i64 = 3
832const FA_EL_O_POG_Y: i64 = 4
833const FA_EL_O_POG_Z: i64 = 5
834const FA_EL_O_LS_Y: i64 = 6
835const FA_EL_O_LS_Z: i64 = 7
836const FA_EL_O_LI_Y: i64 = 8
837const FA_EL_O_LI_Z: i64 = 9
838const FA_EL_O_REASON: i64 = 10
839// RAW UNITS TRAVEL BESIDE THE MILLIMETRES, DELIBERATELY. The mm conversion divides by MMU, and MMU
840// (3.5 u/mm) disagrees by ~2.2x with four independent witnesses of this model's OWN declared geometry:
841// eye width 210u, eyeball diameter 188u, eye-line-to-stomion 568u and trichion-to-gnathion 1436u all
842// imply 7-8.5 u/mm. That disagreement is unresolved -- MMU was empirically fitted against a reference,
843// so it may be compensating for something else rather than simply wrong -- and until the reference-fit
844// lane settles it, a consumer reading only the mm field is reading a contested constant. The
845// unconverted measurement is published alongside so every claim survives any correction to MMU.
846const FA_EL_O_ULIP_U: i64 = 11
847const FA_EL_O_LLIP_U: i64 = 12
848const FA_EL_O_FIELDS: i64 = 13
849const FA_EL_R_OK: i64 = 0
850const FA_EL_R_NO_PRONASALE: i64 = 1
851const FA_EL_R_NO_POGONION: i64 = 2
852const FA_EL_R_NO_UPPER_LIP: i64 = 3
853const FA_EL_R_NO_LOWER_LIP: i64 = 4
854const FA_EL_R_DEGENERATE: i64 = 5
855const FA_EL_MM10_NUM: i64 = 100
856
857// Most-proud midline point in [y0,y1] walking DOWN (y0 > y1). Writes y,z into out[oy],out[oz].
858// Returns 1 when a surface was found anywhere in the band, else 0 -- an empty band is a real answer
859// and the caller must not read it as a very recessed one.
860func fa_el_apex(base: i64, y0: i64, y1: i64, out: *i64, oy: i64, oz: i64) -> i64 {
861 var found: i64 = 0
862 var by: i64 = 0
863 var bz: i64 = 0
864 var y: i64 = y0
865 while y >= y1 {
866 let z: i64 = fa_midline_z(base, y)
867 if z != FA_LIP_NOSURF {
868 if found == 0 { found = 1; by = y; bz = z }
869 if z < bz { by = y; bz = z }
870 }
871 y = y - FA_EL_YSTEP
872 }
873 if found == 0 { return 0 }
874 out[oy] = by
875 out[oz] = bz
876 return 1
877}
878
879func fa_eline_offset(base: i64, out: *i64) -> i64 {
880 var f: i64 = 0
881 while f < FA_EL_O_FIELDS { out[f] = FA_LIP_UNMEASURED; f = f + 1 }
882 if fa_el_apex(base, FA_EL_NOSE_Y0, FA_EL_NOSE_Y1, out, FA_EL_O_PRN_Y, FA_EL_O_PRN_Z) == 0 {
883 out[FA_EL_O_REASON] = FA_EL_R_NO_PRONASALE
884 return FA_LIP_UNMEASURED
885 }
886 if fa_el_apex(base, FA_EL_POG_Y0, FA_EL_POG_Y1, out, FA_EL_O_POG_Y, FA_EL_O_POG_Z) == 0 {
887 out[FA_EL_O_REASON] = FA_EL_R_NO_POGONION
888 return FA_LIP_UNMEASURED
889 }
890 let py: i64 = out[FA_EL_O_PRN_Y]
891 let pz: i64 = out[FA_EL_O_PRN_Z]
892 let gy: i64 = out[FA_EL_O_POG_Y]
893 let gz: i64 = out[FA_EL_O_POG_Z]
894 // A zero-length baseline has no direction, so there is no line to be in front of. The bands above
895 // cannot produce it; it is guarded anyway because the divide below would trap.
896 if py == gy { out[FA_EL_O_REASON] = FA_EL_R_DEGENERATE; return FA_LIP_UNMEASURED }
897 if fa_el_apex(base, FA_EL_ULIP_Y0, FA_EL_ULIP_Y1, out, FA_EL_O_LS_Y, FA_EL_O_LS_Z) == 0 {
898 out[FA_EL_O_REASON] = FA_EL_R_NO_UPPER_LIP
899 return FA_LIP_UNMEASURED
900 }
901 if fa_el_apex(base, FA_EL_LLIP_Y0, FA_EL_LLIP_Y1, out, FA_EL_O_LI_Y, FA_EL_O_LI_Z) == 0 {
902 out[FA_EL_O_REASON] = FA_EL_R_NO_LOWER_LIP
903 return FA_LIP_UNMEASURED
904 }
905 let ulz: i64 = pz + (gz - pz) * (py - out[FA_EL_O_LS_Y]) / (py - gy)
906 let llz: i64 = pz + (gz - pz) * (py - out[FA_EL_O_LI_Y]) / (py - gy)
907 out[FA_EL_O_ULIP_U] = ulz - out[FA_EL_O_LS_Z]
908 out[FA_EL_O_LLIP_U] = llz - out[FA_EL_O_LI_Z]
909 out[FA_EL_O_ULIP] = out[FA_EL_O_ULIP_U] * FA_EL_MM10_NUM / fa_mmu_x10()
910 out[FA_EL_O_LLIP] = out[FA_EL_O_LLIP_U] * FA_EL_MM10_NUM / fa_mmu_x10()
911 out[FA_EL_O_REASON] = FA_EL_R_OK
912 return 0
913}
914
915// ---- AT16: THE PALPEBRAL FISSURE, MEASURED FROM THE SURFACE -----------------
916// The canthi are found, never placed: this scans ACROSS the eye and locates the two ends of the
917// aperture from the rendered field. Reading the lid parts back out of the table would report the
918// numbers typed above rather than the shape the blend produces, and the blend is what is rendered.
919const FA_PF_XSTEP: i64 = 4
920const FA_PF_YSTEP: i64 = 4
921const FA_PF_EYE_CX: i64 = 258
922const FA_PF_XSPAN: i64 = 170
923const FA_PF_Y_TOP: i64 = 250
924const FA_PF_Y_BOT: i64 = 110
925// Sample count per column, DERIVED from the band the scan owns -- a hand-counted length beside the
926// band constants would be a second copy of their shape, and the two would drift silently.
927const FA_PF_NS: i64 = (FA_PF_Y_TOP - FA_PF_Y_BOT) / FA_PF_YSTEP + 1
928const FA_PF_MIN_STEPS: i64 = 3
929const FA_PF_DY_FLOOR: i64 = 0 // the column record: floor y, opening height, upper crest y, lower crest y
930const FA_PF_DY_UP: i64 = 2
931const FA_PF_DY_DN: i64 = 3
932const FA_PF_DY_SLOTS: i64 = 4
933const FA_PF_O_MED_X: i64 = 0
934const FA_PF_O_MED_Y: i64 = 1
935const FA_PF_O_LAT_X: i64 = 2
936const FA_PF_O_LAT_Y: i64 = 3
937const FA_PF_O_WIDTH: i64 = 4
938const FA_PF_O_PEAK_D: i64 = 5
939const FA_PF_O_PEAK_X: i64 = 6
940const FA_PF_O_REASON: i64 = 7
941const FA_PF_O_PEAK_SPAN: i64 = 8
942const FA_PF_O_FIELDS: i64 = 9
943const FA_PF_R_OK: i64 = 0
944const FA_PF_R_NO_SURFACE: i64 = 1
945const FA_PF_R_NO_APERTURE: i64 = 2
946const FA_PF_R_NO_CLOSURE: i64 = 3
947// Reason 4 (BOWL-NOT-SLIT) existed for one failed gate run on 2026-08-29 and was retired with the
948// span heuristic that emitted it -- the turning-point column refuses bowls geometrically, so the
949// verdict has no emitter. The value stays reserved so no future reason silently reuses it.
950
951// REWRITTEN AFTER THE NEGATIVE CONTROL FIRED TWICE -- RULE 3, NOT A THIRD PATCH. Version one read a
952// plain spread and scored the ORBIT as a fissure at depth 172. Version two required a shoulder on both
953// sides and cut the phantom to 82; the orbit is ALSO two-sided (upper rim above, cheek below). Version
954// two-and-a-half added a recessed-span bowl filter and cut it to 54; a bowl's tapering EDGE columns are
955// genuinely narrow, so per-column width heuristics cannot separate them from a slit -- and worse, the
956// quarter-peak closure bar made the measured canthi drift when the peak moved: two patches, still
957// failing, so the mechanism is wrong, not the tuning.
958//
959// THE MOUTH ALREADY SOLVED THIS SHAPE. fa_lip_ratio finds an INTERIOR extremum, walks OUTWARD to the
960// FIRST turning points with plateaus walked through, and refuses anything pinned to the band edge --
961// because a landmark at the window boundary is the window, not the face. The same pattern separates
962// fissure from orbit STRUCTURALLY: with lids, the profile down a mid-eye column is lid-front (proud),
963// aperture floor (recessed), lid-front (proud) -- an interior floor bracketed by two interior proud
964// turning points. Without lids the recession deepens toward the brow and socket wall, the most-recessed
965// sample lands AT the band edge, and the interior-floor guard refuses before any depth is computed.
966// No width bar, no bowl verdict, no tunable fraction -- the refusal is geometric.
967//
968// zs is the caller's sample buffer (never allocate in a per-column loop). dy[0] = the floor's y (the
969// aperture line at this x); dy[1] = the aperture HEIGHT, turning point to turning point -- the
970// palpebral fissure height, an anatomical quantity reported through the peak-span field.
971func fa_pf_column(base: i64, x: i64, ytop: i64, zs: *i64, dy: *i64) -> i64 {
972 var i: i64 = 0
973 while i < FA_PF_NS {
974 let y: i64 = ytop - i * FA_PF_YSTEP
975 let z: i64 = fa_surface_z(base, x, y)
976 if z == FA_LIP_NOSURF { return FA_LIP_UNMEASURED }
977 zs[i] = z
978 i = i + 1
979 }
980 // Interior floor: the most recessed sample. Ties keep the FIRST hit and the plateau walk below
981 // handles the rest. At either band edge it is a slope leaving the window, refused before scoring.
982 var fi: i64 = 0
983 i = 1
984 while i < FA_PF_NS {
985 if zs[i] > zs[fi] { fi = i }
986 i = i + 1
987 }
988 if fi <= 0 { return FA_LIP_UNMEASURED }
989 if fi >= FA_PF_NS - 1 { return FA_LIP_UNMEASURED }
990 var ui: i64 = fi
991 var walk: i64 = 1
992 while walk == 1 {
993 walk = 0
994 if ui > 0 { if zs[ui - 1] <= zs[ui] { ui = ui - 1; walk = 1 } }
995 }
996 var di: i64 = fi
997 walk = 1
998 while walk == 1 {
999 walk = 0
1000 if di < FA_PF_NS - 1 { if zs[di + 1] <= zs[di] { di = di + 1; walk = 1 } }
1001 }
1002 // A walk that ran to the band edge found no margin inside the window; a walk that never left the
1003 // floor found no protrusion. Both refuse -- the same guards, for the same reasons, as the mouth's.
1004 if ui <= 0 { return FA_LIP_UNMEASURED }
1005 if ui >= fi { return FA_LIP_UNMEASURED }
1006 if di >= FA_PF_NS - 1 { return FA_LIP_UNMEASURED }
1007 if di <= fi { return FA_LIP_UNMEASURED }
1008 var d: i64 = zs[fi] - zs[ui]
1009 let d2: i64 = zs[fi] - zs[di]
1010 if d2 < d { d = d2 }
1011 // Shallower than the marcher's own step resolution is quantisation wearing a landmark's name.
1012 if d < FA_PF_MIN_STEPS * FA_LIP_ZSTEP { return FA_LIP_UNMEASURED }
1013 dy[0] = ytop - fi * FA_PF_YSTEP
1014 dy[1] = (di - ui) * FA_PF_YSTEP
1015 dy[FA_PF_DY_UP] = ytop - ui * FA_PF_YSTEP
1016 dy[FA_PF_DY_DN] = ytop - di * FA_PF_YSTEP
1017 return d
1018}
1019
1020// THE STATED CORNER of an eye's lid shell, model units, in out2: which = +1 the lateral canthus, -1 the medial. The opening's
1021// +x end sits at halfw along the rolled x axis; the lateral end of a right-side eye is its +x end and of a left-side eye its -x
1022// end, so one signed expression serves both. Returns 0 when this eye has no lid shell (then it has no lid margin and no canthus)
1023func fa_lid_corner(base: i64, eye_sign: i64, which: i64, out2: *i64) -> i64 {
1024 var lid: i64 = FA_LID_R
1025 if eye_sign < 0 { lid = FA_LID_L }
1026 let nparts: *i64 = (base + O_NPART) as *i64
1027 let opsv: *i64 = (base + O_OPS) as *i64
1028 if nparts[0] <= lid { return 0 }
1029 if opsv[lid] != SDF_OP_LIDSHELL { return 0 }
1030 let pp: *i64 = (base + O_PARTS) as *i64
1031 let rollv: *i64 = (base + O_ROLL) as *i64
1032 var rc: i64 = rollv[lid * SDF_ROT_FIELDS]
1033 let rs: i64 = rollv[lid * SDF_ROT_FIELDS + 1]
1034 if rc == 0 { if rs == 0 { rc = IT_FX } }
1035 let halfw: i64 = sdf_get_prim(base, lid, SDF_PR_HALFW)
1036 out2[0] = pp[lid * FA_PART_FIELDS + FA_F_CX] + which * eye_sign * (halfw * rc / IT_FX)
1037 out2[1] = pp[lid * FA_PART_FIELDS + FA_F_CY] + which * eye_sign * (halfw * rs / IT_FX)
1038 return 1
1039}
1040// the depth of a point of an eye's lid shell OUTER sphere at model (x, y): the canthus is the tip of the opening and lies on
1041// that sphere by construction, so its depth is arithmetic, not a march through a blended field that is steep and discontinuous
1042// exactly there. Returns FA_LIP_NOSURF when the eye has no lid shell or the point lies outside the sphere's silhouette
1043func fa_lid_corner_z(base: i64, eye_sign: i64, x: i64, y: i64) -> i64 {
1044 var lid: i64 = FA_LID_R
1045 if eye_sign < 0 { lid = FA_LID_L }
1046 let nparts: *i64 = (base + O_NPART) as *i64
1047 let opsv: *i64 = (base + O_OPS) as *i64
1048 if nparts[0] <= lid { return FA_LIP_NOSURF }
1049 if opsv[lid] != SDF_OP_LIDSHELL { return FA_LIP_NOSURF }
1050 let pp: *i64 = (base + O_PARTS) as *i64
1051 let rout: i64 = pp[lid * FA_PART_FIELDS + FA_F_RX] + pp[lid * FA_PART_FIELDS + FA_F_RY]
1052 let dx: i64 = x - pp[lid * FA_PART_FIELDS + FA_F_CX]
1053 let dy: i64 = y - pp[lid * FA_PART_FIELDS + FA_F_CY]
1054 let inside: i64 = rout * rout - dx * dx - dy * dy
1055 if inside < 0 { return FA_LIP_NOSURF }
1056 return pp[lid * FA_PART_FIELDS + FA_F_CZ] - sdf_isqrt(inside)
1057}
1058// ONE CANTHUS, FOUND ON THE SURFACE NEAR WHERE THE LID SHELL PUTS IT (AT39). The columns of the scan say three things the two
1059// earlier rules each ignored: a groove OUTSIDE the eye can measure (a fold beside a long nasal bridge read as the medial
1060// canthus 23 units off with the tilt's sign flipped), columns INSIDE the opening can refuse (where the globe's edge sits
1061// flush with the lid margin the recess is shallower than the marcher can resolve), and the corner columns themselves measure
1062// deeply because they look past the globe. So neither "first column from the span's end" nor "connected run from the centre"
1063// is a canthus. The lid shell states where its opening ends; the surface is asked whether a closure is really THERE: walking
1064// inward from FA_PF_CORNER_WINDOW outside the stated corner, the first column that measures AND whose opening (one sample of
1065// slack each way) contains the stated corner's height is the found canthus. Two readings of one landmark, and the caller
1066// publishes how far apart they are. dir is +1 when outward is +x. Returns 1 when found
1067const FA_CORNER_LATERAL: i64 = 1
1068const FA_CORNER_MEDIAL: i64 = 0 - 1
1069const FA_PF_CORNER_WINDOW: i64 = 24 // three millimetres at the derived scale: wider than the unresolvable tip, narrower than any neighbour
1070// the window is walked ONE unit at a time: at a thin corner the aperture is shallow against the marcher's resolution, so whether a
1071// column measures flickers from one column to the next, and a four-unit walk aligned to the stated corner stepped between the
1072// columns that measure on a held-out seed (seed 11, small wide-set eyes: NO-CLOSURE on both eyes with closures at hand)
1073const FA_PF_CORNER_XSTEP: i64 = 1
1074func fa_pf_corner(base: i64, ex: i64, ey: i64, dir: i64, ytop: i64, zs: *i64, dy: *i64, out: *i64, slot_x: i64) -> i64 {
1075 let steps: i64 = (FA_PF_CORNER_WINDOW * 2) / FA_PF_CORNER_XSTEP
1076 var found: i64 = 0
1077 var j: i64 = 0
1078 while j <= steps {
1079 if found == 0 {
1080 let x: i64 = ex + dir * (FA_PF_CORNER_WINDOW - j * FA_PF_CORNER_XSTEP)
1081 let d: i64 = fa_pf_column(base, x, ytop, zs, dy)
1082 if d != FA_LIP_UNMEASURED {
1083 if dy[FA_PF_DY_UP] + FA_PF_YSTEP >= ey { if dy[FA_PF_DY_DN] - FA_PF_YSTEP <= ey {
1084 found = 1
1085 out[slot_x] = x
1086 out[slot_x + 1] = dy[FA_PF_DY_FLOOR]
1087 } }
1088 }
1089 }
1090 j = j + 1
1091 }
1092 return found
1093}
1094// eye_sign: -1 left, +1 right. MEDIAL is the end nearer the midline, LATERAL the end away from it, so
1095// both are derived from the sign rather than hard-coded per eye -- one code path, and a mirrored face
1096// must therefore read the same magnitudes.
1097func fa_palpebral_fissure(base: i64, eye_sign: i64, out: *i64) -> i64 {
1098 var f: i64 = 0
1099 while f < FA_PF_O_FIELDS { out[f] = FA_LIP_UNMEASURED; f = f + 1 }
1100 // WHERE to look follows the face (AT39): the window is centred on the globe this eye actually has, so a width or length
1101 // morph moves the scan with the eye. WHAT is found still comes from the surface alone.
1102 let pp: *i64 = (base + O_PARTS) as *i64
1103 var gx: i64 = pp[FA_GLOBE_R * FA_PART_FIELDS + FA_F_CX]
1104 if gx < 0 { gx = 0 - gx }
1105 let cx: i64 = gx * eye_sign
1106 let ytop: i64 = pp[FA_GLOBE_R * FA_PART_FIELDS + FA_F_CY] + (FA_PF_Y_TOP - FA_EYE_CY)
1107 let zs: *i64 = (sys_mmap(FA_PF_NS * 8 + FA_LIP_SLACK)) as *i64
1108 let dy: *i64 = (sys_mmap(FA_PF_DY_SLOTS * 8 + FA_LIP_SLACK)) as *i64
1109 var peak: i64 = 0
1110 var peak_x: i64 = 0
1111 var peak_span: i64 = 0
1112 var any: i64 = 0
1113 var j: i64 = 0
1114 let steps: i64 = (FA_PF_XSPAN * 2) / FA_PF_XSTEP
1115 while j <= steps {
1116 let x: i64 = cx - FA_PF_XSPAN + j * FA_PF_XSTEP
1117 let d: i64 = fa_pf_column(base, x, ytop, zs, dy)
1118 if d != FA_LIP_UNMEASURED {
1119 any = 1
1120 if d > peak { peak = d; peak_x = x; peak_span = dy[1] }
1121 }
1122 j = j + 1
1123 }
1124 if any == 0 { out[FA_PF_O_REASON] = FA_PF_R_NO_APERTURE; return FA_LIP_UNMEASURED }
1125 out[FA_PF_O_PEAK_D] = peak
1126 out[FA_PF_O_PEAK_X] = peak_x
1127 out[FA_PF_O_PEAK_SPAN] = peak_span
1128 // the stated corners of THIS eye's lid shell: an arena with no lid shell has no lid margin, so it has no canthus to find
1129 // and refuses by name before any column is read (the pre-AT16 face is exactly this case)
1130 let c2: *i64 = (sys_mmap(FA_LIP_SLACK)) as *i64
1131 if fa_lid_corner(base, eye_sign, FA_CORNER_LATERAL, c2) == 0 { out[FA_PF_O_REASON] = FA_PF_R_NO_APERTURE; return FA_LIP_UNMEASURED }
1132 let found_l: i64 = fa_pf_corner(base, c2[0], c2[1], eye_sign, ytop, zs, dy, out, FA_PF_O_LAT_X)
1133 fa_lid_corner(base, eye_sign, FA_CORNER_MEDIAL, c2)
1134 let found_m: i64 = fa_pf_corner(base, c2[0], c2[1], 0 - eye_sign, ytop, zs, dy, out, FA_PF_O_MED_X)
1135 if found_m == 0 { out[FA_PF_O_REASON] = FA_PF_R_NO_CLOSURE; return FA_LIP_UNMEASURED }
1136 if found_l == 0 { out[FA_PF_O_REASON] = FA_PF_R_NO_CLOSURE; return FA_LIP_UNMEASURED }
1137 var w: i64 = out[FA_PF_O_LAT_X] - out[FA_PF_O_MED_X]
1138 if w < 0 { w = 0 - w }
1139 out[FA_PF_O_WIDTH] = w
1140 out[FA_PF_O_REASON] = FA_PF_R_OK
1141 return 0
1142}