diff --git a/src/lang/std/extrude.ts b/src/lang/std/extrude.ts deleted file mode 100644 index e0d8a3354..000000000 --- a/src/lang/std/extrude.ts +++ /dev/null @@ -1,80 +0,0 @@ -import { InternalFn } from './stdTypes' -import { - ExtrudeGroup, - ExtrudeSurface, - SketchGroup, - Position, - Rotation, -} from '../executor' -import { clockwiseSign } from './std' -import { generateUuidFromHashSeed } from '../../lib/uuid' - -export const extrude: InternalFn = ( - { sourceRange, engineCommandManager, code }, - length: number, - sketchVal: SketchGroup -): ExtrudeGroup => { - const sketch = sketchVal - const { position, rotation } = sketchVal - - const id = generateUuidFromHashSeed( - JSON.stringify({ - code, - sourceRange, - data: { - length, - sketchVal, - }, - }) - ) - - const extrudeSurfaces: ExtrudeSurface[] = [] - const extrusionDirection = clockwiseSign(sketch.value.map((line) => line.to)) - engineCommandManager.sendModelingCommand({ - id, - range: sourceRange, - command: { - type: 'modeling_cmd_req', - cmd: { - type: 'extrude', - target: sketch.id, - distance: length, - cap: true, - }, - cmd_id: id, - }, - }) - - return { - type: 'extrudeGroup', - id, - value: extrudeSurfaces, // TODO, this is just an empty array now, should be deleted. - height: length, - position, - rotation, - __meta: [ - { - sourceRange, - }, - { - sourceRange: sketchVal.__meta[0].sourceRange, - }, - ], - } -} - -export const getExtrudeWallTransform: InternalFn = ( - _, - pathName: string, - extrudeGroup: ExtrudeGroup -): { - position: Position - quaternion: Rotation -} => { - const path = extrudeGroup?.value.find((path) => path.name === pathName) - if (!path) throw new Error(`Could not find path with name ${pathName}`) - return { - position: path.position, - quaternion: path.rotation, - } -} diff --git a/src/lang/std/sketch.ts b/src/lang/std/sketch.ts index 1b11297ce..1e9cc8554 100644 --- a/src/lang/std/sketch.ts +++ b/src/lang/std/sketch.ts @@ -23,12 +23,7 @@ import { GuiModes, toolTips, TooTip } from '../../useStore' import { splitPathAtPipeExpression } from '../modifyAst' import { generateUuidFromHashSeed } from '../../lib/uuid' -import { - SketchLineHelper, - ModifyAstBase, - InternalFn, - TransformCallback, -} from './stdTypes' +import { SketchLineHelper, ModifyAstBase, TransformCallback } from './stdTypes' import { createLiteral, @@ -42,10 +37,7 @@ import { } from '../modifyAst' import { roundOff, getLength, getAngle } from '../../lib/utils' import { getSketchSegmentFromSourceRange } from './sketchConstraints' -import { - intersectionWithParallelLine, - perpendicularDistance, -} from 'sketch-helpers' +import { perpendicularDistance } from 'sketch-helpers' export type Coords2d = [number, number] @@ -115,44 +107,6 @@ function makeId(seed: string | any) { } export const lineTo: SketchLineHelper = { - fn: ( - { sourceRange, code }, - data: - | [number, number] - | { - to: [number, number] - tag?: string - }, - previousSketch: SketchGroup - ): SketchGroup => { - if (!previousSketch) - throw new Error('lineTo must be called after startSketchAt') - const sketchGroup = { ...previousSketch } - const from = getCoordsFromPaths(sketchGroup, sketchGroup.value.length - 1) - const to = 'to' in data ? data.to : data - - const id = makeId({ - code, - sourceRange, - data, - }) - const currentPath: Path = { - type: 'toPoint', - to, - from, - __geoMeta: { - sourceRange, - id, - }, - } - if ('tag' in data) { - currentPath.name = data.tag - } - return { - ...sketchGroup, - value: [...sketchGroup.value, currentPath], - } - }, add: ({ node, pathToNode, @@ -220,75 +174,6 @@ export const lineTo: SketchLineHelper = { } export const line: SketchLineHelper = { - fn: ( - { sourceRange, engineCommandManager, code }, - data: - | [number, number] - | 'default' - | { - to: [number, number] | 'default' - // name?: string - tag?: string - }, - previousSketch: SketchGroup - ): SketchGroup => { - if (!previousSketch) throw new Error('lineTo must be called after lineTo') - const sketchGroup = { ...previousSketch } - const from = getCoordsFromPaths(sketchGroup, sketchGroup.value.length - 1) - let args: [number, number] = [0.2, 1] - if (data !== 'default' && 'to' in data && data.to !== 'default') { - args = data.to - } else if (data !== 'default' && !('to' in data)) { - args = data - } - - const to: [number, number] = [from[0] + args[0], from[1] + args[1]] - const lineData: LineData = { - from: [...from, 0], - to: [...to, 0], - } - const id = makeId({ - code, - sourceRange, - data, - }) - engineCommandManager.sendModelingCommand({ - id, - range: sourceRange, - command: { - type: 'modeling_cmd_req', - cmd: { - type: 'extend_path', - path: sketchGroup.id, - segment: { - type: 'line', - end: { - x: lineData.to[0], - y: lineData.to[1], - z: 0, - }, - }, - }, - cmd_id: id, - }, - }) - const currentPath: Path = { - type: 'toPoint', - to, - from, - __geoMeta: { - id, - sourceRange, - }, - } - if (data !== 'default' && 'tag' in data) { - currentPath.name = data.tag - } - return { - ...sketchGroup, - value: [...sketchGroup.value, currentPath], - } - }, add: ({ node, previousProgramMemory, @@ -382,25 +267,6 @@ export const line: SketchLineHelper = { } export const xLineTo: SketchLineHelper = { - fn: ( - meta, - data: - | number - | { - to: number - // name?: string - tag?: string - }, - previousSketch: SketchGroup - ) => { - if (!previousSketch) throw new Error('bad bad bad') - const from = getCoordsFromPaths( - previousSketch, - previousSketch.value.length - 1 - ) - const [xVal, tag] = typeof data !== 'number' ? [data.to, data.tag] : [data] - return lineTo.fn(meta, { to: [xVal, from[1]], tag }, previousSketch) - }, add: ({ node, pathToNode, to, replaceExisting, createCallback }) => { const _node = { ...node } const getNode = getNodeFromPathCurry(_node, pathToNode) @@ -449,25 +315,6 @@ export const xLineTo: SketchLineHelper = { } export const yLineTo: SketchLineHelper = { - fn: ( - meta, - data: - | number - | { - to: number - // name?: string - tag?: string - }, - previousSketch: SketchGroup - ) => { - if (!previousSketch) throw new Error('bad bad bad') - const from = getCoordsFromPaths( - previousSketch, - previousSketch.value.length - 1 - ) - const [yVal, tag] = typeof data !== 'number' ? [data.to, data.tag] : [data] - return lineTo.fn(meta, { to: [from[0], yVal], tag }, previousSketch) - }, add: ({ node, pathToNode, to, replaceExisting, createCallback }) => { const _node = { ...node } const getNode = getNodeFromPathCurry(_node, pathToNode) @@ -516,21 +363,6 @@ export const yLineTo: SketchLineHelper = { } export const xLine: SketchLineHelper = { - fn: ( - meta, - data: - | number - | { - length: number - tag?: string - }, - previousSketch: SketchGroup - ) => { - if (!previousSketch) throw new Error('bad bad bad') - const [xVal, tag] = - typeof data !== 'number' ? [data.length, data.tag] : [data] - return line.fn(meta, { to: [xVal, 0], tag }, previousSketch) - }, add: ({ node, pathToNode, to, from, replaceExisting, createCallback }) => { const _node = { ...node } const getNode = getNodeFromPathCurry(_node, pathToNode) @@ -581,22 +413,6 @@ export const xLine: SketchLineHelper = { } export const yLine: SketchLineHelper = { - fn: ( - meta, - data: - | number - | { - length: number - // name?: string - tag?: string - }, - previousSketch: SketchGroup - ) => { - if (!previousSketch) throw new Error('bad bad bad') - const [yVal, tag] = - typeof data !== 'number' ? [data.length, data.tag] : [data] - return line.fn(meta, { to: [0, yVal], tag }, previousSketch) - }, add: ({ node, pathToNode, to, from, replaceExisting, createCallback }) => { const _node = { ...node } const getNode = getNodeFromPathCurry(_node, pathToNode) @@ -641,47 +457,6 @@ export const yLine: SketchLineHelper = { } export const angledLine: SketchLineHelper = { - fn: ( - { sourceRange, engineCommandManager, code }, - data: - | [number, number] - | { - angle: number - length: number - tag?: string - }, - previousSketch: SketchGroup - ) => { - if (!previousSketch) throw new Error('lineTo must be called after lineTo') - const sketchGroup = { ...previousSketch } - const from = getCoordsFromPaths(sketchGroup, sketchGroup.value.length - 1) - const [angle, length] = 'angle' in data ? [data.angle, data.length] : data - const to: [number, number] = [ - from[0] + length * Math.cos((angle * Math.PI) / 180), - from[1] + length * Math.sin((angle * Math.PI) / 180), - ] - const id = makeId({ - code, - sourceRange, - data, - }) - const currentPath: Path = { - type: 'toPoint', - to, - from, - __geoMeta: { - id, - sourceRange, - }, - } - if ('tag' in data) { - currentPath.name = data.tag - } - return { - ...sketchGroup, - value: [...sketchGroup.value, currentPath], - } - }, add: ({ node, pathToNode, @@ -749,26 +524,6 @@ export const angledLine: SketchLineHelper = { } export const angledLineOfXLength: SketchLineHelper = { - fn: ( - { sourceRange, programMemory, engineCommandManager, code }, - data: - | [number, number] - | { - angle: number - length: number - tag?: string - }, - previousSketch: SketchGroup - ) => { - if (!previousSketch) throw new Error('lineTo must be called after lineTo') - const [angle, length, tag] = - 'angle' in data ? [data.angle, data.length, data.tag] : data - return line.fn( - { sourceRange, programMemory, engineCommandManager, code }, - { to: getYComponent(angle, length), tag }, - previousSketch - ) - }, add: ({ node, previousProgramMemory, @@ -842,26 +597,6 @@ export const angledLineOfXLength: SketchLineHelper = { } export const angledLineOfYLength: SketchLineHelper = { - fn: ( - { sourceRange, programMemory, engineCommandManager, code }, - data: - | [number, number] - | { - angle: number - length: number - tag?: string - }, - previousSketch: SketchGroup - ) => { - if (!previousSketch) throw new Error('lineTo must be called after lineTo') - const [angle, length, tag] = - 'angle' in data ? [data.angle, data.length, data.tag] : data - return line.fn( - { sourceRange, programMemory, engineCommandManager, code }, - { to: getXComponent(angle, length), tag }, - previousSketch - ) - }, add: ({ node, previousProgramMemory, @@ -936,33 +671,6 @@ export const angledLineOfYLength: SketchLineHelper = { } export const angledLineToX: SketchLineHelper = { - fn: ( - { sourceRange, programMemory, engineCommandManager, code }, - data: - | [number, number] - | { - angle: number - to: number - tag?: string - }, - previousSketch: SketchGroup - ) => { - if (!previousSketch) throw new Error('lineTo must be called after lineTo') - const from = getCoordsFromPaths( - previousSketch, - previousSketch.value.length - 1 - ) - const [angle, xTo, tag] = - 'angle' in data ? [data.angle, data.to, data.tag] : data - const xComponent = xTo - from[0] - const yComponent = xComponent * Math.tan((angle * Math.PI) / 180) - const yTo = from[1] + yComponent - return lineTo.fn( - { sourceRange, programMemory, engineCommandManager, code }, - { to: [xTo, yTo], tag }, - previousSketch - ) - }, add: ({ node, pathToNode, @@ -1032,33 +740,6 @@ export const angledLineToX: SketchLineHelper = { } export const angledLineToY: SketchLineHelper = { - fn: ( - { sourceRange, programMemory, engineCommandManager, code }, - data: - | [number, number] - | { - angle: number - to: number - tag?: string - }, - previousSketch: SketchGroup - ) => { - if (!previousSketch) throw new Error('lineTo must be called after lineTo') - const from = getCoordsFromPaths( - previousSketch, - previousSketch.value.length - 1 - ) - const [angle, yTo, tag] = - 'angle' in data ? [data.angle, data.to, data.tag] : data - const yComponent = yTo - from[1] - const xComponent = yComponent / Math.tan((angle * Math.PI) / 180) - const xTo = from[0] + xComponent - return lineTo.fn( - { sourceRange, programMemory, engineCommandManager, code }, - { to: [xTo, yTo], tag }, - previousSketch - ) - }, add: ({ node, pathToNode, @@ -1129,37 +810,6 @@ export const angledLineToY: SketchLineHelper = { } export const angledLineThatIntersects: SketchLineHelper = { - fn: ( - { sourceRange, programMemory, engineCommandManager, code }, - data: { - angle: number - intersectTag: string - offset?: number - tag?: string - }, - previousSketch: SketchGroup - ) => { - if (!previousSketch) throw new Error('lineTo must be called after lineTo') - const intersectPath = previousSketch.value.find( - ({ name }) => name === data.intersectTag - ) - if (!intersectPath) throw new Error('intersectTag must match a line') - const from = getCoordsFromPaths( - previousSketch, - previousSketch.value.length - 1 - ) - const to = intersectionWithParallelLine({ - line1: [intersectPath.from, intersectPath.to], - line1Offset: data.offset || 0, - line2Point: from, - line2Angle: data.angle, - }) - return lineTo.fn( - { sourceRange, programMemory, engineCommandManager, code }, - { to, tag: data.tag }, - previousSketch - ) - }, add: ({ node, pathToNode, @@ -1522,133 +1172,6 @@ function addTagWithTo( } } -export const close: InternalFn = ( - { sourceRange, engineCommandManager, code }, - sketchGroup: SketchGroup -): SketchGroup => { - const from = getCoordsFromPaths(sketchGroup, sketchGroup.value.length - 1) - const to = sketchGroup.start - ? sketchGroup.start.from - : getCoordsFromPaths(sketchGroup, 0) - - const id = makeId({ - code, - sourceRange, - data: sketchGroup, - }) - engineCommandManager.sendModelingCommand({ - id, - range: sourceRange, - command: { - type: 'modeling_cmd_req', - cmd: { - type: 'close_path', - path_id: sketchGroup.id, - }, - cmd_id: id, - }, - }) - - const currentPath: Path = { - type: 'toPoint', - to, - from, - __geoMeta: { - id, - sourceRange, - }, - } - const newValue = [...sketchGroup.value] - newValue.push(currentPath) - return { - ...sketchGroup, - value: newValue, - } -} - -export const startSketchAt: InternalFn = ( - { sourceRange, programMemory, engineCommandManager, code }, - data: - | [number, number] - | 'default' - | { - to: [number, number] | 'default' - // name?: string - tag?: string - } -): SketchGroup => { - let to: [number, number] = [0, 0] - if (data !== 'default' && 'to' in data && data.to !== 'default') { - to = data.to - } else if (data !== 'default' && !('to' in data)) { - to = data - } - - const lineData: { to: [number, number, number] } = { - to: [...to, 0], - } - const id = makeId({ - code, - sourceRange, - data, - }) - const pathId = makeId({ - code, - sourceRange, - data, - isPath: true, - }) - engineCommandManager.sendModelingCommand({ - id: pathId, - range: sourceRange, - command: { - type: 'modeling_cmd_req', - cmd: { - type: 'start_path', - }, - cmd_id: pathId, - }, - }) - engineCommandManager.sendSceneCommand({ - type: 'modeling_cmd_req', - cmd: { - type: 'move_path_pen', - path: pathId, - to: { - x: lineData.to[0], - y: lineData.to[1], - z: 0, - }, - }, - cmd_id: id, - }) - const currentPath: Path = { - type: 'base', - to, - from: to, - __geoMeta: { - id, - sourceRange, - }, - } - if (data !== 'default' && 'tag' in data) { - currentPath.name = data.tag - } - return { - type: 'sketchGroup', - start: currentPath, - value: [], - position: [0, 0, 0], - rotation: [0, 0, 0, 1], - id: pathId, - __meta: [ - { - sourceRange, - }, - ], - } -} - export function getYComponent( angleDegree: number, xComponent: number diff --git a/src/lang/std/sketchConstraints.ts b/src/lang/std/sketchConstraints.ts index 151096572..e71512333 100644 --- a/src/lang/std/sketchConstraints.ts +++ b/src/lang/std/sketchConstraints.ts @@ -1,4 +1,3 @@ -import { getAngle } from '../../lib/utils' import { TooTip, toolTips } from '../../useStore' import { Program, @@ -6,7 +5,6 @@ import { CallExpression, } from '../abstractSyntaxTreeTypes' import { SketchGroup, SourceRange } from '../executor' -import { InternalFn } from './stdTypes' export function getSketchSegmentFromSourceRange( sketchGroup: SketchGroup, @@ -36,79 +34,6 @@ export function getSketchSegmentFromSourceRange( } } -export const segLen: InternalFn = ( - _, - segName: string, - sketchGroup: SketchGroup -): number => { - const line = sketchGroup?.value.find((seg) => seg?.name === segName) - // maybe this should throw, but the language doesn't have a way to handle errors yet - if (!line) return 0 - - return Math.sqrt( - (line.from[1] - line.to[1]) ** 2 + (line.from[0] - line.to[0]) ** 2 - ) -} - -export const segAng: InternalFn = ( - _, - segName: string, - sketchGroup: SketchGroup -): number => { - const line = sketchGroup?.value.find((seg) => seg.name === segName) - // maybe this should throw, but the language doesn't have a way to handle errors yet - if (!line) return 0 - return getAngle(line.from, line.to) -} - -function segEndFactory(which: 'x' | 'y'): InternalFn { - return (_, segName: string, sketchGroup: SketchGroup): number => { - const line = - sketchGroup?.start?.name === segName - ? sketchGroup?.start - : sketchGroup?.value.find((seg) => seg.name === segName) - // maybe this should throw, but the language doesn't have a way to handle errors yet - if (!line) return 0 - return which === 'x' ? line.to[0] : line.to[1] - } -} - -export const segEndX: InternalFn = segEndFactory('x') -export const segEndY: InternalFn = segEndFactory('y') - -function lastSegFactory(which: 'x' | 'y'): InternalFn { - return (_, sketchGroup: SketchGroup): number => { - const lastLine = sketchGroup?.value[sketchGroup.value.length - 1] - return which === 'x' ? lastLine.to[0] : lastLine.to[1] - } -} - -export const lastSegX: InternalFn = lastSegFactory('x') -export const lastSegY: InternalFn = lastSegFactory('y') - -function angleToMatchLengthFactory(which: 'x' | 'y'): InternalFn { - return (_, segName: string, to: number, sketchGroup: SketchGroup): number => { - const isX = which === 'x' - const lineToMatch = sketchGroup?.value.find((seg) => seg.name === segName) - // maybe this should throw, but the language doesn't have a way to handle errors yet - if (!lineToMatch) return 0 - const lengthToMatch = Math.sqrt( - (lineToMatch.from[1] - lineToMatch.to[1]) ** 2 + - (lineToMatch.from[0] - lineToMatch.to[0]) ** 2 - ) - - const lastLine = sketchGroup?.value[sketchGroup.value.length - 1] - const diff = Math.abs(to - (isX ? lastLine.to[0] : lastLine.to[1])) - - const angleR = Math[isX ? 'acos' : 'asin'](diff / lengthToMatch) - - return diff > lengthToMatch ? 0 : (angleR * 180) / Math.PI - } -} - -export const angleToMatchLengthX: InternalFn = angleToMatchLengthFactory('x') -export const angleToMatchLengthY: InternalFn = angleToMatchLengthFactory('y') - export function isSketchVariablesLinked( secondaryVarDec: VariableDeclarator, primaryVarDec: VariableDeclarator, diff --git a/src/lang/std/std.ts b/src/lang/std/std.ts deleted file mode 100644 index 4265407c7..000000000 --- a/src/lang/std/std.ts +++ /dev/null @@ -1,170 +0,0 @@ -import { - lineTo, - xLineTo, - yLineTo, - line, - xLine, - yLine, - angledLine, - angledLineOfXLength, - angledLineToX, - angledLineOfYLength, - angledLineToY, - close, - startSketchAt, - angledLineThatIntersects, -} from './sketch' -import { - segLen, - segAng, - angleToMatchLengthX, - angleToMatchLengthY, - segEndX, - segEndY, - lastSegX, - lastSegY, -} from './sketchConstraints' -import { getExtrudeWallTransform, extrude } from './extrude' - -import { InternalFn, InternalFnNames } from './stdTypes' - -// const transform: InternalFn = ( -// { sourceRange }: InternalFirstArg, -// transformInfo: { -// position: Position -// quaternion: Rotation -// }, -// sketch: T -// ): T => { -// const quaternionToApply = new Quaternion(...transformInfo?.quaternion) -// const newQuaternion = new Quaternion(...sketch.rotation).multiply( -// quaternionToApply.invert() -// ) - -// const oldPosition = new Vector3(...sketch?.position) -// const newPosition = oldPosition -// .applyQuaternion(quaternionToApply) -// .add(new Vector3(...transformInfo?.position)) -// return { -// ...sketch, -// position: newPosition.toArray(), -// rotation: newQuaternion.toArray(), -// __meta: [ -// ...sketch.__meta, -// { -// sourceRange, -// pathToNode: [], // TODO -// }, -// ], -// } -// } - -// const translate: InternalFn = ( -// { sourceRange }: InternalFirstArg, -// vec3: [number, number, number], -// sketch: T -// ): T => { -// const oldPosition = new Vector3(...sketch.position) -// const newPosition = oldPosition.add(new Vector3(...vec3)) -// return { -// ...sketch, -// position: newPosition.toArray(), -// __meta: [ -// ...sketch.__meta, -// { -// sourceRange, -// pathToNode: [], // TODO -// }, -// ], -// } -// } - -const min: InternalFn = (_, a: number, b: number): number => Math.min(a, b) - -const legLen: InternalFn = (_, hypotenuse: number, leg: number): number => - Math.sqrt( - hypotenuse ** 2 - Math.min(Math.abs(leg), Math.abs(hypotenuse)) ** 2 - ) - -const legAngX: InternalFn = (_, hypotenuse: number, leg: number): number => - (Math.acos(Math.min(leg, hypotenuse) / hypotenuse) * 180) / Math.PI - -const legAngY: InternalFn = (_, hypotenuse: number, leg: number): number => - (Math.asin(Math.min(leg, hypotenuse) / hypotenuse) * 180) / Math.PI - -export const internalFns: { [key in InternalFnNames]: InternalFn } = { - // TODO - re-enable these - // rx: rotateOnAxis([1, 0, 0]), // Enable rotations #152 - // ry: rotateOnAxis([0, 1, 0]), - // rz: rotateOnAxis([0, 0, 1]), - extrude, - // translate, - // transform, - getExtrudeWallTransform, - min, - legLen, - legAngX, - legAngY, - segEndX, - segEndY, - lastSegX, - lastSegY, - segLen, - segAng, - angleToMatchLengthX, - angleToMatchLengthY, - lineTo: lineTo.fn, - xLineTo: xLineTo.fn, - yLineTo: yLineTo.fn, - line: line.fn, - xLine: xLine.fn, - yLine: yLine.fn, - angledLine: angledLine.fn, - angledLineOfXLength: angledLineOfXLength.fn, - angledLineToX: angledLineToX.fn, - angledLineOfYLength: angledLineOfYLength.fn, - angledLineToY: angledLineToY.fn, - angledLineThatIntersects: angledLineThatIntersects.fn, - startSketchAt, - close, -} - -// function rotateOnAxis( -// axisMultiplier: [number, number, number] -// ): InternalFn { -// return ({ sourceRange }, rotationD: number, sketch: T): T => { -// const rotationR = rotationD * (Math.PI / 180) -// const rotateVec = new Vector3(...axisMultiplier) -// const quaternion = new Quaternion() -// quaternion.setFromAxisAngle(rotateVec, rotationR) - -// const position = new Vector3(...sketch.position) -// .applyQuaternion(quaternion) -// .toArray() - -// const existingQuat = new Quaternion(...sketch.rotation) -// const rotation = quaternion.multiply(existingQuat).toArray() -// return { -// ...sketch, -// rotation, -// position, -// __meta: [ -// ...sketch.__meta, -// { -// sourceRange, -// pathToNode: [], // TODO -// }, -// ], -// } -// } -// } - -export function clockwiseSign(points: [number, number][]): number { - let sum = 0 - for (let i = 0; i < points.length; i++) { - const currentPoint = points[i] - const nextPoint = points[(i + 1) % points.length] - sum += (nextPoint[0] - currentPoint[0]) * (nextPoint[1] + currentPoint[1]) - } - return sum >= 0 ? 1 : -1 -} diff --git a/src/lang/std/stdTypes.ts b/src/lang/std/stdTypes.ts index 40a6b3b6a..d25721526 100644 --- a/src/lang/std/stdTypes.ts +++ b/src/lang/std/stdTypes.ts @@ -17,44 +17,6 @@ export interface PathReturn { currentPath: Path } -export type InternalFn = (internals: InternalFirstArg, ...args: any[]) => any - -export type InternalFnNames = - // TODO re-enable these - // | 'translate' - // | 'transform' - // | 'rx' // Enable rotations #152 - // | 'ry' - // | 'rz' - | 'extrude' - | 'getExtrudeWallTransform' - | 'min' - | 'legLen' - | 'legAngX' - | 'legAngY' - | 'segEndX' - | 'segEndY' - | 'lastSegX' - | 'lastSegY' - | 'segLen' - | 'segAng' - | 'angleToMatchLengthX' - | 'angleToMatchLengthY' - | 'lineTo' - | 'yLineTo' - | 'xLineTo' - | 'line' - | 'yLine' - | 'xLine' - | 'angledLine' - | 'angledLineOfXLength' - | 'angledLineToX' - | 'angledLineOfYLength' - | 'angledLineToY' - | 'startSketchAt' - | 'close' - | 'angledLineThatIntersects' - export interface ModifyAstBase { node: Program previousProgramMemory: ProgramMemory @@ -87,7 +49,6 @@ export type SketchCallTransfromMap = { } export interface SketchLineHelper { - fn: InternalFn add: (a: addCall) => { modifiedAst: Program pathToNode: PathToNode diff --git a/src/wasm-lib/Cargo.lock b/src/wasm-lib/Cargo.lock index 47576d5ce..2f726ed3f 100644 --- a/src/wasm-lib/Cargo.lock +++ b/src/wasm-lib/Cargo.lock @@ -1249,7 +1249,6 @@ dependencies = [ "uuid", "wasm-bindgen", "wasm-bindgen-futures", - "web-sys", ] [[package]] diff --git a/src/wasm-lib/Cargo.toml b/src/wasm-lib/Cargo.toml index 5090fc854..4e395c9c9 100644 --- a/src/wasm-lib/Cargo.toml +++ b/src/wasm-lib/Cargo.toml @@ -30,32 +30,6 @@ uuid = { version = "1.4.1", features = ["v4", "js", "serde"] } wasm-bindgen = "0.2.87" wasm-bindgen-futures = "0.4.37" -[dependencies.web-sys] -version = "0.3.64" -features = [ - "BinaryType", - "Blob", - "CloseEvent", - "ErrorEvent", - "FileReader", - "MessageEvent", - "ProgressEvent", - "RtcConfiguration", - "RtcIceServer", - "RtcIceTransportPolicy", - "RtcPeerConnection", - "RtcSignalingState", - "RtcSdpType", - "RtcSessionDescriptionInit", - "RtcPeerConnectionIceEvent", - "RtcIceCandidate", - "RtcDataChannel", - "RtcDataChannelEvent", - "RtcRtpTransceiver", - "WebSocket", -] -optional = true - [profile.release] panic = "abort" debug = true @@ -66,5 +40,5 @@ tokio = { version = "1.32.0", features = ["rt-multi-thread", "macros", "time"] } [features] default = ["web"] -web = ["dep:gloo-file", "dep:js-sys", "dep:web-sys"] +web = ["dep:gloo-file", "dep:js-sys"] noweb = ["dep:futures", "dep:httparse", "dep:tokio", "dep:tokio-tungstenite"] diff --git a/src/wasm-lib/src/engine/conn_web.rs b/src/wasm-lib/src/engine/conn_web.rs index 428782b52..b2f249c37 100644 --- a/src/wasm-lib/src/engine/conn_web.rs +++ b/src/wasm-lib/src/engine/conn_web.rs @@ -56,343 +56,3 @@ impl EngineConnection { Ok(()) } } - -/*use anyhow::Result; -use kittycad::types::{WebSocketMessages, WebSocketResponses}; -use wasm_bindgen::prelude::*; -use web_sys::{CloseEvent, ErrorEvent, MessageEvent, RtcDataChannel, RtcPeerConnection, WebSocket}; - -use crate::errors::{KclError, KclErrorDetails}; - -macro_rules! console_log { - ($($t:tt)*) => (log(&format_args!($($t)*).to_string())) -} - -#[wasm_bindgen] -extern "C" { - #[wasm_bindgen(js_namespace = console)] - fn log(s: &str); -} - -#[derive(Debug, Clone)] -pub struct EngineConnection { - ws: WebSocket, - pc: RtcPeerConnection, - lossy_data_channel: RtcDataChannel, - - ready: bool, -} - -impl EngineConnection { - pub async fn new( - conn_str: &str, - auth_token: &str, - _origin: &str, - ) -> Result { - // Setup the websocket connection. - let ws = WebSocket::new(conn_str)?; - - // Setup the WebRTC connection. - let pc = RtcPeerConnection::new()?; - let lossy_data_channel = pc.create_data_channel("unreliable_modeling_cmds"); - - let cloned_ws = ws.clone(); - let cloned_auth_token = auth_token.to_owned(); - let onopen_callback = Closure::::new(move || { - println!("Connected to websocket, waiting for ICE servers"); - - // Send our token for auth. - cloned_ws - .send_with_str(&cloned_auth_token) - .expect("failed to send auth token"); - }); - ws.set_onopen(Some(onopen_callback.as_ref().unchecked_ref())); - onopen_callback.forget(); - - let onerror_callback = Closure::::new(move |e: ErrorEvent| { - console_log!("error event: {:?}", e); - }); - ws.set_onerror(Some(onerror_callback.as_ref().unchecked_ref())); - onerror_callback.forget(); - - // For small binary messages, like CBOR, Arraybuffer is more efficient than Blob handling - // Export is huge so let's use Blob. - ws.set_binary_type(web_sys::BinaryType::Blob); - - let engine_conn = EngineConnection { - ws, - pc, - lossy_data_channel, - ready: false, - }; - - let mut cloned_engine_conn = engine_conn.clone(); - let onclose_callback = Closure::::new(move |e: CloseEvent| { - console_log!("close event: {:?}", e); - cloned_engine_conn - .close() - .expect("failed to close engine connection"); - }); - engine_conn - .ws - .set_onclose(Some(onclose_callback.as_ref().unchecked_ref())); - onclose_callback.forget(); - - let mut cloned_engine_conn = engine_conn.clone(); - let onmessage_callback = Closure::::new(move |msg: MessageEvent| { - // Parse the message as our types. - let msg = match parse_message(msg) { - Ok(msg) => msg, - Err(e) => { - console_log!("Failed to parse message: {:?}", e); - return; - } - }; - - match msg { - WebSocketResponses::IceServerInfo { ice_servers } => { - // When we set the Configuration, we want to always force - // iceTransportPolicy to 'relay', since we know the topology - // of the ICE/STUN/TUN server and the engine. We don't wish to - // talk to the engine in any configuration /other/ than relay - // from a infra POV. - let mut config = web_sys::RtcConfiguration::new(); - let converted_ice_servers = js_sys::Array::new(); - for server in ice_servers { - let mut ice_server = web_sys::RtcIceServer::new(); - let urls = js_sys::Array::new(); - for url in server.urls { - urls.push(&JsValue::from(url)); - } - ice_server.urls(&urls.into()); - if let Some(credential) = server.credential { - ice_server.credential(&credential); - } - if let Some(username) = server.username { - ice_server.username(&username); - } - converted_ice_servers.push(&ice_server.into()); - } - config.ice_servers(&converted_ice_servers.into()); - config.ice_transport_policy(web_sys::RtcIceTransportPolicy::Relay); - cloned_engine_conn.pc = web_sys::RtcPeerConnection::new_with_configuration( - &config, - ) - .expect("Failed to create RtcPeerConnection with our custom configuration"); - - // We have an ICE Servers set now. We just setConfiguration, so let's - // start adding things we care about to the PeerConnection and let - // ICE negotiation happen in the background. Everything from here - // until the end of this function is setup of our end of the - // PeerConnection and waiting for events to fire our callbacks. - - let mut cloned_engine_conn2 = cloned_engine_conn.clone(); - let onicecandidate_callback = - Closure::::new(move |ev: MessageEvent| { - if !cloned_engine_conn2.ready { - return; - } - - let ev: web_sys::RtcPeerConnectionIceEvent = ev - .dyn_into() - .expect("Failed to cast to RtcPeerConnectionIceEvent"); - - if let Some(candidate) = ev.candidate() { - console_log!("sending trickle ice candidate"); - cloned_engine_conn2 - .ws_send(WebSocketMessages::TrickleIce { - candidate: kittycad::types::RtcIceCandidateInit { - candidate: candidate.candidate(), - sdp_mid: candidate.sdp_mid(), - sdp_m_line_index: candidate.sdp_m_line_index(), - username_fragment: Default::default(), - }, - }) - .expect("failed to send trickle ice candidate"); - } - }); - cloned_engine_conn - .pc - .set_onicecandidate(Some(onicecandidate_callback.as_ref().unchecked_ref())); - onicecandidate_callback.forget(); - - let onconnectionstatechange_callback = - Closure::::new(move |e: MessageEvent| { - console_log!("connection state changed: {:?}", e); - }); - cloned_engine_conn.pc.set_onconnectionstatechange(Some( - onconnectionstatechange_callback.as_ref().unchecked_ref(), - )); - onconnectionstatechange_callback.forget(); - - // Offer to receive 1 video track - cloned_engine_conn.pc.add_transceiver_with_str("video"); - - // Finally (but actually firstly!), to kick things off, we're going to - // generate our SDP, set it on our PeerConnection, and let the server - // know about our capabilities. - let cloned_engine_conn2 = cloned_engine_conn.clone(); - let create_offer_callback = Closure::::new(move |v: JsValue| { - let desc: web_sys::RtcSessionDescriptionInit = v.into(); - let _ = cloned_engine_conn2.pc.set_local_description(&desc); - console_log!("sent sdp_offer begin"); - let object: js_sys::Object = desc.into(); - console_log!("got offer object: {:?}", object); - /*cloned_engine_conn2 - .send(WebSocketMessages::SdpOffer { - offer: kittycad::types::RtcSessionDescription { - sdp: desc.sdp(), - type_: kittycad::types::RtcSdpType::Offer, - }, - }) - .expect("failed to send sdp offer");*/ - }); - let create_offer_catch = Closure::::new(move |v: JsValue| { - console_log!("Failed to create offer: {:?}", v); - }); - let _ = cloned_engine_conn - .pc - .create_offer() - .then(&create_offer_callback) - .catch(&create_offer_catch); - create_offer_callback.forget(); - create_offer_catch.forget(); - } - WebSocketResponses::SdpAnswer { answer } => { - if answer.type_ == kittycad::types::RtcSdpType::Unspecified { - console_log!("Received an unspecified rtc sdp answer, ignoring"); - } else if cloned_engine_conn.pc.signaling_state() - != web_sys::RtcSignalingState::Stable - { - // If the connection is stable, we shouldn't bother updating the - // SDP, since we have a stable connection to the backend. If we - // need to renegotiate, the whole PeerConnection needs to get - // tore down. - let mut desc = - web_sys::RtcSessionDescriptionInit::new(match answer.type_ { - kittycad::types::RtcSdpType::Offer => web_sys::RtcSdpType::Offer, - kittycad::types::RtcSdpType::Pranswer => { - web_sys::RtcSdpType::Pranswer - } - kittycad::types::RtcSdpType::Answer => web_sys::RtcSdpType::Answer, - kittycad::types::RtcSdpType::Rollback => { - web_sys::RtcSdpType::Rollback - } - kittycad::types::RtcSdpType::Unspecified => { - unreachable!( - "Unspecified RtcSdpType should have been handled above" - ) - } - }); - desc.sdp(answer.sdp.as_str()); - let _ = cloned_engine_conn.pc.set_remote_description(&desc); - } - } - WebSocketResponses::TrickleIce { candidate } => { - console_log!("got trickle ice candidate: {:?}", candidate); - // this.pc?.addIceCandidate(message.candidate as RTCIceCandidateInit) - /*let mut candidate_init = web_sys::RtcIceCandidateInit::new(candidate.candidate); - cloned_engine_conn - .pc - .add_ice_candidate_with_opt_rtc_ice_candidate_init(&candidate_init);*/ - todo!() - } - WebSocketResponses::Modeling { .. } => {} - WebSocketResponses::Export { .. } => {} - } - }); - // set message event handler on WebSocket - engine_conn - .ws - .set_onmessage(Some(onmessage_callback.as_ref().unchecked_ref())); - // forget the callback to keep it alive - onmessage_callback.forget(); - - Ok(engine_conn) - } - - fn close(&mut self) -> Result<(), JsValue> { - self.ready = false; - self.ws.close()?; - self.pc.close(); - self.lossy_data_channel.close(); - - Ok(()) - } - - fn ws_send(&mut self, msg: kittycad::types::WebSocketMessages) -> Result<(), JsValue> { - self.ws.send_with_str( - serde_json::to_string(&msg) - .map_err(|err| JsValue::from(err.to_string()))? - .as_str(), - )?; - - Ok(()) - } - - fn lossy_send(&mut self, msg: kittycad::types::WebSocketMessages) -> Result<(), JsValue> { - self.lossy_data_channel.send_with_str( - serde_json::to_string(&msg) - .map_err(|err| JsValue::from(err.to_string()))? - .as_str(), - )?; - - Ok(()) - } - - pub fn send_lossy_cmd( - &mut self, - id: uuid::Uuid, - source_range: crate::executor::SourceRange, - cmd: kittycad::types::ModelingCmd, - ) -> Result<(), KclError> { - self.lossy_send(WebSocketMessages::ModelingCmdReq { cmd, cmd_id: id }) - .map_err(|e| { - KclError::Engine(KclErrorDetails { - message: format!("Failed to send modeling command: {:?}", e), - source_ranges: vec![source_range], - }) - })?; - - Ok(()) - } - - pub fn send_modeling_cmd( - &mut self, - id: uuid::Uuid, - source_range: crate::executor::SourceRange, - cmd: kittycad::types::ModelingCmd, - ) -> Result<(), KclError> { - self.ws_send(WebSocketMessages::ModelingCmdReq { cmd, cmd_id: id }) - .map_err(|e| { - KclError::Engine(KclErrorDetails { - message: format!("Failed to send modeling command: {:?}", e), - source_ranges: vec![source_range], - }) - })?; - Ok(()) - } -} - -fn parse_message(msg: MessageEvent) -> Result { - if let Ok(abuf) = msg.data().dyn_into::() { - let array = js_sys::Uint8Array::new(&abuf); - Ok(serde_json::from_slice(&array.to_vec())?) - } else if let Ok(blob) = msg.data().dyn_into::() { - let (sender, receiver) = std::sync::mpsc::channel(); - gloo_file::callbacks::read_as_bytes(&blob.into(), move |res| { - sender.send(res).unwrap(); - }); - let value = receiver.recv()??; - Ok(serde_json::from_slice(&value)?) - } else if let Ok(txt) = msg.data().dyn_into::() { - console_log!("message event, received Text: {:?}", txt); - let s = txt - .as_string() - .ok_or_else(|| anyhow::anyhow!("Failed to convert JsString: {:?}", txt))?; - Ok(serde_json::from_str(&s)?) - } else { - console_log!("message event, received Unknown: {:?}", msg.data()); - anyhow::bail!("message event, received Unknown: {:?}", msg.data()); - } -}*/