code wiki / (root) / nx_print_session.nx

nx_print_session.nx source

↩ module page · 133 lines · 4710 B

1// nx_print_session.nx -- ALL-IN-ONE push-and-play operator entry. 2// 3// Single function takes (mesh, machine, material, layer_h, line_w, 4// infill_pct, output_buffer_capacity) and: 5// 6// 1. nx_preflight_check (5 sanity gates; refuse on UNSAFE) 7// 2. nx_gemit_new + preamble 8// 3. nx_slice_pipe_run (multi-layer slice + perim + infill) 9// (slice_pipe internally calls skirt + postamble) 10// 4. Returns NxPrintSession with: 11// verdict (SAFE_PRINT / REFUSED) 12// preflight_reason (if REFUSED) 13// emitter pointer (G-code bytes in emitter.buf) 14// layer count 15// 16// Per cardinal feedback-engineering-sciences-bits-up-3d-print-first 17// + NISHI_3D_PRINT_BULLETPROOF_PREFLIGHT_ROADMAP: this is the 18// operator-facing "push and play" API. Instead of orchestrating 5+ 19// primitives by hand, operator calls one function -- substrate 20// refuses to emit G-code if any sanity gate fails. 21// 22// Composes EVERY shipped pre-print primitive: 23// nx_preflight (gate) 24// nx_machine_graph (machine envelope) 25// nx_material_profile (material spec) 26// nx_gcode_emit (orchestrator) 27// nx_slice_pipeline (multi-layer) 28// 29// Smoke verifies SAFE case (tetrahedron + Qidi + PLA = G-code 30// produced) + REFUSED case (oversize mesh → no G-code emitted, code 31// fails-loud + verdict carries reason). 32// 33// license_tier: ORIGINAL 34 35import "nx_syscalls.nx" 36import "nx_mesh.nx" 37import "nx_machine_graph.nx" 38import "nx_material_profile.nx" 39import "nx_preflight.nx" 40import "nx_gcode_emit.nx" 41import "nx_slice_pipeline.nx" 42 43// ===== sealed-enum verdicts ======================================== 44 45const NX_SESSION_OK: i64 = 0 46const NX_SESSION_REFUSED: i64 = 1 47const NX_SESSION_EMIT_ERR: i64 = 2 48 49func nx_session_verdict_name(v: i64) -> *u8 { 50 if v == NX_SESSION_OK { return "OK" } 51 if v == NX_SESSION_REFUSED { return "REFUSED" } 52 if v == NX_SESSION_EMIT_ERR { return "EMIT_ERR" } 53 return "UNKNOWN" 54} 55 56// ===== result struct =============================================== 57 58struct NxPrintSession { 59 verdict: i64, 60 preflight_reason: i64, // NX_PFR_* code; OK if verdict == OK 61 emitter: *NxGcodeEmitter, 62 n_layers: i64, 63} 64 65const NX_PRINT_SESSION_BYTES: i64 = 32 66 67// ===== run ========================================================= 68// 69// All-in-one push-and-play. Returns NxPrintSession pointer with: 70// verdict == NX_SESSION_OK + emitter populated + n_layers > 0 71// -> G-code in emitter.buf[0..emitter.len], operator can upload. 72// verdict == NX_SESSION_REFUSED + preflight_reason set 73// -> Substrate refused; operator must fix the input. 74// verdict == NX_SESSION_EMIT_ERR 75// -> G-code emission failed mid-way (capacity exceeded etc). 76 77func nx_print_session_run(mesh: *NxMesh, 78 machine: *NxMachineGraph, 79 material: *NxMaterialProfile, 80 layer_height_q14: i64, 81 line_width_q14: i64, 82 infill_density_pct: i64, 83 buf_capacity: i64) -> *NxPrintSession { 84 let s: *NxPrintSession = (sys_mmap(NX_PRINT_SESSION_BYTES)) as *NxPrintSession 85 s.verdict = NX_SESSION_OK 86 s.preflight_reason = NX_PFR_OK 87 s.emitter = 0 as *NxGcodeEmitter 88 s.n_layers = 0 89 90 // Step 1: preflight gate 91 let pf: *NxPreflightResult = nx_preflight_check(mesh, machine, material, 92 layer_height_q14, 93 line_width_q14, 94 material.print_speed_mms) 95 if pf.verdict != NX_PREFLIGHT_SAFE { 96 s.verdict = NX_SESSION_REFUSED 97 s.preflight_reason = pf.first_reason 98 return s 99 } 100 101 // Step 2: emitter 102 let e: *NxGcodeEmitter = nx_gemit_new(machine, material, 103 layer_height_q14, 104 line_width_q14, 105 buf_capacity) 106 if (e as i64) == 0 { 107 s.verdict = NX_SESSION_EMIT_ERR 108 return s 109 } 110 s.emitter = e 111 112 // Step 3: preamble + slice pipeline (which calls skirt + per-layer 113 // perimeter+infill + postamble internally) 114 nx_gemit_preamble(e) 115 if e.verdict != NX_GEMIT_OK { 116 s.verdict = NX_SESSION_EMIT_ERR 117 return s 118 } 119 120 let n: i64 = nx_slice_pipe_run(e, mesh, infill_density_pct) 121 if n <= 0 { 122 s.verdict = NX_SESSION_EMIT_ERR 123 return s 124 } 125 s.n_layers = n 126 127 if e.verdict != NX_GEMIT_OK { 128 s.verdict = NX_SESSION_EMIT_ERR 129 return s 130 } 131 132 return s 133}