3 puntos por GN⁺ 2025-01-09 | 1 comentarios | Compartir por WhatsApp
  • Fidget es una biblioteca de Rust para representar, compilar y evaluar expresiones matemáticas formadas por cientos o miles de cláusulas aritméticas; su uso principal es como backend de superficies implícitas
  • Las superficies implícitas distinguen entre interior y exterior mediante una función de distancia con forma $f(x,y,z) \rightarrow d$, y se adaptan bien a operaciones CSG y a la evaluación en paralelo
  • El frontend ofrece un pipeline que va desde scripts en Rhai hasta árboles matemáticos, DAG, cintas SSA y bytecode basado en registros reutilizables
  • El backend ofrece un intérprete y un compilador JIT, y soporta evaluación de punto único, arreglos SIMD, diferenciación automática hacia adelante y aritmética de intervalos
  • En una evaluación brute force de 1024² sobre 7867 expresiones, el JIT redujo el tiempo de 5.8 segundos a 182 ms, pero en renderizado optimizado la diferencia se redujo a unos 25%, con 6 ms frente a 4.6 ms

Objetivos de Fidget y superficies implícitas

  • Fidget es una biblioteca para representar, compilar y evaluar expresiones matemáticas a gran escala
    • Está orientada a expresiones con cientos o miles de cláusulas aritméticas
    • Su uso principal es como backend de superficies implícitas, aunque también puede usarse para otros fines
  • Una superficie implícita es una expresión de la forma $f(x, y, z) \rightarrow d$ que devuelve un único valor de distancia $d$
    • Si $d$ es positivo, el punto $(x,y,z)$ está fuera del modelo
    • Si $d$ es negativo, el punto está dentro del modelo
    • Una esfera de radio 1 puede expresarse como $\sqrt{x^2 + y^2 + z^2} - 1$
  • Fidget se enfoca en superficies implícitas cerradas construidas con operaciones aritméticas básicas
    • Esto contrasta con enfoques que calculan el valor de distancia usando programas Turing completos, como GLSL en pixel shaders
    • En vez de escribirse a mano, estas funciones se parecen más a un “lenguaje ensamblador de shapes” al que es fácil apuntar desde representaciones de nivel superior

Dónde tienen ventaja las superficies implícitas

  • Las superficies implícitas son compactas y aptas para evaluación en paralelo
    • Encajan bien con evaluación masiva en paralelo usando instrucciones SIMD o GPU
  • Las operaciones CSG se vuelven simples
    • Operaciones como union e intersección, difíciles en meshes o NURBS, pueden expresarse fácilmente
    • La unión de dos cilindros que se superponen exactamente puede expresarse como min(a, b)
  • Las ecuaciones cerradas crean oportunidades de optimización
    • Fidget puede capturar una traza de ejecución (trace) que muestra qué rama se eligió durante la evaluación
    • Esa traza se usa para simplificar la expresión y reducir el costo de evaluaciones posteriores

Por qué se creó después de libfive

  • Fidget es una biblioteca nueva creada para reemplazar el kernel existente de libfive
    • libfive está compuesto por unas 40K líneas de código, en su mayoría C++
    • Incluso para su autor original era difícil de modificar, y al recompilarlo meses después era frecuente que el build fallara y hubiera que tocar CMake
  • La nueva implementación sirve como base para experimentar con preguntas que hoy resultan interesantes
    • Busca una API adecuada para kernels implícitos, incluso aceptando la posibilidad de romper compatibilidad
    • Experimenta con compilación JIT nativa para mejorar rendimiento sin mover la carga a la GPU
    • Puede compilarse de forma cruzada a WebAssembly y permitir demos web más accesibles
  • Fidget está escrito en Rust
    • Se compila con un simple cargo build
    • Se compila de forma cruzada a WebAssembly de manera natural
    • El sistema de tipos fuerte de Rust y su seguridad de memoria aumentan la confianza al hacer refactors

Frontend: de script a bytecode

  • El frontend de Fidget ofrece un pipeline que lleva desde el script de entrada hasta el bytecode
    • No es obligatorio seguir todo este flujo; la biblioteca puede usarse en cualquiera de las etapas intermedias
  • Scripting con Rhai

    • Fidget incluye bindings para Rhai, un lenguaje de scripting embebido para Rust
    • Gracias a la sobrecarga de operadores, las expresiones matemáticas pueden construirse dentro del script
    • El valor pasado a draw es un árbol matemático que representa la expresión creada por el script
  • Árboles, grafos y cinta SSA

    • Tras eliminar duplicados, el árbol matemático se convierte en un grafo acíclico dirigido (DAG)
    • Mediante orden topológico, el grafo se aplana en código lineal
    • Ese código tiene forma SSA (single static assignment)
    • Hay una cantidad arbitraria de pseudorregistros rX, y cada registro se escribe una sola vez
    • La cinta SSA también puede evaluarse, pero escala mal porque cada operación necesita una ubicación de memoria
    • Esto se debe a que los pseudorregistros no se reutilizan
  • Bytecode y asignación de registros

    • Para mejorar la eficiencia de evaluación, los pseudorregistros se mapean a registros físicos reutilizables
    • La cinta SSA de ejemplo puede comprimirse en 6 registros reutilizables
    • La asignación de registros usa el simple algorithm presentado anteriormente
    • Es un algoritmo de una sola pasada que prioriza velocidad y determinismo sobre eficiencia
    • El intérprete de bytecode usa 256 registros
    • Los índices de registro se guardan en u8
    • Si faltan registros, el asignador inserta LOAD y STORE para escribir en memoria auxiliar con índices u32

Backend: métodos de evaluación y simplificación

  • El backend de Fidget está separado del frontend mediante los traits Function, TracingEvaluator y BulkEvaluator
    • Los algoritmos no quedan acoplados a una implementación específica de árbol matemático, sino que pueden operar sobre un Function general
    • Actualmente no existen implementaciones no basadas en árboles matemáticos del trait Function
  • Actualmente hay dos formas de evaluar árboles matemáticos
    • Intérprete de bytecode
    • Funciones compiladas con JIT
  • Modos de evaluación

    • Fidget ofrece cuatro modos de evaluación
      • Evaluación de punto único
      • Evaluación SIMD basada en arreglos
      • Diferenciación automática hacia adelante
      • Aritmética de intervalos
    • En la evaluación bulk, el usuario proporciona arreglos de entrada y recibe arreglos de salida
    • El backend JIT genera código SIMD para procesar 4 elementos a la vez en AArch64 y 8 en x86-64
  • Diferenciación automática hacia adelante

    • El evaluador de derivadas calcula el valor y hasta 3 derivadas parciales
    • En superficies implícitas normalmente se calcula $(f, \partial f/\partial x, \partial f/\partial y, \partial f/\partial z)(x,y,z)$
    • Sobre la superficie, cuando $f(x,y,z)=0$, las derivadas parciales son una buena aproximación de la normal de la superficie
    • Ese valor puede usarse para shading
    • La evaluación se hace con diferenciación automática hacia adelante
    • Se adjuntan derivadas a los valores de registro y se aplica la regla de la cadena en cada paso
    • El evaluador JIT guarda el valor y 3 derivadas en un solo registro 4 x f32
  • Aritmética de intervalos

    • La aritmética de intervalos evalúa rangos de entrada en lugar de un valor único
    • Por ejemplo, en vez de $x=1$ puede usarse $1 \le x \le 5$
    • La salida también pasa a ser un intervalo, como $2 \le f(x,y,z) \le 20$
    • Los resultados de la aritmética de intervalos son conservadores
      • Puede que no ajusten de forma precisa el rango real de la función
      • Pero sí incluyen todas las salidas posibles dentro del intervalo de entrada dado
    • En la evaluación de superficies implícitas, la aritmética de intervalos es un componente clave
    • Si al evaluar una región del espacio como intervalos de $x,y,z$ el intervalo de salida es claramente mayor que 0, toda esa región está fuera de la forma y no hace falta seguir evaluándola
  • Simplificación basada en trazas

    • El evaluador de aritmética de intervalos también captura una traza (trace) de ejecución
    • En min(a,b), si $0 \le a \le 1$ y $4 \le b \le 5$, entonces a siempre es menor, así que la expresión puede simplificarse a a
    • Cada operación min y max registra qué argumento afecta el resultado
    • La elección se registra como izquierda, derecha o ambos
    • Esa elección se usa para simplificar la función original
    • Fidget soporta simplificación de min y max usados en CSG, así como de operaciones lógicas and y or
    • Las shapes sin CSG ni lógica no obtienen beneficios de esta simplificación
    • Aun así, permanece la ventaja de omitir regiones vacías o completamente llenas usando aritmética de intervalos

Combinación de aritmética de intervalos y simplificación de la cinta

  • La combinación de aritmética de intervalos y simplificación de la cinta es una técnica clave para hacer más manejables las expresiones a gran escala
    • Salta regiones inactivas del espacio y también abarata la evaluación de las regiones activas restantes
  • La simplificación de la cinta calcula expresiones simplificadas que solo son válidas dentro de una región espacial específica
    • A diferencia de una estructura de aceleración tradicional de ray tracing, en la práctica crea una estructura de aceleración de forma dinámica durante la evaluación
  • En rasterización, el costo de la evaluación por intervalos se reparte entre varios píxeles
    • La evaluación por intervalos de una región de píxeles de $N \times N$ es $O(T)$, proporcional a la longitud de la cinta $T$
    • No depende de la cantidad de píxeles
  • Cuando se baja a regiones pequeñas y luego se evalúa por píxel, se usa una cinta mucho más corta
    • En una región de $M \times M$, el costo es $O(T' \times M \times M)$
    • Aquí, $T' < T$
  • La cinta original del ejemplo de renderizado 2D hello, world de 256×256 tiene 254 cláusulas
    • Se evalúan por intervalos 64 tiles de 32×32 píxeles
      • Se omiten las regiones vacías y quedan 47 tiles activos
      • La longitud promedio de la cinta en los tiles activos se reduce a 73 cláusulas
    • Cada tile se subdivide en 16 tiles de 8×8 píxeles
    • Se evalúan por intervalos 752 tiles de 8×8 píxeles
      • Se omiten las regiones vacías y quedan 351 tiles activos
      • La longitud promedio de la cinta en los tiles activos se reduce a 20 cláusulas
    • Los 351 tiles restantes de 8×8 se evalúan por píxel
  • Para cuando llega la evaluación por píxel, la cinta se vuelve más de 10 veces más corta que su longitud original

Compilación JIT

  • El intérprete de bytecode es un bucle ajustado, pero tiene sobrecarga inevitable
    • El despacho de instrucciones es una sola bifurcación difícil de predecir
    • Cada instrucción lee y escribe memoria a través de los slots de registros del evaluador de la VM
  • Para obtener el máximo rendimiento, Fidget incluye un compilador JIT que baja el bytecode a código máquina
    • Las instrucciones máquina forman código lineal sin despacho
    • Como usa registros físicos directamente, se reducen las lecturas y escrituras de memoria
  • La entrada del JIT es la misma cinta de bytecode de siempre
    • En vez de los 255 registros base de la VM, planifica según 12 registros físicos en x86-64 y 24 en AArch64
    • En AArch64 se asigna a v8-31, y en x86-64 a xmm4-15
  • Para cada combinación de opcode × tipo de dato × arquitectura, se escriben a mano fragmentos de ensamblador
    • Los registros físicos deseados se parchean en el fragmento y luego se copia a una región de memoria obtenida con mmap
  • A nivel de Rust, la memoria generada se convierte con cast a un puntero de función y se invoca
    • La entrada y la salida se pasan convirtiendo los slices de Rust a raw pointers
  • Métricas de rendimiento

    • En un ejemplo complejo compuesto por 7867 expresiones, la evaluación brute force de 1024² píxeles muestra claramente el efecto del JIT
    • Intérprete de bytecode: 5.8 segundos
    • Backend JIT: 182 ms
    • Mejora de velocidad: 31 veces
    • El brute force no usa aritmética de intervalos ni simplificación de la cinta
    • Si se usa un algoritmo más inteligente, la diferencia se reduce
    • La implementación de renderizado optimizado de Fidget dibuja la misma imagen en 6 ms con el intérprete de bytecode y en 4.6 ms con el backend JIT
    • En este caso, la mejora es de alrededor de 25%

Renderizado y generación de mallas

  • Renderizado

    • Todo el renderizado de modelos usa los algoritmos de fidget::render
    • El renderizado usa el algoritmo central del artículo de SIGGRAPH
    • Renderiza regiones espaciales grandes con aritmética de intervalos
    • Genera cintas acortadas a partir del rastreo
    • Las regiones ambiguas se subdividen y se procesan recursivamente
    • En renderizado 3D, las normales se calculan con derivadas parciales
    • Los modelos se transforman durante el renderizado con matrices homogéneas de 4×4
    • Soporta transformación de perspectiva
    • El resultado del renderizado suele ser un heightmap y una imagen de normales por píxel
    • El resultado puede dibujarse con técnicas estándar de renderizado diferido como SSAO
  • Generación de mallas

    • Fidget implementa Manifold Dual Contouring para generar mallas
    • Esta implementación debería generar siempre mallas con las siguientes características
      • watertight
      • manifold
      • conserva bordes y esquinas afilados
      • comportamiento adaptativo que reduce la densidad de triángulos en zonas mayormente planas
    • También tiene defectos conocidos
      • no necesariamente preserva características delgadas
      • la malla resultante puede incluir autointersecciones
      • la ubicación de los vértices es vulnerable a adversarial cases
    • La buena generación de mallas para superficies implícitas arbitrarias sigue siendo un problema sin resolver
    • Manifold Dual Contouring no es perfecto, pero ofrece un punto de equilibrio entre simplicidad y rendimiento

Demo y GUI web

  • El repositorio de Fidget incluye varios demos
    • La GUI web se presenta como el demo más interesante
    • También están fidget-cli, una CLI simple, y fidget-viewer, un visor nativo de scripts
  • El demo web combina varias tecnologías web
    • La GUI está escrita en TypeScript
    • El crate de Fidget no controla el event loop y se usa como biblioteca
    • El editor de texto usa CodeMirror
    • Se necesitó un bundler para usar módulos de Node, y se eligió webpack
    • La evaluación de scripts y el renderizado se ejecutan en un web worker para no bloquear el event loop principal
    • Para sortear la ausencia de std::thread en el navegador, el renderizado se paraleliza con wasm-bindgen-rayon
    • El worker y el event loop principal comparten memoria
    • Cuando el usuario da una nueva entrada, se puede cancelar un renderizado largo mediante una bandera Arc<AtomicBool> compartida con el worker
  • Hacer que todos los componentes funcionaran juntos fue difícil
    • Cada componente tenía ejemplos funcionales, pero el bundler, la configuración y el servidor eran distintos entre sí
    • Una corrección reciente de bugs en wasm-bindgen cambió el comportamiento que necesitaba wasm-bindgen-rayon, así que hubo que fijar una versión antigua
  • El demo web también funciona en teléfonos
    • Como usa eventos de mouse, no soporta control de cámara

La tensión entre el demo y la biblioteca

  • Fidget es прежде всего una biblioteca
    • La forma de uso prevista es que los usuarios la integren como infraestructura en sus propios proyectos, más que usar el demo como una herramienta CAD real
  • Pero hay mucha más gente que prueba el demo que gente que crea herramientas con la biblioteca
    • Algunos incluso usan el demo para trabajo de diseño
    • Existe una tensión entre mejorar el demo para una base de usuarios más grande o mejorar la biblioteca para una base más pequeña de creadores de herramientas
  • Mantener al mismo tiempo el kernel y una UI CAD completa fue difícil, y el alcance del demo se fue reduciendo
    • Incluso un demo “mínimo” como el editor web es un proyecto considerable
  • El plan va en tres direcciones
    • seguir persiguiendo sus propios intereses para mantener la motivación y el enfoque
    • aceptar sugerencias de usuarios de herramientas, pero manteniendo expectativas razonables
    • idealmente, priorizar el feedback de creadores de herramientas que ayude a reducir la carga del demo

Posibilidades futuras

  • Backend de GPU

    • El backend de GPU es una extensión natural
    • Ya existe un artículo de SIGGRAPH relacionado
    • Ya está implementado en la rama wgpu-bytecode
    • El rendimiento en una laptop Apple M1 Max no resulta especialmente atractivo
    • El bucle del intérprete de bytecode parece ser muy ineficiente
    • Se sigue investigando la causa de fondo
  • Mejor generación de mallas

    • Para los usuarios serios de la biblioteca, la generación de mallas es un problema importante
    • Fidget usa una estrategia de generación de mallas similar a la de libfive, pero no incluye varios ajustes finos que hacen más robusto el comportamiento de libfive
    • Como no estaba satisfecho con las opciones disponibles actualmente, no dediqué mucho tiempo a esta parte
    • Quiero implementar un algoritmo de mallas a prueba de fallos en lugar de seguir parcheando dual contouring
    • Aún no existe un método en la literatura ni una alternativa propia que cumpla con los requisitos
    • Según la demanda de los usuarios, podría hacer algunos ajustes, pero también planeo seguir buscando mejores alternativas
  • Biblioteca estándar de shape y transform

    • A lo largo de varias generaciones de software, he ido portando la biblioteca estándar de shapes de Fab Modules a herramientas nuevas
    • Este trabajo es tedioso, pero proporciona una base más o menos estándar para el modelado de alto nivel
    • En libfive, cada shape se escribía en C++, y desde el archivo de encabezado se generaban automáticamente los bindings para C, Python y Scheme
    • El README explica que libfive_stdlib.h es a la vez un encabezado en C y documentación estructurada que analiza un helper script
    • El enfoque de Fidget todavía está en discusión
    • La discusión en curso está en fidget#145
    • Es factible llevar la biblioteca de shapes de Fab a Rust
    • También sirve como referencia un código más elegante que aprovecha vectores de GLSL, como la biblioteca de primitivas de Inigo Quilez
  • Bindings para lenguajes de alto nivel

    • Actualmente, Fidget solo ofrece bindings para Rhai
    • Se eligió Rhai porque es uno de los lenguajes de scripting Rust-first maduros
    • Fue fácil de integrar y tiene la ventaja de compilar a WebAssembly
    • Muchos usuarios podrían preferir bindings para Python o Node
    • La forma de hacer los bindings también sigue siendo una pregunta pendiente
    • La API de C permite aprovechar las bibliotecas FFI de cada lenguaje, pero en un diseño Rust-first se siente como bajar un nivel
    • Cuando exista una biblioteca estándar, sería bueno que se expusiera automáticamente en cada binding con una usabilidad adecuada, como docstrings y argumentos predeterminados

Estado de publicación y cómo usarlo

  • El README de Fidget ha descrito su estado desde la publicación inicial como “quietly public”
    • Se han publicado 19 versiones en crates.io
    • Algunos usuarios ya empezaron a construir cosas sobre Fidget
  • Ahora Fidget pasa a la etapa de “loudly public”
  • El código fuente está en Github
    • En proyectos de Rust, se puede agregar con cargo add fidget
    • La licencia es la débilmente copyleft MPL 2.0
    • Se presenta como una licencia amigable tanto para OSS como para uso comercial

1 comentarios

 
GN⁺ 2025-01-09
Opiniones de Hacker News
  • Hola, es mi proyecto :)
    Esta área de CS me gusta especialmente porque tiene algo para todos: estructuras de datos y algoritmos, trabajo de rendimiento de bajo nivel, compiladores, renderizado/gráficos por computadora, UI/UX para herramientas de diseño, programación GPGPU, etc.
    Voy a responder las preguntas que vea en el hilo, pero también pueden seguir actualizaciones adicionales en redes sociales (https://mattkeeter.com/links/) o en el feed RSS del blog (https://mattkeeter.com/atom.xml)

    • Estaba mirando el blog y encontré esto; me pareció excelente: https://www.mattkeeter.com/projects/machined-pen/the_plan.jp...
      Ilustra muy bien una idea que tengo en la cabeza desde hace tiempo. ¿Qué pasaría si el propio proceso de diseñar este plan de fabricación se convirtiera en una API de CAD orientada al usuario? Cuando uno aborda problemas de “fabricación” como carpintería, plomería, trabajo en metal o mecanizado, naturalmente piensa en la materia prima, las herramientas disponibles y la secuencia de operaciones para obtener el resultado deseado.
      Pero las API de CAD actuales, ya sean herramientas de CAD por código o interfaces tradicionales basadas en mouse, no funcionan de esa manera: hacen que uno se concentre en cómo representar la forma terminada, más que en cómo se va a fabricar realmente. Al final, lo importante es hacer el objeto, y el modelado es solo una herramienta para ayudar a lograrlo, pero esa herramienta termina ocupando demasiado protagonismo.
      Un flujo de modelado más basado en la realidad parece tener muchas ventajas. Desde tu perspectiva, con mucha más experiencia en CAD, ¿ves potencial de desarrollo en este concepto o crees que es un callejón sin salida?
      También agrego un comentario sobre la pluma: podrías sujetar la barra en un chuck de 3 mordazas, tornearla hasta una dimensión compatible con el collet, cortar de esa barra dimensionada un blank para 1 tapa y 2 cuerpos, y luego sujetar el resto del trabajo con el collet para mantener la concentricidad. Eso sí, si las dimensiones finales no coinciden con la medida del collet, habrá algo de desperdicio de material.
    • Matt, una pregunta rápida. No investigué lo suficiente, así que disculpa si es demasiado general o tonta.
      En cuanto a funcionalidad, ¿en qué se diferencia Fidget de libfive o Ao?
    • ¡Muy bueno! Recuerdo haber contribuido al código del parser de expresiones del trabajo de Knoll et al. 2009 citado en el paper de SIGGRAPH.
      Ese código solo convertía una expresión única, amigable para el usuario, en llamadas a funciones anidadas para una biblioteca de IA dentro de GLSL; no hacía ninguna optimización. Esto va mucho más allá.
  • Casualmente, justo estaba leyendo otro excelente artículo del autor: https://www.mattkeeter.com/projects/constraints/

  • Vaya, si hubiera sabido de esto cuando hice mi propio renderizador de superficies implícitas, me habría sido tremendamente útil.
    Mi enfoque era parecido en algunos aspectos (aritmética de intervalos) y diferente en otros. Estaba menos optimizado y generaba GLSL directamente para el fragment shader.
    Sinceramente, me dan ganas de tirar todo y volver a implementarlo usando esto como reemplazo. No sé si alegrarme o entristecerme.

    • ¡Puedes alegrarte! Trabajas en un campo donde puedes crear tus propias herramientas y también usar herramientas hechas por otros.
      Puedes tomar ideas prestadas, o usar esto y contribuir al proyecto. Cualquiera de las dos opciones es genial.
  • ¡Es fantástico que haya aparecido un nuevo kernel CAD de código abierto! Por el artículo no me quedó claro si admite exportar a formatos comunes como STEP.
    Si fuera posible, o si llegara a serlo, creo que podría convertirse en una gran base para varias bibliotecas CAD de código abierto.

    • Lamentablemente, no admite exportación a STEP. Los archivos STEP usan una representación interna completamente distinta.
      La mayoría de los archivos STEP representan la geometría como un conjunto de superficies, por ejemplo trimmed NURBS. Esas superficies deben formar una variedad sin huecos, y entonces pueden tratarse como un volumen sólido.
      Para hacer que esto funcione en la práctica, se necesita un kernel de representación por bordes (b-reps), no las representaciones funcionales (f-reps) de Fidget. Escribir un kernel de ese tipo es un problema mucho más difícil. Por ejemplo, la intersección de dos superficies NURBS no siempre tiene una representación en forma cerrada.
      Al hablar con alguien de la industria, estimó que incluso un equipo que ya lo hubiera hecho antes necesitaría alrededor de 6 ingenieros durante aproximadamente un año para escribir un kernel b-rep decente.
      Si quieres saber más, casualmente también escribí un visor de archivos STEP que incluye un kernel b-rep muy lejos de ser de nivel industrial: https://www.mattkeeter.com/projects/foxtrot/
  • “Si se hace una evaluación por fuerza bruta sobre 1024² píxeles, el intérprete de bytecode tarda 5.8 segundos, mientras que el backend JIT tarda 182 ms, así que es 31 veces más rápido”
    “Si se usan algoritmos más inteligentes, la mejora de velocidad es menos dramática. El método de fuerza bruta no aprovecha la aritmética de intervalos ni la simplificación de cinta. La implementación de renderizado optimizada de Fidget dibuja esta imagen en 6 ms con el intérprete de bytecode y en 4.6 ms con el backend JIT, por lo que la mejora es de apenas alrededor del 25%”
    Me gusta que aquí se enfoquen en que el backend JIT es menos importante después de la optimización algorítmica, y no en que la optimización algorítmica da una mejora de 1000 veces en bytecode y de 40 veces en JIT

  • Hace unos años trabajé un poco en la universidad en un simulador de física nuclear, es decir, algo como modelado de reactores nucleares
    Ese modelo geométrico se basaba en superficies implícitas, en particular en R-functions. min(x,y) también es un ejemplo, y tienen propiedades interesantes, como ser diferenciables en todas partes
    Un buen material introductorio es este. Quizá sea el único material disponible en inglés: https://ecommons.cornell.edu/items/35ae0f68-1af5-4f28-8b8b-7...
    Hace bastante que dejé el campo nuclear, pero supongo que para el modelado todavía se usa mucho código Fortran antiguo. Fidget tiene posibilidades interesantes como kernel para nuevos paquetes de simulación

  • Un poco aparte, estoy buscando el mejor software CAD basado en código
    Probé CadQuery y tuve algunos problemas. ¿Hay algo que recomienden para impresión 3D?

    • Di una charla sobre CAD basado en código y cubrí bastantes opciones
      https://youtu.be/0wn7vUmWQgg?si=9Rc1tvbiQgQDgQzd&t=2766
      También estoy desarrollando uno en Rust, pero todavía es difícil decir que esté listo
    • También está build123d
      https://github.com/gumyr/build123d
    • Para quienes no quieran abrir el video, la lista mencionada en otros comentarios/el video es esta
      OpenSCAD, DSLCAD, CadQuery, Build123d, Cascade Studio, Declaracad, Replicad
    • replicad
  • Interesante. Ya había visto antes artículos y demos sobre este tipo de superficies implícitas. Quizá incluso eran trabajos del autor
    Es impresionante ver qué modelos se pueden crear usando la imaginación, pero me gustaría ver algo más grande que ejemplos de juguete
    Por ejemplo, ¿sería posible extruir superficies como en un kernel b-rep, o importar SVG/fuentes y convertirlos en sólidos?
    De verdad me gustaría ver un kernel open source rápido que soporte estas funciones y además paralelice bien

  • Me recuerda mucho a https://bauble.studio/ de Ian Henry

  • Yo también quería probar algo parecido: usar SDF para manejar un árbol abstracto para generación de superficies
    La idea es tener una malla o nube de puntos objetivo, y mediante hill climbing/annealing encontrar un árbol que se ajuste bien a la forma deseada

    • “A Unified Differentiable Boolean Operator with Fuzzy Logic” podría resultar interesante
      https://arxiv.org/abs/2407.10954
      Permite combinar leaves diferenciables (cuádricas) mediante operaciones similares a Boolean diferenciables para crear un árbol CSG, y así hacer hill climbing sobre la forma completa