code wiki / (root) / nx_devpaint.nx

nx_devpaint.nx source

↩ module page · 69 lines · 4314 B

1// nx_devpaint.nx -- CLI for the derived-scale deviation heatmap (2026-08-26). 2// nx_devpaint <candidate.nxmesh> <reference.nxmesh> <out.nxmesh> 3// Writes the candidate back out with every triangle painted by its distance to the reference surface, 4// and prints the DERIVED colour-scale bounds together with the rule that derived them -- because a 5// heatmap whose scale is not published is a picture nobody can read a number off. 6// Exit 0 painted / 2 usage / 3 unreadable / 4 REFUSED extent bound / 5 empty mesh / 6 unwritable. 7// Thin main: every function lives in nx_devpaint_lib so nx_devpaint_gate composes it IN-PROCESS. 8// license_tier: ORIGINAL 9 10import "nx_syscalls.nx" 11import "nx_itoa_lib.nx" 12import "nx_nxmesh_lib.nx" 13import "nx_devpaint_lib.nx" 14 15func dv_w(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } 16func dv_kv(k: *u8, v: i64, last: i64) -> i64 { 17 dv_w("\x22" as *u8); dv_w(k); dv_w("\x22:" as *u8); nxi_out(v) 18 if last == 0 { dv_w("," as *u8) } 19 return 0 20} 21 22func main(argc: i64, argv: *i64) -> i64 { 23 if argc < 4 { 24 dv_w("{\x22error\x22:\x22usage: nx_devpaint <candidate.nxmesh> <reference.nxmesh> <out.nxmesh> -- paints the candidate by distance to the reference, colour scale DERIVED from the measured distribution and printed\x22}\n" as *u8) 25 return 2 26 } 27 let lc: *i64 = sys_mmap(16) as *i64 28 let lr: *i64 = sys_mmap(16) as *i64 29 let ca: *u8 = sys_read_file(argv[1] as *u8, lc) 30 let rf: *u8 = sys_read_file(argv[2] as *u8, lr) 31 if (ca as i64) == 0 { dv_w("{\x22error\x22:\x22cannot read candidate\x22}\n" as *u8); return 3 } 32 if (rf as i64) == 0 { dv_w("{\x22error\x22:\x22cannot read reference\x22}\n" as *u8); return 3 } 33 let nt: i64 = nm_ntris(ca) 34 if nt <= 0 { dv_w("{\x22error\x22:\x22candidate has no triangles\x22}\n" as *u8); return 5 } 35 let res: *i64 = dp_res() 36 let dev: *i64 = sys_mmap(nt * 3 * 8 + 64) as *i64 37 let rc: i64 = dp_measure(ca, rf, dev, res) 38 if rc == 1 { 39 dv_w("{\x22error\x22:\x22REFUSED extent over 2.5 m -- the integer point-triangle test would overflow; the ruler declines rather than reporting garbage\x22}\n" as *u8) 40 return 4 41 } 42 if rc == 3 { dv_w("{\x22error\x22:\x22reference has no triangles\x22}\n" as *u8); return 5 } 43 let hi: i64 = dp_scale(res) 44 res[DP_R_SATURATED] = dp_saturated(dev, res[DP_R_CORNERS], hi) 45 dp_paint(ca, nm_tri_base(ca), nt, dev, res[DP_R_LO], hi) 46 let fd: i64 = sys_openat_wr(argv[3] as *u8, MODE_0644) 47 if fd < 0 { dv_w("{\x22error\x22:\x22output unwritable\x22}\n" as *u8); return 6 } 48 sys_write(fd, ca, lc[0]) 49 sys_close(fd) 50 51 dv_w("{\x22organ\x22:\x22nx_devpaint\x22,\x22unit\x22:\x22tenths-of-a-millimetre\x22,\x22sampled\x22:0," as *u8) 52 dv_kv("tris" as *u8, res[DP_R_TRIS], 0) 53 dv_kv("corners_measured" as *u8, res[DP_R_CORNERS], 0) 54 dv_kv("out_bytes" as *u8, lc[0], 0) 55 dv_w("\x22scale\x22:{" as *u8) 56 dv_kv("lo_x10mm" as *u8, res[DP_R_LO], 0) 57 dv_kv("hi_x10mm" as *u8, hi, 0) 58 dv_kv("p50_x10mm" as *u8, res[DP_R_P50], 0) 59 dv_kv("p95_x10mm" as *u8, res[DP_R_P95], 0) 60 dv_kv("max_x10mm" as *u8, res[DP_R_MAX], 0) 61 dv_kv("mean_x10mm" as *u8, res[DP_R_MEAN], 0) 62 dv_kv("saturated_corners" as *u8, res[DP_R_SATURATED], 0) 63 dv_kv("saturated_permil" as *u8, res[DP_R_SATURATED] * 1000 / res[DP_R_CORNERS], 0) 64 dv_kv("hist_overflow" as *u8, res[DP_R_OVERFLOW], 0) 65 dv_w("\x22derivation\x22:\x22lo=0 because zero deviation must map to the zero colour; hi=p95 rounded UP to the next whole millimetre, the ruler's own clinical unit; floor one millimetre so two agreeing meshes paint entirely in the floor colour instead of dividing by zero. p95 rather than max so one stray outlier cannot flatten the whole picture into the floor colour.\x22}" as *u8) 66 dv_w(",\x22ramp\x22:\x22continuous, five stops interpolated: green-yellow-orange-red-magenta, the same five colours nx_meshdist md_paint uses as hard bands, so readings taken off the older banded picture stay valid\x22" as *u8) 67 dv_w(",\x22reduction\x22:\x22max-of-corners: measured per vertex, but NXMSH2 carries ONE colour per triangle, so a triangle takes its worst corner -- wrong in the direction of showing deviation, never hiding it\x22}\n" as *u8) 68 return 0 69}