| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576 |
- 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 and sizes
- volume_match = re.search(r"volume\s*=\s*([\d\.]+)", content)
- size_x_match = re.search(r"size_x\s*=\s*([\d\.]+)", content)
- size_y_match = re.search(r"size_y\s*=\s*([\d\.]+)", content)
- size_z_match = re.search(r"size_z\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
-
- dimensions_str = ""
- if size_x_match and size_y_match and size_z_match:
- x = round(float(size_x_match.group(1)), 1)
- y = round(float(size_y_match.group(1)), 1)
- z = round(float(size_z_match.group(1)), 1)
- dimensions_str = f"{x} x {y} x {z} mm"
- # 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
- 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,
- "dimensions": dimensions_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
|