Files
Web_FreeCAD_Bitbybit/native/occt-history/README.md
wangdequan 97967041e2
Some checks failed
real-verification / chrome (push) Has been cancelled
real-verification / freecad-oracle (push) Has been cancelled
real-verification / wasm (push) Has been cancelled
feat: prepare FreeCAD private naming worker linkage
2026-08-11 23:16:22 -04:00

6.9 KiB

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:

./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:

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 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.