cleanup code we are no longer using (#319)

Signed-off-by: Jess Frazelle <github@jessfraz.com>
This commit is contained in:
Jess Frazelle
2023-08-24 17:28:59 -07:00
committed by GitHub
parent de255acc59
commit 11658e2ff5
8 changed files with 3 additions and 1211 deletions

View File

@ -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,
}
}

View File

@ -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

View File

@ -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,

View File

@ -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 = <T extends SketchGroup | ExtrudeGroup>(
// { 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 = <T extends SketchGroup | ExtrudeGroup>(
// { 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<T extends SketchGroup | ExtrudeGroup>(
// 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
}

View File

@ -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

View File

@ -1249,7 +1249,6 @@ dependencies = [
"uuid",
"wasm-bindgen",
"wasm-bindgen-futures",
"web-sys",
]
[[package]]

View File

@ -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"]

View File

@ -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<EngineConnection, JsValue> {
// 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::<dyn FnMut()>::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::<dyn FnMut(_)>::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::<dyn FnMut(_)>::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::<dyn FnMut(_)>::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::<dyn FnMut(_)>::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::<dyn FnMut(_)>::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::<dyn FnMut(_)>::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::<dyn FnMut(_)>::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<WebSocketResponses> {
if let Ok(abuf) = msg.data().dyn_into::<js_sys::ArrayBuffer>() {
let array = js_sys::Uint8Array::new(&abuf);
Ok(serde_json::from_slice(&array.to_vec())?)
} else if let Ok(blob) = msg.data().dyn_into::<web_sys::Blob>() {
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::<js_sys::JsString>() {
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());
}
}*/