code wiki / _hdl_build / nx_slicer.nx

nx_slicer.nx source

↩ module page · 92 lines · 3383 B

1// nx_slicer.nx -- sovereign STL -> G-code slicer (CLI / MCP organ). 2// 3// nx_slicer slice <stl-path> <gcode-out-path> [layer_h_um] [infill_pct] 4// 5// Reads a binary STL, slices it through the sovereign stack (nx_slicer_lib -> 6// nx_stl + nx_gemit + nx_slice_pipe_run_v2 on the QIDI X-Max 3 machine profile 7// + generic PLA), writes the G-code file, and emits a summary JSON. The 8// sovereign alternative to third-party slicers -- our own geometry->toolpath. 9// 10// license_tier: ORIGINAL No hw writes (Rule 26). expect_exit: 0 11import "nx_syscalls.nx" 12import "nx_gcode_emit.nx" 13import "nx_slicer_lib.nx" 14const SL_MAGIC_4096: i64 = 4096 15 16const SL_LH_DEFAULT: i64 = 3277 // 0.2 mm in the slicer's Q14 units 17const SL_Q_PER_MM: i64 = 16384 18 19func slw(fd: i64, s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(fd, s, n); return 0 } 20 21func main(argc: i64, argv: *i64) -> i64 { 22 if argc < 4 { 23 slw(2, "usage: nx_slicer slice <stl-path> <gcode-out-path> [layer_h_um] [infill_pct]\n" as *u8) 24 sys_exit(2) 25 return 2 26 } 27 let stl_path: *u8 = argv[2] as *u8 28 let out_path: *u8 = argv[3] as *u8 29 var layer_h: i64 = SL_LH_DEFAULT 30 if argc > 4 { 31 let um: i64 = sl_atoi(argv[4] as *u8) 32 if um > 0 { layer_h = (um * SL_Q_PER_MM) / 1000 } 33 } 34 var infill: i64 = 20 35 if argc > 5 { 36 let inf: i64 = sl_atoi(argv[5] as *u8) 37 if inf >= 0 { infill = inf } 38 } 39 40 let out: *u8 = sys_mmap(SL_MAGIC_4096) 41 let lenp: *i64 = sys_mmap(8) as *i64 42 let stl: *u8 = sys_read_file(stl_path, lenp) 43 if (stl as i64) == 0 { 44 let eo: i64 = sl_cat(out, 0, "{\"verb\":\"slice\",\"verdict\":\"READ_FAIL\",\"stl\":\"" as *u8) 45 let eo2: i64 = sl_cat(out, eo, stl_path) 46 let eo3: i64 = sl_cat(out, eo2, "\"}\n" as *u8) 47 sys_write(1, out, eo3) 48 sys_exit(1) 49 return 1 50 } 51 let stl_len: i64 = lenp[0] 52 53 let nl: *i64 = sys_mmap(8) as *i64 54 let nt: *i64 = sys_mmap(8) as *i64 55 let e: *NxGcodeEmitter = sl_slice_stl(stl, stl_len, layer_h, infill, nl, nt) 56 if (e as i64) == 0 { 57 let eo: i64 = sl_cat(out, 0, "{\"verb\":\"slice\",\"verdict\":\"SLICE_FAIL\",\"note\":\"STL parse or slice produced no layers\"}\n" as *u8) 58 sys_write(1, out, eo) 59 sys_exit(1) 60 return 1 61 } 62 63 let fd: i64 = sys_openat_wr(out_path, 0x1a4) 64 if fd < 0 { 65 let eo: i64 = sl_cat(out, 0, "{\"verb\":\"slice\",\"verdict\":\"WRITE_FAIL\"}\n" as *u8) 66 sys_write(1, out, eo) 67 sys_exit(1) 68 return 1 69 } 70 sys_write(fd, e.buf, e.len) 71 sys_close(fd) 72 73 var o: i64 = 0 74 o = sl_cat(out, o, "{\"verb\":\"slice\",\"verdict\":\"OK\",\"stl\":\"" as *u8) 75 o = sl_cat(out, o, stl_path) 76 o = sl_cat(out, o, "\",\"gcode\":\"" as *u8) 77 o = sl_cat(out, o, out_path) 78 o = sl_cat(out, o, "\",\"n_tris\":" as *u8) 79 o = sl_catn(out, o, nt[0]) 80 o = sl_cat(out, o, ",\"n_layers\":" as *u8) 81 o = sl_catn(out, o, nl[0]) 82 o = sl_cat(out, o, ",\"gcode_bytes\":" as *u8) 83 o = sl_catn(out, o, e.len) 84 o = sl_cat(out, o, ",\"layer_h_q14\":" as *u8) 85 o = sl_catn(out, o, layer_h) 86 o = sl_cat(out, o, ",\"infill_pct\":" as *u8) 87 o = sl_catn(out, o, infill) 88 o = sl_cat(out, o, ",\"machine\":\"qidi-xmax3\",\"material\":\"pla\"}\n" as *u8) 89 sys_write(1, out, o) 90 sys_exit(0) 91 return 0 92}