From 81342d834a84c0a3516b213fd18db063feb7f647 Mon Sep 17 00:00:00 2001 From: Rodrigo Bertoldo de Sousa Martins Date: Tue, 8 Sep 2026 13:14:44 -0300 Subject: [PATCH] fix 3 --- data-pipeline/package.json | 1 + data-pipeline/scripts/extract-manifest.mjs | 18 ++++++++++++++++-- deploy/nginx-vhost-atlas.conf | 4 ++++ nginx/nginx.conf | 14 +++++++++++++- 4 files changed, 34 insertions(+), 3 deletions(-) diff --git a/data-pipeline/package.json b/data-pipeline/package.json index 682c90e..42618a7 100644 --- a/data-pipeline/package.json +++ b/data-pipeline/package.json @@ -16,6 +16,7 @@ "@gltf-transform/core": "^4.0.4", "@gltf-transform/extensions": "^4.0.4", "@gltf-transform/functions": "^4.0.4", + "meshoptimizer": "^0.22.0", "pg": "^8.12.0" } } diff --git a/data-pipeline/scripts/extract-manifest.mjs b/data-pipeline/scripts/extract-manifest.mjs index 089df16..5af8a71 100644 --- a/data-pipeline/scripts/extract-manifest.mjs +++ b/data-pipeline/scripts/extract-manifest.mjs @@ -6,7 +6,8 @@ // - data-pipeline/seed/manifest-real.json (entradas para o seed do banco) import { NodeIO } from "@gltf-transform/core"; import { ALL_EXTENSIONS } from "@gltf-transform/extensions"; -import { prune, dedup } from "@gltf-transform/functions"; +import { prune, dedup, weld, simplify } from "@gltf-transform/functions"; +import { MeshoptSimplifier } from "meshoptimizer"; import { writeFileSync, mkdirSync } from "node:fs"; import path from "node:path"; import { fileURLToPath } from "node:url"; @@ -14,6 +15,8 @@ import { SOURCES, SOURCE_TARGETS, RESPIRATORY_KEYWORDS } from "./sources.mjs"; import { translateToPt } from "./translate-pt.mjs"; import { SYSTEMS } from "../seed/systems.mjs"; +await MeshoptSimplifier.ready; + const __dirname = path.dirname(fileURLToPath(import.meta.url)); const CONVERTED_DIR = path.resolve(__dirname, "../converted"); const MODELS_OUT_DIR = path.resolve(__dirname, "../seed/models"); @@ -121,7 +124,18 @@ for (const { fbx, key } of SOURCES) { console.warn(` ⚠ nenhuma malha nomeada encontrada em ${fbx} — confira o log do assimp/conversão.`); } - await doc.transform(prune(), dedup()); + // Malhas do Z-Anatomy vêm pensadas para um app desktop (Unity), com + // densidade de polígonos bem maior do que um visualizador web aguenta + // com dezenas de estruturas na tela ao mesmo tempo — sem isso os .glb + // ficam grandes demais para transferir e derrubam o contexto WebGL + // (GPU sobrecarregada). Reduzimos para ~15% dos triângulos originais, + // que mantém a forma reconhecível para fins de estudo. + await doc.transform( + weld(), + simplify({ simplifier: MeshoptSimplifier, ratio: 0.15, error: 0.01 }), + prune(), + dedup(), + ); const outPath = path.join(MODELS_OUT_DIR, target.modelFile); await io.write(outPath, doc); diff --git a/deploy/nginx-vhost-atlas.conf b/deploy/nginx-vhost-atlas.conf index 733c69c..590c565 100644 --- a/deploy/nginx-vhost-atlas.conf +++ b/deploy/nginx-vhost-atlas.conf @@ -80,5 +80,9 @@ server { proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; + # Arquivos .glb grandes (dezenas de MB) e o host com outras + # aplicações rodando podem passar do timeout padrão de 60s. + proxy_read_timeout 300s; + proxy_send_timeout 300s; } } diff --git a/nginx/nginx.conf b/nginx/nginx.conf index 97d8f45..83b2654 100644 --- a/nginx/nginx.conf +++ b/nginx/nginx.conf @@ -44,6 +44,10 @@ http { proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; + # Consultas grandes (milhares de estruturas) ou o host sob carga de + # outras aplicações podem passar de 60s (default do nginx). + proxy_read_timeout 300s; + proxy_send_timeout 300s; } location /models/ { @@ -53,7 +57,15 @@ http { proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; - add_header Cache-Control "public, max-age=604800, immutable"; + proxy_read_timeout 300s; + proxy_send_timeout 300s; + # NÃO usar "immutable"/cache longo aqui: os arquivos .glb têm nome + # fixo por sistema (ex: muscular.glb) mas o CONTEÚDO muda toda vez + # que o pipeline roda de novo — com cache "immutable" o navegador + # nunca mais rebaixava a versão nova, mesmo com hard-refresh. + # "no-cache" ainda permite resposta 304 (rápida) quando o arquivo + # realmente não mudou, via ETag do @fastify/static. + add_header Cache-Control "no-cache"; } # SPA fallback.