diff --git a/core/nodeslicer/nodes/output.py b/core/nodeslicer/nodes/output.py index e1e353f..c79f985 100644 --- a/core/nodeslicer/nodes/output.py +++ b/core/nodeslicer/nodes/output.py @@ -25,8 +25,7 @@ class SLICENODE_GcodeToFile(ExecSliceNode): super().draw_buttons(context, layout) def evaluate(self, operator=None): - from ....infra.networking.bgcode import convert_to_bgcode - from ....infra.networking.gcode_utils import get_gcode_name_from_metadata + from ....infra.networking.gcode_utils import get_gcode_name_from_metadata, prepare_gcode_file gcodes: list[str] = [gc for gc in self.resolve_multi_input('Gcode') if gc] @@ -49,20 +48,14 @@ class SLICENODE_GcodeToFile(ExecSliceNode): name_part = basename.split('.')[0] os.makedirs(dirname, exist_ok=True) - # Detect binary trigger in gcode comments - is_binary = "; binary_gcode = 1" in gc - try: - if is_binary: - filepath = os.path.join(dirname, name_part + ".bgcode") - content = convert_to_bgcode(gc, name_part, True) - with open(filepath, "wb") as f: - f.write(content) + file_bytes, filename = prepare_gcode_file(gc, name_part) + filepath = os.path.join(dirname, filename) + with open(filepath, "wb") as f: + f.write(file_bytes) + if filename.endswith(".bgcode"): if operator: operator.report({'INFO'}, f"Binary G-code generated at {filepath}") else: - filepath = os.path.join(dirname, name_part + ".gcode") - with open(filepath, "w", encoding="utf-8", newline="\n") as f: - f.write(gc) if operator: operator.report({'INFO'}, f"G-code saved to {filepath}") except Exception as e: if operator: operator.report({'ERROR'}, str(e)) @@ -149,14 +142,23 @@ class SLICENODE_StartPrint(ExecSliceNode): if operator: operator.report({'ERROR'}, f"Unsupported host type: {config.host_type}") return 'unsupported' + from ....infra.networking.gcode_utils import prepare_gcode_file + # Write to temp file to send - with tempfile.NamedTemporaryFile(mode='w', suffix='.gcode', delete=False) as tf: - tf.write(gcode) + name_part = f"NodeSlicer_{config.label}".replace(" ", "_") + try: + file_bytes, filename = prepare_gcode_file(gcode, name_part) + except Exception as e: + if operator: operator.report({'ERROR'}, f"Failed to prepare G-code: {str(e)}") + return 'error' + + suffix = Path(filename).suffix + with tempfile.NamedTemporaryFile(mode='wb', suffix=suffix, delete=False) as tf: + tf.write(file_bytes) temp_path = Path(tf.name) try: - print_name = f"NodeSlicer_{config.label}.gcode".replace(" ", "_") - backend.start_print(temp_path, print_name) + backend.start_print(temp_path, filename) if operator: operator.report({'INFO'}, f"Print started on {config.label}") except Exception as e: if operator: operator.report({'ERROR'}, f"Failed to start print: {str(e)}") diff --git a/core/nodeslicer/nodes/system.py b/core/nodeslicer/nodes/system.py index 95db19e..06ac285 100644 --- a/core/nodeslicer/nodes/system.py +++ b/core/nodeslicer/nodes/system.py @@ -72,6 +72,7 @@ class SLICENODE_PrinterList(ExecSliceNode): CrealityBackend, MoonrakerBackend ) + from ....infra.networking.gcode_utils import prepare_gcode_file self._refresh() @@ -124,13 +125,20 @@ class SLICENODE_PrinterList(ExecSliceNode): continue # Write to temp file to send - with tempfile.NamedTemporaryFile(mode='w', suffix='.gcode', delete=False) as tf: - tf.write(gcode) + name_part = f"NodeSlicer_{sock.name}".replace(" ", "_") + try: + file_bytes, filename = prepare_gcode_file(gcode, name_part) + except Exception as e: + if operator: operator.report({'ERROR'}, f"Failed to prepare G-code for {sock.name}: {str(e)}") + continue + + suffix = Path(filename).suffix + with tempfile.NamedTemporaryFile(mode='wb', suffix=suffix, delete=False) as tf: + tf.write(file_bytes) temp_path = Path(tf.name) try: - print_name = f"NodeSlicer_{sock.name}.gcode".replace(" ", "_") - backend.start_print(temp_path, print_name) + backend.start_print(temp_path, filename) if operator: operator.report({'INFO'}, f"Print started on {sock.name}") any_printed = True except Exception as e: diff --git a/infra/networking/gcode_utils.py b/infra/networking/gcode_utils.py index 4d32205..e47bd97 100644 --- a/infra/networking/gcode_utils.py +++ b/infra/networking/gcode_utils.py @@ -57,3 +57,18 @@ def get_gcode_name_from_metadata(gcode: str, default: str = "output") -> str: except: pass return default + + +def prepare_gcode_file(gcode: str, name_part: str) -> tuple[bytes, str]: + """ + Checks if the G-code string contains instructions to generate binary BGcode. + Converts to binary if needed. + Returns a tuple of (file_bytes, filename_with_suffix). + """ + is_binary = "; binary_gcode = 1" in gcode + if is_binary: + from .bgcode import convert_to_bgcode + bgcode_bytes = convert_to_bgcode(gcode, name_part, True) + return bgcode_bytes, f"{name_part}.bgcode" + else: + return gcode.encode("utf-8"), f"{name_part}.gcode"