P5: expose Sketcher solve command and OCCT dress-up features

This commit is contained in:
2026-08-02 10:29:30 -04:00
parent 6a1bd18384
commit 64b7369918
8 changed files with 65 additions and 6 deletions

View File

@@ -1,6 +1,6 @@
import { BitByBitOCCT, OccStateEnum } from '@bitbybit-dev/occt-worker'
import type { Inputs } from '@bitbybit-dev/occt'
import type { ApplyPlacementInput, BooleanCutInput, BooleanIntersectionInput, BooleanUnionInput, CreateBoxInput, CreateConeInput, CreateCylinderInput, CreateSphereInput, GeometryCapabilities, GeometryDocumentContext, LinearFeatureParameters, MeshAsset, PadInput, PlanarProfile, PocketInput, Point3, RevolutionInput, ShapeHandle, SubshapeRef } from './types'
import type { ApplyPlacementInput, BooleanCutInput, BooleanIntersectionInput, BooleanUnionInput, ChamferInput, CreateBoxInput, CreateConeInput, CreateCylinderInput, CreateSphereInput, FilletInput, GeometryCapabilities, GeometryDocumentContext, LinearFeatureParameters, MeshAsset, PadInput, PlanarProfile, PocketInput, Point3, RevolutionInput, ShapeHandle, SubshapeRef } from './types'
import { createSubshapeRefs } from './topologyNaming'
type KernelShapeReference = Inputs.OCCT.TopoDSShapePointer
@@ -102,6 +102,16 @@ export const validateBooleanCutInput = (input: BooleanCutInput) => {
export const validateBooleanIntersectionInput = (input: BooleanIntersectionInput) => validateBooleanShapes(input, input.shapes, 2)
const validateEdgeFeature = (input: GeometryDocumentContext & { base: ShapeHandle; indexes?: number[]; radius?: number; distance?: number }, value: number, name: string) => {
validateDocumentContext(input)
validateShapeContext(input, input.base)
finitePositive(value, name)
if (input.indexes?.some((index) => !Number.isSafeInteger(index) || index < 0)) throw new RangeError('Edge indexes must be non-negative safe integers.')
}
export const validateFilletInput = (input: FilletInput) => validateEdgeFeature(input, input.radius, 'radius')
export const validateChamferInput = (input: ChamferInput) => validateEdgeFeature(input, input.distance, 'distance')
const samePoint = (left: Point3, right: Point3, tolerance = 1e-9) => left.every((coordinate, axis) => Math.abs(coordinate - right[axis]) <= tolerance)
const subtract = (left: Point3, right: Point3): Point3 => [left[0] - right[0], left[1] - right[1], left[2] - right[2]]
const cross = (left: Point3, right: Point3): Point3 => [left[1] * right[2] - left[2] * right[1], left[2] * right[0] - left[0] * right[2], left[0] * right[1] - left[1] * right[0]]
@@ -354,6 +364,22 @@ export class BitbybitGeometryRuntime {
return this.registerShape(kernelShape, input.documentId, input.documentVersion)
}
async fillet(input: FilletInput): Promise<ShapeHandle> {
validateFilletInput(input)
const base = this.resolveShape(input.base).reference
const client = await this.readyClient()
const kernelShape = await client.occt.fillets.filletEdges({ shape: base, radius: input.radius, indexes: input.indexes })
return this.registerShape(kernelShape, input.documentId, input.documentVersion)
}
async chamfer(input: ChamferInput): Promise<ShapeHandle> {
validateChamferInput(input)
const base = this.resolveShape(input.base).reference
const client = await this.readyClient()
const kernelShape = await client.occt.fillets.chamferEdges({ shape: base, distance: input.distance, indexes: input.indexes })
return this.registerShape(kernelShape, input.documentId, input.documentVersion)
}
async pad(input: PadInput): Promise<ShapeHandle> {
validatePadInput(input)
const client = await this.readyClient()