code wiki / _hdl_build / nx_explodelab_meshgen.nx
nx_explodelab_meshgen.nx source
↩ module page · 361 lines · 12863 B
1// nx_explodelab_meshgen.nx -- GENERATOR: bake the REAL 53/53 file-true part meshes into a compiled data module
2// for the /explodelab viewer (build-generators-not-artifacts doctrine). Parses as1 -> per-part v2 tessellation
3// (nx_cadtwin_report pipeline: attribution + planar/NURBS + weld) -> CENTERS each part at its own origin and
4// scales fx256 -> world units (/8 = 32 units/mm; rod ±3200, plate ±2880 -- fits the viewer's existing ~3400
5// camera scale) -> emits runtime/nx_explodelab_meshes.nx: exm_load(e,kind,col) writing ex3_vert/ex3_tri (tri
6// indices offset by the captured e[1] base), chunked <=200 emissions/function (compiler-safe), plus
7// exm_counts(kind) and exm_dims(kind) = TRUE mm dims + thou (via nx_unitconv, baked). Display quantization:
8// /8 truncation <= 31um -- labels carry the TRUE fx256 dims, the mesh is display-only. Kinds: 1 nut, 2 bolt,
9// 3 rod, 4 plate, 5 l-bracket. expect_exit: 0 license_tier: ORIGINAL
10import "nx_cadtwin_report.nx"
11import "nx_step_write.nx"
12const K_MAGIC_4194304: i64 = 4194304
13const K_MAGIC_524288: i64 = 524288
14const K_MAGIC_8192: i64 = 8192
15const K_MAGIC_4096: i64 = 4096
16const K_MAGIC_1024: i64 = 1024
17const K_MAGIC_20480: i64 = 20480
18
19// emit a signed constant as a wasm-safe term: "N" or "(0 - N)"
20func mg_term(b: *i64, v: i64) -> i64 {
21 if v >= 0 { swb_n(b, v); return 0 }
22 swb_s(b, "(0 - " as *u8)
23 swb_n(b, 0 - v)
24 swb_s(b, ")" as *u8)
25 return 0
26}
27
28// emit one part's mesh as chunked functions; returns tri count. names: exm_k<K>_v<N> / exm_k<K>_t<N> / exm_k<K>.
29// Loaders take the instance CENTER (cx,cy,cz world units) -- ex3 verts are ABSOLUTE assembled coords (pose adds
30// displacement only), matching the mp_* convention they replace.
31func mg_part(b: *i64, mesh: i64, kind: i64, cx3: *i64) -> i64 {
32 let h: *i64 = m3_hdr(mesh)
33 let nv: i64 = h[0]
34 let ntr: i64 = h[1]
35 // vert chunks
36 var chunk: i64 = 0
37 var i: i64 = 0
38 while i < nv {
39 swb_s(b, "func exm_k" as *u8)
40 swb_n(b, kind)
41 swb_s(b, "_v" as *u8)
42 swb_n(b, chunk)
43 swb_s(b, "(e: *i64, cx: i64, cy: i64, cz: i64, col: i64) -> i64 " as *u8)
44 swb_c(b, 123)
45 swb_c(b, 10)
46 var e2: i64 = i + 200
47 if e2 > nv { e2 = nv }
48 while i < e2 {
49 let v: *i64 = m3_vert(mesh, i)
50 swb_s(b, " ex3_vert(e, cx + " as *u8)
51 mg_term(b, (v[0] - cx3[0]) / 8)
52 swb_s(b, ", cy + " as *u8)
53 mg_term(b, (v[1] - cx3[1]) / 8)
54 swb_s(b, ", cz + " as *u8)
55 mg_term(b, (v[2] - cx3[2]) / 8)
56 swb_s(b, ", col)" as *u8)
57 swb_c(b, 10)
58 i = i + 1
59 }
60 swb_s(b, " return 0" as *u8)
61 swb_c(b, 10)
62 swb_c(b, 125)
63 swb_c(b, 10)
64 chunk = chunk + 1
65 }
66 let vchunks: i64 = chunk
67 // tri chunks (indices offset by b0)
68 chunk = 0
69 var t: i64 = 0
70 while t < ntr {
71 swb_s(b, "func exm_k" as *u8)
72 swb_n(b, kind)
73 swb_s(b, "_t" as *u8)
74 swb_n(b, chunk)
75 swb_s(b, "(e: *i64, b0: i64) -> i64 " as *u8)
76 swb_c(b, 123)
77 swb_c(b, 10)
78 var e3: i64 = t + 200
79 if e3 > ntr { e3 = ntr }
80 while t < e3 {
81 let tr: *i64 = m3_tri(mesh, t)
82 swb_s(b, " ex3_tri(e, b0 + " as *u8)
83 swb_n(b, tr[0])
84 swb_s(b, ", b0 + " as *u8)
85 swb_n(b, tr[1])
86 swb_s(b, ", b0 + " as *u8)
87 swb_n(b, tr[2])
88 swb_s(b, ")" as *u8)
89 swb_c(b, 10)
90 t = t + 1
91 }
92 swb_s(b, " return 0" as *u8)
93 swb_c(b, 10)
94 swb_c(b, 125)
95 swb_c(b, 10)
96 chunk = chunk + 1
97 }
98 let tchunks: i64 = chunk
99 // parent
100 swb_s(b, "func exm_k" as *u8)
101 swb_n(b, kind)
102 swb_s(b, "(e: *i64, cx: i64, cy: i64, cz: i64, col: i64) -> i64 " as *u8)
103 swb_c(b, 123)
104 swb_c(b, 10)
105 swb_s(b, " let b0: i64 = e[1]" as *u8)
106 swb_c(b, 10)
107 var c2: i64 = 0
108 while c2 < vchunks {
109 swb_s(b, " exm_k" as *u8)
110 swb_n(b, kind)
111 swb_s(b, "_v" as *u8)
112 swb_n(b, c2)
113 swb_s(b, "(e, cx, cy, cz, col)" as *u8)
114 swb_c(b, 10)
115 c2 = c2 + 1
116 }
117 c2 = 0
118 while c2 < tchunks {
119 swb_s(b, " exm_k" as *u8)
120 swb_n(b, kind)
121 swb_s(b, "_t" as *u8)
122 swb_n(b, c2)
123 swb_s(b, "(e, b0)" as *u8)
124 swb_c(b, 10)
125 c2 = c2 + 1
126 }
127 swb_s(b, " return 0" as *u8)
128 swb_c(b, 10)
129 swb_c(b, 125)
130 swb_c(b, 10)
131 return ntr
132}
133
134func main() -> i64 {
135 sp_puts("=== nx_explodelab_meshgen -- bake REAL 53/53 part meshes for the viewer ===\n" as *u8)
136 let buf: *u8 = sys_mmap(K_MAGIC_4194304)
137 let a1: *i64 = sys_mmap(K_MAGIC_524288) as *i64
138 let a2: *i64 = sys_mmap(K_MAGIC_524288) as *i64
139 let a3: *i64 = sys_mmap(K_MAGIC_524288) as *i64
140 let a4: *i64 = sys_mmap(K_MAGIC_524288) as *i64
141 let a5: *i64 = sys_mmap(K_MAGIC_524288) as *i64
142 let st: *i64 = sys_mmap(256) as *i64
143 let n: i64 = sp_read_file("knowledge/fetched/step_as1.stp" as *u8, buf, K_MAGIC_4194304)
144 if n <= 0 { sp_puts("MISSING as1\nRED\n" as *u8); return 1 }
145 sp_init(st, buf, n, a1, a2, a3, a4, a5)
146 sp_scan(st)
147 // ctxs (report-pipeline pattern)
148 let tt: *i64 = sys_mmap(128) as *i64
149 let cp: *i64 = sys_mmap(128) as *i64
150 var z: i64 = 0
151 while z < 16 { cp[z] = 0; z = z + 1 }
152 tt[0] = st as i64
153 tt[2] = cp as i64
154 tt[3] = sys_mmap(768) as i64
155 tt[4] = 0
156 tt[5] = sys_mmap(K_MAGIC_8192) as i64
157 tt[6] = sys_mmap(K_MAGIC_4096) as i64
158 tt[7] = sys_mmap(128) as i64
159 tt[8] = sys_mmap(16) as i64
160 tt[9] = 0
161 let t2: *i64 = sys_mmap(128) as *i64
162 t2[0] = st as i64
163 t2[1] = cp as i64
164 t2[2] = sys_mmap(32) as i64
165 t2[3] = sys_mmap(960) as i64
166 t2[4] = sys_mmap(K_MAGIC_1024) as i64
167 t2[5] = sys_mmap(128) as i64
168 t2[6] = sys_mmap(512) as i64
169 t2[7] = sys_mmap(256) as i64
170 t2[8] = sys_mmap(K_MAGIC_8192) as i64
171 t2[9] = sys_mmap(128) as i64
172 t2[10] = sys_mmap(768) as i64
173 t2[11] = sys_mmap(128) as i64
174 t2[12] = sys_mmap(256) as i64
175 let slab: *i64 = sys_mmap(K_MAGIC_20480) as *i64
176 let nt: *i64 = sys_mmap(128) as *i64
177 let c2n: *i64 = sys_mmap(128) as *i64
178 z = 0
179 while z < 16 { c2n[z] = 0; z = z + 1 }
180 nt[0] = st as i64
181 nt[2] = c2n as i64
182 nt[3] = sys_mmap(256) as i64
183 nt[4] = sys_mmap(64) as i64
184 nt[5] = sys_mmap(16) as i64
185 nt[6] = sys_mmap(128) as i64
186 nt[7] = sys_mmap(128) as i64
187 let pdid: *i64 = sys_mmap(128) as *i64
188 let prodidx: *i64 = sys_mmap(128) as *i64
189 let shellidx: *i64 = sys_mmap(128) as *i64
190 let np: i64 = cr_find_parts(st, pdid, prodidx, shellidx)
191 if np != 5 { sp_puts("expected 5 parts\nRED\n" as *u8); return 1 }
192 // units registry for baked thou values
193 let u: *i64 = sys_mmap(64) as *i64
194 ur_init(u, 64)
195 ur_std(u)
196 let iFX: i64 = ur_find(u, "fx256mm" as *u8)
197 let iTHOU: i64 = ur_find(u, "thou" as *u8)
198 let uout: *i64 = sys_mmap(16) as *i64
199 // output builder
200 let b: *i64 = sys_mmap(64) as *i64
201 swb_init(b, K_MAGIC_4194304)
202 swb_s(b, "// nx_explodelab_meshes.nx -- GENERATED by nx_explodelab_meshgen (do not hand-edit): the REAL 53/53" as *u8)
203 swb_c(b, 10)
204 swb_s(b, "// file-true as1 part meshes for /explodelab, centered per part, world scale = fx256/8 (32 units/mm)." as *u8)
205 swb_c(b, 10)
206 swb_s(b, "// exm_load(e,kind,col): 1 nut, 2 bolt, 3 rod, 4 plate, 5 l-bracket. exm_dims = TRUE mm (fx256) + thou." as *u8)
207 swb_c(b, 10)
208 swb_s(b, "// license_tier: ORIGINAL" as *u8)
209 swb_c(b, 10)
210 swb_s(b, "import " as *u8)
211 swb_c(b, 34)
212 swb_s(b, "nx_explode3d.nx" as *u8)
213 swb_c(b, 34)
214 swb_c(b, 10)
215 // per kind: name order 1..5
216 let vcnt: *i64 = sys_mmap(64) as *i64
217 let tcnt: *i64 = sys_mmap(64) as *i64
218 let dims: *i64 = sys_mmap(256) as *i64 // per kind: w,h,d fx + thou
219 let out4: *i64 = sys_mmap(32) as *i64
220 var kind: i64 = 1
221 while kind <= 5 {
222 // find the part index by name
223 var want: i64 = 0 - 1
224 var pi: i64 = 0
225 while pi < np {
226 var m: i64 = 0
227 if kind == 1 { m = sp_prod_name_is(st, prodidx[pi], "nut" as *u8) }
228 if kind == 2 { m = sp_prod_name_is(st, prodidx[pi], "bolt" as *u8) }
229 if kind == 3 { m = sp_prod_name_is(st, prodidx[pi], "rod" as *u8) }
230 if kind == 4 { m = sp_prod_name_is(st, prodidx[pi], "plate" as *u8) }
231 if kind == 5 { m = sp_prod_name_is(st, prodidx[pi], "l-bracket" as *u8) }
232 if m == 1 { want = pi }
233 pi = pi + 1
234 }
235 if want < 0 { sp_puts("part missing\nRED\n" as *u8); return 1 }
236 let mesh: i64 = sys_mmap(m3_bytes()) as i64
237 m3_init(mesh)
238 tt[1] = mesh
239 nt[1] = mesh
240 cr_tess_part(tt, nt, t2, slab, shellidx[want], out4)
241 cr_weld(mesh)
242 let h: *i64 = m3_hdr(mesh)
243 // bbox + center
244 var mn0: i64 = 0
245 var mx0: i64 = 0
246 var mn1: i64 = 0
247 var mx1: i64 = 0
248 var mn2: i64 = 0
249 var mx2: i64 = 0
250 if h[0] > 0 {
251 let v0: *i64 = m3_vert(mesh, 0)
252 mn0 = v0[0]; mx0 = v0[0]; mn1 = v0[1]; mx1 = v0[1]; mn2 = v0[2]; mx2 = v0[2]
253 var vi: i64 = 1
254 while vi < h[0] {
255 let v: *i64 = m3_vert(mesh, vi)
256 if v[0] < mn0 { mn0 = v[0] }
257 if v[0] > mx0 { mx0 = v[0] }
258 if v[1] < mn1 { mn1 = v[1] }
259 if v[1] > mx1 { mx1 = v[1] }
260 if v[2] < mn2 { mn2 = v[2] }
261 if v[2] > mx2 { mx2 = v[2] }
262 vi = vi + 1
263 }
264 }
265 let cx3: *i64 = sys_mmap(32) as *i64
266 cx3[0] = (mn0 + mx0) / 2
267 cx3[1] = (mn1 + mx1) / 2
268 cx3[2] = (mn2 + mx2) / 2
269 mg_part(b, mesh, kind, cx3)
270 vcnt[kind] = h[0]
271 tcnt[kind] = h[1]
272 dims[kind * 4] = mx0 - mn0
273 dims[kind * 4 + 1] = mx1 - mn1
274 dims[kind * 4 + 2] = mx2 - mn2
275 var ext: i64 = mx0 - mn0
276 if mx1 - mn1 > ext { ext = mx1 - mn1 }
277 if mx2 - mn2 > ext { ext = mx2 - mn2 }
278 ur_conv(u, ext, iFX, iTHOU, uout)
279 dims[kind * 4 + 3] = uout[0]
280 sp_puts(" kind " as *u8); sp_putn(kind)
281 sp_puts(": verts=" as *u8); sp_putn(h[0])
282 sp_puts(" tris=" as *u8); sp_putn(h[1])
283 sp_puts(" maxext-thou=" as *u8); sp_putn(uout[0]); sp_puts("\n" as *u8)
284 kind = kind + 1
285 }
286 // dispatcher + tables
287 swb_s(b, "func exm_load(e: *i64, kind: i64, cx: i64, cy: i64, cz: i64, col: i64) -> i64 " as *u8)
288 swb_c(b, 123)
289 swb_c(b, 10)
290 kind = 1
291 while kind <= 5 {
292 swb_s(b, " if kind == " as *u8)
293 swb_n(b, kind)
294 swb_s(b, " " as *u8)
295 swb_c(b, 123)
296 swb_s(b, " return exm_k" as *u8)
297 swb_n(b, kind)
298 swb_s(b, "(e, cx, cy, cz, col) " as *u8)
299 swb_c(b, 125)
300 swb_c(b, 10)
301 kind = kind + 1
302 }
303 swb_s(b, " return 0 - 1" as *u8)
304 swb_c(b, 10)
305 swb_c(b, 125)
306 swb_c(b, 10)
307 swb_s(b, "func exm_counts(kind: i64, out2: *i64) -> i64 " as *u8)
308 swb_c(b, 123)
309 swb_c(b, 10)
310 kind = 1
311 while kind <= 5 {
312 swb_s(b, " if kind == " as *u8)
313 swb_n(b, kind)
314 swb_s(b, " " as *u8)
315 swb_c(b, 123)
316 swb_s(b, " out2[0] = " as *u8)
317 swb_n(b, vcnt[kind])
318 swb_s(b, "; out2[1] = " as *u8)
319 swb_n(b, tcnt[kind])
320 swb_s(b, "; return 1 " as *u8)
321 swb_c(b, 125)
322 swb_c(b, 10)
323 kind = kind + 1
324 }
325 swb_s(b, " return 0" as *u8)
326 swb_c(b, 10)
327 swb_c(b, 125)
328 swb_c(b, 10)
329 swb_s(b, "func exm_dims(kind: i64, out4: *i64) -> i64 " as *u8)
330 swb_c(b, 123)
331 swb_c(b, 10)
332 kind = 1
333 while kind <= 5 {
334 swb_s(b, " if kind == " as *u8)
335 swb_n(b, kind)
336 swb_s(b, " " as *u8)
337 swb_c(b, 123)
338 swb_s(b, " out4[0] = " as *u8)
339 swb_n(b, dims[kind * 4])
340 swb_s(b, "; out4[1] = " as *u8)
341 swb_n(b, dims[kind * 4 + 1])
342 swb_s(b, "; out4[2] = " as *u8)
343 swb_n(b, dims[kind * 4 + 2])
344 swb_s(b, "; out4[3] = " as *u8)
345 swb_n(b, dims[kind * 4 + 3])
346 swb_s(b, "; return 1 " as *u8)
347 swb_c(b, 125)
348 swb_c(b, 10)
349 kind = kind + 1
350 }
351 swb_s(b, " return 0" as *u8)
352 swb_c(b, 10)
353 swb_c(b, 125)
354 swb_c(b, 10)
355 let fd: i64 = sys_openat_wr("runtime/nx_explodelab_meshes.nx" as *u8, 420)
356 if fd < 0 { sp_puts("open fail\nRED\n" as *u8); return 1 }
357 sys_write(fd, b[0] as *u8, b[1])
358 sys_close(fd)
359 sp_puts("wrote runtime/nx_explodelab_meshes.nx bytes=" as *u8); sp_putn(b[1]); sp_puts("\nGREEN -- real meshes baked\n" as *u8)
360 return 0
361}