| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566 |
- 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
|