feat: galeria muestra foto impresa + estimacion por placa en detalle

- Galeria: cards muestran imagen de referencia si existe, fallback a thumbnail 3D
- Detalle: nueva seccion 'Placas de impresion' con estimacion individual por parte
- Endpoint /estimate ahora acepta file_id para calcular por archivo
- Visualizacion de placa 220x220mm con proporcion de pieza y totales acumulados
This commit is contained in:
Consultoria AS
2026-05-01 08:23:03 +00:00
parent 7a66cc1d6e
commit 0764be4945
4 changed files with 129 additions and 5 deletions

View File

@@ -560,18 +560,22 @@ def validate_mesh(model_id: int, db: Session = Depends(get_db)):
@router.get("/{model_id}/estimate")
def estimate_print(model_id: int, price_per_kg: float = Query(20.0), material_density: float = Query(1.24), db: Session = Depends(get_db)):
def estimate_print(model_id: int, file_id: Optional[int] = Query(None), price_per_kg: float = Query(20.0), material_density: float = Query(1.24), db: Session = Depends(get_db)):
model = db.query(Model3D).filter(Model3D.id == model_id).first()
if not model:
raise HTTPException(status_code=404, detail="Model not found")
primary = next((f for f in model.files if f.is_primary and f.file_type in ('stl', '3mf')), None)
if not primary:
if file_id:
target = next((f for f in model.files if f.id == file_id and f.file_type in ('stl', '3mf')), None)
else:
target = next((f for f in model.files if f.is_primary and f.file_type in ('stl', '3mf')), None)
if not target:
raise HTTPException(status_code=404, detail="No 3D file found")
try:
import trimesh
mesh = trimesh.load(primary.file_path, force='mesh')
mesh = trimesh.load(target.file_path, force='mesh')
volume_cm3 = abs(float(mesh.volume)) / 1000.0
grams = volume_cm3 * material_density
cost = (grams / 1000.0) * price_per_kg
@@ -579,7 +583,11 @@ def estimate_print(model_id: int, price_per_kg: float = Query(20.0), material_de
hours = seconds // 3600
mins = (seconds % 3600) // 60
bounds = mesh.bounds
dims = bounds[1] - bounds[0]
return {
"file_id": target.id,
"part_name": target.part_name or target.filename,
"volume_cm3": round(volume_cm3, 2),
"grams": round(grams, 2),
"cost": round(cost, 2),
@@ -587,6 +595,9 @@ def estimate_print(model_id: int, price_per_kg: float = Query(20.0), material_de
"estimated_seconds": seconds,
"price_per_kg": price_per_kg,
"material_density": material_density,
"width_mm": round(float(dims[0]), 1),
"depth_mm": round(float(dims[1]), 1),
"height_mm": round(float(dims[2]), 1),
}
except Exception as e:
raise HTTPException(status_code=500, detail=f"Estimation failed: {str(e)}")