feat: complete supported Sketcher and PartDesign ABI contract
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

This commit is contained in:
2026-08-11 20:34:23 -04:00
parent 2be18a511e
commit aa607451ad
20 changed files with 918 additions and 62 deletions

View File

@@ -1,7 +1,8 @@
/// <reference lib="webworker" />
import type { NativeOcctHistoryStepProvider } from './nativeHistoryProvider'
import { NATIVE_OCCT_NAMING_ABI_UNAVAILABLE, type NativeOcctHistoryCapabilities, type NativeOcctHistoryRequest, type NativeOcctHistoryProtocolResponse } from './nativeHistoryProtocol'
import { nativeNamingCapabilitiesForModule, type NativeOcctHistoryCapabilities, type NativeOcctHistoryRequest, type NativeOcctHistoryProtocolResponse } from './nativeHistoryProtocol'
import { captureFreeCadPrivateNamingEvidence, createFreeCadPrivateNamingAbiRequest } from './nativeNamingAbi'
type WorkerRequest = { type: 'initialize'; moduleUrl: string } | { type: 'capture'; request: NativeOcctHistoryRequest } | { type: 'cancel'; requestId: string } | { type: 'dispose' }
type WorkerResponse = { type: 'ready'; capabilities: NativeOcctHistoryCapabilities } | { type: 'response'; response: NativeOcctHistoryProtocolResponse } | { type: 'error'; requestId?: string; error: string }
@@ -11,6 +12,16 @@ let provider: NativeOcctHistoryStepProvider | null = null
const cancelled = new Set<string>()
const send = (message: WorkerResponse) => scope.postMessage(message)
const operations: NativeOcctHistoryCapabilities['operations'] = ['fuse', 'cut', 'common', 'rotate', 'pad', 'pocket', 'loft', 'pipe', 'revolution', 'groove', 'fillet', 'chamfer', 'hole', 'draft', 'thickness', 'linear-pattern', 'polar-pattern', 'mirrored', 'multi-transform']
const capabilitiesFor = (module: NativeOcctHistoryStepProvider, occtVersion = module.occtVersion()): NativeOcctHistoryCapabilities => ({
providerId: 'occt-native.history-step',
providerVersion: '8.0.0-embind',
occtVersion,
availability: 'available',
operations: [...operations],
transport: 'step-text',
naming: nativeNamingCapabilitiesForModule(module),
})
const captureMultiTransform = (module: NativeOcctHistoryStepProvider, request: NativeOcctHistoryRequest) => {
if (request.transforms && request.transforms.length >= 2) return module.multiTransformHistoryFromStep?.(request.objectStep, request.transforms)
@@ -25,15 +36,7 @@ const initialize = async (moduleUrl: string) => {
provider = await imported.default()
send({
type: 'ready',
capabilities: {
providerId: 'occt-native.history-step',
providerVersion: '8.0.0-embind',
occtVersion: provider.occtVersion(),
availability: 'available',
operations: ['fuse', 'cut', 'common', 'rotate', 'pad', 'pocket', 'loft', 'pipe', 'revolution', 'groove', 'fillet', 'chamfer', 'hole', 'draft', 'thickness', 'linear-pattern', 'polar-pattern', 'mirrored', 'multi-transform'],
transport: 'step-text',
naming: NATIVE_OCCT_NAMING_ABI_UNAVAILABLE,
},
capabilities: capabilitiesFor(provider),
})
}
@@ -81,7 +84,25 @@ scope.onmessage = ({ data }: MessageEvent<WorkerRequest>) => {
: provider.booleanHistoryFromStep(request.objectStep, request.toolStep || '', request.operation)
if (!history) throw new Error('Native OCCT history provider does not expose the requested feature operation.')
if (cancelled.delete(data.request.requestId)) return
send({ type: 'response', response: { protocolVersion: request.protocolVersion, requestId: request.requestId, documentId: request.documentId, documentVersion: request.documentVersion, operationId: request.operationId, provider: { providerId: 'occt-native.history-step', providerVersion: '8.0.0-embind', occtVersion: history.occtVersion, availability: 'available', operations: ['fuse', 'cut', 'common', 'rotate', 'pad', 'pocket', 'loft', 'pipe', 'revolution', 'groove', 'fillet', 'chamfer', 'hole', 'draft', 'thickness', 'linear-pattern', 'polar-pattern', 'mirrored', 'multi-transform'], transport: 'step-text', naming: NATIVE_OCCT_NAMING_ABI_UNAVAILABLE }, history } })
const orderedStages = [...(request.stages ?? [])].sort((left, right) => left.ordinal - right.ordinal)
const finalStage = orderedStages.at(-1)
const stageId = finalStage?.resultStageId ?? finalStage?.stageId ?? `${request.operationId}:stage:0`
const namingEvidence = captureFreeCadPrivateNamingEvidence(provider, createFreeCadPrivateNamingAbiRequest({
requestId: request.requestId,
documentId: request.documentId,
documentVersion: request.documentVersion,
operationId: request.operationId,
operation: request.operation,
stageId,
resultObjectId: request.operationId,
inputs: (request.inputs ?? [{ inputId: 'object', role: 'object', step: request.objectStep }, ...(request.toolStep ? [{ inputId: 'tool', role: 'tool', step: request.toolStep }] : [])]).map(({ inputId, role, stageId: inputStageId, step }) => ({ inputId, step, ...(role ? { role } : {}), ...(inputStageId ? { stageId: inputStageId } : {}) })),
stages: orderedStages.map((stage) => ({ ...stage, inputIds: [...stage.inputIds] })),
...(history.resultStep ? { resultStep: history.resultStep } : {}),
...(history.resultBrep ? { resultBrep: history.resultBrep } : {}),
...(request.resultStepByStage ? { resultStepByStage: { ...request.resultStepByStage } } : {}),
history,
}))
send({ type: 'response', response: { protocolVersion: request.protocolVersion, requestId: request.requestId, documentId: request.documentId, documentVersion: request.documentVersion, operationId: request.operationId, provider: capabilitiesFor(provider, history.occtVersion), history: namingEvidence ? { ...history, namingEvidence } : history } })
} catch (error) {
send({ type: 'error', requestId: data.type === 'capture' ? data.request.requestId : undefined, error: error instanceof Error ? error.message : String(error) })
}