code wiki / _hdl_build / nx_i2mesh_gate.nx
nx_i2mesh_gate.nx source
↩ module page · 103 lines · 5671 B
1// nx_i2mesh_gate.nx -- prove IMAGE-to-MESH: ingest images (synthetic masks AND our own render/Z-Image
2// foreground) -> silhouette-inflation -> closed meshes. T1 each image -> valid CLOSED mesh. T2 different images
3// -> different geometry. T3 OUR-image (a rendered body's foreground) ingests too (Z-Image plugs in the same
4// way). Writes knowledge/i2m_*.stl. GREEN = the ecosystem ingests an IMAGE and emits a 3D mesh. ORIGINAL
5import "nx_syscalls.nx"
6import "nx_sdfrender.nx"
7import "nx_meshgen.nx"
8import "nx_i2mesh.nx"
9
10func hw(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 }
11func hwf(fd: i64, s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(fd, s, n); return 0 }
12func pn(v: i64) -> i64 {
13 let b: *u8 = sys_mmap(32) as *u8
14 var x: i64 = v; var neg: i64 = 0
15 if x < 0 { neg = 1; x = 0 - x }
16 var i: i64 = 31
17 if x == 0 { b[i] = 48 as u8; i = i - 1 }
18 while x > 0 { b[i] = (48 + x % 10) as u8; x = x / 10; i = i - 1 }
19 if neg == 1 { b[i] = 45 as u8; i = i - 1 }
20 sys_write(1, (b as i64 + i + 1) as *u8, 31 - i)
21 return 0
22}
23func snum(fd: i64, v: i64) -> i64 {
24 let b: *u8 = sys_mmap(32) as *u8
25 var x: i64 = v; var neg: i64 = 0
26 if x < 0 { neg = 1; x = 0 - x }
27 var i: i64 = 31
28 if x == 0 { b[i] = 48 as u8; i = i - 1 }
29 while x > 0 { b[i] = (48 + x % 10) as u8; x = x / 10; i = i - 1 }
30 if neg == 1 { b[i] = 45 as u8; i = i - 1 }
31 sys_write(fd, (b as i64 + i + 1) as *u8, 31 - i); sys_write(fd, " " as *u8, 1); return 0
32}
33func wstl(vb: *i64, fb: *i64, nf: i64, path: *u8) -> i64 {
34 let fd: i64 = sys_openat_wr(path, 0x1a4)
35 if fd < 0 { return 0 - 1 }
36 hwf(fd, "solid nishi_i2m\n" as *u8)
37 var t: i64 = 0
38 while t < nf {
39 let a: i64 = fb[t * 3]; let b: i64 = fb[t * 3 + 1]; let c: i64 = fb[t * 3 + 2]
40 hwf(fd, "facet normal 0 0 0\nouter loop\nvertex " as *u8)
41 snum(fd, vb[a*3]); snum(fd, vb[a*3+1]); snum(fd, vb[a*3+2]); hwf(fd, "\nvertex " as *u8)
42 snum(fd, vb[b*3]); snum(fd, vb[b*3+1]); snum(fd, vb[b*3+2]); hwf(fd, "\nvertex " as *u8)
43 snum(fd, vb[c*3]); snum(fd, vb[c*3+1]); snum(fd, vb[c*3+2]); hwf(fd, "\nendloop\nendfacet\n" as *u8)
44 t = t + 1
45 }
46 hwf(fd, "endsolid nishi_i2m\n" as *u8); sys_close(fd); return 0
47}
48
49func emit_i2m(label: *u8, mask: *u8, din: *i64, dout: *i64, F: *i64, cv: *i64, vb: *i64, fb: *i64, out: *i64, stl: *u8, failp: *i64) -> i64 {
50 i2m_dt(mask, din, 1)
51 i2m_dt(mask, dout, 0)
52 i2m_fill_field(F, mask, din, dout)
53 mg_extract(F, cv, vb, fb, out)
54 let nv: i64 = out[0]; let nf: i64 = out[1]
55 hw(" image '"); hw(label); hw("' -> mesh: verts="); pn(nv); hw(" tris="); pn(nf)
56 var ok: i64 = 1
57 if nv < 400 { ok = 0 }
58 if nf < nv * 3 / 2 { ok = 0 }
59 if nf > nv * 5 / 2 { ok = 0 }
60 if ok == 1 { hw(" [closed]\n" as *u8) } else { hw(" [BAD]\n" as *u8); failp[0] = failp[0] + 1 }
61 wstl(vb, fb, nf, stl)
62 return nv
63}
64
65func main() -> i64 {
66 let base: i64 = sys_mmap(sdf_bytes()) as i64
67 let mask: *u8 = sys_mmap(I2_MW * I2_MH) as *u8
68 let din: *i64 = sys_mmap(I2_MW * I2_MH * 8) as *i64
69 let dout: *i64 = sys_mmap(I2_MW * I2_MH * 8) as *i64
70 let F: *i64 = sys_mmap((MG_N + 1) * (MG_N + 1) * (MG_N + 1) * 8) as *i64
71 let cv: *i64 = sys_mmap(MG_N * MG_N * MG_N * 8) as *i64
72 let vb: *i64 = sys_mmap(MG_MAXV * 3 * 8) as *i64
73 let fb: *i64 = sys_mmap(MG_MAXF * 3 * 8) as *i64
74 let out: *i64 = sys_mmap(16) as *i64
75 let nvs: *i64 = sys_mmap(16 * 8) as *i64
76 let failp: *i64 = sys_mmap(8) as *i64; failp[0] = 0
77 hw("=== nx_i2mesh_gate -- ingest an IMAGE, EMIT a 3D mesh (silhouette inflation, our own code) ===\n" as *u8)
78
79 i2m_mask_circle(mask); nvs[0] = emit_i2m("circle" as *u8, mask, din, dout, F, cv, vb, fb, out, "knowledge/i2m_circle.stl" as *u8, failp)
80 i2m_mask_square(mask); nvs[1] = emit_i2m("square" as *u8, mask, din, dout, F, cv, vb, fb, out, "knowledge/i2m_square.stl" as *u8, failp)
81 i2m_mask_cross(mask); nvs[2] = emit_i2m("cross" as *u8, mask, din, dout, F, cv, vb, fb, out, "knowledge/i2m_cross.stl" as *u8, failp)
82
83 // ★ingest OUR OWN image: render the pioneer body, use its foreground as the input image (Z-Image plugs in here)
84 sdf_body(base)
85 sdf_render(base, 0, 5, 240, 184, 160)
86 i2m_mask_from_fb(mask, (base + fb_off()) as *i64, ww(), hh())
87 nvs[3] = emit_i2m("our-render-body" as *u8, mask, din, dout, F, cv, vb, fb, out, "knowledge/i2m_ourbody.stl" as *u8, failp)
88
89 var fails: i64 = failp[0]
90 if fails == 0 { hw("T1 PASS every image -> a valid CLOSED mesh (4/4)\n" as *u8) }
91 else { hw("T1 FAIL "); pn(fails); hw(" bad\n" as *u8) }
92 var distinct: i64 = 0
93 var a: i64 = 0
94 while a < 4 { var seen: i64 = 0; var b: i64 = 0; while b < a { if nvs[b] == nvs[a] { seen = 1 } b = b + 1 } if seen == 0 { distinct = distinct + 1 } a = a + 1 }
95 if distinct >= 3 { hw("T2 PASS varies by image: "); pn(distinct); hw("/4 distinct -> different silhouettes -> different meshes\n" as *u8) }
96 else { hw("T2 FAIL only "); pn(distinct); hw(" distinct\n" as *u8); fails = fails + 1 }
97 if nvs[3] > 800 { hw("T3 PASS OUR-image ingested: rendered body foreground -> a 3D mesh (verts="); pn(nvs[3]); hw(") -- Z-Image plugs in identically\n" as *u8) }
98 else { hw("T3 FAIL our-image mesh verts="); pn(nvs[3]); hw("\n" as *u8); fails = fails + 1 }
99
100 if fails == 0 { hw("GATE GREEN: i2mesh v0 ingests an IMAGE -> EMITS a 3D mesh (knowledge/i2m_*.stl). Z-Image -> 3D is wired; the ecosystem generates from images too.\n" as *u8) }
101 else { hw("GATE RED fails="); pn(fails); hw("\n" as *u8) }
102 return fails
103}