code wiki / _hdl_build / nx_explode3d_gate.nx
nx_explode3d_gate.nx source
↩ module page · 311 lines · 14144 B
1// nx_explode3d_gate.nx -- teeth for R2: the 3D exploded-view engine DRIVEN BY THE REAL STEP ASSEMBLY.
2// Parses banked as1-oc-214.stp (nx_step_parse R1a) -> DFS the occurrence tree -> one 3D part per leaf
3// instance (box/prism STAND-INS by product name; real face tessellation = R1b) -> nx_explode3d staged
4// radial explode -> nx_meshrender frames -> ANIMATED APNG knowledge/nx_explode_as1.apng (assemble<->explode
5// loop = the explodeview signature). T1 part count == INDEPENDENT occurrence-expansion count (two different
6// computations agree) · T2 mean pairwise part distance strictly MONOTONIC in t · T3 exploded >= 2x assembled
7// spread · T4 pose determinism (same t -> same bytes) · T5 staged depth (depth-3 parts travel further than
8// depth-1) · T6 renders non-vacuous + assembled differs from exploded · T7 APNG written (signature + size).
9// expect_exit: 0 license_tier: ORIGINAL
10import "nx_syscalls.nx"
11import "nx_step_parse.nx"
12import "nx_explode3d.nx"
13import "nx_render_core.nx"
14import "nx_meshrender.nx"
15import "nx_apng.nx"
16import "nx_gate_verdict.nx"
17
18func xg_tooth(name: *u8, pass: i64, c: *i64) -> i64 { gv_check(name, pass == 1, c); return 0 }
19
20// layout law lives in nx_explode3d (ex3_rad/ex3_dyv) -- shared with the explodelab tree generator
21
22// framebuffer coverage vs background + additive checksum (determinism/difference probes)
23func xg_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 }
24func xg_chk(v: *i64, n: i64) -> i64 { var x: i64 = 0; var i: i64 = 0; while i < n { x = x + v[i] * (1 + (i % 7)); i = i + 1 } return x }
25
26func main() -> i64 {
27 sp_puts("=== nx_explode3d_gate -- 3D staged explode of the REAL as1 STEP assembly ===\n" as *u8)
28 let fails: *i64 = gv_ctr()
29
30 // ---- parse the real STEP file (R1a) ----
31 let buf: *u8 = sys_mmap(4194304)
32 let aid: *i64 = sys_mmap(524288) as *i64
33 let anm: *i64 = sys_mmap(524288) as *i64
34 let anl: *i64 = sys_mmap(524288) as *i64
35 let aao: *i64 = sys_mmap(524288) as *i64
36 let aal: *i64 = sys_mmap(524288) as *i64
37 let st: *i64 = sys_mmap(256) as *i64
38 let n: i64 = sp_read_file("knowledge/fetched/step_as1.stp" as *u8, buf, 4194304)
39 // The fixture is a precondition, not a tooth: an absent STEP file means NOTHING was examined, and the base
40 // class says so (gv_subjects -> SKIP-shaped verdict) instead of a hand-rolled RED that reads as a physics failure.
41 gv_subjects("step-as1-fixture-bytes" as *u8, n, fails)
42 if n <= 0 { sp_puts("MISSING knowledge/fetched/step_as1.stp -- run nx_step_sample_fetch\n" as *u8); return gv_verdict("nx_explode3d_gate" as *u8, fails, "fixture absent: nothing was examined" as *u8) }
43 let ig0: i64 = sp_init(st, buf, n, aid, anm, anl, aao, aal)
44 let cnt: i64 = sp_scan(st)
45 let pe: *i64 = sys_mmap(2048) as *i64
46 let ce: *i64 = sys_mmap(2048) as *i64
47 let en: i64 = sp_nauo_collect(st, pe, ce, 256)
48 sp_puts("entities=" as *u8); sp_putn(cnt); sp_puts(" edges=" as *u8); sp_putn(en); sp_puts("\n" as *u8)
49
50 // root = parent that is never a child
51 var rootpd: i64 = 0 - 1
52 var i: i64 = 0
53 while i < en {
54 let p: i64 = pe[i]
55 var ischild: i64 = 0
56 var j: i64 = 0
57 while j < en { if ce[j] == p { ischild = 1 } j = j + 1 }
58 if ischild == 0 { rootpd = p }
59 i = i + 1
60 }
61
62 // ---- INDEPENDENT expanded-occurrence count (relaxation over the edge list, no DFS) ----
63 let dpd: *i64 = sys_mmap(1024) as *i64
64 var nd: i64 = 0
65 var e2: i64 = 0
66 while e2 < en {
67 var side: i64 = 0
68 while side < 2 {
69 var v: i64 = pe[e2]
70 if side == 1 { v = ce[e2] }
71 var seen: i64 = 0
72 var q: i64 = 0
73 while q < nd { if dpd[q] == v { seen = 1 } q = q + 1 }
74 if seen == 0 { dpd[nd] = v; nd = nd + 1 }
75 side = side + 1
76 }
77 e2 = e2 + 1
78 }
79 let occ: *i64 = sys_mmap(1024) as *i64
80 let occn: *i64 = sys_mmap(1024) as *i64
81 var q2: i64 = 0
82 while q2 < nd { occ[q2] = 0; if dpd[q2] == rootpd { occ[q2] = 1 } q2 = q2 + 1 }
83 var pass: i64 = 0
84 while pass < 12 {
85 var q3: i64 = 0
86 while q3 < nd { occn[q3] = 0; if dpd[q3] == rootpd { occn[q3] = 1 } q3 = q3 + 1 }
87 var e3: i64 = 0
88 while e3 < en {
89 var pi: i64 = 0 - 1
90 var ci: i64 = 0 - 1
91 var q4: i64 = 0
92 while q4 < nd {
93 if dpd[q4] == pe[e3] { pi = q4 }
94 if dpd[q4] == ce[e3] { ci = q4 }
95 q4 = q4 + 1
96 }
97 if pi >= 0 { if ci >= 0 { occn[ci] = occn[ci] + occ[pi] } }
98 e3 = e3 + 1
99 }
100 var q5: i64 = 0
101 while q5 < nd { occ[q5] = occn[q5]; q5 = q5 + 1 }
102 pass = pass + 1
103 }
104 var leafinst: i64 = 0
105 var q6: i64 = 0
106 while q6 < nd {
107 var hasout: i64 = 0
108 var e4: i64 = 0
109 while e4 < en { if pe[e4] == dpd[q6] { hasout = 1 } e4 = e4 + 1 }
110 if hasout == 0 { leafinst = leafinst + occ[q6] }
111 q6 = q6 + 1
112 }
113 sp_puts("independent expanded leaf instances=" as *u8); sp_putn(leafinst); sp_puts("\n" as *u8)
114
115 // ---- build the 3D scene by DFS (part per leaf instance; stand-in geometry by product name) ----
116 let e: *i64 = sys_mmap(256) as *i64
117 let lverts: *i64 = sys_mmap(131072) as *i64
118 let wverts: *i64 = sys_mmap(131072) as *i64
119 let idx: *i64 = sys_mmap(196608) as *i64
120 let home: *i64 = sys_mmap(2048) as *i64
121 let dir: *i64 = sys_mmap(2048) as *i64
122 let dep: *i64 = sys_mmap(1024) as *i64
123 let vst: *i64 = sys_mmap(1024) as *i64
124 let vct: *i64 = sys_mmap(1024) as *i64
125 let exsc: *i64 = sys_mmap(16) as *i64
126 let ig1: i64 = ex3_init(e, lverts, idx, home, dir, dep, vst, vct, 4096, 8192, 64, exsc)
127
128 // colors: packed (a<<24 | b<<16 | g<<8 | r)
129 let C_GOLD: i64 = 4280860390 // nut r230 g190 b40
130 let C_RED: i64 = 4280824550 // bolt r230 g50 b40
131 let C_GRN: i64 = 4284139580 // rod r60 g200 b90
132 let C_GRY: i64 = 4288714390 // plate r150 g150 b160
133 let C_BLU: i64 = 4293294150 // l-bracket r70 g120 b230
134 let C_WHT: i64 = 4292006610 // default r210 g210 b210
135 let BG: i64 = 4280293912 // background r24 g26 b32
136
137 let s_pd: *i64 = sys_mmap(2048) as *i64
138 let s_dep: *i64 = sys_mmap(2048) as *i64
139 let s_x: *i64 = sys_mmap(2048) as *i64
140 let s_y: *i64 = sys_mmap(2048) as *i64
141 let s_z: *i64 = sys_mmap(2048) as *i64
142 let s_px: *i64 = sys_mmap(2048) as *i64
143 let s_py: *i64 = sys_mmap(2048) as *i64
144 let s_pz: *i64 = sys_mmap(2048) as *i64
145 let out2: *i64 = sys_mmap(16) as *i64
146 var sp2: i64 = 0
147 if rootpd >= 0 {
148 s_pd[0] = rootpd; s_dep[0] = 0
149 s_x[0] = 0; s_y[0] = 2200; s_z[0] = 0
150 s_px[0] = 0; s_py[0] = 0; s_pz[0] = 0
151 sp2 = 1
152 }
153 var overflow: i64 = 0
154 while sp2 > 0 {
155 sp2 = sp2 - 1
156 let pd: i64 = s_pd[sp2]
157 let d: i64 = s_dep[sp2]
158 let px: i64 = s_x[sp2]
159 let py: i64 = s_y[sp2]
160 let pz: i64 = s_z[sp2]
161 let ppx: i64 = s_px[sp2]
162 let ppy: i64 = s_py[sp2]
163 let ppz: i64 = s_pz[sp2]
164 var haschild: i64 = 0
165 var k: i64 = 0
166 var e5: i64 = 0
167 while e5 < en {
168 if pe[e5] == pd {
169 haschild = 1
170 let cd: i64 = d + 1
171 let ig2: i64 = ex3_oct(k, out2)
172 let r: i64 = ex3_rad(cd)
173 let cx: i64 = px + (out2[0] * r) / 16384
174 let cz: i64 = pz + (out2[1] * r) / 16384
175 let cy: i64 = py + ex3_dyv(cd)
176 if sp2 < 250 {
177 s_pd[sp2] = ce[e5]; s_dep[sp2] = cd
178 s_x[sp2] = cx; s_y[sp2] = cy; s_z[sp2] = cz
179 s_px[sp2] = px; s_py[sp2] = py; s_pz[sp2] = pz
180 sp2 = sp2 + 1
181 } else { overflow = 1 }
182 k = k + 1
183 }
184 e5 = e5 + 1
185 }
186 if haschild == 0 {
187 // LEAF instance -> a real 3D part; explode dir = radial from its parent's centroid
188 let prodi: i64 = sp_pd_product(st, pd)
189 let pidx: i64 = ex3_part_begin(e, px, py, pz, px - ppx, py - ppy, pz - ppz, d)
190 var done: i64 = 0
191 if prodi >= 0 {
192 let isnut: i64 = sp_prod_name_is(st, prodi, "nut" as *u8)
193 if isnut == 1 { let g1: i64 = ex3_add_prism(e, px, py, pz, 900, 420, 0, C_GOLD); done = 1 }
194 if done == 0 {
195 let isbolt: i64 = sp_prod_name_is(st, prodi, "bolt" as *u8)
196 if isbolt == 1 { let g2: i64 = ex3_add_prism(e, px, py, pz, 520, 1300, 0, C_RED); done = 1 }
197 }
198 if done == 0 {
199 let isrod: i64 = sp_prod_name_is(st, prodi, "rod" as *u8)
200 if isrod == 1 { let g3: i64 = ex3_add_prism(e, px, py, pz, 460, 3400, 1, C_GRN); done = 1 }
201 }
202 if done == 0 {
203 let isplate: i64 = sp_prod_name_is(st, prodi, "plate" as *u8)
204 if isplate == 1 { let g4: i64 = ex3_add_box(e, px, py, pz, 4400, 300, 2800, C_GRY); done = 1 }
205 }
206 if done == 0 {
207 let islb: i64 = sp_prod_name_is(st, prodi, "l-bracket" as *u8)
208 if islb == 1 { let g5: i64 = ex3_add_box(e, px, py, pz, 1000, 2000, 800, C_BLU); done = 1 }
209 }
210 }
211 if done == 0 { let g6: i64 = ex3_add_box(e, px, py, pz, 900, 900, 900, C_WHT) }
212 }
213 }
214 sp_puts("scene parts=" as *u8); sp_putn(e[4])
215 sp_puts(" verts=" as *u8); sp_putn(e[1])
216 sp_puts(" tris=" as *u8); sp_putn(e[3])
217 sp_puts(" overflow=" as *u8); sp_putn(overflow); sp_puts("\n" as *u8)
218
219 var t1: i64 = 0
220 if e[4] == leafinst { if e[4] >= 10 { if overflow == 0 { t1 = 1 } } }
221 let ig3: i64 = xg_tooth("T1 DFS parts == independent occurrence expansion (>=10)" as *u8, t1, fails)
222
223 // T2 monotonic explode spread
224 let m0: i64 = ex3_mean_pairdist(e, 0)
225 let m1: i64 = ex3_mean_pairdist(e, 256)
226 let m2: i64 = ex3_mean_pairdist(e, 512)
227 let m3: i64 = ex3_mean_pairdist(e, 768)
228 let m4: i64 = ex3_mean_pairdist(e, 1024)
229 sp_puts("mean pair distance t=0/256/512/768/1024: " as *u8)
230 sp_putn(m0); sp_puts(" " as *u8); sp_putn(m1); sp_puts(" " as *u8); sp_putn(m2); sp_puts(" " as *u8); sp_putn(m3); sp_puts(" " as *u8); sp_putn(m4); sp_puts("\n" as *u8)
231 var t2: i64 = 0
232 if m0 < m1 { if m1 < m2 { if m2 < m3 { if m3 < m4 { t2 = 1 } } } }
233 let ig4: i64 = xg_tooth("T2 spread strictly monotonic in t" as *u8, t2, fails)
234
235 var t3: i64 = 0
236 if m4 >= 2 * m0 { t3 = 1 }
237 let ig5: i64 = xg_tooth("T3 exploded spread >= 2x assembled" as *u8, t3, fails)
238
239 // T4 pose determinism
240 let ig6: i64 = ex3_pose(e, 512, wverts)
241 let ck1: i64 = xg_chk(wverts, e[1] * 4)
242 let ig7: i64 = ex3_pose(e, 0, wverts)
243 let ig8: i64 = ex3_pose(e, 512, wverts)
244 let ck2: i64 = xg_chk(wverts, e[1] * 4)
245 var t4: i64 = 0
246 if ck1 == ck2 { t4 = 1 }
247 let ig9: i64 = xg_tooth("T4 pose(t) deterministic (same t -> same bytes)" as *u8, t4, fails)
248
249 // T5 staged depth: deeper parts travel further at full explode
250 let d1: i64 = ex3_mean_disp_at_depth(e, 1024, 1)
251 let d3: i64 = ex3_mean_disp_at_depth(e, 1024, 3)
252 sp_puts("mean displacement depth1=" as *u8); sp_putn(d1); sp_puts(" depth3=" as *u8); sp_putn(d3); sp_puts("\n" as *u8)
253 var t5: i64 = 0
254 if d3 > d1 { if d1 > 0 { t5 = 1 } }
255 let ig10: i64 = xg_tooth("T5 staged: depth-3 travels further than depth-1" as *u8, t5, fails)
256
257 // T6+T7 render 16-frame assemble<->explode loop -> APNG
258 let W: i64 = 256
259 let H: i64 = 192
260 let N: i64 = W * H
261 let fb: *i64 = sys_mmap(N * 8) as *i64
262 let zb: *i64 = sys_mmap(N * 8) as *i64
263 let proj: *i64 = sys_mmap(128) as *i64
264 let roty: *i64 = sys_mmap(128) as *i64
265 let mv: *i64 = sys_mmap(128) as *i64
266 let trans: *i64 = sys_mmap(128) as *i64
267 let mvp: *i64 = sys_mmap(128) as *i64
268 let vbuf: *i64 = sys_mmap(64) as *i64
269 let clipbuf: *i64 = sys_mmap(64) as *i64
270 let scr: *i64 = sys_mmap(131072) as *i64 // PER-VERTEX: nverts*4 i64 (192B was a latent under-size, masked by page rounding)
271 let tribuf: *i64 = sys_mmap(128) as *i64
272 let ap: *u8 = sys_mmap(16777216)
273 let seq: *i64 = sys_mmap(8) as *i64
274 seq[0] = 0
275 var o: i64 = apng_open(ap, W, H, 16)
276 var cov0: i64 = 0
277 var cov7: i64 = 0
278 var chA: i64 = 0
279 var chB: i64 = 0
280 var fr: i64 = 0
281 while fr < 16 {
282 var t: i64 = 0
283 if fr < 8 { t = fr * 146 } else { t = (15 - fr) * 146 }
284 let igp: i64 = ex3_pose(e, t, wverts)
285 let drawn: i64 = mr_render(wverts, e[1], idx, e[3], proj, roty, mv, trans, mvp, vbuf, clipbuf, scr, tribuf, fb, zb, W, H, 28, 40000, 30, BG)
286 let cv: i64 = xg_cover(fb, N, BG)
287 if fr == 0 { cov0 = cv; chA = xg_chk(fb, N) }
288 if fr == 7 { cov7 = cv; chB = xg_chk(fb, N) }
289 var first: i64 = 0
290 if fr == 0 { first = 1 }
291 o = apng_frame(ap, o, seq, fb, W, H, 12, first)
292 fr = fr + 1
293 }
294 o = apng_close(ap, o)
295 sp_puts("coverage assembled=" as *u8); sp_putn(cov0); sp_puts(" exploded=" as *u8); sp_putn(cov7); sp_puts("\n" as *u8)
296 var t6: i64 = 0
297 if cov0 > 200 { if cov7 > 200 { if chA != chB { t6 = 1 } } }
298 let ig11: i64 = xg_tooth("T6 frames non-vacuous + assembled != exploded" as *u8, t6, fails)
299
300 let fd: i64 = sys_openat_wr("knowledge/nx_explode_as1.apng" as *u8, 0x1a4)
301 var t7: i64 = 0
302 if fd >= 0 {
303 sys_write(fd, ap, o)
304 sys_close(fd)
305 if o > 2000 { if ap[1] == (80 as u8) { t7 = 1 } }
306 }
307 sp_puts("APNG bytes=" as *u8); sp_putn(o); sp_puts(" -> knowledge/nx_explode_as1.apng\n" as *u8)
308 let ig12: i64 = xg_tooth("T7 animated explode APNG written" as *u8, t7, fails)
309
310 return gv_verdict("nx_explode3d_gate" as *u8, fails, "3D staged explode of the REAL as1 STEP tree; geometry = R1b stand-ins, stated; each tooth prints what it measured." as *u8)
311}