preview_utils.py 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. import os
  2. import matplotlib
  3. matplotlib.use('Agg')
  4. import matplotlib.pyplot as plt
  5. from stl import mesh
  6. from mpl_toolkits import mplot3d
  7. def generate_stl_preview(stl_path: str, output_path: str):
  8. """
  9. Generates a PNG preview image for an STL file.
  10. Optimized for large files using decimation and smaller figure size.
  11. """
  12. try:
  13. # Load the STL file
  14. your_mesh = mesh.Mesh.from_file(stl_path)
  15. # Decimate if too many triangles to avoid OOM and slow rendering
  16. # 20,000 triangles is plenty for a small thumbnail
  17. vectors = your_mesh.vectors
  18. if len(vectors) > 20000:
  19. step = len(vectors) // 20000
  20. vectors = vectors[::step]
  21. # Create a new plot with smaller size for faster rendering
  22. figure = plt.figure(figsize=(4, 4))
  23. # Use transparent background
  24. figure.patch.set_alpha(0.0)
  25. axes = figure.add_subplot(111, projection='3d')
  26. axes.set_facecolor((0,0,0,0))
  27. # Add the mesh to the plot
  28. poly = mplot3d.art3d.Poly3DCollection(vectors)
  29. # Professional-looking blue/gray color
  30. poly.set_facecolor([0.2, 0.5, 0.8, 0.9])
  31. poly.set_edgecolor([0.1, 0.1, 0.1, 0.1]) # Reduced edge opacity
  32. axes.add_collection3d(poly)
  33. # Auto-scale the plot using original mesh bounds for accuracy
  34. scale = your_mesh.points.flatten()
  35. axes.auto_scale_xyz(scale, scale, scale)
  36. # Hide axes
  37. axes.set_axis_off()
  38. # Adjust view
  39. axes.view_init(elev=30, azim=45)
  40. # Save with lower DPI for speed
  41. plt.savefig(output_path, dpi=80, bbox_inches='tight', transparent=True)
  42. plt.close(figure)
  43. return True
  44. except Exception as e:
  45. print(f"Error generating preview: {e}")
  46. return False