code wiki / (root) / nx_faceanat.nx

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}