- Fidget é uma biblioteca em Rust para representar, compilar e avaliar expressões matemáticas compostas por centenas ou milhares de cláusulas aritméticas, com uso principal como backend de superfícies implícitas
- Superfícies implícitas usam funções de distância no formato $f(x,y,z) \rightarrow d$ para distinguir interior e exterior, sendo adequadas para operações CSG e avaliação paralela
- O frontend fornece um pipeline que vai de scripts em Rhai até árvores matemáticas, DAGs, fitas SSA e bytecode baseado em registradores reutilizáveis
- O backend oferece interpretador e compilador JIT, com suporte a avaliação em ponto único, arrays SIMD, diferenciação automática direta e aritmética intervalar
- Na avaliação brute force de 1024² com 7867 expressões, o JIT reduziu 5,8 s para 182 ms, mas em renderização otimizada a diferença caiu para cerca de 25%, com 6 ms contra 4,6 ms
Objetivos do Fidget e superfícies implícitas
- Fidget é uma biblioteca para representar, compilar e avaliar expressões matemáticas grandes
- Voltada a expressões com centenas ou milhares de cláusulas aritméticas
- O uso principal é como backend de superfícies implícitas, mas pode servir para outros fins
- Superfícies implícitas são expressões no formato $f(x, y, z) \rightarrow d$, que retornam um único valor de distância $d$
- Se $d$ for positivo, o ponto $(x,y,z)$ está fora do modelo
- Se $d$ for negativo, o ponto está dentro do modelo
- Uma esfera de raio 1 pode ser representada como $\sqrt{x^2 + y^2 + z^2} - 1$
- O Fidget foca em superfícies implícitas fechadas que constroem expressões com operações aritméticas básicas
- Em contraste com abordagens que calculam o valor de distância por meio de programas Turing-completos, como GLSL em pixel shaders
- Essas funções se parecem mais com uma “linguagem assembly para shapes”, mais fácil de ser alvo de representações de nível superior do que de ser escrita manualmente
Onde superfícies implícitas levam vantagem
- Superfícies implícitas são compactas e adequadas para avaliação paralela
- Funcionam bem para avaliação massiva em paralelo com instruções SIMD ou GPU
- Operações CSG ficam simples
- Operações como union e intersection, difíceis em meshes ou NURBS, podem ser expressas com facilidade
- A união de dois cilindros que se sobrepõem exatamente é expressa como
min(a, b)
- Equações fechadas criam oportunidades de otimização
- O Fidget pode capturar um trace de execução mostrando qual ramificação foi escolhida durante a avaliação
- Esse trace é usado para simplificar a expressão e reduzir o custo das avaliações seguintes
Por que criar algo novo depois do libfive
- Fidget é uma biblioteca nova criada para substituir o kernel existente do
libfive- O
libfiveé composto por cerca de 40 mil linhas de código, em sua maior parte C++ - Era difícil de modificar até para o próprio autor, e recompilar depois de alguns meses frequentemente quebrava o build e exigia mexer no CMake
- O
- A nova implementação serve como base para experimentar questões que hoje são interessantes
- Buscar uma API adequada para kernels implícitos, inclusive aceitando possíveis quebras de compatibilidade
- Experimentar compilação JIT nativa para aumentar o desempenho sem migrar para GPU
- Fazer cross-compilation para WebAssembly e criar demos web mais acessíveis
- O Fidget é escrito em Rust
- Compila com um simples
cargo build - Faz cross-compilation para WebAssembly de forma natural
- O sistema de tipos forte e a segurança de memória do Rust aumentam a confiança em refatorações
- Compila com um simples
Frontend: de scripts até bytecode
- O frontend do Fidget fornece um pipeline que vai do script de entrada até o bytecode
- O usuário não é obrigado a seguir esse fluxo inteiro; a biblioteca pode ser usada em qualquer etapa intermediária
-
Scripting com Rhai
- O Fidget inclui bindings para Rhai, uma linguagem de scripting embarcada para Rust
- Com operator overloading, é possível montar expressões matemáticas no script
- O valor passado para
drawé uma árvore matemática que representa a expressão criada pelo script
-
Árvores, grafos e fitas SSA
- A árvore matemática é convertida em um grafo acíclico direcionado (DAG) após eliminação de duplicações
- O grafo é linearizado em código de linha reta por meio de ordenação topológica
- Esse código está em formato SSA (single static assignment)
- Há uma quantidade arbitrária de pseudorregistradores
rX, e cada registrador é escrito apenas uma vez - A fita SSA também pode ser avaliada, mas escala mal porque cada operação exige uma posição de memória
- Isso acontece porque os pseudorregistradores não são reutilizados
-
Bytecode e alocação de registradores
- Para melhorar a eficiência da avaliação, os pseudorregistradores são mapeados para registradores físicos reutilizáveis
- A fita SSA de exemplo pode ser comprimida em 6 registradores reutilizáveis
- A alocação de registradores usa o simple algorithm apresentado anteriormente
- É um algoritmo single-pass que prioriza velocidade e determinismo acima da eficiência
- O interpretador de bytecode usa 256 registradores
- Os índices dos registradores são armazenados em
u8 - Se faltarem registradores, o alocador insere
LOADeSTOREpara gravar em memória auxiliar com índicesu32
Backend: formas de avaliação e simplificação
- O backend do Fidget é separado do frontend pelos traits
Function,TracingEvaluatoreBulkEvaluator- Os algoritmos podem operar sobre um
Functiongenérico, sem acoplamento forte à implementação da árvore matemática - No momento, não há implementações não baseadas em árvore matemática para o trait
Function
- Os algoritmos podem operar sobre um
- Atualmente há duas formas de avaliar árvores matemáticas
- Interpretador de bytecode
- Funções compiladas por JIT
-
Modos de avaliação
- O Fidget oferece quatro modos de avaliação
- Avaliação em ponto único
- Avaliação SIMD baseada em arrays
- Diferenciação automática direta
- Aritmética intervalar
- Na avaliação em lote, o usuário fornece arrays de entrada e recebe arrays de saída
- O backend JIT gera código SIMD que processa 4 elementos por vez em
AArch64e 8 emx86-64
- O Fidget oferece quatro modos de avaliação
-
Diferenciação automática direta
- O avaliador diferencial calcula o valor e até 3 derivadas parciais
- Em superfícies implícitas, normalmente calcula-se $(f, \partial f/\partial x, \partial f/\partial y, \partial f/\partial z)(x,y,z)$
- Na superfície, quando $f(x,y,z)=0$, as derivadas parciais são uma boa aproximação da normal da superfície
- Esses valores podem ser usados para shading
- A avaliação é feita com diferenciação automática direta
- Valores diferenciais são anexados aos valores dos registradores, e a regra da cadeia é aplicada em cada etapa
- O avaliador JIT armazena o valor e 3 derivadas em um único registrador
4 x f32
-
Aritmética intervalar
- A aritmética intervalar avalia um intervalo de entrada em vez de um único valor de entrada
- Por exemplo, em vez de $x=1$, pode-se usar $1 \le x \le 5$
- A saída também se torna um intervalo, como $2 \le f(x,y,z) \le 20$
- O resultado da aritmética intervalar é conservador
- Pode não envolver o intervalo real da função de forma justa
- Mas inclui todas as saídas possíveis dentro do intervalo de entrada dado
- Em avaliação de superfícies implícitas, a aritmética intervalar é um componente central
- Ao avaliar uma região do espaço como intervalos em $x,y,z$, se o intervalo de saída for claramente maior que 0, toda a região está fora da forma e não precisa ser examinada mais
-
Simplificação baseada em trace
- O avaliador de aritmética intervalar também captura um trace de execução
- Em
min(a,b), se $0 \le a \le 1$ e $4 \le b \le 5$, entãoaé sempre menor, então a expressão pode ser simplificada paraa - Cada operação
minemaxregistra qual argumento afeta o resultado - A escolha é registrada como esquerda, direita ou ambos
- Essas escolhas são usadas para simplificar a função original
- O Fidget oferece suporte à simplificação de
minemaxusados em CSG, além das operações lógicasandeor - Formas sem CSG nem lógica não ganham benefícios com essa simplificação
- Ainda assim, permanece a vantagem de pular regiões vazias ou completamente cheias com base em aritmética intervalar
Combinação de aritmética intervalar e simplificação de tape
- A combinação de aritmética intervalar e simplificação de tape é a técnica central que torna mais fácil lidar com expressões em grande escala
- Ela pula regiões inativas do espaço e também torna mais barata a avaliação das regiões ativas restantes
- A simplificação de tape é uma forma de calcular expressões simplificadas válidas apenas em uma determinada região do espaço
- Diferentemente das estruturas gerais de aceleração para ray tracing, isso equivale a criar dinamicamente uma estrutura de aceleração durante a avaliação
- Na rasterização, o custo da avaliação intervalar é distribuído entre vários pixels
- A avaliação intervalar de uma região de pixels $N \times N$ é $O(T)$, proporcional ao comprimento do tape $T$
- Não depende do número de pixels
- Ao descer até regiões menores e então fazer a avaliação por pixel, usa-se um tape muito mais curto
- Em uma região $M \times M$, o custo é $O(T' \times M \times M)$
- Aqui, $T' < T$
- No exemplo de renderização 2D
hello, worldem 256×256, o tape original tem 254 cláusulas- São avaliados por intervalo 64 tiles de 32×32 pixels
- Regiões vazias são puladas e restam 47 tiles ativos
- O comprimento médio do tape nos tiles ativos cai para 73 cláusulas
- Cada tile é subdividido em 16 tiles de 8×8 pixels
- São avaliados por intervalo 752 tiles de 8×8 pixels
- Regiões vazias são puladas e restam 351 tiles ativos
- O comprimento médio do tape nos tiles ativos cai para 20 cláusulas
- Os 351 tiles restantes de 8×8 passam por avaliação por pixel
- São avaliados por intervalo 64 tiles de 32×32 pixels
- No momento da avaliação por pixel, o tape fica mais de 10 vezes menor que o comprimento original
Compilação JIT
- O interpretador de bytecode é um loop apertado, mas tem overhead inevitável
- O despacho de instruções é um único branch difícil de prever
- Cada instrução lê e escreve memória por meio dos slots de registrador do avaliador da VM
- Para desempenho máximo, o Fidget inclui um compilador JIT que reduz o bytecode a código de máquina
- As instruções de máquina formam código linear sem despacho
- Como usam diretamente registradores físicos, reduzem leituras e escritas de memória
- A entrada do JIT é o mesmo tape de bytecode de antes
- Em vez dos 255 registradores padrão da VM, ele planeja de acordo com 12 registradores físicos em
x86-64e 24 emAArch64 - Em
AArch64, o mapeamento é parav8-31; emx86-64, paraxmm4-15
- Em vez dos 255 registradores padrão da VM, ele planeja de acordo com 12 registradores físicos em
- Para cada combinação de opcode × tipo de dado × arquitetura, são escritos manualmente snippets em assembly
- Os registradores físicos desejados são aplicados por patch nesses snippets e copiados para uma região de memória criada com
mmap
- Os registradores físicos desejados são aplicados por patch nesses snippets e copiados para uma região de memória criada com
- No nível de Rust, a memória gerada é convertida para um ponteiro de função e chamada
- Entradas e saídas são passadas convertendo slices de Rust em raw pointers
-
Números de desempenho
- Em um exemplo complexo composto por 7.867 expressões, a avaliação brute force de 1024² pixels mostra um grande efeito do JIT
- Interpretador de bytecode: 5,8 segundos
- Backend JIT: 182 ms
- Ganho de velocidade: 31 vezes
- O brute force não usa aritmética intervalar nem simplificação de tape
- Ao usar algoritmos mais inteligentes, a diferença diminui
- A implementação de renderização otimizada do Fidget desenha a mesma imagem em 6 ms com o interpretador de bytecode e em 4,6 ms com o backend JIT
- Nesse caso, a melhora é de cerca de 25%
Renderização e geração de malha
-
Renderização
- Toda a renderização de modelos usa o algoritmo de
fidget::render - A renderização usa o algoritmo central do artigo da SIGGRAPH
- Grandes regiões do espaço são renderizadas com aritmética intervalar
- Um tape encurtado é gerado com base em tracing
- Regiões ambíguas são subdivididas e processadas recursivamente
- Na renderização 3D, as normais são calculadas com derivadas parciais
- Os modelos são transformados durante a renderização com matrizes homogêneas 4×4
- Há suporte a transformação de perspectiva
- O resultado da renderização geralmente são duas imagens: um heightmap e as normais por pixel
- O resultado pode ser desenhado com técnicas padrão de deferred rendering, como SSAO
- Toda a renderização de modelos usa o algoritmo de
-
Geração de malha
- Para geração de malha, o Fidget implementa Manifold Dual Contouring
- Essa implementação deve sempre produzir uma malha com as seguintes características
- watertight
- manifold
- preservação de edges e corners agudos
- comportamento adaptativo, com menor densidade de triângulos em regiões majoritariamente planas
- Também há defeitos conhecidos
- características finas não são necessariamente preservadas
- a malha resultante pode conter auto-interseções
- o posicionamento de vértices é vulnerável a adversarial cases
- A boa geração de malhas para superfícies implícitas arbitrárias continua sendo um problema não resolvido
- Manifold Dual Contouring não é perfeito, mas fica em um ponto de equilíbrio entre simplicidade e desempenho
Demos e GUI web
- O repositório do Fidget inclui vários demos
- A GUI web é apresentada como o demo mais interessante
- Também existem o
fidget-cli, uma CLI simples, e ofidget-viewer, um visualizador de scripts nativo
- O demo web combina várias tecnologias da web
- A GUI foi escrita em TypeScript
- O crate Fidget é usado como biblioteca e não conduz o event loop
- O editor de texto usa CodeMirror
- Foi preciso um bundler para usar módulos Node, e a escolha foi o webpack
- A avaliação de scripts e a renderização são feitas em um web worker para não bloquear o event loop principal
- Para contornar a ausência de
std::threadno navegador, a renderização é paralelizada comwasm-bindgen-rayon - O worker e o event loop principal compartilham memória
- Quando o usuário fornece uma nova entrada, renderizações demoradas podem ser canceladas com uma flag
Arc<AtomicBool>compartilhada com o worker
- Fazer todos esses componentes funcionarem juntos foi difícil
- Cada componente tinha exemplos funcionais, mas bundlers, configurações e servidores diferentes entre si
- Uma correção recente de bug em
wasm-bindgenmudou o comportamento de quewasm-bindgen-rayonprecisava, exigindo fixar uma versão antiga
- O demo web também funciona em celulares
- Como usa eventos de mouse, a manipulação da câmera não é suportada
A tensão entre demos e a biblioteca
- O Fidget é прежде de tudo uma biblioteca
- A forma de uso pretendida é que usuários o incorporem como infraestrutura em seus próprios projetos, em vez de usar o demo como uma ferramenta CAD de verdade
- Mas há muito mais gente mexendo no demo do que criando ferramentas com a biblioteca
- Algumas pessoas chegam a usar o demo para trabalho de design
- Existe uma tensão entre melhorar o demo para uma base maior de usuários ou melhorar a biblioteca para a base menor de criadores de ferramentas
- Manter ao mesmo tempo o kernel e uma UI CAD completa era difícil, e o escopo do demo foi diminuindo aos poucos
- Mesmo um demo “mínimo”, como o editor web, já é um projeto considerável
- O plano segue três direções
- continuar seguindo os próprios interesses para manter motivação e foco
- aceitar sugestões de usuários da ferramenta, mas manter expectativas razoáveis
- idealmente, priorizar o feedback de criadores de ferramentas que reduza a carga de manter demos
Possibilidades futuras
-
Backend para GPU
- O backend para GPU é uma extensão natural
- Já existem artigos relacionados na SIGGRAPH
- Já está implementado no branch
wgpu-bytecode - No notebook Apple M1 Max, o desempenho não é particularmente atraente
- O loop do interpretador de bytecode parece muito ineficiente
- A causa raiz ainda está sendo investigada
-
Geração de malha melhor
- Para usuários sérios da biblioteca, a geração de malha é um grande problema
- O Fidget usa a mesma estratégia de geração de malha que o
libfive, mas não tem vários ajustes finos que tornam o comportamento dolibfivemais robusto - Como não estava satisfeito com as opções disponíveis no momento, não dedicou muito tempo a essa parte
- Prefere implementar um algoritmo de malha à prova de falhas em vez de continuar remendando o dual contouring
- Ainda não há um método na literatura que atenda aos requisitos, nem uma alternativa própria
- Dependendo da demanda dos usuários, algum ajuste pode ser feito, mas o plano é continuar procurando opções melhores
-
Biblioteca padrão de shapes e transforms
- Ao longo de várias gerações de software, a biblioteca padrão de shapes do Fab Modules vem sendo portada para novas ferramentas
- Esse trabalho é tedioso, mas fornece uma base mais ou menos padrão para modelagem de alto nível
- No
libfive, cada shape era escrito em C++, e os bindings para C, Python e Scheme eram gerados automaticamente a partir de arquivos de cabeçalho - O README explica que
libfive_stdlib.hé ao mesmo tempo um cabeçalho C e uma documentação estruturada analisada por scripts auxiliares - A abordagem do Fidget ainda está em discussão
- A discussão em andamento está em fidget#145
- Há uma forma viável de trazer a biblioteca Fab shapes para Rust
- Um ponto de referência também é um código mais elegante que aproveita vetores GLSL, como a biblioteca de primitives de Inigo Quilez
-
Bindings para linguagens de alto nível
- Atualmente, o Fidget oferece apenas bindings para Rhai
- Rhai foi escolhido por ser uma das linguagens de script Rust-first maduras
- A integração foi fácil, e há a vantagem de compilar para WebAssembly
- Muitos usuários podem preferir bindings para Python ou Node
- A forma desses bindings também continua em aberto
- A API C permite aproveitar as bibliotecas FFI de cada linguagem, mas, em um projeto com design Rust-first, isso passa a sensação de descer um nível
- Quando existir uma biblioteca padrão, seria ideal que cada binding pudesse expô-la automaticamente com a usabilidade adequada, como docstrings e argumentos padrão
Estado de divulgação e como usar
- O
READMEdo Fidget vinha descrevendo o projeto como “quietly public” desde o lançamento inicial- 19 versões foram publicadas no crates.io
- Alguns usuários já começaram a construir coisas sobre o Fidget
- Agora o Fidget está passando para a fase “loudly public”
- O código-fonte está no Github
- Em projetos Rust, é possível adicionar com
cargo add fidget - A licença é a MPL 2.0, um copyleft fraco
- Ela é apresentada como uma licença amigável tanto para OSS quanto para uso comercial
- Em projetos Rust, é possível adicionar com
1 comentários
Opiniões no Hacker News
Olá, este é meu projeto :)
O motivo de eu gostar especialmente desta área de CS é que ela tem algo para todo mundo. Envolve estruturas de dados e algoritmos, trabalho de desempenho em baixo nível, compiladores, renderização/computação gráfica, UI/UX para ferramentas de design, programação GPGPU etc.
Vou responder às perguntas que aparecerem na thread, mas vocês também podem acompanhar atualizações adicionais pelas redes sociais (https://mattkeeter.com/links/) ou pelo feed RSS do blog (https://mattkeeter.com/atom.xml)
Ele ilustra bem uma ideia que tenho na cabeça há tempos. E se o próprio processo de projetar esse plano de fabricação se tornasse uma API de CAD voltada ao usuário? Ao lidar com problemas de “fazer coisas”, como marcenaria, encanamento, fabricação em metal e usinagem, é natural pensar nas matérias-primas, nas ferramentas disponíveis e na sequência de operações para obter o resultado desejado.
Mas as APIs de CAD atuais, sejam ferramentas de CAD por código ou interfaces tradicionais baseadas em mouse, não funcionam assim; elas fazem você se concentrar em como representar a forma final, mais do que em como de fato fabricá-la. No fim, o que importa é fabricar o objeto, e a modelagem é apenas uma ferramenta para ajudar nisso, mas essa ferramenta acaba ficando em destaque demais.
Um fluxo de modelagem mais baseado na realidade parece ter muitas vantagens; do ponto de vista de alguém com muito mais experiência em CAD, você acha que esse conceito tem potencial de evoluir ou é um beco sem saída?
Acrescentando também um feedback sobre a caneta: você pode prender a barra em um mandril de 3 castanhas, tornear até a dimensão adequada para a pinça, cortar da barra dimensionada um blank para a tampa e dois para o corpo, e então prender o restante das operações com a pinça para manter a concentricidade. O porém é que, se a dimensão final for diferente da dimensão da pinça, haverá um pouco de desperdício de material.
Em termos de funcionalidades, em que o Fidget difere do libfive ou do Ao?
Aquele código apenas convertia uma expressão única amigável ao usuário em chamadas de função aninhadas para a biblioteca de IA dentro de GLSL, sem nenhuma otimização. Isto aqui foi muito mais longe.
Por coincidência, eu também estava acabando de ler outro excelente texto do autor: https://www.mattkeeter.com/projects/constraints/
Demo: https://mattkeeter.com/projects/fidget/constraints
Fonte: https://github.com/mkeeter/fidget/blob/main/demos/constraint...
Documentação do solucionador: https://docs.rs/fidget/latest/fidget/solver/
Uau, isso teria sido extremamente útil quando criei meu próprio renderizador de superfícies implícitas.
Minha abordagem era parecida em alguns aspectos (aritmética intervalar) e diferente em outros. Era menos otimizada e gerava GLSL diretamente para fragment shaders.
Sinceramente, dá vontade de jogar tudo fora e reimplementar usando isto no lugar. Não sei se fico feliz ou triste.
Você pode aproveitar as ideias ou usar isto e contribuir para o projeto. De qualquer forma, é algo ótimo.
É incrível ver um novo kernel CAD open source! Pelo texto, não consegui saber se ele oferece suporte a exportação para formatos comuns, como STEP.
Se isso for possível, ou se vier a ser possível, parece que poderia se tornar uma ótima base para várias bibliotecas CAD open source.
A maioria dos arquivos STEP representa a geometria como um conjunto de superfícies, por exemplo trimmed NURBS. Essas superfícies precisam formar uma variedade sem lacunas, para então poderem ser tratadas como um volume sólido.
Para fazer isso funcionar de verdade, é necessário um kernel de representação por fronteira (b-rep), não as representações por função (f-reps) do Fidget. Escrever um kernel desse tipo é um problema muito mais difícil. Por exemplo, a interseção entre duas superfícies NURBS nem sempre tem uma representação em forma fechada.
Conversando com alguém da indústria, a estimativa foi que, mesmo para uma equipe que já tivesse feito isso antes, seriam necessários cerca de 6 engenheiros por aproximadamente 1 ano para criar um bom kernel b-rep.
Se quiser saber mais, por coincidência eu também escrevi um visualizador de arquivos STEP que inclui um kernel b-rep bem distante de nível industrial: https://www.mattkeeter.com/projects/foxtrot/.
“Se você fizer uma avaliação por força bruta em 1024² pixels, o interpretador de bytecode leva 5,8 segundos, enquanto o backend JIT leva 182 ms, ficando 31 vezes mais rápido”
“Com um algoritmo mais inteligente, o ganho de velocidade é menos dramático. A abordagem por força bruta não aproveita aritmética de intervalos nem simplificação de tape. A implementação de renderização otimizada do Fidget desenha essa imagem em 6 ms com o interpretador de bytecode e em 4,6 ms com o backend JIT, então a melhoria é de apenas cerca de 25%”
Gosto do fato de o foco aqui estar em como o backend JIT se torna menos importante depois das otimizações algorítmicas, e não no fato de que a otimização algorítmica traz uma melhora de 1000 vezes no bytecode e de 40 vezes no JIT
Alguns anos atrás, na universidade, trabalhei um pouco em um simulador de física nuclear, isto é, algo como modelagem de reatores nucleares
O modelo geométrico era baseado em superfícies implícitas, especialmente R-functions. min(x,y) também é um exemplo disso, e elas têm propriedades interessantes, como serem diferenciáveis em todos os pontos
Um bom material introdutório é este. Talvez seja até o único material em inglês: https://ecommons.cornell.edu/items/35ae0f68-1af5-4f28-8b8b-7...
Já faz bastante tempo que saí da área nuclear, mas imagino que ainda se use muito código Fortran antigo para modelagem. O Fidget tem um potencial interessante como kernel para novos pacotes de simulação
Um pouco fora do assunto, mas estou procurando o melhor software CAD baseado em código
Experimentei o CadQuery, mas tive alguns problemas. Alguém teria uma recomendação para uso com impressão 3D?
https://youtu.be/0wn7vUmWQgg?si=9Rc1tvbiQgQDgQzd&t=2766
Também estou desenvolvendo uma em Rust, mas é difícil dizer que já esteja pronta
https://github.com/gumyr/build123d
OpenSCAD, DSLCAD, CadQuery, Build123d, Cascade Studio, Declaracad, Replicad
Interessante. Já vi antes artigos e demos sobre esse tipo de superfície implícita. Talvez fossem trabalhos do próprio autor
É impressionante ver que tipos de modelos dá para criar usando a imaginação, mas eu gostaria de ver algo maior do que exemplos de brinquedo
Por exemplo, seria possível extrudar superfícies como em um kernel b-rep, ou importar SVG/fontes e transformá-los em sólidos?
Eu realmente gostaria de ver um kernel open source rápido que desse suporte a esse tipo de recurso e também paralelizasse bem
Isso me lembra muito o https://bauble.studio/ do Ian Henry
Eu também tinha vontade de experimentar algo parecido, usando SDF para manipular uma árvore abstrata para geração de superfícies
A ideia é ter uma malha ou nuvem de pontos alvo e, por hill climbing/annealing, encontrar uma árvore que se ajuste bem à forma desejada
https://arxiv.org/abs/2407.10954
Ele combina folhas diferenciáveis (superfícies quádricas) com operações semelhantes a Boolean diferenciáveis para criar uma árvore CSG, permitindo fazer hill climbing sobre a forma inteira