make delet of extrusions work for multi profile

This commit is contained in:
Kurt Hutten Irev-Dev
2025-02-14 00:00:47 +11:00
committed by Frank Noirot
parent 42016b7335
commit df8977407c

View File

@ -25,6 +25,7 @@ import {
formatNumber, formatNumber,
ArtifactGraph, ArtifactGraph,
VariableMap, VariableMap,
KclValue,
} from './wasm' } from './wasm'
import { import {
isNodeSafeToReplacePath, isNodeSafeToReplacePath,
@ -52,7 +53,7 @@ import {
transformAstSketchLines, transformAstSketchLines,
} from './std/sketchcombos' } from './std/sketchcombos'
import { DefaultPlaneStr } from 'lib/planes' import { DefaultPlaneStr } from 'lib/planes'
import { isOverlap, roundOff } from 'lib/utils' import { isArray, isOverlap, roundOff } from 'lib/utils'
import { KCL_DEFAULT_CONSTANT_PREFIXES } from 'lib/constants' import { KCL_DEFAULT_CONSTANT_PREFIXES } from 'lib/constants'
import { SimplifiedArgDetails } from './std/stdTypes' import { SimplifiedArgDetails } from './std/stdTypes'
import { TagDeclarator } from 'wasm-lib/kcl/bindings/TagDeclarator' import { TagDeclarator } from 'wasm-lib/kcl/bindings/TagDeclarator'
@ -65,6 +66,8 @@ import {
expandCap, expandCap,
expandPlane, expandPlane,
expandWall, expandWall,
getArtifactOfTypes,
getArtifactsOfTypes,
getPathsFromArtifact, getPathsFromArtifact,
} from './std/artifactGraph' } from './std/artifactGraph'
import { BodyItem } from 'wasm-lib/kcl/bindings/BodyItem' import { BodyItem } from 'wasm-lib/kcl/bindings/BodyItem'
@ -1391,12 +1394,11 @@ export async function deleteFromSelection(
({} as any) ({} as any)
): Promise<Node<Program> | Error> { ): Promise<Node<Program> | Error> {
const astClone = structuredClone(ast) const astClone = structuredClone(ast)
console.log('deleting', selection, variables)
if ( if (
(selection.artifact?.type === 'plane' || (selection.artifact?.type === 'plane' ||
selection.artifact?.type === 'cap' || selection.artifact?.type === 'cap' ||
selection.artifact?.type === 'wall') && selection.artifact?.type === 'wall') &&
selection.artifact.pathIds.length selection.artifact?.pathIds?.length
) { ) {
const plane = const plane =
selection.artifact.type === 'plane' selection.artifact.type === 'plane'
@ -1503,59 +1505,108 @@ export async function deleteFromSelection(
if (extrudeNameToDelete) { if (extrudeNameToDelete) {
await new Promise((resolve) => { await new Promise((resolve) => {
;(async () => { ;(async () => {
let currentVariableName = ''
const pathsDependingOnExtrude: Array<{ const pathsDependingOnExtrude: Array<{
path: PathToNode path: PathToNode
sketchName: string variable: KclValue
}> = [] }> = []
traverse(astClone, {
leave: (node) => {
if (node.type === 'VariableDeclaration') {
currentVariableName = ''
}
},
enter: (node, path) => {
;(async () => {
if (node.type === 'VariableDeclaration') {
currentVariableName = node.declaration.id.name
}
if (
// match startSketchOn(${extrudeNameToDelete})
node.type === 'CallExpression' &&
node.callee.name === 'startSketchOn' &&
node.arguments[0].type === 'Identifier' &&
node.arguments[0].name === extrudeNameToDelete
) {
pathsDependingOnExtrude.push({
path,
sketchName: currentVariableName,
})
}
})().catch(reportRejection)
},
})
const roundLiteral = (x: number) => createLiteral(roundOff(x)) const roundLiteral = (x: number) => createLiteral(roundOff(x))
const modificationDetails: { const modificationDetails: {
parent: PipeExpression['body'] parentPipe: PipeExpression['body']
parentInit: VariableDeclarator
faceDetails: Models['FaceIsPlanar_type'] faceDetails: Models['FaceIsPlanar_type']
lastKey: number lastKey: number | string
}[] = [] }[] = []
for (const { path, sketchName } of pathsDependingOnExtrude) { const wallArtifact =
const parent = getNodeFromPath<PipeExpression['body']>( selection.artifact?.type === 'wall'
? selection.artifact
: selection.artifact?.type === 'segment' &&
selection.artifact.surfaceId
? getArtifactOfTypes(
{ key: selection.artifact.surfaceId, types: ['wall'] },
engineCommandManager.artifactGraph
)
: null
if (err(wallArtifact)) return
if (wallArtifact) {
const sweep = getArtifactOfTypes(
{ key: wallArtifact.sweepId, types: ['sweep'] },
engineCommandManager.artifactGraph
)
if (err(sweep)) return
const wallsWithDependencies = Array.from(
getArtifactsOfTypes(
{ keys: sweep.surfaceIds, types: ['wall', 'cap'] },
engineCommandManager.artifactGraph
).values()
).filter((wall) => wall?.pathIds?.length)
const wallIds = wallsWithDependencies.map((wall) => wall.id)
Object.entries(variables).forEach(([key, _var]) => {
if (
_var?.type === 'Face' &&
wallIds.includes(_var.value.artifactId)
) {
const pathToStartSketchOn = getNodePathFromSourceRange(
astClone,
_var.value.__meta[0].sourceRange
)
pathsDependingOnExtrude.push({
path: pathToStartSketchOn,
variable: _var,
})
}
if (
_var?.type === 'Sketch' &&
_var.value.on.type === 'face' &&
wallIds.includes(_var.value.on.artifactId)
) {
const pathToStartSketchOn = getNodePathFromSourceRange(
astClone,
_var.value.on.__meta[0].sourceRange
)
pathsDependingOnExtrude.push({
path: pathToStartSketchOn,
variable: {
type: 'Face',
value: _var.value.on,
},
})
}
})
}
for (const { path, variable } of pathsDependingOnExtrude) {
// `parentPipe` and `parentInit` are the exact same node, but because it could either be an array or on object node
// putting them in two different variables was the only way to get TypeScript to stop complaining
// the reason why we're grabbing the parent and the last key is because we want to mutate the ast
// so `parent[lastKey]` does the trick, if there's a better way of doing this I'm all years
const parentPipe = getNodeFromPath<PipeExpression['body']>(
astClone, astClone,
path.slice(0, -1) path.slice(0, -1)
) )
if (err(parent)) { const parentInit = getNodeFromPath<VariableDeclarator>(
astClone,
path.slice(0, -1)
)
if (err(parentPipe) || err(parentInit)) {
return return
} }
const sketchToPreserve = sketchFromKclValue( if (!variable) return new Error('Could not find sketch')
variables[sketchName], const artifactId =
sketchName variable.type === 'Sketch'
) ? variable.value.artifactId
if (err(sketchToPreserve)) return sketchToPreserve : variable.type === 'Face'
? variable.value.artifactId
: ''
if (!artifactId) return new Error('Sketch not on anything')
const onId =
variable.type === 'Sketch'
? variable.value.on.id
: variable.type === 'Face'
? variable.value.id
: ''
if (!onId) return new Error('Sketch not on anything')
// Can't kick off multiple requests at once as getFaceDetails // Can't kick off multiple requests at once as getFaceDetails
// is three engine calls in one and they conflict // is three engine calls in one and they conflict
const faceDetails = await getFaceDetails(sketchToPreserve.on.id) const faceDetails = await getFaceDetails(onId)
if ( if (
!( !(
faceDetails.origin && faceDetails.origin &&
@ -1566,14 +1617,20 @@ export async function deleteFromSelection(
) { ) {
return return
} }
const lastKey = Number(path.slice(-1)[0][0]) const lastKey = path.slice(-1)[0][0]
modificationDetails.push({ modificationDetails.push({
parent: parent.node, parentPipe: parentPipe.node,
parentInit: parentInit.node,
faceDetails, faceDetails,
lastKey, lastKey,
}) })
} }
for (const { parent, faceDetails, lastKey } of modificationDetails) { for (const {
parentInit,
parentPipe,
faceDetails,
lastKey,
} of modificationDetails) {
if ( if (
!( !(
faceDetails.origin && faceDetails.origin &&
@ -1584,7 +1641,7 @@ export async function deleteFromSelection(
) { ) {
continue continue
} }
parent[lastKey] = createCallExpressionStdLib('startSketchOn', [ const expression = createCallExpressionStdLib('startSketchOn', [
createObjectExpression({ createObjectExpression({
plane: createObjectExpression({ plane: createObjectExpression({
origin: createObjectExpression({ origin: createObjectExpression({
@ -1610,6 +1667,14 @@ export async function deleteFromSelection(
}), }),
}), }),
]) ])
if (
parentInit.type === 'VariableDeclarator' &&
lastKey === 'init'
) {
parentInit[lastKey] = expression
} else if (isArray(parentPipe) && typeof lastKey === 'number') {
parentPipe[lastKey] = expression
}
} }
resolve(true) resolve(true)
})().catch(reportRejection) })().catch(reportRejection)
@ -1621,8 +1686,12 @@ export async function deleteFromSelection(
return deleteEdgeTreatment(astClone, selection) return deleteEdgeTreatment(astClone, selection)
} else if (varDec.node.init.type === 'PipeExpression') { } else if (varDec.node.init.type === 'PipeExpression') {
const pipeBody = varDec.node.init.body const pipeBody = varDec.node.init.body
const doNotDeleteProfileIfItHasBeenExtruded = !(
selection?.artifact?.type === 'segment' && selection?.artifact?.surfaceId
)
if ( if (
pipeBody[0].type === 'CallExpression' && pipeBody[0].type === 'CallExpression' &&
doNotDeleteProfileIfItHasBeenExtruded &&
(pipeBody[0].callee.name === 'startSketchOn' || (pipeBody[0].callee.name === 'startSketchOn' ||
pipeBody[0].callee.name === 'startProfileAt') pipeBody[0].callee.name === 'startProfileAt')
) { ) {