Projeto pessoal · C++ e WebGL
3D Analyzer — Inspetor de malhas com motor C++
Orçamentar uma peça para fabrico exige medi-la. Construí uma ferramenta que lê o ficheiro 3D, calcula o volume real da malha e estima o material necessário.
Contexto
Projeto pessoal, individual. Motor de cálculo em C++ nativo, interface em Vue 3 com Three.js.
O problema
Um ficheiro STL ou OBJ de uma peça real tem dezenas ou centenas de milhares de triângulos. Processar isso em JavaScript, na thread principal do browser, congela a interface — e uma interface congelada durante o cálculo parece avariada.
Mas o problema maior não era a velocidade. Era o número estar errado.
Decisões técnicas
Dois processos, duas linguagens
O motor em C++ trata da geometria — carrega a malha, percorre os triângulos, calcula volume e área. O Vue trata daquilo em que o browser é bom: interface reativa e renderização em WebGL através do Three.js. Cada lado faz o que faz melhor. O custo é honesto e grande: a aplicação deixa de ser portável, deixa de correr só num browser, e passa a exigir compilação antes de arrancar. Para distribuir a utilizadores seria a decisão errada. Para uma ferramenta local de análise, é a certa — e foi a que me ensinou mais.
Volume pelo teorema da divergência, não pela caixa envolvente
A primeira versão calculava o volume multiplicando as três dimensões da caixa que envolve a peça. É simples, é rápido e está errado para tudo o que não seja um paralelepípedo: uma esfera pagava como o cubo que a contém. Substituí-o pelo teorema da divergência aplicado aos triângulos da malha, acumulado no mesmo passo de leitura que já percorria o ficheiro. O cálculo passou a dar o volume do sólido em vez do volume do espaço que ele ocupa.
Um número que diz se o outro é de confiança
O teorema da divergência assume que a malha é fechada. Uma malha com buracos devolve um valor à mesma, e esse valor pode até estar certo por acidente. Passei a acumular também o somatório dos vetores de área — o resíduo de fecho — no mesmo passo. Se a malha for estanque, o resíduo é praticamente zero; se não for, o resíduo denuncia-a. A ferramenta deixou de dar só um número e passou a dizer se pode confiar nele.
Leitura de STL em streaming, com memória constante
Os ficheiros STL são percorridos triângulo a triângulo, acumulando os resultados à medida que a leitura avança, em vez de serem carregados inteiros para memória. O consumo deixa de depender do tamanho do ficheiro: uma peça de duzentos megabytes usa a mesma memória que uma de dois.
Gestão explícita da memória gráfica
O Three.js não liberta automaticamente a memória do GPU das malhas e materiais que saem de cena — o coletor de lixo do JavaScript não sabe nada sobre VRAM. Uma aplicação que carrega modelos em sequência sem destruir os anteriores acumula memória até ficar lenta e morrer, e o erro aparece longe da causa. Destruo explicitamente as malhas e os materiais antigos antes de cada modelo novo.
O que correu mal
O volume estava errado desde o início e ninguém o teria notado a olhar para a interface. A caixa envolvente dá sempre um número plausível — só é o número certo quando a peça é um paralelepípedo. Numa esfera, a caixa dá quase o dobro do volume real.
Só percebi ao comparar o resultado com uma peça cujo volume eu conhecia. E depois de o corrigir, percebi que tinha um segundo problema por baixo: a fórmula nova assume uma malha fechada, e nada no programa verificava isso. Uma peça com um buraco continuaria a devolver um número de aparência normal.
A solução dos dois problemas acabou por ser a mesma passagem pelo ficheiro: o volume e o resíduo de fecho são acumulados lado a lado, e o segundo qualifica o primeiro.
Escrevi dois testes que existem só para isto: provam que o volume varia quando a peça é deslocada no espaço, e que o resíduo não. Se algum dia alguém trocar a fórmula por uma que dependa da posição, os testes apanham.
Resultado
Ferramenta funcional, com 34 testes compilados contra o motor real. Lê STL e OBJ, calcula volume, área e contagem de triângulos, mostra o modelo em WebGL e exporta para PDF e Excel.
O que faria diferente
Partiria o App.vue mais cedo. Tem mil setecentas linhas e cresceu por acumulação, porque cada funcionalidade nova era mais rápida de acrescentar ali do que de separar. Hoje é o ficheiro que mais custa a alterar — e o custo de o ter deixado crescer é maior do que teria sido o de o dividir a meio do caminho.