import subprocess import os import re import logging import shutil from config import SLICER_PATH, SLICER_CONFIG logger = logging.getLogger(__name__) def slice_model(file_path: str): """ Runs PrusaSlicer CLI to extract the EXACT 3D volume of the STL/OBJ file using --info. Returns a dict with estimated print_time (str) and filament_used (g). """ if not shutil.which(SLICER_PATH): logger.error(f"Slicer not found at {SLICER_PATH}") return None cmd = [ SLICER_PATH, "--info", file_path ] try: # Run info extraction (very fast, no full G-code generation) process = subprocess.run(cmd, capture_output=True, text=True, check=True) content = process.stdout # Regex to find volume in mm3 # Format: volume = 87552.437500 volume_match = re.search(r"volume\s*=\s*([\d\.]+)", content) if not volume_match: logger.error("Volume could not be parsed from PrusaSlicer output.") return None volume_mm3 = float(volume_match.group(1)) volume_cm3 = volume_mm3 / 1000.0 # Estimate weight assuming average density of PLA/PETG (~1.25 g/cm3) filament_g = round(volume_cm3 * 1.25, 2) # Estimate printing time assuming average volumetric flow rate of ~10 mm3/s # (This is a very realistic average for standard 0.4mm nozzle including travel/supports) time_seconds = int(volume_mm3 / 10.0) hours = time_seconds // 3600 minutes = (time_seconds % 3600) // 60 if hours > 0: time_str = f"{hours}h {minutes}m" else: time_str = f"{minutes}m" return { "filament_g": filament_g, "print_time_str": time_str, "success": True } except subprocess.CalledProcessError as e: logger.error(f"Slicing info error: {e.stderr}") return None except Exception as e: logger.error(f"General error in slice_model: {e}") return None