import os import subprocess import tempfile import platform from pathlib import Path def get_bgcode_binary(): """Returns the path to the correct bgcode binary for the current platform.""" addon_dir = os.path.dirname(os.path.dirname(os.path.dirname(__file__))) os_name = platform.system() if os_name == "Windows": bin_name = "bgcode.exe" elif os_name == "Darwin": # macOS bin_name = "bgcode_mac" else: # Linux/Other bin_name = "bgcode" bin_path = os.path.join(addon_dir, "infra", "bin", bin_name) # Fallback to just "bgcode" if platform-specific one isn't found if not os.path.exists(bin_path): fallback_path = os.path.join(addon_dir, "infra", "bin", "bgcode") if os.path.exists(fallback_path): return fallback_path return bin_path def convert_to_bgcode(gcode: str, name_part: str, compress: bool = True) -> bytes: """ Converts a G-code string to binary BGCode using the internal bgcode tool. Returns the binary content of the converted file. """ bgcode_bin = get_bgcode_binary() if not os.path.exists(bgcode_bin): raise FileNotFoundError(f"bgcode binary not found at {bgcode_bin}") with tempfile.TemporaryDirectory() as tmpdir: tmp_gcode = Path(tmpdir) / (name_part + ".gcode") tmp_gcode.write_text(gcode, encoding="utf-8") # Run conversion: bgcode cmd = [bgcode_bin, str(tmp_gcode)] if compress: # Recommended settings for true binary bgcode cmd.extend([ "--slicer_metadata_compression=1", "--gcode_compression=3", "--gcode_encoding=2" ]) res = subprocess.run(cmd, capture_output=True, text=True) if res.returncode != 0: err_msg = res.stderr.strip() or res.stdout.strip() or "Unknown error" raise RuntimeError(f"bgcode conversion failed: {err_msg}") tmp_bgcode = tmp_gcode.with_suffix(".bgcode") if tmp_bgcode.exists(): return tmp_bgcode.read_bytes() else: raise FileNotFoundError("Failed to find generated .bgcode file")