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}