README: coverage complete, and the speedup the plan did not expect
138 symbols, 53 modules, published as 7.9.3.1.dev5. The app's full suite passes against it and the whole project store sweeps identical. Corrects the "call overhead is not a bottleneck" claim: it is true of any single call and false of the aggregate. The app's benchmark suite runs 194 s -> 73 s with nothing but the wheel swapped, and the win grows with face count — 3.3x at 4 features, 7.0x at 32. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DfriM8XUkn7uYf5Dwe2xo6
This commit is contained in:
32
README.md
32
README.md
@@ -2,18 +2,19 @@
|
|||||||
|
|
||||||
Hand-written [nanobind](https://github.com/wjakob/nanobind) bindings for the
|
Hand-written [nanobind](https://github.com/wjakob/nanobind) bindings for the
|
||||||
OpenCASCADE (OCCT) geometry kernel, covering exactly the surface the N3XD CAD
|
OpenCASCADE (OCCT) geometry kernel, covering exactly the surface the N3XD CAD
|
||||||
backend uses — 139 symbols across 48 `OCP.*` modules, not all of OCCT.
|
backend uses — 138 symbols across 47 `OCP.*` modules, not all of OCCT.
|
||||||
|
|
||||||
The package installs as a top-level `OCP`, so it is a drop-in replacement for
|
The package installs as a top-level `OCP`, so it is a drop-in replacement for
|
||||||
`cadquery-ocp-novtk` and the app's 442 import sites stay untouched.
|
`cadquery-ocp-novtk` and the app's 442 import sites stay untouched.
|
||||||
|
|
||||||
Status: **Inc 0 (spike) shipped** — build system, OCCT builder image, handle
|
Status: **coverage complete** — all 138 symbols the app imports, across 53
|
||||||
model, and the first module surface (`gp`, `TopAbs`, `TopoDS`, `TopExp`,
|
bound modules, published as `7.9.3.1.dev5`. The app's full backend suite passes
|
||||||
`TopLoc`, `TopTools`, `BRep`, `BinTools`, `Poly`, `Standard`), published as
|
against it (1797 passed / 1 skipped, the same as the stock wheel), a sweep of
|
||||||
`7.9.3.1.dev1`. BREP serialisation is byte-identical to the stock wheel, which
|
the whole project store reproduces every part's geometry exactly (4486 parts;
|
||||||
is the gate that mattered: the pools and the content-addressed derive payloads
|
no change in statuses, volume, area, bbox, entity counts, triangles or anchor
|
||||||
both depend on it. Coverage is 34 of the 139 symbols the app imports; the rest
|
digests), and BREP serialisation stays byte-identical, which the pools and the
|
||||||
lands in increments 1-4 (roadmap 10C).
|
content-addressed derive payloads depend on. The app is not swapped yet — that
|
||||||
|
is the cutover, roadmap 10C.
|
||||||
|
|
||||||
Start with [docs/design.md](docs/design.md) for the decisions,
|
Start with [docs/design.md](docs/design.md) for the decisions,
|
||||||
[docs/building.md](docs/building.md) to build one, and
|
[docs/building.md](docs/building.md) to build one, and
|
||||||
@@ -25,9 +26,8 @@ phase plan lives in the app repo at `docs-private/reference/roadmap.md`
|
|||||||
|
|
||||||
`cadquery-ocp` lags OCCT (it wraps 7.9.3; OCCT 8.0 shipped 2026-05), builds
|
`cadquery-ocp` lags OCCT (it wraps 7.9.3; OCCT 8.0 shipped 2026-05), builds
|
||||||
Windows and macOS wheels we never use, and until recently forced a 638 MB VTK
|
Windows and macOS wheels we never use, and until recently forced a 638 MB VTK
|
||||||
dependency into the image. Binding *call* overhead is not a bottleneck — the
|
dependency into the image. So this exists for version velocity, footprint, and
|
||||||
CAD hotspots live inside the C++ kernel — so this exists for version velocity,
|
two defects that a binding we control prevents by construction:
|
||||||
footprint, and two defects that a binding we control prevents by construction:
|
|
||||||
|
|
||||||
- OCCT sub-shapes are returned **by value**, so a wrapper can never alias a
|
- OCCT sub-shapes are returned **by value**, so a wrapper can never alias a
|
||||||
`TShape` whose owner has died (this segfaulted a process-global face memo).
|
`TShape` whose owner has died (this segfaulted a process-global face memo).
|
||||||
@@ -37,6 +37,16 @@ footprint, and two defects that a binding we control prevents by construction:
|
|||||||
It also releases the GIL around kernel calls and ships type stubs, neither of
|
It also releases the GIL around kernel calls and ships type stubs, neither of
|
||||||
which upstream does.
|
which upstream does.
|
||||||
|
|
||||||
|
**It is also considerably faster, which was not the point and turned out to
|
||||||
|
matter most.** With the app otherwise unchanged, its benchmark suite runs
|
||||||
|
194 s → 73 s, and rebuild time improves *superlinearly* with model complexity:
|
||||||
|
3.3x for a 4-feature part, 7.0x for a 32-feature one (13.4 s → 1.9 s). The
|
||||||
|
premise going in was that call overhead is irrelevant because the hotspots live
|
||||||
|
inside the kernel — true of any single call, false of the aggregate, because
|
||||||
|
this backend reaches OCCT once per face, per node and per edge.
|
||||||
|
`tools/bench_ext.py` has the numbers and the two places they contradicted the
|
||||||
|
plan.
|
||||||
|
|
||||||
## Build
|
## Build
|
||||||
|
|
||||||
OCCT is compiled once into a builder image and reused; it is never built on the
|
OCCT is compiled once into a builder image and reused; it is never built on the
|
||||||
|
|||||||
Reference in New Issue
Block a user