fix(gmsh): force preview-quality settings when GMSH fallback path is taken

Fine production settings (0.03mm/0.05rad) with GMSH → CharacteristicLengthMax
0.45mm → OOM kill on large assemblies even with per-solid iteration.

GMSH quality is algorithmic (conforming seams, no fan triangles) — a denser
mesh provides no extra UV-unwrap benefit. Cap GMSH tessellation at preview
settings (0.1mm/0.1rad) in the production fallback path.

Normal path (GMSH + valid geometry GLB) is unaffected — continues to reuse
_geometry.glb directly without re-tessellating.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-11 20:46:42 +01:00
parent dbc032ec74
commit cd6c2f48e2
@@ -283,20 +283,30 @@ def generate_gltf_production_task(self, cad_file_id: str, product_id: str | None
"info", "info",
) )
else: else:
# No usable cache: run tessellation from STEP # No usable cache: run tessellation from STEP.
# When GMSH is selected, force preview-quality settings (0.1mm / 0.1rad) even here.
# Fine production settings (e.g. 0.03mm) combined with GMSH OOM-kill on large assemblies
# because CharacteristicLengthMax becomes too small. GMSH quality is algorithmic
# (conforming seams) not density-based — a denser GMSH mesh adds no UV-unwrap benefit.
if tessellation_engine == "gmsh":
eff_linear = float(sys_settings.get("gltf_preview_linear_deflection", "0.1"))
eff_angular = float(sys_settings.get("gltf_preview_angular_deflection", "0.1"))
else:
eff_linear = prod_linear
eff_angular = prod_angular
occ_cmd = [ occ_cmd = [
python_bin, str(occ_script), python_bin, str(occ_script),
"--step_path", str(step_path), "--step_path", str(step_path),
"--output_path", str(prod_geom_glb), "--output_path", str(prod_geom_glb),
"--linear_deflection", str(prod_linear), "--linear_deflection", str(eff_linear),
"--angular_deflection", str(prod_angular), "--angular_deflection", str(eff_angular),
"--sharp_threshold", str(sharp_threshold), "--sharp_threshold", str(sharp_threshold),
"--tessellation_engine", tessellation_engine, "--tessellation_engine", tessellation_engine,
] ]
log_task_event( log_task_event(
self.request.id, self.request.id,
f"Tessellating STEP at production quality ({tessellation_engine}, " f"Tessellating STEP for production ({tessellation_engine}, "
f"linear={prod_linear}mm, angular={prod_angular}rad)", f"linear={eff_linear}mm, angular={eff_angular}rad)",
"info", "info",
) )
try: try: