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 thekernelbranch.
📊 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.
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).
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/).
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 |
| 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) |
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 checkOptional: export RUSTC_WRAPPER=sccache to share compilation caches.
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 threadEvery 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 purposeA 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.
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.
- 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.
- 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. - 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).
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.
solidcore's continuous integration runs on Blacksmith, which sponsors its CI minutes.
Apache-2.0. See LICENSE, NOTICE and ATTRIBUTION.md. solidcore is an independent project, not affiliated with or endorsed by NVIDIA.
