cleanup code we are no longer using (#319)
Signed-off-by: Jess Frazelle <github@jessfraz.com>
This commit is contained in:
@ -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,
|
||||
}
|
||||
}
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
}
|
@ -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
|
||||
|
1
src/wasm-lib/Cargo.lock
generated
1
src/wasm-lib/Cargo.lock
generated
@ -1249,7 +1249,6 @@ dependencies = [
|
||||
"uuid",
|
||||
"wasm-bindgen",
|
||||
"wasm-bindgen-futures",
|
||||
"web-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -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"]
|
||||
|
@ -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());
|
||||
}
|
||||
}*/
|
||||
|
Reference in New Issue
Block a user