Add Point-and-Click Deletion for Fillets and Chamfers (#5098)

* ast mod

* point and click test

* tsc

* test test

* unit test edit

* topLevelRange

* disable unit test

* remove bad imports

* fix typo

* Fix cyclic dependency hell with getNodePathFromSourceRange

* tsc

* fix ImportStatement

* fix isValueZero

* pre-emptively ==> preemptively

* yarn fmt-check

* reenable the unit test

* fmt

* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)

* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)

* Trigger CI

* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)

* Trigger CI

* add test

* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)

* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)

* Trigger CI

* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)

* Trigger CI

* several treatments

* consolidate

* typos

* fix imports, consolidate

* consolidate import

* fix imports

* add tests

* stress test CI

* fix test

* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)

* Trigger CI

* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)

* Trigger CI

* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)

* Trigger CI

* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)

* Trigger CI

* fix tests

* clean test for fillets

* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)

* Trigger CI

* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)

* test chamfers

* comments

* simplify main tests

* typo

* typo2

* remove import

* clean up comments

---------

Co-authored-by: 49lf <ircsurfer33@gmail.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
This commit is contained in:
max
2025-02-03 18:11:26 +01:00
committed by GitHub
parent a44516bc7e
commit 3e8ee3ffc4
4 changed files with 694 additions and 1 deletions

View File

@ -20,6 +20,7 @@ import {
FilletParameters,
ChamferParameters,
EdgeTreatmentParameters,
deleteEdgeTreatment,
} from './addEdgeTreatment'
import { getNodeFromPath } from '../queryAst'
import { getNodePathFromSourceRange } from 'lang/queryAstNodePathUtils'
@ -287,7 +288,7 @@ const runModifyAstCloneWithEdgeTreatmentAndTag = async (
otherSelections: [],
}
// apply edge treatment to seleciton
// apply edge treatment to selection
const result = modifyAstWithEdgeTreatmentAndTag(ast, selection, parameters)
if (err(result)) {
return result
@ -298,6 +299,46 @@ const runModifyAstCloneWithEdgeTreatmentAndTag = async (
expect(newCode).toContain(expectedCode)
}
const runDeleteEdgeTreatmentTest = async (
code: string,
edgeTreatmentSnippet: string,
expectedCode: string
) => {
// parse ast
const ast = assertParse(code)
// update artifact graph
await kclManager.executeAst({ ast })
const artifactGraph = engineCommandManager.artifactGraph
// define snippet range
const edgeTreatmentRange = topLevelRange(
code.indexOf(edgeTreatmentSnippet),
code.indexOf(edgeTreatmentSnippet) + edgeTreatmentSnippet.length
)
// find artifact
const maybeArtifact = [...artifactGraph].find(([, artifact]) => {
if (!('codeRef' in artifact)) return false
return isOverlap(artifact.codeRef.range, edgeTreatmentRange)
})
// build selection
const selection: Selection = {
codeRef: codeRefFromRange(edgeTreatmentRange, ast),
artifact: maybeArtifact ? maybeArtifact[1] : undefined,
}
// delete edge treatment
const result = await deleteEdgeTreatment(ast, selection)
if (err(result)) {
return result
}
// recast and check
const newCode = recast(result)
expect(newCode).toContain(expectedCode)
}
const createFilletParameters = (radiusValue: number): FilletParameters => ({
type: EdgeTreatmentType.Fillet,
radius: {
@ -574,6 +615,191 @@ extrude002 = extrude(-25, sketch002)
)
})
})
describe(`Testing deleteEdgeTreatment with ${edgeTreatmentType}s`, () => {
// simple cases
it(`should delete a piped ${edgeTreatmentType} from a single segment`, async () => {
const code = `sketch001 = startSketchOn('XY')
|> startProfileAt([-10, 10], %)
|> line([20, 0], %)
|> line([0, -20], %)
|> line([-20, 0], %, $seg01)
|> lineTo([profileStartX(%), profileStartY(%)], %)
|> close(%)
extrude001 = extrude(-15, sketch001)
|> ${edgeTreatmentType}({ ${parameterName} = 3, tags = [seg01] }, %)`
const edgeTreatmentSnippet = `${edgeTreatmentType}({ ${parameterName} = 3, tags = [seg01] }, %)`
const expectedCode = `sketch001 = startSketchOn('XY')
|> startProfileAt([-10, 10], %)
|> line([20, 0], %)
|> line([0, -20], %)
|> line([-20, 0], %, $seg01)
|> lineTo([profileStartX(%), profileStartY(%)], %)
|> close(%)
extrude001 = extrude(-15, sketch001)`
await runDeleteEdgeTreatmentTest(
code,
edgeTreatmentSnippet,
expectedCode
)
})
it(`should delete a non-piped ${edgeTreatmentType} from a single segment`, async () => {
const code = `sketch001 = startSketchOn('XY')
|> startProfileAt([-10, 10], %)
|> line([20, 0], %)
|> line([0, -20], %)
|> line([-20, 0], %, $seg01)
|> lineTo([profileStartX(%), profileStartY(%)], %)
|> close(%)
extrude001 = extrude(-15, sketch001)
fillet001 = ${edgeTreatmentType}({ ${parameterName} = 3, tags = [seg01] }, extrude001)`
const edgeTreatmentSnippet = `fillet001 = ${edgeTreatmentType}({ ${parameterName} = 3, tags = [seg01] }, extrude001)`
const expectedCode = `sketch001 = startSketchOn('XY')
|> startProfileAt([-10, 10], %)
|> line([20, 0], %)
|> line([0, -20], %)
|> line([-20, 0], %, $seg01)
|> lineTo([profileStartX(%), profileStartY(%)], %)
|> close(%)
extrude001 = extrude(-15, sketch001)`
await runDeleteEdgeTreatmentTest(
code,
edgeTreatmentSnippet,
expectedCode
)
})
// getOppositeEdge and getNextAdjacentEdge cases
it(`should delete a piped ${edgeTreatmentType} tagged with getOppositeEdge`, async () => {
const code = `sketch001 = startSketchOn('XY')
|> startProfileAt([-10, 10], %)
|> line([20, 0], %)
|> line([0, -20], %)
|> line([-20, 0], %, $seg01)
|> lineTo([profileStartX(%), profileStartY(%)], %)
|> close(%)
extrude001 = extrude(-15, sketch001)
fillet001 = ${edgeTreatmentType}({ ${parameterName} = 3, tags = [getOppositeEdge(seg01)] }, extrude001)`
const edgeTreatmentSnippet = `fillet001 = ${edgeTreatmentType}({ ${parameterName} = 3, tags = [getOppositeEdge(seg01)] }, extrude001)`
const expectedCode = `sketch001 = startSketchOn('XY')
|> startProfileAt([-10, 10], %)
|> line([20, 0], %)
|> line([0, -20], %)
|> line([-20, 0], %, $seg01)
|> lineTo([profileStartX(%), profileStartY(%)], %)
|> close(%)
extrude001 = extrude(-15, sketch001)`
await runDeleteEdgeTreatmentTest(
code,
edgeTreatmentSnippet,
expectedCode
)
})
it(`should delete a non-piped ${edgeTreatmentType} tagged with getNextAdjacentEdge`, async () => {
const code = `sketch001 = startSketchOn('XY')
|> startProfileAt([-10, 10], %)
|> line([20, 0], %)
|> line([0, -20], %)
|> line([-20, 0], %, $seg01)
|> lineTo([profileStartX(%), profileStartY(%)], %)
|> close(%)
extrude001 = extrude(-15, sketch001)
fillet001 = ${edgeTreatmentType}({ ${parameterName} = 3, tags = [getNextAdjacentEdge(seg01)] }, extrude001)`
const edgeTreatmentSnippet = `fillet001 = ${edgeTreatmentType}({ ${parameterName} = 3, tags = [getNextAdjacentEdge(seg01)] }, extrude001)`
const expectedCode = `sketch001 = startSketchOn('XY')
|> startProfileAt([-10, 10], %)
|> line([20, 0], %)
|> line([0, -20], %)
|> line([-20, 0], %, $seg01)
|> lineTo([profileStartX(%), profileStartY(%)], %)
|> close(%)
extrude001 = extrude(-15, sketch001)`
await runDeleteEdgeTreatmentTest(
code,
edgeTreatmentSnippet,
expectedCode
)
})
// cases with several edge treatments
it(`should delete a piped ${edgeTreatmentType} from a body with multiple treatments`, async () => {
const code = `sketch001 = startSketchOn('XY')
|> startProfileAt([-10, 10], %)
|> line([20, 0], %, $seg01)
|> line([0, -20], %)
|> line([-20, 0], %, $seg02)
|> lineTo([profileStartX(%), profileStartY(%)], %)
|> close(%)
extrude001 = extrude(-15, sketch001)
|> ${edgeTreatmentType}({ ${parameterName} = 3, tags = [seg01] }, %)
|> fillet({ radius = 5, tags = [getOppositeEdge(seg02)] }, %)
fillet001 = ${edgeTreatmentType}({ ${parameterName} = 6, tags = [seg02] }, extrude001)
chamfer001 = chamfer({ length = 5, tags = [getOppositeEdge(seg01)] }, extrude001)`
const edgeTreatmentSnippet = `${edgeTreatmentType}({ ${parameterName} = 3, tags = [seg01] }, %)`
const expectedCode = `sketch001 = startSketchOn('XY')
|> startProfileAt([-10, 10], %)
|> line([20, 0], %, $seg01)
|> line([0, -20], %)
|> line([-20, 0], %, $seg02)
|> lineTo([profileStartX(%), profileStartY(%)], %)
|> close(%)
extrude001 = extrude(-15, sketch001)
|> fillet({
radius = 5,
tags = [getOppositeEdge(seg02)]
}, %)
fillet001 = ${edgeTreatmentType}({ ${parameterName} = 6, tags = [seg02] }, extrude001)
chamfer001 = chamfer({
length = 5,
tags = [getOppositeEdge(seg01)]
}, extrude001)`
await runDeleteEdgeTreatmentTest(
code,
edgeTreatmentSnippet,
expectedCode
)
})
it(`should delete a non-piped ${edgeTreatmentType} from a body with multiple treatments`, async () => {
const code = `sketch001 = startSketchOn('XY')
|> startProfileAt([-10, 10], %)
|> line([20, 0], %, $seg01)
|> line([0, -20], %)
|> line([-20, 0], %, $seg02)
|> lineTo([profileStartX(%), profileStartY(%)], %)
|> close(%)
extrude001 = extrude(-15, sketch001)
|> ${edgeTreatmentType}({ ${parameterName} = 3, tags = [seg01] }, %)
|> fillet({ radius = 5, tags = [getOppositeEdge(seg02)] }, %)
fillet001 = ${edgeTreatmentType}({ ${parameterName} = 6, tags = [seg02] }, extrude001)
chamfer001 = chamfer({ length = 5, tags = [getOppositeEdge(seg01)] }, extrude001)`
const edgeTreatmentSnippet = `fillet001 = ${edgeTreatmentType}({ ${parameterName} = 6, tags = [seg02] }, extrude001)`
const expectedCode = `sketch001 = startSketchOn('XY')
|> startProfileAt([-10, 10], %)
|> line([20, 0], %, $seg01)
|> line([0, -20], %)
|> line([-20, 0], %, $seg02)
|> lineTo([profileStartX(%), profileStartY(%)], %)
|> close(%)
extrude001 = extrude(-15, sketch001)
|> ${edgeTreatmentType}({ ${parameterName} = 3, tags = [seg01] }, %)
|> fillet({
radius = 5,
tags = [getOppositeEdge(seg02)]
}, %)
chamfer001 = chamfer({
length = 5,
tags = [getOppositeEdge(seg01)]
}, extrude001)`
await runDeleteEdgeTreatmentTest(
code,
edgeTreatmentSnippet,
expectedCode
)
})
})
}
)