code wiki / (root) / nx_dcc_to_print_test.nx

nx_dcc_to_print_test.nx source

↩ module page · 108 lines · 5244 B

1// nx_dcc_to_print_test.nx -- DCC->PRINT CAPSTONE on AUTHORED, SCULPTED geometry. 2// 3// The cube capstone proved a hardcoded cube prints. This proves the WHOLE DCC 4// toolchain feeds the real pipeline: an icosphere built from an octahedron 5// (nx_mesh_sculpt) is SCULPTED with an inflate brush (a north-pole bump), placed 6// on the bed with the translate verb (nx_mesh_edit), exported with the GENERAL 7// writer (nx_stl_write_mesh), then run through the EXISTING reader + QIDI slicer + 8// G-code emitter -- supports auto-generated for the spherical overhangs. Every 9// geometry op is sovereign + gate-proven; the downstream fabrication stack is all 10// reused. model(sculpted) -> print, end to end. expect_exit: 0. 11 12import "nx_syscalls.nx" 13import "nx_mesh.nx" 14import "nx_mesh_edit.nx" 15import "nx_mesh_sculpt.nx" 16import "nx_stl_write.nx" 17import "nx_stl.nx" 18import "nx_machine_graph.nx" 19import "nx_material_profile.nx" 20import "nx_gcode_emit.nx" 21import "nx_slice_pipeline.nx" 22 23func w(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } 24func wn(v: i64) -> i64 { 25 let b: *u8 = sys_mmap(28); var m: i64 = v 26 if m < 0 { m = 0 - m; sys_write(1, "-" as *u8, 1) } 27 let t: *u8 = sys_mmap(28); var k: i64 = 0 28 if m == 0 { t[0] = 48 as u8; k = 1 } 29 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 30 var i: i64 = 0; while i < k { b[i] = t[k - 1 - i]; i = i + 1 } 31 sys_write(1, b, k); return 0 32} 33func smoke_count(buf: *u8, len: i64, needle: *u8) -> i64 { 34 var nlen: i64 = 0; while needle[nlen] != 0 { nlen = nlen + 1 } 35 if len < nlen { return 0 } 36 var count: i64 = 0; var i: i64 = 0; let last: i64 = len - nlen 37 while i <= last { 38 var j: i64 = 0; var matched: i64 = 1 39 while j < nlen { if buf[i + j] != needle[j] { matched = 0; j = nlen } j = j + 1 } 40 if matched == 1 { count = count + 1 } 41 i = i + 1 42 } 43 return count 44} 45func chk(cond: i64, pass: *i64, fail: *i64, label: *u8) -> i64 { 46 if cond == 1 { pass[0] = pass[0] + 1; w(" ok " as *u8); w(label); w("\n" as *u8) } 47 else { fail[0] = fail[0] + 1; w(" XX " as *u8); w(label); w("\n" as *u8) } 48 return 0 49} 50func eqi(a: i64, b: i64) -> i64 { if a == b { return 1 } return 0 } 51 52func main() -> i64 { 53 let pass: *i64 = (sys_mmap(8)) as *i64 54 let fail: *i64 = (sys_mmap(8)) as *i64 55 pass[0] = 0 56 fail[0] = 0 57 let bb: *i64 = (sys_mmap(48)) as *i64 58 w("=== DCC->print: sculpted icosphere -> existing QIDI slicer -> G-code ===\n" as *u8) 59 60 // 1. AUTHOR in our Blender/ZBrush-class tools: icosphere + inflate brush 61 let model: *NxMesh = nx_mesh_make_icosphere(163840, 2, 0) // 10mm radius, subdiv 2 62 nx_mesh_sculpt_brush(model, 0, 0, 163840, 81920, 32768) // +2mm bump at north pole 63 chk(eqi(model.n_tris, 128), pass, fail, "authored sculpted mesh: 128 tris" as *u8) 64 65 // 2. PLACE on the bed with the translate verb (corner -> origin, z>=0) 66 nx_mesh_aabb(model, bb) 67 nx_mesh_translate(model, 0 - bb[0], 0 - bb[1], 0 - bb[2]) 68 nx_mesh_aabb(model, bb) 69 chk(eqi(bb[2], 0), pass, fail, "model sits on bed (min_z = 0)" as *u8) 70 let height_mm: i64 = bb[5] / 16384 71 w(" model z-height(mm)=" as *u8); wn(height_mm); w("\n" as *u8) 72 73 // 3. EXPORT with the general writer 74 let stl: *u8 = sys_mmap(16384) 75 let n: i64 = nx_stl_write_mesh(stl, model) 76 chk(eqi(n, 84 + 50 * 128), pass, fail, "STL written (84 + 50*128 = 6484 B)" as *u8) 77 78 // 4. EXISTING reader 79 let r: *NxStlResult = nx_stl_load_binary(stl, n) 80 chk(eqi(r.verdict, NX_STL_OK), pass, fail, "existing reader OK on sculpted STL" as *u8) 81 chk(eqi(r.n_tris_header, 128), pass, fail, "reader sees 128 triangles" as *u8) 82 let mesh: *NxMesh = r.mesh 83 84 // 5. EXISTING QIDI slicer -> G-code (supports auto-built for overhangs) 85 let qidi: *NxMachineGraph = nx_machine_graph_qidi_xmax3() 86 let pla: *NxMaterialProfile = nx_material_profile_generic_pla() 87 let lh: i64 = 3277 // 0.2mm layer 88 let lw: i64 = 6554 // 0.4mm width 89 let e: *NxGcodeEmitter = nx_gemit_new(qidi, pla, lh, lw, 4194304) 90 chk((e as i64) != 0, pass, fail, "gcode emitter created" as *u8) 91 nx_gemit_preamble(e) 92 let n_layers: i64 = nx_slice_pipe_run_v2(e, mesh, 20, lh) // 20% infill 93 let n_g1: i64 = smoke_count(e.buf, e.len, "G1 X" as *u8) 94 w(" layers=" as *u8); wn(n_layers) 95 w(" gcode_bytes=" as *u8); wn(e.len); w(" G1_moves=" as *u8); wn(n_g1); w("\n" as *u8) 96 97 // 6. real G-code assertions (~22mm @0.2mm ~ 110 layers) 98 chk(n_layers >= 50, pass, fail, "sliced >= 50 layers" as *u8) 99 chk(n_layers <= 250, pass, fail, "layer count sane (<=250)" as *u8) 100 chk(smoke_count(e.buf, e.len, "M104 S" as *u8) >= 1, pass, fail, "hotend heat command present" as *u8) 101 chk(smoke_count(e.buf, e.len, "M84" as *u8) >= 1, pass, fail, "motors-off at end present" as *u8) 102 chk(n_g1 >= 100, pass, fail, "many G1 extrusion moves" as *u8) 103 chk(e.len >= 10000, pass, fail, "substantial real G-code emitted" as *u8) 104 105 w("=== VERDICT pass=" as *u8); wn(pass[0]); w(" fail=" as *u8); wn(fail[0]); w(" ===\n" as *u8) 106 if fail[0] == 0 { return 0 } 107 return 1 108}