135 lines
7.6 KiB
Markdown
135 lines
7.6 KiB
Markdown
# Native OCCT history provider
|
|
|
|
This provider is compiled from the cached OCCT checkout selected by
|
|
`OCCT_SOURCE_DIR` and exposes native Boolean and PartDesign history APIs through
|
|
Emscripten Embind. The provider keeps `TopoDS_Shape` handles and history queries in one
|
|
WASM instance. A handle from `@bitbybit-dev/occt` must never be passed directly
|
|
to this module because WebAssembly linear memories are independent.
|
|
|
|
Build and verify it with the project wrapper:
|
|
|
|
```bash
|
|
./npmw run build:occt-history
|
|
./npmw run test:occt-history
|
|
```
|
|
|
|
The build also publishes the JS/WASM pair to
|
|
`public/native/occt-history/`, which is the default URL used by
|
|
`NativeOcctHistoryWorkerProvider`. The generated artifacts remain ignored; a
|
|
clean checkout must run the build after restoring the pinned OCCT source and
|
|
Emscripten toolchain.
|
|
|
|
## FreeCAD private naming build boundary
|
|
|
|
The default build is intentionally OCCT-only. It does not export
|
|
`freecadNamingAbiVersion`, `freecadNamingCapabilitiesJson`, or
|
|
`freecadNamingEvidenceJson`, and it must not be described as exact FreeCAD
|
|
naming support.
|
|
|
|
A separate fail-closed build lane is available for an actual FreeCAD WASM SDK:
|
|
|
|
```bash
|
|
FREECAD_WASM_SDK_DIR=/absolute/path/to/sdk ./npmw run check:freecad-naming-sdk
|
|
FREECAD_WASM_SDK_DIR=/absolute/path/to/sdk ./npmw run build:freecad-naming-worker
|
|
./npmw run check:occt-history-artifact
|
|
```
|
|
|
|
The SDK layout is defined by `freecad-wasm-sdk-manifest.example.json`. The
|
|
checker requires the locked FreeCAD 1.1.1 commit, Emscripten 3.1.69, wasm Qt
|
|
and Python targets, private App headers, hashed static FreeCAD/Part/Qt/Python
|
|
libraries, and a hashed bridge source exporting all three callbacks. If any
|
|
input is absent, `build:freecad-naming-worker` exits before rebuilding or
|
|
publishing the OCCT-only artifact. A successful artifact probe still only
|
|
establishes ABI linkage; exact promotion additionally requires valid
|
|
MappedNameRef, StringHasher, ElementMap2, stage history, and round-trip evidence.
|
|
|
|
The repository also carries a prerequisite-only source probe. It builds QtBase
|
|
6.8.2 `Qt6Core` for wasm, then compiles the locked FreeCAD `IndexedName.cpp` and
|
|
`MappedName.cpp` sources without exporting the production naming callbacks:
|
|
|
|
```bash
|
|
./npmw run build:qt6-wasm-core
|
|
./npmw run build:freecad-naming-source-probe
|
|
./npmw run test:freecad-naming-source-probe
|
|
./npmw run check:freecad-private-naming-boundary
|
|
```
|
|
|
|
Passing this probe establishes that the private source subset and toolchain are
|
|
cross-compilable. It does not link the production OCCT Worker, does not close
|
|
EX-TSN-02, and does not change `systemExact=false`.
|
|
|
|
The versioned JSON request carries document `objectId`, stable positive
|
|
`objectTag`, prior naming evidence, result object identity, result tag, stage
|
|
DAG, STEP/BRep, and OCCT Generated/Modified/Deleted history. No Web fallback is
|
|
allowed to synthesize a FreeCAD private token.
|
|
|
|
The exported `booleanHistory(object, tool, operation)` function supports
|
|
`fuse`, `cut`, and `common`. It returns the native result shape, per-input
|
|
`modified`/`generated`/`deleted` records, a validity/topology/quality summary,
|
|
and capability flags. `prismHistory(profile, dx, dy, dz)` adds the first
|
|
PartDesign Pad contract: profile vertices can generate edges and profile edges
|
|
can generate faces, while the profile face is preserved as a result face.
|
|
`booleanProbe` and `booleanResult` are intentionally smaller operations for
|
|
Worker stress/ownership gates; callers must delete every returned Embind shape
|
|
handle. Primitive constructors cover positioned boxes, cylinders, spheres,
|
|
cones and a test rectangle Face. The provider also exports `shapeToStep(shape)`,
|
|
`booleanHistoryFromStep(objectStep, toolStep, operation)` and
|
|
`prismHistoryFromStep(profileStep, dx, dy, dz)`. The STEP functions are the
|
|
cross-WASM transport: Bitbybit exports STEP text, the native provider reads it
|
|
with `STEPControl_Reader`, returns the result again as `resultStep`, and no
|
|
linear-memory pointer crosses the boundary. Pad history currently requires a
|
|
valid planar Face profile; solids are rejected by OCCT rather than silently
|
|
treated as sketches. `loftHistoryFromStep(firstSectionStep, secondSectionStep,
|
|
ruled)` adds a verified two-section solid loft using `BRepOffsetAPI_ThruSections`.
|
|
It records generated edges/faces for both source profiles; more than two
|
|
sections, closed lofts, and PartDesign base fusion/cut stay on the signature
|
|
history path until their multi-source contract is implemented.
|
|
`pipeHistoryFromStep(profileStep, spineStep)` adds a verified single-edge
|
|
open-spine solid sweep using `BRepOffsetAPI_MakePipe`. It records profile
|
|
vertex/edge generation, profile end caps, and spine edge/endpoint provenance;
|
|
multi-edge spines, Frenet/transition modes, and hollow profiles remain explicit
|
|
unsupported cases.
|
|
`filletHistoryFromStep(baseStep, radius)` enables the first
|
|
native dress-up slice: OCCT `BRepFilletAPI_MakeFillet` applies a fixed radius to
|
|
all source edges and returns per-edge/face `Modified`, `Generated`, and `Deleted`
|
|
relations with result-kind mapping. The native build enables `TKFillet` and its
|
|
`TKBool` dependency.
|
|
`chamferHistoryFromStep(baseStep, distance)` uses the same native history
|
|
collector with `BRepFilletAPI_MakeChamfer` for a symmetric, fixed-distance,
|
|
all-edge chamfer.
|
|
`holeHistoryFromStep(baseStep, radius, depth, px, py, pz, dx, dy, dz)` composes
|
|
an OCCT cylinder and `BRepAlgoAPI_Cut` for a straight cylindrical hole with
|
|
explicit position and direction, returning the Boolean source history. Thread,
|
|
counterbore, countersink, and face-attached hole semantics remain outside this
|
|
minimal native contract.
|
|
`draftHistoryFromStep(baseStep, faceIndex, angle, direction, neutralPlane,
|
|
reversed)` uses `BRepOffsetAPI_DraftAngle` from `TKOffset` for one explicitly
|
|
selected source face. It returns native per-subshape history and rejects an
|
|
invalid face index, zero direction, zero angle, or invalid neutral plane before
|
|
publishing a result. Multi-face propagation and STEP files whose imported face
|
|
orientation OCCT cannot draft remain explicit unsupported/error cases.
|
|
`thicknessHistoryFromStep(baseStep, faceIndex, offset, intersectionJoin)` uses
|
|
`BRepOffsetAPI_MakeThickSolid` for one explicitly removed source face and
|
|
returns native offset history. Zero offsets and invalid face indexes are
|
|
rejected before execution.
|
|
`linearPatternHistoryFromStep(baseStep, dx, dy, dz)` creates one transformed
|
|
copy and fuses it with the source, preserving both Boolean input histories.
|
|
The contract intentionally covers exactly two whole-shape instances.
|
|
`polarPatternHistoryFromStep(baseStep, axis, angle)` creates one rotated copy
|
|
and fuses it with the source. It likewise covers exactly two whole-shape
|
|
instances around an explicit finite axis.
|
|
`mirroredHistoryFromStep(baseStep, planeOrigin, planeNormal)` creates one plane
|
|
reflected copy and fuses it with the source. The native contract is limited to
|
|
one whole-shape base, one standard document plane, and a fused result.
|
|
The `multiTransformHistoryFromStep(baseStep, steps)` binding accepts two to six
|
|
ordered two-instance linear, polar, or mirrored whole-shape steps. Each created
|
|
instance retains its transformed Base subshape mapping; one multi-argument Fuse
|
|
then aggregates every instance history back to the original Base indexes. The
|
|
single-step protocol continues to reuse the individual verified bindings.
|
|
|
|
The TypeScript boundary mapper is `mapNativeOcctHistoryRecords`; the reusable
|
|
`createNativeOcctStepHistoryBridge` exports Bitbybit ShapeHandles to STEP and
|
|
converts provider source names into document object IDs before calling
|
|
`captureNativeTopologyHistory`. The direct handle API remains for calls that
|
|
stay inside this single native WASM instance.
|