2025-01-23 10:25:21 -05:00
|
|
|
|
import { useMachine, useSelector } from '@xstate/react'
|
2025-04-01 15:31:19 -07:00
|
|
|
|
import React, {
|
|
|
|
|
createContext,
|
2025-04-01 23:54:26 -07:00
|
|
|
|
useContext,
|
2025-04-01 15:31:19 -07:00
|
|
|
|
useEffect,
|
|
|
|
|
useMemo,
|
|
|
|
|
useRef,
|
|
|
|
|
} from 'react'
|
2025-04-01 23:54:26 -07:00
|
|
|
|
import toast from 'react-hot-toast'
|
2025-04-01 15:31:19 -07:00
|
|
|
|
import { useHotkeys } from 'react-hotkeys-hook'
|
2025-04-01 23:54:26 -07:00
|
|
|
|
import { useLoaderData, useNavigate, useSearchParams } from 'react-router-dom'
|
|
|
|
|
import type { Actor, ContextFrom, Prop, SnapshotFrom, StateFrom } from 'xstate'
|
|
|
|
|
import { assign, fromPromise } from 'xstate'
|
|
|
|
|
|
|
|
|
|
import type {
|
|
|
|
|
OutputFormat3d,
|
|
|
|
|
Point3d,
|
|
|
|
|
} from '@rust/kcl-lib/bindings/ModelingCmd'
|
|
|
|
|
import type { Node } from '@rust/kcl-lib/bindings/Node'
|
|
|
|
|
import type { Plane } from '@rust/kcl-lib/bindings/Plane'
|
|
|
|
|
|
|
|
|
|
import { letEngineAnimateAndSyncCamAfter } from '@src/clientSideScene/CameraControls'
|
|
|
|
|
import {
|
|
|
|
|
SEGMENT_BODIES,
|
|
|
|
|
getParentGroup,
|
|
|
|
|
} from '@src/clientSideScene/sceneConstants'
|
|
|
|
|
import type { MachineManager } from '@src/components/MachineManagerProvider'
|
|
|
|
|
import { MachineManagerContext } from '@src/components/MachineManagerProvider'
|
|
|
|
|
import { applyConstraintIntersect } from '@src/components/Toolbar/Intersect'
|
|
|
|
|
import { applyConstraintAbsDistance } from '@src/components/Toolbar/SetAbsDistance'
|
2025-04-01 15:31:19 -07:00
|
|
|
|
import {
|
|
|
|
|
angleBetweenInfo,
|
|
|
|
|
applyConstraintAngleBetween,
|
2025-04-01 23:54:26 -07:00
|
|
|
|
} from '@src/components/Toolbar/SetAngleBetween'
|
|
|
|
|
import { applyConstraintHorzVertDistance } from '@src/components/Toolbar/SetHorzVertDistance'
|
2025-04-01 15:31:19 -07:00
|
|
|
|
import {
|
|
|
|
|
applyConstraintAngleLength,
|
|
|
|
|
applyConstraintLength,
|
2025-04-01 23:54:26 -07:00
|
|
|
|
} from '@src/components/Toolbar/setAngleLength'
|
|
|
|
|
import { useFileContext } from '@src/hooks/useFileContext'
|
|
|
|
|
import { useSetupEngineManager } from '@src/hooks/useSetupEngineManager'
|
|
|
|
|
import useStateMachineCommands from '@src/hooks/useStateMachineCommands'
|
|
|
|
|
import { updateModelingState } from '@src/lang/modelingWorkflows'
|
2024-05-24 20:54:42 +10:00
|
|
|
|
import {
|
2024-12-09 16:43:58 -05:00
|
|
|
|
insertNamedConstant,
|
|
|
|
|
replaceValueAtNodePath,
|
2024-05-24 20:54:42 +10:00
|
|
|
|
sketchOnExtrudedFace,
|
2024-11-18 16:25:25 -05:00
|
|
|
|
sketchOnOffsetPlane,
|
2025-02-15 00:57:04 +11:00
|
|
|
|
splitPipedProfile,
|
2024-05-24 20:54:42 +10:00
|
|
|
|
startSketchOnDefault,
|
2025-04-01 23:54:26 -07:00
|
|
|
|
} from '@src/lang/modifyAst'
|
2025-02-15 00:57:04 +11:00
|
|
|
|
import {
|
2025-04-01 15:31:19 -07:00
|
|
|
|
artifactIsPlaneWithPaths,
|
|
|
|
|
doesSketchPipeNeedSplitting,
|
|
|
|
|
getNodeFromPath,
|
|
|
|
|
isCursorInFunctionDefinition,
|
|
|
|
|
traverse,
|
2025-04-01 23:54:26 -07:00
|
|
|
|
} from '@src/lang/queryAst'
|
|
|
|
|
import { getNodePathFromSourceRange } from '@src/lang/queryAstNodePathUtils'
|
2025-04-01 15:31:19 -07:00
|
|
|
|
import {
|
|
|
|
|
getFaceCodeRef,
|
|
|
|
|
getPathsFromArtifact,
|
|
|
|
|
getPlaneFromArtifact,
|
2025-04-01 23:54:26 -07:00
|
|
|
|
} from '@src/lang/std/artifactGraph'
|
|
|
|
|
import {
|
|
|
|
|
EngineConnectionEvents,
|
|
|
|
|
EngineConnectionStateType,
|
|
|
|
|
} from '@src/lang/std/engineConnection'
|
|
|
|
|
import {
|
|
|
|
|
isCursorInSketchCommandRange,
|
|
|
|
|
updateSketchDetailsNodePaths,
|
|
|
|
|
} from '@src/lang/util'
|
|
|
|
|
import type {
|
|
|
|
|
KclValue,
|
|
|
|
|
PathToNode,
|
|
|
|
|
PipeExpression,
|
|
|
|
|
Program,
|
|
|
|
|
VariableDeclaration,
|
|
|
|
|
} from '@src/lang/wasm'
|
|
|
|
|
import { parse, recast, resultIsOk } from '@src/lang/wasm'
|
|
|
|
|
import type { ModelingCommandSchema } from '@src/lib/commandBarConfigs/modelingCommandConfig'
|
|
|
|
|
import { modelingMachineCommandConfig } from '@src/lib/commandBarConfigs/modelingCommandConfig'
|
|
|
|
|
import {
|
|
|
|
|
EXECUTION_TYPE_MOCK,
|
|
|
|
|
EXPORT_TOAST_MESSAGES,
|
|
|
|
|
MAKE_TOAST_MESSAGES,
|
|
|
|
|
} from '@src/lib/constants'
|
|
|
|
|
import { exportMake } from '@src/lib/exportMake'
|
|
|
|
|
import { exportSave } from '@src/lib/exportSave'
|
|
|
|
|
import { promptToEditFlow } from '@src/lib/promptToEdit'
|
|
|
|
|
import type { Selections } from '@src/lib/selections'
|
|
|
|
|
import { handleSelectionBatch, updateSelections } from '@src/lib/selections'
|
|
|
|
|
import {
|
|
|
|
|
codeManager,
|
|
|
|
|
editorManager,
|
|
|
|
|
engineCommandManager,
|
|
|
|
|
kclManager,
|
|
|
|
|
rustContext,
|
|
|
|
|
sceneEntitiesManager,
|
|
|
|
|
sceneInfra,
|
|
|
|
|
} from '@src/lib/singletons'
|
|
|
|
|
import { submitAndAwaitTextToKcl } from '@src/lib/textToCad'
|
|
|
|
|
import { err, reject, reportRejection, trap } from '@src/lib/trap'
|
|
|
|
|
import type { IndexLoaderData } from '@src/lib/types'
|
|
|
|
|
import { platform, uuidv4 } from '@src/lib/utils'
|
|
|
|
|
import { useSettings, useToken } from '@src/machines/appMachine'
|
|
|
|
|
import { commandBarActor } from '@src/machines/commandBarMachine'
|
|
|
|
|
import { kclEditorActor } from '@src/machines/kclEditorMachine'
|
|
|
|
|
import {
|
|
|
|
|
getPersistedContext,
|
|
|
|
|
modelingMachine,
|
|
|
|
|
modelingMachineDefaultContext,
|
|
|
|
|
} from '@src/machines/modelingMachine'
|
2023-10-11 13:36:54 +11:00
|
|
|
|
|
|
|
|
|
export const ModelingMachineContext = createContext(
|
2025-03-18 20:25:51 -07:00
|
|
|
|
{} as {
|
|
|
|
|
state: StateFrom<typeof modelingMachine>
|
|
|
|
|
context: ContextFrom<typeof modelingMachine>
|
|
|
|
|
send: Prop<Actor<typeof modelingMachine>, 'send'>
|
|
|
|
|
}
|
2023-10-11 13:36:54 +11:00
|
|
|
|
)
|
|
|
|
|
|
2025-01-23 10:25:21 -05:00
|
|
|
|
const commandBarIsClosedSelector = (
|
|
|
|
|
state: SnapshotFrom<typeof commandBarActor>
|
|
|
|
|
) => state.matches('Closed')
|
|
|
|
|
|
2023-10-11 13:36:54 +11:00
|
|
|
|
export const ModelingMachineProvider = ({
|
|
|
|
|
children,
|
|
|
|
|
}: {
|
|
|
|
|
children: React.ReactNode
|
|
|
|
|
}) => {
|
2024-03-04 16:06:43 -05:00
|
|
|
|
const {
|
2025-02-28 16:15:57 -08:00
|
|
|
|
app: { theme, allowOrbitInSketchMode },
|
2025-02-21 13:47:36 -05:00
|
|
|
|
modeling: {
|
|
|
|
|
defaultUnit,
|
|
|
|
|
cameraProjection,
|
|
|
|
|
highlightEdges,
|
|
|
|
|
showScaleGrid,
|
|
|
|
|
cameraOrbit,
|
2025-02-28 16:15:57 -08:00
|
|
|
|
enableSSAO,
|
2024-03-04 16:06:43 -05:00
|
|
|
|
},
|
2025-02-21 13:47:36 -05:00
|
|
|
|
} = useSettings()
|
2024-08-14 14:26:44 -04:00
|
|
|
|
const navigate = useNavigate()
|
|
|
|
|
const { context, send: fileMachineSend } = useFileContext()
|
2024-10-21 14:27:32 -07:00
|
|
|
|
const { file } = useLoaderData() as IndexLoaderData
|
2025-01-31 14:47:08 -05:00
|
|
|
|
const token = useToken()
|
2023-10-11 13:36:54 +11:00
|
|
|
|
const streamRef = useRef<HTMLDivElement>(null)
|
2024-08-02 15:39:05 -04:00
|
|
|
|
const persistedContext = useMemo(() => getPersistedContext(), [])
|
2024-04-25 15:51:33 -04:00
|
|
|
|
|
|
|
|
|
let [searchParams] = useSearchParams()
|
|
|
|
|
const pool = searchParams.get('pool')
|
|
|
|
|
|
2025-01-23 10:25:21 -05:00
|
|
|
|
const isCommandBarClosed = useSelector(
|
|
|
|
|
commandBarActor,
|
|
|
|
|
commandBarIsClosedSelector
|
|
|
|
|
)
|
2023-10-11 13:36:54 +11:00
|
|
|
|
// Settings machine setup
|
|
|
|
|
// const retrievedSettings = useRef(
|
|
|
|
|
// localStorage?.getItem(MODELING_PERSIST_KEY) || '{}'
|
|
|
|
|
// )
|
|
|
|
|
|
|
|
|
|
// What should we persist from modeling state? Nothing?
|
|
|
|
|
// const persistedSettings = Object.assign(
|
|
|
|
|
// settingsMachine.initialState.context,
|
|
|
|
|
// JSON.parse(retrievedSettings.current) as Partial<
|
|
|
|
|
// (typeof settingsMachine)['context']
|
|
|
|
|
// >
|
|
|
|
|
// )
|
|
|
|
|
|
2024-10-25 19:28:10 -04:00
|
|
|
|
const machineManager = useContext(MachineManagerContext)
|
|
|
|
|
|
Command bar: add extrude command, nonlinear editing, etc (#1204)
* Tweak toaster look and feel
* Add icons, tweak plus icon names
* Rename commandBarMeta to commandBarConfig
* Refactor command bar, add support for icons
* Create a tailwind plugin for aria-pressed button state
* Remove overlay from behind command bar
* Clean up toolbar
* Button and other style tweaks
* Icon tweaks follow-up: make old icons work with new sizing
* Delete unused static icons
* More CSS tweaks
* Small CSS tweak to project sidebar
* Add command bar E2E test
* fumpt
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)
* fix typo in a comment
* Fix icon padding (built version only)
* Update onboarding and warning banner icons padding
* Misc minor style fixes
* Get Extrude opening and canceling from command bar
* Iconography tweaks
* Get extrude kind of working
* Refactor command bar config types and organization
* Move command bar configs to be co-located with each other
* Start building a state machine for the command bar
* Start converting command bar to state machine
* Add support for multiple args, confirmation step
* Submission behavior, hotkeys, code organization
* Add new test for extruding from command bar
* Polish step back and selection hotkeys, CSS tweaks
* Loading style tweaks
* Validate selection inputs, polish UX of args re-editing
* Prevent submission with multiple selection on singlular arg
* Remove stray console logs
* Tweak test, CSS nit, remove extrude "result" argument
* Fix linting warnings
* Show Ctrl+/ instead of ⌘K on all platforms but Mac
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)
* Add "Enter sketch" to command bar
* fix command bar test
* Fix flaky cmd bar extrude test by waiting for engine select response
* Cover both button labels '⌘K' and 'Ctrl+/' in test
---------
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-12-13 12:49:01 -05:00
|
|
|
|
const [modelingState, modelingSend, modelingActor] = useMachine(
|
2024-09-09 19:59:36 +03:00
|
|
|
|
modelingMachine.provide({
|
Command bar: add extrude command, nonlinear editing, etc (#1204)
* Tweak toaster look and feel
* Add icons, tweak plus icon names
* Rename commandBarMeta to commandBarConfig
* Refactor command bar, add support for icons
* Create a tailwind plugin for aria-pressed button state
* Remove overlay from behind command bar
* Clean up toolbar
* Button and other style tweaks
* Icon tweaks follow-up: make old icons work with new sizing
* Delete unused static icons
* More CSS tweaks
* Small CSS tweak to project sidebar
* Add command bar E2E test
* fumpt
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)
* fix typo in a comment
* Fix icon padding (built version only)
* Update onboarding and warning banner icons padding
* Misc minor style fixes
* Get Extrude opening and canceling from command bar
* Iconography tweaks
* Get extrude kind of working
* Refactor command bar config types and organization
* Move command bar configs to be co-located with each other
* Start building a state machine for the command bar
* Start converting command bar to state machine
* Add support for multiple args, confirmation step
* Submission behavior, hotkeys, code organization
* Add new test for extruding from command bar
* Polish step back and selection hotkeys, CSS tweaks
* Loading style tweaks
* Validate selection inputs, polish UX of args re-editing
* Prevent submission with multiple selection on singlular arg
* Remove stray console logs
* Tweak test, CSS nit, remove extrude "result" argument
* Fix linting warnings
* Show Ctrl+/ instead of ⌘K on all platforms but Mac
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)
* Add "Enter sketch" to command bar
* fix command bar test
* Fix flaky cmd bar extrude test by waiting for engine select response
* Cover both button labels '⌘K' and 'Ctrl+/' in test
---------
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-12-13 12:49:01 -05:00
|
|
|
|
actions: {
|
2024-07-01 21:05:31 -07:00
|
|
|
|
'disable copilot': () => {
|
|
|
|
|
editorManager.setCopilotEnabled(false)
|
|
|
|
|
},
|
|
|
|
|
'enable copilot': () => {
|
|
|
|
|
editorManager.setCopilotEnabled(true)
|
|
|
|
|
},
|
2025-01-11 09:59:09 -05:00
|
|
|
|
'sketch exit execute': ({ context: { store } }) => {
|
|
|
|
|
// TODO: Remove this async callback. For some reason eslint wouldn't
|
|
|
|
|
// let me disable @typescript-eslint/no-misused-promises for the line.
|
|
|
|
|
;(async () => {
|
|
|
|
|
// When cancelling the sketch mode we should disable sketch mode within the engine.
|
|
|
|
|
await engineCommandManager.sendSceneCommand({
|
|
|
|
|
type: 'modeling_cmd_req',
|
|
|
|
|
cmd_id: uuidv4(),
|
|
|
|
|
cmd: { type: 'sketch_mode_disable' },
|
|
|
|
|
})
|
2024-10-09 10:33:20 -04:00
|
|
|
|
|
2025-01-11 09:59:09 -05:00
|
|
|
|
sceneInfra.camControls.syncDirection = 'clientToEngine'
|
2024-07-17 18:58:01 +10:00
|
|
|
|
|
2025-01-11 09:59:09 -05:00
|
|
|
|
if (cameraProjection.current === 'perspective') {
|
|
|
|
|
await sceneInfra.camControls.snapToPerspectiveBeforeHandingBackControlToEngine()
|
|
|
|
|
}
|
2024-06-18 16:08:41 +10:00
|
|
|
|
|
2025-01-11 09:59:09 -05:00
|
|
|
|
sceneInfra.camControls.syncDirection = 'engineToClient'
|
2024-06-18 16:08:41 +10:00
|
|
|
|
|
2025-01-11 09:59:09 -05:00
|
|
|
|
store.videoElement?.pause()
|
2024-08-07 03:11:57 -04:00
|
|
|
|
|
2025-01-11 09:59:09 -05:00
|
|
|
|
return kclManager
|
|
|
|
|
.executeCode()
|
|
|
|
|
.then(() => {
|
|
|
|
|
if (engineCommandManager.engineConnection?.idleMode) return
|
2024-07-07 13:10:52 -04:00
|
|
|
|
|
2025-01-11 09:59:09 -05:00
|
|
|
|
store.videoElement?.play().catch((e) => {
|
|
|
|
|
console.warn('Video playing was prevented', e)
|
|
|
|
|
})
|
2024-08-01 01:40:14 -04:00
|
|
|
|
})
|
2025-01-11 09:59:09 -05:00
|
|
|
|
.catch(reportRejection)
|
|
|
|
|
})().catch(reportRejection)
|
Command bar: add extrude command, nonlinear editing, etc (#1204)
* Tweak toaster look and feel
* Add icons, tweak plus icon names
* Rename commandBarMeta to commandBarConfig
* Refactor command bar, add support for icons
* Create a tailwind plugin for aria-pressed button state
* Remove overlay from behind command bar
* Clean up toolbar
* Button and other style tweaks
* Icon tweaks follow-up: make old icons work with new sizing
* Delete unused static icons
* More CSS tweaks
* Small CSS tweak to project sidebar
* Add command bar E2E test
* fumpt
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)
* fix typo in a comment
* Fix icon padding (built version only)
* Update onboarding and warning banner icons padding
* Misc minor style fixes
* Get Extrude opening and canceling from command bar
* Iconography tweaks
* Get extrude kind of working
* Refactor command bar config types and organization
* Move command bar configs to be co-located with each other
* Start building a state machine for the command bar
* Start converting command bar to state machine
* Add support for multiple args, confirmation step
* Submission behavior, hotkeys, code organization
* Add new test for extruding from command bar
* Polish step back and selection hotkeys, CSS tweaks
* Loading style tweaks
* Validate selection inputs, polish UX of args re-editing
* Prevent submission with multiple selection on singlular arg
* Remove stray console logs
* Tweak test, CSS nit, remove extrude "result" argument
* Fix linting warnings
* Show Ctrl+/ instead of ⌘K on all platforms but Mac
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)
* Add "Enter sketch" to command bar
* fix command bar test
* Fix flaky cmd bar extrude test by waiting for engine select response
* Cover both button labels '⌘K' and 'Ctrl+/' in test
---------
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-12-13 12:49:01 -05:00
|
|
|
|
},
|
2024-09-09 19:59:36 +03:00
|
|
|
|
'Set mouse state': assign(({ context, event }) => {
|
|
|
|
|
if (event.type !== 'Set mouse state') return {}
|
|
|
|
|
const nextSegmentHoverMap = () => {
|
2024-05-24 20:54:42 +10:00
|
|
|
|
if (event.data.type === 'isHovering') {
|
2024-09-23 22:42:51 +10:00
|
|
|
|
const parent = getParentGroup(event.data.on, SEGMENT_BODIES)
|
2024-05-24 20:54:42 +10:00
|
|
|
|
const pathToNode = parent?.userData?.pathToNode
|
|
|
|
|
const pathToNodeString = JSON.stringify(pathToNode)
|
2024-09-09 19:59:36 +03:00
|
|
|
|
if (!parent || !pathToNode) return context.segmentHoverMap
|
|
|
|
|
if (context.segmentHoverMap[pathToNodeString] !== undefined)
|
|
|
|
|
clearTimeout(
|
|
|
|
|
context.segmentHoverMap[JSON.stringify(pathToNode)]
|
|
|
|
|
)
|
2024-05-24 20:54:42 +10:00
|
|
|
|
return {
|
2024-09-09 19:59:36 +03:00
|
|
|
|
...context.segmentHoverMap,
|
2024-05-24 20:54:42 +10:00
|
|
|
|
[pathToNodeString]: 0,
|
|
|
|
|
}
|
|
|
|
|
} else if (
|
|
|
|
|
event.data.type === 'idle' &&
|
2024-09-09 19:59:36 +03:00
|
|
|
|
context.mouseState.type === 'isHovering'
|
2024-05-24 20:54:42 +10:00
|
|
|
|
) {
|
2024-09-23 22:42:51 +10:00
|
|
|
|
const mouseOnParent = getParentGroup(
|
|
|
|
|
context.mouseState.on,
|
|
|
|
|
SEGMENT_BODIES
|
|
|
|
|
)
|
2024-05-24 20:54:42 +10:00
|
|
|
|
if (!mouseOnParent || !mouseOnParent?.userData?.pathToNode)
|
2024-09-09 19:59:36 +03:00
|
|
|
|
return context.segmentHoverMap
|
2024-05-24 20:54:42 +10:00
|
|
|
|
const pathToNodeString = JSON.stringify(
|
|
|
|
|
mouseOnParent?.userData?.pathToNode
|
|
|
|
|
)
|
|
|
|
|
const timeoutId = setTimeout(() => {
|
|
|
|
|
sceneInfra.modelingSend({
|
|
|
|
|
type: 'Set mouse state',
|
|
|
|
|
data: {
|
|
|
|
|
type: 'timeoutEnd',
|
|
|
|
|
pathToNodeString,
|
|
|
|
|
},
|
|
|
|
|
})
|
2024-09-23 22:42:51 +10:00
|
|
|
|
// overlay timeout is 1s
|
|
|
|
|
}, 1000) as unknown as number
|
2024-05-24 20:54:42 +10:00
|
|
|
|
return {
|
2024-09-09 19:59:36 +03:00
|
|
|
|
...context.segmentHoverMap,
|
2024-05-24 20:54:42 +10:00
|
|
|
|
[pathToNodeString]: timeoutId,
|
|
|
|
|
}
|
|
|
|
|
} else if (event.data.type === 'timeoutEnd') {
|
2024-09-09 19:59:36 +03:00
|
|
|
|
const copy = { ...context.segmentHoverMap }
|
2024-05-24 20:54:42 +10:00
|
|
|
|
delete copy[event.data.pathToNodeString]
|
|
|
|
|
return copy
|
|
|
|
|
}
|
|
|
|
|
return {}
|
2024-09-09 19:59:36 +03:00
|
|
|
|
}
|
|
|
|
|
return {
|
|
|
|
|
mouseState: event.data,
|
|
|
|
|
segmentHoverMap: nextSegmentHoverMap(),
|
|
|
|
|
}
|
2024-05-24 20:54:42 +10:00
|
|
|
|
}),
|
|
|
|
|
'Set Segment Overlays': assign({
|
2024-09-09 19:59:36 +03:00
|
|
|
|
segmentOverlays: ({ context: { segmentOverlays }, event }) => {
|
|
|
|
|
if (event.type !== 'Set Segment Overlays') return {}
|
2025-02-15 00:57:04 +11:00
|
|
|
|
if (event.data.type === 'add-many')
|
|
|
|
|
return {
|
|
|
|
|
...segmentOverlays,
|
|
|
|
|
...event.data.overlays,
|
|
|
|
|
}
|
2024-09-09 19:59:36 +03:00
|
|
|
|
if (event.data.type === 'set-one')
|
2024-05-24 20:54:42 +10:00
|
|
|
|
return {
|
|
|
|
|
...segmentOverlays,
|
2024-09-09 19:59:36 +03:00
|
|
|
|
[event.data.pathToNodeString]: event.data.seg,
|
2024-05-24 20:54:42 +10:00
|
|
|
|
}
|
2024-09-09 19:59:36 +03:00
|
|
|
|
if (event.data.type === 'delete-one') {
|
2024-05-24 20:54:42 +10:00
|
|
|
|
const copy = { ...segmentOverlays }
|
2024-09-09 19:59:36 +03:00
|
|
|
|
delete copy[event.data.pathToNodeString]
|
2024-05-24 20:54:42 +10:00
|
|
|
|
return copy
|
|
|
|
|
}
|
|
|
|
|
// data.type === 'clear'
|
|
|
|
|
return {}
|
|
|
|
|
},
|
2024-04-04 11:07:51 +11:00
|
|
|
|
}),
|
2024-10-04 13:47:44 -07:00
|
|
|
|
'Center camera on selection': () => {
|
|
|
|
|
engineCommandManager
|
|
|
|
|
.sendSceneCommand({
|
|
|
|
|
type: 'modeling_cmd_req',
|
|
|
|
|
cmd_id: uuidv4(),
|
|
|
|
|
cmd: {
|
|
|
|
|
type: 'default_camera_center_to_selection',
|
2025-01-09 16:02:05 -05:00
|
|
|
|
camera_movement: 'vantage',
|
2024-10-04 13:47:44 -07:00
|
|
|
|
},
|
|
|
|
|
})
|
|
|
|
|
.catch(reportRejection)
|
|
|
|
|
},
|
2024-09-09 19:59:36 +03:00
|
|
|
|
'Set sketchDetails': assign(({ context: { sketchDetails }, event }) => {
|
|
|
|
|
if (event.type !== 'Delete segment') return {}
|
|
|
|
|
if (!sketchDetails) return {}
|
|
|
|
|
return {
|
|
|
|
|
sketchDetails: {
|
|
|
|
|
...sketchDetails,
|
2025-02-15 00:57:04 +11:00
|
|
|
|
sketchEntryNodePath: event.data,
|
2024-09-09 19:59:36 +03:00
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
}),
|
|
|
|
|
'Set selection': assign(
|
|
|
|
|
({ context: { selectionRanges, sketchDetails }, event }) => {
|
|
|
|
|
// this was needed for ts after adding 'Set selection' action to on done modal events
|
|
|
|
|
const setSelections =
|
|
|
|
|
('data' in event &&
|
|
|
|
|
event.data &&
|
|
|
|
|
'selectionType' in event.data &&
|
|
|
|
|
event.data) ||
|
|
|
|
|
('output' in event &&
|
|
|
|
|
event.output &&
|
|
|
|
|
'selectionType' in event.output &&
|
|
|
|
|
event.output) ||
|
|
|
|
|
null
|
|
|
|
|
if (!setSelections) return {}
|
|
|
|
|
|
|
|
|
|
let selections: Selections = {
|
2024-11-21 15:04:30 +11:00
|
|
|
|
graphSelections: [],
|
2024-09-09 19:59:36 +03:00
|
|
|
|
otherSelections: [],
|
|
|
|
|
}
|
|
|
|
|
if (setSelections.selectionType === 'singleCodeCursor') {
|
|
|
|
|
if (!setSelections.selection && editorManager.isShiftDown) {
|
|
|
|
|
} else if (
|
|
|
|
|
!setSelections.selection &&
|
|
|
|
|
!editorManager.isShiftDown
|
|
|
|
|
) {
|
|
|
|
|
selections = {
|
2024-11-21 15:04:30 +11:00
|
|
|
|
graphSelections: [],
|
2024-09-09 19:59:36 +03:00
|
|
|
|
otherSelections: [],
|
|
|
|
|
}
|
|
|
|
|
} else if (
|
|
|
|
|
setSelections.selection &&
|
|
|
|
|
!editorManager.isShiftDown
|
|
|
|
|
) {
|
|
|
|
|
selections = {
|
2024-11-21 15:04:30 +11:00
|
|
|
|
graphSelections: [setSelections.selection],
|
2024-09-09 19:59:36 +03:00
|
|
|
|
otherSelections: [],
|
|
|
|
|
}
|
|
|
|
|
} else if (setSelections.selection && editorManager.isShiftDown) {
|
2025-02-11 14:16:48 +01:00
|
|
|
|
// selecting and deselecting multiple objects
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* There are two scenarios:
|
|
|
|
|
* 1. General case:
|
|
|
|
|
* When selecting and deselecting edges,
|
|
|
|
|
* faces or segment (during sketch edit)
|
|
|
|
|
* we use its artifact ID to identify the selection
|
|
|
|
|
* 2. Initial sketch setup:
|
|
|
|
|
* The artifact is not yet created
|
|
|
|
|
* so we use the codeRef.range
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
let updatedSelections: typeof selectionRanges.graphSelections
|
|
|
|
|
|
|
|
|
|
// 1. General case: Artifact exists, use its ID
|
|
|
|
|
if (setSelections.selection.artifact?.id) {
|
|
|
|
|
// check if already selected
|
|
|
|
|
const alreadySelected = selectionRanges.graphSelections.some(
|
|
|
|
|
(selection) =>
|
|
|
|
|
selection.artifact?.id ===
|
|
|
|
|
setSelections.selection?.artifact?.id
|
|
|
|
|
)
|
|
|
|
|
if (
|
|
|
|
|
alreadySelected &&
|
|
|
|
|
setSelections.selection?.artifact?.id
|
|
|
|
|
) {
|
|
|
|
|
// remove it
|
|
|
|
|
updatedSelections = selectionRanges.graphSelections.filter(
|
|
|
|
|
(selection) =>
|
|
|
|
|
selection.artifact?.id !==
|
|
|
|
|
setSelections.selection?.artifact?.id
|
|
|
|
|
)
|
|
|
|
|
} else {
|
|
|
|
|
// add it
|
|
|
|
|
updatedSelections = [
|
|
|
|
|
...selectionRanges.graphSelections,
|
|
|
|
|
setSelections.selection,
|
|
|
|
|
]
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
// 2. Initial sketch setup: Artifact not yet created – use codeRef.range
|
|
|
|
|
const selectionRange = JSON.stringify(
|
|
|
|
|
setSelections.selection?.codeRef?.range
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// check if already selected
|
|
|
|
|
const alreadySelected = selectionRanges.graphSelections.some(
|
|
|
|
|
(selection) => {
|
|
|
|
|
const existingRange = JSON.stringify(
|
|
|
|
|
selection.codeRef?.range
|
|
|
|
|
)
|
|
|
|
|
return existingRange === selectionRange
|
|
|
|
|
}
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
if (
|
|
|
|
|
alreadySelected &&
|
|
|
|
|
setSelections.selection?.codeRef?.range
|
|
|
|
|
) {
|
|
|
|
|
// remove it
|
|
|
|
|
updatedSelections = selectionRanges.graphSelections.filter(
|
|
|
|
|
(selection) =>
|
|
|
|
|
JSON.stringify(selection.codeRef?.range) !==
|
|
|
|
|
selectionRange
|
|
|
|
|
)
|
|
|
|
|
} else {
|
|
|
|
|
// add it
|
|
|
|
|
updatedSelections = [
|
|
|
|
|
...selectionRanges.graphSelections,
|
|
|
|
|
setSelections.selection,
|
|
|
|
|
]
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-09 19:59:36 +03:00
|
|
|
|
selections = {
|
2025-02-11 14:16:48 +01:00
|
|
|
|
graphSelections: updatedSelections,
|
2024-09-09 19:59:36 +03:00
|
|
|
|
otherSelections: selectionRanges.otherSelections,
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-03-22 10:23:04 +11:00
|
|
|
|
|
2024-09-09 19:59:36 +03:00
|
|
|
|
const {
|
|
|
|
|
engineEvents,
|
|
|
|
|
codeMirrorSelection,
|
|
|
|
|
updateSceneObjectColors,
|
|
|
|
|
} = handleSelectionBatch({
|
|
|
|
|
selections,
|
|
|
|
|
})
|
2024-12-20 16:19:59 -05:00
|
|
|
|
if (codeMirrorSelection) {
|
|
|
|
|
kclEditorActor.send({
|
|
|
|
|
type: 'setLastSelectionEvent',
|
|
|
|
|
data: {
|
|
|
|
|
codeMirrorSelection,
|
|
|
|
|
scrollIntoView: setSelections.scrollIntoView ?? false,
|
|
|
|
|
},
|
|
|
|
|
})
|
|
|
|
|
}
|
2024-09-09 19:59:36 +03:00
|
|
|
|
engineEvents &&
|
2024-09-09 18:17:45 -04:00
|
|
|
|
engineEvents.forEach((event) => {
|
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
2024-09-09 19:59:36 +03:00
|
|
|
|
engineCommandManager.sendSceneCommand(event)
|
2024-09-09 18:17:45 -04:00
|
|
|
|
})
|
2024-09-09 19:59:36 +03:00
|
|
|
|
updateSceneObjectColors()
|
2024-04-19 14:24:40 -07:00
|
|
|
|
|
2024-09-09 19:59:36 +03:00
|
|
|
|
return {
|
|
|
|
|
selectionRanges: selections,
|
|
|
|
|
}
|
2023-12-01 20:18:51 +11:00
|
|
|
|
}
|
Command bar: add extrude command, nonlinear editing, etc (#1204)
* Tweak toaster look and feel
* Add icons, tweak plus icon names
* Rename commandBarMeta to commandBarConfig
* Refactor command bar, add support for icons
* Create a tailwind plugin for aria-pressed button state
* Remove overlay from behind command bar
* Clean up toolbar
* Button and other style tweaks
* Icon tweaks follow-up: make old icons work with new sizing
* Delete unused static icons
* More CSS tweaks
* Small CSS tweak to project sidebar
* Add command bar E2E test
* fumpt
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)
* fix typo in a comment
* Fix icon padding (built version only)
* Update onboarding and warning banner icons padding
* Misc minor style fixes
* Get Extrude opening and canceling from command bar
* Iconography tweaks
* Get extrude kind of working
* Refactor command bar config types and organization
* Move command bar configs to be co-located with each other
* Start building a state machine for the command bar
* Start converting command bar to state machine
* Add support for multiple args, confirmation step
* Submission behavior, hotkeys, code organization
* Add new test for extruding from command bar
* Polish step back and selection hotkeys, CSS tweaks
* Loading style tweaks
* Validate selection inputs, polish UX of args re-editing
* Prevent submission with multiple selection on singlular arg
* Remove stray console logs
* Tweak test, CSS nit, remove extrude "result" argument
* Fix linting warnings
* Show Ctrl+/ instead of ⌘K on all platforms but Mac
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)
* Add "Enter sketch" to command bar
* fix command bar test
* Fix flaky cmd bar extrude test by waiting for engine select response
* Cover both button labels '⌘K' and 'Ctrl+/' in test
---------
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-12-13 12:49:01 -05:00
|
|
|
|
|
2024-09-09 19:59:36 +03:00
|
|
|
|
if (setSelections.selectionType === 'mirrorCodeMirrorSelections') {
|
|
|
|
|
return {
|
|
|
|
|
selectionRanges: setSelections.selection,
|
|
|
|
|
}
|
Command bar: add extrude command, nonlinear editing, etc (#1204)
* Tweak toaster look and feel
* Add icons, tweak plus icon names
* Rename commandBarMeta to commandBarConfig
* Refactor command bar, add support for icons
* Create a tailwind plugin for aria-pressed button state
* Remove overlay from behind command bar
* Clean up toolbar
* Button and other style tweaks
* Icon tweaks follow-up: make old icons work with new sizing
* Delete unused static icons
* More CSS tweaks
* Small CSS tweak to project sidebar
* Add command bar E2E test
* fumpt
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)
* fix typo in a comment
* Fix icon padding (built version only)
* Update onboarding and warning banner icons padding
* Misc minor style fixes
* Get Extrude opening and canceling from command bar
* Iconography tweaks
* Get extrude kind of working
* Refactor command bar config types and organization
* Move command bar configs to be co-located with each other
* Start building a state machine for the command bar
* Start converting command bar to state machine
* Add support for multiple args, confirmation step
* Submission behavior, hotkeys, code organization
* Add new test for extruding from command bar
* Polish step back and selection hotkeys, CSS tweaks
* Loading style tweaks
* Validate selection inputs, polish UX of args re-editing
* Prevent submission with multiple selection on singlular arg
* Remove stray console logs
* Tweak test, CSS nit, remove extrude "result" argument
* Fix linting warnings
* Show Ctrl+/ instead of ⌘K on all platforms but Mac
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)
* Add "Enter sketch" to command bar
* fix command bar test
* Fix flaky cmd bar extrude test by waiting for engine select response
* Cover both button labels '⌘K' and 'Ctrl+/' in test
---------
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-12-13 12:49:01 -05:00
|
|
|
|
}
|
2024-03-22 10:23:04 +11:00
|
|
|
|
|
2024-11-26 11:36:14 -05:00
|
|
|
|
if (
|
|
|
|
|
setSelections.selectionType === 'axisSelection' ||
|
|
|
|
|
setSelections.selectionType === 'defaultPlaneSelection'
|
|
|
|
|
) {
|
2024-09-09 19:59:36 +03:00
|
|
|
|
if (editorManager.isShiftDown) {
|
|
|
|
|
selections = {
|
2024-11-21 15:04:30 +11:00
|
|
|
|
graphSelections: selectionRanges.graphSelections,
|
2024-09-09 19:59:36 +03:00
|
|
|
|
otherSelections: [setSelections.selection],
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
selections = {
|
2024-11-21 15:04:30 +11:00
|
|
|
|
graphSelections: [],
|
2024-09-09 19:59:36 +03:00
|
|
|
|
otherSelections: [setSelections.selection],
|
|
|
|
|
}
|
2024-03-22 10:23:04 +11:00
|
|
|
|
}
|
2024-09-09 19:59:36 +03:00
|
|
|
|
return {
|
|
|
|
|
selectionRanges: selections,
|
Command bar: add extrude command, nonlinear editing, etc (#1204)
* Tweak toaster look and feel
* Add icons, tweak plus icon names
* Rename commandBarMeta to commandBarConfig
* Refactor command bar, add support for icons
* Create a tailwind plugin for aria-pressed button state
* Remove overlay from behind command bar
* Clean up toolbar
* Button and other style tweaks
* Icon tweaks follow-up: make old icons work with new sizing
* Delete unused static icons
* More CSS tweaks
* Small CSS tweak to project sidebar
* Add command bar E2E test
* fumpt
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)
* fix typo in a comment
* Fix icon padding (built version only)
* Update onboarding and warning banner icons padding
* Misc minor style fixes
* Get Extrude opening and canceling from command bar
* Iconography tweaks
* Get extrude kind of working
* Refactor command bar config types and organization
* Move command bar configs to be co-located with each other
* Start building a state machine for the command bar
* Start converting command bar to state machine
* Add support for multiple args, confirmation step
* Submission behavior, hotkeys, code organization
* Add new test for extruding from command bar
* Polish step back and selection hotkeys, CSS tweaks
* Loading style tweaks
* Validate selection inputs, polish UX of args re-editing
* Prevent submission with multiple selection on singlular arg
* Remove stray console logs
* Tweak test, CSS nit, remove extrude "result" argument
* Fix linting warnings
* Show Ctrl+/ instead of ⌘K on all platforms but Mac
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)
* Add "Enter sketch" to command bar
* fix command bar test
* Fix flaky cmd bar extrude test by waiting for engine select response
* Cover both button labels '⌘K' and 'Ctrl+/' in test
---------
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-12-13 12:49:01 -05:00
|
|
|
|
}
|
|
|
|
|
}
|
2024-11-26 11:36:14 -05:00
|
|
|
|
|
2024-09-09 19:59:36 +03:00
|
|
|
|
if (setSelections.selectionType === 'completeSelection') {
|
2025-01-23 09:45:45 -05:00
|
|
|
|
const codeMirrorSelection = editorManager.createEditorSelection(
|
|
|
|
|
setSelections.selection
|
|
|
|
|
)
|
|
|
|
|
kclEditorActor.send({
|
|
|
|
|
type: 'setLastSelectionEvent',
|
|
|
|
|
data: {
|
|
|
|
|
codeMirrorSelection,
|
|
|
|
|
scrollIntoView: false,
|
|
|
|
|
},
|
|
|
|
|
})
|
2024-09-09 19:59:36 +03:00
|
|
|
|
if (!sketchDetails)
|
|
|
|
|
return {
|
|
|
|
|
selectionRanges: setSelections.selection,
|
|
|
|
|
}
|
2024-05-31 11:36:08 +10:00
|
|
|
|
return {
|
|
|
|
|
selectionRanges: setSelections.selection,
|
2024-09-09 19:59:36 +03:00
|
|
|
|
sketchDetails: {
|
|
|
|
|
...sketchDetails,
|
2025-02-15 00:57:04 +11:00
|
|
|
|
sketchEntryNodePath:
|
|
|
|
|
setSelections.updatedSketchEntryNodePath ||
|
|
|
|
|
sketchDetails?.sketchEntryNodePath ||
|
|
|
|
|
[],
|
|
|
|
|
sketchNodePaths:
|
|
|
|
|
setSelections.updatedSketchNodePaths ||
|
|
|
|
|
sketchDetails?.sketchNodePaths ||
|
|
|
|
|
[],
|
|
|
|
|
planeNodePath:
|
|
|
|
|
setSelections.updatedPlaneNodePath ||
|
|
|
|
|
sketchDetails?.planeNodePath ||
|
2024-09-09 19:59:36 +03:00
|
|
|
|
[],
|
|
|
|
|
},
|
2024-05-31 11:36:08 +10:00
|
|
|
|
}
|
2024-05-30 13:28:29 +10:00
|
|
|
|
}
|
2024-03-22 10:23:04 +11:00
|
|
|
|
|
2024-09-09 19:59:36 +03:00
|
|
|
|
return {}
|
|
|
|
|
}
|
|
|
|
|
),
|
2024-09-09 18:17:45 -04:00
|
|
|
|
'Submit to Text-to-CAD API': ({ event }) => {
|
2024-09-09 19:59:36 +03:00
|
|
|
|
if (event.type !== 'Text-to-CAD') return
|
|
|
|
|
const trimmedPrompt = event.data.prompt.trim()
|
2024-08-14 14:26:44 -04:00
|
|
|
|
if (!trimmedPrompt) return
|
|
|
|
|
|
2024-09-09 18:17:45 -04:00
|
|
|
|
submitAndAwaitTextToKcl({
|
2024-08-14 14:26:44 -04:00
|
|
|
|
trimmedPrompt,
|
|
|
|
|
fileMachineSend,
|
|
|
|
|
navigate,
|
|
|
|
|
context,
|
|
|
|
|
token,
|
|
|
|
|
settings: {
|
|
|
|
|
theme: theme.current,
|
|
|
|
|
highlightEdges: highlightEdges.current,
|
|
|
|
|
},
|
2024-09-09 18:17:45 -04:00
|
|
|
|
}).catch(reportRejection)
|
2024-08-14 14:26:44 -04:00
|
|
|
|
},
|
2023-10-11 13:36:54 +11:00
|
|
|
|
},
|
Command bar: add extrude command, nonlinear editing, etc (#1204)
* Tweak toaster look and feel
* Add icons, tweak plus icon names
* Rename commandBarMeta to commandBarConfig
* Refactor command bar, add support for icons
* Create a tailwind plugin for aria-pressed button state
* Remove overlay from behind command bar
* Clean up toolbar
* Button and other style tweaks
* Icon tweaks follow-up: make old icons work with new sizing
* Delete unused static icons
* More CSS tweaks
* Small CSS tweak to project sidebar
* Add command bar E2E test
* fumpt
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)
* fix typo in a comment
* Fix icon padding (built version only)
* Update onboarding and warning banner icons padding
* Misc minor style fixes
* Get Extrude opening and canceling from command bar
* Iconography tweaks
* Get extrude kind of working
* Refactor command bar config types and organization
* Move command bar configs to be co-located with each other
* Start building a state machine for the command bar
* Start converting command bar to state machine
* Add support for multiple args, confirmation step
* Submission behavior, hotkeys, code organization
* Add new test for extruding from command bar
* Polish step back and selection hotkeys, CSS tweaks
* Loading style tweaks
* Validate selection inputs, polish UX of args re-editing
* Prevent submission with multiple selection on singlular arg
* Remove stray console logs
* Tweak test, CSS nit, remove extrude "result" argument
* Fix linting warnings
* Show Ctrl+/ instead of ⌘K on all platforms but Mac
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)
* Add "Enter sketch" to command bar
* fix command bar test
* Fix flaky cmd bar extrude test by waiting for engine select response
* Cover both button labels '⌘K' and 'Ctrl+/' in test
---------
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-12-13 12:49:01 -05:00
|
|
|
|
guards: {
|
2024-09-09 19:59:36 +03:00
|
|
|
|
'has valid selection for deletion': ({
|
|
|
|
|
context: { selectionRanges },
|
|
|
|
|
}) => {
|
2025-01-23 10:25:21 -05:00
|
|
|
|
if (!isCommandBarClosed) return false
|
2024-11-21 15:04:30 +11:00
|
|
|
|
if (selectionRanges.graphSelections.length <= 0) return false
|
2024-06-29 10:36:04 -07:00
|
|
|
|
return true
|
|
|
|
|
},
|
2024-09-09 19:59:36 +03:00
|
|
|
|
'Selection is on face': ({ context: { selectionRanges }, event }) => {
|
|
|
|
|
if (event.type !== 'Enter sketch') return false
|
|
|
|
|
if (event.data?.forceNewSketch) return false
|
2024-12-20 16:19:59 -05:00
|
|
|
|
if (artifactIsPlaneWithPaths(selectionRanges)) {
|
|
|
|
|
return true
|
2025-02-28 16:06:26 -05:00
|
|
|
|
} else if (selectionRanges.graphSelections[0]?.artifact) {
|
|
|
|
|
// See if the selection is "close enough" to be coerced to the plane later
|
|
|
|
|
const maybePlane = getPlaneFromArtifact(
|
|
|
|
|
selectionRanges.graphSelections[0].artifact,
|
2025-03-29 17:25:26 -07:00
|
|
|
|
kclManager.artifactGraph
|
2025-02-28 16:06:26 -05:00
|
|
|
|
)
|
|
|
|
|
return !err(maybePlane)
|
2024-12-20 16:19:59 -05:00
|
|
|
|
}
|
2025-02-15 00:57:04 +11:00
|
|
|
|
if (
|
|
|
|
|
isCursorInFunctionDefinition(
|
|
|
|
|
kclManager.ast,
|
|
|
|
|
selectionRanges.graphSelections[0]
|
|
|
|
|
)
|
2025-03-20 08:30:11 +11:00
|
|
|
|
) {
|
2024-02-19 17:23:03 +11:00
|
|
|
|
return false
|
2025-03-20 08:30:11 +11:00
|
|
|
|
}
|
Command bar: add extrude command, nonlinear editing, etc (#1204)
* Tweak toaster look and feel
* Add icons, tweak plus icon names
* Rename commandBarMeta to commandBarConfig
* Refactor command bar, add support for icons
* Create a tailwind plugin for aria-pressed button state
* Remove overlay from behind command bar
* Clean up toolbar
* Button and other style tweaks
* Icon tweaks follow-up: make old icons work with new sizing
* Delete unused static icons
* More CSS tweaks
* Small CSS tweak to project sidebar
* Add command bar E2E test
* fumpt
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)
* fix typo in a comment
* Fix icon padding (built version only)
* Update onboarding and warning banner icons padding
* Misc minor style fixes
* Get Extrude opening and canceling from command bar
* Iconography tweaks
* Get extrude kind of working
* Refactor command bar config types and organization
* Move command bar configs to be co-located with each other
* Start building a state machine for the command bar
* Start converting command bar to state machine
* Add support for multiple args, confirmation step
* Submission behavior, hotkeys, code organization
* Add new test for extruding from command bar
* Polish step back and selection hotkeys, CSS tweaks
* Loading style tweaks
* Validate selection inputs, polish UX of args re-editing
* Prevent submission with multiple selection on singlular arg
* Remove stray console logs
* Tweak test, CSS nit, remove extrude "result" argument
* Fix linting warnings
* Show Ctrl+/ instead of ⌘K on all platforms but Mac
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)
* Add "Enter sketch" to command bar
* fix command bar test
* Fix flaky cmd bar extrude test by waiting for engine select response
* Cover both button labels '⌘K' and 'Ctrl+/' in test
---------
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-12-13 12:49:01 -05:00
|
|
|
|
return !!isCursorInSketchCommandRange(
|
2025-03-29 17:25:26 -07:00
|
|
|
|
kclManager.artifactGraph,
|
Command bar: add extrude command, nonlinear editing, etc (#1204)
* Tweak toaster look and feel
* Add icons, tweak plus icon names
* Rename commandBarMeta to commandBarConfig
* Refactor command bar, add support for icons
* Create a tailwind plugin for aria-pressed button state
* Remove overlay from behind command bar
* Clean up toolbar
* Button and other style tweaks
* Icon tweaks follow-up: make old icons work with new sizing
* Delete unused static icons
* More CSS tweaks
* Small CSS tweak to project sidebar
* Add command bar E2E test
* fumpt
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)
* fix typo in a comment
* Fix icon padding (built version only)
* Update onboarding and warning banner icons padding
* Misc minor style fixes
* Get Extrude opening and canceling from command bar
* Iconography tweaks
* Get extrude kind of working
* Refactor command bar config types and organization
* Move command bar configs to be co-located with each other
* Start building a state machine for the command bar
* Start converting command bar to state machine
* Add support for multiple args, confirmation step
* Submission behavior, hotkeys, code organization
* Add new test for extruding from command bar
* Polish step back and selection hotkeys, CSS tweaks
* Loading style tweaks
* Validate selection inputs, polish UX of args re-editing
* Prevent submission with multiple selection on singlular arg
* Remove stray console logs
* Tweak test, CSS nit, remove extrude "result" argument
* Fix linting warnings
* Show Ctrl+/ instead of ⌘K on all platforms but Mac
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)
* Add "Enter sketch" to command bar
* fix command bar test
* Fix flaky cmd bar extrude test by waiting for engine select response
* Cover both button labels '⌘K' and 'Ctrl+/' in test
---------
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-12-13 12:49:01 -05:00
|
|
|
|
selectionRanges
|
|
|
|
|
)
|
|
|
|
|
},
|
2024-05-23 16:03:34 -07:00
|
|
|
|
'Has exportable geometry': () => {
|
2024-12-06 13:57:31 +13:00
|
|
|
|
if (!kclManager.hasErrors() && kclManager.ast.body.length > 0)
|
2024-05-23 16:03:34 -07:00
|
|
|
|
return true
|
|
|
|
|
else {
|
|
|
|
|
let errorMessage = 'Unable to Export '
|
2024-12-06 13:57:31 +13:00
|
|
|
|
if (kclManager.hasErrors()) errorMessage += 'due to KCL Errors'
|
2024-05-23 16:03:34 -07:00
|
|
|
|
else if (kclManager.ast.body.length === 0)
|
|
|
|
|
errorMessage += 'due to Empty Scene'
|
|
|
|
|
console.error(errorMessage)
|
2025-03-18 20:25:51 -07:00
|
|
|
|
toast.error(errorMessage)
|
2024-05-23 16:03:34 -07:00
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
},
|
2023-10-11 13:36:54 +11:00
|
|
|
|
},
|
2024-09-09 19:59:36 +03:00
|
|
|
|
actors: {
|
2025-03-18 20:25:51 -07:00
|
|
|
|
exportFromEngine: fromPromise(
|
|
|
|
|
async ({ input }: { input?: ModelingCommandSchema['Export'] }) => {
|
|
|
|
|
if (!input) {
|
|
|
|
|
return new Error('No input provided')
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let fileName = file?.name?.replace('.kcl', `.${input.type}`) || ''
|
|
|
|
|
// Ensure the file has an extension.
|
|
|
|
|
if (!fileName.includes('.')) {
|
|
|
|
|
fileName += `.${input.type}`
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const format = {
|
|
|
|
|
...input,
|
|
|
|
|
} as Partial<OutputFormat3d>
|
|
|
|
|
|
|
|
|
|
// Set all the un-configurable defaults here.
|
|
|
|
|
if (format.type === 'gltf') {
|
|
|
|
|
format.presentation = 'pretty'
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (
|
|
|
|
|
format.type === 'obj' ||
|
|
|
|
|
format.type === 'ply' ||
|
|
|
|
|
format.type === 'step' ||
|
|
|
|
|
format.type === 'stl'
|
|
|
|
|
) {
|
|
|
|
|
// Set the default coords.
|
|
|
|
|
// In the future we can make this configurable.
|
|
|
|
|
// But for now, its probably best to keep it consistent with the
|
|
|
|
|
// UI.
|
|
|
|
|
format.coords = {
|
|
|
|
|
forward: {
|
|
|
|
|
axis: 'y',
|
|
|
|
|
direction: 'negative',
|
|
|
|
|
},
|
|
|
|
|
up: {
|
|
|
|
|
axis: 'z',
|
|
|
|
|
direction: 'positive',
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (
|
|
|
|
|
format.type === 'obj' ||
|
|
|
|
|
format.type === 'stl' ||
|
|
|
|
|
format.type === 'ply'
|
|
|
|
|
) {
|
|
|
|
|
format.units = defaultUnit.current
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (format.type === 'ply' || format.type === 'stl') {
|
|
|
|
|
format.selection = { type: 'default_scene' }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const toastId = toast.loading(EXPORT_TOAST_MESSAGES.START)
|
|
|
|
|
const files = await rustContext.export(
|
|
|
|
|
format,
|
|
|
|
|
{
|
|
|
|
|
settings: { modeling: { base_unit: defaultUnit.current } },
|
|
|
|
|
},
|
|
|
|
|
toastId
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
if (files === undefined) {
|
|
|
|
|
// We already sent the toast message in the export function.
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
await exportSave({ files, toastId, fileName })
|
|
|
|
|
}
|
|
|
|
|
),
|
|
|
|
|
makeFromEngine: fromPromise(
|
|
|
|
|
async ({
|
|
|
|
|
input,
|
|
|
|
|
}: {
|
|
|
|
|
input?: {
|
|
|
|
|
machineManager: MachineManager
|
|
|
|
|
} & ModelingCommandSchema['Make']
|
|
|
|
|
}) => {
|
|
|
|
|
if (input === undefined) {
|
|
|
|
|
return new Error('No input provided')
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const name = file?.name || ''
|
|
|
|
|
|
|
|
|
|
// Set the current machine.
|
|
|
|
|
// Due to our use of singeton pattern, we need to do this to reliably
|
|
|
|
|
// update this object across React and non-React boundary.
|
|
|
|
|
// We need to do this eagerly because of the exportToEngine call below.
|
|
|
|
|
if (engineCommandManager.machineManager === null) {
|
|
|
|
|
console.warn(
|
|
|
|
|
"engineCommandManager.machineManager is null. It shouldn't be at this point. Aborting operation."
|
|
|
|
|
)
|
|
|
|
|
return new Error('Machine manager is not set')
|
|
|
|
|
} else {
|
|
|
|
|
engineCommandManager.machineManager.currentMachine = input.machine
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Update the rest of the UI that needs to know the current machine
|
|
|
|
|
input.machineManager.setCurrentMachine(input.machine)
|
|
|
|
|
|
|
|
|
|
const format: OutputFormat3d = {
|
|
|
|
|
type: 'stl',
|
|
|
|
|
coords: {
|
|
|
|
|
forward: {
|
|
|
|
|
axis: 'y',
|
|
|
|
|
direction: 'negative',
|
|
|
|
|
},
|
|
|
|
|
up: {
|
|
|
|
|
axis: 'z',
|
|
|
|
|
direction: 'positive',
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
storage: 'ascii',
|
|
|
|
|
// Convert all units to mm since that is what the slicer expects.
|
|
|
|
|
units: 'mm',
|
|
|
|
|
selection: { type: 'default_scene' },
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const toastId = toast.loading(MAKE_TOAST_MESSAGES.START)
|
|
|
|
|
const files = await rustContext.export(
|
|
|
|
|
format,
|
|
|
|
|
{
|
|
|
|
|
settings: { modeling: { base_unit: 'mm' } },
|
|
|
|
|
},
|
|
|
|
|
toastId
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
if (files === undefined) {
|
|
|
|
|
// We already sent the toast message in the export function.
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
await exportMake({
|
|
|
|
|
files,
|
|
|
|
|
toastId,
|
|
|
|
|
name,
|
|
|
|
|
machineManager: engineCommandManager.machineManager,
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
),
|
2024-09-09 19:59:36 +03:00
|
|
|
|
'AST-undo-startSketchOn': fromPromise(
|
|
|
|
|
async ({ input: { sketchDetails } }) => {
|
|
|
|
|
if (!sketchDetails) return
|
|
|
|
|
if (kclManager.ast.body.length) {
|
|
|
|
|
const newAst = structuredClone(kclManager.ast)
|
2025-02-15 00:57:04 +11:00
|
|
|
|
const varDecIndex = sketchDetails.planeNodePath[1][0]
|
|
|
|
|
|
|
|
|
|
const varDec = getNodeFromPath<VariableDeclaration>(
|
|
|
|
|
newAst,
|
|
|
|
|
sketchDetails.planeNodePath,
|
|
|
|
|
'VariableDeclaration'
|
|
|
|
|
)
|
|
|
|
|
if (err(varDec)) return reject(new Error('No varDec'))
|
|
|
|
|
const variableName = varDec.node.declaration.id.name
|
|
|
|
|
let isIdentifierUsed = false
|
|
|
|
|
traverse(newAst, {
|
|
|
|
|
enter: (node) => {
|
2025-03-24 20:58:55 +13:00
|
|
|
|
if (node.type === 'Name' && node.name.name === variableName) {
|
2025-02-15 00:57:04 +11:00
|
|
|
|
isIdentifierUsed = true
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
})
|
|
|
|
|
if (isIdentifierUsed) return
|
|
|
|
|
|
2024-09-09 19:59:36 +03:00
|
|
|
|
// remove body item at varDecIndex
|
|
|
|
|
newAst.body = newAst.body.filter((_, i) => i !== varDecIndex)
|
|
|
|
|
await kclManager.executeAstMock(newAst)
|
2025-02-15 00:57:04 +11:00
|
|
|
|
await codeManager.updateEditorWithAstAndWriteToFile(newAst)
|
2024-09-09 19:59:36 +03:00
|
|
|
|
}
|
|
|
|
|
sceneInfra.setCallbacks({
|
|
|
|
|
onClick: () => {},
|
|
|
|
|
onDrag: () => {},
|
|
|
|
|
})
|
|
|
|
|
return undefined
|
2024-07-03 22:03:04 +10:00
|
|
|
|
}
|
2024-09-09 19:59:36 +03:00
|
|
|
|
),
|
|
|
|
|
'animate-to-face': fromPromise(async ({ input }) => {
|
2025-02-15 00:57:04 +11:00
|
|
|
|
if (!input) return null
|
2024-11-18 16:25:25 -05:00
|
|
|
|
if (input.type === 'extrudeFace' || input.type === 'offsetPlane') {
|
|
|
|
|
const sketched =
|
|
|
|
|
input.type === 'extrudeFace'
|
|
|
|
|
? sketchOnExtrudedFace(
|
|
|
|
|
kclManager.ast,
|
|
|
|
|
input.sketchPathToNode,
|
|
|
|
|
input.extrudePathToNode,
|
|
|
|
|
input.faceInfo
|
|
|
|
|
)
|
|
|
|
|
: sketchOnOffsetPlane(kclManager.ast, input.pathToNode)
|
2024-09-26 18:25:05 +10:00
|
|
|
|
if (err(sketched)) {
|
|
|
|
|
const sketchedError = new Error(
|
|
|
|
|
'Incompatible face, please try another'
|
|
|
|
|
)
|
|
|
|
|
trap(sketchedError)
|
|
|
|
|
return Promise.reject(sketchedError)
|
|
|
|
|
}
|
2024-06-24 11:45:40 -04:00
|
|
|
|
const { modifiedAst, pathToNode: pathToNewSketchNode } = sketched
|
|
|
|
|
|
2024-04-17 20:18:07 -07:00
|
|
|
|
await kclManager.executeAstMock(modifiedAst)
|
2024-03-22 10:23:04 +11:00
|
|
|
|
|
2024-11-18 16:25:25 -05:00
|
|
|
|
const id =
|
|
|
|
|
input.type === 'extrudeFace' ? input.faceId : input.planeId
|
|
|
|
|
await letEngineAnimateAndSyncCamAfter(engineCommandManager, id)
|
2024-06-18 16:08:41 +10:00
|
|
|
|
sceneInfra.camControls.syncDirection = 'clientToEngine'
|
2024-03-22 10:23:04 +11:00
|
|
|
|
return {
|
2025-02-15 00:57:04 +11:00
|
|
|
|
sketchEntryNodePath: [],
|
|
|
|
|
planeNodePath: pathToNewSketchNode,
|
|
|
|
|
sketchNodePaths: [],
|
2024-09-09 19:59:36 +03:00
|
|
|
|
zAxis: input.zAxis,
|
|
|
|
|
yAxis: input.yAxis,
|
|
|
|
|
origin: input.position,
|
2024-03-22 10:23:04 +11:00
|
|
|
|
}
|
|
|
|
|
}
|
2024-02-11 12:59:00 +11:00
|
|
|
|
const { modifiedAst, pathToNode } = startSketchOnDefault(
|
|
|
|
|
kclManager.ast,
|
2024-09-09 19:59:36 +03:00
|
|
|
|
input.plane
|
2024-02-11 12:59:00 +11:00
|
|
|
|
)
|
|
|
|
|
await kclManager.updateAst(modifiedAst, false)
|
2025-01-16 12:48:13 -05:00
|
|
|
|
sceneInfra.camControls.enableRotate =
|
|
|
|
|
sceneInfra.camControls._setting_allowOrbitInSketchMode
|
2024-04-22 20:14:06 +10:00
|
|
|
|
sceneInfra.camControls.syncDirection = 'clientToEngine'
|
2024-06-24 11:45:40 -04:00
|
|
|
|
|
2024-06-18 16:08:41 +10:00
|
|
|
|
await letEngineAnimateAndSyncCamAfter(
|
|
|
|
|
engineCommandManager,
|
2024-09-09 19:59:36 +03:00
|
|
|
|
input.planeId
|
2024-06-18 16:08:41 +10:00
|
|
|
|
)
|
2024-06-24 11:45:40 -04:00
|
|
|
|
|
2024-02-11 12:59:00 +11:00
|
|
|
|
return {
|
2025-02-15 00:57:04 +11:00
|
|
|
|
sketchEntryNodePath: [],
|
|
|
|
|
planeNodePath: pathToNode,
|
|
|
|
|
sketchNodePaths: [],
|
2024-09-09 19:59:36 +03:00
|
|
|
|
zAxis: input.zAxis,
|
|
|
|
|
yAxis: input.yAxis,
|
2024-03-22 10:23:04 +11:00
|
|
|
|
origin: [0, 0, 0],
|
2025-01-16 12:48:13 -05:00
|
|
|
|
animateTargetId: input.planeId,
|
2024-02-11 12:59:00 +11:00
|
|
|
|
}
|
2024-09-09 19:59:36 +03:00
|
|
|
|
}),
|
|
|
|
|
'animate-to-sketch': fromPromise(
|
|
|
|
|
async ({ input: { selectionRanges } }) => {
|
2025-02-21 02:14:35 +11:00
|
|
|
|
const artifact = selectionRanges.graphSelections[0].artifact
|
2025-02-15 00:57:04 +11:00
|
|
|
|
const plane = getPlaneFromArtifact(
|
2025-02-21 02:14:35 +11:00
|
|
|
|
artifact,
|
2025-03-29 17:25:26 -07:00
|
|
|
|
kclManager.artifactGraph
|
2024-09-09 19:59:36 +03:00
|
|
|
|
)
|
2025-02-15 00:57:04 +11:00
|
|
|
|
if (err(plane)) return Promise.reject(plane)
|
2025-02-25 23:51:25 +11:00
|
|
|
|
// if the user selected a segment, make sure we enter the right sketch as there can be multiple on a plane
|
2025-02-21 02:14:35 +11:00
|
|
|
|
// but still works if the user selected a plane/face by defaulting to the first path
|
|
|
|
|
const mainPath =
|
|
|
|
|
artifact?.type === 'segment' || artifact?.type === 'solid2d'
|
|
|
|
|
? artifact?.pathId
|
|
|
|
|
: plane?.pathIds[0]
|
2025-02-15 00:57:04 +11:00
|
|
|
|
let sketch: KclValue | null = null
|
2025-03-20 08:30:11 +11:00
|
|
|
|
let planeVar: Plane | null = null
|
2025-02-15 00:57:04 +11:00
|
|
|
|
for (const variable of Object.values(
|
|
|
|
|
kclManager.execState.variables
|
|
|
|
|
)) {
|
|
|
|
|
// find programMemory that matches path artifact
|
|
|
|
|
if (
|
|
|
|
|
variable?.type === 'Sketch' &&
|
2025-02-21 02:14:35 +11:00
|
|
|
|
variable.value.artifactId === mainPath
|
2025-02-15 00:57:04 +11:00
|
|
|
|
) {
|
|
|
|
|
sketch = variable
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
if (
|
|
|
|
|
// if the variable is an sweep, check if the underlying sketch matches the artifact
|
|
|
|
|
variable?.type === 'Solid' &&
|
|
|
|
|
variable.value.sketch.on.type === 'plane' &&
|
2025-02-21 02:14:35 +11:00
|
|
|
|
variable.value.sketch.artifactId === mainPath
|
2025-02-15 00:57:04 +11:00
|
|
|
|
) {
|
|
|
|
|
sketch = {
|
|
|
|
|
type: 'Sketch',
|
|
|
|
|
value: variable.value.sketch,
|
|
|
|
|
}
|
|
|
|
|
break
|
|
|
|
|
}
|
2025-03-20 08:30:11 +11:00
|
|
|
|
if (
|
|
|
|
|
variable?.type === 'Plane' &&
|
|
|
|
|
plane.id === variable.value.id
|
|
|
|
|
) {
|
|
|
|
|
planeVar = variable.value
|
|
|
|
|
}
|
2025-02-15 00:57:04 +11:00
|
|
|
|
}
|
2025-03-20 08:30:11 +11:00
|
|
|
|
if (!sketch || sketch.type !== 'Sketch') {
|
|
|
|
|
if (artifact?.type !== 'plane')
|
|
|
|
|
return Promise.reject(new Error('No sketch'))
|
|
|
|
|
const planeCodeRef = getFaceCodeRef(artifact)
|
|
|
|
|
if (planeVar && planeCodeRef) {
|
|
|
|
|
const toTuple = (point: Point3d): [number, number, number] => [
|
|
|
|
|
point.x,
|
|
|
|
|
point.y,
|
|
|
|
|
point.z,
|
|
|
|
|
]
|
|
|
|
|
const planPath = getNodePathFromSourceRange(
|
|
|
|
|
kclManager.ast,
|
|
|
|
|
planeCodeRef.range
|
|
|
|
|
)
|
|
|
|
|
await letEngineAnimateAndSyncCamAfter(
|
|
|
|
|
engineCommandManager,
|
|
|
|
|
artifact.id
|
|
|
|
|
)
|
|
|
|
|
return {
|
|
|
|
|
sketchEntryNodePath: [],
|
|
|
|
|
planeNodePath: planPath,
|
|
|
|
|
sketchNodePaths: [],
|
|
|
|
|
zAxis: toTuple(planeVar.zAxis),
|
|
|
|
|
yAxis: toTuple(planeVar.yAxis),
|
|
|
|
|
origin: toTuple(planeVar.origin),
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-02-15 00:57:04 +11:00
|
|
|
|
return Promise.reject(new Error('No sketch'))
|
2025-03-20 08:30:11 +11:00
|
|
|
|
}
|
2025-04-01 23:54:26 -07:00
|
|
|
|
const info = await sceneEntitiesManager.getSketchOrientationDetails(
|
|
|
|
|
sketch.value
|
|
|
|
|
)
|
2024-09-09 19:59:36 +03:00
|
|
|
|
await letEngineAnimateAndSyncCamAfter(
|
|
|
|
|
engineCommandManager,
|
|
|
|
|
info?.sketchDetails?.faceId || ''
|
|
|
|
|
)
|
2025-02-15 00:57:04 +11:00
|
|
|
|
|
2025-03-29 17:25:26 -07:00
|
|
|
|
const sketchArtifact = kclManager.artifactGraph.get(mainPath)
|
2025-02-15 00:57:04 +11:00
|
|
|
|
if (sketchArtifact?.type !== 'path')
|
|
|
|
|
return Promise.reject(new Error('No sketch artifact'))
|
|
|
|
|
const sketchPaths = getPathsFromArtifact({
|
2025-03-29 17:25:26 -07:00
|
|
|
|
artifact: kclManager.artifactGraph.get(plane.id),
|
2025-02-15 00:57:04 +11:00
|
|
|
|
sketchPathToNode: sketchArtifact?.codeRef?.pathToNode,
|
2025-03-29 17:25:26 -07:00
|
|
|
|
artifactGraph: kclManager.artifactGraph,
|
2025-02-15 00:57:04 +11:00
|
|
|
|
ast: kclManager.ast,
|
|
|
|
|
})
|
|
|
|
|
if (err(sketchPaths)) return Promise.reject(sketchPaths)
|
|
|
|
|
let codeRef = getFaceCodeRef(plane)
|
|
|
|
|
if (!codeRef) return Promise.reject(new Error('No plane codeRef'))
|
|
|
|
|
// codeRef.pathToNode is not always populated correctly
|
|
|
|
|
const planeNodePath = getNodePathFromSourceRange(
|
|
|
|
|
kclManager.ast,
|
|
|
|
|
codeRef.range
|
|
|
|
|
)
|
2024-12-14 09:57:33 +11:00
|
|
|
|
return {
|
2025-02-15 00:57:04 +11:00
|
|
|
|
sketchEntryNodePath: sketchArtifact.codeRef.pathToNode || [],
|
|
|
|
|
sketchNodePaths: sketchPaths,
|
|
|
|
|
planeNodePath,
|
2024-09-09 19:59:36 +03:00
|
|
|
|
zAxis: info.sketchDetails.zAxis || null,
|
|
|
|
|
yAxis: info.sketchDetails.yAxis || null,
|
|
|
|
|
origin: info.sketchDetails.origin.map(
|
|
|
|
|
(a) => a / sceneInfra._baseUnitMultiplier
|
|
|
|
|
) as [number, number, number],
|
2025-01-16 12:48:13 -05:00
|
|
|
|
animateTargetId: info?.sketchDetails?.faceId || '',
|
2024-09-09 19:59:36 +03:00
|
|
|
|
}
|
2024-03-22 10:23:04 +11:00
|
|
|
|
}
|
2024-09-09 19:59:36 +03:00
|
|
|
|
),
|
2024-11-21 15:04:30 +11:00
|
|
|
|
|
2024-09-09 19:59:36 +03:00
|
|
|
|
'Get horizontal info': fromPromise(
|
|
|
|
|
async ({ input: { selectionRanges, sketchDetails } }) => {
|
2025-02-15 00:57:04 +11:00
|
|
|
|
const { modifiedAst, pathToNodeMap, exprInsertIndex } =
|
2024-09-09 19:59:36 +03:00
|
|
|
|
await applyConstraintHorzVertDistance({
|
|
|
|
|
constraint: 'setHorzDistance',
|
|
|
|
|
selectionRanges,
|
|
|
|
|
})
|
2024-12-06 13:57:31 +13:00
|
|
|
|
const pResult = parse(recast(modifiedAst))
|
|
|
|
|
if (trap(pResult) || !resultIsOk(pResult))
|
|
|
|
|
return Promise.reject(new Error('Unexpected compilation error'))
|
|
|
|
|
const _modifiedAst = pResult.program
|
|
|
|
|
|
2024-09-09 19:59:36 +03:00
|
|
|
|
if (!sketchDetails)
|
|
|
|
|
return Promise.reject(new Error('No sketch details'))
|
2025-02-15 00:57:04 +11:00
|
|
|
|
|
|
|
|
|
const {
|
|
|
|
|
updatedSketchEntryNodePath,
|
|
|
|
|
updatedSketchNodePaths,
|
|
|
|
|
updatedPlaneNodePath,
|
|
|
|
|
} = updateSketchDetailsNodePaths({
|
|
|
|
|
sketchEntryNodePath: sketchDetails.sketchEntryNodePath,
|
|
|
|
|
sketchNodePaths: sketchDetails.sketchNodePaths,
|
|
|
|
|
planeNodePath: sketchDetails.planeNodePath,
|
|
|
|
|
exprInsertIndex,
|
|
|
|
|
})
|
|
|
|
|
|
2024-09-09 19:59:36 +03:00
|
|
|
|
const updatedAst =
|
|
|
|
|
await sceneEntitiesManager.updateAstAndRejigSketch(
|
2025-02-15 00:57:04 +11:00
|
|
|
|
updatedSketchEntryNodePath,
|
|
|
|
|
updatedSketchNodePaths,
|
|
|
|
|
updatedPlaneNodePath,
|
2024-09-09 19:59:36 +03:00
|
|
|
|
_modifiedAst,
|
|
|
|
|
sketchDetails.zAxis,
|
|
|
|
|
sketchDetails.yAxis,
|
|
|
|
|
sketchDetails.origin
|
|
|
|
|
)
|
|
|
|
|
if (err(updatedAst)) return Promise.reject(updatedAst)
|
2024-11-16 16:49:44 -05:00
|
|
|
|
|
|
|
|
|
await codeManager.updateEditorWithAstAndWriteToFile(
|
|
|
|
|
updatedAst.newAst
|
|
|
|
|
)
|
|
|
|
|
|
2024-09-09 19:59:36 +03:00
|
|
|
|
const selection = updateSelections(
|
|
|
|
|
pathToNodeMap,
|
2023-12-01 20:18:51 +11:00
|
|
|
|
selectionRanges,
|
2024-09-09 19:59:36 +03:00
|
|
|
|
updatedAst.newAst
|
|
|
|
|
)
|
|
|
|
|
if (err(selection)) return Promise.reject(selection)
|
|
|
|
|
return {
|
|
|
|
|
selectionType: 'completeSelection',
|
|
|
|
|
selection,
|
2025-02-15 00:57:04 +11:00
|
|
|
|
updatedSketchEntryNodePath,
|
|
|
|
|
updatedSketchNodePaths,
|
|
|
|
|
updatedPlaneNodePath,
|
2024-09-09 19:59:36 +03:00
|
|
|
|
}
|
Command bar: add extrude command, nonlinear editing, etc (#1204)
* Tweak toaster look and feel
* Add icons, tweak plus icon names
* Rename commandBarMeta to commandBarConfig
* Refactor command bar, add support for icons
* Create a tailwind plugin for aria-pressed button state
* Remove overlay from behind command bar
* Clean up toolbar
* Button and other style tweaks
* Icon tweaks follow-up: make old icons work with new sizing
* Delete unused static icons
* More CSS tweaks
* Small CSS tweak to project sidebar
* Add command bar E2E test
* fumpt
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)
* fix typo in a comment
* Fix icon padding (built version only)
* Update onboarding and warning banner icons padding
* Misc minor style fixes
* Get Extrude opening and canceling from command bar
* Iconography tweaks
* Get extrude kind of working
* Refactor command bar config types and organization
* Move command bar configs to be co-located with each other
* Start building a state machine for the command bar
* Start converting command bar to state machine
* Add support for multiple args, confirmation step
* Submission behavior, hotkeys, code organization
* Add new test for extruding from command bar
* Polish step back and selection hotkeys, CSS tweaks
* Loading style tweaks
* Validate selection inputs, polish UX of args re-editing
* Prevent submission with multiple selection on singlular arg
* Remove stray console logs
* Tweak test, CSS nit, remove extrude "result" argument
* Fix linting warnings
* Show Ctrl+/ instead of ⌘K on all platforms but Mac
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)
* Add "Enter sketch" to command bar
* fix command bar test
* Fix flaky cmd bar extrude test by waiting for engine select response
* Cover both button labels '⌘K' and 'Ctrl+/' in test
---------
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-12-13 12:49:01 -05:00
|
|
|
|
}
|
2024-09-09 19:59:36 +03:00
|
|
|
|
),
|
|
|
|
|
'Get vertical info': fromPromise(
|
|
|
|
|
async ({ input: { selectionRanges, sketchDetails } }) => {
|
2025-02-15 00:57:04 +11:00
|
|
|
|
const { modifiedAst, pathToNodeMap, exprInsertIndex } =
|
2024-09-09 19:59:36 +03:00
|
|
|
|
await applyConstraintHorzVertDistance({
|
|
|
|
|
constraint: 'setVertDistance',
|
|
|
|
|
selectionRanges,
|
|
|
|
|
})
|
2024-12-06 13:57:31 +13:00
|
|
|
|
const pResult = parse(recast(modifiedAst))
|
|
|
|
|
if (trap(pResult) || !resultIsOk(pResult))
|
|
|
|
|
return Promise.reject(new Error('Unexpected compilation error'))
|
|
|
|
|
const _modifiedAst = pResult.program
|
2024-09-09 19:59:36 +03:00
|
|
|
|
if (!sketchDetails)
|
|
|
|
|
return Promise.reject(new Error('No sketch details'))
|
2025-02-15 00:57:04 +11:00
|
|
|
|
|
|
|
|
|
const {
|
|
|
|
|
updatedSketchEntryNodePath,
|
|
|
|
|
updatedSketchNodePaths,
|
|
|
|
|
updatedPlaneNodePath,
|
|
|
|
|
} = updateSketchDetailsNodePaths({
|
|
|
|
|
sketchEntryNodePath: sketchDetails.sketchEntryNodePath,
|
|
|
|
|
sketchNodePaths: sketchDetails.sketchNodePaths,
|
|
|
|
|
planeNodePath: sketchDetails.planeNodePath,
|
|
|
|
|
exprInsertIndex,
|
|
|
|
|
})
|
|
|
|
|
|
2024-09-09 19:59:36 +03:00
|
|
|
|
const updatedAst =
|
|
|
|
|
await sceneEntitiesManager.updateAstAndRejigSketch(
|
2025-02-15 00:57:04 +11:00
|
|
|
|
updatedSketchEntryNodePath,
|
|
|
|
|
updatedSketchNodePaths,
|
|
|
|
|
updatedPlaneNodePath,
|
2024-09-09 19:59:36 +03:00
|
|
|
|
_modifiedAst,
|
|
|
|
|
sketchDetails.zAxis,
|
|
|
|
|
sketchDetails.yAxis,
|
|
|
|
|
sketchDetails.origin
|
|
|
|
|
)
|
|
|
|
|
if (err(updatedAst)) return Promise.reject(updatedAst)
|
2024-11-16 16:49:44 -05:00
|
|
|
|
|
|
|
|
|
await codeManager.updateEditorWithAstAndWriteToFile(
|
|
|
|
|
updatedAst.newAst
|
|
|
|
|
)
|
|
|
|
|
|
2024-09-09 19:59:36 +03:00
|
|
|
|
const selection = updateSelections(
|
|
|
|
|
pathToNodeMap,
|
|
|
|
|
selectionRanges,
|
|
|
|
|
updatedAst.newAst
|
|
|
|
|
)
|
|
|
|
|
if (err(selection)) return Promise.reject(selection)
|
|
|
|
|
return {
|
|
|
|
|
selectionType: 'completeSelection',
|
|
|
|
|
selection,
|
2025-02-15 00:57:04 +11:00
|
|
|
|
updatedSketchEntryNodePath,
|
|
|
|
|
updatedSketchNodePaths,
|
|
|
|
|
updatedPlaneNodePath,
|
2024-09-09 19:59:36 +03:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
),
|
|
|
|
|
'Get angle info': fromPromise(
|
|
|
|
|
async ({ input: { selectionRanges, sketchDetails } }) => {
|
|
|
|
|
const info = angleBetweenInfo({
|
Command bar: add extrude command, nonlinear editing, etc (#1204)
* Tweak toaster look and feel
* Add icons, tweak plus icon names
* Rename commandBarMeta to commandBarConfig
* Refactor command bar, add support for icons
* Create a tailwind plugin for aria-pressed button state
* Remove overlay from behind command bar
* Clean up toolbar
* Button and other style tweaks
* Icon tweaks follow-up: make old icons work with new sizing
* Delete unused static icons
* More CSS tweaks
* Small CSS tweak to project sidebar
* Add command bar E2E test
* fumpt
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)
* fix typo in a comment
* Fix icon padding (built version only)
* Update onboarding and warning banner icons padding
* Misc minor style fixes
* Get Extrude opening and canceling from command bar
* Iconography tweaks
* Get extrude kind of working
* Refactor command bar config types and organization
* Move command bar configs to be co-located with each other
* Start building a state machine for the command bar
* Start converting command bar to state machine
* Add support for multiple args, confirmation step
* Submission behavior, hotkeys, code organization
* Add new test for extruding from command bar
* Polish step back and selection hotkeys, CSS tweaks
* Loading style tweaks
* Validate selection inputs, polish UX of args re-editing
* Prevent submission with multiple selection on singlular arg
* Remove stray console logs
* Tweak test, CSS nit, remove extrude "result" argument
* Fix linting warnings
* Show Ctrl+/ instead of ⌘K on all platforms but Mac
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)
* Add "Enter sketch" to command bar
* fix command bar test
* Fix flaky cmd bar extrude test by waiting for engine select response
* Cover both button labels '⌘K' and 'Ctrl+/' in test
---------
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-12-13 12:49:01 -05:00
|
|
|
|
selectionRanges,
|
|
|
|
|
})
|
2024-09-09 19:59:36 +03:00
|
|
|
|
if (err(info)) return Promise.reject(info)
|
2025-02-15 00:57:04 +11:00
|
|
|
|
const { modifiedAst, pathToNodeMap, exprInsertIndex } =
|
|
|
|
|
await (info.enabled
|
|
|
|
|
? applyConstraintAngleBetween({
|
|
|
|
|
selectionRanges,
|
|
|
|
|
})
|
|
|
|
|
: applyConstraintAngleLength({
|
|
|
|
|
selectionRanges,
|
|
|
|
|
angleOrLength: 'setAngle',
|
|
|
|
|
}))
|
2024-12-06 13:57:31 +13:00
|
|
|
|
const pResult = parse(recast(modifiedAst))
|
|
|
|
|
if (trap(pResult) || !resultIsOk(pResult))
|
|
|
|
|
return Promise.reject(new Error('Unexpected compilation error'))
|
|
|
|
|
const _modifiedAst = pResult.program
|
2024-09-09 19:59:36 +03:00
|
|
|
|
if (err(_modifiedAst)) return Promise.reject(_modifiedAst)
|
|
|
|
|
|
|
|
|
|
if (!sketchDetails)
|
|
|
|
|
return Promise.reject(new Error('No sketch details'))
|
2025-02-15 00:57:04 +11:00
|
|
|
|
|
|
|
|
|
const {
|
|
|
|
|
updatedSketchEntryNodePath,
|
|
|
|
|
updatedSketchNodePaths,
|
|
|
|
|
updatedPlaneNodePath,
|
|
|
|
|
} = updateSketchDetailsNodePaths({
|
|
|
|
|
sketchEntryNodePath: sketchDetails.sketchEntryNodePath,
|
|
|
|
|
sketchNodePaths: sketchDetails.sketchNodePaths,
|
|
|
|
|
planeNodePath: sketchDetails.planeNodePath,
|
|
|
|
|
exprInsertIndex,
|
|
|
|
|
})
|
|
|
|
|
|
2024-09-09 19:59:36 +03:00
|
|
|
|
const updatedAst =
|
|
|
|
|
await sceneEntitiesManager.updateAstAndRejigSketch(
|
2025-02-15 00:57:04 +11:00
|
|
|
|
updatedSketchEntryNodePath,
|
|
|
|
|
updatedSketchNodePaths,
|
|
|
|
|
updatedPlaneNodePath,
|
2024-09-09 19:59:36 +03:00
|
|
|
|
_modifiedAst,
|
|
|
|
|
sketchDetails.zAxis,
|
|
|
|
|
sketchDetails.yAxis,
|
|
|
|
|
sketchDetails.origin
|
|
|
|
|
)
|
|
|
|
|
if (err(updatedAst)) return Promise.reject(updatedAst)
|
2024-11-16 16:49:44 -05:00
|
|
|
|
|
|
|
|
|
await codeManager.updateEditorWithAstAndWriteToFile(
|
|
|
|
|
updatedAst.newAst
|
|
|
|
|
)
|
|
|
|
|
|
2024-09-09 19:59:36 +03:00
|
|
|
|
const selection = updateSelections(
|
|
|
|
|
pathToNodeMap,
|
|
|
|
|
selectionRanges,
|
|
|
|
|
updatedAst.newAst
|
|
|
|
|
)
|
|
|
|
|
if (err(selection)) return Promise.reject(selection)
|
|
|
|
|
return {
|
|
|
|
|
selectionType: 'completeSelection',
|
|
|
|
|
selection,
|
2025-02-15 00:57:04 +11:00
|
|
|
|
updatedSketchEntryNodePath,
|
|
|
|
|
updatedSketchNodePaths,
|
|
|
|
|
updatedPlaneNodePath,
|
2024-09-09 19:59:36 +03:00
|
|
|
|
}
|
2023-12-01 20:18:51 +11:00
|
|
|
|
}
|
2024-09-09 19:59:36 +03:00
|
|
|
|
),
|
2024-12-09 16:43:58 -05:00
|
|
|
|
astConstrainLength: fromPromise(
|
|
|
|
|
async ({
|
|
|
|
|
input: { selectionRanges, sketchDetails, lengthValue },
|
|
|
|
|
}) => {
|
|
|
|
|
if (!lengthValue)
|
|
|
|
|
return Promise.reject(new Error('No length value'))
|
|
|
|
|
const constraintResult = await applyConstraintLength({
|
|
|
|
|
selectionRanges,
|
|
|
|
|
length: lengthValue,
|
|
|
|
|
})
|
|
|
|
|
if (err(constraintResult)) return Promise.reject(constraintResult)
|
2025-02-15 00:57:04 +11:00
|
|
|
|
const { modifiedAst, pathToNodeMap, exprInsertIndex } =
|
|
|
|
|
constraintResult
|
2024-12-06 13:57:31 +13:00
|
|
|
|
const pResult = parse(recast(modifiedAst))
|
|
|
|
|
if (trap(pResult) || !resultIsOk(pResult))
|
|
|
|
|
return Promise.reject(new Error('Unexpected compilation error'))
|
|
|
|
|
const _modifiedAst = pResult.program
|
2024-09-09 19:59:36 +03:00
|
|
|
|
if (!sketchDetails)
|
|
|
|
|
return Promise.reject(new Error('No sketch details'))
|
2025-02-15 00:57:04 +11:00
|
|
|
|
|
|
|
|
|
const {
|
|
|
|
|
updatedSketchEntryNodePath,
|
|
|
|
|
updatedSketchNodePaths,
|
|
|
|
|
updatedPlaneNodePath,
|
|
|
|
|
} = updateSketchDetailsNodePaths({
|
|
|
|
|
sketchEntryNodePath: sketchDetails.sketchEntryNodePath,
|
|
|
|
|
sketchNodePaths: sketchDetails.sketchNodePaths,
|
|
|
|
|
planeNodePath: sketchDetails.planeNodePath,
|
|
|
|
|
exprInsertIndex,
|
|
|
|
|
})
|
2024-09-09 19:59:36 +03:00
|
|
|
|
const updatedAst =
|
|
|
|
|
await sceneEntitiesManager.updateAstAndRejigSketch(
|
2025-02-15 00:57:04 +11:00
|
|
|
|
updatedSketchEntryNodePath,
|
|
|
|
|
updatedSketchNodePaths,
|
|
|
|
|
updatedPlaneNodePath,
|
2024-09-09 19:59:36 +03:00
|
|
|
|
_modifiedAst,
|
|
|
|
|
sketchDetails.zAxis,
|
|
|
|
|
sketchDetails.yAxis,
|
|
|
|
|
sketchDetails.origin
|
|
|
|
|
)
|
|
|
|
|
if (err(updatedAst)) return Promise.reject(updatedAst)
|
2024-11-16 16:49:44 -05:00
|
|
|
|
|
|
|
|
|
await codeManager.updateEditorWithAstAndWriteToFile(
|
|
|
|
|
updatedAst.newAst
|
|
|
|
|
)
|
|
|
|
|
|
2024-09-09 19:59:36 +03:00
|
|
|
|
const selection = updateSelections(
|
|
|
|
|
pathToNodeMap,
|
|
|
|
|
selectionRanges,
|
|
|
|
|
updatedAst.newAst
|
|
|
|
|
)
|
|
|
|
|
if (err(selection)) return Promise.reject(selection)
|
|
|
|
|
return {
|
|
|
|
|
selectionType: 'completeSelection',
|
|
|
|
|
selection,
|
2025-02-15 00:57:04 +11:00
|
|
|
|
updatedSketchEntryNodePath,
|
|
|
|
|
updatedSketchNodePaths,
|
|
|
|
|
updatedPlaneNodePath,
|
2024-09-09 19:59:36 +03:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
),
|
|
|
|
|
'Get perpendicular distance info': fromPromise(
|
|
|
|
|
async ({ input: { selectionRanges, sketchDetails } }) => {
|
2025-02-15 00:57:04 +11:00
|
|
|
|
const { modifiedAst, pathToNodeMap, exprInsertIndex } =
|
2024-09-09 19:59:36 +03:00
|
|
|
|
await applyConstraintIntersect({
|
Command bar: add extrude command, nonlinear editing, etc (#1204)
* Tweak toaster look and feel
* Add icons, tweak plus icon names
* Rename commandBarMeta to commandBarConfig
* Refactor command bar, add support for icons
* Create a tailwind plugin for aria-pressed button state
* Remove overlay from behind command bar
* Clean up toolbar
* Button and other style tweaks
* Icon tweaks follow-up: make old icons work with new sizing
* Delete unused static icons
* More CSS tweaks
* Small CSS tweak to project sidebar
* Add command bar E2E test
* fumpt
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)
* fix typo in a comment
* Fix icon padding (built version only)
* Update onboarding and warning banner icons padding
* Misc minor style fixes
* Get Extrude opening and canceling from command bar
* Iconography tweaks
* Get extrude kind of working
* Refactor command bar config types and organization
* Move command bar configs to be co-located with each other
* Start building a state machine for the command bar
* Start converting command bar to state machine
* Add support for multiple args, confirmation step
* Submission behavior, hotkeys, code organization
* Add new test for extruding from command bar
* Polish step back and selection hotkeys, CSS tweaks
* Loading style tweaks
* Validate selection inputs, polish UX of args re-editing
* Prevent submission with multiple selection on singlular arg
* Remove stray console logs
* Tweak test, CSS nit, remove extrude "result" argument
* Fix linting warnings
* Show Ctrl+/ instead of ⌘K on all platforms but Mac
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)
* Add "Enter sketch" to command bar
* fix command bar test
* Fix flaky cmd bar extrude test by waiting for engine select response
* Cover both button labels '⌘K' and 'Ctrl+/' in test
---------
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-12-13 12:49:01 -05:00
|
|
|
|
selectionRanges,
|
|
|
|
|
})
|
2024-12-06 13:57:31 +13:00
|
|
|
|
const pResult = parse(recast(modifiedAst))
|
|
|
|
|
if (trap(pResult) || !resultIsOk(pResult))
|
|
|
|
|
return Promise.reject(new Error('Unexpected compilation error'))
|
|
|
|
|
const _modifiedAst = pResult.program
|
2024-09-09 19:59:36 +03:00
|
|
|
|
if (!sketchDetails)
|
|
|
|
|
return Promise.reject(new Error('No sketch details'))
|
2025-02-15 00:57:04 +11:00
|
|
|
|
|
|
|
|
|
const {
|
|
|
|
|
updatedSketchEntryNodePath,
|
|
|
|
|
updatedSketchNodePaths,
|
|
|
|
|
updatedPlaneNodePath,
|
|
|
|
|
} = updateSketchDetailsNodePaths({
|
|
|
|
|
sketchEntryNodePath: sketchDetails.sketchEntryNodePath,
|
|
|
|
|
sketchNodePaths: sketchDetails.sketchNodePaths,
|
|
|
|
|
planeNodePath: sketchDetails.planeNodePath,
|
|
|
|
|
exprInsertIndex,
|
|
|
|
|
})
|
2024-09-09 19:59:36 +03:00
|
|
|
|
const updatedAst =
|
|
|
|
|
await sceneEntitiesManager.updateAstAndRejigSketch(
|
2025-02-15 00:57:04 +11:00
|
|
|
|
updatedSketchEntryNodePath,
|
|
|
|
|
updatedSketchNodePaths,
|
|
|
|
|
updatedPlaneNodePath,
|
2024-09-09 19:59:36 +03:00
|
|
|
|
_modifiedAst,
|
|
|
|
|
sketchDetails.zAxis,
|
|
|
|
|
sketchDetails.yAxis,
|
|
|
|
|
sketchDetails.origin
|
|
|
|
|
)
|
|
|
|
|
if (err(updatedAst)) return Promise.reject(updatedAst)
|
2024-11-16 16:49:44 -05:00
|
|
|
|
|
|
|
|
|
await codeManager.updateEditorWithAstAndWriteToFile(
|
|
|
|
|
updatedAst.newAst
|
|
|
|
|
)
|
|
|
|
|
|
2024-09-09 19:59:36 +03:00
|
|
|
|
const selection = updateSelections(
|
|
|
|
|
pathToNodeMap,
|
Command bar: add extrude command, nonlinear editing, etc (#1204)
* Tweak toaster look and feel
* Add icons, tweak plus icon names
* Rename commandBarMeta to commandBarConfig
* Refactor command bar, add support for icons
* Create a tailwind plugin for aria-pressed button state
* Remove overlay from behind command bar
* Clean up toolbar
* Button and other style tweaks
* Icon tweaks follow-up: make old icons work with new sizing
* Delete unused static icons
* More CSS tweaks
* Small CSS tweak to project sidebar
* Add command bar E2E test
* fumpt
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)
* fix typo in a comment
* Fix icon padding (built version only)
* Update onboarding and warning banner icons padding
* Misc minor style fixes
* Get Extrude opening and canceling from command bar
* Iconography tweaks
* Get extrude kind of working
* Refactor command bar config types and organization
* Move command bar configs to be co-located with each other
* Start building a state machine for the command bar
* Start converting command bar to state machine
* Add support for multiple args, confirmation step
* Submission behavior, hotkeys, code organization
* Add new test for extruding from command bar
* Polish step back and selection hotkeys, CSS tweaks
* Loading style tweaks
* Validate selection inputs, polish UX of args re-editing
* Prevent submission with multiple selection on singlular arg
* Remove stray console logs
* Tweak test, CSS nit, remove extrude "result" argument
* Fix linting warnings
* Show Ctrl+/ instead of ⌘K on all platforms but Mac
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)
* Add "Enter sketch" to command bar
* fix command bar test
* Fix flaky cmd bar extrude test by waiting for engine select response
* Cover both button labels '⌘K' and 'Ctrl+/' in test
---------
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-12-13 12:49:01 -05:00
|
|
|
|
selectionRanges,
|
2024-09-09 19:59:36 +03:00
|
|
|
|
updatedAst.newAst
|
|
|
|
|
)
|
|
|
|
|
if (err(selection)) return Promise.reject(selection)
|
|
|
|
|
return {
|
|
|
|
|
selectionType: 'completeSelection',
|
|
|
|
|
selection,
|
2025-02-15 00:57:04 +11:00
|
|
|
|
updatedSketchEntryNodePath,
|
|
|
|
|
updatedSketchNodePaths,
|
|
|
|
|
updatedPlaneNodePath,
|
Command bar: add extrude command, nonlinear editing, etc (#1204)
* Tweak toaster look and feel
* Add icons, tweak plus icon names
* Rename commandBarMeta to commandBarConfig
* Refactor command bar, add support for icons
* Create a tailwind plugin for aria-pressed button state
* Remove overlay from behind command bar
* Clean up toolbar
* Button and other style tweaks
* Icon tweaks follow-up: make old icons work with new sizing
* Delete unused static icons
* More CSS tweaks
* Small CSS tweak to project sidebar
* Add command bar E2E test
* fumpt
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)
* fix typo in a comment
* Fix icon padding (built version only)
* Update onboarding and warning banner icons padding
* Misc minor style fixes
* Get Extrude opening and canceling from command bar
* Iconography tweaks
* Get extrude kind of working
* Refactor command bar config types and organization
* Move command bar configs to be co-located with each other
* Start building a state machine for the command bar
* Start converting command bar to state machine
* Add support for multiple args, confirmation step
* Submission behavior, hotkeys, code organization
* Add new test for extruding from command bar
* Polish step back and selection hotkeys, CSS tweaks
* Loading style tweaks
* Validate selection inputs, polish UX of args re-editing
* Prevent submission with multiple selection on singlular arg
* Remove stray console logs
* Tweak test, CSS nit, remove extrude "result" argument
* Fix linting warnings
* Show Ctrl+/ instead of ⌘K on all platforms but Mac
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)
* Add "Enter sketch" to command bar
* fix command bar test
* Fix flaky cmd bar extrude test by waiting for engine select response
* Cover both button labels '⌘K' and 'Ctrl+/' in test
---------
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-12-13 12:49:01 -05:00
|
|
|
|
}
|
|
|
|
|
}
|
2024-09-09 19:59:36 +03:00
|
|
|
|
),
|
|
|
|
|
'Get ABS X info': fromPromise(
|
|
|
|
|
async ({ input: { selectionRanges, sketchDetails } }) => {
|
2025-02-15 00:57:04 +11:00
|
|
|
|
const { modifiedAst, pathToNodeMap, exprInsertIndex } =
|
2024-09-09 19:59:36 +03:00
|
|
|
|
await applyConstraintAbsDistance({
|
|
|
|
|
constraint: 'xAbs',
|
|
|
|
|
selectionRanges,
|
|
|
|
|
})
|
2024-12-06 13:57:31 +13:00
|
|
|
|
const pResult = parse(recast(modifiedAst))
|
|
|
|
|
if (trap(pResult) || !resultIsOk(pResult))
|
|
|
|
|
return Promise.reject(new Error('Unexpected compilation error'))
|
|
|
|
|
const _modifiedAst = pResult.program
|
2024-09-09 19:59:36 +03:00
|
|
|
|
if (!sketchDetails)
|
|
|
|
|
return Promise.reject(new Error('No sketch details'))
|
2025-02-15 00:57:04 +11:00
|
|
|
|
|
|
|
|
|
const {
|
|
|
|
|
updatedSketchEntryNodePath,
|
|
|
|
|
updatedSketchNodePaths,
|
|
|
|
|
updatedPlaneNodePath,
|
|
|
|
|
} = updateSketchDetailsNodePaths({
|
|
|
|
|
sketchEntryNodePath: sketchDetails.sketchEntryNodePath,
|
|
|
|
|
sketchNodePaths: sketchDetails.sketchNodePaths,
|
|
|
|
|
planeNodePath: sketchDetails.planeNodePath,
|
|
|
|
|
exprInsertIndex,
|
|
|
|
|
})
|
2024-09-09 19:59:36 +03:00
|
|
|
|
const updatedAst =
|
|
|
|
|
await sceneEntitiesManager.updateAstAndRejigSketch(
|
2025-02-15 00:57:04 +11:00
|
|
|
|
updatedSketchEntryNodePath,
|
|
|
|
|
updatedSketchNodePaths,
|
|
|
|
|
updatedPlaneNodePath,
|
2024-09-09 19:59:36 +03:00
|
|
|
|
_modifiedAst,
|
|
|
|
|
sketchDetails.zAxis,
|
|
|
|
|
sketchDetails.yAxis,
|
|
|
|
|
sketchDetails.origin
|
|
|
|
|
)
|
|
|
|
|
if (err(updatedAst)) return Promise.reject(updatedAst)
|
2024-11-16 16:49:44 -05:00
|
|
|
|
|
|
|
|
|
await codeManager.updateEditorWithAstAndWriteToFile(
|
|
|
|
|
updatedAst.newAst
|
|
|
|
|
)
|
|
|
|
|
|
2024-09-09 19:59:36 +03:00
|
|
|
|
const selection = updateSelections(
|
|
|
|
|
pathToNodeMap,
|
Command bar: add extrude command, nonlinear editing, etc (#1204)
* Tweak toaster look and feel
* Add icons, tweak plus icon names
* Rename commandBarMeta to commandBarConfig
* Refactor command bar, add support for icons
* Create a tailwind plugin for aria-pressed button state
* Remove overlay from behind command bar
* Clean up toolbar
* Button and other style tweaks
* Icon tweaks follow-up: make old icons work with new sizing
* Delete unused static icons
* More CSS tweaks
* Small CSS tweak to project sidebar
* Add command bar E2E test
* fumpt
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)
* fix typo in a comment
* Fix icon padding (built version only)
* Update onboarding and warning banner icons padding
* Misc minor style fixes
* Get Extrude opening and canceling from command bar
* Iconography tweaks
* Get extrude kind of working
* Refactor command bar config types and organization
* Move command bar configs to be co-located with each other
* Start building a state machine for the command bar
* Start converting command bar to state machine
* Add support for multiple args, confirmation step
* Submission behavior, hotkeys, code organization
* Add new test for extruding from command bar
* Polish step back and selection hotkeys, CSS tweaks
* Loading style tweaks
* Validate selection inputs, polish UX of args re-editing
* Prevent submission with multiple selection on singlular arg
* Remove stray console logs
* Tweak test, CSS nit, remove extrude "result" argument
* Fix linting warnings
* Show Ctrl+/ instead of ⌘K on all platforms but Mac
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)
* Add "Enter sketch" to command bar
* fix command bar test
* Fix flaky cmd bar extrude test by waiting for engine select response
* Cover both button labels '⌘K' and 'Ctrl+/' in test
---------
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-12-13 12:49:01 -05:00
|
|
|
|
selectionRanges,
|
2024-09-09 19:59:36 +03:00
|
|
|
|
updatedAst.newAst
|
|
|
|
|
)
|
|
|
|
|
if (err(selection)) return Promise.reject(selection)
|
|
|
|
|
return {
|
|
|
|
|
selectionType: 'completeSelection',
|
|
|
|
|
selection,
|
2025-02-15 00:57:04 +11:00
|
|
|
|
updatedSketchEntryNodePath,
|
|
|
|
|
updatedSketchNodePaths,
|
|
|
|
|
updatedPlaneNodePath,
|
2024-09-09 19:59:36 +03:00
|
|
|
|
}
|
Command bar: add extrude command, nonlinear editing, etc (#1204)
* Tweak toaster look and feel
* Add icons, tweak plus icon names
* Rename commandBarMeta to commandBarConfig
* Refactor command bar, add support for icons
* Create a tailwind plugin for aria-pressed button state
* Remove overlay from behind command bar
* Clean up toolbar
* Button and other style tweaks
* Icon tweaks follow-up: make old icons work with new sizing
* Delete unused static icons
* More CSS tweaks
* Small CSS tweak to project sidebar
* Add command bar E2E test
* fumpt
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)
* fix typo in a comment
* Fix icon padding (built version only)
* Update onboarding and warning banner icons padding
* Misc minor style fixes
* Get Extrude opening and canceling from command bar
* Iconography tweaks
* Get extrude kind of working
* Refactor command bar config types and organization
* Move command bar configs to be co-located with each other
* Start building a state machine for the command bar
* Start converting command bar to state machine
* Add support for multiple args, confirmation step
* Submission behavior, hotkeys, code organization
* Add new test for extruding from command bar
* Polish step back and selection hotkeys, CSS tweaks
* Loading style tweaks
* Validate selection inputs, polish UX of args re-editing
* Prevent submission with multiple selection on singlular arg
* Remove stray console logs
* Tweak test, CSS nit, remove extrude "result" argument
* Fix linting warnings
* Show Ctrl+/ instead of ⌘K on all platforms but Mac
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)
* Add "Enter sketch" to command bar
* fix command bar test
* Fix flaky cmd bar extrude test by waiting for engine select response
* Cover both button labels '⌘K' and 'Ctrl+/' in test
---------
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-12-13 12:49:01 -05:00
|
|
|
|
}
|
2024-09-09 19:59:36 +03:00
|
|
|
|
),
|
|
|
|
|
'Get ABS Y info': fromPromise(
|
|
|
|
|
async ({ input: { selectionRanges, sketchDetails } }) => {
|
2025-02-15 00:57:04 +11:00
|
|
|
|
const { modifiedAst, pathToNodeMap, exprInsertIndex } =
|
2024-09-09 19:59:36 +03:00
|
|
|
|
await applyConstraintAbsDistance({
|
|
|
|
|
constraint: 'yAbs',
|
|
|
|
|
selectionRanges,
|
|
|
|
|
})
|
2024-12-06 13:57:31 +13:00
|
|
|
|
const pResult = parse(recast(modifiedAst))
|
|
|
|
|
if (trap(pResult) || !resultIsOk(pResult))
|
|
|
|
|
return Promise.reject(new Error('Unexpected compilation error'))
|
|
|
|
|
const _modifiedAst = pResult.program
|
2024-09-09 19:59:36 +03:00
|
|
|
|
if (!sketchDetails)
|
|
|
|
|
return Promise.reject(new Error('No sketch details'))
|
2025-02-15 00:57:04 +11:00
|
|
|
|
|
|
|
|
|
const {
|
|
|
|
|
updatedSketchEntryNodePath,
|
|
|
|
|
updatedSketchNodePaths,
|
|
|
|
|
updatedPlaneNodePath,
|
|
|
|
|
} = updateSketchDetailsNodePaths({
|
|
|
|
|
sketchEntryNodePath: sketchDetails.sketchEntryNodePath,
|
|
|
|
|
sketchNodePaths: sketchDetails.sketchNodePaths,
|
|
|
|
|
planeNodePath: sketchDetails.planeNodePath,
|
|
|
|
|
exprInsertIndex,
|
|
|
|
|
})
|
2024-09-09 19:59:36 +03:00
|
|
|
|
const updatedAst =
|
|
|
|
|
await sceneEntitiesManager.updateAstAndRejigSketch(
|
2025-02-15 00:57:04 +11:00
|
|
|
|
updatedSketchEntryNodePath,
|
|
|
|
|
updatedSketchNodePaths,
|
|
|
|
|
updatedPlaneNodePath,
|
2024-09-09 19:59:36 +03:00
|
|
|
|
_modifiedAst,
|
|
|
|
|
sketchDetails.zAxis,
|
|
|
|
|
sketchDetails.yAxis,
|
|
|
|
|
sketchDetails.origin
|
|
|
|
|
)
|
|
|
|
|
if (err(updatedAst)) return Promise.reject(updatedAst)
|
2024-11-16 16:49:44 -05:00
|
|
|
|
|
|
|
|
|
await codeManager.updateEditorWithAstAndWriteToFile(
|
|
|
|
|
updatedAst.newAst
|
|
|
|
|
)
|
|
|
|
|
|
2024-09-09 19:59:36 +03:00
|
|
|
|
const selection = updateSelections(
|
|
|
|
|
pathToNodeMap,
|
Command bar: add extrude command, nonlinear editing, etc (#1204)
* Tweak toaster look and feel
* Add icons, tweak plus icon names
* Rename commandBarMeta to commandBarConfig
* Refactor command bar, add support for icons
* Create a tailwind plugin for aria-pressed button state
* Remove overlay from behind command bar
* Clean up toolbar
* Button and other style tweaks
* Icon tweaks follow-up: make old icons work with new sizing
* Delete unused static icons
* More CSS tweaks
* Small CSS tweak to project sidebar
* Add command bar E2E test
* fumpt
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)
* fix typo in a comment
* Fix icon padding (built version only)
* Update onboarding and warning banner icons padding
* Misc minor style fixes
* Get Extrude opening and canceling from command bar
* Iconography tweaks
* Get extrude kind of working
* Refactor command bar config types and organization
* Move command bar configs to be co-located with each other
* Start building a state machine for the command bar
* Start converting command bar to state machine
* Add support for multiple args, confirmation step
* Submission behavior, hotkeys, code organization
* Add new test for extruding from command bar
* Polish step back and selection hotkeys, CSS tweaks
* Loading style tweaks
* Validate selection inputs, polish UX of args re-editing
* Prevent submission with multiple selection on singlular arg
* Remove stray console logs
* Tweak test, CSS nit, remove extrude "result" argument
* Fix linting warnings
* Show Ctrl+/ instead of ⌘K on all platforms but Mac
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)
* Add "Enter sketch" to command bar
* fix command bar test
* Fix flaky cmd bar extrude test by waiting for engine select response
* Cover both button labels '⌘K' and 'Ctrl+/' in test
---------
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-12-13 12:49:01 -05:00
|
|
|
|
selectionRanges,
|
2024-09-09 19:59:36 +03:00
|
|
|
|
updatedAst.newAst
|
|
|
|
|
)
|
|
|
|
|
if (err(selection)) return Promise.reject(selection)
|
|
|
|
|
return {
|
|
|
|
|
selectionType: 'completeSelection',
|
|
|
|
|
selection,
|
2025-02-15 00:57:04 +11:00
|
|
|
|
updatedSketchEntryNodePath,
|
|
|
|
|
updatedSketchNodePaths,
|
|
|
|
|
updatedPlaneNodePath,
|
2024-09-09 19:59:36 +03:00
|
|
|
|
}
|
Command bar: add extrude command, nonlinear editing, etc (#1204)
* Tweak toaster look and feel
* Add icons, tweak plus icon names
* Rename commandBarMeta to commandBarConfig
* Refactor command bar, add support for icons
* Create a tailwind plugin for aria-pressed button state
* Remove overlay from behind command bar
* Clean up toolbar
* Button and other style tweaks
* Icon tweaks follow-up: make old icons work with new sizing
* Delete unused static icons
* More CSS tweaks
* Small CSS tweak to project sidebar
* Add command bar E2E test
* fumpt
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)
* fix typo in a comment
* Fix icon padding (built version only)
* Update onboarding and warning banner icons padding
* Misc minor style fixes
* Get Extrude opening and canceling from command bar
* Iconography tweaks
* Get extrude kind of working
* Refactor command bar config types and organization
* Move command bar configs to be co-located with each other
* Start building a state machine for the command bar
* Start converting command bar to state machine
* Add support for multiple args, confirmation step
* Submission behavior, hotkeys, code organization
* Add new test for extruding from command bar
* Polish step back and selection hotkeys, CSS tweaks
* Loading style tweaks
* Validate selection inputs, polish UX of args re-editing
* Prevent submission with multiple selection on singlular arg
* Remove stray console logs
* Tweak test, CSS nit, remove extrude "result" argument
* Fix linting warnings
* Show Ctrl+/ instead of ⌘K on all platforms but Mac
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)
* Add "Enter sketch" to command bar
* fix command bar test
* Fix flaky cmd bar extrude test by waiting for engine select response
* Cover both button labels '⌘K' and 'Ctrl+/' in test
---------
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-12-13 12:49:01 -05:00
|
|
|
|
}
|
2024-09-09 19:59:36 +03:00
|
|
|
|
),
|
2024-12-09 16:43:58 -05:00
|
|
|
|
'Apply named value constraint': fromPromise(
|
2024-09-09 19:59:36 +03:00
|
|
|
|
async ({ input: { selectionRanges, sketchDetails, data } }) => {
|
2024-12-09 16:43:58 -05:00
|
|
|
|
if (!sketchDetails) {
|
2024-09-09 19:59:36 +03:00
|
|
|
|
return Promise.reject(new Error('No sketch details'))
|
2024-12-09 16:43:58 -05:00
|
|
|
|
}
|
|
|
|
|
if (!data) {
|
|
|
|
|
return Promise.reject(new Error('No data from command flow'))
|
|
|
|
|
}
|
2024-12-06 13:57:31 +13:00
|
|
|
|
let pResult = parse(recast(kclManager.ast))
|
|
|
|
|
if (trap(pResult) || !resultIsOk(pResult))
|
|
|
|
|
return Promise.reject(new Error('Unexpected compilation error'))
|
|
|
|
|
let parsed = pResult.program
|
2024-09-09 19:59:36 +03:00
|
|
|
|
|
2024-12-09 16:43:58 -05:00
|
|
|
|
let result: {
|
|
|
|
|
modifiedAst: Node<Program>
|
|
|
|
|
pathToReplaced: PathToNode | null
|
2025-02-15 00:57:04 +11:00
|
|
|
|
exprInsertIndex: number
|
2024-12-09 16:43:58 -05:00
|
|
|
|
} = {
|
|
|
|
|
modifiedAst: parsed,
|
|
|
|
|
pathToReplaced: null,
|
2025-02-15 00:57:04 +11:00
|
|
|
|
exprInsertIndex: -1,
|
2024-12-09 16:43:58 -05:00
|
|
|
|
}
|
|
|
|
|
// If the user provided a constant name,
|
|
|
|
|
// we need to insert the named constant
|
|
|
|
|
// and then replace the node with the constant's name.
|
|
|
|
|
if ('variableName' in data.namedValue) {
|
|
|
|
|
const astAfterReplacement = replaceValueAtNodePath({
|
|
|
|
|
ast: parsed,
|
|
|
|
|
pathToNode: data.currentValue.pathToNode,
|
|
|
|
|
newExpressionString: data.namedValue.variableName,
|
|
|
|
|
})
|
|
|
|
|
if (trap(astAfterReplacement)) {
|
|
|
|
|
return Promise.reject(astAfterReplacement)
|
|
|
|
|
}
|
|
|
|
|
const parseResultAfterInsertion = parse(
|
|
|
|
|
recast(
|
|
|
|
|
insertNamedConstant({
|
|
|
|
|
node: astAfterReplacement.modifiedAst,
|
|
|
|
|
newExpression: data.namedValue,
|
|
|
|
|
})
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
if (
|
|
|
|
|
trap(parseResultAfterInsertion) ||
|
|
|
|
|
!resultIsOk(parseResultAfterInsertion)
|
2024-09-09 19:59:36 +03:00
|
|
|
|
)
|
2024-12-09 16:43:58 -05:00
|
|
|
|
return Promise.reject(parseResultAfterInsertion)
|
|
|
|
|
result = {
|
|
|
|
|
modifiedAst: parseResultAfterInsertion.program,
|
|
|
|
|
pathToReplaced: astAfterReplacement.pathToReplaced,
|
2025-02-15 00:57:04 +11:00
|
|
|
|
exprInsertIndex: astAfterReplacement.exprInsertIndex,
|
2024-12-09 16:43:58 -05:00
|
|
|
|
}
|
|
|
|
|
} else if ('valueText' in data.namedValue) {
|
|
|
|
|
// If they didn't provide a constant name,
|
|
|
|
|
// just replace the node with the value.
|
|
|
|
|
const astAfterReplacement = replaceValueAtNodePath({
|
|
|
|
|
ast: parsed,
|
|
|
|
|
pathToNode: data.currentValue.pathToNode,
|
|
|
|
|
newExpressionString: data.namedValue.valueText,
|
|
|
|
|
})
|
|
|
|
|
if (trap(astAfterReplacement)) {
|
|
|
|
|
return Promise.reject(astAfterReplacement)
|
|
|
|
|
}
|
|
|
|
|
// The `replacer` function returns a pathToNode that assumes
|
|
|
|
|
// an identifier is also being inserted into the AST, creating an off-by-one error.
|
|
|
|
|
// This corrects that error, but TODO we should fix this upstream
|
|
|
|
|
// to avoid this kind of error in the future.
|
|
|
|
|
astAfterReplacement.pathToReplaced[1][0] =
|
|
|
|
|
(astAfterReplacement.pathToReplaced[1][0] as number) - 1
|
|
|
|
|
result = astAfterReplacement
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pResult = parse(recast(result.modifiedAst))
|
2024-12-06 13:57:31 +13:00
|
|
|
|
if (trap(pResult) || !resultIsOk(pResult))
|
|
|
|
|
return Promise.reject(new Error('Unexpected compilation error'))
|
|
|
|
|
parsed = pResult.program
|
|
|
|
|
|
2024-09-09 19:59:36 +03:00
|
|
|
|
if (trap(parsed)) return Promise.reject(parsed)
|
2024-12-09 16:43:58 -05:00
|
|
|
|
if (!result.pathToReplaced)
|
2024-09-09 19:59:36 +03:00
|
|
|
|
return Promise.reject(new Error('No path to replaced node'))
|
2025-02-15 00:57:04 +11:00
|
|
|
|
const {
|
|
|
|
|
updatedSketchEntryNodePath,
|
|
|
|
|
updatedSketchNodePaths,
|
|
|
|
|
updatedPlaneNodePath,
|
|
|
|
|
} = updateSketchDetailsNodePaths({
|
|
|
|
|
sketchEntryNodePath: sketchDetails.sketchEntryNodePath,
|
|
|
|
|
sketchNodePaths: sketchDetails.sketchNodePaths,
|
|
|
|
|
planeNodePath: sketchDetails.planeNodePath,
|
|
|
|
|
exprInsertIndex: result.exprInsertIndex,
|
|
|
|
|
})
|
2024-09-09 19:59:36 +03:00
|
|
|
|
|
|
|
|
|
const updatedAst =
|
|
|
|
|
await sceneEntitiesManager.updateAstAndRejigSketch(
|
2025-02-15 00:57:04 +11:00
|
|
|
|
updatedSketchEntryNodePath,
|
|
|
|
|
updatedSketchNodePaths,
|
|
|
|
|
updatedPlaneNodePath,
|
2024-09-09 19:59:36 +03:00
|
|
|
|
parsed,
|
|
|
|
|
sketchDetails.zAxis,
|
|
|
|
|
sketchDetails.yAxis,
|
|
|
|
|
sketchDetails.origin
|
|
|
|
|
)
|
|
|
|
|
if (err(updatedAst)) return Promise.reject(updatedAst)
|
2024-11-16 16:49:44 -05:00
|
|
|
|
|
|
|
|
|
await codeManager.updateEditorWithAstAndWriteToFile(
|
|
|
|
|
updatedAst.newAst
|
|
|
|
|
)
|
|
|
|
|
|
2024-09-09 19:59:36 +03:00
|
|
|
|
const selection = updateSelections(
|
2024-12-09 16:43:58 -05:00
|
|
|
|
{ 0: result.pathToReplaced },
|
2024-09-09 19:59:36 +03:00
|
|
|
|
selectionRanges,
|
|
|
|
|
updatedAst.newAst
|
2024-05-24 20:54:42 +10:00
|
|
|
|
)
|
2024-09-09 19:59:36 +03:00
|
|
|
|
if (err(selection)) return Promise.reject(selection)
|
|
|
|
|
return {
|
|
|
|
|
selectionType: 'completeSelection',
|
|
|
|
|
selection,
|
2025-02-15 00:57:04 +11:00
|
|
|
|
updatedSketchEntryNodePath,
|
|
|
|
|
updatedSketchNodePaths,
|
|
|
|
|
updatedPlaneNodePath,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
),
|
|
|
|
|
'set-up-draft-circle': fromPromise(
|
|
|
|
|
async ({ input: { sketchDetails, data } }) => {
|
|
|
|
|
if (!sketchDetails || !data)
|
|
|
|
|
return reject('No sketch details or data')
|
|
|
|
|
sceneEntitiesManager.tearDownSketch({ removeAxis: false })
|
|
|
|
|
|
|
|
|
|
const result = await sceneEntitiesManager.setupDraftCircle(
|
|
|
|
|
sketchDetails.sketchEntryNodePath,
|
|
|
|
|
sketchDetails.sketchNodePaths,
|
|
|
|
|
sketchDetails.planeNodePath,
|
|
|
|
|
sketchDetails.zAxis,
|
|
|
|
|
sketchDetails.yAxis,
|
|
|
|
|
sketchDetails.origin,
|
|
|
|
|
data
|
|
|
|
|
)
|
|
|
|
|
if (err(result)) return reject(result)
|
|
|
|
|
await codeManager.updateEditorWithAstAndWriteToFile(kclManager.ast)
|
|
|
|
|
|
|
|
|
|
return result
|
|
|
|
|
}
|
|
|
|
|
),
|
|
|
|
|
'set-up-draft-circle-three-point': fromPromise(
|
|
|
|
|
async ({ input: { sketchDetails, data } }) => {
|
|
|
|
|
if (!sketchDetails || !data)
|
|
|
|
|
return reject('No sketch details or data')
|
|
|
|
|
sceneEntitiesManager.tearDownSketch({ removeAxis: false })
|
|
|
|
|
|
|
|
|
|
const result =
|
|
|
|
|
await sceneEntitiesManager.setupDraftCircleThreePoint(
|
|
|
|
|
sketchDetails.sketchEntryNodePath,
|
|
|
|
|
sketchDetails.sketchNodePaths,
|
|
|
|
|
sketchDetails.planeNodePath,
|
|
|
|
|
sketchDetails.zAxis,
|
|
|
|
|
sketchDetails.yAxis,
|
|
|
|
|
sketchDetails.origin,
|
|
|
|
|
data.p1,
|
|
|
|
|
data.p2
|
|
|
|
|
)
|
|
|
|
|
if (err(result)) return reject(result)
|
|
|
|
|
await codeManager.updateEditorWithAstAndWriteToFile(kclManager.ast)
|
|
|
|
|
|
|
|
|
|
return result
|
|
|
|
|
}
|
|
|
|
|
),
|
|
|
|
|
'set-up-draft-rectangle': fromPromise(
|
|
|
|
|
async ({ input: { sketchDetails, data } }) => {
|
|
|
|
|
if (!sketchDetails || !data)
|
|
|
|
|
return reject('No sketch details or data')
|
|
|
|
|
sceneEntitiesManager.tearDownSketch({ removeAxis: false })
|
|
|
|
|
|
|
|
|
|
const result = await sceneEntitiesManager.setupDraftRectangle(
|
|
|
|
|
sketchDetails.sketchEntryNodePath,
|
|
|
|
|
sketchDetails.sketchNodePaths,
|
|
|
|
|
sketchDetails.planeNodePath,
|
|
|
|
|
sketchDetails.zAxis,
|
|
|
|
|
sketchDetails.yAxis,
|
|
|
|
|
sketchDetails.origin,
|
|
|
|
|
data
|
|
|
|
|
)
|
|
|
|
|
if (err(result)) return reject(result)
|
|
|
|
|
await codeManager.updateEditorWithAstAndWriteToFile(kclManager.ast)
|
|
|
|
|
|
|
|
|
|
return result
|
|
|
|
|
}
|
|
|
|
|
),
|
|
|
|
|
'set-up-draft-center-rectangle': fromPromise(
|
|
|
|
|
async ({ input: { sketchDetails, data } }) => {
|
|
|
|
|
if (!sketchDetails || !data)
|
|
|
|
|
return reject('No sketch details or data')
|
|
|
|
|
sceneEntitiesManager.tearDownSketch({ removeAxis: false })
|
|
|
|
|
const result = await sceneEntitiesManager.setupDraftCenterRectangle(
|
|
|
|
|
sketchDetails.sketchEntryNodePath,
|
|
|
|
|
sketchDetails.sketchNodePaths,
|
|
|
|
|
sketchDetails.planeNodePath,
|
|
|
|
|
sketchDetails.zAxis,
|
|
|
|
|
sketchDetails.yAxis,
|
|
|
|
|
sketchDetails.origin,
|
|
|
|
|
data
|
|
|
|
|
)
|
|
|
|
|
if (err(result)) return reject(result)
|
|
|
|
|
await codeManager.updateEditorWithAstAndWriteToFile(kclManager.ast)
|
|
|
|
|
|
|
|
|
|
return result
|
|
|
|
|
}
|
|
|
|
|
),
|
2025-03-18 11:14:12 +11:00
|
|
|
|
'set-up-draft-arc-three-point': fromPromise(
|
|
|
|
|
async ({ input: { sketchDetails, data } }) => {
|
|
|
|
|
if (!sketchDetails || !data)
|
|
|
|
|
return reject('No sketch details or data')
|
|
|
|
|
sceneEntitiesManager.tearDownSketch({ removeAxis: false })
|
|
|
|
|
const result = await sceneEntitiesManager.setupDraftArcThreePoint(
|
|
|
|
|
sketchDetails.sketchEntryNodePath,
|
|
|
|
|
sketchDetails.sketchNodePaths,
|
|
|
|
|
sketchDetails.planeNodePath,
|
|
|
|
|
sketchDetails.zAxis,
|
|
|
|
|
sketchDetails.yAxis,
|
|
|
|
|
sketchDetails.origin,
|
|
|
|
|
data
|
|
|
|
|
)
|
|
|
|
|
if (err(result)) return reject(result)
|
|
|
|
|
|
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
|
|
|
codeManager.updateEditorWithAstAndWriteToFile(kclManager.ast)
|
|
|
|
|
|
|
|
|
|
return result
|
|
|
|
|
}
|
|
|
|
|
),
|
|
|
|
|
'set-up-draft-arc': fromPromise(
|
|
|
|
|
async ({ input: { sketchDetails, data } }) => {
|
|
|
|
|
if (!sketchDetails || !data)
|
|
|
|
|
return reject('No sketch details or data')
|
|
|
|
|
sceneEntitiesManager.tearDownSketch({ removeAxis: false })
|
|
|
|
|
const result = await sceneEntitiesManager.setupDraftArc(
|
|
|
|
|
sketchDetails.sketchEntryNodePath,
|
|
|
|
|
sketchDetails.sketchNodePaths,
|
|
|
|
|
sketchDetails.planeNodePath,
|
|
|
|
|
sketchDetails.zAxis,
|
|
|
|
|
sketchDetails.yAxis,
|
|
|
|
|
sketchDetails.origin,
|
|
|
|
|
data
|
|
|
|
|
)
|
|
|
|
|
if (err(result)) return reject(result)
|
|
|
|
|
await codeManager.updateEditorWithAstAndWriteToFile(kclManager.ast)
|
|
|
|
|
|
|
|
|
|
return result
|
|
|
|
|
}
|
|
|
|
|
),
|
2025-02-15 00:57:04 +11:00
|
|
|
|
'setup-client-side-sketch-segments': fromPromise(
|
|
|
|
|
async ({ input: { sketchDetails, selectionRanges } }) => {
|
|
|
|
|
if (!sketchDetails) return
|
2025-03-20 08:30:11 +11:00
|
|
|
|
if (!sketchDetails.sketchEntryNodePath?.length) return
|
2025-02-15 00:57:04 +11:00
|
|
|
|
if (Object.keys(sceneEntitiesManager.activeSegments).length > 0) {
|
|
|
|
|
sceneEntitiesManager.tearDownSketch({ removeAxis: false })
|
|
|
|
|
}
|
|
|
|
|
sceneInfra.resetMouseListeners()
|
|
|
|
|
await sceneEntitiesManager.setupSketch({
|
|
|
|
|
sketchEntryNodePath: sketchDetails?.sketchEntryNodePath || [],
|
|
|
|
|
sketchNodePaths: sketchDetails.sketchNodePaths,
|
|
|
|
|
forward: sketchDetails.zAxis,
|
|
|
|
|
up: sketchDetails.yAxis,
|
|
|
|
|
position: sketchDetails.origin,
|
|
|
|
|
maybeModdedAst: kclManager.ast,
|
|
|
|
|
selectionRanges,
|
|
|
|
|
})
|
|
|
|
|
sceneInfra.resetMouseListeners()
|
|
|
|
|
|
|
|
|
|
sceneEntitiesManager.setupSketchIdleCallbacks({
|
|
|
|
|
sketchEntryNodePath: sketchDetails?.sketchEntryNodePath || [],
|
|
|
|
|
forward: sketchDetails.zAxis,
|
|
|
|
|
up: sketchDetails.yAxis,
|
|
|
|
|
position: sketchDetails.origin,
|
|
|
|
|
sketchNodePaths: sketchDetails.sketchNodePaths,
|
|
|
|
|
planeNodePath: sketchDetails.planeNodePath,
|
|
|
|
|
// We will want to pass sketchTools here
|
|
|
|
|
// to add their interactions
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
// We will want to update the context with sketchTools.
|
|
|
|
|
// They'll be used for their .destroy() in tearDownSketch
|
|
|
|
|
return undefined
|
|
|
|
|
}
|
|
|
|
|
),
|
|
|
|
|
'split-sketch-pipe-if-needed': fromPromise(
|
|
|
|
|
async ({ input: { sketchDetails } }) => {
|
|
|
|
|
if (!sketchDetails) return reject('No sketch details')
|
|
|
|
|
const existingSketchInfoNoOp = {
|
|
|
|
|
updatedEntryNodePath: sketchDetails.sketchEntryNodePath,
|
|
|
|
|
updatedSketchNodePaths: sketchDetails.sketchNodePaths,
|
|
|
|
|
updatedPlaneNodePath: sketchDetails.planeNodePath,
|
|
|
|
|
expressionIndexToDelete: -1,
|
|
|
|
|
} as const
|
2025-03-20 08:30:11 +11:00
|
|
|
|
if (!sketchDetails?.sketchEntryNodePath?.length) {
|
|
|
|
|
return existingSketchInfoNoOp
|
|
|
|
|
}
|
2025-02-15 00:57:04 +11:00
|
|
|
|
if (
|
|
|
|
|
!sketchDetails.sketchNodePaths.length &&
|
|
|
|
|
sketchDetails.planeNodePath.length
|
|
|
|
|
) {
|
|
|
|
|
// new sketch, no profiles yet
|
|
|
|
|
return existingSketchInfoNoOp
|
|
|
|
|
}
|
|
|
|
|
const doesNeedSplitting = doesSketchPipeNeedSplitting(
|
|
|
|
|
kclManager.ast,
|
|
|
|
|
sketchDetails.sketchEntryNodePath
|
|
|
|
|
)
|
|
|
|
|
if (err(doesNeedSplitting)) return reject(doesNeedSplitting)
|
2025-03-25 05:06:27 -04:00
|
|
|
|
let moddedAst: Node<Program> = structuredClone(kclManager.ast)
|
2025-02-15 00:57:04 +11:00
|
|
|
|
let pathToProfile = sketchDetails.sketchEntryNodePath
|
|
|
|
|
let updatedSketchNodePaths = sketchDetails.sketchNodePaths
|
|
|
|
|
if (doesNeedSplitting) {
|
|
|
|
|
const splitResult = splitPipedProfile(
|
|
|
|
|
moddedAst,
|
|
|
|
|
sketchDetails.sketchEntryNodePath
|
|
|
|
|
)
|
|
|
|
|
if (err(splitResult)) return reject(splitResult)
|
|
|
|
|
moddedAst = splitResult.modifiedAst
|
|
|
|
|
pathToProfile = splitResult.pathToProfile
|
|
|
|
|
updatedSketchNodePaths = [pathToProfile]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const indexToDelete = sketchDetails?.expressionIndexToDelete || -1
|
2025-03-18 11:14:12 +11:00
|
|
|
|
let isLastInPipeThreePointArc = false
|
2025-02-15 00:57:04 +11:00
|
|
|
|
if (indexToDelete >= 0) {
|
|
|
|
|
// this is the expression that was added when as sketch tool was used but not completed
|
|
|
|
|
// i.e first click for the center of the circle, but not the second click for the radius
|
|
|
|
|
// we added a circle to editor, but they bailed out early so we should remove it
|
2025-03-18 11:14:12 +11:00
|
|
|
|
|
|
|
|
|
const pipe = getNodeFromPath<PipeExpression>(
|
|
|
|
|
moddedAst,
|
|
|
|
|
pathToProfile,
|
|
|
|
|
'PipeExpression'
|
2025-02-15 00:57:04 +11:00
|
|
|
|
)
|
2025-03-18 11:14:12 +11:00
|
|
|
|
if (err(pipe)) {
|
|
|
|
|
isLastInPipeThreePointArc = false
|
|
|
|
|
} else {
|
|
|
|
|
const lastInPipe = pipe?.node?.body?.[pipe.node.body.length - 1]
|
|
|
|
|
if (
|
|
|
|
|
lastInPipe &&
|
|
|
|
|
Number(pathToProfile[1][0]) === indexToDelete &&
|
|
|
|
|
lastInPipe.type === 'CallExpression' &&
|
2025-03-24 20:58:55 +13:00
|
|
|
|
lastInPipe.callee.type === 'Name' &&
|
|
|
|
|
lastInPipe.callee.name.name === 'arcTo'
|
2025-03-18 11:14:12 +11:00
|
|
|
|
) {
|
|
|
|
|
isLastInPipeThreePointArc = true
|
|
|
|
|
pipe.node.body = pipe.node.body.slice(0, -1)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!isLastInPipeThreePointArc) {
|
|
|
|
|
moddedAst.body.splice(indexToDelete, 1)
|
|
|
|
|
// make sure the deleted expression is removed from the sketchNodePaths
|
|
|
|
|
updatedSketchNodePaths = updatedSketchNodePaths.filter(
|
|
|
|
|
(path) => path[1][0] !== indexToDelete
|
|
|
|
|
)
|
|
|
|
|
// if the deleted expression was the entryNodePath, we should just make it the first sketchNodePath
|
|
|
|
|
// as a safe default
|
|
|
|
|
pathToProfile =
|
|
|
|
|
pathToProfile[1][0] !== indexToDelete
|
|
|
|
|
? pathToProfile
|
|
|
|
|
: updatedSketchNodePaths[0]
|
|
|
|
|
}
|
2025-02-15 00:57:04 +11:00
|
|
|
|
}
|
|
|
|
|
|
2025-03-18 11:14:12 +11:00
|
|
|
|
if (
|
|
|
|
|
doesNeedSplitting ||
|
|
|
|
|
indexToDelete >= 0 ||
|
|
|
|
|
isLastInPipeThreePointArc
|
|
|
|
|
) {
|
2025-03-25 05:06:27 -04:00
|
|
|
|
await updateModelingState(moddedAst, EXECUTION_TYPE_MOCK, {
|
|
|
|
|
kclManager,
|
|
|
|
|
editorManager,
|
|
|
|
|
codeManager,
|
|
|
|
|
})
|
2025-02-15 00:57:04 +11:00
|
|
|
|
}
|
|
|
|
|
return {
|
|
|
|
|
updatedEntryNodePath: pathToProfile,
|
|
|
|
|
updatedSketchNodePaths: updatedSketchNodePaths,
|
|
|
|
|
updatedPlaneNodePath: sketchDetails.planeNodePath,
|
|
|
|
|
expressionIndexToDelete: -1,
|
2024-09-09 19:59:36 +03:00
|
|
|
|
}
|
2024-06-24 11:45:40 -04:00
|
|
|
|
}
|
2024-09-09 19:59:36 +03:00
|
|
|
|
),
|
2024-12-20 13:39:06 +11:00
|
|
|
|
'submit-prompt-edit': fromPromise(async ({ input }) => {
|
|
|
|
|
return await promptToEditFlow({
|
|
|
|
|
code: codeManager.code,
|
|
|
|
|
prompt: input.prompt,
|
|
|
|
|
selections: input.selection,
|
|
|
|
|
token,
|
2025-03-29 17:25:26 -07:00
|
|
|
|
artifactGraph: kclManager.artifactGraph,
|
2025-02-12 14:44:47 -08:00
|
|
|
|
projectName: context.project.name,
|
2024-12-20 13:39:06 +11:00
|
|
|
|
})
|
|
|
|
|
}),
|
2024-09-09 19:59:36 +03:00
|
|
|
|
},
|
|
|
|
|
}),
|
|
|
|
|
{
|
|
|
|
|
input: {
|
|
|
|
|
...modelingMachineDefaultContext,
|
|
|
|
|
store: {
|
|
|
|
|
...modelingMachineDefaultContext.store,
|
|
|
|
|
...persistedContext,
|
2024-05-24 20:54:42 +10:00
|
|
|
|
},
|
2024-10-25 19:28:10 -04:00
|
|
|
|
machineManager,
|
2023-12-01 20:18:51 +11:00
|
|
|
|
},
|
2024-09-09 19:59:36 +03:00
|
|
|
|
// devTools: true,
|
Command bar: add extrude command, nonlinear editing, etc (#1204)
* Tweak toaster look and feel
* Add icons, tweak plus icon names
* Rename commandBarMeta to commandBarConfig
* Refactor command bar, add support for icons
* Create a tailwind plugin for aria-pressed button state
* Remove overlay from behind command bar
* Clean up toolbar
* Button and other style tweaks
* Icon tweaks follow-up: make old icons work with new sizing
* Delete unused static icons
* More CSS tweaks
* Small CSS tweak to project sidebar
* Add command bar E2E test
* fumpt
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)
* fix typo in a comment
* Fix icon padding (built version only)
* Update onboarding and warning banner icons padding
* Misc minor style fixes
* Get Extrude opening and canceling from command bar
* Iconography tweaks
* Get extrude kind of working
* Refactor command bar config types and organization
* Move command bar configs to be co-located with each other
* Start building a state machine for the command bar
* Start converting command bar to state machine
* Add support for multiple args, confirmation step
* Submission behavior, hotkeys, code organization
* Add new test for extruding from command bar
* Polish step back and selection hotkeys, CSS tweaks
* Loading style tweaks
* Validate selection inputs, polish UX of args re-editing
* Prevent submission with multiple selection on singlular arg
* Remove stray console logs
* Tweak test, CSS nit, remove extrude "result" argument
* Fix linting warnings
* Show Ctrl+/ instead of ⌘K on all platforms but Mac
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)
* Add "Enter sketch" to command bar
* fix command bar test
* Fix flaky cmd bar extrude test by waiting for engine select response
* Cover both button labels '⌘K' and 'Ctrl+/' in test
---------
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-12-13 12:49:01 -05:00
|
|
|
|
}
|
|
|
|
|
)
|
2025-03-20 08:30:11 +11:00
|
|
|
|
|
|
|
|
|
// Add debug function to window object
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
// @ts-ignore - we're intentionally adding this to window
|
|
|
|
|
window.getModelingState = () => {
|
|
|
|
|
const modelingState = modelingActor.getSnapshot()
|
|
|
|
|
return {
|
|
|
|
|
modelingState,
|
|
|
|
|
id: modelingState._nodes[modelingState._nodes.length - 1].id,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}, [modelingActor])
|
2023-10-11 13:36:54 +11:00
|
|
|
|
|
2024-08-07 03:11:57 -04:00
|
|
|
|
useSetupEngineManager(
|
|
|
|
|
streamRef,
|
2024-07-02 17:16:27 +10:00
|
|
|
|
modelingSend,
|
2024-08-07 03:11:57 -04:00
|
|
|
|
modelingState.context,
|
|
|
|
|
{
|
|
|
|
|
pool: pool,
|
|
|
|
|
theme: theme.current,
|
|
|
|
|
highlightEdges: highlightEdges.current,
|
|
|
|
|
enableSSAO: enableSSAO.current,
|
|
|
|
|
showScaleGrid: showScaleGrid.current,
|
2024-09-30 11:40:00 -04:00
|
|
|
|
cameraProjection: cameraProjection.current,
|
2025-02-01 15:03:04 -05:00
|
|
|
|
cameraOrbit: cameraOrbit.current,
|
2024-08-07 03:11:57 -04:00
|
|
|
|
},
|
|
|
|
|
token
|
|
|
|
|
)
|
2024-07-02 17:16:27 +10:00
|
|
|
|
|
2023-10-18 08:03:02 +11:00
|
|
|
|
useEffect(() => {
|
|
|
|
|
kclManager.registerExecuteCallback(() => {
|
|
|
|
|
modelingSend({ type: 'Re-execute' })
|
|
|
|
|
})
|
2024-05-24 16:01:16 -04:00
|
|
|
|
|
|
|
|
|
// Before this component unmounts, call the 'Cancel'
|
|
|
|
|
// event to clean up any state in the modeling machine.
|
|
|
|
|
return () => {
|
|
|
|
|
modelingSend({ type: 'Cancel' })
|
|
|
|
|
}
|
2023-10-18 08:03:02 +11:00
|
|
|
|
}, [modelingSend])
|
|
|
|
|
|
2024-04-19 14:24:40 -07:00
|
|
|
|
// Give the state back to the editorManager.
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
editorManager.modelingSend = modelingSend
|
|
|
|
|
}, [modelingSend])
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
2024-09-09 19:59:36 +03:00
|
|
|
|
editorManager.modelingState = modelingState
|
|
|
|
|
}, [modelingState])
|
2024-04-19 14:24:40 -07:00
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
editorManager.selectionRanges = modelingState.context.selectionRanges
|
|
|
|
|
}, [modelingState.context.selectionRanges])
|
|
|
|
|
|
2025-02-01 15:03:04 -05:00
|
|
|
|
// When changing camera modes reset the camera to the default orientation to correct
|
|
|
|
|
// the up vector otherwise the conconical orientation for the camera modes will be
|
|
|
|
|
// wrong
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
sceneInfra.camControls.resetCameraPosition().catch(reportRejection)
|
|
|
|
|
}, [cameraOrbit.current])
|
|
|
|
|
|
2024-05-24 16:11:49 -07:00
|
|
|
|
useEffect(() => {
|
2024-08-07 03:11:57 -04:00
|
|
|
|
const onConnectionStateChanged = ({ detail }: CustomEvent) => {
|
2024-05-24 16:11:49 -07:00
|
|
|
|
// If we are in sketch mode we need to exit it.
|
|
|
|
|
// TODO: how do i check if we are in a sketch mode, I only want to call
|
|
|
|
|
// this then.
|
2024-08-07 03:11:57 -04:00
|
|
|
|
if (detail.type === EngineConnectionStateType.Disconnecting) {
|
|
|
|
|
modelingSend({ type: 'Cancel' })
|
|
|
|
|
}
|
2024-05-24 16:11:49 -07:00
|
|
|
|
}
|
2024-08-07 03:11:57 -04:00
|
|
|
|
engineCommandManager.engineConnection?.addEventListener(
|
|
|
|
|
EngineConnectionEvents.ConnectionStateChanged,
|
|
|
|
|
onConnectionStateChanged as EventListener
|
|
|
|
|
)
|
2024-05-24 16:11:49 -07:00
|
|
|
|
return () => {
|
2024-08-07 03:11:57 -04:00
|
|
|
|
engineCommandManager.engineConnection?.removeEventListener(
|
|
|
|
|
EngineConnectionEvents.ConnectionStateChanged,
|
|
|
|
|
onConnectionStateChanged as EventListener
|
|
|
|
|
)
|
2024-05-24 16:11:49 -07:00
|
|
|
|
}
|
2024-08-07 03:11:57 -04:00
|
|
|
|
}, [engineCommandManager.engineConnection, modelingSend])
|
2024-05-24 16:11:49 -07:00
|
|
|
|
|
2025-01-16 12:48:13 -05:00
|
|
|
|
useEffect(() => {
|
|
|
|
|
const inSketchMode = modelingState.matches('Sketch')
|
|
|
|
|
|
|
|
|
|
// If you are in sketch mode and you disable the orbit, return back to the normal view to the target
|
|
|
|
|
if (!allowOrbitInSketchMode.current) {
|
|
|
|
|
const targetId = modelingState.context.sketchDetails?.animateTargetId
|
|
|
|
|
if (inSketchMode && targetId) {
|
|
|
|
|
letEngineAnimateAndSyncCamAfter(engineCommandManager, targetId)
|
|
|
|
|
.then(() => {})
|
|
|
|
|
.catch((e) => {
|
|
|
|
|
console.error(
|
|
|
|
|
'failed to sync engine and client scene after disabling allow orbit in sketch mode'
|
|
|
|
|
)
|
|
|
|
|
console.error(e)
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// While you are in sketch mode you should be able to control the enable rotate
|
|
|
|
|
// Once you exit it goes back to normal
|
|
|
|
|
if (inSketchMode) {
|
|
|
|
|
sceneInfra.camControls.enableRotate = allowOrbitInSketchMode.current
|
|
|
|
|
}
|
2025-03-24 18:23:12 -05:00
|
|
|
|
}, [allowOrbitInSketchMode.current])
|
2025-01-16 12:48:13 -05:00
|
|
|
|
|
2025-02-25 09:41:25 -05:00
|
|
|
|
// Allow using the delete key to delete solids. Backspace only on macOS as Windows and Linux have dedicated Delete
|
2025-03-13 11:13:33 -07:00
|
|
|
|
// `navigator.platform` is deprecated, but the alternative `navigator.userAgentData.platform` is not reliable
|
2025-02-25 09:41:25 -05:00
|
|
|
|
const deleteKeys =
|
2025-03-13 11:13:33 -07:00
|
|
|
|
platform() === 'macos' ? ['backspace', 'delete', 'del'] : ['delete', 'del']
|
2025-02-25 09:41:25 -05:00
|
|
|
|
useHotkeys(deleteKeys, () => {
|
2024-06-29 10:36:04 -07:00
|
|
|
|
modelingSend({ type: 'Delete selection' })
|
|
|
|
|
})
|
|
|
|
|
|
2024-10-04 13:47:44 -07:00
|
|
|
|
// Allow ctrl+alt+c to center to selection
|
|
|
|
|
useHotkeys(['mod + alt + c'], () => {
|
|
|
|
|
modelingSend({ type: 'Center camera on selection' })
|
|
|
|
|
})
|
|
|
|
|
|
Command bar: add extrude command, nonlinear editing, etc (#1204)
* Tweak toaster look and feel
* Add icons, tweak plus icon names
* Rename commandBarMeta to commandBarConfig
* Refactor command bar, add support for icons
* Create a tailwind plugin for aria-pressed button state
* Remove overlay from behind command bar
* Clean up toolbar
* Button and other style tweaks
* Icon tweaks follow-up: make old icons work with new sizing
* Delete unused static icons
* More CSS tweaks
* Small CSS tweak to project sidebar
* Add command bar E2E test
* fumpt
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)
* fix typo in a comment
* Fix icon padding (built version only)
* Update onboarding and warning banner icons padding
* Misc minor style fixes
* Get Extrude opening and canceling from command bar
* Iconography tweaks
* Get extrude kind of working
* Refactor command bar config types and organization
* Move command bar configs to be co-located with each other
* Start building a state machine for the command bar
* Start converting command bar to state machine
* Add support for multiple args, confirmation step
* Submission behavior, hotkeys, code organization
* Add new test for extruding from command bar
* Polish step back and selection hotkeys, CSS tweaks
* Loading style tweaks
* Validate selection inputs, polish UX of args re-editing
* Prevent submission with multiple selection on singlular arg
* Remove stray console logs
* Tweak test, CSS nit, remove extrude "result" argument
* Fix linting warnings
* Show Ctrl+/ instead of ⌘K on all platforms but Mac
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)
* Add "Enter sketch" to command bar
* fix command bar test
* Fix flaky cmd bar extrude test by waiting for engine select response
* Cover both button labels '⌘K' and 'Ctrl+/' in test
---------
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-12-13 12:49:01 -05:00
|
|
|
|
useStateMachineCommands({
|
|
|
|
|
machineId: 'modeling',
|
|
|
|
|
state: modelingState,
|
|
|
|
|
send: modelingSend,
|
|
|
|
|
actor: modelingActor,
|
2024-07-12 16:16:26 -04:00
|
|
|
|
commandBarConfig: modelingMachineCommandConfig,
|
2024-02-26 21:02:33 +11:00
|
|
|
|
allCommandsRequireNetwork: true,
|
2024-05-24 16:01:16 -04:00
|
|
|
|
// TODO for when sketch tools are in the toolbar: This was added when we used one "Cancel" event,
|
|
|
|
|
// but we need to support "SketchCancel" and basically
|
|
|
|
|
// make this function take the actor or state so it
|
|
|
|
|
// can call the correct event.
|
2024-02-11 12:59:00 +11:00
|
|
|
|
onCancel: () => modelingSend({ type: 'Cancel' }),
|
Command bar: add extrude command, nonlinear editing, etc (#1204)
* Tweak toaster look and feel
* Add icons, tweak plus icon names
* Rename commandBarMeta to commandBarConfig
* Refactor command bar, add support for icons
* Create a tailwind plugin for aria-pressed button state
* Remove overlay from behind command bar
* Clean up toolbar
* Button and other style tweaks
* Icon tweaks follow-up: make old icons work with new sizing
* Delete unused static icons
* More CSS tweaks
* Small CSS tweak to project sidebar
* Add command bar E2E test
* fumpt
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)
* fix typo in a comment
* Fix icon padding (built version only)
* Update onboarding and warning banner icons padding
* Misc minor style fixes
* Get Extrude opening and canceling from command bar
* Iconography tweaks
* Get extrude kind of working
* Refactor command bar config types and organization
* Move command bar configs to be co-located with each other
* Start building a state machine for the command bar
* Start converting command bar to state machine
* Add support for multiple args, confirmation step
* Submission behavior, hotkeys, code organization
* Add new test for extruding from command bar
* Polish step back and selection hotkeys, CSS tweaks
* Loading style tweaks
* Validate selection inputs, polish UX of args re-editing
* Prevent submission with multiple selection on singlular arg
* Remove stray console logs
* Tweak test, CSS nit, remove extrude "result" argument
* Fix linting warnings
* Show Ctrl+/ instead of ⌘K on all platforms but Mac
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)
* Add "Enter sketch" to command bar
* fix command bar test
* Fix flaky cmd bar extrude test by waiting for engine select response
* Cover both button labels '⌘K' and 'Ctrl+/' in test
---------
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-12-13 12:49:01 -05:00
|
|
|
|
})
|
2023-10-11 13:36:54 +11:00
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<ModelingMachineContext.Provider
|
|
|
|
|
value={{
|
|
|
|
|
state: modelingState,
|
|
|
|
|
context: modelingState.context,
|
|
|
|
|
send: modelingSend,
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
{/* TODO #818: maybe pass reff down to children/app.ts or render app.tsx directly?
|
|
|
|
|
since realistically it won't ever have generic children that isn't app.tsx */}
|
|
|
|
|
<div className="h-screen overflow-hidden select-none" ref={streamRef}>
|
|
|
|
|
{children}
|
|
|
|
|
</div>
|
|
|
|
|
</ModelingMachineContext.Provider>
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export default ModelingMachineProvider
|