Move artifact graph out of engine connection (#6062)
* cleanups Signed-off-by: Jess Frazelle <github@jessfraz.com> * cleanups Signed-off-by: Jess Frazelle <github@jessfraz.com> * fmt Signed-off-by: Jess Frazelle <github@jessfraz.com> --------- Signed-off-by: Jess Frazelle <github@jessfraz.com>
This commit is contained in:
@ -1,6 +1,6 @@
|
|||||||
import { useRef, useMemo, memo, useCallback, useState } from 'react'
|
import { useRef, useMemo, memo, useCallback, useState } from 'react'
|
||||||
import { isCursorInSketchCommandRange } from 'lang/util'
|
import { isCursorInSketchCommandRange } from 'lang/util'
|
||||||
import { editorManager, engineCommandManager, kclManager } from 'lib/singletons'
|
import { editorManager, kclManager } from 'lib/singletons'
|
||||||
import { useModelingContext } from 'hooks/useModelingContext'
|
import { useModelingContext } from 'hooks/useModelingContext'
|
||||||
import { useNetworkContext } from 'hooks/useNetworkContext'
|
import { useNetworkContext } from 'hooks/useNetworkContext'
|
||||||
import { NetworkHealthState } from 'hooks/useNetworkStatus'
|
import { NetworkHealthState } from 'hooks/useNetworkStatus'
|
||||||
@ -45,10 +45,10 @@ export function Toolbar({
|
|||||||
)
|
)
|
||||||
return false
|
return false
|
||||||
return isCursorInSketchCommandRange(
|
return isCursorInSketchCommandRange(
|
||||||
engineCommandManager.artifactGraph,
|
kclManager.artifactGraph,
|
||||||
context.selectionRanges
|
context.selectionRanges
|
||||||
)
|
)
|
||||||
}, [engineCommandManager.artifactGraph, context.selectionRanges])
|
}, [kclManager.artifactGraph, context.selectionRanges])
|
||||||
|
|
||||||
const toolbarButtonsRef = useRef<HTMLUListElement>(null)
|
const toolbarButtonsRef = useRef<HTMLUListElement>(null)
|
||||||
const { overallState } = useNetworkContext()
|
const { overallState } = useNetworkContext()
|
||||||
|
@ -3700,7 +3700,7 @@ function computeSelectionFromSourceRangeAndAST(
|
|||||||
sourceRange: SourceRange,
|
sourceRange: SourceRange,
|
||||||
ast: Node<Program>
|
ast: Node<Program>
|
||||||
): Selections {
|
): Selections {
|
||||||
const artifactGraph = engineCommandManager.artifactGraph
|
const artifactGraph = kclManager.artifactGraph
|
||||||
const artifact = getArtifactFromRange(sourceRange, artifactGraph) || undefined
|
const artifact = getArtifactFromRange(sourceRange, artifactGraph) || undefined
|
||||||
const selection: Selections = {
|
const selection: Selections = {
|
||||||
graphSelections: [
|
graphSelections: [
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { useModelingContext } from 'hooks/useModelingContext'
|
import { useModelingContext } from 'hooks/useModelingContext'
|
||||||
import { editorManager, engineCommandManager, kclManager } from 'lib/singletons'
|
import { editorManager, kclManager } from 'lib/singletons'
|
||||||
import { getNodeFromPath } from 'lang/queryAst'
|
import { getNodeFromPath } from 'lang/queryAst'
|
||||||
import { getNodePathFromSourceRange } from 'lang/queryAstNodePathUtils'
|
import { getNodePathFromSourceRange } from 'lang/queryAstNodePathUtils'
|
||||||
import { useEffect, useRef, useState } from 'react'
|
import { useEffect, useRef, useState } from 'react'
|
||||||
@ -135,12 +135,10 @@ function DisplayObj({
|
|||||||
const range = topLevelRange(obj?.start || 0, obj.end || 0)
|
const range = topLevelRange(obj?.start || 0, obj.end || 0)
|
||||||
const idInfo = codeToIdSelections(
|
const idInfo = codeToIdSelections(
|
||||||
[{ codeRef: codeRefFromRange(range, kclManager.ast) }],
|
[{ codeRef: codeRefFromRange(range, kclManager.ast) }],
|
||||||
engineCommandManager.artifactGraph,
|
kclManager.artifactGraph,
|
||||||
engineCommandManager.artifactIndex
|
kclManager.artifactIndex
|
||||||
)[0]
|
)[0]
|
||||||
const artifact = engineCommandManager.artifactGraph.get(
|
const artifact = kclManager.artifactGraph.get(idInfo?.id || '')
|
||||||
idInfo?.id || ''
|
|
||||||
)
|
|
||||||
if (!artifact) return
|
if (!artifact) return
|
||||||
send({
|
send({
|
||||||
type: 'Set selection',
|
type: 'Set selection',
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
import { useMemo } from 'react'
|
import { useMemo } from 'react'
|
||||||
import { engineCommandManager } from 'lib/singletons'
|
import { kclManager } from 'lib/singletons'
|
||||||
import { expandPlane, PlaneArtifactRich } from 'lang/std/artifactGraph'
|
import { expandPlane, PlaneArtifactRich } from 'lang/std/artifactGraph'
|
||||||
import { ArtifactGraph } from 'lang/wasm'
|
import { ArtifactGraph } from 'lang/wasm'
|
||||||
import { DebugDisplayArray, GenericObj } from './DebugDisplayObj'
|
import { DebugDisplayArray, GenericObj } from './DebugDisplayObj'
|
||||||
|
|
||||||
export function DebugArtifactGraph() {
|
export function DebugArtifactGraph() {
|
||||||
const artifactGraphTree = useMemo(() => {
|
const artifactGraphTree = useMemo(() => {
|
||||||
return computeTree(engineCommandManager.artifactGraph)
|
return computeTree(kclManager.artifactGraph)
|
||||||
}, [engineCommandManager.artifactGraph])
|
}, [kclManager.artifactGraph])
|
||||||
|
|
||||||
const filterKeys: string[] = ['codeRef', 'pathToNode']
|
const filterKeys: string[] = ['codeRef', 'pathToNode']
|
||||||
return (
|
return (
|
||||||
|
@ -566,7 +566,7 @@ export const ModelingMachineProvider = ({
|
|||||||
// See if the selection is "close enough" to be coerced to the plane later
|
// See if the selection is "close enough" to be coerced to the plane later
|
||||||
const maybePlane = getPlaneFromArtifact(
|
const maybePlane = getPlaneFromArtifact(
|
||||||
selectionRanges.graphSelections[0].artifact,
|
selectionRanges.graphSelections[0].artifact,
|
||||||
engineCommandManager.artifactGraph
|
kclManager.artifactGraph
|
||||||
)
|
)
|
||||||
return !err(maybePlane)
|
return !err(maybePlane)
|
||||||
}
|
}
|
||||||
@ -579,7 +579,7 @@ export const ModelingMachineProvider = ({
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return !!isCursorInSketchCommandRange(
|
return !!isCursorInSketchCommandRange(
|
||||||
engineCommandManager.artifactGraph,
|
kclManager.artifactGraph,
|
||||||
selectionRanges
|
selectionRanges
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
@ -841,7 +841,7 @@ export const ModelingMachineProvider = ({
|
|||||||
const artifact = selectionRanges.graphSelections[0].artifact
|
const artifact = selectionRanges.graphSelections[0].artifact
|
||||||
const plane = getPlaneFromArtifact(
|
const plane = getPlaneFromArtifact(
|
||||||
artifact,
|
artifact,
|
||||||
engineCommandManager.artifactGraph
|
kclManager.artifactGraph
|
||||||
)
|
)
|
||||||
if (err(plane)) return Promise.reject(plane)
|
if (err(plane)) return Promise.reject(plane)
|
||||||
// if the user selected a segment, make sure we enter the right sketch as there can be multiple on a plane
|
// if the user selected a segment, make sure we enter the right sketch as there can be multiple on a plane
|
||||||
@ -917,14 +917,13 @@ export const ModelingMachineProvider = ({
|
|||||||
info?.sketchDetails?.faceId || ''
|
info?.sketchDetails?.faceId || ''
|
||||||
)
|
)
|
||||||
|
|
||||||
const sketchArtifact =
|
const sketchArtifact = kclManager.artifactGraph.get(mainPath)
|
||||||
engineCommandManager.artifactGraph.get(mainPath)
|
|
||||||
if (sketchArtifact?.type !== 'path')
|
if (sketchArtifact?.type !== 'path')
|
||||||
return Promise.reject(new Error('No sketch artifact'))
|
return Promise.reject(new Error('No sketch artifact'))
|
||||||
const sketchPaths = getPathsFromArtifact({
|
const sketchPaths = getPathsFromArtifact({
|
||||||
artifact: engineCommandManager.artifactGraph.get(plane.id),
|
artifact: kclManager.artifactGraph.get(plane.id),
|
||||||
sketchPathToNode: sketchArtifact?.codeRef?.pathToNode,
|
sketchPathToNode: sketchArtifact?.codeRef?.pathToNode,
|
||||||
artifactGraph: engineCommandManager.artifactGraph,
|
artifactGraph: kclManager.artifactGraph,
|
||||||
ast: kclManager.ast,
|
ast: kclManager.ast,
|
||||||
})
|
})
|
||||||
if (err(sketchPaths)) return Promise.reject(sketchPaths)
|
if (err(sketchPaths)) return Promise.reject(sketchPaths)
|
||||||
@ -1743,7 +1742,7 @@ export const ModelingMachineProvider = ({
|
|||||||
prompt: input.prompt,
|
prompt: input.prompt,
|
||||||
selections: input.selection,
|
selections: input.selection,
|
||||||
token,
|
token,
|
||||||
artifactGraph: engineCommandManager.artifactGraph,
|
artifactGraph: kclManager.artifactGraph,
|
||||||
projectName: context.project.name,
|
projectName: context.project.name,
|
||||||
})
|
})
|
||||||
}),
|
}),
|
||||||
|
@ -13,7 +13,7 @@ import {
|
|||||||
getOperationLabel,
|
getOperationLabel,
|
||||||
stdLibMap,
|
stdLibMap,
|
||||||
} from 'lib/operations'
|
} from 'lib/operations'
|
||||||
import { editorManager, engineCommandManager, kclManager } from 'lib/singletons'
|
import { editorManager, kclManager } from 'lib/singletons'
|
||||||
import { ComponentProps, useEffect, useMemo, useRef, useState } from 'react'
|
import { ComponentProps, useEffect, useMemo, useRef, useState } from 'react'
|
||||||
import { Operation } from '@rust/kcl-lib/bindings/Operation'
|
import { Operation } from '@rust/kcl-lib/bindings/Operation'
|
||||||
import { Actor, Prop } from 'xstate'
|
import { Actor, Prop } from 'xstate'
|
||||||
@ -58,7 +58,7 @@ export const FeatureTreePane = () => {
|
|||||||
const artifact = context.targetSourceRange
|
const artifact = context.targetSourceRange
|
||||||
? getArtifactFromRange(
|
? getArtifactFromRange(
|
||||||
context.targetSourceRange,
|
context.targetSourceRange,
|
||||||
engineCommandManager.artifactGraph
|
kclManager.artifactGraph
|
||||||
)
|
)
|
||||||
: null
|
: null
|
||||||
|
|
||||||
|
@ -304,7 +304,7 @@ export const Stream = () => {
|
|||||||
}
|
}
|
||||||
const path = getArtifactOfTypes(
|
const path = getArtifactOfTypes(
|
||||||
{ key: entity_id, types: ['path', 'solid2d', 'segment', 'helix'] },
|
{ key: entity_id, types: ['path', 'solid2d', 'segment', 'helix'] },
|
||||||
engineCommandManager.artifactGraph
|
kclManager.artifactGraph
|
||||||
)
|
)
|
||||||
if (err(path)) {
|
if (err(path)) {
|
||||||
return path
|
return path
|
||||||
|
@ -16,7 +16,7 @@ import { TransformInfo } from 'lang/std/stdTypes'
|
|||||||
import { GetInfoModal, createInfoModal } from '../SetHorVertDistanceModal'
|
import { GetInfoModal, createInfoModal } from '../SetHorVertDistanceModal'
|
||||||
import { createVariableDeclaration } from '../../lang/modifyAst'
|
import { createVariableDeclaration } from '../../lang/modifyAst'
|
||||||
import { removeDoubleNegatives } from '../AvailableVarsHelpers'
|
import { removeDoubleNegatives } from '../AvailableVarsHelpers'
|
||||||
import { engineCommandManager, kclManager } from 'lib/singletons'
|
import { kclManager } from 'lib/singletons'
|
||||||
import { err } from 'lib/trap'
|
import { err } from 'lib/trap'
|
||||||
import { Node } from '@rust/kcl-lib/bindings/Node'
|
import { Node } from '@rust/kcl-lib/bindings/Node'
|
||||||
|
|
||||||
@ -45,7 +45,7 @@ export function intersectInfo({
|
|||||||
selectionRanges.graphSelections.length > 1 &&
|
selectionRanges.graphSelections.length > 1 &&
|
||||||
isLinesParallelAndConstrained(
|
isLinesParallelAndConstrained(
|
||||||
kclManager.ast,
|
kclManager.ast,
|
||||||
engineCommandManager.artifactGraph,
|
kclManager.artifactGraph,
|
||||||
kclManager.variables,
|
kclManager.variables,
|
||||||
selectionRanges.graphSelections[0],
|
selectionRanges.graphSelections[0],
|
||||||
selectionRanges.graphSelections[1]
|
selectionRanges.graphSelections[1]
|
||||||
|
@ -374,7 +374,7 @@ export default class EditorManager {
|
|||||||
selectionRanges: this._selectionRanges,
|
selectionRanges: this._selectionRanges,
|
||||||
isShiftDown: this._isShiftDown,
|
isShiftDown: this._isShiftDown,
|
||||||
ast: kclManager.ast,
|
ast: kclManager.ast,
|
||||||
artifactGraph: engineCommandManager.artifactGraph,
|
artifactGraph: kclManager.artifactGraph,
|
||||||
})
|
})
|
||||||
|
|
||||||
if (!eventInfo) {
|
if (!eventInfo) {
|
||||||
|
@ -39,7 +39,7 @@ export function useEngineConnectionSubscriptions() {
|
|||||||
if (data?.entity_id) {
|
if (data?.entity_id) {
|
||||||
const codeRefs = getCodeRefsByArtifactId(
|
const codeRefs = getCodeRefsByArtifactId(
|
||||||
data.entity_id,
|
data.entity_id,
|
||||||
engineCommandManager.artifactGraph
|
kclManager.artifactGraph
|
||||||
)
|
)
|
||||||
if (codeRefs) {
|
if (codeRefs) {
|
||||||
editorManager.setHighlightRange(codeRefs.map(({ range }) => range))
|
editorManager.setHighlightRange(codeRefs.map(({ range }) => range))
|
||||||
@ -140,8 +140,7 @@ export function useEngineConnectionSubscriptions() {
|
|||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const artifact =
|
const artifact = kclManager.artifactGraph.get(planeOrFaceId)
|
||||||
engineCommandManager.artifactGraph.get(planeOrFaceId)
|
|
||||||
|
|
||||||
if (artifact?.type === 'plane') {
|
if (artifact?.type === 'plane') {
|
||||||
const planeInfo = await getFaceDetails(planeOrFaceId)
|
const planeInfo = await getFaceDetails(planeOrFaceId)
|
||||||
@ -179,7 +178,7 @@ export function useEngineConnectionSubscriptions() {
|
|||||||
const faceId = planeOrFaceId
|
const faceId = planeOrFaceId
|
||||||
const extrusion = getSweepFromSuspectedSweepSurface(
|
const extrusion = getSweepFromSuspectedSweepSurface(
|
||||||
faceId,
|
faceId,
|
||||||
engineCommandManager.artifactGraph
|
kclManager.artifactGraph
|
||||||
)
|
)
|
||||||
|
|
||||||
if (
|
if (
|
||||||
@ -193,9 +192,9 @@ export function useEngineConnectionSubscriptions() {
|
|||||||
|
|
||||||
const codeRef =
|
const codeRef =
|
||||||
artifact.type === 'cap'
|
artifact.type === 'cap'
|
||||||
? getCapCodeRef(artifact, engineCommandManager.artifactGraph)
|
? getCapCodeRef(artifact, kclManager.artifactGraph)
|
||||||
: artifact.type === 'wall'
|
: artifact.type === 'wall'
|
||||||
? getWallCodeRef(artifact, engineCommandManager.artifactGraph)
|
? getWallCodeRef(artifact, kclManager.artifactGraph)
|
||||||
: artifact.codeRef
|
: artifact.codeRef
|
||||||
|
|
||||||
const faceInfo = await getFaceDetails(faceId)
|
const faceInfo = await getFaceDetails(faceId)
|
||||||
@ -221,7 +220,7 @@ export function useEngineConnectionSubscriptions() {
|
|||||||
key: artifact.consumedEdgeId,
|
key: artifact.consumedEdgeId,
|
||||||
types: ['segment', 'sweepEdge'],
|
types: ['segment', 'sweepEdge'],
|
||||||
},
|
},
|
||||||
engineCommandManager.artifactGraph
|
kclManager.artifactGraph
|
||||||
)
|
)
|
||||||
if (err(consumedArtifact)) return null
|
if (err(consumedArtifact)) return null
|
||||||
if (consumedArtifact.type === 'segment') {
|
if (consumedArtifact.type === 'segment') {
|
||||||
@ -232,7 +231,7 @@ export function useEngineConnectionSubscriptions() {
|
|||||||
} else {
|
} else {
|
||||||
const segment = getArtifactOfTypes(
|
const segment = getArtifactOfTypes(
|
||||||
{ key: consumedArtifact.segId, types: ['segment'] },
|
{ key: consumedArtifact.segId, types: ['segment'] },
|
||||||
engineCommandManager.artifactGraph
|
kclManager.artifactGraph
|
||||||
)
|
)
|
||||||
if (err(segment)) return null
|
if (err(segment)) return null
|
||||||
chamferInfo = {
|
chamferInfo = {
|
||||||
|
@ -5,10 +5,12 @@ import {
|
|||||||
compilationErrorsToDiagnostics,
|
compilationErrorsToDiagnostics,
|
||||||
kclErrorsToDiagnostics,
|
kclErrorsToDiagnostics,
|
||||||
} from './errors'
|
} from './errors'
|
||||||
import { uuidv4 } from 'lib/utils'
|
import { uuidv4, isOverlap, deferExecution } from 'lib/utils'
|
||||||
import { EngineCommandManager } from './std/engineConnection'
|
import { EngineCommandManager } from './std/engineConnection'
|
||||||
import { err, reportRejection } from 'lib/trap'
|
import { err, reportRejection } from 'lib/trap'
|
||||||
import { EXECUTE_AST_INTERRUPT_ERROR_MESSAGE } from 'lib/constants'
|
import { EXECUTE_AST_INTERRUPT_ERROR_MESSAGE } from 'lib/constants'
|
||||||
|
import { buildArtifactIndex } from 'lib/artifactIndex'
|
||||||
|
import { ArtifactIndex } from 'lib/artifactIndex'
|
||||||
|
|
||||||
import {
|
import {
|
||||||
emptyExecState,
|
emptyExecState,
|
||||||
@ -24,6 +26,7 @@ import {
|
|||||||
SourceRange,
|
SourceRange,
|
||||||
topLevelRange,
|
topLevelRange,
|
||||||
VariableMap,
|
VariableMap,
|
||||||
|
ArtifactGraph,
|
||||||
} from 'lang/wasm'
|
} from 'lang/wasm'
|
||||||
import { getNodeFromPath, getSettingsAnnotation } from './queryAst'
|
import { getNodeFromPath, getSettingsAnnotation } from './queryAst'
|
||||||
import {
|
import {
|
||||||
@ -53,6 +56,14 @@ interface ExecuteArgs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class KclManager {
|
export class KclManager {
|
||||||
|
/**
|
||||||
|
* The artifactGraph is a client-side representation of the commands that have been sent
|
||||||
|
* see: src/lang/std/artifactGraph-README.md for a full explanation.
|
||||||
|
*/
|
||||||
|
artifactGraph: ArtifactGraph = new Map()
|
||||||
|
artifactIndex: ArtifactIndex = []
|
||||||
|
defaultPlanesShown: boolean = false
|
||||||
|
|
||||||
private _ast: Node<Program> = {
|
private _ast: Node<Program> = {
|
||||||
body: [],
|
body: [],
|
||||||
shebang: null,
|
shebang: null,
|
||||||
@ -289,6 +300,47 @@ export class KclManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async updateArtifactGraph(
|
||||||
|
execStateArtifactGraph: ExecState['artifactGraph']
|
||||||
|
) {
|
||||||
|
this.artifactGraph = execStateArtifactGraph
|
||||||
|
this.artifactIndex = buildArtifactIndex(execStateArtifactGraph)
|
||||||
|
if (this.artifactGraph.size) {
|
||||||
|
// TODO: we wanna remove this logic from xstate, it is racey
|
||||||
|
// This defer is bullshit but playwright wants it
|
||||||
|
// It was like this in engineConnection.ts already
|
||||||
|
deferExecution((a?: null) => {
|
||||||
|
this.engineCommandManager.modelingSend({
|
||||||
|
type: 'Artifact graph emptied',
|
||||||
|
})
|
||||||
|
}, 200)(null)
|
||||||
|
} else {
|
||||||
|
deferExecution((a?: null) => {
|
||||||
|
this.engineCommandManager.modelingSend({
|
||||||
|
type: 'Artifact graph populated',
|
||||||
|
})
|
||||||
|
}, 200)(null)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Some "objects" have the same source range, such as sketch_mode_start and start_path.
|
||||||
|
// So when passing a range, we need to also specify the command type
|
||||||
|
private mapRangeToObjectId(
|
||||||
|
range: SourceRange,
|
||||||
|
commandTypeToTarget: string
|
||||||
|
): string | undefined {
|
||||||
|
for (const [artifactId, artifact] of this.artifactGraph) {
|
||||||
|
if (
|
||||||
|
'codeRef' in artifact &&
|
||||||
|
artifact.codeRef &&
|
||||||
|
isOverlap(range, artifact.codeRef.range)
|
||||||
|
) {
|
||||||
|
if (commandTypeToTarget === artifact.type) return artifactId
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
|
||||||
async safeParse(code: string): Promise<Node<Program> | null> {
|
async safeParse(code: string): Promise<Node<Program> | null> {
|
||||||
const result = parse(code)
|
const result = parse(code)
|
||||||
this.diagnostics = []
|
this.diagnostics = []
|
||||||
@ -330,6 +382,7 @@ export class KclManager {
|
|||||||
}
|
}
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
console.error(e)
|
||||||
this.wasmInitFailed = true
|
this.wasmInitFailed = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -370,12 +423,12 @@ export class KclManager {
|
|||||||
// Do not send send scene commands if the program was interrupted, go to clean up
|
// Do not send send scene commands if the program was interrupted, go to clean up
|
||||||
if (!isInterrupted) {
|
if (!isInterrupted) {
|
||||||
this.addDiagnostics(await lintAst({ ast: ast }))
|
this.addDiagnostics(await lintAst({ ast: ast }))
|
||||||
setSelectionFilterToDefault(this.engineCommandManager)
|
await setSelectionFilterToDefault(this.engineCommandManager)
|
||||||
|
|
||||||
if (args.zoomToFit) {
|
if (args.zoomToFit) {
|
||||||
let zoomObjectId: string | undefined = ''
|
let zoomObjectId: string | undefined = ''
|
||||||
if (args.zoomOnRangeAndType) {
|
if (args.zoomOnRangeAndType) {
|
||||||
zoomObjectId = this.engineCommandManager?.mapRangeToObjectId(
|
zoomObjectId = this.mapRangeToObjectId(
|
||||||
args.zoomOnRangeAndType.range,
|
args.zoomOnRangeAndType.range,
|
||||||
args.zoomOnRangeAndType.type
|
args.zoomOnRangeAndType.type
|
||||||
)
|
)
|
||||||
@ -429,7 +482,7 @@ export class KclManager {
|
|||||||
}
|
}
|
||||||
this.ast = { ...ast }
|
this.ast = { ...ast }
|
||||||
// updateArtifactGraph relies on updated executeState/variables
|
// updateArtifactGraph relies on updated executeState/variables
|
||||||
this.engineCommandManager.updateArtifactGraph(execState.artifactGraph)
|
await this.updateArtifactGraph(execState.artifactGraph)
|
||||||
this._executeCallback()
|
this._executeCallback()
|
||||||
if (!isInterrupted) {
|
if (!isInterrupted) {
|
||||||
sceneInfra.modelingSend({ type: 'code edit during sketch' })
|
sceneInfra.modelingSend({ type: 'code edit during sketch' })
|
||||||
|
@ -139,7 +139,7 @@ const runGetPathToExtrudeForSegmentSelectionTest = async (
|
|||||||
|
|
||||||
// executeAst and artifactGraph
|
// executeAst and artifactGraph
|
||||||
await kclManager.executeAst({ ast })
|
await kclManager.executeAst({ ast })
|
||||||
const artifactGraph = engineCommandManager.artifactGraph
|
const artifactGraph = kclManager.artifactGraph
|
||||||
|
|
||||||
// find artifact
|
// find artifact
|
||||||
const maybeArtifact = [...artifactGraph].find(([, artifact]) => {
|
const maybeArtifact = [...artifactGraph].find(([, artifact]) => {
|
||||||
@ -348,7 +348,7 @@ const runModifyAstCloneWithEdgeTreatmentAndTag = async (
|
|||||||
|
|
||||||
// executeAst
|
// executeAst
|
||||||
await kclManager.executeAst({ ast })
|
await kclManager.executeAst({ ast })
|
||||||
const artifactGraph = engineCommandManager.artifactGraph
|
const artifactGraph = kclManager.artifactGraph
|
||||||
|
|
||||||
const selection: Selections = {
|
const selection: Selections = {
|
||||||
graphSelections: segmentRanges.map((segmentRange) => {
|
graphSelections: segmentRanges.map((segmentRange) => {
|
||||||
@ -390,7 +390,7 @@ const runDeleteEdgeTreatmentTest = async (
|
|||||||
|
|
||||||
// update artifact graph
|
// update artifact graph
|
||||||
await kclManager.executeAst({ ast })
|
await kclManager.executeAst({ ast })
|
||||||
const artifactGraph = engineCommandManager.artifactGraph
|
const artifactGraph = kclManager.artifactGraph
|
||||||
|
|
||||||
// define snippet range
|
// define snippet range
|
||||||
const edgeTreatmentRange = topLevelRange(
|
const edgeTreatmentRange = topLevelRange(
|
||||||
|
@ -118,7 +118,7 @@ export function modifyAstWithEdgeTreatmentAndTag(
|
|||||||
const astResult = insertParametersIntoAst(clonedAst, parameters)
|
const astResult = insertParametersIntoAst(clonedAst, parameters)
|
||||||
if (err(astResult)) return astResult
|
if (err(astResult)) return astResult
|
||||||
|
|
||||||
const artifactGraph = dependencies.engineCommandManager.artifactGraph
|
const artifactGraph = dependencies.kclManager.artifactGraph
|
||||||
|
|
||||||
// Step 1: modify ast with tags and group them by extrude nodes (bodies)
|
// Step 1: modify ast with tags and group them by extrude nodes (bodies)
|
||||||
const extrudeToTagsMap: Map<
|
const extrudeToTagsMap: Map<
|
||||||
|
@ -42,11 +42,11 @@ export async function applySubtractFromTargetOperatorSelections(
|
|||||||
}
|
}
|
||||||
const orderedChildrenTarget = findAllChildrenAndOrderByPlaceInCode(
|
const orderedChildrenTarget = findAllChildrenAndOrderByPlaceInCode(
|
||||||
target.artifact,
|
target.artifact,
|
||||||
dependencies.engineCommandManager.artifactGraph
|
dependencies.kclManager.artifactGraph
|
||||||
)
|
)
|
||||||
const orderedChildrenTool = findAllChildrenAndOrderByPlaceInCode(
|
const orderedChildrenTool = findAllChildrenAndOrderByPlaceInCode(
|
||||||
tool.artifact,
|
tool.artifact,
|
||||||
dependencies.engineCommandManager.artifactGraph
|
dependencies.kclManager.artifactGraph
|
||||||
)
|
)
|
||||||
|
|
||||||
const lastVarTarget = getLastVariable(orderedChildrenTarget, ast)
|
const lastVarTarget = getLastVariable(orderedChildrenTarget, ast)
|
||||||
@ -89,7 +89,7 @@ export async function applyUnionFromTargetOperatorSelections(
|
|||||||
const orderedChildrenEach = artifacts.map((artifact) =>
|
const orderedChildrenEach = artifacts.map((artifact) =>
|
||||||
findAllChildrenAndOrderByPlaceInCode(
|
findAllChildrenAndOrderByPlaceInCode(
|
||||||
artifact,
|
artifact,
|
||||||
dependencies.engineCommandManager.artifactGraph
|
dependencies.kclManager.artifactGraph
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -136,7 +136,7 @@ export async function applyIntersectFromTargetOperatorSelections(
|
|||||||
const orderedChildrenEach = artifacts.map((artifact) =>
|
const orderedChildrenEach = artifacts.map((artifact) =>
|
||||||
findAllChildrenAndOrderByPlaceInCode(
|
findAllChildrenAndOrderByPlaceInCode(
|
||||||
artifact,
|
artifact,
|
||||||
dependencies.engineCommandManager.artifactGraph
|
dependencies.kclManager.artifactGraph
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -4,7 +4,6 @@ import { deleteFromSelection } from 'lang/modifyAst'
|
|||||||
import {
|
import {
|
||||||
codeManager,
|
codeManager,
|
||||||
editorManager,
|
editorManager,
|
||||||
engineCommandManager,
|
|
||||||
kclManager,
|
kclManager,
|
||||||
rustContext,
|
rustContext,
|
||||||
} from 'lib/singletons'
|
} from 'lib/singletons'
|
||||||
@ -25,7 +24,7 @@ export async function deleteSelectionPromise(
|
|||||||
ast,
|
ast,
|
||||||
selection,
|
selection,
|
||||||
kclManager.variables,
|
kclManager.variables,
|
||||||
engineCommandManager.artifactGraph,
|
kclManager.artifactGraph,
|
||||||
getFaceDetails
|
getFaceDetails
|
||||||
)
|
)
|
||||||
if (err(modifiedAst)) {
|
if (err(modifiedAst)) {
|
||||||
|
@ -1,13 +1,8 @@
|
|||||||
import {
|
import { defaultSourceRange, SourceRange } from 'lang/wasm'
|
||||||
ArtifactGraph,
|
|
||||||
defaultSourceRange,
|
|
||||||
ExecState,
|
|
||||||
SourceRange,
|
|
||||||
} from 'lang/wasm'
|
|
||||||
import { VITE_KC_API_WS_MODELING_URL, VITE_KC_DEV_TOKEN } from 'env'
|
import { VITE_KC_API_WS_MODELING_URL, VITE_KC_DEV_TOKEN } from 'env'
|
||||||
import { Models } from '@kittycad/lib'
|
import { Models } from '@kittycad/lib'
|
||||||
import { deferExecution, isOverlap, uuidv4 } from 'lib/utils'
|
import { uuidv4, binaryToUuid } from 'lib/utils'
|
||||||
import { BSON, Binary as BSONBinary } from 'bson'
|
import { BSON } from 'bson'
|
||||||
import {
|
import {
|
||||||
Themes,
|
Themes,
|
||||||
getThemeColorForEngine,
|
getThemeColorForEngine,
|
||||||
@ -22,8 +17,6 @@ import { KclManager } from 'lang/KclSingleton'
|
|||||||
import { reportRejection } from 'lib/trap'
|
import { reportRejection } from 'lib/trap'
|
||||||
import { markOnce } from 'lib/performance'
|
import { markOnce } from 'lib/performance'
|
||||||
import { MachineManager } from 'components/MachineManagerProvider'
|
import { MachineManager } from 'components/MachineManagerProvider'
|
||||||
import { buildArtifactIndex } from 'lib/artifactIndex'
|
|
||||||
import { ArtifactIndex } from 'lib/artifactIndex'
|
|
||||||
|
|
||||||
// TODO(paultag): This ought to be tweakable.
|
// TODO(paultag): This ought to be tweakable.
|
||||||
const pingIntervalMs = 5_000
|
const pingIntervalMs = 5_000
|
||||||
@ -1047,11 +1040,9 @@ class EngineConnection extends EventTarget {
|
|||||||
})
|
})
|
||||||
.join('\n')
|
.join('\n')
|
||||||
if (message.request_id) {
|
if (message.request_id) {
|
||||||
const artifactThatFailed =
|
|
||||||
this.engineCommandManager.artifactGraph.get(message.request_id)
|
|
||||||
console.error(
|
console.error(
|
||||||
`Error in response to request ${message.request_id}:\n${errorsString}
|
`Error in response to request ${message.request_id}:\n${errorsString}
|
||||||
failed cmd type was ${artifactThatFailed?.type}`
|
failed`
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
console.error(`Error from server:\n${errorsString}`)
|
console.error(`Error from server:\n${errorsString}`)
|
||||||
@ -1355,8 +1346,7 @@ export enum EngineCommandManagerEvents {
|
|||||||
*
|
*
|
||||||
* As commands are send their state is tracked in {@link pendingCommands} and clear as soon as we receive a response.
|
* As commands are send their state is tracked in {@link pendingCommands} and clear as soon as we receive a response.
|
||||||
*
|
*
|
||||||
* Also all commands that are sent are kept track of in WASM artifactCommands and their responses are kept in {@link responseMap}
|
* Also all commands that are sent are kept track of in WASM and their responses are kept in {@link responseMap}
|
||||||
* Both of these data structures are used to process the {@link artifactGraph}.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
interface PendingMessage {
|
interface PendingMessage {
|
||||||
@ -1369,12 +1359,6 @@ interface PendingMessage {
|
|||||||
isSceneCommand: boolean
|
isSceneCommand: boolean
|
||||||
}
|
}
|
||||||
export class EngineCommandManager extends EventTarget {
|
export class EngineCommandManager extends EventTarget {
|
||||||
/**
|
|
||||||
* The artifactGraph is a client-side representation of the commands that have been sent
|
|
||||||
* see: src/lang/std/artifactGraph-README.md for a full explanation.
|
|
||||||
*/
|
|
||||||
artifactGraph: ArtifactGraph = new Map()
|
|
||||||
artifactIndex: ArtifactIndex = []
|
|
||||||
/**
|
/**
|
||||||
* The pendingCommands object is a map of the commands that have been sent to the engine that are still waiting on a reply
|
* The pendingCommands object is a map of the commands that have been sent to the engine that are still waiting on a reply
|
||||||
*/
|
*/
|
||||||
@ -1382,7 +1366,7 @@ export class EngineCommandManager extends EventTarget {
|
|||||||
[commandId: string]: PendingMessage
|
[commandId: string]: PendingMessage
|
||||||
} = {}
|
} = {}
|
||||||
/**
|
/**
|
||||||
* A map of the responses to the WASM artifactCommands, when processing the commands into the artifactGraph, this response map allow
|
* A map of the responses to the WASM, this response map allow
|
||||||
* us to look up the response by command id
|
* us to look up the response by command id
|
||||||
*/
|
*/
|
||||||
responseMap: ResponseMap = {}
|
responseMap: ResponseMap = {}
|
||||||
@ -1878,7 +1862,7 @@ export class EngineCommandManager extends EventTarget {
|
|||||||
registerCommandLogCallback(callback: (command: CommandLog[]) => void) {
|
registerCommandLogCallback(callback: (command: CommandLog[]) => void) {
|
||||||
this._commandLogCallBack = callback
|
this._commandLogCallBack = callback
|
||||||
}
|
}
|
||||||
sendSceneCommand(
|
async sendSceneCommand(
|
||||||
command: EngineCommand,
|
command: EngineCommand,
|
||||||
forceWebsocket = false
|
forceWebsocket = false
|
||||||
): Promise<Models['WebSocketResponse_type'] | null> {
|
): Promise<Models['WebSocketResponse_type'] | null> {
|
||||||
@ -2032,13 +2016,6 @@ export class EngineCommandManager extends EventTarget {
|
|||||||
return promise
|
return promise
|
||||||
}
|
}
|
||||||
|
|
||||||
deferredArtifactPopulated = deferExecution((a?: null) => {
|
|
||||||
this.modelingSend({ type: 'Artifact graph populated' })
|
|
||||||
}, 200)
|
|
||||||
deferredArtifactEmptied = deferExecution((a?: null) => {
|
|
||||||
this.modelingSend({ type: 'Artifact graph emptied' })
|
|
||||||
}, 200)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When an execution takes place we want to wait until we've got replies for all of the commands
|
* When an execution takes place we want to wait until we've got replies for all of the commands
|
||||||
* When this is done when we build the artifact map synchronously.
|
* When this is done when we build the artifact map synchronously.
|
||||||
@ -2048,16 +2025,6 @@ export class EngineCommandManager extends EventTarget {
|
|||||||
Object.values(this.pendingCommands).map((a) => a.promise)
|
Object.values(this.pendingCommands).map((a) => a.promise)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
updateArtifactGraph(execStateArtifactGraph: ExecState['artifactGraph']) {
|
|
||||||
this.artifactGraph = execStateArtifactGraph
|
|
||||||
this.artifactIndex = buildArtifactIndex(execStateArtifactGraph)
|
|
||||||
// TODO check if these still need to be deferred once e2e tests are working again.
|
|
||||||
if (this.artifactGraph.size) {
|
|
||||||
this.deferredArtifactEmptied(null)
|
|
||||||
} else {
|
|
||||||
this.deferredArtifactPopulated(null)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reject all of the modeling pendingCommands created from sendModelingCommandFromWasm
|
* Reject all of the modeling pendingCommands created from sendModelingCommandFromWasm
|
||||||
@ -2121,24 +2088,6 @@ export class EngineCommandManager extends EventTarget {
|
|||||||
},
|
},
|
||||||
}).catch(reportRejection)
|
}).catch(reportRejection)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Some "objects" have the same source range, such as sketch_mode_start and start_path.
|
|
||||||
// So when passing a range, we need to also specify the command type
|
|
||||||
mapRangeToObjectId(
|
|
||||||
range: SourceRange,
|
|
||||||
commandTypeToTarget: string
|
|
||||||
): string | undefined {
|
|
||||||
for (const [artifactId, artifact] of this.artifactGraph) {
|
|
||||||
if (
|
|
||||||
'codeRef' in artifact &&
|
|
||||||
artifact.codeRef &&
|
|
||||||
isOverlap(range, artifact.codeRef.range)
|
|
||||||
) {
|
|
||||||
if (commandTypeToTarget === artifact.type) return artifactId
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return undefined
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function promiseFactory<T>() {
|
function promiseFactory<T>() {
|
||||||
@ -2150,65 +2099,3 @@ function promiseFactory<T>() {
|
|||||||
})
|
})
|
||||||
return { promise, resolve, reject }
|
return { promise, resolve, reject }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Converts a binary buffer to a UUID string.
|
|
||||||
*
|
|
||||||
* @param buffer - The binary buffer containing the UUID bytes.
|
|
||||||
* @returns A string representation of the UUID in the format 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'.
|
|
||||||
*/
|
|
||||||
function binaryToUuid(
|
|
||||||
binaryData: Buffer | Uint8Array | BSONBinary | string
|
|
||||||
): string {
|
|
||||||
if (typeof binaryData === 'string') {
|
|
||||||
return binaryData
|
|
||||||
}
|
|
||||||
|
|
||||||
let buffer: Uint8Array
|
|
||||||
|
|
||||||
// Handle MongoDB BSON Binary object
|
|
||||||
if (
|
|
||||||
binaryData &&
|
|
||||||
'_bsontype' in binaryData &&
|
|
||||||
binaryData._bsontype === 'Binary'
|
|
||||||
) {
|
|
||||||
// Extract the buffer from the BSON Binary object
|
|
||||||
buffer = binaryData.buffer
|
|
||||||
}
|
|
||||||
// Handle case where buffer property exists (some MongoDB drivers structure)
|
|
||||||
else if (binaryData && binaryData.buffer instanceof Uint8Array) {
|
|
||||||
buffer = binaryData.buffer
|
|
||||||
}
|
|
||||||
// Handle direct Buffer or Uint8Array
|
|
||||||
else if (binaryData instanceof Uint8Array || Buffer.isBuffer(binaryData)) {
|
|
||||||
buffer = binaryData
|
|
||||||
} else {
|
|
||||||
console.error(
|
|
||||||
'Invalid input type: expected MongoDB BSON Binary, Buffer, or Uint8Array'
|
|
||||||
)
|
|
||||||
return ''
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ensure we have exactly 16 bytes (128 bits) for a UUID
|
|
||||||
if (buffer.length !== 16) {
|
|
||||||
// For debugging
|
|
||||||
console.log('Buffer length:', buffer.length)
|
|
||||||
console.log('Buffer content:', Array.from(buffer))
|
|
||||||
console.error('UUID must be exactly 16 bytes')
|
|
||||||
return ''
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert each byte to a hex string and pad with zeros if needed
|
|
||||||
const hexValues = Array.from(buffer).map((byte) =>
|
|
||||||
byte.toString(16).padStart(2, '0')
|
|
||||||
)
|
|
||||||
|
|
||||||
// Format into UUID structure (8-4-4-4-12 characters)
|
|
||||||
return [
|
|
||||||
hexValues.slice(0, 4).join(''),
|
|
||||||
hexValues.slice(4, 6).join(''),
|
|
||||||
hexValues.slice(6, 8).join(''),
|
|
||||||
hexValues.slice(8, 10).join(''),
|
|
||||||
hexValues.slice(10, 16).join(''),
|
|
||||||
].join('-')
|
|
||||||
}
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { Models } from '@kittycad/lib'
|
import { Models } from '@kittycad/lib'
|
||||||
import { engineCommandManager } from 'lib/singletons'
|
import { engineCommandManager, kclManager } from 'lib/singletons'
|
||||||
import { uuidv4 } from 'lib/utils'
|
import { uuidv4 } from 'lib/utils'
|
||||||
import { CommandBarContext } from 'machines/commandBarMachine'
|
import { CommandBarContext } from 'machines/commandBarMachine'
|
||||||
import { Selections } from 'lib/selections'
|
import { Selections } from 'lib/selections'
|
||||||
@ -188,7 +188,7 @@ export const shellValidator = async ({
|
|||||||
// So we're listing out the sweeps as if they were solids and taking the first one, just like in Rust for Shell:
|
// So we're listing out the sweeps as if they were solids and taking the first one, just like in Rust for Shell:
|
||||||
// https://github.com/KittyCAD/modeling-app/blob/e61fff115b9fa94aaace6307b1842cc15d41655e/src/wasm-lib/kcl/src/std/shell.rs#L237-L238
|
// https://github.com/KittyCAD/modeling-app/blob/e61fff115b9fa94aaace6307b1842cc15d41655e/src/wasm-lib/kcl/src/std/shell.rs#L237-L238
|
||||||
// TODO: This is one cheap way to make sketch-on-face supported now but will likely fail multiple solids
|
// TODO: This is one cheap way to make sketch-on-face supported now but will likely fail multiple solids
|
||||||
const object_id = engineCommandManager.artifactGraph
|
const object_id = kclManager.artifactGraph
|
||||||
.values()
|
.values()
|
||||||
.find((v) => v.type === 'sweep')?.pathId
|
.find((v) => v.type === 'sweep')?.pathId
|
||||||
|
|
||||||
|
@ -200,17 +200,6 @@ export class CoreDumpManager {
|
|||||||
// engine_command_manager
|
// engine_command_manager
|
||||||
debugLog('CoreDump: engineCommandManager', this.engineCommandManager)
|
debugLog('CoreDump: engineCommandManager', this.engineCommandManager)
|
||||||
|
|
||||||
// artifact map - this.engineCommandManager.artifactGraph
|
|
||||||
if (this.engineCommandManager?.artifactGraph) {
|
|
||||||
debugLog(
|
|
||||||
'CoreDump: Engine Command Manager artifact map',
|
|
||||||
this.engineCommandManager.artifactGraph
|
|
||||||
)
|
|
||||||
clientState.engine_command_manager.artifact_map = structuredClone(
|
|
||||||
this.engineCommandManager.artifactGraph
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// command logs - this.engineCommandManager.commandLogs
|
// command logs - this.engineCommandManager.commandLogs
|
||||||
if (this.engineCommandManager?.commandLogs) {
|
if (this.engineCommandManager?.commandLogs) {
|
||||||
debugLog(
|
debugLog(
|
||||||
@ -274,6 +263,21 @@ export class CoreDumpManager {
|
|||||||
clientState.kcl_manager.ast = structuredClone(kclManager.ast)
|
clientState.kcl_manager.ast = structuredClone(kclManager.ast)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// artifact map - this.kclManager.artifactGraph
|
||||||
|
debugLog(
|
||||||
|
'CoreDump: KCL Manager artifact map',
|
||||||
|
kclManager?.artifactGraph
|
||||||
|
)
|
||||||
|
if (kclManager.artifactGraph) {
|
||||||
|
debugLog(
|
||||||
|
'CoreDump: Engine Command Manager artifact map',
|
||||||
|
kclManager.artifactGraph
|
||||||
|
)
|
||||||
|
clientState.engine_command_manager.artifact_map = structuredClone(
|
||||||
|
kclManager.artifactGraph
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
// KCL Errors
|
// KCL Errors
|
||||||
debugLog('CoreDump: KCL Errors', kclManager?.kclErrors)
|
debugLog('CoreDump: KCL Errors', kclManager?.kclErrors)
|
||||||
if (kclManager?.kclErrors) {
|
if (kclManager?.kclErrors) {
|
||||||
|
@ -8,7 +8,7 @@ import {
|
|||||||
getWallCodeRef,
|
getWallCodeRef,
|
||||||
} from 'lang/std/artifactGraph'
|
} from 'lang/std/artifactGraph'
|
||||||
import { Operation } from '@rust/kcl-lib/bindings/Operation'
|
import { Operation } from '@rust/kcl-lib/bindings/Operation'
|
||||||
import { codeManager, engineCommandManager, kclManager } from './singletons'
|
import { codeManager, kclManager, rustContext } from './singletons'
|
||||||
import { err } from './trap'
|
import { err } from './trap'
|
||||||
import { getNodePathFromSourceRange } from 'lang/queryAstNodePathUtils'
|
import { getNodePathFromSourceRange } from 'lang/queryAstNodePathUtils'
|
||||||
import { sourceRangeFromRust } from 'lang/wasm'
|
import { sourceRangeFromRust } from 'lang/wasm'
|
||||||
@ -20,7 +20,6 @@ import {
|
|||||||
} from './commandBarConfigs/modelingCommandConfig'
|
} from './commandBarConfigs/modelingCommandConfig'
|
||||||
import { isDefaultPlaneStr } from './planes'
|
import { isDefaultPlaneStr } from './planes'
|
||||||
import { Selection, Selections } from './selections'
|
import { Selection, Selections } from './selections'
|
||||||
import { rustContext } from './singletons'
|
|
||||||
import { KclExpression } from './commandTypes'
|
import { KclExpression } from './commandTypes'
|
||||||
|
|
||||||
type ExecuteCommandEvent = CommandBarMachineEvent & {
|
type ExecuteCommandEvent = CommandBarMachineEvent & {
|
||||||
@ -73,7 +72,7 @@ const prepareToEditExtrude: PrepareToEditCallback =
|
|||||||
key: artifact.pathId,
|
key: artifact.pathId,
|
||||||
types: ['path'],
|
types: ['path'],
|
||||||
},
|
},
|
||||||
engineCommandManager.artifactGraph
|
kclManager.artifactGraph
|
||||||
)
|
)
|
||||||
if (
|
if (
|
||||||
err(pathArtifact) ||
|
err(pathArtifact) ||
|
||||||
@ -86,7 +85,7 @@ const prepareToEditExtrude: PrepareToEditCallback =
|
|||||||
key: pathArtifact.solid2dId,
|
key: pathArtifact.solid2dId,
|
||||||
types: ['solid2d'],
|
types: ['solid2d'],
|
||||||
},
|
},
|
||||||
engineCommandManager.artifactGraph
|
kclManager.artifactGraph
|
||||||
)
|
)
|
||||||
if (err(solid2DArtifact) || solid2DArtifact.type !== 'solid2d') {
|
if (err(solid2DArtifact) || solid2DArtifact.type !== 'solid2d') {
|
||||||
return baseCommand
|
return baseCommand
|
||||||
@ -157,7 +156,7 @@ const prepareToEditEdgeTreatment: PrepareToEditCallback = async ({
|
|||||||
key: artifact.consumedEdgeId,
|
key: artifact.consumedEdgeId,
|
||||||
types: ['segment', 'sweepEdge'],
|
types: ['segment', 'sweepEdge'],
|
||||||
},
|
},
|
||||||
engineCommandManager.artifactGraph
|
kclManager.artifactGraph
|
||||||
)
|
)
|
||||||
if (err(edgeArtifact)) {
|
if (err(edgeArtifact)) {
|
||||||
return { reason: "Couldn't find edge artifact" }
|
return { reason: "Couldn't find edge artifact" }
|
||||||
@ -165,7 +164,7 @@ const prepareToEditEdgeTreatment: PrepareToEditCallback = async ({
|
|||||||
|
|
||||||
let edgeCodeRef = getEdgeCutConsumedCodeRef(
|
let edgeCodeRef = getEdgeCutConsumedCodeRef(
|
||||||
artifact,
|
artifact,
|
||||||
engineCommandManager.artifactGraph
|
kclManager.artifactGraph
|
||||||
)
|
)
|
||||||
if (err(edgeCodeRef)) {
|
if (err(edgeCodeRef)) {
|
||||||
return { reason: "Couldn't find edge coderef" }
|
return { reason: "Couldn't find edge coderef" }
|
||||||
@ -272,16 +271,13 @@ const prepareToEditShell: PrepareToEditCallback =
|
|||||||
// that we can query in another loop later
|
// that we can query in another loop later
|
||||||
const sweepId = operation.unlabeledArg.value.value.artifactId
|
const sweepId = operation.unlabeledArg.value.value.artifactId
|
||||||
const candidates: Map<string, Selection> = new Map()
|
const candidates: Map<string, Selection> = new Map()
|
||||||
for (const artifact of engineCommandManager.artifactGraph.values()) {
|
for (const artifact of kclManager.artifactGraph.values()) {
|
||||||
if (
|
if (
|
||||||
artifact.type === 'cap' &&
|
artifact.type === 'cap' &&
|
||||||
artifact.sweepId === sweepId &&
|
artifact.sweepId === sweepId &&
|
||||||
artifact.subType
|
artifact.subType
|
||||||
) {
|
) {
|
||||||
const codeRef = getCapCodeRef(
|
const codeRef = getCapCodeRef(artifact, kclManager.artifactGraph)
|
||||||
artifact,
|
|
||||||
engineCommandManager.artifactGraph
|
|
||||||
)
|
|
||||||
if (err(codeRef)) {
|
if (err(codeRef)) {
|
||||||
return baseCommand
|
return baseCommand
|
||||||
}
|
}
|
||||||
@ -297,7 +293,7 @@ const prepareToEditShell: PrepareToEditCallback =
|
|||||||
) {
|
) {
|
||||||
const segArtifact = getArtifactOfTypes(
|
const segArtifact = getArtifactOfTypes(
|
||||||
{ key: artifact.segId, types: ['segment'] },
|
{ key: artifact.segId, types: ['segment'] },
|
||||||
engineCommandManager.artifactGraph
|
kclManager.artifactGraph
|
||||||
)
|
)
|
||||||
if (err(segArtifact)) {
|
if (err(segArtifact)) {
|
||||||
return baseCommand
|
return baseCommand
|
||||||
@ -461,7 +457,7 @@ const prepareToEditSweep: PrepareToEditCallback = async ({
|
|||||||
key: artifact.pathId,
|
key: artifact.pathId,
|
||||||
types: ['path'],
|
types: ['path'],
|
||||||
},
|
},
|
||||||
engineCommandManager.artifactGraph
|
kclManager.artifactGraph
|
||||||
)
|
)
|
||||||
|
|
||||||
if (
|
if (
|
||||||
@ -477,7 +473,7 @@ const prepareToEditSweep: PrepareToEditCallback = async ({
|
|||||||
key: pathArtifact.solid2dId,
|
key: pathArtifact.solid2dId,
|
||||||
types: ['solid2d'],
|
types: ['solid2d'],
|
||||||
},
|
},
|
||||||
engineCommandManager.artifactGraph
|
kclManager.artifactGraph
|
||||||
)
|
)
|
||||||
|
|
||||||
if (err(targetArtifact) || targetArtifact.type !== 'solid2d') {
|
if (err(targetArtifact) || targetArtifact.type !== 'solid2d') {
|
||||||
@ -508,7 +504,7 @@ const prepareToEditSweep: PrepareToEditCallback = async ({
|
|||||||
key: operation.labeledArgs.path.value.value.artifactId,
|
key: operation.labeledArgs.path.value.value.artifactId,
|
||||||
types: ['path'],
|
types: ['path'],
|
||||||
},
|
},
|
||||||
engineCommandManager.artifactGraph
|
kclManager.artifactGraph
|
||||||
)
|
)
|
||||||
|
|
||||||
if (err(trajectoryPathArtifact) || trajectoryPathArtifact.type !== 'path') {
|
if (err(trajectoryPathArtifact) || trajectoryPathArtifact.type !== 'path') {
|
||||||
@ -520,7 +516,7 @@ const prepareToEditSweep: PrepareToEditCallback = async ({
|
|||||||
key: trajectoryPathArtifact.segIds[0],
|
key: trajectoryPathArtifact.segIds[0],
|
||||||
types: ['segment'],
|
types: ['segment'],
|
||||||
},
|
},
|
||||||
engineCommandManager.artifactGraph
|
kclManager.artifactGraph
|
||||||
)
|
)
|
||||||
|
|
||||||
if (err(trajectoryArtifact) || trajectoryArtifact.type !== 'segment') {
|
if (err(trajectoryArtifact) || trajectoryArtifact.type !== 'segment') {
|
||||||
@ -607,7 +603,7 @@ const prepareToEditHelix: PrepareToEditCallback = async ({ operation }) => {
|
|||||||
key: axisValue.artifact_id,
|
key: axisValue.artifact_id,
|
||||||
types: ['segment'],
|
types: ['segment'],
|
||||||
},
|
},
|
||||||
engineCommandManager.artifactGraph
|
kclManager.artifactGraph
|
||||||
)
|
)
|
||||||
if (err(artifact)) {
|
if (err(artifact)) {
|
||||||
return { reason: "Couldn't find related edge artifact" }
|
return { reason: "Couldn't find related edge artifact" }
|
||||||
@ -630,16 +626,13 @@ const prepareToEditHelix: PrepareToEditCallback = async ({ operation }) => {
|
|||||||
key: axisValue.value,
|
key: axisValue.value,
|
||||||
types: ['sweepEdge'],
|
types: ['sweepEdge'],
|
||||||
},
|
},
|
||||||
engineCommandManager.artifactGraph
|
kclManager.artifactGraph
|
||||||
)
|
)
|
||||||
if (err(artifact)) {
|
if (err(artifact)) {
|
||||||
return { reason: "Couldn't find related edge artifact" }
|
return { reason: "Couldn't find related edge artifact" }
|
||||||
}
|
}
|
||||||
|
|
||||||
const codeRef = getSweepEdgeCodeRef(
|
const codeRef = getSweepEdgeCodeRef(artifact, kclManager.artifactGraph)
|
||||||
artifact,
|
|
||||||
engineCommandManager.artifactGraph
|
|
||||||
)
|
|
||||||
if (err(codeRef)) {
|
if (err(codeRef)) {
|
||||||
return { reason: "Couldn't find related edge code ref" }
|
return { reason: "Couldn't find related edge code ref" }
|
||||||
}
|
}
|
||||||
@ -667,7 +660,7 @@ const prepareToEditHelix: PrepareToEditCallback = async ({ operation }) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const sweepId = operation.labeledArgs.cylinder.value.value.artifactId
|
const sweepId = operation.labeledArgs.cylinder.value.value.artifactId
|
||||||
const wallArtifact = [...engineCommandManager.artifactGraph.values()].find(
|
const wallArtifact = [...kclManager.artifactGraph.values()].find(
|
||||||
(p) => p.type === 'wall' && p.sweepId === sweepId
|
(p) => p.type === 'wall' && p.sweepId === sweepId
|
||||||
)
|
)
|
||||||
if (!wallArtifact || wallArtifact.type !== 'wall') {
|
if (!wallArtifact || wallArtifact.type !== 'wall') {
|
||||||
@ -676,10 +669,7 @@ const prepareToEditHelix: PrepareToEditCallback = async ({ operation }) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const wallCodeRef = getWallCodeRef(
|
const wallCodeRef = getWallCodeRef(wallArtifact, kclManager.artifactGraph)
|
||||||
wallArtifact,
|
|
||||||
engineCommandManager.artifactGraph
|
|
||||||
)
|
|
||||||
if (err(wallCodeRef)) {
|
if (err(wallCodeRef)) {
|
||||||
return {
|
return {
|
||||||
reason: "Cylinder arg found doesn't point to a valid sweep code ref",
|
reason: "Cylinder arg found doesn't point to a valid sweep code ref",
|
||||||
|
@ -102,10 +102,10 @@ export async function getEventForSelectWithPoint({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let _artifact = engineCommandManager.artifactGraph.get(data.entity_id)
|
let _artifact = kclManager.artifactGraph.get(data.entity_id)
|
||||||
const codeRefs = getCodeRefsByArtifactId(
|
const codeRefs = getCodeRefsByArtifactId(
|
||||||
data.entity_id,
|
data.entity_id,
|
||||||
engineCommandManager.artifactGraph
|
kclManager.artifactGraph
|
||||||
)
|
)
|
||||||
if (_artifact && codeRefs) {
|
if (_artifact && codeRefs) {
|
||||||
return {
|
return {
|
||||||
@ -140,15 +140,15 @@ export function getEventForSegmentSelection(
|
|||||||
// id does not match up with the artifact graph when in sketch mode, because mock executions
|
// id does not match up with the artifact graph when in sketch mode, because mock executions
|
||||||
// do not update the artifact graph, therefore we match up the pathToNode instead
|
// do not update the artifact graph, therefore we match up the pathToNode instead
|
||||||
// we can reliably use `type === 'segment'` since it's in sketch mode and we're concerned with segments
|
// we can reliably use `type === 'segment'` since it's in sketch mode and we're concerned with segments
|
||||||
const segWithMatchingPathToNode__Id = [
|
const segWithMatchingPathToNode__Id = [...kclManager.artifactGraph].find(
|
||||||
...engineCommandManager.artifactGraph,
|
(entry) => {
|
||||||
].find((entry) => {
|
return (
|
||||||
return (
|
entry[1].type === 'segment' &&
|
||||||
entry[1].type === 'segment' &&
|
JSON.stringify(entry[1].codeRef.pathToNode) ===
|
||||||
JSON.stringify(entry[1].codeRef.pathToNode) ===
|
JSON.stringify(group?.userData?.pathToNode)
|
||||||
JSON.stringify(group?.userData?.pathToNode)
|
)
|
||||||
)
|
}
|
||||||
})?.[0]
|
)?.[0]
|
||||||
|
|
||||||
const id = segWithMatchingPathToNode__Id
|
const id = segWithMatchingPathToNode__Id
|
||||||
|
|
||||||
@ -172,7 +172,7 @@ export function getEventForSegmentSelection(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!id || !group) return null
|
if (!id || !group) return null
|
||||||
const artifact = engineCommandManager.artifactGraph.get(id)
|
const artifact = kclManager.artifactGraph.get(id)
|
||||||
if (!artifact) return null
|
if (!artifact) return null
|
||||||
const node = getNodeFromPath<Expr>(kclManager.ast, group.userData.pathToNode)
|
const node = getNodeFromPath<Expr>(kclManager.ast, group.userData.pathToNode)
|
||||||
if (err(node)) return null
|
if (err(node)) return null
|
||||||
@ -208,10 +208,8 @@ export function handleSelectionBatch({
|
|||||||
selectionToEngine.push({
|
selectionToEngine.push({
|
||||||
id: artifact?.id,
|
id: artifact?.id,
|
||||||
range:
|
range:
|
||||||
getCodeRefsByArtifactId(
|
getCodeRefsByArtifactId(artifact.id, kclManager.artifactGraph)?.[0]
|
||||||
artifact.id,
|
.range || defaultSourceRange(),
|
||||||
engineCommandManager.artifactGraph
|
|
||||||
)?.[0].range || defaultSourceRange(),
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
const engineEvents: Models['WebSocketRequest_type'][] =
|
const engineEvents: Models['WebSocketRequest_type'][] =
|
||||||
@ -291,7 +289,7 @@ export function processCodeMirrorRanges({
|
|||||||
const idBasedSelections: SelectionToEngine[] = codeToIdSelections(
|
const idBasedSelections: SelectionToEngine[] = codeToIdSelections(
|
||||||
codeBasedSelections,
|
codeBasedSelections,
|
||||||
artifactGraph,
|
artifactGraph,
|
||||||
engineCommandManager.artifactIndex
|
kclManager.artifactIndex
|
||||||
)
|
)
|
||||||
const selections: Selection[] = []
|
const selections: Selection[] = []
|
||||||
for (const { id, range } of idBasedSelections) {
|
for (const { id, range } of idBasedSelections) {
|
||||||
@ -396,10 +394,7 @@ function resetAndSetEngineEntitySelectionCmds(
|
|||||||
*/
|
*/
|
||||||
export function isSketchPipe(selectionRanges: Selections) {
|
export function isSketchPipe(selectionRanges: Selections) {
|
||||||
if (!isSingleCursorInPipe(selectionRanges, kclManager.ast)) return false
|
if (!isSingleCursorInPipe(selectionRanges, kclManager.ast)) return false
|
||||||
return isCursorInSketchCommandRange(
|
return isCursorInSketchCommandRange(kclManager.artifactGraph, selectionRanges)
|
||||||
engineCommandManager.artifactGraph,
|
|
||||||
selectionRanges
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// This accounts for non-geometry selections under "other"
|
// This accounts for non-geometry selections under "other"
|
||||||
@ -692,12 +687,9 @@ export function updateSelections(
|
|||||||
if (err(nodeMeta)) return undefined
|
if (err(nodeMeta)) return undefined
|
||||||
const node = nodeMeta.node
|
const node = nodeMeta.node
|
||||||
let artifact: Artifact | null = null
|
let artifact: Artifact | null = null
|
||||||
for (const [id, a] of engineCommandManager.artifactGraph) {
|
for (const [id, a] of kclManager.artifactGraph) {
|
||||||
if (previousSelection?.artifact?.type === a.type) {
|
if (previousSelection?.artifact?.type === a.type) {
|
||||||
const codeRefs = getCodeRefsByArtifactId(
|
const codeRefs = getCodeRefsByArtifactId(id, kclManager.artifactGraph)
|
||||||
id,
|
|
||||||
engineCommandManager.artifactGraph
|
|
||||||
)
|
|
||||||
if (!codeRefs) continue
|
if (!codeRefs) continue
|
||||||
if (
|
if (
|
||||||
JSON.stringify(codeRefs[0].pathToNode) ===
|
JSON.stringify(codeRefs[0].pathToNode) ===
|
||||||
|
@ -4,6 +4,7 @@ import { v4 } from 'uuid'
|
|||||||
import { isDesktop } from './isDesktop'
|
import { isDesktop } from './isDesktop'
|
||||||
import { AnyMachineSnapshot } from 'xstate'
|
import { AnyMachineSnapshot } from 'xstate'
|
||||||
import { AsyncFn } from './types'
|
import { AsyncFn } from './types'
|
||||||
|
import { Binary as BSONBinary } from 'bson'
|
||||||
|
|
||||||
export const uuidv4 = v4
|
export const uuidv4 = v4
|
||||||
|
|
||||||
@ -406,3 +407,65 @@ export function isClockwise(points: [number, number][]): boolean {
|
|||||||
// If sum is positive, the points are in clockwise order
|
// If sum is positive, the points are in clockwise order
|
||||||
return sum > 0
|
return sum > 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a binary buffer to a UUID string.
|
||||||
|
*
|
||||||
|
* @param buffer - The binary buffer containing the UUID bytes.
|
||||||
|
* @returns A string representation of the UUID in the format 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'.
|
||||||
|
*/
|
||||||
|
export function binaryToUuid(
|
||||||
|
binaryData: Buffer | Uint8Array | BSONBinary | string
|
||||||
|
): string {
|
||||||
|
if (typeof binaryData === 'string') {
|
||||||
|
return binaryData
|
||||||
|
}
|
||||||
|
|
||||||
|
let buffer: Uint8Array
|
||||||
|
|
||||||
|
// Handle MongoDB BSON Binary object
|
||||||
|
if (
|
||||||
|
binaryData &&
|
||||||
|
'_bsontype' in binaryData &&
|
||||||
|
binaryData._bsontype === 'Binary'
|
||||||
|
) {
|
||||||
|
// Extract the buffer from the BSON Binary object
|
||||||
|
buffer = binaryData.buffer
|
||||||
|
}
|
||||||
|
// Handle case where buffer property exists (some MongoDB drivers structure)
|
||||||
|
else if (binaryData && binaryData.buffer instanceof Uint8Array) {
|
||||||
|
buffer = binaryData.buffer
|
||||||
|
}
|
||||||
|
// Handle direct Buffer or Uint8Array
|
||||||
|
else if (binaryData instanceof Uint8Array || Buffer.isBuffer(binaryData)) {
|
||||||
|
buffer = binaryData
|
||||||
|
} else {
|
||||||
|
console.error(
|
||||||
|
'Invalid input type: expected MongoDB BSON Binary, Buffer, or Uint8Array'
|
||||||
|
)
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure we have exactly 16 bytes (128 bits) for a UUID
|
||||||
|
if (buffer.length !== 16) {
|
||||||
|
// For debugging
|
||||||
|
console.log('Buffer length:', buffer.length)
|
||||||
|
console.log('Buffer content:', Array.from(buffer))
|
||||||
|
console.error('UUID must be exactly 16 bytes')
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert each byte to a hex string and pad with zeros if needed
|
||||||
|
const hexValues = Array.from(buffer).map((byte) =>
|
||||||
|
byte.toString(16).padStart(2, '0')
|
||||||
|
)
|
||||||
|
|
||||||
|
// Format into UUID structure (8-4-4-4-12 characters)
|
||||||
|
return [
|
||||||
|
hexValues.slice(0, 4).join(''),
|
||||||
|
hexValues.slice(4, 6).join(''),
|
||||||
|
hexValues.slice(6, 8).join(''),
|
||||||
|
hexValues.slice(8, 10).join(''),
|
||||||
|
hexValues.slice(10, 16).join(''),
|
||||||
|
].join('-')
|
||||||
|
}
|
||||||
|
@ -5,7 +5,7 @@ import {
|
|||||||
enterEditFlow,
|
enterEditFlow,
|
||||||
EnterEditFlowProps,
|
EnterEditFlowProps,
|
||||||
} from 'lib/operations'
|
} from 'lib/operations'
|
||||||
import { engineCommandManager, kclManager } from 'lib/singletons'
|
import { kclManager } from 'lib/singletons'
|
||||||
import { err } from 'lib/trap'
|
import { err } from 'lib/trap'
|
||||||
import toast from 'react-hot-toast'
|
import toast from 'react-hot-toast'
|
||||||
import { Operation } from '@rust/kcl-lib/bindings/Operation'
|
import { Operation } from '@rust/kcl-lib/bindings/Operation'
|
||||||
@ -275,7 +275,7 @@ export const featureTreeMachine = setup({
|
|||||||
const artifact = context.targetSourceRange
|
const artifact = context.targetSourceRange
|
||||||
? getArtifactFromRange(
|
? getArtifactFromRange(
|
||||||
context.targetSourceRange,
|
context.targetSourceRange,
|
||||||
engineCommandManager.artifactGraph
|
kclManager.artifactGraph
|
||||||
) ?? undefined
|
) ?? undefined
|
||||||
: undefined
|
: undefined
|
||||||
return {
|
return {
|
||||||
@ -329,7 +329,7 @@ export const featureTreeMachine = setup({
|
|||||||
const artifact = context.targetSourceRange
|
const artifact = context.targetSourceRange
|
||||||
? getArtifactFromRange(
|
? getArtifactFromRange(
|
||||||
context.targetSourceRange,
|
context.targetSourceRange,
|
||||||
engineCommandManager.artifactGraph
|
kclManager.artifactGraph
|
||||||
) ?? undefined
|
) ?? undefined
|
||||||
: undefined
|
: undefined
|
||||||
return {
|
return {
|
||||||
@ -383,7 +383,7 @@ export const featureTreeMachine = setup({
|
|||||||
const artifact = context.targetSourceRange
|
const artifact = context.targetSourceRange
|
||||||
? getArtifactFromRange(
|
? getArtifactFromRange(
|
||||||
context.targetSourceRange,
|
context.targetSourceRange,
|
||||||
engineCommandManager.artifactGraph
|
kclManager.artifactGraph
|
||||||
) ?? undefined
|
) ?? undefined
|
||||||
: undefined
|
: undefined
|
||||||
return {
|
return {
|
||||||
|
@ -766,7 +766,7 @@ export const modelingMachine = setup({
|
|||||||
axisOrEdge,
|
axisOrEdge,
|
||||||
axis,
|
axis,
|
||||||
edge,
|
edge,
|
||||||
engineCommandManager.artifactGraph,
|
kclManager.artifactGraph,
|
||||||
selection.graphSelections[0]?.artifact
|
selection.graphSelections[0]?.artifact
|
||||||
)
|
)
|
||||||
if (trap(revolveSketchRes)) return
|
if (trap(revolveSketchRes)) return
|
||||||
@ -1123,9 +1123,7 @@ export const modelingMachine = setup({
|
|||||||
}),
|
}),
|
||||||
're-eval nodePaths': assign(({ context: { sketchDetails } }) => {
|
're-eval nodePaths': assign(({ context: { sketchDetails } }) => {
|
||||||
if (!sketchDetails) return {}
|
if (!sketchDetails) return {}
|
||||||
const planeArtifact = [
|
const planeArtifact = [...kclManager.artifactGraph.values()].find(
|
||||||
...engineCommandManager.artifactGraph.values(),
|
|
||||||
].find(
|
|
||||||
(artifact) =>
|
(artifact) =>
|
||||||
artifact.type === 'plane' &&
|
artifact.type === 'plane' &&
|
||||||
stringifyPathToNode(artifact.codeRef.pathToNode) ===
|
stringifyPathToNode(artifact.codeRef.pathToNode) ===
|
||||||
@ -1134,7 +1132,7 @@ export const modelingMachine = setup({
|
|||||||
if (planeArtifact?.type !== 'plane') return {}
|
if (planeArtifact?.type !== 'plane') return {}
|
||||||
const newPaths = getPathsFromPlaneArtifact(
|
const newPaths = getPathsFromPlaneArtifact(
|
||||||
planeArtifact,
|
planeArtifact,
|
||||||
engineCommandManager.artifactGraph,
|
kclManager.artifactGraph,
|
||||||
kclManager.ast
|
kclManager.ast
|
||||||
)
|
)
|
||||||
return {
|
return {
|
||||||
@ -1794,7 +1792,7 @@ export const modelingMachine = setup({
|
|||||||
node: ast,
|
node: ast,
|
||||||
pathToNode,
|
pathToNode,
|
||||||
artifact: selection.graphSelections[0].artifact,
|
artifact: selection.graphSelections[0].artifact,
|
||||||
artifactGraph: engineCommandManager.artifactGraph,
|
artifactGraph: kclManager.artifactGraph,
|
||||||
distance:
|
distance:
|
||||||
'variableName' in distance
|
'variableName' in distance
|
||||||
? distance.variableIdentifierAst
|
? distance.variableIdentifierAst
|
||||||
@ -1987,7 +1985,7 @@ export const modelingMachine = setup({
|
|||||||
const extrudeLookupResult = getPathToExtrudeForSegmentSelection(
|
const extrudeLookupResult = getPathToExtrudeForSegmentSelection(
|
||||||
clonedAstForGetExtrude,
|
clonedAstForGetExtrude,
|
||||||
cylinder.graphSelections[0],
|
cylinder.graphSelections[0],
|
||||||
engineCommandManager.artifactGraph
|
kclManager.artifactGraph
|
||||||
)
|
)
|
||||||
if (err(extrudeLookupResult)) {
|
if (err(extrudeLookupResult)) {
|
||||||
return extrudeLookupResult
|
return extrudeLookupResult
|
||||||
@ -2249,7 +2247,7 @@ export const modelingMachine = setup({
|
|||||||
const extrudeLookupResult = getPathToExtrudeForSegmentSelection(
|
const extrudeLookupResult = getPathToExtrudeForSegmentSelection(
|
||||||
clonedAstForGetExtrude,
|
clonedAstForGetExtrude,
|
||||||
graphSelection,
|
graphSelection,
|
||||||
engineCommandManager.artifactGraph
|
kclManager.artifactGraph
|
||||||
)
|
)
|
||||||
if (err(extrudeLookupResult)) {
|
if (err(extrudeLookupResult)) {
|
||||||
return new Error(
|
return new Error(
|
||||||
|
Reference in New Issue
Block a user