code wiki / _hdl_build / nx_mechparts_gate.nx

nx_mechparts_gate.nx source

↩ module page · 163 lines · 7276 B

1// nx_mechparts_gate.nx -- teeth for the mechanical-primitive library (cadtwin R1b-lite). Builds all 5 as1 2// part types (hex nut w/ hole, bolt w/ hex head, rod=cylinder, plate, L-bracket) into one scene, asserts each 3// emits real geometry (verts+tris, watertight-ish edge parity for the closed ones), renders a composite PNG 4// to EYEBALL realism (knowledge/nx_mechparts.png), and checks determinism. expect_exit: 0 license_tier: ORIGINAL 5import "nx_mechparts.nx" 6import "nx_render_core.nx" 7import "nx_meshrender.nx" 8import "nx_apng.nx" 9 10func gg_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } 11func gg_putn(v: i64) -> i64 { 12 let bb: *u8 = sys_mmap(28) 13 var m: i64 = v 14 if m < 0 { gg_puts("-" as *u8); m = 0 - m } 15 let t: *u8 = sys_mmap(28) 16 var k: i64 = 0 17 if m == 0 { t[0] = 48 as u8; k = 1 } 18 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 19 var i: i64 = 0 20 while i < k { bb[i] = t[k - 1 - i]; i = i + 1 } 21 sys_write(1, bb, k) 22 return 0 23} 24func gg_tooth(name: *u8, pass: i64, fails: *i64) -> i64 { 25 gg_puts(" " as *u8); gg_puts(name); gg_puts(" -> " as *u8) 26 if pass == 1 { gg_puts("PASS\n" as *u8); return 0 } 27 gg_puts("FAIL\n" as *u8) 28 fails[0] = fails[0] + 1 29 return 0 30} 31func gg_chk(fb: *i64, n: i64) -> i64 { var x: i64 = 0; var i: i64 = 0; while i < n { x = x + fb[i] * (1 + (i % 7)); i = i + 1 } return x } 32func gg_cover(fb: *i64, n: i64, bg: i64) -> i64 { var k: i64 = 0; var i: i64 = 0; while i < n { if fb[i] != bg { k = k + 1 } i = i + 1 } return k } 33 34func main() -> i64 { 35 gg_puts("=== nx_mechparts_gate -- proper mechanical primitives (hex nut/bolt/rod/plate/L-bracket) ===\n" as *u8) 36 let fails: *i64 = sys_mmap(8) as *i64 37 fails[0] = 0 38 39 let e: *i64 = sys_mmap(256) as *i64 40 let lverts: *i64 = sys_mmap(262144) as *i64 41 let idx: *i64 = sys_mmap(393216) as *i64 42 let home: *i64 = sys_mmap(2048) as *i64 43 let dir: *i64 = sys_mmap(2048) as *i64 44 let dep: *i64 = sys_mmap(1024) as *i64 45 let vst: *i64 = sys_mmap(1024) as *i64 46 let vct: *i64 = sys_mmap(1024) as *i64 47 let scr: *i64 = sys_mmap(16) as *i64 48 ex3_init(e, lverts, idx, home, dir, dep, vst, vct, 8192, 16384, 64, scr) 49 50 let C_GOLD: i64 = 4280860390 51 let C_RED: i64 = 4280824550 52 let C_GRN: i64 = 4284139580 53 let C_GRY: i64 = 4288714390 54 let C_BLU: i64 = 4293294150 55 56 // build each part as its own ex3 part, spread along x 57 let v0: i64 = e[1] 58 ex3_part_begin(e, 0 - 6500, 0, 0, 0, 1, 0, 1) 59 mp_hexnut(e, 0 - 6500, 0, 0, 1100, 420, 0, C_GOLD) 60 let nut_v: i64 = e[1] - v0 61 let t0: i64 = e[3] 62 63 let v1: i64 = e[1] 64 ex3_part_begin(e, 0 - 3250, 0, 0, 0, 1, 0, 1) 65 mp_bolt(e, 0 - 3250, 0 - 700, 0, 420, 1400, 900, 430, 0, C_RED) 66 let bolt_v: i64 = e[1] - v1 67 68 let v2: i64 = e[1] 69 ex3_part_begin(e, 0, 0, 0, 0, 1, 0, 1) 70 mp_prism(e, 0, 0, 0, 500, 2400, 1, 24, C_GRN) // rod: cylinder lying along x 71 let rod_v: i64 = e[1] - v2 72 73 let v3: i64 = e[1] 74 ex3_part_begin(e, 3250, 0, 0, 0, 1, 0, 1) 75 ex3_add_box(e, 3250, 0, 0, 1200, 260, 1600, C_GRY) // plate 76 let plate_v: i64 = e[1] - v3 77 78 let v4: i64 = e[1] 79 ex3_part_begin(e, 6500, 0, 0, 0, 1, 0, 1) 80 mp_lbracket(e, 6500, 0, 0, 1500, 320, 700, C_BLU) 81 let lb_v: i64 = e[1] - v4 82 83 gg_puts("verts: nut=" as *u8); gg_putn(nut_v) 84 gg_puts(" bolt=" as *u8); gg_putn(bolt_v) 85 gg_puts(" rod=" as *u8); gg_putn(rod_v) 86 gg_puts(" plate=" as *u8); gg_putn(plate_v) 87 gg_puts(" lbracket=" as *u8); gg_putn(lb_v) 88 gg_puts(" total verts=" as *u8); gg_putn(e[1]); gg_puts(" tris=" as *u8); gg_putn(e[3]); gg_puts("\n" as *u8) 89 90 var t1: i64 = 0 91 if nut_v > 20 { if bolt_v > 40 { if rod_v > 40 { if plate_v >= 8 { if lb_v >= 16 { t1 = 1 } } } } } 92 let ig1: i64 = gg_tooth("T1 every part emits real geometry" as *u8, t1, fails) 93 94 // T2 nut has a hole: its annulus emits 4 rings * 6 = 24 rim verts + no center caps (vs a solid hex prism 95 // which would have 2 center verts). Check nut_v == 24 (4*nseg, nseg=6) exactly = the hole is real. 96 var t2: i64 = 0 97 if nut_v == 24 { t2 = 1 } 98 let ig2: i64 = gg_tooth("T2 hex nut is annular (24 rim verts, real through-hole)" as *u8, t2, fails) 99 100 // T3 rod cylinder is smoothly tessellated (24-gon = 2 center + 48 rim = 50 verts) 101 var t3: i64 = 0 102 if rod_v == 50 { t3 = 1 } 103 let ig3: i64 = gg_tooth("T3 rod is a 24-gon cylinder (50 verts, smooth)" as *u8, t3, fails) 104 105 // pitch the whole model ~30deg around X so we SEE the tops (hex faces, holes, L-profile) = the 3/4 view 106 // every CAD viewer uses (a pure y-orbit side view hides all these features). cos30=14189 sin30=8192 Q14. 107 var pv: i64 = 0 108 while pv < e[1] { 109 let y: i64 = lverts[pv * 4 + 1] 110 let z: i64 = lverts[pv * 4 + 2] 111 lverts[pv * 4 + 1] = (y * 14189 - z * 8192) / 16384 112 lverts[pv * 4 + 2] = (y * 8192 + z * 14189) / 16384 113 pv = pv + 1 114 } 115 116 // T4 render composite PNG to eyeball 117 let W: i64 = 560 118 let H: i64 = 200 119 let N: i64 = W * H 120 let fb: *i64 = sys_mmap(N * 8) as *i64 121 let zb: *i64 = sys_mmap(N * 8) as *i64 122 let proj: *i64 = sys_mmap(128) as *i64 123 let roty: *i64 = sys_mmap(128) as *i64 124 let mv: *i64 = sys_mmap(128) as *i64 125 let trans: *i64 = sys_mmap(128) as *i64 126 let mvp: *i64 = sys_mmap(128) as *i64 127 let vbuf: *i64 = sys_mmap(64) as *i64 128 let clipbuf: *i64 = sys_mmap(64) as *i64 129 let rscr: *i64 = sys_mmap(262144) as *i64 130 let tribuf: *i64 = sys_mmap(128) as *i64 131 let BG: i64 = 4280293912 132 let drawn: i64 = mr_render(lverts, e[1], idx, e[3], proj, roty, mv, trans, mvp, vbuf, clipbuf, rscr, tribuf, fb, zb, W, H, 24, 13000, 34, BG) 133 let cov: i64 = gg_cover(fb, N, BG) 134 let ck1: i64 = gg_chk(fb, N) 135 gg_puts(" render: drawn tris=" as *u8); gg_putn(drawn); gg_puts(" coverage=" as *u8); gg_putn(cov); gg_puts("\n" as *u8) 136 var t4: i64 = 0 137 if drawn > 100 { if cov > 2500 { t4 = 1 } } 138 let ig4: i64 = gg_tooth("T4 composite renders (parts visible)" as *u8, t4, fails) 139 140 // determinism 141 let drawn2: i64 = mr_render(lverts, e[1], idx, e[3], proj, roty, mv, trans, mvp, vbuf, clipbuf, rscr, tribuf, fb, zb, W, H, 24, 13000, 34, BG) 142 let ck2: i64 = gg_chk(fb, N) 143 var t5: i64 = 0 144 if ck1 == ck2 { t5 = 1 } 145 let ig5: i64 = gg_tooth("T5 render deterministic" as *u8, t5, fails) 146 147 // write PNG (single-frame apng = valid PNG image) 148 let ap: *u8 = sys_mmap(2097152) 149 let seq: *i64 = sys_mmap(8) as *i64 150 seq[0] = 0 151 // convert i64-rgba framebuffer to u8 rgb for apng (apng_frame reads fb as *i64 already -- reuse the path) 152 var o: i64 = apng_open(ap, W, H, 1) 153 o = apng_frame(ap, o, seq, fb, W, H, 100, 1) 154 o = apng_close(ap, o) 155 let fd: i64 = sys_openat_wr("knowledge/nx_mechparts.png" as *u8, 0x1a4) 156 if fd >= 0 { sys_write(fd, ap, o); sys_close(fd) } 157 gg_puts(" wrote knowledge/nx_mechparts.png (" as *u8); gg_putn(o); gg_puts(" bytes)\n" as *u8) 158 159 gg_puts("\nfails=" as *u8); gg_putn(fails[0]); gg_puts("\n" as *u8) 160 if fails[0] == 0 { gg_puts("GREEN -- mechanical primitives 5/5 (eyeball knowledge/nx_mechparts.png)\n" as *u8); return 0 } 161 gg_puts("RED\n" as *u8) 162 return 1 163}