Skip to content
tangency-labsPublic

About

A Rust port of NVIDIA's SMLib B-rep kernel (CAD subset): safe, deterministic, wasm-compatible

Resources

Contributing

Stars

388 stars

Watchers

8 watching

Forks

Repository files navigation

solidcore is developed inside SolidCraft, at solidcore/. The tangency-labs/solidcore repository is an automatic, read-only mirror of that folder. Open issues and pull requests in tangency-labs/solidcraft: kernel-only work against the kernel branch.

solidcore logo: an isometric solid with one filleted edge and a NURBS curve on its top face

solidcore

📊 Live progress: tangency-labs.github.io/solidcore: every unit's port status, the upstream-issues log, and the surface/surface intersection corpus scores, regenerated on every merge.

solidcore is a boundary-representation (B-rep) solid modeling kernel in safe Rust. It is based on NVIDIA's SMLib (from USD BRep, Apache-2.0) and goes its own way from there: it started as a port, and its new constructions, such as the generic rolling-ball blend (docs/generic-blend.md), are designed and built here as clean, procedural constructions that replace the code they supersede. Contributing: CONTRIBUTING.md. Design discussion: the #solidcore-dev channel on Discord.

Solids are exact: shells, faces, loops, edges and vertices bound to analytic and NURBS curves and surfaces. solidcore's first consumer is SolidCraft.

Scope

In scope: the SMLib kernel and the SM_API operation layer of upstream — NURBS math, curve and surface geometry, B-rep topology, intersections, booleans, fillets and chamfers, offset/shell, sweeps and skins, primitives, healing/stitching, mass properties and queries.

Out of scope: upstream's OCCT translators, USD/Hydra integration and Python bindings. See ATTRIBUTION.md.

Goals: no unsafe in the kernel, no panics on bad input, deterministic results, no global state (one Kernel per thread), builds for wasm32-unknown-unknown, and exact or certified geometry. The gate is its own tests, SolidCraft's operation cases and the goldens: every unit's cases checked against their committed expected outputs (AGENTS.md §1).

Status

Every SMLib kernel module has a Rust counterpart, and primitive construction is exercised end to end. Integration remains in progress: deferred paths still limit coverage. The API is experimental (0.0.x).

Use the live unit results for each unit's status and blockers, and the primitive checks for whole-solid results. Per-unit plans and notes live in plan/units/; the generated checklist is PROGRESS.md on the site, with handoff notes in plan/STATUS.md. The progress site is built by site/build.py (python3 site/build.py -> bin/site/).

Reference docs

How the kernel's constructions work, the theory behind them and the invariants they keep, with schematics. Start with the first; each ends with "If you're stuck".

Doc What it covers
Definitions and certificates A surface is its definition and its B-spline a certified approximation; the certificate; exactness classes; the exact extension; the invariants every construction keeps
The generic blend Fillets, chamfers, corners and setbacks
The procedural sweep Swept surfaces, their rotation-minimizing frames, threads
Surface-surface intersection The SSI pipeline, its exact classes, and what the boolean takes from it
Layers Which layer each job lives in

Layout

Path Contents
crates/solidcore The kernel library
crates/goldens Every unit's cases, checked against their goldens
crates/diagnostics solidcore-diag: a shaded picture and a tolerance report of one .smb body
plan/ Unit list, port order, status, findings
site/ Generator for the GitHub Pages progress site
upstream/ Local clone of usd-brep v1.0.1 at 3fd5b95, read only (gitignored)
bin/ All build output (gitignored)

Building

Requires the stable toolchain (pinned by rust-toolchain.toml, which also installs rustfmt, clippy and the wasm32-unknown-unknown target). Cargo output goes to bin/ (see .cargo/config.toml).

cargo build -p solidcore
cargo test -p solidcore
cargo fmt --all --check
cargo clippy --workspace --all-targets -- -D warnings
cargo check -p solidcore --target wasm32-unknown-unknown   # wasm check

Optional: export RUSTC_WRAPPER=sccache to share compilation caches.

WebAssembly stack size

On wasm32-unknown-unknown the Rust stack lives in linear memory without a guard page, so an overflow corrupts memory instead of aborting. solidcore bounds input-driven recursion, but kernel algorithms (subdivision, intersection, filleting) still recurse legitimately. Link wasm consumers with a larger stack than the ~1 MB default, e.g. in the consumer's .cargo/config.toml:

[target.wasm32-unknown-unknown]
rustflags = ["-C", "link-arg=-zstack-size=8388608"]   # 8 MiB, as a native main thread

Goldens

Every unit's cases (fixtures/<unit>/, upstream's TestFiles, seeded generators) run on solidcore and are checked against the unit's golden, crates/goldens/expected/<unit>.jsonl: the outputs recorded when it was blessed. CI fails on any changed, added, missing or broken case. Many cases read upstream's test files, so clone upstream/ first:

git clone https://github.com/NVIDIA-Omniverse/usd-brep upstream
git -C upstream checkout 3fd5b95   # v1.0.1; the pin is in scripts/upstream-pin.env
cargo run --profile goldens -p goldens -- --all --goldens --jobs 0   # every unit (CI)
cargo run --profile goldens -p goldens -- --unit <unit id> --goldens   # one unit
cargo run --profile goldens -p goldens -- --unit <unit id> --bless     # record a change on purpose

A golden proves a result unchanged, not correct. A change that moves one is blessed and justified in its pull request: the cases that changed, their numbers, and pictures for geometry (crates/goldens/README.md). upstream's C++ is a reading reference only: nothing here builds, links or runs it.

Contributing

Contributions go through pull requests, and AI agents are welcome. Useful work includes connecting ported units, resolving deferred cases, adding operation regressions and fixing bugs.

  1. Check the live unit results, open issues and open PRs. Choose an unclaimed unit or a specific completion task: a missing function, back-edge, exact import, coverage gap or bug. A passing golden does not prove every branch is exercised.
  2. Search PR titles and bodies for the unit, symbols and paths. Claim the specific work in a draft PR; initial ports use port: <unit id>. A claim covers its stated scope, leaving independent tasks in the same unit available. Coordinate overlapping functions or shared interfaces in the existing PR before editing them.
  3. Describe the intended behavior, affected paths, related PRs and validation, and list independent follow-ups others can take. Check the affected units against their goldens and justify every golden you bless. CI is the merge gate. See AGENTS.md §4 for the claim template, handoffs and inactivity rules.

To keep parallel PRs from conflicting: edit only your unit's plan/units/<unit id>.toml, and put each finding or upstream issue in its own new file under plan/findings/ or plan/upstream-issues/ (never append to a shared file). A branch started before the per-unit split migrates with git fetch origin && git merge origin/main; scripts/units-migrate-branch.sh && git commit --no-edit.

The full rules, style and step-by-step workflow are in AGENTS.md (point your agent at it).

Releasing

solidcore is published to crates.io from CI: bump version in crates/solidcore/Cargo.toml in a PR, merge it, then push a tag solidcore-v<version> (.github/workflows/release.yml, needs the CARGO_REGISTRY_TOKEN repository secret). Only solidcore is published; goldens is test-only. It stays at 0.0.x until it is usable end to end.

Sponsors

CI powered by Blacksmith

solidcore's continuous integration runs on Blacksmith, which sponsors its CI minutes.

Licence

Apache-2.0. See LICENSE, NOTICE and ATTRIBUTION.md. solidcore is an independent project, not affiliated with or endorsed by NVIDIA.

About

A Rust port of NVIDIA's SMLib B-rep kernel (CAD subset): safe, deterministic, wasm-compatible

Resources

Contributing

Stars

388 stars

Watchers

8 watching

Forks

Releases

Packages

Used by

Contributors

Languages