code wiki / _hdl_build / nx_print_e2e_gate.nx

nx_print_e2e_gate.nx source

↩ module page · 93 lines · 5174 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" 15 16func 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 } 17func g_i(v: i64) -> i64 { 18 let bb: *u8 = sys_mmap(28); var m: i64 = v 19 if m < 0 { sys_write(1, "-" as *u8, 1); m = 0 - m } 20 let t: *u8 = sys_mmap(28); var k: i64 = 0 21 if m == 0 { t[0] = 48 as u8; k = 1 } 22 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 23 var i: i64 = 0; while i < k { bb[i] = t[k - 1 - i]; i = i + 1 } sys_write(1, bb, k); return 0 24} 25 26func main() -> i64 { 27 g_p("=== nx_print_e2e_gate (R1-e2e: real STL -> slicer -> bridge -> multi-material G-code) ===\n" as *u8) 28 pm_seed("knowledge/store/print-" as *u8) 29 30 var pass: i64 = 0 31 var tot: i64 = 0 32 33 // 1. authored cube STL 34 let stl: *u8 = sys_mmap(4096) 35 let nstl: i64 = nx_stl_write_cube(stl, 20) 36 tot = tot + 1 37 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) } 38 39 // 2. existing reader -> mesh 40 let r: *NxStlResult = nx_stl_load_binary(stl, nstl) 41 let mesh: *NxMesh = r.mesh 42 tot = tot + 1 43 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) } 44 45 // 3. existing slicer: bbox + BVH + slice at mid-height -> contours 46 let bbox: *NxMeshBBox = nx_mesh_bbox_compute(mesh) 47 let bvh: *NxBvh = nx_bvh_build(mesh) 48 let z_mid: i64 = (bbox.min_z + bbox.max_z) / 2 49 let soup: *NxSliceSoup = nx_slice_plane(mesh, bvh, z_mid) 50 let contours: *NxSliceContours = nx_slice_contour_build(soup) 51 let npoly: i64 = contours.n_polys 52 g_p("sliced at mid-height: contours=" as *u8); g_i(npoly); g_p("\n" as *u8) 53 tot = tot + 1 54 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) } 55 56 // 4. bridge the real NxPolygon -> mm contour; the cube cross-section is a ~20mm square 57 let poly: *NxPolygon = nx_slice_contours_get(contours, 0) 58 let xs: *i64 = sys_mmap(8 * 512) as *i64 59 let ys: *i64 = sys_mmap(8 * 512) as *i64 60 let nv: i64 = cb_polygon_to_contour(poly, xs, ys) 61 var mnx: i64 = xs[0]; var mxx: i64 = xs[0] 62 var i: i64 = 1 63 while i < nv { if xs[i] < mnx { mnx = xs[i] } if xs[i] > mxx { mxx = xs[i] } i = i + 1 } 64 let extent: i64 = mxx - mnx 65 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) 66 tot = tot + 1 67 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) } 68 69 // 5. emit the sliced contour as CONCRETE G-code via the multi-material emitter 70 let gc: *u8 = sys_mmap(131072) 71 let ngc: i64 = cb_emit_polygon("knowledge/store/print-" as *u8, "concrete" as *u8, poly, 50, gc) 72 tot = tot + 1 73 var ok5: i64 = 1 74 if ngc <= 0 { ok5 = 0 } 75 if as_contains(gc, ngc, "G1 X" as *u8) != 1 { ok5 = 0 } 76 if as_contains(gc, ngc, "M84" as *u8) != 1 { ok5 = 0 } 77 if as_contains(gc, ngc, "M997" as *u8) != 0 { ok5 = 0 } // never-brick 78 if as_contains(gc, ngc, "M500" as *u8) != 0 { ok5 = 0 } 79 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) } 80 81 // 6. the chain 82 tot = tot + 1 83 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) } 84 85 sys_mkdir("knowledge/staging" as *u8, 0x1ed) 86 sys_mkdir("knowledge/staging/print" as *u8, 0x1ed) 87 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) } 88 89 g_p("nx_print_e2e_gate pass=" as *u8); g_i(pass); g_p("/" as *u8); g_i(tot) 90 if pass == tot { g_p(" verdict=GREEN (any STL -> any material, end to end, the pipeline is whole)\n" as *u8); return 0 } 91 g_p(" verdict=RED\n" as *u8) 92 return 1 93}