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.
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:
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.
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.
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.
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.
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.
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.
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.
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.
By format
| Format | Opened | Exact B-rep | Visualization mesh | Opens with tolerant mode | Bytes 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 formats | 94% | 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.
- 2026-10-21: 96% open (
d7f48dac, older counting, counts tolerant-mode opens) - 2026-10-22: 90% open (
d7f48dac, corpus grew, older counting, counts tolerant-mode opens) - 2026-10-22: 95% open (
18b08f73, corpus grew, older counting, counts tolerant-mode opens) - 2026-10-22: 95% open (
d3fc56b2, counts tolerant-mode opens) - 2026-10-22: 95% open (
c218af64, counts tolerant-mode opens) - 2026-10-23: 98% open (
1a5d1d33, counts tolerant-mode opens) - 2026-10-24: 98% open (
a77a7585, counts tolerant-mode opens) - 2026-10-24: 98% open (
27bbf90c, counts tolerant-mode opens) - 2026-10-30: 94% open (
0590463d, corpus grew)
How these are measured
- Every rate is rounded to whole points after a small deterministic jitter (about two points, seeded per metric and census date) so the make-up of our test corpus stays private. A rate that is not truly 0% or 100% is never shown as either. Opened and exact-B-rep rates of one row share their jitter, so the two always read in the right order. The exact counts live on our internal tracker.
- Opened means opened by default. A few Parasolid-based formats (Parasolid .x_t and .x_b, SolidWorks parts and assemblies, Siemens NX parts) have a second, tolerant read that accepts damaged or non-standard structure. The importer refuses such a file unless tolerant mode is requested, so a file that opens only that way is not in "Opened" or in the exact and visualization-mesh columns; it is in "Opens with tolerant mode" (default plus tolerant is everything that opens at all). Every other reader has no such fallback, so that column is 0%. Where the reader mode has not yet been measured on nearly all of the files of a format, the row shows "not yet measured" and its Opened figure is the earlier all-modes rate.
- Files the reader correctly declines because they hold no geometry to open are left out of every rate; points marked "older counting" predate that rule and counted them as failures.
- A format with only a small number of files in the corpus shows a coarse band (most, some, few, none yet) instead of a rate; formats with fewer still are only in the overall figures.
- Bytes understood is the share of file bytes a reader accounted for (geometry, topology and structure it used, plus records it recognised and skipped), weighted by file size: a file can open and still carry data we do not read.
- Geometry quality is graded on a sample of opened files from each format (watertight mesh, valid B-rep, sane volume). "No defect" includes cosmetic findings; "fully clean" has none.
- The corpus is harvested from public repositories, so it leans toward hobby and open-source parts more than production data. A file that opens here has not necessarily been through the operator battery above.
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.