Assemblies: Set translate and rotate via point-and-click (#6167)

* WIP: Add point-and-click Import for geometry
Will eventually fix #6120
Right now the whole loop is there but the codemod doesn't work yet

* Better pathToNOde, log on non-working cm dispatch call

* Add workaround to updateModelingState not working

* Back to updateModelingState with a skip flag

* Better todo

* Change working from Import to Insert, cleanups

* Sister command in kclCommands to populate file options

* Improve path selector

* Unsure: move importAstMod to kclCommands onSubmit 😶

* Add e2e test

* Clean up for review

* Add native file menu entry and test

* No await yo lint said so

* WIP: UX improvements around foreign file imports
Fixes #6152

* WIP: Set translate and rotate via point-and-click on imports. Boilerplate code
Will eventually close #6020

* Full working loop of rotate and translate pipe mutation, including edits, only on module imports. VERY VERBOSE

* Add first e2e test for set transform. Bunch of caveats listed as TODOs

* @lrev-Dev's suggestion to remove a comment

Co-authored-by: Kurt Hutten <k.hutten@protonmail.ch>

* Update to scene.settled(cmdBar)

* Add partNNN default name for alias

* Lint

* Lint

* Fix unit tests

* Add sad path insert test
Thanks @Irev-Dev for the suggestion

* Add step insert test

* Lint

* Add test for second foreign import thru file tree click

* WIP: Add point-and-click Load to copy files from outside the project into the project
Towards #6210

* Move Insert button to modeling toolbar, update menus and toolbars

* Add default value for local name alias

* Aligning tests

* Fix tests

* Add padding for filenames starting with a digit

* Lint

* Lint

* Update snapshots

* Merge branch 'main' into pierremtb/issue6210-Add-point-and-click-Load-to-copy-files-from-outside-the-project-into-the-project

* Add disabled transform subbutton

* Allow start of Transform flow from toolbar with selection

* Merge kcl-samples and local disk load into one 'Load external model' command

* Fix em tests

* Fix test

* Add test for file pick import, better input

* Fix non .kcl loading

* Lint

* Update snapshots

* Fix issue leading to test failure

* Fix clone test

* Add note

* Fix nested clone issue

* Clean up for review

* Add valueSummary for path

* Fix test after path change

* Clean up for review

* Support much wider range for transform

* Set display names

* Bug fixed itself moment...

* Add test for extrude tranform

* Oops missed a thing

* Clean up selection arg

* More tests incl for variable stuff

* Fix imports

* Add supportsTransform: true on all solids returning operations

* Fix edit flow on variables, add test

* Split transform command into translate and rotate

* Clean up and comment

* Clean up operations.ts

* Add comment

* Improve assemblies test

* Support more things

* Typo

* Fix test after unit change on import

* Last clean up for review

* Fix remaining test

---------

Co-authored-by: Kurt Hutten <k.hutten@protonmail.ch>
This commit is contained in:
Pierre Jacquier
2025-04-17 11:44:31 -04:00
committed by GitHub
parent 056a4d4a22
commit 6f2d127c4f
17 changed files with 1496 additions and 48 deletions

View File

@ -1,6 +1,7 @@
import type { OpKclValue, Operation } from '@rust/kcl-lib/bindings/Operation'
import type { CustomIconName } from '@src/components/CustomIcon'
import { getNodeFromPath } from '@src/lang/queryAst'
import { getNodePathFromSourceRange } from '@src/lang/queryAstNodePathUtils'
import type { Artifact } from '@src/lang/std/artifactGraph'
import {
@ -10,13 +11,16 @@ import {
getSweepEdgeCodeRef,
getWallCodeRef,
} from '@src/lang/std/artifactGraph'
import { sourceRangeFromRust } from '@src/lang/wasm'
import { type PipeExpression, sourceRangeFromRust } from '@src/lang/wasm'
import type {
HelixModes,
ModelingCommandSchema,
} from '@src/lib/commandBarConfigs/modelingCommandConfig'
import type { KclExpression } from '@src/lib/commandTypes'
import { stringToKclExpression } from '@src/lib/kclHelpers'
import {
stringToKclExpression,
retrieveArgFromPipedCallExpression,
} from '@src/lib/kclHelpers'
import { isDefaultPlaneStr } from '@src/lib/planes'
import type { Selection, Selections } from '@src/lib/selections'
import { codeManager, kclManager, rustContext } from '@src/lib/singletons'
@ -46,6 +50,7 @@ interface StdLibCallInfo {
| PrepareToEditCallback
| PrepareToEditFailurePayload
supportsAppearance?: boolean
supportsTransform?: boolean
}
/**
@ -1008,6 +1013,7 @@ export const stdLibMap: Record<string, StdLibCallInfo> = {
icon: 'extrude',
prepareToEdit: prepareToEditExtrude,
supportsAppearance: true,
supportsTransform: true,
},
fillet: {
label: 'Fillet',
@ -1026,19 +1032,26 @@ export const stdLibMap: Record<string, StdLibCallInfo> = {
hollow: {
label: 'Hollow',
icon: 'hollow',
supportsAppearance: true,
supportsTransform: true,
},
import: {
label: 'Import',
icon: 'import',
supportsAppearance: true,
supportsTransform: true,
},
intersect: {
label: 'Intersect',
icon: 'booleanIntersect',
supportsAppearance: true,
supportsTransform: true,
},
loft: {
label: 'Loft',
icon: 'loft',
supportsAppearance: true,
supportsTransform: true,
},
offsetPlane: {
label: 'Offset Plane',
@ -1052,6 +1065,8 @@ export const stdLibMap: Record<string, StdLibCallInfo> = {
patternCircular3d: {
label: 'Circular Pattern',
icon: 'patternCircular3d',
supportsAppearance: true,
supportsTransform: true,
},
patternLinear2d: {
label: 'Linear Pattern',
@ -1060,18 +1075,22 @@ export const stdLibMap: Record<string, StdLibCallInfo> = {
patternLinear3d: {
label: 'Linear Pattern',
icon: 'patternLinear3d',
supportsAppearance: true,
supportsTransform: true,
},
revolve: {
label: 'Revolve',
icon: 'revolve',
prepareToEdit: prepareToEditRevolve,
supportsAppearance: true,
supportsTransform: true,
},
shell: {
label: 'Shell',
icon: 'shell',
prepareToEdit: prepareToEditShell,
supportsAppearance: true,
supportsTransform: true,
},
startSketchOn: {
label: 'Sketch',
@ -1284,7 +1303,6 @@ export async function enterEditFlow({
export async function enterAppearanceFlow({
operation,
artifact,
}: EnterEditFlowProps): Promise<Error | CommandBarMachineEvent> {
if (operation.type !== 'StdLibCall' && operation.type !== 'KclStdLibCall') {
return new Error(
@ -1300,7 +1318,6 @@ export async function enterAppearanceFlow({
sourceRangeFromRust(operation.sourceRange)
),
}
console.log('argDefaultValues', argDefaultValues)
return {
type: 'Find and select command',
data: {
@ -1315,3 +1332,101 @@ export async function enterAppearanceFlow({
'Appearance setting not yet supported for this operation. Please edit in the code editor.'
)
}
export async function enterTranslateFlow({
operation,
}: EnterEditFlowProps): Promise<Error | CommandBarMachineEvent> {
const isModuleImport = operation.type === 'GroupBegin'
const isSupportedStdLibCall =
(operation.type === 'KclStdLibCall' || operation.type === 'StdLibCall') &&
stdLibMap[operation.name]?.supportsTransform
if (!isModuleImport && !isSupportedStdLibCall) {
return new Error(
'Unsupported operation type. Please edit in the code editor.'
)
}
const nodeToEdit = getNodePathFromSourceRange(
kclManager.ast,
sourceRangeFromRust(operation.sourceRange)
)
let x: KclExpression | undefined = undefined
let y: KclExpression | undefined = undefined
let z: KclExpression | undefined = undefined
const pipe = getNodeFromPath<PipeExpression>(
kclManager.ast,
nodeToEdit,
'PipeExpression'
)
if (!err(pipe) && pipe.node.body) {
const translate = pipe.node.body.find(
(n) => n.type === 'CallExpressionKw' && n.callee.name.name === 'translate'
)
if (translate?.type === 'CallExpressionKw') {
x = await retrieveArgFromPipedCallExpression(translate, 'x')
y = await retrieveArgFromPipedCallExpression(translate, 'y')
z = await retrieveArgFromPipedCallExpression(translate, 'z')
}
}
// Won't be used since we provide nodeToEdit
const selection: Selections = { graphSelections: [], otherSelections: [] }
const argDefaultValues = { nodeToEdit, selection, x, y, z }
return {
type: 'Find and select command',
data: {
name: 'Translate',
groupId: 'modeling',
argDefaultValues,
},
}
}
export async function enterRotateFlow({
operation,
}: EnterEditFlowProps): Promise<Error | CommandBarMachineEvent> {
const isModuleImport = operation.type === 'GroupBegin'
const isSupportedStdLibCall =
(operation.type === 'KclStdLibCall' || operation.type === 'StdLibCall') &&
stdLibMap[operation.name]?.supportsTransform
if (!isModuleImport && !isSupportedStdLibCall) {
return new Error(
'Unsupported operation type. Please edit in the code editor.'
)
}
const nodeToEdit = getNodePathFromSourceRange(
kclManager.ast,
sourceRangeFromRust(operation.sourceRange)
)
let roll: KclExpression | undefined = undefined
let pitch: KclExpression | undefined = undefined
let yaw: KclExpression | undefined = undefined
const pipe = getNodeFromPath<PipeExpression>(
kclManager.ast,
nodeToEdit,
'PipeExpression'
)
if (!err(pipe) && pipe.node.body) {
const rotate = pipe.node.body.find(
(n) => n.type === 'CallExpressionKw' && n.callee.name.name === 'rotate'
)
if (rotate?.type === 'CallExpressionKw') {
roll = await retrieveArgFromPipedCallExpression(rotate, 'roll')
pitch = await retrieveArgFromPipedCallExpression(rotate, 'pitch')
yaw = await retrieveArgFromPipedCallExpression(rotate, 'yaw')
}
}
// Won't be used since we provide nodeToEdit
const selection: Selections = { graphSelections: [], otherSelections: [] }
const argDefaultValues = { nodeToEdit, selection, roll, pitch, yaw }
return {
type: 'Find and select command',
data: {
name: 'Rotate',
groupId: 'modeling',
argDefaultValues,
},
}
}