Installation -> Quick start, and the build commands move into it so the file ends on Layout then More like every other repo. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WsxkJEmqEECM1PygXdN1zU
n3xd-ocp
Hand-written nanobind wrapper for the
OpenCASCADE (OCCT) geometry kernel. It installs as a top-level OCP and is a
drop-in replacement for cadquery-ocp: same
symbols, same call shapes. What it buys over upstream is version velocity (the
kernel is ours to bump), a much smaller footprint, correctness around object
ownership, and room to add APIs upstream does not offer, such as releasing the
GIL and extracting whole shapes in one call.
Status
The binding covers the subset of OCCT that n3xd actually uses, not the whole
kernel; run tools/inventory.py for the current count. Adding a class is a
routine, documented change, see
docs/adding-symbols.md.
Quick start
The packages sit on our Gitea instance, so install by pointing at its index:
uv pip install --index-url https://git.stroblme.de/api/packages/N3XD/pypi/simple/ \
--prerelease=allow n3xd-ocp
Versions are <occt-version>.N, enforced at configure time against the OCCT
actually found.
Wheels are built on a dev box and published to that registry. To build one yourself, everything runs in the OCCT builder image, so Docker is the only prerequisite:
make image # compiles OCCT 8.0.1 into the builder image
make dev # incremental compile + tests
make wheel # compile, stubs, auditwheel, self-containment smoke test
make publish # publish to Gitea using .secret credentials
Usage
OCP mirrors cadquery-ocp symbol-for-symbol, so code written against it runs
unchanged:
from OCP.BRepPrimAPI import BRepPrimAPI_MakeBox
from OCP.BRepAlgoAPI import BRepAlgoAPI_Cut
from OCP.TopTools import TopTools_ListOfShape
box = BRepPrimAPI_MakeBox(10.0, 20.0, 30.0).Shape()
hole = BRepPrimAPI_MakeBox(3.0, 3.0, 30.0).Shape()
args, tools = TopTools_ListOfShape(), TopTools_ListOfShape()
args.Append(box)
tools.Append(hole)
cut = BRepAlgoAPI_Cut()
cut.SetArguments(args)
cut.SetTools(tools)
cut.Build()
result = cut.Shape()
One deliberate gap from upstream: constructors that run the algorithm
immediately (the two-argument BRepAlgoAPI_Cut(a, b) form) are not bound, only
the deferred SetArguments/SetTools/Build() sequence above. See
docs/design.md for why.
n3xd_ocp adds a handful of batch operations OCP does not have. They run on the
same OCCT build and take and return plain OCP shapes, and they exist because
doing the same work as a per-face Python loop is measurably slower (face
extraction came out 4.6-5.5x faster on ordinary geometry when the app adopted
it):
import n3xd_ocp
areas, centroids = n3xd_ocp.measure.face_surface_props(result) # one call for every face
meshes = n3xd_ocp.tess.extract_meshes(result) # triangulated faces, ready to render
data = n3xd_ocp.bintools.write_bytes(result) # BREP bytes, no temp file needed
points, normals, uv_bounds = n3xd_ocp.sample.face_grid(face, 33) # a 33x33 UV grid on one face
n3xd_ocp.helix reaches OCCT 8.0's TKHelix, which upstream has no binding for.
For N segments it wants N pitches, N turn counts and N+1 diameters, one per
segment boundary, so consecutive values that differ taper across that segment:
from OCP.gp import gp_Ax3, gp_Dir, gp_Pnt
axis = gp_Ax3(gp_Pnt(0, 0, 0), gp_Dir(0, 0, 1), gp_Dir(1, 0, 0))
wire, tolerance_reached = n3xd_ocp.helix.pure_helix(axis, 8.0, [1.25], [12.0])
builder = n3xd_ocp.helix.BuilderHelix() # tapered, e.g. an NPT thread
builder.set_parameters(axis, [10.0, 8.0], [2.0], [4.0])
builder.set_approx_parameters(1.0e-4)
builder.perform()
Layout
| Path | What it is |
|---|---|
src/modules/ |
The bound OCCT classes, one file per OCCT module |
src/ext/ |
The n3xd_ocp extras: batch measure, tessellation, sampling, helix |
src/common/ |
Handle and transient casters, the machinery every module relies on |
python/OCP/, python/n3xd_ocp/ |
The Python packages and their type stubs |
occt/ |
The Dockerfile that compiles OCCT 8.0.1 into the builder image |
tools/ |
Inventory, signature diffing against upstream, and benchmarks |
More
- docs/design.md — the decisions and the handle model
- docs/building.md — the builder image and the wheel
- docs/adding-symbols.md — extending the surface
Licensed LGPL-2.1-only, following OCCT.