Engineering · Robustness

Kernel robustness on real-world CAD files

Any kernel looks good on its own primitives. NativeCAD is measured on other people's geometry: SolidWorks parts, STEP and Parasolid files from real vendors, put through the same operator battery every sweep. Imported parts mesh, measure and round-trip through STEP at or near 100%. Since September, blends on real parts have gone from rare to routine, and every boolean now builds more often than it did.

Since September

The same real-world files, measured again.

Each rate is the share of parts on which the operator returned a valid, checked body. A part the kernel declines with a named reason counts against it, and so does a result that fails the independent volume check. The grey part of a bar is where the operator stood in September; green is ground gained since. Rates are rounded to whole points after a small deterministic jitter (about two points) so the make-up of our test corpus stays private.

IGES, since 2026-09-02

IGES has its own scoreboard. IGES files arrive as loose surfaces that the importer stitches into solids, so they are a different question from native solid formats and are measured separately. Unions and subtracts on IGES parts have gained since September. Intersect results are now checked against an independent volume estimate, and a body that fails that check is scored as a miss. That stricter check is why the intersect bar is shorter than in September.

Design loops, since 2026-09-29

The corpus above imports other people's files and runs whole-body operators on them. It never asks for what a designer reaches for next: move this wall, draft that face, round only those edges, shell the block. Design loops do. An agent builds a part, asks a verdict tool what is wrong with it, and applies the fix the verdict names, one call at a time. Every call it makes on a part it built itself is scored here, and every refusal is kept as a minimal repro with a fingerprint, so one defect is filed once instead of once per run. These are our own parts, so their rates carry no jitter. The set is small and one refusal moves a row by tens of points: read a row as "builds" or "refuses", not as a trend. The first sweep is the baseline.

Blends, broken down

The every convex edge at once rows are deliberately the hardest question in the family: one radius on every convex edge of a real machined part, and a single refused edge fails the body. Real parts are full of edges nobody would fillet, such as the tangent seams where a corner-round already meets its wall, so that figure says little about what the blend engine can do. The indented rows ask what a designer asks: round this edge, round this chain, round the inside corner, vary the radius along the way. Those are the rates this sprint is moving. On geometry the engine can reach, this is what it delivers:

Volume vs closed form

Fillets within 0.3% of the analytic volume

Constant-radius fillets on prismatic parts land within 0.28% of the closed-form volume across the whole radius sweep (gate 0.5%); chamfers agree to 0.0001%. Volume falls strictly as the radius grows, on every body.

benchmarks/bench_blend_volume.js · run 2026-09-02 · all gates passed
Variable width

A full d4-to-d20 dice set, every edge rounded

Tip-weighted rolling-ball strips at arbitrary dihedral angles, two radii along each chain, corner patches at 3-, 4- and 5-valent vertices. Six dice blend on every edge, write to one STEP file, and re-import watertight with identical volumes.

benchmarks/bench_b2_dice_set.js · 39 checks · 984 faces, 0 open edges
Continuity

G1, G2 and G3 sections

Circular, curvature-continuous and G3 blend sections on the same rails, including variable width; the modeler refuses combinations the geometry cannot honour with a named reason code instead of a silent approximation.

ops/blend.js · CADSF-433
Real-part edges

Fillets and chamfers on NURBS-bounded edges

The rolling-ball spine comes from offset-surface intersection, sampled sections are fitted to a B-spline strip with a declared tolerance, and the chamfer is a ruled strip. This is the path the single-edge and chain rows above take on vendor parts.

ops/blendNurbs.js · CADSF-971 · landed 2026-09-02
Watertight or refused

Every blend that builds passes the mesh audit

Fillet and chamfer results in the sweep are watertight at 100%. A blend that would open the shell is refused with a reason code and lands on the board as a ticket, never in your file.

operator_robustness.js · watertight column above
Engine

Sixteen blend modules

Prismatic, revolved, bore, cone-rim, channel and band blends, vertex blends, blend groups, overflow and consumption handling, feasibility checks and the NURBS path, all hand-written with no kernel underneath.

ops/blend*.js · ops/vertexBlend.js

Method

Each corpus file is imported through the product import path. Files that produce at least one solid go through the battery: tessellate, mass properties, boolean union / intersect / subtract against an overlapping box tool, fillet and chamfer on every convex edge plus the single-edge, chain, concave and variable-radius cases, shell, and a STEP write/read round-trip. Every operator runs on a fresh import, so one operator's document mutation never contaminates the next measurement. A per-file time limit turns a hang into a recorded timeout, and whatever finished before it is kept.

The boolean rows also cross-check the volume identity vol(A∪B)+vol(A∩B) = vol(A)+vol(B) whenever union and intersect both build; the share of checked parts passing it is reported above. Every boolean and blend result is also checked for validity and against a volume bound. A body that fails is counted as a wrong answer, never as a success. A silent wrong answer is the most serious fault a kernel can have, and each one becomes top-priority work the same day.

Why publish this

Robustness is only real when it is measured on files we did not author. The same sweep that renders this page files the tickets for the next round of kernel work, and the page is regenerated when that work lands, so what you see here is the kernel you would install today.

Tolerance reclassification, since 2026-09-05

CADSF-1159 gave every imported solid a per-entity tolerance profile (Topology.toleranceSummary()) instead of one global epsilon for the whole model. This re-sweeps the same pinned 150-file subset the CADSF-1089 retro used (corpus/robustness_subset.json) and asks the question that opened up: of the files the battery calls not_watertight, how many are actually closed once each seam gets its own declared or derived tolerance instead of being held to one model-wide epsilon — and how wide is the tolerance that closes them? A file lands in the new tolerant_ok class when Topology.validate() reports the shell closed (valid: true) but its tolerance.countAboveEps is greater than zero — at least one seam only meets because its own tolerance is wider than this model's eps. Everything else keeps its old class: watertight (closed with no seam needing more than eps) or not_watertight (still open or non-manifold even with full per-entity widening).

Recovered by the fallback ladder

When an operator refuses, the kernel retries it down an ordered ladder of fallback strategies (a reordered edge chain, a split chain, a reduced radius, a swapped boolean operand, a thickened shell) before giving up. Each bar splits the same battery run into the share that passes with no ladder at all, the share the default ladder recovers, and the share that still refuses. The default ladder never uses a rung that degrades the geometry.

passes without the ladderrecovered by the ladderstill refuses

Interoperability: do real-world files open?

Before any operator can run, the file has to open. Every file in our real-world test corpus is re-imported on each census, and every rate here is for files written by other CAD systems; these rates are from the census at commit 0590463d (2026-10-30). A file opens as an exact B-rep when the importer builds solid or sheet bodies from it; a file whose only readable geometry is its stored visualization tessellation opens as a visualization mesh: viewable, not editable, counted apart. "Opens" means opens by default: some Parasolid-based files (Parasolid, SolidWorks, Siemens NX) open only when the reader is told to tolerate damaged or non-standard structure. Those are published apart as opens with tolerant mode, never inside the opened figure.

94%
of real-world files open with default settings
Files that open
1%
more open only when the reader is told to tolerate damaged structure (tolerant mode)
Opens with tolerant mode
92%
open as an exact, editable B-rep
Exact B-rep
92%
of file bytes the readers account for
Bytes understood
72%
of graded opens have no geometry defect (61% fully clean)
Geometry quality
68%
of checked SolidWorks parts: kernel volume within 1.5% of the file's own visualization mesh (1% differ, 27% could not be compared; a further 1% whose saved visualization mesh is older than the model are set aside)
Volume agreement

By format

FormatOpenedExact B-repVisualization meshOpens with tolerant modeBytes understood
STEP (.step, .stp)99%99%1%0%98%
SolidWorks part (.sldprt)95%95%1%3%97%
SolidWorks assembly (.sldasm)93%93%0%4%99%
IGES (.igs, .iges)93%93%0%0%99%
Parasolid (.x_t, .x_b)90%90%0%10%100%
Siemens NX and Creo part (.prt)77%76%1%1%62%
Autodesk Inventor (.ipt, .iam)92%92%0%0%99%
CATIA V5 (.CATPart, .CATProduct)84%70%12%0%38%
Rhino (.3dm)99%89%11%0%99%
Creo assembly (.asm)64%64%0%0%40%
ACIS (.sat, .sab)99%99%0%0%–
All formats94%92%2%1%92%

JT: in the overall figures, but too few files in the corpus to publish a rate of their own.

Not counted above: files NativeCAD wrote itself (exports and test fixtures kept in our repository). 98% of them reopen (98% as exact B-reps).

Progress

Share of files that open at each census, earliest first. The whole line carries one jitter (the same as the headline), so the change along it is real to within rounding. A hollow point is a census after the corpus grew: a dip there is new, harder files arriving, not a regression.

85%90%95%100%2026-10-21: 96%2026-10-22: 90%, corpus grew2026-10-22: 95%, corpus grew2026-10-22: 95%2026-10-22: 95%2026-10-23: 98%2026-10-24: 98%2026-10-24: 98%2026-10-30: 94%, corpus grew2026-10-212026-10-30

How these are measured

More demos

All demos →

Build your own part with NativeCAD

Free for education and makers with a registered key · $200 per seat per year · Kernel SDK for products.