P3-04: add OCCT pad pocket and revolution

This commit is contained in:
2026-08-02 07:30:29 -04:00
parent 9dc5cfe3fd
commit 8d8d1b7c26
8 changed files with 189 additions and 6 deletions

View File

@@ -3,7 +3,7 @@ import assert from 'node:assert/strict'
import { createMockFacade } from '../src/facade/mockFacade'
import { PROJECT_SCHEMA_MIGRATIONS, PROJECT_SCHEMA_SQL, PROJECT_SCHEMA_VERSION } from '../src/facade/projectSchema'
import { PersistenceWriteQueue, ProjectAutosaveScheduler } from '../src/facade/projectStore'
import { assertShapeHandleIntegrity, normalizeBitbybitMesh, validateBooleanUnionInput, validateBoxInput, validateConeInput, validateCylinderInput, validatePlacementInput, validateSphereInput } from '../src/facade/geometryRuntime'
import { assertShapeHandleIntegrity, normalizeBitbybitMesh, validateBooleanUnionInput, validateBoxInput, validateConeInput, validateCylinderInput, validatePadInput, validatePlacementInput, validatePlanarProfile, validateRevolutionInput, validateSphereInput } from '../src/facade/geometryRuntime'
import type { ShapeHandle } from '../src/facade/types'
test('facade exposes a stable initial document projection', () => {
@@ -43,6 +43,15 @@ test('boolean geometry rejects cross-document and future-version operands', () =
assert.throws(() => validateBooleanUnionInput({ shapes: [first], documentId: 'doc-one', documentVersion: 2 }), /at least 2/)
})
test('feature profiles reject degenerate and non-planar geometry', () => {
const rectangle = { outer: [[-1, 0, -1], [1, 0, -1], [1, 0, 1], [-1, 0, 1]] as [number, number, number][] }
assert.doesNotThrow(() => validatePlanarProfile(rectangle))
assert.doesNotThrow(() => validatePadInput({ profile: rectangle, length: 4, documentId: 'doc', documentVersion: 1 }))
assert.throws(() => validatePlanarProfile({ outer: [[0, 0, 0], [1, 0, 0], [2, 0, 0]] }), /collinear/)
assert.throws(() => validatePlanarProfile({ outer: [[0, 0, 0], [1, 0, 0], [1, 0, 1], [0, 0.1, 1]] }), /coplanar/)
assert.throws(() => validateRevolutionInput({ profile: rectangle, axisDirection: [0, 0, 0], documentId: 'doc', documentVersion: 1 }), /axisDirection/)
})
test('Bitbybit face meshes are normalized into a facade-owned indexed asset', () => {
const shape: ShapeHandle = { id: 'shape-test', kernel: 'bitbybit-occt', kind: 'solid', documentId: 'doc', documentVersion: 7 }
const mesh = normalizeBitbybitMesh(shape, {