NVIDIA Open-Sourced a CAD Kernel. Its Own Known-Issues File Is the Best Documentation

NVIDIA published USD BRep, a NURBS solid-modeling kernel, on Oct 8. It drew 1,592 stars on 3 commits. We read the architecture, the build traps (MSVC v142, macOS gaps), and the known-issues file that admits two functions report success while doing nothing.

NVIDIA published a NURBS solid-modeling kernel to GitHub on 8 October 2026. Nine days later it had 1,592 stars and 222 forks.

It also has three commits. And the contributors endpoint returns empty.

Those two facts are not a contradiction to be alarmed about — they tell you exactly what this release is. 44.9 MB of C++ across 1,522 files, with copyright spanning 2020–2026, pushed as a single v1.0.0 code drop. This is not a project that grew on GitHub. It is six years of internal work made public in one afternoon.

Which raises the more useful question: is the code worth your time, and what will it cost you to find out? For once, the repository answers that itself — in a KNOWN_ISSUES.md that is unusually honest about what does not work.

What USD BRep actually is

The repo description is precise: “a standalone C++ and Python library for NURBS-based boundary representation (BRep) solid modeling.”

The distinction that matters is BRep versus polygon mesh. From AGENTS.md:

“SMLib is a NURBS-based boundary representation (BRep) solid modeling kernel. It represents solids as collections of topological entities (shells, faces, edges, vertices) bound to exact geometric definitions (NURBS surfaces, B-spline curves, analytic primitives). Geometry is mathematically exact and resolution-independent, unlike polygon meshes.”

“Mathematically exact” is not marketing shorthand. The kernel supports “analytic, NURBS, and other curve/surface subclasses” — a NURBS surface can represent a sphere exactly, with no polygonal approximation at the source. The topology is a real hierarchy: SmBrep → SmShell → SmFace → SmEdge → SmVertex, with adjacency tracked between them.

The mesh you eventually render is generated downstream, on demand, by tessellation. That ordering is the whole point: exact geometry is the source of truth, triangles are a view of it.

Five layers, and where the seams are

AGENTS.md lays out the stack cleanly:

LayerPathOwns
SMLibsource/SMLib/Core C++ kernel: geometry/topology classes and algorithms; memory via SmContext
SM_APIsource/SM_API/High-level C-style API, SmApi* naming — booleans, sweeps, fillets, tessellation
SM_API_USDsource/SM_API_USD/USD import/export
BREP_SM_USD / BREP_USD_DATAinternalBRep ↔ USD data conversion
SmPyLibsource/SmPyLib/, module _omni_solidpybind11 bindings, tessellation to PolyBrep, polygon-mesh booleans

The C++ surface is broad and named predictably — SmApiPrimitives.h (box, sphere, cone, cylinder, torus, pyramid, partial primitives), SmApiBrep.h (booleans, sweeps, cut, project, stitch, fillet, offset/shell), SmApiFillets.h (chamfer, circular, remove), SmApiIntersectors.h, SmApiHeal.h, SmApiQueries.h.

The rule most readers will miss

Buried in AGENTS.md under end-to-end asset generation is a hard rule that contradicts the intuitive path:

"Do not round-trip through BrepArray USD prims for asset authoring. Stay in-process via — SMLib → sm.tessellate(brep) → PolyBrep → PolyBrep.to_mesh_arrays() → UsdGeom.Mesh prims (z-up, cm scale)."

So BrepArray exists for interchange and preservation, not as a pipeline checkpoint. Authoring through it is explicitly discouraged. If you were planning to use the USD round-trip as your internal format, that is not the intended use.

BrepArray itself is a custom schema holding BRep data alongside standard USD prims, and it respects composition: usd.heal_file heals BrepArray definitions “keeping its layers, references, native instancing, transforms and materials.” Material subset opinions outside the defining prim spec are “rejected rather than lost” — a small detail, but the right instinct.

Now the part worth the read: KNOWN_ISSUES.md

Most vendor repos of this shape ship a changelog and a roadmap. This one ships a list of twenty-odd specific defects, several of which are worse than “wrong output.”

Two functions report success while doing nothing

"remove_fillet (SmApiRemoveFillet) returns success without removing the fillet."

Workaround: “none. Check the result after the call, for example its face count or volume().”

"heal_brep (SmApiHealBrep) does not report failures from its repair stages, including seam insertion."

Workaround: check the healed Brep with is_manifold_solid(), or bin/brep_geometry_validator after exporting to USD.

A silent no-op with no workaround is bad enough. heal_brep is worse, because of where it sits: healing is the automated pre-processing step a CAD-to-USD pipeline runs on every import. A function that returns success while failing to insert seams passes corrupted topology downstream without an exception — and the same file documents that un-repaired topology can later crash the process on USD import, render inside-out triangles, or cascade into validator failures.

If you take one thing from this article: verify heal_brep’s output, not its return code.

Seam handling on tori, spheres and cylinders

The healing section lists ten distinct failure modes on periodic and closed surfaces. The specific ones:

  • “Inserting the first seam on an uncut torus splits it into two faces.”
  • “A torus whose one seam edge is used by two loops is treated as collapsed.”
  • “A sphere bounded by two coincident seam edges is treated as collapsed and deleted.”
  • “A cylindrical face with a pocket can be left with two outer loops after its seam is repaired.”
  • “A missing seam on a torus face is not detected when the face boundary lies partly along the other seam, or when the face has only interior holes.”

A deleted sphere face is not a tolerance issue. And the file is careful to locate the cause: "These faces mostly come from other CAD systems." BrepArrays written by USD BRep itself are not affected.

That matters for how you read the whole document. This is a kernel that is reliable on its own output and explicitly unsure about everyone else’s — which is precisely the geometry a CAD interoperability pipeline ingests.

Measurement error, with numbers

This is the kind of disclosure most vendors omit:

Face area, Brep area, volume and mass properties “can be inaccurate for faces whose trim curves have interior knots, such as rational circles. Measured relative area errors were up to about 1.4% at the default relative_accuracy of 1e-3, and up to 20% at 1e-1.”

20% volume error at a coarse setting. The workaround is real — error fell as accuracy tightened in every measured case — but the takeaway is that relative_accuracy is a correctness dial, not a speed dial, on circular trims. A mass-properties query used for quoting material cost needs to know that.

Also admitted

  • Tessellation: on circular_fillet solids, tessellate() can wind triangles against the face normal, rendering inside out — “Seen on cylinder caps and on cones next to fillets.” Workaround: surface_angle_tolerance_deg of 15° avoided every case found.
  • Import crash: “Reading a BrepArray whose topology counts or indices disagree with its array sizes can read out of bounds and crash the process.” Validate first with brep_validator_cli/validate_usd.sh --brep-only or nvidia_usd_validate.
  • Validator noise: a single orphan edge (BA.582) makes the validator report unrelated failures (BA.175, BA.205, BA.225 …) for later Breps. Fix BA.582 first, then re-validate.
  • Release-package scripts broken: validate_usd.sh expects a source checkout and exits 127 when run from the release package.

Build reality: the MSVC v142 trap and macOS gaps

The README is upfront about dependencies, in a way that suggests the authors have watched people fail at this.

Pulled automatically via Packman: OpenUSD, Python 3.12, pybind11, premake, and the repo_* tools.

You must install:

  • Git + Git LFS — LFS is required for large binary fixtures (USD assets, STEP/IGES/JT models) tracked in .gitattributes.
  • Linux: build-essential.
  • Windows: Visual Studio 2019 or 2022 with the “Desktop development with C++” workload, plus the Windows SDK, plus the VC++ Redistributable to run the binaries.

And then this, which will cost Windows teams an afternoon:

"msbuild.vs_version is pinned to vs2019, so VS 2022 users also need the MSVC v142 build tools component."

Also: “The build uses this host-installed compiler (msbuild.link_host_toolchain in repo.toml), not Packman msvc.” Discovery failures are fixed by pointing msbuild.vs_path / msbuild.vs_version / msbuild.winsdk_path at an existing install — those settings locate a toolchain, they do not install one.

macOS is where the gaps are widest, and the README says so plainly:

  • Apple Silicon only.
  • The default Python-only build includes the kernel, C++ tests, _smlib_tests and _smlib_dev — but no OpenUSD, no OCCT, and no _omni_solid. The primary Python extension is in Tier 1, which is optional.
  • “Packman OpenUSD/Python packages are not available on macOS.”
  • The macOS premake package “is not on the public Packman server either” — you must supply it through a user-level Packman configuration.

So a Mac developer’s default experience is the kernel without the USD integration, and reaching Tier 1 means staging OpenUSD locally (SMLIB_USD_ROOT=~/opt/usd-25.11-py312) via a script and bringing your own premake.

Two Python APIs, and you need to know which you have

The README’s examples use _omni_solid, the source-checkout module. There is a separate packaged usd_brep distribution with its own README and operation submodules.

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)}

Tessellation is governed by five parameters — chord_height_tolerance, curve_angle_tolerance_deg, surface_angle_tolerance_deg, max_edge_length, max_aspect_ratio — and the defaults live in SmTessellationDefaults (kChordHeightTol, kCurveAngleTolDeg, kSurfaceAngleTolDeg, kMaxEdgeLength, kMaxAspectRatio). The actual default float values are not published anywhere in the docs. If your output depends on them, read them off the header.

The contradiction nobody explains

README.md and CONTRIBUTING.md both state, identically:

“This project is currently not accepting contributions. Issues and bug reports are welcome through the project issue tracker.”

And AGENTS.md opens with:

“This file provides guidance to AI coding agents when working with code in this repository.”

A repository that refuses external pull requests but maintains a detailed guide for AI coding agents is a coherent position only if the intended contributor is internal, or a developer running a local checkout — an agent helping you modify your fork, not one submitting upstream. No source states this rationale.

Practically, it means one thing: you are adopting a code drop, not joining a community. The 15 open issues may get fixed; there is no published roadmap, no bug-fix schedule, and no obligation to accept your patch. Plan for an internal fork strategy on day one, not on the day you need it.

What you cannot learn from the docs

Worth stating explicitly, because each is a decision input that the documentation simply does not provide:

  • Thread safety. SMU_THREAD_LOCAL macros exist in the headers, but no rules for mutex usage, re-entrancy, or concurrent SmContext access are documented.
  • Performance. No benchmarks, no memory footprint per BRep entity or tessellated face. For a 45 MB kernel this is the single biggest unknown.
  • Algorithm mechanics. No mention of Delaunay versus advancing-front tessellation, no healing heuristics described.
  • Exact default tolerances. Named but not valued, as above.

Who this is for

A strong fit if you need exact solid geometry inside an OpenUSD pipeline — CAD interchange, procedural parts, simulation-ready assemblies — and you would rather have a real BRep kernel than a mesh approximation you have to re-tessellate forever. The Apache-2.0 licence, the native BrepArray schema, and the fact that healing preserves layers, references, instancing and materials all point at production USD workflows rather than demos.

A poor fit if you are on macOS and need the full stack today (Tier 1 is optional and under-supported), if you need a supported product with an SLA and a support channel, or if your pipeline ingests third-party CAD exclusively — which is exactly the geometry KNOWN_ISSUES.md is least confident about.

The verification checklist

Before committing to this, run these six checks against your own data rather than the README:

  1. Healing on your real CAD files. Import a representative batch of STEP/IGES, call heal_brep, then verify with is_manifold_solid() and bin/brep_geometry_validator — do not trust the return code.
  2. Look for deleted or split faces on tori, spheres and cylinders, especially pocketed cylindrical faces and any sphere bounded by coincident seams.
  3. Measure a known solid. Compare volume() and area() against an established kernel, and re-run with relative_accuracy tightened. Expect up to 1.4% error at the default on rational circular trims.
  4. Inspect tessellated fillets for inverted triangles on cylinder caps and cones.
  5. Validate every incoming BrepArray before import — malformed topology indices can crash the process, not raise an error.
  6. Build on your actual CI. Windows agents need VS with the v142 component; macOS agents need custom Packman config plus local OpenUSD staging.

The bottom line

This is a genuine NURBS BRep kernel — six years of work, Apache-2.0, with a real USD schema, not a thin wrapper. The 1,592 stars in nine days reflect how few credible open-source exact-geometry kernels exist inside the USD ecosystem.

What makes it trustworthy is not the star count. It is that the project documents its own silent failures. A KNOWN_ISSUES.md that admits remove_fillet does nothing and provides no workaround is more useful to you than a roadmap promising v1.1 — because it tells you precisely which invariants to test before you depend on them.

Read that file first. Then build it, heal your ugliest import, and check the face count yourself.

Sources: NVIDIA-Omniverse/usd-brep README.md, AGENTS.md, KNOWN_ISSUES.md, CHANGELOG.md, CONTRIBUTING.md and VERSION read on 2026-10-17; NVIDIA’s published API reference at nvidia-omniverse.github.io/usd-brep; repository metrics via the GitHub REST API on 2026-10-17 (1,592 stars, 222 forks, 24 watchers, 3 commits, one release v1.0.0, 1,522 files, C++ 95.1%).