NVIDIA publicó un kernel de modelado sólido NURBS en GitHub el 8 de octubre de 2026. Nueve días después tenía 1.592 estrellas y 222 forks.
También tiene tres commits. Y el endpoint de contributors devuelve vacío.
No es una contradicción alarmante: indica exactamente qué es esta publicación. 44,9 MB de C++ repartidos en 1.522 archivos, con copyright que abarca de 2020 a 2026, publicados como un único volcado de código en la versión v1.0.0. No es un proyecto que creció en GitHub. Son seis años de trabajo interno hechos públicos en una tarde.
Lo cual plantea la pregunta útil: ¿merece tu tiempo el código, y cuánto te costará averiguarlo? Por una vez, el propio repositorio responde — en un KNOWN_ISSUES.md inusualmente honesto sobre lo que no funciona.
Qué es realmente USD BRep
La descripción del repositorio es precisa: “una biblioteca independiente de C++ y Python para modelado sólido mediante representación de contornos (BRep) basada en NURBS.”
La distinción que importa es BRep frente a malla poligonal. De AGENTS.md:
“SMLib es un kernel de modelado sólido BRep basado en NURBS. Representa sólidos como colecciones de entidades topológicas (shells, caras, aristas, vértices) ligadas a definiciones geométricas exactas (superficies NURBS, curvas B-spline, primitivas analíticas). La geometría es matemáticamente exacta e independiente de la resolución, a diferencia de las mallas poligonales.”
“Matemáticamente exacta” no es un eslogan: el kernel admite curvas y superficies analíticas, NURBS y otras subclases, y una superficie NURBS puede representar una esfera de forma exacta, sin aproximación poligonal en el origen. La topología es una jerarquía real: SmBrep → SmShell → SmFace → SmEdge → SmVertex, con adyacencia registrada entre ellas.
La malla que acabas renderizando se genera después, bajo demanda, mediante teselación. Ese orden lo es todo: la geometría exacta es la fuente de verdad, los triángulos son una vista de ella.
Cinco capas, y dónde están las costuras
AGENTS.md describe la pila con claridad:
| Capa | Ruta | Responsabilidad |
|---|---|---|
SMLib | source/SMLib/ | Kernel C++ central: clases de geometría/topología y algoritmos; memoria vía SmContext |
SM_API | source/SM_API/ | API de alto nivel estilo C, nomenclatura SmApi* — booleanos, barridos, redondeos, teselación |
SM_API_USD | source/SM_API_USD/ | Importación/exportación USD |
BREP_SM_USD / BREP_USD_DATA | internas | Conversión de datos BRep ↔ USD |
SmPyLib | source/SmPyLib/, módulo _omni_solid | Enlaces pybind11, teselación a PolyBrep, booleanos de malla |
La superficie C++ es amplia y con nombres predecibles: SmApiPrimitives.h (caja, esfera, cono, cilindro, toro, pirámide, primitivas parciales), SmApiBrep.h (booleanos, barridos, corte, proyección, costura, redondeo, offset/shell), SmApiFillets.h (chaflán, circular, eliminación), SmApiIntersectors.h, SmApiHeal.h, SmApiQueries.h.
La regla que casi nadie leerá
Enterrada en AGENTS.md, dentro de la generación de assets de extremo a extremo, hay una regla estricta que contradice el camino intuitivo:
"No hagas ida y vuelta a través de prims USD
BrepArraypara la creación de assets. Quédate en proceso vía — SMLib →sm.tessellate(brep)→PolyBrep→PolyBrep.to_mesh_arrays()→ primsUsdGeom.Mesh(z-up, escala cm)."
Es decir: BrepArray existe para intercambio y preservación, no como punto de control del pipeline. Crear assets a través de él está explícitamente desaconsejado. Si pensabas usar el ida y vuelta USD como formato interno, no es el uso previsto.
BrepArray es un esquema personalizado que almacena datos BRep junto a prims USD estándar, y respeta la composición: usd.heal_file sanea las definiciones de BrepArray “manteniendo sus capas, referencias, instanciación nativa, transformaciones y materiales.” Las opiniones de subconjunto de material fuera del prim spec que define el BRep se “rechazan en lugar de perderse” — un detalle pequeño, pero con el instinto correcto.
Ahora la parte que merece leerse: KNOWN_ISSUES.md
Casi todos los repositorios de proveedor con esta forma incluyen un changelog y un roadmap. Este incluye una lista de más de veinte defectos concretos, varios peores que “resultado incorrecto”.
Dos funciones devuelven éxito sin hacer nada
"
remove_fillet(SmApiRemoveFillet) devuelve éxito sin eliminar el redondeo."Solución: “ninguna. Comprueba el resultado tras la llamada, por ejemplo su número de caras o
volume().”
"
heal_brep(SmApiHealBrep) no informa de fallos en sus etapas de reparación, incluida la inserción de costuras."Solución: revisa el BRep saneado con
is_manifold_solid(), o conbin/brep_geometry_validatortras exportarlo a USD.
Un no-op silencioso sin solución ya es malo. heal_brep es peor, por dónde se sitúa: el saneamiento es el paso automático de preprocesado que un pipeline CAD-a-USD ejecuta en cada importación. Una función que devuelve éxito mientras falla al insertar costuras deja pasar topología corrupta aguas abajo sin lanzar excepción — y el mismo archivo documenta que la topología sin reparar puede después tumbar el proceso al importar USD, renderizar triángulos invertidos o provocar fallos en cascada del validador.
Si te llevas una sola cosa de este artículo: verifica la salida de heal_brep, no su código de retorno.
Costuras en toros, esferas y cilindros
La sección de saneamiento enumera diez modos de fallo distintos en superficies periódicas y cerradas. Los concretos:
- “Insertar la primera costura en un toro sin cortar lo divide en dos caras.”
- “Un toro cuya única arista de costura usan dos bucles se trata como colapsado.”
- “Una esfera delimitada por dos aristas de costura coincidentes se trata como colapsada y se elimina.”
- “Una cara cilíndrica con un bolsillo puede quedar con dos bucles exteriores tras reparar su costura.”
- “No se detecta una costura ausente en una cara de toro cuando el contorno de la cara discurre en parte por la otra costura, o cuando la cara solo tiene agujeros interiores.”
Una cara de esfera eliminada no es un problema de tolerancia. Y el archivo se cuida de localizar la causa: "Estas caras provienen mayoritariamente de otros sistemas CAD." Los BrepArray escritos por el propio USD BRep no se ven afectados.
Eso importa para cómo leer el documento entero. Es un kernel fiable con su propia salida y explícitamente inseguro con la de los demás — precisamente la geometría que ingiere un pipeline de interoperabilidad CAD.
Error de medición, con números
Este es el tipo de revelación que casi todos los proveedores omiten:
El área de cara, el área y el volumen del Brep y las propiedades másicas “pueden ser inexactos en caras cuyas curvas de recorte tienen nudos interiores, como las circunferencias racionales. Los errores relativos de área medidos llegaron a unos 1,4% con el
relative_accuracypor defecto de 1e-3, y hasta un 20% con 1e-1.”
20% de error de volumen con un ajuste grueso. La solución existe — el error bajó al apretar la precisión en todos los casos medidos — pero la conclusión es que relative_accuracy es un dial de corrección, no de velocidad en recortes circulares. Una consulta de propiedades másicas usada para presupuestar material necesita saberlo.
También admitido
- Teselación: en sólidos redondeados con
circular_fillet,tessellate()puede orientar triángulos contra la normal de la cara y renderizarlos del revés — “Visto en tapas de cilindro y en conos junto a redondeos.” Solución:surface_angle_tolerance_degde 15° evitó todos los casos encontrados. - Cuelgue en importación: “Leer un BrepArray cuyos recuentos o índices topológicos no concuerdan con los tamaños de sus arrays puede leer fuera de límites y tumbar el proceso.” Valida antes con
brep_validator_cli/validate_usd.sh --brep-onlyonvidia_usd_validate. - Ruido del validador: una sola arista huérfana (BA.582) hace que el validador informe fallos no relacionados (BA.175, BA.205, BA.225…) en Breps posteriores. Corrige primero BA.582 y vuelve a validar.
- Scripts del paquete release rotos:
validate_usd.shespera un checkout de código fuente y sale con código 127 desde el paquete release.
Realidad de compilación: la trampa MSVC v142 y los huecos de macOS
El README es explícito con las dependencias, de una forma que sugiere que los autores han visto fallar a gente en esto.
Se descarga automáticamente vía Packman: OpenUSD, Python 3.12, pybind11, premake y las herramientas repo_*.
Debes instalar tú:
- Git + Git LFS — LFS es obligatorio para los fixtures binarios grandes (assets USD, modelos STEP/IGES/JT) rastreados en
.gitattributes. - Linux:
build-essential. - Windows: Visual Studio 2019 o 2022 con la carga de trabajo “Desarrollo de escritorio con C++”, más el Windows SDK, más el redistribuible VC++ para ejecutar los binarios.
Y luego esto, que costará una tarde a los equipos Windows:
"
msbuild.vs_versionestá fijado avs2019, así que los usuarios de VS 2022 también necesitan el componente MSVC v142 build tools."
Además: “La compilación usa este compilador instalado en el host (msbuild.link_host_toolchain en repo.toml), no el msvc de Packman.” Los fallos de detección se resuelven apuntando msbuild.vs_path / msbuild.vs_version / msbuild.winsdk_path a una instalación existente — esos ajustes localizan una cadena de herramientas, no la instalan.
macOS es donde los huecos son más anchos, y el README lo dice sin rodeos:
- Solo Apple Silicon.
- La compilación
Python-onlypor defecto incluye el kernel, los tests de C++,_smlib_testsy_smlib_dev— pero ni OpenUSD, ni OCCT, ni_omni_solid. La extensión principal de Python está en el Tier 1, que es opcional. - “Los paquetes Packman de OpenUSD/Python no están disponibles en macOS.”
- El paquete premake de macOS “tampoco está en el servidor público de Packman” — debes aportarlo mediante una configuración de usuario.
Así que la experiencia por defecto de un desarrollador en Mac es el kernel sin la integración USD, y llegar al Tier 1 exige preparar OpenUSD en local (SMLIB_USD_ROOT=~/opt/usd-25.11-py312) mediante un script y traer tu propio premake.
Dos APIs de Python, y hay que saber cuál tienes
Los ejemplos del README usan _omni_solid, el módulo del checkout de código fuente. Existe además una distribución empaquetada usd_brep, con su propio README y submódulos de operaciones.
import _omni_solid as sm
box = sm.create_box((0, 0, 0), 10, 10, 10)
sph = sm.create_sphere((0, 0, 0), 5)
result = sm.boolean_union(box.copy(), sph.copy())
result = sm.boolean_difference(box.copy(), sph.copy())
mesh = sm.tessellate(box, chord_height_tolerance=0.0,
curve_angle_tolerance_deg=25.0,
surface_angle_tolerance_deg=25.0)
sm.usd.export_brep(box, "out.usda")
print(box.info()) # {"faces": 6, "edges": 12, "vertices": 8, "manifold": True,
# "volume": 1000.0, "bounds": ((0,0,0),(10,10,10)), "center": (5,5,5)}
La teselación se gobierna con cinco parámetros — chord_height_tolerance, curve_angle_tolerance_deg, surface_angle_tolerance_deg, max_edge_length, max_aspect_ratio — y los valores por defecto viven en SmTessellationDefaults (kChordHeightTol, kCurveAngleTolDeg, kSurfaceAngleTolDeg, kMaxEdgeLength, kMaxAspectRatio). Los valores float por defecto no se publican en ninguna parte de la documentación. Si tu salida depende de ellos, léelos de la cabecera.
La contradicción que nadie explica
README.md y CONTRIBUTING.md dicen ambos, de forma idéntica:
“Este proyecto no acepta contribuciones actualmente. Las issues e informes de fallos son bienvenidos a través del rastreador del proyecto.”
Y AGENTS.md abre con:
“Este archivo proporciona guía a los agentes de codificación con IA cuando trabajan con el código de este repositorio.”
Un repositorio que rechaza pull requests externos pero mantiene una guía detallada para agentes de IA solo es coherente si el contribuidor previsto es interno, o un desarrollador con un checkout local — un agente que te ayuda a modificar tu fork, no uno que envía cambios upstream. Ninguna fuente indica esta razón.
En la práctica significa una cosa: adoptas un volcado de código, no te unes a una comunidad. Puede que se corrijan las 15 issues abiertas; no hay roadmap publicado, ni calendario de correcciones, ni obligación de aceptar tu parche. Planifica una estrategia de fork interno desde el primer día, no el día que lo necesites.
Lo que no puedes aprender de la documentación
Conviene decirlo explícitamente, porque cada punto es un dato para decidir que la documentación simplemente no aporta:
- Seguridad de hilos. Existen macros
SMU_THREAD_LOCALen las cabeceras, pero no se documentan reglas de mutex, reentrada ni acceso concurrente aSmContext. - Rendimiento. Sin benchmarks ni huella de memoria por entidad BRep o cara teselada. Para un kernel de 45 MB es la mayor incógnita.
- Mecánica de los algoritmos. No se menciona teselación Delaunay frente a frente de avance, ni se describen las heurísticas de saneamiento.
- Tolerancias por defecto exactas. Nombradas pero sin valor, como se indicó.
Para quién es
Encaja bien si necesitas geometría sólida exacta dentro de un pipeline OpenUSD — intercambio CAD, piezas procedurales, ensamblajes listos para simulación — y prefieres un kernel BRep real antes que una aproximación de malla que tengas que reteselar indefinidamente. La licencia Apache-2.0, el esquema nativo BrepArray y el hecho de que el saneamiento preserve capas, referencias, instanciación y materiales apuntan a flujos de trabajo USD de producción, no a demos.
Encaja mal si estás en macOS y necesitas la pila completa hoy (el Tier 1 es opcional y está poco soportado), si necesitas un producto con soporte, SLA y canal de ayuda, o si tu pipeline ingiere CAD de terceros en exclusiva — que es justo la geometría sobre la que KNOWN_ISSUES.md se muestra menos seguro.
La lista de verificación
Antes de comprometerte, ejecuta estas seis comprobaciones sobre tus propios datos, no sobre el README:
- Saneamiento con tus archivos CAD reales. Importa un lote representativo de STEP/IGES, llama a
heal_brepy verifica conis_manifold_solid()ybin/brep_geometry_validator— no confíes en el código de retorno. - Busca caras eliminadas o divididas en toros, esferas y cilindros, sobre todo caras cilíndricas con bolsillo y cualquier esfera delimitada por costuras coincidentes.
- Mide un sólido conocido. Compara
volume()yarea()contra un kernel establecido y repite conrelative_accuracymás estricta. Espera hasta 1,4% de error por defecto en recortes circulares racionales. - Inspecciona los redondeos teselados en busca de triángulos invertidos en tapas de cilindro y conos.
- Valida cada BrepArray entrante antes de importar — índices topológicos malformados pueden tumbar el proceso en lugar de lanzar un error.
- Compila en tu CI real. Los agentes Windows necesitan VS con el componente v142; los de macOS necesitan configuración Packman propia y preparación local de OpenUSD.
Conclusión
Es un kernel BRep NURBS genuino — seis años de trabajo, Apache-2.0, con un esquema USD real, no un envoltorio fino. Las 1.592 estrellas en nueve días reflejan lo pocos que son los kernels de geometría exacta creíbles dentro del ecosistema USD.
Lo que lo hace fiable no es el número de estrellas. Es que el proyecto documenta sus propios fallos silenciosos. Un KNOWN_ISSUES.md que admite que remove_fillet no hace nada y no ofrece solución te resulta más útil que un roadmap que prometa la v1.1 — porque te dice exactamente qué invariantes probar antes de depender de ellas.
Lee ese archivo primero. Luego compílalo, sanea tu importación más fea y comprueba tú mismo el número de caras.
Fuentes: README.md, AGENTS.md, KNOWN_ISSUES.md, CHANGELOG.md, CONTRIBUTING.md y VERSION de NVIDIA-Omniverse/usd-brep, leídos el 17 de octubre de 2026; referencia de API publicada en nvidia-omniverse.github.io/usd-brep; métricas del repositorio vía la API REST de GitHub el 17 de octubre de 2026 (1.592 estrellas, 222 forks, 24 watchers, 3 commits, una release v1.0.0, 1.522 archivos, C++ 95,1%).