code wiki / _hdl_build / nx_print_e2e_gate.nx
nx_print_e2e_gate.nx source
↩ module page · 100 lines · 5572 B
1// nx_print_e2e_gate.nx -- GATE: 3D-printing R1-e2e. The FULL chain, end to end, with a REAL STL: an authored
2// cube STL -> the existing reader (nx_stl_load_binary) -> the existing slicer (bbox + BVH + nx_slice_plane ->
3// nx_slice_contour_build) -> a real NxPolygon contour -> my bridge (cb_polygon_to_contour) -> the multi-
4// material emitter (cb_emit_polygon) -> concrete G-code. Proves the sliced geometry of a real model reaches
5// any material, all sovereign, never-brick. license_tier: ORIGINAL
6import "nx_stl_write.nx"
7import "nx_stl.nx"
8import "nx_mesh.nx"
9import "nx_mesh_print_check.nx"
10import "nx_bvh.nx"
11import "nx_slice_plane.nx"
12import "nx_slice_contour.nx"
13import "nx_slice_bridge.nx"
14import "nx_syscalls.nx"
15import "nx_gate_verdict.nx"
16
17func g_p(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 }
18func g_i(v: i64) -> i64 {
19 let bb: *u8 = sys_mmap(28); var m: i64 = v
20 if m < 0 { sys_write(1, "-" as *u8, 1); m = 0 - m }
21 let t: *u8 = sys_mmap(28); var k: i64 = 0
22 if m == 0 { t[0] = 48 as u8; k = 1 }
23 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
24 var i: i64 = 0; while i < k { bb[i] = t[k - 1 - i]; i = i + 1 } sys_write(1, bb, k); return 0
25}
26
27func main() -> i64 {
28 g_p("=== nx_print_e2e_gate (R1-e2e: real STL -> slicer -> bridge -> multi-material G-code) ===\n" as *u8)
29 pm_seed("knowledge/store/print-" as *u8)
30
31 var pass: i64 = 0
32 var tot: i64 = 0
33
34 // 1. authored cube STL
35 let stl: *u8 = sys_mmap(4096)
36 let nstl: i64 = nx_stl_write_cube(stl, 20)
37 tot = tot + 1
38 if nstl == 684 { pass = pass + 1; g_p("PASS T1 authored a 20mm cube STL (684B, 12 triangles)\n" as *u8) } else { g_p("FAIL T1 nstl=" as *u8); g_i(nstl); g_p("\n" as *u8) }
39
40 // 2. existing reader -> mesh
41 let r: *NxStlResult = nx_stl_load_binary(stl, nstl)
42 let mesh: *NxMesh = r.mesh
43 tot = tot + 1
44 if r.verdict == NX_STL_OK { if mesh.n_verts == 8 { pass = pass + 1; g_p("PASS T2 existing reader loaded the mesh (8 cube vertices)\n" as *u8) } else { g_p("FAIL T2 verts\n" as *u8) } } else { g_p("FAIL T2 verdict\n" as *u8) }
45
46 // 3. existing slicer: bbox + BVH + slice at mid-height -> contours
47 let bbox: *NxMeshBBox = nx_mesh_bbox_compute(mesh)
48 let bvh: *NxBvh = nx_bvh_build(mesh)
49 let z_mid: i64 = (bbox.min_z + bbox.max_z) / 2
50 let soup: *NxSliceSoup = nx_slice_plane(mesh, bvh, z_mid)
51 let contours: *NxSliceContours = nx_slice_contour_build(soup)
52 let npoly: i64 = contours.n_polys
53 g_p("sliced at mid-height: contours=" as *u8); g_i(npoly); g_p("\n" as *u8)
54 tot = tot + 1
55 if bbox.valid == 1 { if npoly >= 1 { pass = pass + 1; g_p("PASS T3 the existing slicer produced a real cross-section contour\n" as *u8) } else { g_p("FAIL T3 npoly\n" as *u8) } } else { g_p("FAIL T3 bbox\n" as *u8) }
56
57 // 4. bridge the real NxPolygon -> mm contour; the cube cross-section is a ~20mm square
58 let poly: *NxPolygon = nx_slice_contours_get(contours, 0)
59 let xs: *i64 = sys_mmap(8 * 512) as *i64
60 let ys: *i64 = sys_mmap(8 * 512) as *i64
61 let nv: i64 = cb_polygon_to_contour(poly, xs, ys)
62 var mnx: i64 = xs[0]; var mxx: i64 = xs[0]
63 var i: i64 = 1
64 while i < nv { if xs[i] < mnx { mnx = xs[i] } if xs[i] > mxx { mxx = xs[i] } i = i + 1 }
65 let extent: i64 = mxx - mnx
66 g_p("bridged contour: verts=" as *u8); g_i(nv); g_p(" x-extent=" as *u8); g_i(extent); g_p("mm\n" as *u8)
67 tot = tot + 1
68 if nv >= 4 { if extent >= 15 { pass = pass + 1; g_p("PASS T4 bridged a real ~20mm square cross-section (verts>=4, extent~20mm)\n" as *u8) } else { g_p("FAIL T4 extent\n" as *u8) } } else { g_p("FAIL T4 verts\n" as *u8) }
69
70 // 5. emit the sliced contour as CONCRETE G-code via the multi-material emitter
71 let gc: *u8 = sys_mmap(131072)
72 let ngc: i64 = cb_emit_polygon("knowledge/store/print-" as *u8, "concrete" as *u8, poly, 50, gc)
73 tot = tot + 1
74 var ok5: i64 = 1
75 if ngc <= 0 { ok5 = 0 }
76 if as_contains(gc, ngc, "G1 X" as *u8) != 1 { ok5 = 0 }
77 if as_contains(gc, ngc, "M84" as *u8) != 1 { ok5 = 0 }
78 if as_contains(gc, ngc, "M997" as *u8) != 0 { ok5 = 0 } // never-brick
79 if as_contains(gc, ngc, "M500" as *u8) != 0 { ok5 = 0 }
80 if ok5 == 1 { pass = pass + 1; g_p("PASS T5 the sliced contour emitted as concrete G-code (" as *u8); g_i(ngc); g_p("B, never-brick)\n" as *u8) } else { g_p("FAIL T5 ngc=" as *u8); g_i(ngc); g_p("\n" as *u8) }
81
82 // 6. the chain
83 tot = tot + 1
84 if pass == 5 { pass = pass + 1; g_p("PASS T6 END-TO-END: real STL -> slice -> NxPolygon -> bridge -> multi-material G-code\n" as *u8) } else { g_p("FAIL T6 (earlier step failed)\n" as *u8) }
85
86 sys_mkdir("knowledge/staging" as *u8, 0x1ed)
87 sys_mkdir("knowledge/staging/print" as *u8, 0x1ed)
88 let fd: i64 = sys_openat_wr("knowledge/staging/print/cube_sliced_concrete.gcode" as *u8, 420); if fd >= 0 { sys_write(fd, gc, ngc); sys_close(fd) }
89
90 g_p("nx_print_e2e_gate pass=" as *u8); g_i(pass); g_p("/" as *u8); g_i(tot)
91 // MIGRATED onto nx_gate_verdict by nx_gate_dry_apply (D001, minimal form): every check
92 // row above is untouched, so the PASS/FAIL vector cannot change; only the hand-rolled
93 // verdict emission is replaced by the ONE shared base class. Proven by nx_gate_migrate verify.
94 let ctr__dry: *i64 = gv_ctr()
95 ctr__dry[0] = pass
96 ctr__dry[1] = tot
97 let rc__dry: i64 = gv_verdict("PRINT-E2E-GATE" as *u8, ctr__dry, "any STL -> any material, end to end, the pipeline is whole)" as *u8)
98 sys_exit(rc__dry)
99 return rc__dry
100}