有3d gcode预览,基本能按要求切片,但是缩放后切片会失败

This commit is contained in:
2026-04-12 17:09:19 +08:00
parent 3020957367
commit a3f8a31432
3280 changed files with 1433 additions and 634630 deletions

View File

@@ -6,30 +6,44 @@ import os
def simplify_stl(input_path, output_path, keep_ratio=0.1):
try:
# Load mesh using numpy-stl
m = mesh.Mesh.from_file(input_path)
vertices = m.vectors.reshape(-1, 3)
try:
import trimesh
mesh_data = trimesh.load(input_path, file_type='stl')
if hasattr(mesh_data, 'triangles'):
vertices = mesh_data.triangles.reshape(-1, 3)
else:
vertices = mesh_data.vertices[mesh_data.faces].reshape(-1, 3)
use_trimesh = True
except ImportError:
# Load mesh using numpy-stl fallback
m = mesh.Mesh.from_file(input_path)
vertices = m.vectors.reshape(-1, 3)
use_trimesh = False
min_v = vertices.min(axis=0)
max_v = vertices.max(axis=0)
bbox_size = max_v - min_v
max_dim = np.max(bbox_size)
if max_dim == 0:
m.save(output_path)
if use_trimesh:
mesh_data.export(output_path, file_type='stl')
else:
m.save(output_path)
return True
# Target roughly a resolution that gives us keep_ratio faces.
# This is a heuristic approach to grid-based vertex clustering.
# We start with a baseline resolution (e.g. 2% of max dimension)
# and adjust if needed.
grid_resolution = max_dim * 0.02
# Function to simplify given a grid size
def do_simplify(g_size):
v_idx = np.round((vertices - min_v) / g_size).astype(np.int32)
v_idx = np.round((vertices - min_v) / g_size).astype(np.int64)
# Fast 1D hash to avoid extremely slow np.unique(axis=0) on 2D arrays
max_idx = v_idx.max(axis=0) + 1
v_1d = v_idx[:, 0] + v_idx[:, 1] * max_idx[0] + v_idx[:, 2] * max_idx[0] * max_idx[1]
# Find unique grid cells and map old vertices to them
_, unique_idx, inv_idx = np.unique(v_idx, axis=0, return_index=True, return_inverse=True)
_, unique_idx, inv_idx = np.unique(v_1d, return_index=True, return_inverse=True)
new_verts = vertices[unique_idx]
# Map faces to new vertices
@@ -41,9 +55,36 @@ def simplify_stl(input_path, output_path, keep_ratio=0.1):
return new_verts, valid_faces
new_vertices, valid_faces = do_simplify(grid_resolution)
target_faces = max(1, int((len(vertices) // 3) * keep_ratio))
low_g = max_dim * 0.0005
high_g = max_dim * 0.2
best_verts = vertices
best_faces = np.arange(len(vertices)).reshape(-1, 3)
# Build the simplified mesh
# Binary search for the right grid size
for _ in range(8):
g_size = (low_g + high_g) / 2
v, f = do_simplify(g_size)
best_verts, best_faces = v, f
if len(f) > target_faces:
# too many faces, make grid coarser (larger)
low_g = g_size
else:
# too few faces, make grid finer (smaller)
high_g = g_size
if abs(len(f) - target_faces) < target_faces * 0.05:
break
new_vertices, valid_faces = best_verts, best_faces
if use_trimesh:
simplified = trimesh.Trimesh(vertices=new_vertices, faces=valid_faces, process=False)
simplified.export(output_path, file_type='stl')
return True
# Build the simplified mesh using fallback
new_m = mesh.Mesh(np.zeros(valid_faces.shape[0], dtype=mesh.Mesh.dtype))
# Vectorized assignment