feat: establish reproducible FreeCAD web compatibility baseline

This commit is contained in:
2026-08-10 16:11:38 -04:00
parent e5a5d74dbc
commit b962a5c3b5
733 changed files with 349081 additions and 647 deletions

View File

@@ -12,6 +12,13 @@ const cancelled = new Set<string>()
const send = (message: WorkerResponse) => scope.postMessage(message)
const captureMultiTransform = (module: NativeOcctHistoryStepProvider, request: NativeOcctHistoryRequest) => {
if (request.transforms && request.transforms.length >= 2) return module.multiTransformHistoryFromStep?.(request.objectStep, request.transforms)
if (request.transformKind === 'linear') return module.linearPatternHistoryFromStep?.(request.objectStep, ...(request.direction || [0, 0, 0]))
if (request.transformKind === 'polar') return module.polarPatternHistoryFromStep?.(request.objectStep, ...(request.axisOrigin || [0, 0, 0]), ...(request.direction || [0, 0, 0]), request.angle || 0)
if (request.transformKind === 'mirrored') return module.mirroredHistoryFromStep?.(request.objectStep, ...(request.axisOrigin || [0, 0, 0]), ...(request.direction || [0, 0, 0]))
}
const initialize = async (moduleUrl: string) => {
const imported = await import(/* @vite-ignore */ moduleUrl) as { default?: () => Promise<NativeOcctHistoryStepProvider> }
if (typeof imported.default !== 'function') throw new Error('Native OCCT history module has no default Emscripten factory export.')
@@ -23,7 +30,7 @@ const initialize = async (moduleUrl: string) => {
providerVersion: '8.0.0-embind',
occtVersion: provider.occtVersion(),
availability: 'available',
operations: ['fuse', 'cut', 'common'],
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',
},
})
@@ -37,9 +44,43 @@ scope.onmessage = ({ data }: MessageEvent<WorkerRequest>) => {
if (data.type === 'cancel') { cancelled.add(data.requestId); return }
if (!provider) throw new Error('Native OCCT history Worker is not initialized.')
if (cancelled.delete(data.request.requestId)) return
const history = provider.booleanHistoryFromStep(data.request.objectStep, data.request.toolStep, data.request.operation)
const request = data.request
const history = request.operation === 'rotate'
? provider.rotateHistoryFromStep?.(request.objectStep, ...(request.axisOrigin || [0, 0, 0]), ...(request.direction || [0, 0, 0]), request.angle || 0)
: request.operation === 'pad'
? provider.prismHistoryFromStep?.(request.objectStep, ...(request.direction || [0, 0, 0]))
: request.operation === 'pocket'
? provider.pocketHistoryFromStep?.(request.objectStep, request.toolStep || '', ...(request.direction || [0, 0, 0]))
: request.operation === 'loft'
? provider.loftHistoryFromStep?.(request.objectStep, request.toolStep || '', request.ruled === true)
: request.operation === 'pipe'
? provider.pipeHistoryFromStep?.(request.objectStep, request.toolStep || '')
: request.operation === 'revolution'
? provider.revolutionHistoryFromStep?.(request.objectStep, ...(request.axisOrigin || [0, 0, 0]), ...(request.direction || [0, 0, 0]), request.angle || 0)
: request.operation === 'groove'
? provider.grooveHistoryFromStep?.(request.objectStep, request.toolStep || '', ...(request.axisOrigin || [0, 0, 0]), ...(request.direction || [0, 0, 0]), request.angle || 0)
: request.operation === 'fillet'
? provider.filletHistoryFromStep?.(request.objectStep, request.radius || 0)
: request.operation === 'chamfer'
? provider.chamferHistoryFromStep?.(request.objectStep, request.distance || 0)
: request.operation === 'hole'
? provider.holeHistoryFromStep?.(request.objectStep, request.radius || 0, request.depth || 0, ...(request.position || [0, 0, 0]), ...(request.direction || [0, 0, 0]))
: request.operation === 'draft'
? provider.draftHistoryFromStep?.(request.objectStep, request.faceIndex || 0, request.angle || 0, ...(request.direction || [0, 0, 0]), ...(request.axisOrigin || [0, 0, 0]), ...(request.neutralPlaneDirection || [0, 0, 0]), request.reversed === true)
: request.operation === 'thickness'
? provider.thicknessHistoryFromStep?.(request.objectStep, request.faceIndex || 0, request.offset || 0, request.joinType === 'Intersection')
: request.operation === 'linear-pattern'
? provider.linearPatternHistoryFromStep?.(request.objectStep, ...(request.direction || [0, 0, 0]))
: request.operation === 'polar-pattern'
? provider.polarPatternHistoryFromStep?.(request.objectStep, ...(request.axisOrigin || [0, 0, 0]), ...(request.direction || [0, 0, 0]), request.angle || 0)
: request.operation === 'mirrored'
? provider.mirroredHistoryFromStep?.(request.objectStep, ...(request.axisOrigin || [0, 0, 0]), ...(request.direction || [0, 0, 0]))
: request.operation === 'multi-transform'
? captureMultiTransform(provider, request)
: 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: data.request.protocolVersion, requestId: data.request.requestId, documentId: data.request.documentId, documentVersion: data.request.documentVersion, operationId: data.request.operationId, provider: { providerId: 'occt-native.history-step', providerVersion: '8.0.0-embind', occtVersion: history.occtVersion, availability: 'available', operations: ['fuse', 'cut', 'common'], transport: 'step-text' }, history } })
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' }, history } })
} catch (error) {
send({ type: 'error', requestId: data.type === 'capture' ? data.request.requestId : undefined, error: error instanceof Error ? error.message : String(error) })
}