Compare commits
2 Commits
v1.0.2
...
kurt-flang
Author | SHA1 | Date | |
---|---|---|---|
46bac7bb03 | |||
ab966423ac |
@ -1733,7 +1733,7 @@ profile003 = startProfile(sketch001, at = [206.63, -56.73])
|
||||
await page.waitForTimeout(600)
|
||||
})
|
||||
|
||||
const codeFromTangentialArc = ` |> tangentialArc(end = [-10.82, 144.95])`
|
||||
const codeFromTangentialArc = ` |> tangentialArc(endAbsolute = [39.49, 88.22])`
|
||||
await test.step('check that tangential tool does not snap to other profile starts', async () => {
|
||||
await toolbar.selectTangentialArc()
|
||||
await page.waitForTimeout(1000)
|
||||
@ -1755,7 +1755,7 @@ profile003 = startProfile(sketch001, at = [206.63, -56.73])
|
||||
// check pixel is now gray at tanArcLocation to verify code has executed
|
||||
await scene.expectPixelColor([26, 26, 26], tanArcLocation, 15)
|
||||
await editor.expectEditor.not.toContain(
|
||||
`tangentialArc(end = [-10.82, 144.95])`
|
||||
`tangentialArc(endAbsolute = [39.49, 88.22])`
|
||||
)
|
||||
})
|
||||
|
||||
@ -1955,7 +1955,7 @@ profile003 = startProfile(sketch001, at = [206.63, -56.73])
|
||||
|
||||
await endArcStartLine()
|
||||
await editor.expectEditor.toContain(
|
||||
`|> tangentialArc(end = [2.98, -7.52])`
|
||||
`|> tangentialArc(endAbsolute = [16.61, 4.14])`
|
||||
)
|
||||
|
||||
// Add a three-point arc segment
|
||||
@ -3181,7 +3181,7 @@ test.describe('Redirecting to home page and back to the original file should cle
|
||||
sketch001 = startSketchOn(XZ)
|
||||
profile001 = startProfile(sketch001, at = [0, 0])
|
||||
|> line(end = [191.39, 191.39])
|
||||
|> tangentialArc(end = [95.69, -95.7], tag = $seg01)
|
||||
|> tangentialArc(endAbsolute = [287.08, 95.69], tag = $seg01)
|
||||
|> angledLine(angle = tangentToEnd(seg01), length = 135.34)
|
||||
|> arc(interiorAbsolute = [191.39, -95.69], endAbsolute = [287.08, -95.69], tag = $seg02)
|
||||
|> angledLine(angle = tangentToEnd(seg02) + turns::HALF_TURN, length = 270.67)
|
||||
|
@ -375,22 +375,22 @@ test.describe(
|
||||
await expect(u.codeLocator).toHaveText(code)
|
||||
|
||||
await toolbar.selectTangentialArc()
|
||||
await page.waitForTimeout(200)
|
||||
await page.waitForTimeout(100)
|
||||
|
||||
// click to continue profile
|
||||
await page.mouse.click(813, 392)
|
||||
await page.waitForTimeout(300)
|
||||
await page.waitForTimeout(100)
|
||||
|
||||
await page.mouse.click(startXPx + PUR * 30, 500 - PUR * 20)
|
||||
|
||||
code += `
|
||||
|> tangentialArc(end = [184.31, 184.31])`
|
||||
|> tangentialArc(endAbsolute = [551.2, -62.01])`
|
||||
await expect(u.codeLocator).toHaveText(code)
|
||||
|
||||
// click tangential arc tool again to unequip it
|
||||
// it will be available directly in the toolbar since it was last equipped
|
||||
await toolbar.tangentialArcBtn.click()
|
||||
await page.waitForTimeout(1000)
|
||||
await page.waitForTimeout(100)
|
||||
|
||||
// screen shot should show the sketch
|
||||
await expect(page).toHaveScreenshot({
|
||||
@ -472,20 +472,20 @@ test.describe(
|
||||
await expect(u.codeLocator).toHaveText(code)
|
||||
|
||||
await toolbar.selectTangentialArc()
|
||||
await page.waitForTimeout(200)
|
||||
await page.waitForTimeout(100)
|
||||
|
||||
// click to continue profile
|
||||
await page.mouse.click(813, 392)
|
||||
await page.waitForTimeout(300)
|
||||
await page.waitForTimeout(100)
|
||||
|
||||
await page.mouse.click(startXPx + PUR * 30, 500 - PUR * 20)
|
||||
|
||||
code += `
|
||||
|> tangentialArc(end = [184.31, 184.31])`
|
||||
|> tangentialArc(endAbsolute = [551.2, -62.01])`
|
||||
await expect(u.codeLocator).toHaveText(code)
|
||||
|
||||
await toolbar.tangentialArcBtn.click()
|
||||
await page.waitForTimeout(1000)
|
||||
await page.waitForTimeout(100)
|
||||
|
||||
// screen shot should show the sketch
|
||||
await expect(page).toHaveScreenshot({
|
||||
|
Before Width: | Height: | Size: 56 KiB After Width: | Height: | Size: 57 KiB |
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 50 KiB |
Before Width: | Height: | Size: 56 KiB After Width: | Height: | Size: 57 KiB |
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 50 KiB |
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 52 KiB |
Before Width: | Height: | Size: 58 KiB After Width: | Height: | Size: 58 KiB |
@ -61,7 +61,7 @@ test.describe('Test network related behaviors', () => {
|
||||
})
|
||||
|
||||
// Expect the network to be down
|
||||
await expect(networkToggle).toContainText('Problem')
|
||||
await expect(networkToggle).toContainText('Network health (Offline)')
|
||||
|
||||
// Click the network widget
|
||||
await networkWidget.click()
|
||||
@ -156,7 +156,8 @@ test.describe('Test network related behaviors', () => {
|
||||
|
||||
// Expect the network to be down
|
||||
await networkToggle.hover()
|
||||
await expect(networkToggle).toContainText('Problem')
|
||||
|
||||
await expect(networkToggle).toContainText('Network health (Offline)')
|
||||
|
||||
// Ensure we are not in sketch mode
|
||||
await expect(
|
||||
|
@ -364,11 +364,6 @@ export async function getUtils(page: Page, test_?: typeof test) {
|
||||
)
|
||||
}
|
||||
|
||||
// Chrome devtools protocol session only works in Chromium
|
||||
const browserType = page.context().browser()?.browserType().name()
|
||||
const cdpSession =
|
||||
browserType !== 'chromium' ? null : await page.context().newCDPSession(page)
|
||||
|
||||
const util = {
|
||||
waitForAuthSkipAppStart: () => waitForAuthAndLsp(page),
|
||||
waitForPageLoad: () => waitForPageLoad(page),
|
||||
@ -489,15 +484,9 @@ export async function getUtils(page: Page, test_?: typeof test) {
|
||||
emulateNetworkConditions: async (
|
||||
networkOptions: Protocol.Network.emulateNetworkConditionsParameters
|
||||
) => {
|
||||
if (cdpSession === null) {
|
||||
// Use a fail safe if we can't simulate disconnect (on Safari)
|
||||
return page.evaluate('window.engineCommandManager.tearDown()')
|
||||
}
|
||||
|
||||
return cdpSession?.send(
|
||||
'Network.emulateNetworkConditions',
|
||||
networkOptions
|
||||
)
|
||||
return networkOptions.offline
|
||||
? page.evaluate('window.engineCommandManager.offline()')
|
||||
: page.evaluate('window.engineCommandManager.online()')
|
||||
},
|
||||
|
||||
toNormalizedCode(text: string) {
|
||||
|
@ -7,17 +7,13 @@
|
||||
// Import parameters
|
||||
import pipeInnerDiameter, pipeOuterDiameter, pipeLength from "parameters.kcl"
|
||||
|
||||
// Create a function to make the pipe. Export
|
||||
export fn pipe() {
|
||||
// Create the pipe base
|
||||
pipeBase = startSketchOn(XZ)
|
||||
|> circle(%, center = [0, 0], radius = pipeOuterDiameter / 2)
|
||||
|> extrude(%, length = pipeLength)
|
||||
// Create the pipe base
|
||||
pipeBase = startSketchOn(XZ)
|
||||
|> circle(%, center = [0, 0], radius = pipeOuterDiameter / 2)
|
||||
|> extrude(%, length = pipeLength)
|
||||
|
||||
// Extrude a hole through the length of the pipe
|
||||
pipe = startSketchOn(pipeBase, face = END)
|
||||
|> circle(center = [0, 0], radius = pipeInnerDiameter / 2)
|
||||
|> extrude(%, length = -pipeLength)
|
||||
|> appearance(color = "#a24ed0")
|
||||
return pipe
|
||||
}
|
||||
// Extrude a hole through the length of the pipe
|
||||
startSketchOn(pipeBase, face = END)
|
||||
|> circle(center = [0, 0], radius = pipeInnerDiameter / 2)
|
||||
|> extrude(%, length = -pipeLength)
|
||||
|> appearance(color = "#a24ed0")
|
||||
|
@ -7,38 +7,33 @@
|
||||
// Import parameters
|
||||
import pipeDiameter, mountingHoleDiameter, mountingHolePlacementDiameter, flangeDiameter, flangeTotalThickness, flangeBackHeight, flangeFrontHeight, flangeBaseThickness, flangeBackDiameter, flangeFrontDiameter from "parameters.kcl"
|
||||
|
||||
// Create a function to create the flange. We must create a function since we are using multiple flanges.
|
||||
export fn flange() {
|
||||
// Sketch the mounting hole pattern
|
||||
mountingHoles = startSketchOn(XY)
|
||||
|> circle(%, center = [0, mountingHolePlacementDiameter / 2], radius = mountingHoleDiameter / 2)
|
||||
|> patternCircular2d(
|
||||
%,
|
||||
instances = 4,
|
||||
center = [0, 0],
|
||||
arcDegrees = 360,
|
||||
rotateDuplicates = false,
|
||||
)
|
||||
// Sketch the mounting hole pattern
|
||||
mountingHoles = startSketchOn(XY)
|
||||
|> circle(%, center = [0, mountingHolePlacementDiameter / 2], radius = mountingHoleDiameter / 2)
|
||||
|> patternCircular2d(
|
||||
%,
|
||||
instances = 4,
|
||||
center = [0, 0],
|
||||
arcDegrees = 360,
|
||||
rotateDuplicates = false,
|
||||
)
|
||||
|
||||
// Create the flange base
|
||||
flangeBase = startSketchOn(XY)
|
||||
|> circle(%, center = [0, 0], radius = flangeDiameter / 2)
|
||||
|> subtract2d(tool = mountingHoles)
|
||||
|> extrude(%, length = flangeBaseThickness)
|
||||
// Create the flange base
|
||||
flangeBase = startSketchOn(XY)
|
||||
|> circle(%, center = [0, 0], radius = flangeDiameter / 2)
|
||||
|> subtract2d(tool = mountingHoles)
|
||||
|> extrude(%, length = flangeBaseThickness)
|
||||
|
||||
// Create both the raised portions on the front and back of the flange base
|
||||
flangeBack = startSketchOn(flangeBase, face = START)
|
||||
|> circle(%, center = [0, 0], radius = flangeBackDiameter / 2)
|
||||
|> extrude(%, length = flangeBackHeight)
|
||||
flangeFront = startSketchOn(flangeBase, face = END)
|
||||
|> circle(%, center = [0, 0], radius = flangeFrontDiameter / 2)
|
||||
|> extrude(%, length = flangeFrontHeight)
|
||||
// Create both the raised portions on the front and back of the flange base
|
||||
flangeBack = startSketchOn(flangeBase, face = START)
|
||||
|> circle(%, center = [0, 0], radius = flangeBackDiameter / 2)
|
||||
|> extrude(%, length = flangeBackHeight)
|
||||
flangeFront = startSketchOn(flangeBase, face = END)
|
||||
|> circle(%, center = [0, 0], radius = flangeFrontDiameter / 2)
|
||||
|> extrude(%, length = flangeFrontHeight)
|
||||
|
||||
// Create the circular cut in the center for the pipe
|
||||
pipeCut = startSketchOn(flangeFront, face = END)
|
||||
|> circle(%, center = [0, 0], radius = pipeDiameter / 2)
|
||||
|> extrude(%, length = -flangeTotalThickness)
|
||||
|> appearance(%, color = "#bab0b0")
|
||||
|
||||
return pipeCut
|
||||
}
|
||||
// Create the circular cut in the center for the pipe
|
||||
startSketchOn(flangeFront, face = END)
|
||||
|> circle(%, center = [0, 0], radius = pipeDiameter / 2)
|
||||
|> extrude(%, length = -flangeTotalThickness)
|
||||
|> appearance(%, color = "#bab0b0")
|
||||
|
@ -7,33 +7,28 @@
|
||||
// Import parameters
|
||||
import boltDiameter, boltLength, boltHeadLength, boltHeadDiameter, boltHexDrive, boltHexFlatLength, boltThreadLength from "parameters.kcl"
|
||||
|
||||
// Create a function to make a the bolt
|
||||
export fn bolt() {
|
||||
// Create the head of the cap screw
|
||||
boltHead = startSketchOn(XZ)
|
||||
|> circle(center = [0, 0], radius = boltHeadDiameter / 2, tag = $topEdge)
|
||||
|> extrude(length = -boltHeadLength)
|
||||
|> fillet(radius = 0.020, tags = [topEdge, getOppositeEdge(topEdge)])
|
||||
// Create the head of the cap screw
|
||||
boltHead = startSketchOn(XZ)
|
||||
|> circle(center = [0, 0], radius = boltHeadDiameter / 2, tag = $topEdge)
|
||||
|> extrude(length = -boltHeadLength)
|
||||
|> fillet(radius = 0.020, tags = [topEdge, getOppositeEdge(topEdge)])
|
||||
|
||||
// Define the sketch of the hex pattern on the screw head and extrude into the head
|
||||
hexPatternSketch = startSketchOn(boltHead, face = START)
|
||||
|> startProfile(at = [
|
||||
boltHexDrive / 2,
|
||||
boltHexFlatLength / 2
|
||||
])
|
||||
|> angledLine(angle = 270, length = boltHexFlatLength)
|
||||
|> angledLine(angle = 210, length = boltHexFlatLength)
|
||||
|> angledLine(angle = 150, length = boltHexFlatLength)
|
||||
|> angledLine(angle = 90, length = boltHexFlatLength)
|
||||
|> angledLine(angle = 30, length = boltHexFlatLength)
|
||||
|> close()
|
||||
|> extrude(length = -boltHeadLength * 0.75)
|
||||
// Define the sketch of the hex pattern on the screw head and extrude into the head
|
||||
hexPatternSketch = startSketchOn(boltHead, face = START)
|
||||
|> startProfile(at = [
|
||||
boltHexDrive / 2,
|
||||
boltHexFlatLength / 2
|
||||
])
|
||||
|> angledLine(angle = 270, length = boltHexFlatLength)
|
||||
|> angledLine(angle = 210, length = boltHexFlatLength)
|
||||
|> angledLine(angle = 150, length = boltHexFlatLength)
|
||||
|> angledLine(angle = 90, length = boltHexFlatLength)
|
||||
|> angledLine(angle = 30, length = boltHexFlatLength)
|
||||
|> close()
|
||||
|> extrude(length = -boltHeadLength * 0.75)
|
||||
|
||||
// create the body of the bolt
|
||||
boltBody = startSketchOn(boltHead, face = END)
|
||||
|> circle(center = [0, 0], radius = boltDiameter / 2, tag = $filletEdge)
|
||||
|> extrude(length = boltLength)
|
||||
|> appearance(color = "#4dd043", metalness = 90, roughness = 90)
|
||||
|
||||
return boltBody
|
||||
}
|
||||
// create the body of the bolt
|
||||
startSketchOn(boltHead, face = END)
|
||||
|> circle(center = [0, 0], radius = boltDiameter / 2, tag = $filletEdge)
|
||||
|> extrude(length = boltLength)
|
||||
|> appearance(color = "#4dd043", metalness = 90, roughness = 90)
|
||||
|
@ -7,27 +7,22 @@
|
||||
// Import parameters
|
||||
import hexNutDiameter, hexNutFlatToFlat, hexNutThickness, hexNutFlatLength from "parameters.kcl"
|
||||
|
||||
// Create a function to make the hex nut. Must be a function since multiple hex nuts are used
|
||||
export fn hexNut() {
|
||||
// Create the base of the hex nut
|
||||
hexNutBase = startSketchOn(XY)
|
||||
|> startProfile(at = [
|
||||
hexNutFlatToFlat / 2,
|
||||
hexNutFlatLength / 2
|
||||
])
|
||||
|> angledLine(angle = 270, length = hexNutFlatLength)
|
||||
|> angledLine(angle = 210, length = hexNutFlatLength)
|
||||
|> angledLine(angle = 150, length = hexNutFlatLength)
|
||||
|> angledLine(angle = 90, length = hexNutFlatLength)
|
||||
|> angledLine(angle = 30, length = hexNutFlatLength)
|
||||
|> close()
|
||||
|> extrude(length = hexNutThickness)
|
||||
// Create the base of the hex nut
|
||||
hexNutBase = startSketchOn(XY)
|
||||
|> startProfile(at = [
|
||||
hexNutFlatToFlat / 2,
|
||||
hexNutFlatLength / 2
|
||||
])
|
||||
|> angledLine(angle = 270, length = hexNutFlatLength)
|
||||
|> angledLine(angle = 210, length = hexNutFlatLength)
|
||||
|> angledLine(angle = 150, length = hexNutFlatLength)
|
||||
|> angledLine(angle = 90, length = hexNutFlatLength)
|
||||
|> angledLine(angle = 30, length = hexNutFlatLength)
|
||||
|> close()
|
||||
|> extrude(length = hexNutThickness)
|
||||
|
||||
// Create the hole in the center of the hex nut
|
||||
hexNut = startSketchOn(hexNutBase, face = END)
|
||||
|> circle(center = [0, 0], radius = hexNutDiameter / 2)
|
||||
|> extrude(%, length = -hexNutThickness)
|
||||
|> appearance(%, color = "#4edfd5")
|
||||
|
||||
return hexNut
|
||||
}
|
||||
// Create the hole in the center of the hex nut
|
||||
startSketchOn(hexNutBase, face = END)
|
||||
|> circle(center = [0, 0], radius = hexNutDiameter / 2)
|
||||
|> extrude(%, length = -hexNutThickness)
|
||||
|> appearance(%, color = "#4edfd5")
|
||||
|
@ -7,18 +7,13 @@
|
||||
// Import parameters
|
||||
import washerInnerDia, washerOuterDia, washerThickness from "parameters.kcl"
|
||||
|
||||
// Create a function to make the washer. Must be a function since multiple washers are used.
|
||||
export fn washer() {
|
||||
// Create the base of the washer
|
||||
washerBase = startSketchOn(XY)
|
||||
|> circle(center = [0, 0], radius = washerOuterDia / 2)
|
||||
|> extrude(length = washerThickness)
|
||||
// Create the base of the washer
|
||||
washerBase = startSketchOn(XY)
|
||||
|> circle(center = [0, 0], radius = washerOuterDia / 2)
|
||||
|> extrude(length = washerThickness)
|
||||
|
||||
// Extrude a hole through the washer
|
||||
washer = startSketchOn(washerBase, face = END)
|
||||
|> circle(center = [0, 0], radius = washerInnerDia / 2)
|
||||
|> extrude(%, length = -washerThickness)
|
||||
|> appearance(%, color = "#ee4f4f")
|
||||
|
||||
return washer
|
||||
}
|
||||
// Extrude a hole through the washer
|
||||
washer = startSketchOn(washerBase, face = END)
|
||||
|> circle(center = [0, 0], radius = washerInnerDia / 2)
|
||||
|> extrude(%, length = -washerThickness)
|
||||
|> appearance(%, color = "#ee4f4f")
|
||||
|
@ -9,16 +9,19 @@ import * from "parameters.kcl"
|
||||
|
||||
// Import parts
|
||||
import "9472k188-gasket.kcl" as gasket
|
||||
import flange from "68095k348-flange.kcl"
|
||||
import washer from "98017a257-washer.kcl"
|
||||
import bolt from "91251a404-bolt.kcl"
|
||||
import hexNut from "95479a127-hex-nut.kcl"
|
||||
import pipe from "1120t74-pipe.kcl"
|
||||
import "68095k348-flange.kcl" as flange
|
||||
import "98017a257-washer.kcl" as washer
|
||||
import "91251a404-bolt.kcl" as bolt
|
||||
import "95479a127-hex-nut.kcl" as hexNut
|
||||
import "1120t74-pipe.kcl" as pipe
|
||||
|
||||
// Place flanges
|
||||
flange()
|
||||
flange()
|
||||
|> rotate(axis = [0, 1, 0], angle = 180)
|
||||
// Place flange clone
|
||||
rotate(
|
||||
clone(flange),
|
||||
roll = 180,
|
||||
pitch = 0,
|
||||
yaw = 0,
|
||||
)
|
||||
|> translate(x = 0, y = 0, z = flangeBackHeight * 2 + gasketThickness)
|
||||
|
||||
// Place gasket between the flanges
|
||||
@ -26,7 +29,7 @@ gasket
|
||||
|> translate(x = 0, y = 0, z = -flangeBackHeight - gasketThickness)
|
||||
|
||||
// Place eight washers (four front, four back)
|
||||
washer()
|
||||
washer
|
||||
|> translate(x = mountingHolePlacementDiameter / 2, y = 0, z = flangeBaseThickness)
|
||||
|> patternCircular3d(
|
||||
%,
|
||||
@ -44,7 +47,8 @@ washer()
|
||||
)
|
||||
|
||||
// Place four bolts
|
||||
bolt()
|
||||
|
||||
bolt
|
||||
|> translate(x = mountingHolePlacementDiameter / 2, y = 0, z = flangeBaseThickness + washerThickness)
|
||||
|> rotate(roll = 90, pitch = 0, yaw = 0)
|
||||
|> patternCircular3d(
|
||||
@ -57,7 +61,7 @@ bolt()
|
||||
)
|
||||
|
||||
// Place four hex nuts
|
||||
hexNut()
|
||||
hexNut
|
||||
|> translate(x = mountingHolePlacementDiameter / 2, y = 0, z = -(flangeBackHeight * 2 + gasketThickness + flangeBaseThickness + washerThickness + hexNutThickness))
|
||||
|> patternCircular3d(
|
||||
%,
|
||||
@ -69,9 +73,8 @@ hexNut()
|
||||
)
|
||||
|
||||
// Place both pieces of pipe
|
||||
pipe()
|
||||
|> rotate(
|
||||
%,
|
||||
rotate(
|
||||
pipe,
|
||||
roll = -90,
|
||||
pitch = 0,
|
||||
yaw = 0,
|
||||
@ -83,16 +86,13 @@ pipe()
|
||||
z = flangeBaseThickness + flangeFrontHeight - 0.5,
|
||||
global = true,
|
||||
)
|
||||
|
||||
pipe()
|
||||
|> rotate(
|
||||
%,
|
||||
roll = 90,
|
||||
rotate(
|
||||
clone(pipe),
|
||||
roll = 180,
|
||||
pitch = 0,
|
||||
yaw = 0,
|
||||
)
|
||||
|> translate(
|
||||
%,
|
||||
x = 0,
|
||||
y = 0,
|
||||
z = -(flangeBackHeight * 2 + gasketThickness + flangeBaseThickness + flangeFrontHeight - 0.5),
|
||||
|
Before Width: | Height: | Size: 83 KiB After Width: | Height: | Size: 83 KiB |
Before Width: | Height: | Size: 78 KiB After Width: | Height: | Size: 75 KiB |
@ -652,19 +652,19 @@ flowchart LR
|
||||
84 --- 144
|
||||
84 --- 237
|
||||
86 --- 168
|
||||
86 x--> 188
|
||||
86 x--> 189
|
||||
86 --- 212
|
||||
86 --- 256
|
||||
88 --- 169
|
||||
88 x--> 188
|
||||
88 x--> 189
|
||||
88 --- 213
|
||||
88 --- 257
|
||||
90 --- 167
|
||||
90 x--> 188
|
||||
90 x--> 189
|
||||
90 --- 214
|
||||
90 --- 258
|
||||
92 --- 170
|
||||
92 x--> 188
|
||||
92 x--> 189
|
||||
92 --- 215
|
||||
92 --- 259
|
||||
119 --- 133
|
||||
@ -946,10 +946,10 @@ flowchart LR
|
||||
218 <--x 186
|
||||
219 <--x 186
|
||||
194 <--x 187
|
||||
212 <--x 189
|
||||
213 <--x 189
|
||||
214 <--x 189
|
||||
215 <--x 189
|
||||
212 <--x 188
|
||||
213 <--x 188
|
||||
214 <--x 188
|
||||
215 <--x 188
|
||||
220 <--x 268
|
||||
223 <--x 267
|
||||
```
|
||||
|
Before Width: | Height: | Size: 83 KiB After Width: | Height: | Size: 83 KiB |
@ -87,20 +87,20 @@ flowchart LR
|
||||
27 --- 4
|
||||
8 --- 20
|
||||
8 x--> 25
|
||||
8 --- 29
|
||||
8 --- 35
|
||||
8 --- 30
|
||||
8 --- 36
|
||||
9 --- 21
|
||||
9 x--> 25
|
||||
9 --- 33
|
||||
9 --- 39
|
||||
10 --- 22
|
||||
10 x--> 25
|
||||
10 --- 30
|
||||
10 --- 36
|
||||
10 --- 31
|
||||
10 --- 37
|
||||
11 --- 23
|
||||
11 x--> 25
|
||||
11 --- 31
|
||||
11 --- 37
|
||||
11 --- 29
|
||||
11 --- 35
|
||||
12 --- 24
|
||||
12 x--> 25
|
||||
12 --- 32
|
||||
@ -132,18 +132,18 @@ flowchart LR
|
||||
18 --- 34
|
||||
19 --- 28
|
||||
19 --- 34
|
||||
20 --- 29
|
||||
20 --- 35
|
||||
36 <--x 20
|
||||
20 --- 30
|
||||
20 --- 36
|
||||
37 <--x 20
|
||||
21 --- 33
|
||||
35 <--x 21
|
||||
21 --- 39
|
||||
22 --- 30
|
||||
22 --- 36
|
||||
37 <--x 22
|
||||
23 --- 31
|
||||
23 --- 37
|
||||
38 <--x 23
|
||||
22 --- 31
|
||||
22 --- 37
|
||||
38 <--x 22
|
||||
23 --- 29
|
||||
23 --- 35
|
||||
36 <--x 23
|
||||
24 --- 32
|
||||
24 --- 38
|
||||
39 <--x 24
|
||||
|
@ -366,114 +366,114 @@ flowchart LR
|
||||
11 ---- 74
|
||||
26 --- 75
|
||||
26 x--> 108
|
||||
26 --- 130
|
||||
26 --- 162
|
||||
26 --- 114
|
||||
26 --- 146
|
||||
27 --- 76
|
||||
27 x--> 108
|
||||
27 --- 116
|
||||
27 --- 148
|
||||
27 --- 139
|
||||
27 --- 171
|
||||
28 --- 77
|
||||
28 x--> 108
|
||||
28 --- 139
|
||||
28 --- 171
|
||||
28 --- 135
|
||||
28 --- 167
|
||||
29 --- 78
|
||||
29 x--> 108
|
||||
29 --- 135
|
||||
29 --- 167
|
||||
29 --- 133
|
||||
29 --- 165
|
||||
30 --- 79
|
||||
30 x--> 108
|
||||
30 --- 128
|
||||
30 --- 160
|
||||
30 --- 121
|
||||
30 --- 153
|
||||
31 --- 80
|
||||
31 x--> 108
|
||||
31 --- 123
|
||||
31 --- 155
|
||||
31 --- 115
|
||||
31 --- 147
|
||||
32 --- 81
|
||||
32 x--> 108
|
||||
32 --- 127
|
||||
32 --- 159
|
||||
32 --- 129
|
||||
32 --- 161
|
||||
33 --- 82
|
||||
33 x--> 108
|
||||
33 --- 132
|
||||
33 --- 164
|
||||
33 --- 131
|
||||
33 --- 163
|
||||
34 --- 83
|
||||
34 x--> 108
|
||||
34 --- 133
|
||||
34 --- 165
|
||||
34 --- 138
|
||||
34 --- 170
|
||||
35 --- 84
|
||||
35 x--> 108
|
||||
35 --- 121
|
||||
35 --- 153
|
||||
35 --- 119
|
||||
35 --- 151
|
||||
36 --- 85
|
||||
36 x--> 108
|
||||
36 --- 137
|
||||
36 --- 169
|
||||
36 --- 125
|
||||
36 --- 157
|
||||
37 --- 86
|
||||
37 x--> 108
|
||||
37 --- 115
|
||||
37 --- 147
|
||||
37 --- 117
|
||||
37 --- 149
|
||||
38 --- 87
|
||||
38 x--> 108
|
||||
38 --- 120
|
||||
38 --- 152
|
||||
38 --- 122
|
||||
38 --- 154
|
||||
39 --- 88
|
||||
39 x--> 108
|
||||
39 --- 124
|
||||
39 --- 156
|
||||
39 --- 113
|
||||
39 --- 145
|
||||
40 --- 89
|
||||
40 x--> 108
|
||||
40 --- 134
|
||||
40 --- 166
|
||||
40 --- 124
|
||||
40 --- 156
|
||||
41 --- 90
|
||||
41 x--> 108
|
||||
41 --- 136
|
||||
41 --- 168
|
||||
41 --- 134
|
||||
41 --- 166
|
||||
42 --- 91
|
||||
42 x--> 108
|
||||
42 --- 122
|
||||
42 --- 154
|
||||
42 --- 132
|
||||
42 --- 164
|
||||
43 --- 92
|
||||
43 x--> 108
|
||||
43 --- 114
|
||||
43 --- 146
|
||||
43 --- 120
|
||||
43 --- 152
|
||||
44 --- 93
|
||||
44 x--> 108
|
||||
44 --- 113
|
||||
44 --- 145
|
||||
44 --- 118
|
||||
44 --- 150
|
||||
45 --- 94
|
||||
45 x--> 108
|
||||
45 --- 131
|
||||
45 --- 163
|
||||
45 --- 137
|
||||
45 --- 169
|
||||
46 --- 95
|
||||
46 x--> 108
|
||||
46 --- 117
|
||||
46 --- 149
|
||||
46 --- 130
|
||||
46 --- 162
|
||||
47 --- 96
|
||||
47 x--> 108
|
||||
47 --- 125
|
||||
47 --- 157
|
||||
47 --- 126
|
||||
47 --- 158
|
||||
48 --- 97
|
||||
48 x--> 108
|
||||
48 --- 119
|
||||
48 --- 151
|
||||
48 --- 128
|
||||
48 --- 160
|
||||
49 --- 98
|
||||
49 x--> 108
|
||||
49 --- 126
|
||||
49 --- 158
|
||||
49 --- 127
|
||||
49 --- 159
|
||||
50 --- 99
|
||||
50 x--> 108
|
||||
50 --- 118
|
||||
50 --- 150
|
||||
50 --- 136
|
||||
50 --- 168
|
||||
51 --- 100
|
||||
51 x--> 108
|
||||
51 --- 129
|
||||
51 --- 161
|
||||
51 --- 116
|
||||
51 --- 148
|
||||
52 --- 101
|
||||
52 x--> 108
|
||||
52 --- 138
|
||||
52 --- 170
|
||||
52 --- 123
|
||||
52 --- 155
|
||||
61 --- 102
|
||||
61 x--> 110
|
||||
61 x--> 109
|
||||
61 --- 140
|
||||
61 --- 172
|
||||
63 --- 103
|
||||
@ -594,87 +594,87 @@ flowchart LR
|
||||
74 --- 174
|
||||
74 --- 175
|
||||
74 --- 176
|
||||
75 --- 130
|
||||
75 --- 162
|
||||
163 <--x 75
|
||||
76 --- 116
|
||||
76 --- 148
|
||||
149 <--x 76
|
||||
77 --- 139
|
||||
145 <--x 77
|
||||
77 --- 171
|
||||
78 --- 135
|
||||
78 --- 167
|
||||
168 <--x 78
|
||||
79 --- 128
|
||||
79 --- 160
|
||||
161 <--x 79
|
||||
80 --- 123
|
||||
80 --- 155
|
||||
156 <--x 80
|
||||
81 --- 127
|
||||
81 --- 159
|
||||
160 <--x 81
|
||||
82 --- 132
|
||||
82 --- 164
|
||||
165 <--x 82
|
||||
83 --- 133
|
||||
83 --- 165
|
||||
166 <--x 83
|
||||
84 --- 121
|
||||
84 --- 153
|
||||
154 <--x 84
|
||||
85 --- 137
|
||||
85 --- 169
|
||||
170 <--x 85
|
||||
86 --- 115
|
||||
86 --- 147
|
||||
148 <--x 86
|
||||
87 --- 120
|
||||
87 --- 152
|
||||
153 <--x 87
|
||||
88 --- 124
|
||||
88 --- 156
|
||||
157 <--x 88
|
||||
89 --- 134
|
||||
89 --- 166
|
||||
167 <--x 89
|
||||
90 --- 136
|
||||
90 --- 168
|
||||
169 <--x 90
|
||||
91 --- 122
|
||||
91 --- 154
|
||||
155 <--x 91
|
||||
92 --- 114
|
||||
92 --- 146
|
||||
147 <--x 92
|
||||
93 --- 113
|
||||
93 --- 145
|
||||
146 <--x 93
|
||||
94 --- 131
|
||||
94 --- 163
|
||||
164 <--x 94
|
||||
95 --- 117
|
||||
95 --- 149
|
||||
150 <--x 95
|
||||
96 --- 125
|
||||
96 --- 157
|
||||
158 <--x 96
|
||||
97 --- 119
|
||||
97 --- 151
|
||||
152 <--x 97
|
||||
98 --- 126
|
||||
98 --- 158
|
||||
159 <--x 98
|
||||
99 --- 118
|
||||
99 --- 150
|
||||
151 <--x 99
|
||||
100 --- 129
|
||||
100 --- 161
|
||||
162 <--x 100
|
||||
101 --- 138
|
||||
101 --- 170
|
||||
171 <--x 101
|
||||
75 --- 114
|
||||
75 --- 146
|
||||
147 <--x 75
|
||||
76 --- 139
|
||||
145 <--x 76
|
||||
76 --- 171
|
||||
77 --- 135
|
||||
77 --- 167
|
||||
168 <--x 77
|
||||
78 --- 133
|
||||
78 --- 165
|
||||
166 <--x 78
|
||||
79 --- 121
|
||||
79 --- 153
|
||||
154 <--x 79
|
||||
80 --- 115
|
||||
80 --- 147
|
||||
148 <--x 80
|
||||
81 --- 129
|
||||
81 --- 161
|
||||
162 <--x 81
|
||||
82 --- 131
|
||||
82 --- 163
|
||||
164 <--x 82
|
||||
83 --- 138
|
||||
83 --- 170
|
||||
171 <--x 83
|
||||
84 --- 119
|
||||
84 --- 151
|
||||
152 <--x 84
|
||||
85 --- 125
|
||||
85 --- 157
|
||||
158 <--x 85
|
||||
86 --- 117
|
||||
86 --- 149
|
||||
150 <--x 86
|
||||
87 --- 122
|
||||
87 --- 154
|
||||
155 <--x 87
|
||||
88 --- 113
|
||||
88 --- 145
|
||||
146 <--x 88
|
||||
89 --- 124
|
||||
89 --- 156
|
||||
157 <--x 89
|
||||
90 --- 134
|
||||
90 --- 166
|
||||
167 <--x 90
|
||||
91 --- 132
|
||||
91 --- 164
|
||||
165 <--x 91
|
||||
92 --- 120
|
||||
92 --- 152
|
||||
153 <--x 92
|
||||
93 --- 118
|
||||
93 --- 150
|
||||
151 <--x 93
|
||||
94 --- 137
|
||||
94 --- 169
|
||||
170 <--x 94
|
||||
95 --- 130
|
||||
95 --- 162
|
||||
163 <--x 95
|
||||
96 --- 126
|
||||
96 --- 158
|
||||
159 <--x 96
|
||||
97 --- 128
|
||||
97 --- 160
|
||||
161 <--x 97
|
||||
98 --- 127
|
||||
98 --- 159
|
||||
160 <--x 98
|
||||
99 --- 136
|
||||
99 --- 168
|
||||
169 <--x 99
|
||||
100 --- 116
|
||||
100 --- 148
|
||||
149 <--x 100
|
||||
101 --- 123
|
||||
101 --- 155
|
||||
156 <--x 101
|
||||
102 --- 140
|
||||
102 --- 172
|
||||
103 --- 144
|
||||
@ -689,7 +689,7 @@ flowchart LR
|
||||
106 --- 141
|
||||
106 --- 173
|
||||
174 <--x 106
|
||||
140 <--x 109
|
||||
140 <--x 110
|
||||
141 <--x 111
|
||||
142 <--x 111
|
||||
143 <--x 111
|
||||
|
@ -582,48 +582,48 @@ flowchart LR
|
||||
46 --- 226
|
||||
72 --- 112
|
||||
72 x--> 151
|
||||
72 --- 167
|
||||
72 --- 201
|
||||
72 --- 163
|
||||
72 --- 197
|
||||
73 --- 113
|
||||
73 x--> 151
|
||||
73 --- 169
|
||||
73 --- 203
|
||||
73 --- 164
|
||||
73 --- 198
|
||||
74 --- 114
|
||||
74 x--> 151
|
||||
74 --- 168
|
||||
74 --- 202
|
||||
75 --- 115
|
||||
75 x--> 151
|
||||
75 --- 166
|
||||
75 --- 200
|
||||
75 --- 165
|
||||
75 --- 199
|
||||
76 --- 116
|
||||
76 x--> 151
|
||||
76 --- 165
|
||||
76 --- 199
|
||||
76 --- 162
|
||||
76 --- 196
|
||||
77 --- 117
|
||||
77 x--> 151
|
||||
77 --- 161
|
||||
77 --- 195
|
||||
78 --- 118
|
||||
78 x--> 151
|
||||
78 --- 162
|
||||
78 --- 196
|
||||
78 --- 167
|
||||
78 --- 201
|
||||
79 --- 119
|
||||
79 x--> 151
|
||||
79 --- 163
|
||||
79 --- 197
|
||||
79 --- 170
|
||||
79 --- 204
|
||||
80 --- 120
|
||||
80 x--> 151
|
||||
80 --- 170
|
||||
80 --- 204
|
||||
80 --- 160
|
||||
80 --- 194
|
||||
81 --- 121
|
||||
81 x--> 151
|
||||
81 --- 160
|
||||
81 --- 194
|
||||
81 --- 169
|
||||
81 --- 203
|
||||
82 --- 122
|
||||
82 x--> 151
|
||||
82 --- 164
|
||||
82 --- 198
|
||||
82 --- 166
|
||||
82 --- 200
|
||||
84 --- 123
|
||||
84 x--> 145
|
||||
84 --- 171
|
||||
@ -756,39 +756,39 @@ flowchart LR
|
||||
109 --- 107
|
||||
111 --- 159
|
||||
111 --- 193
|
||||
112 --- 167
|
||||
112 --- 201
|
||||
202 <--x 112
|
||||
113 --- 169
|
||||
113 --- 203
|
||||
204 <--x 113
|
||||
112 --- 163
|
||||
112 --- 197
|
||||
198 <--x 112
|
||||
113 --- 164
|
||||
113 --- 198
|
||||
199 <--x 113
|
||||
114 --- 168
|
||||
114 --- 202
|
||||
203 <--x 114
|
||||
115 --- 166
|
||||
115 --- 200
|
||||
201 <--x 115
|
||||
116 --- 165
|
||||
116 --- 199
|
||||
200 <--x 116
|
||||
115 --- 165
|
||||
115 --- 199
|
||||
200 <--x 115
|
||||
116 --- 162
|
||||
116 --- 196
|
||||
197 <--x 116
|
||||
117 --- 161
|
||||
117 --- 195
|
||||
196 <--x 117
|
||||
118 --- 162
|
||||
118 --- 196
|
||||
197 <--x 118
|
||||
119 --- 163
|
||||
119 --- 197
|
||||
198 <--x 119
|
||||
120 --- 170
|
||||
194 <--x 120
|
||||
120 --- 204
|
||||
121 --- 160
|
||||
121 --- 194
|
||||
195 <--x 121
|
||||
122 --- 164
|
||||
122 --- 198
|
||||
199 <--x 122
|
||||
118 --- 167
|
||||
118 --- 201
|
||||
202 <--x 118
|
||||
119 --- 170
|
||||
194 <--x 119
|
||||
119 --- 204
|
||||
120 --- 160
|
||||
120 --- 194
|
||||
195 <--x 120
|
||||
121 --- 169
|
||||
121 --- 203
|
||||
204 <--x 121
|
||||
122 --- 166
|
||||
122 --- 200
|
||||
201 <--x 122
|
||||
123 --- 171
|
||||
123 --- 205
|
||||
124 --- 186
|
||||
|
@ -177,72 +177,72 @@ flowchart LR
|
||||
2 ---- 34
|
||||
17 --- 35
|
||||
17 x--> 52
|
||||
17 --- 58
|
||||
17 --- 75
|
||||
17 --- 67
|
||||
17 --- 84
|
||||
18 --- 36
|
||||
18 x--> 52
|
||||
18 --- 66
|
||||
18 --- 83
|
||||
18 --- 65
|
||||
18 --- 82
|
||||
19 --- 37
|
||||
19 x--> 52
|
||||
19 --- 60
|
||||
19 --- 77
|
||||
19 --- 55
|
||||
19 --- 72
|
||||
20 --- 38
|
||||
20 x--> 52
|
||||
20 --- 61
|
||||
20 --- 78
|
||||
21 --- 39
|
||||
21 x--> 52
|
||||
21 --- 67
|
||||
21 --- 84
|
||||
21 --- 69
|
||||
21 --- 86
|
||||
22 --- 40
|
||||
22 x--> 52
|
||||
22 --- 63
|
||||
22 --- 80
|
||||
23 --- 41
|
||||
23 x--> 52
|
||||
23 --- 56
|
||||
23 --- 73
|
||||
23 --- 60
|
||||
23 --- 77
|
||||
24 --- 42
|
||||
24 x--> 52
|
||||
24 --- 54
|
||||
24 --- 71
|
||||
25 --- 43
|
||||
25 x--> 52
|
||||
25 --- 70
|
||||
25 --- 87
|
||||
25 --- 66
|
||||
25 --- 83
|
||||
26 --- 44
|
||||
26 x--> 52
|
||||
26 --- 68
|
||||
26 --- 85
|
||||
26 --- 57
|
||||
26 --- 74
|
||||
27 --- 45
|
||||
27 x--> 52
|
||||
27 --- 65
|
||||
27 --- 82
|
||||
27 --- 64
|
||||
27 --- 81
|
||||
28 --- 46
|
||||
28 x--> 52
|
||||
28 --- 62
|
||||
28 --- 79
|
||||
28 --- 58
|
||||
28 --- 75
|
||||
29 --- 47
|
||||
29 x--> 52
|
||||
29 --- 57
|
||||
29 --- 74
|
||||
29 --- 59
|
||||
29 --- 76
|
||||
30 --- 48
|
||||
30 x--> 52
|
||||
30 --- 55
|
||||
30 --- 72
|
||||
30 --- 56
|
||||
30 --- 73
|
||||
31 --- 49
|
||||
31 x--> 52
|
||||
31 --- 64
|
||||
31 --- 81
|
||||
31 --- 62
|
||||
31 --- 79
|
||||
32 --- 50
|
||||
32 x--> 52
|
||||
32 --- 69
|
||||
32 --- 86
|
||||
32 --- 70
|
||||
32 --- 87
|
||||
33 --- 51
|
||||
33 x--> 52
|
||||
33 --- 59
|
||||
33 --- 76
|
||||
33 --- 68
|
||||
33 --- 85
|
||||
34 --- 35
|
||||
34 --- 36
|
||||
34 --- 37
|
||||
@ -296,57 +296,57 @@ flowchart LR
|
||||
34 --- 85
|
||||
34 --- 86
|
||||
34 --- 87
|
||||
35 --- 58
|
||||
74 <--x 35
|
||||
35 --- 75
|
||||
36 --- 66
|
||||
82 <--x 36
|
||||
36 --- 83
|
||||
37 --- 60
|
||||
76 <--x 37
|
||||
37 --- 77
|
||||
35 --- 67
|
||||
83 <--x 35
|
||||
35 --- 84
|
||||
36 --- 65
|
||||
81 <--x 36
|
||||
36 --- 82
|
||||
37 --- 55
|
||||
71 <--x 37
|
||||
37 --- 72
|
||||
38 --- 61
|
||||
77 <--x 38
|
||||
38 --- 78
|
||||
39 --- 67
|
||||
83 <--x 39
|
||||
39 --- 84
|
||||
39 --- 69
|
||||
85 <--x 39
|
||||
39 --- 86
|
||||
40 --- 63
|
||||
79 <--x 40
|
||||
40 --- 80
|
||||
41 --- 56
|
||||
72 <--x 41
|
||||
41 --- 73
|
||||
41 --- 60
|
||||
76 <--x 41
|
||||
41 --- 77
|
||||
42 --- 54
|
||||
42 --- 71
|
||||
87 <--x 42
|
||||
43 --- 70
|
||||
86 <--x 43
|
||||
43 --- 87
|
||||
44 --- 68
|
||||
84 <--x 44
|
||||
44 --- 85
|
||||
45 --- 65
|
||||
81 <--x 45
|
||||
45 --- 82
|
||||
46 --- 62
|
||||
78 <--x 46
|
||||
46 --- 79
|
||||
47 --- 57
|
||||
73 <--x 47
|
||||
47 --- 74
|
||||
48 --- 55
|
||||
71 <--x 48
|
||||
48 --- 72
|
||||
49 --- 64
|
||||
80 <--x 49
|
||||
49 --- 81
|
||||
50 --- 69
|
||||
85 <--x 50
|
||||
50 --- 86
|
||||
51 --- 59
|
||||
75 <--x 51
|
||||
51 --- 76
|
||||
43 --- 66
|
||||
82 <--x 43
|
||||
43 --- 83
|
||||
44 --- 57
|
||||
73 <--x 44
|
||||
44 --- 74
|
||||
45 --- 64
|
||||
80 <--x 45
|
||||
45 --- 81
|
||||
46 --- 58
|
||||
74 <--x 46
|
||||
46 --- 75
|
||||
47 --- 59
|
||||
75 <--x 47
|
||||
47 --- 76
|
||||
48 --- 56
|
||||
72 <--x 48
|
||||
48 --- 73
|
||||
49 --- 62
|
||||
78 <--x 49
|
||||
49 --- 79
|
||||
50 --- 70
|
||||
86 <--x 50
|
||||
50 --- 87
|
||||
51 --- 68
|
||||
84 <--x 51
|
||||
51 --- 85
|
||||
54 <--x 53
|
||||
55 <--x 53
|
||||
56 <--x 53
|
||||
|
@ -59,23 +59,14 @@ description: Result of parsing pipe-flange-assembly.kcl
|
||||
"filename": "68095k348-flange.kcl"
|
||||
},
|
||||
"selector": {
|
||||
"type": "List",
|
||||
"items": [
|
||||
{
|
||||
"alias": null,
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "flange",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"start": 0,
|
||||
"type": "ImportItem"
|
||||
}
|
||||
]
|
||||
"type": "None",
|
||||
"alias": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "flange",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
}
|
||||
},
|
||||
"start": 0,
|
||||
"type": "ImportStatement",
|
||||
@ -89,23 +80,14 @@ description: Result of parsing pipe-flange-assembly.kcl
|
||||
"filename": "98017a257-washer.kcl"
|
||||
},
|
||||
"selector": {
|
||||
"type": "List",
|
||||
"items": [
|
||||
{
|
||||
"alias": null,
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "washer",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"start": 0,
|
||||
"type": "ImportItem"
|
||||
}
|
||||
]
|
||||
"type": "None",
|
||||
"alias": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "washer",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
}
|
||||
},
|
||||
"start": 0,
|
||||
"type": "ImportStatement",
|
||||
@ -119,23 +101,14 @@ description: Result of parsing pipe-flange-assembly.kcl
|
||||
"filename": "91251a404-bolt.kcl"
|
||||
},
|
||||
"selector": {
|
||||
"type": "List",
|
||||
"items": [
|
||||
{
|
||||
"alias": null,
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "bolt",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"start": 0,
|
||||
"type": "ImportItem"
|
||||
}
|
||||
]
|
||||
"type": "None",
|
||||
"alias": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "bolt",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
}
|
||||
},
|
||||
"start": 0,
|
||||
"type": "ImportStatement",
|
||||
@ -149,23 +122,14 @@ description: Result of parsing pipe-flange-assembly.kcl
|
||||
"filename": "95479a127-hex-nut.kcl"
|
||||
},
|
||||
"selector": {
|
||||
"type": "List",
|
||||
"items": [
|
||||
{
|
||||
"alias": null,
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "hexNut",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"start": 0,
|
||||
"type": "ImportItem"
|
||||
}
|
||||
]
|
||||
"type": "None",
|
||||
"alias": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "hexNut",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
}
|
||||
},
|
||||
"start": 0,
|
||||
"type": "ImportStatement",
|
||||
@ -179,91 +143,24 @@ description: Result of parsing pipe-flange-assembly.kcl
|
||||
"filename": "1120t74-pipe.kcl"
|
||||
},
|
||||
"selector": {
|
||||
"type": "List",
|
||||
"items": [
|
||||
{
|
||||
"alias": null,
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "pipe",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"start": 0,
|
||||
"type": "ImportItem"
|
||||
}
|
||||
]
|
||||
"type": "None",
|
||||
"alias": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "pipe",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
}
|
||||
},
|
||||
"start": 0,
|
||||
"type": "ImportStatement",
|
||||
"type": "ImportStatement"
|
||||
},
|
||||
{
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"expression": {
|
||||
"callee": {
|
||||
"abs_path": false,
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "flange",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"path": [],
|
||||
"start": 0,
|
||||
"type": "Name"
|
||||
},
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"start": 0,
|
||||
"type": "CallExpressionKw",
|
||||
"type": "CallExpressionKw",
|
||||
"unlabeled": null
|
||||
},
|
||||
"preComments": [
|
||||
"",
|
||||
"",
|
||||
"// Place flanges"
|
||||
],
|
||||
"start": 0,
|
||||
"type": "ExpressionStatement",
|
||||
"type": "ExpressionStatement"
|
||||
},
|
||||
{
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"expression": {
|
||||
"body": [
|
||||
{
|
||||
"callee": {
|
||||
"abs_path": false,
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "flange",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"path": [],
|
||||
"start": 0,
|
||||
"type": "Name"
|
||||
},
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"start": 0,
|
||||
"type": "CallExpressionKw",
|
||||
"type": "CallExpressionKw",
|
||||
"unlabeled": null
|
||||
},
|
||||
{
|
||||
"arguments": [
|
||||
{
|
||||
@ -271,62 +168,7 @@ description: Result of parsing pipe-flange-assembly.kcl
|
||||
"label": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "axis",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"arg": {
|
||||
"commentStart": 0,
|
||||
"elements": [
|
||||
{
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"raw": "0",
|
||||
"start": 0,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 0.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
},
|
||||
{
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"raw": "1",
|
||||
"start": 0,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 1.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
},
|
||||
{
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"raw": "0",
|
||||
"start": 0,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 0.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
}
|
||||
],
|
||||
"end": 0,
|
||||
"start": 0,
|
||||
"type": "ArrayExpression",
|
||||
"type": "ArrayExpression"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "LabeledArg",
|
||||
"label": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "angle",
|
||||
"name": "roll",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
@ -342,6 +184,50 @@ description: Result of parsing pipe-flange-assembly.kcl
|
||||
"suffix": "None"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "LabeledArg",
|
||||
"label": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "pitch",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"arg": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"raw": "0",
|
||||
"start": 0,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 0.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "LabeledArg",
|
||||
"label": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "yaw",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"arg": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"raw": "0",
|
||||
"start": 0,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 0.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"callee": {
|
||||
@ -364,7 +250,44 @@ description: Result of parsing pipe-flange-assembly.kcl
|
||||
"start": 0,
|
||||
"type": "CallExpressionKw",
|
||||
"type": "CallExpressionKw",
|
||||
"unlabeled": null
|
||||
"unlabeled": {
|
||||
"callee": {
|
||||
"abs_path": false,
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "clone",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"path": [],
|
||||
"start": 0,
|
||||
"type": "Name"
|
||||
},
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"start": 0,
|
||||
"type": "CallExpressionKw",
|
||||
"type": "CallExpressionKw",
|
||||
"unlabeled": {
|
||||
"abs_path": false,
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "flange",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"path": [],
|
||||
"start": 0,
|
||||
"type": "Name",
|
||||
"type": "Name"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"arguments": [
|
||||
@ -510,7 +433,7 @@ description: Result of parsing pipe-flange-assembly.kcl
|
||||
"end": 0,
|
||||
"nonCodeMeta": {
|
||||
"nonCodeNodes": {
|
||||
"2": [
|
||||
"1": [
|
||||
{
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
@ -530,6 +453,11 @@ description: Result of parsing pipe-flange-assembly.kcl
|
||||
"type": "PipeExpression",
|
||||
"type": "PipeExpression"
|
||||
},
|
||||
"preComments": [
|
||||
"",
|
||||
"",
|
||||
"// Place flange clone"
|
||||
],
|
||||
"start": 0,
|
||||
"type": "ExpressionStatement",
|
||||
"type": "ExpressionStatement"
|
||||
@ -717,27 +645,20 @@ description: Result of parsing pipe-flange-assembly.kcl
|
||||
"expression": {
|
||||
"body": [
|
||||
{
|
||||
"callee": {
|
||||
"abs_path": false,
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "washer",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"path": [],
|
||||
"start": 0,
|
||||
"type": "Name"
|
||||
},
|
||||
"abs_path": false,
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "washer",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"path": [],
|
||||
"start": 0,
|
||||
"type": "CallExpressionKw",
|
||||
"type": "CallExpressionKw",
|
||||
"unlabeled": null
|
||||
"type": "Name",
|
||||
"type": "Name"
|
||||
},
|
||||
{
|
||||
"arguments": [
|
||||
@ -1351,27 +1272,20 @@ description: Result of parsing pipe-flange-assembly.kcl
|
||||
"expression": {
|
||||
"body": [
|
||||
{
|
||||
"callee": {
|
||||
"abs_path": false,
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "bolt",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"path": [],
|
||||
"start": 0,
|
||||
"type": "Name"
|
||||
},
|
||||
"abs_path": false,
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "bolt",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"path": [],
|
||||
"start": 0,
|
||||
"type": "CallExpressionKw",
|
||||
"type": "CallExpressionKw",
|
||||
"unlabeled": null
|
||||
"type": "Name",
|
||||
"type": "Name"
|
||||
},
|
||||
{
|
||||
"arguments": [
|
||||
@ -1846,27 +1760,20 @@ description: Result of parsing pipe-flange-assembly.kcl
|
||||
"expression": {
|
||||
"body": [
|
||||
{
|
||||
"callee": {
|
||||
"abs_path": false,
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "hexNut",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"path": [],
|
||||
"start": 0,
|
||||
"type": "Name"
|
||||
},
|
||||
"abs_path": false,
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "hexNut",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"path": [],
|
||||
"start": 0,
|
||||
"type": "CallExpressionKw",
|
||||
"type": "CallExpressionKw",
|
||||
"unlabeled": null
|
||||
"type": "Name",
|
||||
"type": "Name"
|
||||
},
|
||||
{
|
||||
"arguments": [
|
||||
@ -2349,29 +2256,6 @@ description: Result of parsing pipe-flange-assembly.kcl
|
||||
"end": 0,
|
||||
"expression": {
|
||||
"body": [
|
||||
{
|
||||
"callee": {
|
||||
"abs_path": false,
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "pipe",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"path": [],
|
||||
"start": 0,
|
||||
"type": "Name"
|
||||
},
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"start": 0,
|
||||
"type": "CallExpressionKw",
|
||||
"type": "CallExpressionKw",
|
||||
"unlabeled": null
|
||||
},
|
||||
{
|
||||
"arguments": [
|
||||
{
|
||||
@ -2470,11 +2354,20 @@ description: Result of parsing pipe-flange-assembly.kcl
|
||||
"type": "CallExpressionKw",
|
||||
"type": "CallExpressionKw",
|
||||
"unlabeled": {
|
||||
"abs_path": false,
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "pipe",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"path": [],
|
||||
"start": 0,
|
||||
"type": "PipeSubstitution",
|
||||
"type": "PipeSubstitution"
|
||||
"type": "Name",
|
||||
"type": "Name"
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -2657,29 +2550,6 @@ description: Result of parsing pipe-flange-assembly.kcl
|
||||
"end": 0,
|
||||
"expression": {
|
||||
"body": [
|
||||
{
|
||||
"callee": {
|
||||
"abs_path": false,
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "pipe",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"path": [],
|
||||
"start": 0,
|
||||
"type": "Name"
|
||||
},
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"start": 0,
|
||||
"type": "CallExpressionKw",
|
||||
"type": "CallExpressionKw",
|
||||
"unlabeled": null
|
||||
},
|
||||
{
|
||||
"arguments": [
|
||||
{
|
||||
@ -2694,12 +2564,12 @@ description: Result of parsing pipe-flange-assembly.kcl
|
||||
"arg": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"raw": "90",
|
||||
"raw": "180",
|
||||
"start": 0,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 90.0,
|
||||
"value": 180.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
}
|
||||
@ -2770,11 +2640,42 @@ description: Result of parsing pipe-flange-assembly.kcl
|
||||
"type": "CallExpressionKw",
|
||||
"type": "CallExpressionKw",
|
||||
"unlabeled": {
|
||||
"callee": {
|
||||
"abs_path": false,
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "clone",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"path": [],
|
||||
"start": 0,
|
||||
"type": "Name"
|
||||
},
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"start": 0,
|
||||
"type": "PipeSubstitution",
|
||||
"type": "PipeSubstitution"
|
||||
"type": "CallExpressionKw",
|
||||
"type": "CallExpressionKw",
|
||||
"unlabeled": {
|
||||
"abs_path": false,
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "pipe",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"path": [],
|
||||
"start": 0,
|
||||
"type": "Name",
|
||||
"type": "Name"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -3009,13 +2910,7 @@ description: Result of parsing pipe-flange-assembly.kcl
|
||||
"start": 0,
|
||||
"type": "CallExpressionKw",
|
||||
"type": "CallExpressionKw",
|
||||
"unlabeled": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"start": 0,
|
||||
"type": "PipeSubstitution",
|
||||
"type": "PipeSubstitution"
|
||||
}
|
||||
"unlabeled": null
|
||||
}
|
||||
],
|
||||
"commentStart": 0,
|
||||
@ -3111,7 +3006,7 @@ description: Result of parsing pipe-flange-assembly.kcl
|
||||
],
|
||||
"nonCodeMeta": {
|
||||
"nonCodeNodes": {
|
||||
"13": [
|
||||
"9": [
|
||||
{
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
|
@ -3,13 +3,29 @@ source: kcl-lib/src/simulation_tests.rs
|
||||
description: Variables in memory after executing pipe-flange-assembly.kcl
|
||||
---
|
||||
{
|
||||
"__mod_bolt": {
|
||||
"type": "Module",
|
||||
"value": 5
|
||||
},
|
||||
"__mod_flange": {
|
||||
"type": "Module",
|
||||
"value": 3
|
||||
},
|
||||
"__mod_gasket": {
|
||||
"type": "Module",
|
||||
"value": 2
|
||||
},
|
||||
"bolt": {
|
||||
"type": "Function",
|
||||
"value": null
|
||||
"__mod_hexNut": {
|
||||
"type": "Module",
|
||||
"value": 6
|
||||
},
|
||||
"__mod_pipe": {
|
||||
"type": "Module",
|
||||
"value": 7
|
||||
},
|
||||
"__mod_washer": {
|
||||
"type": "Module",
|
||||
"value": 4
|
||||
},
|
||||
"boltDiameter": {
|
||||
"type": "Number",
|
||||
@ -107,10 +123,6 @@ description: Variables in memory after executing pipe-flange-assembly.kcl
|
||||
"type": "TagIdentifier",
|
||||
"value": "filletEdge"
|
||||
},
|
||||
"flange": {
|
||||
"type": "Function",
|
||||
"value": null
|
||||
},
|
||||
"flangeBackDiameter": {
|
||||
"type": "Number",
|
||||
"value": 3.62,
|
||||
@ -241,10 +253,6 @@ description: Variables in memory after executing pipe-flange-assembly.kcl
|
||||
}
|
||||
}
|
||||
},
|
||||
"hexNut": {
|
||||
"type": "Function",
|
||||
"value": null
|
||||
},
|
||||
"hexNutDiameter": {
|
||||
"type": "Number",
|
||||
"value": 0.625,
|
||||
@ -323,10 +331,6 @@ description: Variables in memory after executing pipe-flange-assembly.kcl
|
||||
}
|
||||
}
|
||||
},
|
||||
"pipe": {
|
||||
"type": "Function",
|
||||
"value": null
|
||||
},
|
||||
"pipeDiameter": {
|
||||
"type": "Number",
|
||||
"value": 2.44,
|
||||
@ -379,10 +383,6 @@ description: Variables in memory after executing pipe-flange-assembly.kcl
|
||||
}
|
||||
}
|
||||
},
|
||||
"washer": {
|
||||
"type": "Function",
|
||||
"value": null
|
||||
},
|
||||
"washerInnerDia": {
|
||||
"type": "Number",
|
||||
"value": 0.64,
|
||||
|
Before Width: | Height: | Size: 78 KiB After Width: | Height: | Size: 75 KiB |
@ -112,8 +112,8 @@ flowchart LR
|
||||
8 --- 20
|
||||
8 ---- 25
|
||||
12 <--x 32
|
||||
12 --- 33
|
||||
12 <--x 34
|
||||
12 <--x 33
|
||||
12 --- 34
|
||||
13 --- 31
|
||||
13 x--> 35
|
||||
13 --- 39
|
||||
|
@ -889,7 +889,7 @@ flowchart LR
|
||||
99 --- 265
|
||||
99 --- 314
|
||||
106 --- 181
|
||||
106 x--> 213
|
||||
106 x--> 212
|
||||
106 --- 260
|
||||
106 --- 309
|
||||
126 --- 194
|
||||
@ -1227,7 +1227,7 @@ flowchart LR
|
||||
251 <--x 209
|
||||
252 <--x 209
|
||||
253 <--x 209
|
||||
260 <--x 212
|
||||
260 <--x 213
|
||||
261 <--x 214
|
||||
262 <--x 214
|
||||
263 <--x 214
|
||||
|
@ -114,6 +114,9 @@ export function App() {
|
||||
// by the Projects view.
|
||||
billingActor.send({ type: BillingTransition.Update, apiToken: authToken })
|
||||
|
||||
// Tell engineStream to wait for dependencies to start streaming.
|
||||
engineStreamActor.send({ type: EngineStreamTransition.WaitForDependencies })
|
||||
|
||||
// When leaving the modeling scene, cut the engine stream.
|
||||
return () => {
|
||||
// When leaving the modeling scene, cut the engine stream.
|
||||
|
@ -1107,11 +1107,7 @@ export class SceneEntities {
|
||||
(lastSegment.type === 'TangentialArc' && segmentName !== 'line') ||
|
||||
segmentName === 'tangentialArc'
|
||||
) {
|
||||
if (snappedPoint[0] === 0 || snappedPoint[1] === 0) {
|
||||
resolvedFunctionName = 'tangentialArcTo'
|
||||
} else {
|
||||
resolvedFunctionName = 'tangentialArc'
|
||||
}
|
||||
resolvedFunctionName = 'tangentialArc'
|
||||
} else if (snappedToTangent) {
|
||||
// Generate tag for previous arc segment and use it for the angle of angledLine:
|
||||
// |> tangentialArc(endAbsolute = [5, -10], tag = $arc001)
|
||||
@ -3588,7 +3584,8 @@ export class SceneEntities {
|
||||
})
|
||||
|
||||
if (!resp) {
|
||||
return Promise.reject('no response')
|
||||
console.warn('No response')
|
||||
return {} as Models['GetSketchModePlane_type']
|
||||
}
|
||||
|
||||
if (isArray(resp)) {
|
||||
|
@ -1,4 +1,3 @@
|
||||
import { isPlaywright } from '@src/lib/isPlaywright'
|
||||
import { useAppState } from '@src/AppState'
|
||||
import { ClientSideScene } from '@src/clientSideScene/ClientSideSceneComp'
|
||||
import { ViewControlContextMenu } from '@src/components/ViewControlMenu'
|
||||
@ -52,8 +51,10 @@ export const EngineStream = (props: {
|
||||
const last = useRef<number>(Date.now())
|
||||
|
||||
const [firstPlay, setFirstPlay] = useState(true)
|
||||
const [isRestartRequestStarting, setIsRestartRequestStarting] =
|
||||
useState(false)
|
||||
const [goRestart, setGoRestart] = useState(false)
|
||||
const [timeoutId, setTimeoutId] = useState<
|
||||
ReturnType<typeof setTimeout> | undefined
|
||||
>(undefined)
|
||||
const [attemptTimes, setAttemptTimes] = useState<[number, number]>([
|
||||
0,
|
||||
TIME_1_SECOND,
|
||||
@ -85,18 +86,21 @@ export const EngineStream = (props: {
|
||||
const streamIdleMode = settings.app.streamIdleMode.current
|
||||
|
||||
useEffect(() => {
|
||||
// Will cause a useEffect loop if not checked for.
|
||||
if (engineStreamState.context.videoRef.current !== null) return
|
||||
engineStreamActor.send({
|
||||
type: EngineStreamTransition.SetVideoRef,
|
||||
videoRef: { current: videoRef.current },
|
||||
})
|
||||
}, [videoRef.current])
|
||||
}, [videoRef.current, engineStreamState])
|
||||
|
||||
useEffect(() => {
|
||||
if (engineStreamState.context.canvasRef.current !== null) return
|
||||
engineStreamActor.send({
|
||||
type: EngineStreamTransition.SetCanvasRef,
|
||||
canvasRef: { current: canvasRef.current },
|
||||
})
|
||||
}, [canvasRef.current])
|
||||
}, [canvasRef.current, engineStreamState])
|
||||
|
||||
useEffect(() => {
|
||||
engineStreamActor.send({
|
||||
@ -131,24 +135,6 @@ export const EngineStream = (props: {
|
||||
})
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
// Only try to start the stream if we're stopped or think we're done
|
||||
// waiting for dependencies.
|
||||
if (
|
||||
!(
|
||||
engineStreamState.value === EngineStreamState.WaitingForDependencies ||
|
||||
engineStreamState.value === EngineStreamState.Stopped
|
||||
)
|
||||
)
|
||||
return
|
||||
|
||||
// Don't bother trying to connect if the auth token is empty.
|
||||
// We have the checks in the machine but this can cause a hot loop.
|
||||
if (!engineStreamState.context.authToken) return
|
||||
|
||||
startOrReconfigureEngine()
|
||||
}, [engineStreamState, setAppState])
|
||||
|
||||
// I would inline this but it needs to be a function for removeEventListener.
|
||||
const play = () => {
|
||||
engineStreamActor.send({
|
||||
@ -174,12 +160,13 @@ export const EngineStream = (props: {
|
||||
console.log('scene is ready, execute kcl')
|
||||
const kmp = kclManager.executeCode().catch(trap)
|
||||
|
||||
if (!firstPlay) return
|
||||
|
||||
setFirstPlay(false)
|
||||
// Reset the restart timeouts
|
||||
setAttemptTimes([0, TIME_1_SECOND])
|
||||
|
||||
console.log(firstPlay)
|
||||
if (!firstPlay) return
|
||||
|
||||
setFirstPlay(false)
|
||||
console.log('firstPlay true, zoom to fit')
|
||||
kmp
|
||||
.then(async () => {
|
||||
@ -211,51 +198,76 @@ export const EngineStream = (props: {
|
||||
// We do a back-off restart, using a fibonacci sequence, since it
|
||||
// has a nice retry time curve (somewhat quick then exponential)
|
||||
const attemptRestartIfNecessary = () => {
|
||||
if (isRestartRequestStarting) return
|
||||
setIsRestartRequestStarting(true)
|
||||
setTimeout(() => {
|
||||
engineStreamState.context.videoRef.current?.pause()
|
||||
engineCommandManager.tearDown()
|
||||
startOrReconfigureEngine()
|
||||
setFirstPlay(false)
|
||||
setIsRestartRequestStarting(false)
|
||||
}, attemptTimes[0] + attemptTimes[1])
|
||||
// Timeout already set.
|
||||
if (timeoutId) return
|
||||
|
||||
setTimeoutId(
|
||||
setTimeout(() => {
|
||||
engineStreamState.context.videoRef.current?.pause()
|
||||
engineCommandManager.tearDown()
|
||||
startOrReconfigureEngine()
|
||||
setFirstPlay(true)
|
||||
|
||||
setTimeoutId(undefined)
|
||||
setGoRestart(false)
|
||||
}, attemptTimes[0] + attemptTimes[1])
|
||||
)
|
||||
setAttemptTimes([attemptTimes[1], attemptTimes[0] + attemptTimes[1]])
|
||||
}
|
||||
|
||||
// Poll that we're connected. If not, send a reset signal.
|
||||
// Do not restart if we're in idle mode.
|
||||
const connectionCheckIntervalId = setInterval(() => {
|
||||
// SKIP DURING TESTS BECAUSE IT WILL MESS WITH REUSING THE
|
||||
// ELECTRON INSTANCE.
|
||||
if (isPlaywright()) {
|
||||
const onOffline = () => {
|
||||
if (
|
||||
!(
|
||||
EngineConnectionStateType.Disconnected ===
|
||||
engineCommandManager.engineConnection?.state.type ||
|
||||
EngineConnectionStateType.Disconnecting ===
|
||||
engineCommandManager.engineConnection?.state.type
|
||||
)
|
||||
) {
|
||||
return
|
||||
}
|
||||
|
||||
// Don't try try to restart if we're already connected!
|
||||
const hasEngineConnectionInst = engineCommandManager.engineConnection
|
||||
const isDisconnected =
|
||||
engineCommandManager.engineConnection?.state.type ===
|
||||
EngineConnectionStateType.Disconnected
|
||||
const inIdleMode = engineStreamState.value === EngineStreamState.Paused
|
||||
if ((hasEngineConnectionInst && !isDisconnected) || inIdleMode) return
|
||||
|
||||
engineStreamActor.send({ type: EngineStreamTransition.Stop })
|
||||
attemptRestartIfNecessary()
|
||||
}, TIME_1_SECOND)
|
||||
}
|
||||
|
||||
if (
|
||||
!goRestart &&
|
||||
engineStreamState.value === EngineStreamState.WaitingForDependencies
|
||||
) {
|
||||
setGoRestart(true)
|
||||
}
|
||||
|
||||
if (goRestart && !timeoutId) {
|
||||
attemptRestartIfNecessary()
|
||||
}
|
||||
|
||||
engineCommandManager.addEventListener(
|
||||
EngineCommandManagerEvents.EngineRestartRequest,
|
||||
attemptRestartIfNecessary
|
||||
)
|
||||
return () => {
|
||||
clearInterval(connectionCheckIntervalId)
|
||||
|
||||
engineCommandManager.addEventListener(
|
||||
EngineCommandManagerEvents.Offline,
|
||||
onOffline
|
||||
)
|
||||
|
||||
return () => {
|
||||
engineCommandManager.removeEventListener(
|
||||
EngineCommandManagerEvents.EngineRestartRequest,
|
||||
attemptRestartIfNecessary
|
||||
)
|
||||
engineCommandManager.removeEventListener(
|
||||
EngineCommandManagerEvents.Offline,
|
||||
onOffline
|
||||
)
|
||||
}
|
||||
}, [engineStreamState, attemptTimes, isRestartRequestStarting])
|
||||
}, [
|
||||
engineStreamState,
|
||||
attemptTimes,
|
||||
goRestart,
|
||||
timeoutId,
|
||||
engineCommandManager.engineConnection?.state.type,
|
||||
])
|
||||
|
||||
useEffect(() => {
|
||||
// If engineStreamMachine is already reconfiguring, bail.
|
||||
@ -269,7 +281,7 @@ export const EngineStream = (props: {
|
||||
const canvas = engineStreamState.context.canvasRef?.current
|
||||
if (!canvas) return
|
||||
|
||||
new ResizeObserver(() => {
|
||||
const observer = new ResizeObserver(() => {
|
||||
// Prevents:
|
||||
// `Uncaught ResizeObserver loop completed with undelivered notifications`
|
||||
window.requestAnimationFrame(() => {
|
||||
@ -280,13 +292,19 @@ export const EngineStream = (props: {
|
||||
if (
|
||||
(Math.abs(video.width - window.innerWidth) > 4 ||
|
||||
Math.abs(video.height - window.innerHeight) > 4) &&
|
||||
!engineStreamState.matches(EngineStreamState.WaitingToPlay)
|
||||
engineStreamState.matches(EngineStreamState.Playing)
|
||||
) {
|
||||
timeoutStart.current = Date.now()
|
||||
startOrReconfigureEngine()
|
||||
}
|
||||
})
|
||||
}).observe(document.body)
|
||||
})
|
||||
|
||||
observer.observe(document.body)
|
||||
|
||||
return () => {
|
||||
observer.disconnect()
|
||||
}
|
||||
}, [engineStreamState.value])
|
||||
|
||||
/**
|
||||
@ -345,8 +363,21 @@ export const EngineStream = (props: {
|
||||
timeoutStart.current = null
|
||||
} else if (timeoutStart.current) {
|
||||
const elapsed = Date.now() - timeoutStart.current
|
||||
if (elapsed >= IDLE_TIME_MS) {
|
||||
// Don't pause if we're already disconnected.
|
||||
if (
|
||||
// It's unnecessary to once again setup an event listener for
|
||||
// offline/online to capture this state, when this state already
|
||||
// exists on the window.navigator object. In hindsight it makes
|
||||
// me (lee) regret we set React state variables such as
|
||||
// isInternetConnected in other files when we could check this
|
||||
// object instead.
|
||||
engineCommandManager.engineConnection?.state.type ===
|
||||
EngineConnectionStateType.ConnectionEstablished &&
|
||||
elapsed >= IDLE_TIME_MS &&
|
||||
engineStreamState.value === EngineStreamState.Playing
|
||||
) {
|
||||
timeoutStart.current = null
|
||||
console.log('PAUSING')
|
||||
engineStreamActor.send({ type: EngineStreamTransition.Pause })
|
||||
}
|
||||
}
|
||||
@ -357,7 +388,7 @@ export const EngineStream = (props: {
|
||||
return () => {
|
||||
window.cancelAnimationFrame(frameId)
|
||||
}
|
||||
}, [modelingMachineState])
|
||||
}, [modelingMachineState, engineStreamState.value])
|
||||
|
||||
useEffect(() => {
|
||||
if (!streamIdleMode) return
|
||||
@ -370,9 +401,18 @@ export const EngineStream = (props: {
|
||||
return
|
||||
}
|
||||
|
||||
if (engineStreamState.value === EngineStreamState.Paused) {
|
||||
startOrReconfigureEngine()
|
||||
}
|
||||
engineStreamActor.send({
|
||||
type: EngineStreamTransition.Resume,
|
||||
modelingMachineActorSend,
|
||||
settings: settingsEngine,
|
||||
setAppState,
|
||||
onMediaStream(mediaStream: MediaStream) {
|
||||
engineStreamActor.send({
|
||||
type: EngineStreamTransition.SetMediaStream,
|
||||
mediaStream,
|
||||
})
|
||||
},
|
||||
})
|
||||
|
||||
timeoutStart.current = Date.now()
|
||||
}
|
||||
@ -471,7 +511,11 @@ export const EngineStream = (props: {
|
||||
}
|
||||
|
||||
sendSelectEventToEngine(e)
|
||||
.then(({ entity_id }) => {
|
||||
.then((result) => {
|
||||
if (!result) {
|
||||
return
|
||||
}
|
||||
const { entity_id } = result
|
||||
if (!entity_id) {
|
||||
// No entity selected. This is benign
|
||||
return
|
||||
|
@ -21,7 +21,6 @@ import {
|
||||
filterOperations,
|
||||
getOperationIcon,
|
||||
getOperationLabel,
|
||||
getOperationVariableName,
|
||||
stdLibMap,
|
||||
} from '@src/lib/operations'
|
||||
import { editorManager, kclManager, rustContext } from '@src/lib/singletons'
|
||||
@ -237,7 +236,6 @@ const VisibilityToggle = (props: VisibilityToggleProps) => {
|
||||
const OperationItemWrapper = ({
|
||||
icon,
|
||||
name,
|
||||
variableName,
|
||||
visibilityToggle,
|
||||
menuItems,
|
||||
errors,
|
||||
@ -248,7 +246,6 @@ const OperationItemWrapper = ({
|
||||
}: React.HTMLAttributes<HTMLButtonElement> & {
|
||||
icon: CustomIconName
|
||||
name: string
|
||||
variableName?: string
|
||||
visibilityToggle?: VisibilityToggleProps
|
||||
customSuffix?: JSX.Element
|
||||
menuItems?: ComponentProps<typeof ContextMenu>['items']
|
||||
@ -267,15 +264,8 @@ const OperationItemWrapper = ({
|
||||
className={`reset flex-1 flex items-center gap-2 text-left text-base ${selectable ? 'border-transparent dark:border-transparent' : 'border-none cursor-default'} ${className}`}
|
||||
>
|
||||
<CustomIcon name={icon} className="w-5 h-5 block" />
|
||||
<div className="flex items-baseline align-baseline">
|
||||
<div className="mr-2">
|
||||
{name}
|
||||
{variableName && (
|
||||
<span className="ml-2 opacity-50 text-[11px] font-semibold">
|
||||
{variableName}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
<div className="flex items-baseline">
|
||||
<div className="mr-2">{name}</div>
|
||||
{customSuffix && customSuffix}
|
||||
</div>
|
||||
</button>
|
||||
@ -300,11 +290,6 @@ const OperationItem = (props: {
|
||||
}) => {
|
||||
const kclContext = useKclContext()
|
||||
const name = getOperationLabel(props.item)
|
||||
|
||||
const variableName = useMemo(() => {
|
||||
return getOperationVariableName(props.item, kclContext.ast)
|
||||
}, [props.item, kclContext.ast])
|
||||
|
||||
const errors = useMemo(() => {
|
||||
return kclContext.diagnostics.filter(
|
||||
(diag) =>
|
||||
@ -514,7 +499,6 @@ const OperationItem = (props: {
|
||||
<OperationItemWrapper
|
||||
icon={getOperationIcon(props.item)}
|
||||
name={name}
|
||||
variableName={variableName}
|
||||
menuItems={menuItems}
|
||||
onClick={selectOperation}
|
||||
onDoubleClick={enterEditFlow}
|
||||
|
@ -78,18 +78,19 @@ export function useNetworkStatus() {
|
||||
}, [hasIssues, internetConnected, ping])
|
||||
|
||||
useEffect(() => {
|
||||
const onlineCallback = () => {
|
||||
setInternetConnected(true)
|
||||
}
|
||||
const offlineCallback = () => {
|
||||
setInternetConnected(false)
|
||||
setSteps(structuredClone(initialConnectingTypeGroupState))
|
||||
}
|
||||
window.addEventListener('online', onlineCallback)
|
||||
window.addEventListener('offline', offlineCallback)
|
||||
engineCommandManager.addEventListener(
|
||||
EngineCommandManagerEvents.Offline,
|
||||
offlineCallback
|
||||
)
|
||||
return () => {
|
||||
window.removeEventListener('online', onlineCallback)
|
||||
window.removeEventListener('offline', offlineCallback)
|
||||
engineCommandManager.removeEventListener(
|
||||
EngineCommandManagerEvents.Offline,
|
||||
offlineCallback
|
||||
)
|
||||
}
|
||||
}, [])
|
||||
|
||||
@ -139,6 +140,8 @@ export function useNetworkStatus() {
|
||||
if (
|
||||
engineConnectionState.type === EngineConnectionStateType.Connecting
|
||||
) {
|
||||
setInternetConnected(true)
|
||||
|
||||
const groups = Object.values(nextSteps)
|
||||
for (let group of groups) {
|
||||
for (let step of group) {
|
||||
@ -168,6 +171,10 @@ export function useNetworkStatus() {
|
||||
|
||||
if (engineConnectionState.value.type === DisconnectingType.Error) {
|
||||
setError(engineConnectionState.value.value)
|
||||
} else if (
|
||||
engineConnectionState.value.type === DisconnectingType.Quit
|
||||
) {
|
||||
return structuredClone(initialConnectingTypeGroupState)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -24,7 +24,6 @@ export type ToolTip =
|
||||
| 'yLineTo'
|
||||
| 'angledLineThatIntersects'
|
||||
| 'tangentialArc'
|
||||
| 'tangentialArcTo'
|
||||
| 'circle'
|
||||
| 'circleThreePoint'
|
||||
| 'arcTo'
|
||||
@ -45,7 +44,6 @@ export const toolTips: Array<ToolTip> = [
|
||||
'yLineTo',
|
||||
'angledLineThatIntersects',
|
||||
'tangentialArc',
|
||||
'tangentialArcTo',
|
||||
'circleThreePoint',
|
||||
'arc',
|
||||
'arcTo',
|
||||
|
@ -1,4 +1,3 @@
|
||||
import { TEST } from '@src/env'
|
||||
import type { Models } from '@kittycad/lib'
|
||||
import { VITE_KC_API_WS_MODELING_URL, VITE_KC_DEV_TOKEN } from '@src/env'
|
||||
import { jsAppSettings } from '@src/lib/settings/settingsUtils'
|
||||
@ -83,6 +82,9 @@ export enum ConnectionError {
|
||||
TooManyConnections,
|
||||
Outage,
|
||||
|
||||
// Observed to happen on a local network outage.
|
||||
PeerConnectionRemoteDisconnected,
|
||||
|
||||
// An unknown error is the most severe because it has not been classified
|
||||
// or encountered before.
|
||||
Unknown,
|
||||
@ -107,6 +109,8 @@ export const CONNECTION_ERROR_TEXT: Record<ConnectionError, string> = {
|
||||
'There are too many open engine connections associated with your account.',
|
||||
[ConnectionError.Outage]:
|
||||
'We seem to be experiencing an outage. Please visit [status.zoo.dev](https://status.zoo.dev) for updates.',
|
||||
[ConnectionError.PeerConnectionRemoteDisconnected]:
|
||||
'The remote end has disconnected.',
|
||||
[ConnectionError.Unknown]:
|
||||
'An unexpected error occurred. Please report this to us.',
|
||||
}
|
||||
@ -226,6 +230,9 @@ export enum EngineConnectionEvents {
|
||||
Opened = 'opened', // (engineConnection: EngineConnection) => void
|
||||
Closed = 'closed', // (engineConnection: EngineConnection) => void
|
||||
NewTrack = 'new-track', // (track: NewTrackArgs) => void
|
||||
|
||||
// A general offline state.
|
||||
Offline = 'offline',
|
||||
}
|
||||
|
||||
function toRTCSessionDescriptionInit(
|
||||
@ -674,9 +681,20 @@ class EngineConnection extends EventTarget {
|
||||
|
||||
// The remote end broke up with us! :(
|
||||
case 'disconnected':
|
||||
this.state = {
|
||||
type: EngineConnectionStateType.Disconnecting,
|
||||
value: {
|
||||
type: DisconnectingType.Error,
|
||||
value: {
|
||||
error: ConnectionError.PeerConnectionRemoteDisconnected,
|
||||
context: event,
|
||||
},
|
||||
},
|
||||
}
|
||||
this.dispatchEvent(
|
||||
new CustomEvent(EngineConnectionEvents.RestartRequest, {})
|
||||
new CustomEvent(EngineConnectionEvents.Offline, {})
|
||||
)
|
||||
this.disconnectAll()
|
||||
break
|
||||
case 'closed':
|
||||
this.pc?.removeEventListener('icecandidate', this.onIceCandidate)
|
||||
@ -847,7 +865,6 @@ class EngineConnection extends EventTarget {
|
||||
'message',
|
||||
this.onDataChannelMessage
|
||||
)
|
||||
this.disconnectAll()
|
||||
}
|
||||
|
||||
this.unreliableDataChannel?.addEventListener(
|
||||
@ -866,7 +883,6 @@ class EngineConnection extends EventTarget {
|
||||
},
|
||||
},
|
||||
}
|
||||
this.disconnectAll()
|
||||
}
|
||||
this.unreliableDataChannel?.addEventListener(
|
||||
'error',
|
||||
@ -956,6 +972,9 @@ class EngineConnection extends EventTarget {
|
||||
this.onNetworkStatusReady
|
||||
)
|
||||
|
||||
this.dispatchEvent(
|
||||
new CustomEvent(EngineConnectionEvents.Offline, {})
|
||||
)
|
||||
this.disconnectAll()
|
||||
}
|
||||
this.websocket.addEventListener('close', this.onWebSocketClose)
|
||||
@ -974,8 +993,6 @@ class EngineConnection extends EventTarget {
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
this.disconnectAll()
|
||||
}
|
||||
this.websocket.addEventListener('error', this.onWebSocketError)
|
||||
|
||||
@ -1331,6 +1348,9 @@ export enum EngineCommandManagerEvents {
|
||||
|
||||
// the whole scene is ready (settings loaded)
|
||||
SceneReady = 'scene-ready',
|
||||
|
||||
// we're offline
|
||||
Offline = 'offline',
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1380,6 +1400,7 @@ export class EngineCommandManager extends EventTarget {
|
||||
* This is compared to the {@link outSequence} number to determine if we should ignore
|
||||
* any out-of-order late responses in the unreliable channel.
|
||||
*/
|
||||
keepForcefulOffline = false
|
||||
inSequence = 1
|
||||
engineConnection?: EngineConnection
|
||||
commandLogs: CommandLog[] = []
|
||||
@ -1453,13 +1474,8 @@ export class EngineCommandManager extends EventTarget {
|
||||
)
|
||||
}
|
||||
|
||||
private onOffline = () => {
|
||||
console.log('Browser reported network is offline')
|
||||
if (TEST) {
|
||||
console.warn('DURING TESTS ENGINECONNECTION.ONOFFLINE WILL DO NOTHING.')
|
||||
return
|
||||
}
|
||||
this.onEngineConnectionRestartRequest()
|
||||
private onEngineOffline = () => {
|
||||
this.dispatchEvent(new CustomEvent(EngineCommandManagerEvents.Offline, {}))
|
||||
}
|
||||
|
||||
idleMode: boolean = false
|
||||
@ -1494,6 +1510,11 @@ export class EngineCommandManager extends EventTarget {
|
||||
if (settings) {
|
||||
this.settings = settings
|
||||
}
|
||||
|
||||
if (this.keepForcefulOffline) {
|
||||
return
|
||||
}
|
||||
|
||||
if (width === 0 || height === 0) {
|
||||
return
|
||||
}
|
||||
@ -1509,8 +1530,6 @@ export class EngineCommandManager extends EventTarget {
|
||||
return
|
||||
}
|
||||
|
||||
window.addEventListener('offline', this.onOffline)
|
||||
|
||||
let additionalSettings = this.settings.enableSSAO ? '&post_effect=ssao' : ''
|
||||
additionalSettings +=
|
||||
'&show_grid=' + (this.settings.showScaleGrid ? 'true' : 'false')
|
||||
@ -1537,6 +1556,11 @@ export class EngineCommandManager extends EventTarget {
|
||||
this.onEngineConnectionRestartRequest as EventListener
|
||||
)
|
||||
|
||||
this.engineConnection.addEventListener(
|
||||
EngineConnectionEvents.Offline,
|
||||
this.onEngineOffline as EventListener
|
||||
)
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
||||
this.onEngineConnectionOpened = async () => {
|
||||
console.log('onEngineConnectionOpened')
|
||||
@ -1552,9 +1576,9 @@ export class EngineCommandManager extends EventTarget {
|
||||
// Let's restart.
|
||||
console.warn("shit's gone south")
|
||||
console.warn(e)
|
||||
this.engineConnection?.dispatchEvent(
|
||||
new CustomEvent(EngineConnectionEvents.RestartRequest, {})
|
||||
)
|
||||
// this.engineConnection?.dispatchEvent(
|
||||
// new CustomEvent(EngineConnectionEvents.RestartRequest, {})
|
||||
// )
|
||||
return
|
||||
}
|
||||
|
||||
@ -1597,23 +1621,7 @@ export class EngineCommandManager extends EventTarget {
|
||||
console.log('camControlsCameraChange')
|
||||
this._camControlsCameraChange()
|
||||
|
||||
// We should eventually only have 1 restoral call.
|
||||
if (this.idleMode) {
|
||||
await this.sceneInfra?.camControls.restoreRemoteCameraStateAndTriggerSync()
|
||||
} else {
|
||||
// NOTE: This code is old. It uses the old hack to restore camera.
|
||||
console.log('call default_camera_get_settings')
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
await this.sendSceneCommand({
|
||||
// CameraControls subscribes to default_camera_get_settings response events
|
||||
// firing this at connection ensure the camera's are synced initially
|
||||
type: 'modeling_cmd_req',
|
||||
cmd_id: uuidv4(),
|
||||
cmd: {
|
||||
type: 'default_camera_get_settings',
|
||||
},
|
||||
})
|
||||
}
|
||||
await this.sceneInfra?.camControls.restoreRemoteCameraStateAndTriggerSync()
|
||||
|
||||
setIsStreamReady(true)
|
||||
|
||||
@ -1877,8 +1885,6 @@ export class EngineCommandManager extends EventTarget {
|
||||
tearDown(opts?: { idleMode: boolean }) {
|
||||
this.idleMode = opts?.idleMode ?? false
|
||||
|
||||
window.removeEventListener('offline', this.onOffline)
|
||||
|
||||
if (this.engineConnection) {
|
||||
for (const [cmdId, pending] of Object.entries(this.pendingCommands)) {
|
||||
pending.reject([
|
||||
@ -1928,7 +1934,26 @@ export class EngineCommandManager extends EventTarget {
|
||||
this.engineCommandManager.engineConnection = null
|
||||
}
|
||||
this.engineConnection = undefined
|
||||
|
||||
// It is possible all connections never even started, but we still want
|
||||
// to signal to the whole application we are "offline".
|
||||
this.dispatchEvent(new CustomEvent(EngineCommandManagerEvents.Offline, {}))
|
||||
}
|
||||
|
||||
offline() {
|
||||
this.keepForcefulOffline = true
|
||||
this.tearDown()
|
||||
console.log('offline')
|
||||
}
|
||||
|
||||
online() {
|
||||
this.keepForcefulOffline = false
|
||||
this.dispatchEvent(
|
||||
new CustomEvent(EngineCommandManagerEvents.EngineRestartRequest, {})
|
||||
)
|
||||
console.log('online')
|
||||
}
|
||||
|
||||
async startNewSession() {
|
||||
this.responseMap = {}
|
||||
}
|
||||
|
@ -1018,61 +1018,217 @@ export const yLine: SketchLineHelperKw = {
|
||||
|
||||
export const tangentialArc: SketchLineHelperKw = {
|
||||
add: ({ node, pathToNode, segmentInput, replaceExistingCallback }) => {
|
||||
return tangentialArcHelpers.add({
|
||||
node,
|
||||
if (segmentInput.type !== 'straight-segment') return STRAIGHT_SEGMENT_ERR()
|
||||
const { to } = segmentInput
|
||||
const _node = { ...node }
|
||||
const getNode = getNodeFromPathCurry(_node, pathToNode)
|
||||
const _node1 = getNode<PipeExpression | CallExpressionKw>('PipeExpression')
|
||||
if (err(_node1)) return _node1
|
||||
const { node: pipe } = _node1
|
||||
const _node2 = getNodeFromPath<VariableDeclarator>(
|
||||
_node,
|
||||
pathToNode,
|
||||
segmentInput,
|
||||
replaceExistingCallback,
|
||||
isAbsolute: false,
|
||||
})
|
||||
},
|
||||
updateArgs: ({ node, pathToNode, input }) => {
|
||||
return tangentialArcHelpers.update({
|
||||
node,
|
||||
pathToNode,
|
||||
input,
|
||||
isAbsolute: false,
|
||||
})
|
||||
},
|
||||
getTag: getTagKwArg(),
|
||||
addTag: addTagKw(),
|
||||
getConstraintInfo: (callExp: CallExpressionKw, code, pathToNode) => {
|
||||
return tangentialArcHelpers.getConstraintInfo({
|
||||
callExp,
|
||||
code,
|
||||
pathToNode,
|
||||
isAbsolute: false,
|
||||
})
|
||||
},
|
||||
}
|
||||
'VariableDeclarator'
|
||||
)
|
||||
if (err(_node2)) return _node2
|
||||
const { node: varDec } = _node2
|
||||
|
||||
export const tangentialArcTo: SketchLineHelperKw = {
|
||||
add: ({ node, pathToNode, segmentInput, replaceExistingCallback }) => {
|
||||
return tangentialArcHelpers.add({
|
||||
node,
|
||||
const toX = createLiteral(roundOff(to[0], 2))
|
||||
const toY = createLiteral(roundOff(to[1], 2))
|
||||
|
||||
if (replaceExistingCallback && pipe.type !== 'CallExpressionKw') {
|
||||
const { index: callIndex } = splitPathAtPipeExpression(pathToNode)
|
||||
const result = replaceExistingCallback([
|
||||
{
|
||||
type: 'labeledArgArrayItem',
|
||||
key: ARG_END_ABSOLUTE,
|
||||
index: 0,
|
||||
argType: 'xAbsolute',
|
||||
expr: toX,
|
||||
},
|
||||
{
|
||||
type: 'labeledArgArrayItem',
|
||||
key: ARG_END_ABSOLUTE,
|
||||
index: 1,
|
||||
argType: 'yAbsolute',
|
||||
expr: toY,
|
||||
},
|
||||
])
|
||||
if (err(result)) return result
|
||||
const { callExp, valueUsedInTransform } = result
|
||||
pipe.body[callIndex] = callExp
|
||||
return {
|
||||
modifiedAst: _node,
|
||||
pathToNode,
|
||||
valueUsedInTransform,
|
||||
}
|
||||
}
|
||||
const newLine = createCallExpressionStdLibKw(
|
||||
'tangentialArc',
|
||||
null, // Assumes this is being called in a pipeline, so the first arg is optional and if not given, will become pipeline substitution.
|
||||
[createLabeledArg(ARG_END_ABSOLUTE, createArrayExpression([toX, toY]))]
|
||||
)
|
||||
if (pipe.type === 'PipeExpression') {
|
||||
pipe.body = [...pipe.body, newLine]
|
||||
return {
|
||||
modifiedAst: _node,
|
||||
pathToNode: [
|
||||
...pathToNode.slice(
|
||||
0,
|
||||
pathToNode.findIndex(([_, type]) => type === 'PipeExpression') + 1
|
||||
),
|
||||
['body', 'PipeExpression'],
|
||||
[pipe.body.length - 1, 'CallExpressionKw'],
|
||||
],
|
||||
}
|
||||
} else {
|
||||
varDec.init = createPipeExpression([varDec.init, newLine])
|
||||
}
|
||||
return {
|
||||
modifiedAst: _node,
|
||||
pathToNode,
|
||||
segmentInput,
|
||||
replaceExistingCallback,
|
||||
isAbsolute: true,
|
||||
})
|
||||
}
|
||||
},
|
||||
updateArgs: ({ node, pathToNode, input }) => {
|
||||
return tangentialArcHelpers.update({
|
||||
node,
|
||||
if (input.type !== 'straight-segment') return STRAIGHT_SEGMENT_ERR()
|
||||
const { to } = input
|
||||
const _node = { ...node }
|
||||
const nodeMeta = getNodeFromPath<CallExpressionKw>(_node, pathToNode)
|
||||
if (err(nodeMeta)) return nodeMeta
|
||||
const { node: callExpression } = nodeMeta
|
||||
|
||||
if (callExpression.type !== 'CallExpressionKw') {
|
||||
return new Error(
|
||||
`Expected CallExpressionKw, but found ${callExpression.type}`
|
||||
)
|
||||
}
|
||||
|
||||
for (const arg of callExpression.arguments) {
|
||||
if (arg.label?.name !== ARG_END_ABSOLUTE && arg.label?.name !== ARG_TAG) {
|
||||
console.debug(
|
||||
'Trying to edit unsupported tangentialArc keyword arguments; skipping'
|
||||
)
|
||||
return {
|
||||
modifiedAst: _node,
|
||||
pathToNode,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const toArrExp = createArrayExpression([
|
||||
createLiteral(roundOff(to[0], 2)),
|
||||
createLiteral(roundOff(to[1], 2)),
|
||||
])
|
||||
|
||||
mutateKwArg(ARG_END_ABSOLUTE, callExpression, toArrExp)
|
||||
return {
|
||||
modifiedAst: _node,
|
||||
pathToNode,
|
||||
input,
|
||||
isAbsolute: true,
|
||||
})
|
||||
}
|
||||
},
|
||||
getTag: getTagKwArg(),
|
||||
addTag: addTagKw(),
|
||||
getConstraintInfo: (callExp: CallExpressionKw, code, pathToNode) => {
|
||||
return tangentialArcHelpers.getConstraintInfo({
|
||||
callExp,
|
||||
code,
|
||||
pathToNode,
|
||||
isAbsolute: true,
|
||||
})
|
||||
if (callExp.type !== 'CallExpressionKw') return []
|
||||
if (callExp.callee.name.name !== 'tangentialArc') return []
|
||||
const callee = callExp.callee
|
||||
const pathToCallee: PathToNode = [
|
||||
...pathToNode,
|
||||
['callee', 'CallExpressionKw'],
|
||||
]
|
||||
const endAbsoluteArg = findKwArgWithIndex(ARG_END_ABSOLUTE, callExp)
|
||||
|
||||
const constraints: ConstrainInfo[] = [
|
||||
constrainInfo(
|
||||
'tangentialWithPrevious',
|
||||
true,
|
||||
callee.name.name,
|
||||
'tangentialArc',
|
||||
undefined,
|
||||
topLevelRange(callee.start, callee.end),
|
||||
pathToCallee
|
||||
),
|
||||
]
|
||||
if (endAbsoluteArg) {
|
||||
const { expr, argIndex } = endAbsoluteArg
|
||||
const pathToArgs: PathToNode = [
|
||||
...pathToNode,
|
||||
['arguments', 'CallExpressionKw'],
|
||||
]
|
||||
const pathToArg: PathToNode = [
|
||||
...pathToArgs,
|
||||
[argIndex, ARG_INDEX_FIELD],
|
||||
['arg', LABELED_ARG_FIELD],
|
||||
]
|
||||
if (expr.type !== 'ArrayExpression' || expr.elements.length < 2) {
|
||||
constraints.push({
|
||||
stdLibFnName: 'tangentialArc',
|
||||
type: 'xAbsolute',
|
||||
isConstrained: isNotLiteralArrayOrStatic(expr),
|
||||
sourceRange: topLevelRange(expr.start, expr.end),
|
||||
pathToNode: pathToArg,
|
||||
value: code.slice(expr.start, expr.end),
|
||||
argPosition: {
|
||||
type: 'labeledArgArrayItem',
|
||||
index: 0,
|
||||
key: ARG_END_ABSOLUTE,
|
||||
},
|
||||
})
|
||||
constraints.push({
|
||||
stdLibFnName: 'tangentialArc',
|
||||
type: 'yAbsolute',
|
||||
isConstrained: isNotLiteralArrayOrStatic(expr),
|
||||
sourceRange: topLevelRange(expr.start, expr.end),
|
||||
pathToNode: pathToArg,
|
||||
value: code.slice(expr.start, expr.end),
|
||||
argPosition: {
|
||||
type: 'labeledArgArrayItem',
|
||||
index: 1,
|
||||
key: ARG_END_ABSOLUTE,
|
||||
},
|
||||
})
|
||||
return constraints
|
||||
}
|
||||
const pathToX: PathToNode = [
|
||||
...pathToArg,
|
||||
['elements', 'ArrayExpression'],
|
||||
[0, 'index'],
|
||||
]
|
||||
const pathToY: PathToNode = [
|
||||
...pathToArg,
|
||||
['elements', 'ArrayExpression'],
|
||||
[1, 'index'],
|
||||
]
|
||||
const exprX = expr.elements[0]
|
||||
const exprY = expr.elements[1]
|
||||
constraints.push({
|
||||
stdLibFnName: 'tangentialArc',
|
||||
type: 'xAbsolute',
|
||||
isConstrained: isNotLiteralArrayOrStatic(exprX),
|
||||
sourceRange: topLevelRange(exprX.start, exprX.end),
|
||||
pathToNode: pathToX,
|
||||
value: code.slice(exprX.start, exprX.end),
|
||||
argPosition: {
|
||||
type: 'labeledArgArrayItem',
|
||||
index: 0,
|
||||
key: ARG_END_ABSOLUTE,
|
||||
},
|
||||
})
|
||||
constraints.push({
|
||||
stdLibFnName: 'tangentialArc',
|
||||
type: 'yAbsolute',
|
||||
isConstrained: isNotLiteralArrayOrStatic(exprY),
|
||||
sourceRange: topLevelRange(exprY.start, exprY.end),
|
||||
pathToNode: pathToY,
|
||||
value: code.slice(exprY.start, exprY.end),
|
||||
argPosition: {
|
||||
type: 'labeledArgArrayItem',
|
||||
index: 1,
|
||||
key: ARG_END_ABSOLUTE,
|
||||
},
|
||||
})
|
||||
}
|
||||
return constraints
|
||||
},
|
||||
}
|
||||
|
||||
@ -3155,7 +3311,6 @@ export const sketchLineHelperMapKw: { [key: string]: SketchLineHelperKw } = {
|
||||
angledLineToX,
|
||||
angledLineToY,
|
||||
tangentialArc,
|
||||
tangentialArcTo,
|
||||
startProfile,
|
||||
} as const
|
||||
|
||||
@ -3231,7 +3386,6 @@ export function fnNameToToolTipFromSegment(
|
||||
fnName: string
|
||||
): ToolTip | Error {
|
||||
switch (fnName) {
|
||||
case 'arcTo':
|
||||
case 'arc': {
|
||||
return seg.type === 'ArcThreePoint' ? 'arcTo' : 'arc'
|
||||
}
|
||||
@ -3249,7 +3403,6 @@ export function fnNameToToolTipFromSegment(
|
||||
case 'circleThreePoint':
|
||||
case 'circle':
|
||||
case 'tangentialArc':
|
||||
case 'tangentialArcTo':
|
||||
case 'angledLine':
|
||||
case 'startProfile':
|
||||
case 'arcTo':
|
||||
@ -3273,7 +3426,8 @@ export function fnNameToTooltip(
|
||||
argLabels: string[],
|
||||
fnName: string
|
||||
): ToolTip | Error {
|
||||
const isAbsolute = argLabels.some((label) => label === ARG_END_ABSOLUTE)
|
||||
const isAbsolute =
|
||||
argLabels.findIndex((label) => label === ARG_END_ABSOLUTE) >= 0
|
||||
switch (fnName) {
|
||||
case 'arc': {
|
||||
const isArc = argLabels.some((label) =>
|
||||
@ -3287,11 +3441,10 @@ export function fnNameToTooltip(
|
||||
return isAbsolute ? 'xLineTo' : 'xLine'
|
||||
case 'yLine':
|
||||
return isAbsolute ? 'yLineTo' : 'yLine'
|
||||
case 'tangentialArc':
|
||||
return isAbsolute ? 'tangentialArcTo' : 'tangentialArc'
|
||||
case 'angledLineThatIntersects':
|
||||
case 'circleThreePoint':
|
||||
case 'circle':
|
||||
case 'tangentialArc':
|
||||
case 'startProfile':
|
||||
return fnName
|
||||
case 'angledLine': {
|
||||
@ -3332,7 +3485,6 @@ export function tooltipToFnName(tooltip: ToolTip): string | Error {
|
||||
case 'xLine':
|
||||
case 'yLine':
|
||||
case 'line':
|
||||
case 'tangentialArc':
|
||||
return tooltip
|
||||
case 'lineTo':
|
||||
return 'line'
|
||||
@ -3340,8 +3492,6 @@ export function tooltipToFnName(tooltip: ToolTip): string | Error {
|
||||
return 'xLine'
|
||||
case 'yLineTo':
|
||||
return 'yLine'
|
||||
case 'tangentialArcTo':
|
||||
return 'tangentialArc'
|
||||
case 'angledLine':
|
||||
case 'angledLineToX':
|
||||
case 'angledLineToY':
|
||||
@ -3949,6 +4099,7 @@ export function isAbsoluteLine(lineCall: CallExpressionKw): boolean | Error {
|
||||
const name = lineCall?.callee?.name.name
|
||||
switch (name) {
|
||||
case 'line':
|
||||
case 'tangentialArc':
|
||||
if (findKwArg(ARG_END, lineCall) !== undefined) {
|
||||
return false
|
||||
}
|
||||
@ -3969,8 +4120,6 @@ export function isAbsoluteLine(lineCall: CallExpressionKw): boolean | Error {
|
||||
return new Error(
|
||||
`${name} call has neither ${ARG_END} nor ${ARG_END_ABSOLUTE} params`
|
||||
)
|
||||
case 'tangentialArc':
|
||||
return findKwArg(ARG_END_ABSOLUTE, lineCall) !== undefined
|
||||
case 'angledLineThatIntersects':
|
||||
case 'arc':
|
||||
case 'circle':
|
||||
@ -4002,7 +4151,6 @@ export function getArgForEnd(lineCall: CallExpressionKw):
|
||||
switch (name) {
|
||||
case 'circle':
|
||||
return getCircle(lineCall)
|
||||
case 'tangentialArc':
|
||||
case 'line': {
|
||||
const arg = findKwArgAny(DETERMINING_ARGS, lineCall)
|
||||
if (arg === undefined) {
|
||||
@ -4059,264 +4207,3 @@ export function getArgForEnd(lineCall: CallExpressionKw):
|
||||
function removeDeterminingArgs(callExp: CallExpressionKw) {
|
||||
removeKwArgs(DETERMINING_ARGS, callExp)
|
||||
}
|
||||
|
||||
const tangentialArcHelpers = {
|
||||
add: ({
|
||||
node,
|
||||
pathToNode,
|
||||
segmentInput,
|
||||
replaceExistingCallback,
|
||||
isAbsolute = false,
|
||||
}: {
|
||||
node: Node<Program>
|
||||
pathToNode: PathToNode
|
||||
segmentInput: SegmentInputs
|
||||
replaceExistingCallback?: (
|
||||
rawArgs: RawArgs
|
||||
) => CreatedSketchExprResult | Error
|
||||
isAbsolute?: boolean
|
||||
}) => {
|
||||
if (segmentInput.type !== 'straight-segment') return STRAIGHT_SEGMENT_ERR()
|
||||
const { to, from } = segmentInput
|
||||
const _node = { ...node }
|
||||
const getNode = getNodeFromPathCurry(_node, pathToNode)
|
||||
const _node1 = getNode<PipeExpression | CallExpressionKw>('PipeExpression')
|
||||
if (err(_node1)) return _node1
|
||||
const { node: pipe } = _node1
|
||||
const _node2 = getNodeFromPath<VariableDeclarator>(
|
||||
_node,
|
||||
pathToNode,
|
||||
'VariableDeclarator'
|
||||
)
|
||||
if (err(_node2)) return _node2
|
||||
const { node: varDec } = _node2
|
||||
|
||||
const toX = createLiteral(roundOff(isAbsolute ? to[0] : to[0] - from[0], 2))
|
||||
const toY = createLiteral(roundOff(isAbsolute ? to[1] : to[1] - from[1], 2))
|
||||
|
||||
const argLabel = isAbsolute ? ARG_END_ABSOLUTE : ARG_END
|
||||
const xArgType = isAbsolute ? 'xAbsolute' : 'xRelative'
|
||||
const yArgType = isAbsolute ? 'yAbsolute' : 'yRelative'
|
||||
|
||||
if (replaceExistingCallback && pipe.type !== 'CallExpressionKw') {
|
||||
const { index: callIndex } = splitPathAtPipeExpression(pathToNode)
|
||||
const result = replaceExistingCallback([
|
||||
{
|
||||
type: 'labeledArgArrayItem',
|
||||
key: argLabel,
|
||||
index: 0,
|
||||
argType: xArgType,
|
||||
expr: toX,
|
||||
},
|
||||
{
|
||||
type: 'labeledArgArrayItem',
|
||||
key: argLabel,
|
||||
index: 1,
|
||||
argType: yArgType,
|
||||
expr: toY,
|
||||
},
|
||||
])
|
||||
if (err(result)) return result
|
||||
const { callExp, valueUsedInTransform } = result
|
||||
pipe.body[callIndex] = callExp
|
||||
return {
|
||||
modifiedAst: _node,
|
||||
pathToNode,
|
||||
valueUsedInTransform,
|
||||
}
|
||||
}
|
||||
const newLine = createCallExpressionStdLibKw(
|
||||
'tangentialArc',
|
||||
null, // Assumes this is being called in a pipeline, so the first arg is optional and if not given, will become pipeline substitution.
|
||||
[createLabeledArg(argLabel, createArrayExpression([toX, toY]))]
|
||||
)
|
||||
if (pipe.type === 'PipeExpression') {
|
||||
pipe.body = [...pipe.body, newLine]
|
||||
return {
|
||||
modifiedAst: _node,
|
||||
pathToNode: [
|
||||
...pathToNode.slice(
|
||||
0,
|
||||
pathToNode.findIndex(([_, type]) => type === 'PipeExpression') + 1
|
||||
),
|
||||
['body', 'PipeExpression'],
|
||||
[pipe.body.length - 1, 'CallExpressionKw'],
|
||||
] as PathToNode,
|
||||
}
|
||||
} else {
|
||||
varDec.init = createPipeExpression([varDec.init, newLine])
|
||||
}
|
||||
return {
|
||||
modifiedAst: _node,
|
||||
pathToNode,
|
||||
}
|
||||
},
|
||||
update: ({
|
||||
node,
|
||||
pathToNode,
|
||||
input,
|
||||
isAbsolute = false,
|
||||
}: {
|
||||
node: Node<Program>
|
||||
pathToNode: PathToNode
|
||||
input: SegmentInputs
|
||||
isAbsolute?: boolean
|
||||
}) => {
|
||||
if (input.type !== 'straight-segment') return STRAIGHT_SEGMENT_ERR()
|
||||
const { to, from } = input
|
||||
const _node = { ...node }
|
||||
const nodeMeta = getNodeFromPath<CallExpressionKw>(_node, pathToNode)
|
||||
if (err(nodeMeta)) return nodeMeta
|
||||
const { node: callExpression } = nodeMeta
|
||||
|
||||
if (callExpression.type !== 'CallExpressionKw') {
|
||||
return new Error(
|
||||
`Expected CallExpressionKw, but found ${callExpression.type}`
|
||||
)
|
||||
}
|
||||
|
||||
const argLabel = isAbsolute ? ARG_END_ABSOLUTE : ARG_END
|
||||
const functionName = isAbsolute ? 'tangentialArcTo' : 'tangentialArc'
|
||||
|
||||
for (const arg of callExpression.arguments) {
|
||||
if (arg.label?.name !== argLabel && arg.label?.name !== ARG_TAG) {
|
||||
console.debug(
|
||||
`Trying to edit unsupported ${functionName} keyword arguments; skipping`
|
||||
)
|
||||
return {
|
||||
modifiedAst: _node,
|
||||
pathToNode,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const toArrExp = createArrayExpression([
|
||||
createLiteral(roundOff(isAbsolute ? to[0] : to[0] - from[0], 2)),
|
||||
createLiteral(roundOff(isAbsolute ? to[1] : to[1] - from[1], 2)),
|
||||
])
|
||||
|
||||
mutateKwArg(argLabel, callExpression, toArrExp)
|
||||
return {
|
||||
modifiedAst: _node,
|
||||
pathToNode,
|
||||
}
|
||||
},
|
||||
getConstraintInfo: ({
|
||||
callExp,
|
||||
code,
|
||||
pathToNode,
|
||||
isAbsolute = false,
|
||||
}: {
|
||||
callExp: CallExpressionKw
|
||||
code: string
|
||||
pathToNode: PathToNode
|
||||
isAbsolute?: boolean
|
||||
}): ConstrainInfo[] => {
|
||||
if (callExp.type !== 'CallExpressionKw') return []
|
||||
if (callExp.callee.name.name !== 'tangentialArc') return []
|
||||
|
||||
const callee = callExp.callee
|
||||
const pathToCallee: PathToNode = [
|
||||
...pathToNode,
|
||||
['callee', 'CallExpressionKw'],
|
||||
]
|
||||
|
||||
const argLabel = isAbsolute ? ARG_END_ABSOLUTE : ARG_END
|
||||
const xConstraintType = isAbsolute ? 'xAbsolute' : 'xRelative'
|
||||
const yConstraintType = isAbsolute ? 'yAbsolute' : 'yRelative'
|
||||
|
||||
const endArg = findKwArgWithIndex(argLabel, callExp)
|
||||
|
||||
const constraints: ConstrainInfo[] = [
|
||||
constrainInfo(
|
||||
'tangentialWithPrevious',
|
||||
true,
|
||||
callee.name.name,
|
||||
'tangentialArc',
|
||||
undefined,
|
||||
topLevelRange(callee.start, callee.end),
|
||||
pathToCallee
|
||||
),
|
||||
]
|
||||
if (endArg) {
|
||||
const { expr, argIndex } = endArg
|
||||
const pathToArgs: PathToNode = [
|
||||
...pathToNode,
|
||||
['arguments', 'CallExpressionKw'],
|
||||
]
|
||||
const pathToArg: PathToNode = [
|
||||
...pathToArgs,
|
||||
[argIndex, ARG_INDEX_FIELD],
|
||||
['arg', LABELED_ARG_FIELD],
|
||||
]
|
||||
if (expr.type !== 'ArrayExpression' || expr.elements.length < 2) {
|
||||
constraints.push({
|
||||
stdLibFnName: 'tangentialArc',
|
||||
type: xConstraintType,
|
||||
isConstrained: isNotLiteralArrayOrStatic(expr),
|
||||
sourceRange: topLevelRange(expr.start, expr.end),
|
||||
pathToNode: pathToArg,
|
||||
value: code.slice(expr.start, expr.end),
|
||||
argPosition: {
|
||||
type: 'labeledArgArrayItem',
|
||||
index: 0,
|
||||
key: argLabel,
|
||||
},
|
||||
})
|
||||
constraints.push({
|
||||
stdLibFnName: 'tangentialArc',
|
||||
type: yConstraintType,
|
||||
isConstrained: isNotLiteralArrayOrStatic(expr),
|
||||
sourceRange: topLevelRange(expr.start, expr.end),
|
||||
pathToNode: pathToArg,
|
||||
value: code.slice(expr.start, expr.end),
|
||||
argPosition: {
|
||||
type: 'labeledArgArrayItem',
|
||||
index: 1,
|
||||
key: argLabel,
|
||||
},
|
||||
})
|
||||
return constraints
|
||||
}
|
||||
const pathToX: PathToNode = [
|
||||
...pathToArg,
|
||||
['elements', 'ArrayExpression'],
|
||||
[0, 'index'],
|
||||
]
|
||||
const pathToY: PathToNode = [
|
||||
...pathToArg,
|
||||
['elements', 'ArrayExpression'],
|
||||
[1, 'index'],
|
||||
]
|
||||
const exprX = expr.elements[0]
|
||||
const exprY = expr.elements[1]
|
||||
constraints.push({
|
||||
stdLibFnName: 'tangentialArc',
|
||||
type: xConstraintType,
|
||||
isConstrained: isNotLiteralArrayOrStatic(exprX),
|
||||
sourceRange: topLevelRange(exprX.start, exprX.end),
|
||||
pathToNode: pathToX,
|
||||
value: code.slice(exprX.start, exprX.end),
|
||||
argPosition: {
|
||||
type: 'labeledArgArrayItem',
|
||||
index: 0,
|
||||
key: argLabel,
|
||||
},
|
||||
})
|
||||
constraints.push({
|
||||
stdLibFnName: 'tangentialArc',
|
||||
type: yConstraintType,
|
||||
isConstrained: isNotLiteralArrayOrStatic(exprY),
|
||||
sourceRange: topLevelRange(exprY.start, exprY.end),
|
||||
pathToNode: pathToY,
|
||||
value: code.slice(exprY.start, exprY.end),
|
||||
argPosition: {
|
||||
type: 'labeledArgArrayItem',
|
||||
index: 1,
|
||||
key: argLabel,
|
||||
},
|
||||
})
|
||||
}
|
||||
return constraints
|
||||
},
|
||||
}
|
||||
|
@ -1502,20 +1502,23 @@ export function removeSingleConstraint({
|
||||
const literal = rawArg?.overrideExpr ?? rawArg?.expr
|
||||
return (arg.index === inputToReplace.index && literal) || argExpr
|
||||
})
|
||||
|
||||
// It's a kw call.
|
||||
const isAbsolute = inputs.some((input) => input.argType === 'xAbsolute')
|
||||
const args = [
|
||||
createLabeledArg(
|
||||
isAbsolute ? ARG_END_ABSOLUTE : ARG_END,
|
||||
createArrayExpression(values)
|
||||
),
|
||||
]
|
||||
return createStdlibCallExpressionKw(
|
||||
callExp.node.callee.name.name as ToolTip,
|
||||
args,
|
||||
tag
|
||||
)
|
||||
const isAbsolute = callExp.node.callee.name.name == 'lineTo'
|
||||
if (isAbsolute) {
|
||||
const args = [
|
||||
createLabeledArg(ARG_END_ABSOLUTE, createArrayExpression(values)),
|
||||
]
|
||||
return createStdlibCallExpressionKw('line', args, tag)
|
||||
} else {
|
||||
const args = [
|
||||
createLabeledArg(ARG_END, createArrayExpression(values)),
|
||||
]
|
||||
return createStdlibCallExpressionKw(
|
||||
callExp.node.callee.name.name as ToolTip,
|
||||
args,
|
||||
tag
|
||||
)
|
||||
}
|
||||
}
|
||||
if (
|
||||
inputToReplace.type === 'arrayInObject' ||
|
||||
|
@ -1,12 +1,7 @@
|
||||
import type { Operation } from '@rust/kcl-lib/bindings/Operation'
|
||||
import { topLevelRange } from '@src/lang/util'
|
||||
|
||||
import {
|
||||
assertParse,
|
||||
defaultSourceRange,
|
||||
type SourceRange,
|
||||
} from '@src/lang/wasm'
|
||||
import { filterOperations, getOperationVariableName } from '@src/lib/operations'
|
||||
import { defaultSourceRange } from '@src/lang/wasm'
|
||||
import { filterOperations } from '@src/lib/operations'
|
||||
|
||||
function stdlib(name: string): Operation {
|
||||
return {
|
||||
@ -167,75 +162,3 @@ describe('operations filtering', () => {
|
||||
])
|
||||
})
|
||||
})
|
||||
|
||||
function rangeOfText(fullCode: string, target: string): SourceRange {
|
||||
const start = fullCode.indexOf(target)
|
||||
if (start === -1) {
|
||||
throw new Error(`Could not find \`${target}\` in: ${fullCode}`)
|
||||
}
|
||||
return topLevelRange(start, start + target.length)
|
||||
}
|
||||
|
||||
describe('variable name of operations', () => {
|
||||
it('finds the variable name with simple assignment', async () => {
|
||||
const op = stdlib('stdLibFn')
|
||||
if (op.type !== 'StdLibCall') {
|
||||
throw new Error('Expected operation to be a StdLibCall')
|
||||
}
|
||||
const code = `myVar = stdLibFn()`
|
||||
// Make the source range match the code.
|
||||
op.sourceRange = rangeOfText(code, 'stdLibFn()')
|
||||
|
||||
const program = assertParse(code)
|
||||
const variableName = getOperationVariableName(op, program)
|
||||
expect(variableName).toBe('myVar')
|
||||
})
|
||||
it('finds the variable name inside a function with simple assignment', async () => {
|
||||
const op = stdlib('stdLibFn')
|
||||
if (op.type !== 'StdLibCall') {
|
||||
throw new Error('Expected operation to be a StdLibCall')
|
||||
}
|
||||
const code = `fn myFunc() {
|
||||
myVar = stdLibFn()
|
||||
return 0
|
||||
}
|
||||
`
|
||||
// Make the source range match the code.
|
||||
op.sourceRange = rangeOfText(code, 'stdLibFn()')
|
||||
|
||||
const program = assertParse(code)
|
||||
const variableName = getOperationVariableName(op, program)
|
||||
expect(variableName).toBe('myVar')
|
||||
})
|
||||
it("finds the variable name when it's the last in a pipeline", async () => {
|
||||
const op = stdlib('stdLibFn')
|
||||
if (op.type !== 'StdLibCall') {
|
||||
throw new Error('Expected operation to be a StdLibCall')
|
||||
}
|
||||
const code = `myVar = foo()
|
||||
|> stdLibFn()
|
||||
`
|
||||
// Make the source range match the code.
|
||||
op.sourceRange = rangeOfText(code, 'stdLibFn()')
|
||||
|
||||
const program = assertParse(code)
|
||||
const variableName = getOperationVariableName(op, program)
|
||||
expect(variableName).toBe('myVar')
|
||||
})
|
||||
it("finds nothing when it's not the last in a pipeline", async () => {
|
||||
const op = stdlib('stdLibFn')
|
||||
if (op.type !== 'StdLibCall') {
|
||||
throw new Error('Expected operation to be a StdLibCall')
|
||||
}
|
||||
const code = `myVar = foo()
|
||||
|> stdLibFn()
|
||||
|> bar()
|
||||
`
|
||||
// Make the source range match the code.
|
||||
op.sourceRange = rangeOfText(code, 'stdLibFn()')
|
||||
|
||||
const program = assertParse(code)
|
||||
const variableName = getOperationVariableName(op, program)
|
||||
expect(variableName).toBeUndefined()
|
||||
})
|
||||
})
|
||||
|
@ -15,13 +15,7 @@ import {
|
||||
getSweepEdgeCodeRef,
|
||||
getWallCodeRef,
|
||||
} from '@src/lang/std/artifactGraph'
|
||||
import {
|
||||
type CallExpressionKw,
|
||||
type PipeExpression,
|
||||
type Program,
|
||||
sourceRangeFromRust,
|
||||
type VariableDeclaration,
|
||||
} from '@src/lang/wasm'
|
||||
import { type PipeExpression, sourceRangeFromRust } from '@src/lang/wasm'
|
||||
import type {
|
||||
HelixModes,
|
||||
ModelingCommandSchema,
|
||||
@ -1080,71 +1074,6 @@ export function getOperationIcon(op: Operation): CustomIconName {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If the result of the operation is assigned to a variable, returns the
|
||||
* variable name.
|
||||
*/
|
||||
export function getOperationVariableName(
|
||||
op: Operation,
|
||||
program: Program
|
||||
): string | undefined {
|
||||
if (
|
||||
op.type !== 'StdLibCall' &&
|
||||
!(op.type === 'GroupBegin' && op.group.type === 'FunctionCall')
|
||||
) {
|
||||
return undefined
|
||||
}
|
||||
// Find the AST node.
|
||||
const range = sourceRangeFromRust(op.sourceRange)
|
||||
const pathToNode = getNodePathFromSourceRange(program, range)
|
||||
if (pathToNode.length === 0) {
|
||||
return undefined
|
||||
}
|
||||
const call = getNodeFromPath<CallExpressionKw>(
|
||||
program,
|
||||
pathToNode,
|
||||
'CallExpressionKw'
|
||||
)
|
||||
if (err(call) || call.node.type !== 'CallExpressionKw') {
|
||||
return undefined
|
||||
}
|
||||
// Find the var name from the variable declaration.
|
||||
const varDec = getNodeFromPath<VariableDeclaration>(
|
||||
program,
|
||||
pathToNode,
|
||||
'VariableDeclaration'
|
||||
)
|
||||
if (err(varDec)) {
|
||||
return undefined
|
||||
}
|
||||
if (varDec.node.type !== 'VariableDeclaration') {
|
||||
// There's no variable declaration for this call.
|
||||
return undefined
|
||||
}
|
||||
const varName = varDec.node.declaration.id.name
|
||||
// If the operation is a simple assignment, we can use the variable name.
|
||||
if (varDec.node.declaration.init === call.node) {
|
||||
return varName
|
||||
}
|
||||
// If the AST node is in a pipe expression, we can only use the variable
|
||||
// name if it's the last operation in the pipe.
|
||||
const pipe = getNodeFromPath<PipeExpression>(
|
||||
program,
|
||||
pathToNode,
|
||||
'PipeExpression'
|
||||
)
|
||||
if (err(pipe)) {
|
||||
return undefined
|
||||
}
|
||||
if (
|
||||
pipe.node.type === 'PipeExpression' &&
|
||||
pipe.node.body[pipe.node.body.length - 1] === call.node
|
||||
) {
|
||||
return varName
|
||||
}
|
||||
return undefined
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply all filters to a list of operations.
|
||||
*/
|
||||
|
@ -703,7 +703,8 @@ export async function sendSelectEventToEngine(
|
||||
cmd_id: uuidv4(),
|
||||
})
|
||||
if (!res) {
|
||||
return Promise.reject('no response')
|
||||
console.warn('No response')
|
||||
return undefined
|
||||
}
|
||||
|
||||
if (isArray(res)) {
|
||||
|
@ -70,7 +70,6 @@ export async function holdOntoVideoFrameInCanvas(
|
||||
video: HTMLVideoElement,
|
||||
canvas: HTMLCanvasElement
|
||||
) {
|
||||
video.pause()
|
||||
canvas.width = video.videoWidth
|
||||
canvas.height = video.videoHeight
|
||||
canvas.style.width = video.videoWidth + 'px'
|
||||
@ -220,11 +219,14 @@ export const engineStreamMachine = setup({
|
||||
if (context.videoRef.current && context.canvasRef.current) {
|
||||
await context.videoRef.current.pause()
|
||||
|
||||
await holdOntoVideoFrameInCanvas(
|
||||
context.videoRef.current,
|
||||
context.canvasRef.current
|
||||
)
|
||||
context.videoRef.current.style.display = 'none'
|
||||
// It's possible we've already frozen the frame due to a disconnect.
|
||||
if (context.videoRef.current.style.display !== 'none') {
|
||||
await holdOntoVideoFrameInCanvas(
|
||||
context.videoRef.current,
|
||||
context.canvasRef.current
|
||||
)
|
||||
context.videoRef.current.style.display = 'none'
|
||||
}
|
||||
}
|
||||
|
||||
await rootContext.sceneInfra.camControls.saveRemoteCameraState()
|
||||
@ -365,9 +367,12 @@ export const engineStreamMachine = setup({
|
||||
}),
|
||||
},
|
||||
on: {
|
||||
[EngineStreamTransition.StartOrReconfigureEngine]: {
|
||||
[EngineStreamTransition.Resume]: {
|
||||
target: EngineStreamState.Resuming,
|
||||
},
|
||||
[EngineStreamTransition.Stop]: {
|
||||
target: EngineStreamState.Stopped,
|
||||
},
|
||||
},
|
||||
},
|
||||
[EngineStreamState.Stopped]: {
|
||||
@ -398,12 +403,23 @@ export const engineStreamMachine = setup({
|
||||
rootContext: args.self.system.get('root').getSnapshot().context,
|
||||
event: args.event,
|
||||
}),
|
||||
// Usually only fails if there was a disconnection mid-way.
|
||||
onError: [
|
||||
{
|
||||
target: EngineStreamState.WaitingForDependencies,
|
||||
reenter: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
on: {
|
||||
// The stream can be paused as it's resuming.
|
||||
[EngineStreamTransition.Pause]: {
|
||||
target: EngineStreamState.Paused,
|
||||
},
|
||||
// The stream can be stopped as it's resuming.
|
||||
[EngineStreamTransition.Stop]: {
|
||||
target: EngineStreamState.Stopped,
|
||||
},
|
||||
[EngineStreamTransition.SetMediaStream]: {
|
||||
target: EngineStreamState.Playing,
|
||||
actions: [
|
||||
|