Skip to content

Latest commit

 

History

1,873 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Remus

Exact B-Rep solid modeling kernel for Rust and WebAssembly.

CI Commit activity License: Apache-2.0 Rust 1.88+ unsafe denied

Kernel contract · Architecture · Performance · Getting started · Known limitations · Contributing

One exact-geometry engine, from Rust and from JavaScript. Cut a solid, measure it, export it.

use remus_operations::primitives::{make_box, make_cylinder};
use remus_operations::boolean::{boolean, BooleanOp};
use remus_operations::measure::solid_volume;
use remus_io::step::write_step;
use remus_topology::Topology;

let mut topo = Topology::new();

// Primitives are anchored at the origin, so this cylinder rounds off the
// block's corner. Use `transform_solid` to place it somewhere else.
let block = make_box(&mut topo, 30.0, 20.0, 10.0)?;
let cutter = make_cylinder(&mut topo, 5.0, 15.0)?;
let notched = boolean(&mut topo, BooleanOp::Cut, block, cutter)?;

// Measure and export
let vol = solid_volume(&topo, notched, 0.1)?;
let step = write_step(&topo, &[notched])?;
import { BrepKernel } from 'remus-wasm';

const kernel = new BrepKernel();

// Primitives are anchored at the origin, so this cylinder rounds off the
// block's corner. Use `transformSolid` to place it somewhere else.
const block = kernel.makeBox(30, 20, 10);
const cutter = kernel.makeCylinder(5, 15);
const notched = kernel.cut(block, cutter);

// Measure and export
const vol = kernel.volume(notched, 0.1);
const step = kernel.exportStep(notched); // Uint8Array

Why a CAD kernel?

Remus is a B-Rep solid modeling kernel written from scratch in Rust. It targets WebAssembly, so the same kernel runs in the browser and on the desktop. unsafe is denied by lint, as are unwrap and panic. Every public operation returns a Result.

Parametric CAD in the browser has long meant choosing between proprietary kernels and large C++ codebases compiled to WASM. Remus exists to be the third option: a from-scratch Rust kernel with exact geometry and a permanent Apache-2.0 license. It is maintained by Esau Engineering as the Apache-2.0 continuation of an upstream kernel that relicensed at v3 — see Provenance for how that boundary is enforced.

The geometry is exact. Booleans run on analytic and NURBS surfaces and keep those surfaces through the operation, so a cylinder stays a cylinder instead of becoming a bag of triangles. That keeps face counts low and round-trips lossless.

Remus's canonical modeling convention is millimetres for length and radians for angle. The kernel does not attach units to scalar values or silently convert them; applications using another length unit must scale all coordinates, dimensions, deflections, and linear tolerances consistently at their boundary. See the tolerance and robustness guide.

Kernel contract

Remus is being driven from a broad-but-maturing kernel toward a professional-grade one, and the rules for that are written down rather than implied. This is the part of the repository worth reading before you trust a feature label.

  • Kernel maturity target — what "professional-grade" means here, the program invariants, and the program-wide definition of done.
  • Capability matrix — the qualification structure. Every cell of every operation family is Qualified, Partial, Unqualified, Unsupported-typed, or Unsupported-untyped. It is the promotion authority for the feature labels in Status: no feature is promoted on a single successful fixture.
  • Operation contract — the result, quality, fallback, and postcondition contract every operation converges on.
  • Failure taxonomy — stable failure categories, and how they map onto the error-code registry.
  • Testing strategy — what kind of evidence qualifies a capability cell, and what CI gates.
  • Stability matrix — the audited disposition of each label shipping today, including the rows whose advertised domain is not yet fully evidenced.
  • Stabilization plan — the working plan for promoting every Beta/Experimental row below to Stable, sequenced under the capability-matrix promotion rules.

Four mechanisms carry that contract in code:

Mechanism Where What it gives you
Operation context remus_math::context::OperationContext (RFC 0001) Tolerances and hard work budgets as an explicit, caller-visible argument instead of module-local constants. Defaults reproduce prior behavior exactly; budgets terminate bounded work rather than looping.
Structured diagnostics remus_math::diagnostic Every failure carries a stable category plus a stable code, independent of the Rust error type. Codes are explicit literals, never derived from type or variant names, and the registry is additive only.
Coedges and per-use p-curves remus_topology (RFC 0002) First-class edge uses, so seams, poles, and periodic surfaces are represented correctly. Seam p-curve access is fail-closed rather than silently picking one side.
Reproduction bundles remus_wasm::repro Versioned JSON that replays an operation sequence and its expected results through the batch dispatch path — identically on native and WASM. Bundles are the canonical carrier for new regressions; expected failures are first-class.

Structural work lands through versioned RFCs in docs/design and incremental vertical slices, not repository-wide rewrites. Tests are not weakened, tolerances are not widened, and a mesh fallback is not introduced to make a failing case pass.

Status

Remus is in active development. Core modeling is solid. Each feature below is marked stable, beta, planned, or experimental; Known Limitations covers the gaps, and the stability matrix records what evidence each label currently rests on.

Category Feature Status
Primitives Box, cylinder, cone, sphere, torus, ellipsoid Stable
Primitives Convex hull, Minkowski sum (convex inputs) Stable
Booleans Union, cut, intersect on plane, cylinder, cone, sphere, NURBS Stable
Booleans Batch fuse-all (disjoint-aware union) Stable
Booleans Torus booleans (box ± torus, coaxial torus) Beta
Modifiers Validated planar fillet/chamfer and axisymmetric closed-rim fillet; other curved blend geometry (experimental assembly) Stable / Experimental
Modifiers Resize or remove an analytic blend band (resize_blend) Experimental
Modifiers Shell (hollow solid) Stable
Modifiers Offset face, offset solid, thicken, mirror, pattern Stable
Modifiers Draft (planar faces) Stable
Sweeps Extrude (planar + NURBS profiles) Stable
Sweeps Revolve, sweep, loft, pipe (planar profiles) Stable
Sweeps Helical sweep Stable
Sweeps Non-planar profiles for loft, sweep, pipe, revolve Stable
Construction Coons-patch face fill, sew, untrim Stable
Sectioning Cross-section faces, split by plane Stable
Measurement Bounding box, area, volume, center of mass, inertia tensor + principal axes Stable
Measurement Point-to-solid, solid-to-solid distance, point classification Stable
Drawing Hidden-line edge projection Stable
Geometry NURBS evaluation, derivatives, knot ops, fitting, projection Stable
Geometry Analytic intersections (plane × cylinder, cone, sphere exact; torus sampled) Stable
Geometry Surface-surface intersection (analytic + marching) Stable
Geometry Curve-curve intersection (Bezier clipping) Stable
Tessellation Adaptive deflection, CDT, analytic-surface optimization Stable
Repair Shape healing (wire, face, shell fixes), sewing, validation Stable
I/O STEP import/export (analytic-preserving round-trip) Stable
I/O STL, 3MF, OBJ, PLY, glTF (.glb) import/export Stable
I/O IGES import/export Experimental
Sketching 2D constraint solver (DogLeg) Stable
Feature Recognition Holes, pockets, chamfers, fillets Stable
Assemblies Hierarchy, transforms, bill of materials Stable
Evolution Face provenance (booleans, blends, patterns, draft, defeature, split, shell) Stable
Defeaturing Remove planar faces Stable
Rendering Offscreen wgpu render to image plus face-id buffer (remus-render) Experimental

Known Limitations

A few areas are still maturing. Worth knowing before you build on them:

  • Boolean fallback. Most booleans run on an exact path that preserves analytic and NURBS surfaces. Hard configurations may use a bounded mesh-based fallback, which tessellates curved faces. If its input/work budgets are exceeded or the welded result is open, non-manifold, or invalid, the operation returns an error instead of a partial solid. Exact tangency and sliver crossings are the two contact configurations that still fall over to that path rather than being answered analytically.
  • Walking fillet/chamfer and offset. The v2 modifier APIs validate completed topology and reject partial results. Unsupported/no-op trimming and offsetting a solid that already contains cavity shells return explicit errors; they do not silently drop faces or cavities. Radii the rolling ball cannot fit are refused as typed errors naming the edge and the limit, not delivered as a partial result.
  • Torus booleans. Box-with-torus, coaxial-torus, plane-through-centre, and coaxial-cylinder cases give correct volumes, and coaxial torus×cylinder / axis-centred torus×sphere sections are exact circles. Carving a closed torus face into tube bands is not implemented yet, so those configurations resolve through the bounded mesh fallback (torus×sphere fuse currently refuses on its work budget); general torus-to-torus intersections have known gaps.
  • Non-planar profiles. Loft, sweep, and pipe close non-planar section boundaries with bilinear (4-sided) or Coons (5-or-more-sided) caps whose boundary iso-curves are exactly the ring chords; holes on a non-planar section remain a typed refusal. Revolve accepts non-planar profile surfaces; a full revolution takes any boundary, and a partial revolution closes non-planar polygonal boundaries with the same caps (curved-edge non-planar boundaries and holes stay typed refusals). Only the miter-corner sweep variant still requires planar profiles (its bisector-plane joint faces would otherwise be non-planar).
  • Evolution coverage. Face provenance is exact and construction-derived for booleans, the walking and planar blend builders, patterns, draft, defeature, plane split, and shell. Offset and direct edits still journal as explicit barriers, and edge/vertex provenance beyond the boolean path is roadmap work.
  • IGES is experimental. Export writes planar and NURBS surfaces but skips analytic surfaces and approximates circular and elliptical edges as polylines. Import reconstructs planar placeholder faces only. Use STEP for B-Rep exchange.
  • Declared domains. Feature recognition claims only its declared feature set (holes, rectangular pockets, chamfers, curved fillet bands) — outside it, absence of a claim is the contract. Defeaturing removes features whose wound lies on planar kept faces (the removed feature itself may be curved); draft targets planar faces. Each refuses outside its domain by name.

The versioned WASM fillet/chamfer provenance payload and its strict decoder are documented in WASM face evolution.

Scope

Remus deliberately does not:

  • Bundle a viewport into the kernel. The core emits exact geometry and tessellated meshes; camera, lighting, and shading belong to the caller (Three.js and the like). The optional remus-render crate provides offscreen wgpu rendering with a face-id buffer, for tests and headless verification, and is not required by any core operation.
  • Plan toolpaths or slice. Export STEP, STL, or 3MF and pass the output to a CAM tool or slicer.
  • Model with meshes. The kernel operates on exact B-Rep geometry. Subdivision surfaces, polygon meshes, and voxels are out of scope.
  • Provide a GUI. Remus is a library. Building a UI around it is the application's job.
  • Simulate physics. Measurement (volume, area, center of mass) is included. Stress analysis, collision detection, and dynamics are not.

Architecture

Layered Cargo workspace. Each crate depends only on the same or lower layers, and CI enforces the boundaries with scripts/check-boundaries.sh.

Layer Crate What it does
L0 remus-math Points, vectors, matrices, NURBS curves and surfaces, geometric predicates, CDT, convex hull, operation context, diagnostics
L1 remus-geometry Curve sampling (uniform, deflection, arc-length, curvature), extrema, analytic-to-NURBS conversion
L1 remus-topology Arena-allocated B-Rep: vertex, edge, coedge, loop, wire, face, shell, solid, with an edge-to-face adjacency index
L2 remus-algo General Fuse boolean engine: pave filler, face classification, solid assembly
L2 remus-blend Walking-based fillet and chamfer with constant, variable, and custom radius laws
L2 remus-heal Shape healing: analysis, fixing, upgrading, sewing, tolerance management, configurable pipeline
L2 remus-check Point classification, validation, properties (volume, area, center of mass), distance
L2 remus-offset Solid offset and thickening via global face-face intersection
L2 remus-sketch 2D parametric constraint solver (GCS) using a DogLeg trust-region method
L3 remus-operations Booleans, fillet, chamfer, extrude, revolve, sweep, loft, shell, offset, measure, tessellation
L3 remus-io Import and export: STEP, IGES, STL, 3MF, OBJ, PLY, glTF
L4 remus-wasm JavaScript API via wasm-bindgen, with batch execution, checkpoint/restore, and reproduction bundles
L4 remus-render Offscreen wgpu rendering to a color image plus a face-id buffer. Optional, nothing depends on it

The layer DAG is a program invariant: preserving it is a constraint on every change, and a violation fails both the pre-push hook and CI.

Performance

Median times from the brepjs benchmark suite (5 iterations, Node.js, Linux x86_64). WASM is single-threaded. Native benchmarks use criterion.

Operation Remus (WASM) OCCT (WASM) Speedup Remus (native)
fuse(box, box) (×10) 0.5 ms 43.7 ms 87x 122 µs
cut(box, cylinder) (×10) 28.3 ms 64.3 ms 2.3x 9.3 ms
box + chamfer 0.2 ms 5.4 ms 27x 46 µs
box + fillet 0.3 ms 6.2 ms 21x 127 µs
multi-boolean (16 holes) 4.7 ms 30.1 ms 6.4x 2.8 ms
mesh sphere (tol=0.01) 7.1 ms 51.9 ms 7.3x 6.0 ms
exportSTEP (×10) 0.9 ms 14.3 ms 16x n/a

Every quoted row is output-verified across both kernels before timing is compared: fuse, chamfer, and sphere volumes match exactly; cut, fillet, and multi-boolean volumes agree within 0.004%. The sphere mesh densities are comparable at equal tolerance (9,800 triangles vs 10,176). The intersect(box, sphere) row is excluded: the kernel currently keeps the wrong sphere region for that configuration (an open, pinned defect), so its ~200x timing would not be a like-for-like comparison.

Booleans preserve analytic surfaces, so face counts stay low across chained operations. A nine-step compound boolean settles at 72 faces while a mesh-based approach would reach roughly 7,000. The same holds for blends: a straight edge filleted between two planar faces keeps an exact cylindrical wall rather than a NURBS approximation of one.

The OCCT comparison uses occt-wasm, an OpenCASCADE build compiled to WebAssembly. Both kernels run single-threaded in Node.js. Boolean and exportSTEP rows are timed as batches of ten operations. WASM figures are medians of kernel-comparison.bench.test.ts (5 iterations) against a local cargo xtask wasm-build package, hash-verified at the require path. Native figures: cargo bench -p remus-operations --bench cad_operations, except the mesh-sphere row, which is measured at the same parameters as the WASM row (tessellate_solid_with_tolerance, deflection 0.01, angular 0.1 rad) via crates/operations/examples/perf_probe.rs — the criterion suite's sphere case meshes per-face and is not comparable. Measured 2026-08-06, before the Apache-only line was established, and not re-measured since; treat the figures as indicative and re-run scripts/bench-compare.sh before quoting them.

Data Exchange

Format Type Import Export
STEP B-Rep
STL Mesh
3MF Mesh
OBJ Mesh
PLY Mesh
glTF (.glb) Mesh
IGES B-Rep preview lossy

STEP preserves exact geometry on round-trip. Analytic surfaces (plane, cylinder, cone, sphere, torus) are written as native STEP surface entities rather than tessellated, and they read back to the same surface types. NURBS surfaces are preserved too, as are line, circle, ellipse, and NURBS edges.

Mesh formats export tessellated triangles. glTF is binary .glb, with no materials or scene graph. IGES is experimental, as described in Known Limitations.

All Rust importer entry points apply production defaults through ImportLimits: 128 MiB encoded input, 256 MiB for the uncompressed 3MF model XML entry, and 2,000,000 format-specific model entities. Use each format's *_with_limits reader to choose stricter or application-specific budgets; the WASM importers accept optional maxInputBytes / maxEntities arguments for the same purpose. Limit violations return IoError::LimitExceeded before avoidable large allocations. The WASM batch API separately limits JSON to 16 MiB and 10,000 operations.

Getting Started

Packages

Remus publishes nothing yet. No crates.io releases, no npm packages, no GitHub releases. Release ownership — named maintainers, package identity, vulnerability intake, signing and provenance, rollback and yank authority — has to be established first; the gate is documented in fork maintenance and release policy.

Two consequences worth stating plainly:

  • A remus-wasm package on npm does not come from this repository. It belongs to the historical upstream line, which is no longer permissively licensed. Installing it does not get you this kernel.
  • The checked-in crates/wasm/pkg directory is a frozen compatibility snapshot for an existing consumer that installs it by git path. It is not a release channel and it is not the way to adopt Remus.

Until packages exist, build from source.

As a Rust dependency

[dependencies]
remus-math = { git = "https://github.com/esaueng/remus" }
remus-topology = { git = "https://github.com/esaueng/remus" }
remus-operations = { git = "https://github.com/esaueng/remus" }
remus-io = { git = "https://github.com/esaueng/remus" }        # optional

Pin a revision (rev = "...") for anything you intend to reproduce: nothing is versioned or published yet, so main moves.

Building from source

MSRV is Rust 1.88, and CI holds that floor. Day-to-day development uses the toolchain pinned in rust-toolchain.toml, which rustup picks up automatically along with the wasm32-unknown-unknown target.

cargo build --workspace
cargo test --workspace
cargo clippy --all-targets -- -D warnings
cargo fmt --all

# WASM package: dual-target build, merge, and validation
cargo xtask wasm-build

# Plain WASM builds (with and without I/O)
cargo build -p remus-wasm --target wasm32-unknown-unknown --release
cargo build -p remus-wasm --target wasm32-unknown-unknown --release --no-default-features

# API docs
cargo doc --workspace --no-deps --open

Repository invariants have their own checks, all of which CI runs:

./scripts/check-boundaries.sh              # layer dependency DAG
./scripts/check-doc-paths.sh               # documented file paths still resolve
./scripts/check-apache-lineage.sh          # no prohibited upstream lineage
python3 scripts/check-apache-replay-provenance.py   # provenance ledger integrity

Documentation

Where What
book/ Task-oriented guide: getting started, concepts, tolerances, data exchange, WASM, rendering, troubleshooting
docs/kernel-maturity/ The maturity contract: target, capability matrix, operation contract, failure taxonomy, testing strategy
docs/design/ RFCs and design research, including operation context (0001) and coedge architecture (0002)
docs/production-readiness/ Audit, stability matrix, coverage, release checklist, fork maintenance, Apache replay provenance
AGENTS.md Working guide: module map, ripple-effect checklists, common pitfalls
CHANGELOG.md Full history, including the pre-fork series

Maintainers should use the production-readiness audit, stability matrix, and release checklist before cutting an artifact. The checklist is validation guidance and does not grant authority to publish.

Roadmap

Priorities, not dates. Planning is by dependency and acceptance gate; see the kernel maturity target for the full program.

P0 — foundations and correctness. Capability and failure contracts across every operation family; the reproduction and regression corpus; first-class coedges and explicit curve/p-curve trimming; unified tolerance and operation context; intersection robustness; General Fuse and boolean robustness (shrinking the set of inputs that fall back to meshing, starting with torus and mixed-surface cases); transactional topology mutation; kernel-wide diagnostics.

P1 — professional modeling behavior. Complete vertex, edge, and face evolution with persistent topological naming; general blends, offsets, shelling, sweeps, and lofts — including the miter-corner sweep, boundaries with more than four edges, and partial revolutions with non-planar boundaries; direct face editing; attribute propagation; broad STEP round-trip behavior with topology attributes; memory compaction and session lifecycle.

P2 — extended scope. General and non-manifold bodies; mixed B-rep and facet modeling; cellular topology; lattice representation; concurrent operations and large-model scaling — including parallel tessellation on the WASM target, which native builds already do per face.

Contributing

See CONTRIBUTING.md. Contributions are inbound under Apache-2.0 and require a Developer Certificate of Origin sign-off. Commits are conventional commits, enforced by commitlint; the pre-commit hook runs cargo fmt and clippy, and CI gates the full test suite, the layer-boundary check, and the license-lineage check on every push.

New regressions should land as reproduction bundles where the failure is expressible through the batch API — every discovered defect is meant to become a permanent, replayable regression.

Security reports: see SECURITY.md.

Provenance

Remus continues a codebase whose upstream relicensed to AGPL at v3. This repository is the permanent Apache-2.0 line of that work, maintained by Esau Engineering. The last permissive upstream release is v2.129.15; nothing from v3 or later is merged, and behavior from those releases enters only under an explicit Apache-2.0 grant or as an independent implementation proven by a regression test.

That boundary is enforced in CI and every replayed contribution is recorded in an auditable ledger — see Apache contribution provenance.

The project's use of AI tooling is disclosed in AI-DISCLOSURE.md.

License

Remus is licensed under the Apache License, Version 2.0, permanently — see Provenance for how the AGPL boundary with the historical upstream is enforced. Attribution is in NOTICE, and contributions come in under the same license (see CONTRIBUTING.md).

About

Apache-2.0 boundary representation modeling kernel

Resources

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages