nx_cube_to_gcode_test.nx source
↩ module page · 87 lines · 3959 B
1// nx_cube_to_gcode_test.nx -- MODEL->PRINT CAPSTONE: geometry I created
2// (nx_stl_write_cube) -> existing nx_stl_load_binary -> existing QIDI slicer
3// (nx_slice_pipe_run_v2) -> real G-code. Proves the DCC-export side feeds the
4// whole existing fabrication pipeline end-to-end, all sovereign, no dup.
5// expect_exit: 0.
6
7import "nx_syscalls.nx"
8import "nx_mesh.nx"
9import "nx_stl.nx"
10import "nx_stl_write.nx"
11import "nx_machine_graph.nx"
12import "nx_material_profile.nx"
13import "nx_gcode_emit.nx"
14import "nx_slice_pipeline.nx"
15
16func w(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 }
17func wn(v: i64) -> i64 {
18 let b: *u8 = sys_mmap(28); var m: i64 = v
19 if m < 0 { m = 0 - m; sys_write(1, "-" as *u8, 1) }
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 { b[i] = t[k - 1 - i]; i = i + 1 }
24 sys_write(1, b, k); return 0
25}
26func smoke_count(buf: *u8, len: i64, needle: *u8) -> i64 {
27 var nlen: i64 = 0; while needle[nlen] != 0 { nlen = nlen + 1 }
28 if len < nlen { return 0 }
29 var count: i64 = 0; var i: i64 = 0; let last: i64 = len - nlen
30 while i <= last {
31 var j: i64 = 0; var matched: i64 = 1
32 while j < nlen { if buf[i + j] != needle[j] { matched = 0; j = nlen } j = j + 1 }
33 if matched == 1 { count = count + 1 }
34 i = i + 1
35 }
36 return count
37}
38func chk(cond: i64, pass: *i64, fail: *i64, label: *u8) -> i64 {
39 if cond == 1 { pass[0] = pass[0] + 1; w(" ok " as *u8); w(label); w("\n" as *u8) }
40 else { fail[0] = fail[0] + 1; w(" XX " as *u8); w(label); w("\n" as *u8) }
41 return 0
42}
43
44func main() -> i64 {
45 let pass: *i64 = (sys_mmap(8)) as *i64
46 let fail: *i64 = (sys_mmap(8)) as *i64
47 pass[0] = 0
48 fail[0] = 0
49 w("=== model->print: MY cube STL -> existing QIDI slicer -> G-code ===\n" as *u8)
50
51 // 1. geometry I authored
52 let stl: *u8 = sys_mmap(2048)
53 let n: i64 = nx_stl_write_cube(stl, 20) // 20mm cube
54 chk(n == 684, pass, fail, "wrote 12-tri cube STL (684B)" as *u8)
55
56 // 2. existing reader
57 let r: *NxStlResult = nx_stl_load_binary(stl, n)
58 chk(r.verdict == NX_STL_OK, pass, fail, "existing reader OK" as *u8)
59 chk(r.n_tris_header == 12, pass, fail, "12 triangles" as *u8)
60 let mesh: *NxMesh = r.mesh
61 chk(mesh.n_verts == 8, pass, fail, "8 cube vertices" as *u8)
62
63 // 3. existing QIDI slicer -> G-code
64 let qidi: *NxMachineGraph = nx_machine_graph_qidi_xmax3()
65 let pla: *NxMaterialProfile = nx_material_profile_generic_pla()
66 let lh: i64 = 3277 // 0.2mm layer
67 let lw: i64 = 6554 // 0.4mm width
68 let e: *NxGcodeEmitter = nx_gemit_new(qidi, pla, lh, lw, 4194304)
69 chk((e as i64) != 0, pass, fail, "gcode emitter created" as *u8)
70 nx_gemit_preamble(e)
71 let n_layers: i64 = nx_slice_pipe_run_v2(e, mesh, 20, lh)
72 w(" layers=" as *u8); wn(n_layers)
73 let n_g1: i64 = smoke_count(e.buf, e.len, "G1 X" as *u8)
74 w(" gcode_bytes=" as *u8); wn(e.len); w(" G1_moves=" as *u8); wn(n_g1); w("\n" as *u8)
75
76 // 4. real G-code assertions (20mm cube @0.2mm ~ 100 layers; no supports needed)
77 chk(n_layers >= 50, pass, fail, "sliced >=50 layers (20mm/0.2mm ~100)" as *u8)
78 chk(n_layers <= 250, pass, fail, "layer count sane" as *u8)
79 chk(smoke_count(e.buf, e.len, "M104 S" as *u8) >= 1, pass, fail, "hotend heat command present" as *u8)
80 chk(smoke_count(e.buf, e.len, "M84" as *u8) >= 1, pass, fail, "motors-off at end present" as *u8)
81 chk(n_g1 >= 100, pass, fail, "many G1 extrusion moves" as *u8)
82 chk(e.len >= 10000, pass, fail, "substantial real G-code emitted" as *u8)
83
84 w("=== VERDICT pass=" as *u8); wn(pass[0]); w(" fail=" as *u8); wn(fail[0]); w(" ===\n" as *u8)
85 if fail[0] == 0 { return 0 }
86 return 1
87}