@ -31,6 +31,9 @@ export type ModelingCommandSchema = {
 | 
			
		||||
    // result: (typeof EXTRUSION_RESULTS)[number]
 | 
			
		||||
    distance: KclCommandValue
 | 
			
		||||
  }
 | 
			
		||||
  Loft: {
 | 
			
		||||
    selection: Selections
 | 
			
		||||
  }
 | 
			
		||||
  Revolve: {
 | 
			
		||||
    selection: Selections
 | 
			
		||||
    angle: KclCommandValue
 | 
			
		||||
@ -260,6 +263,20 @@ export const modelingMachineCommandConfig: StateMachineCommandSetConfig<
 | 
			
		||||
      },
 | 
			
		||||
    },
 | 
			
		||||
  },
 | 
			
		||||
  Loft: {
 | 
			
		||||
    description: 'Create a 3D body by blending between two or more sketches',
 | 
			
		||||
    icon: 'loft',
 | 
			
		||||
    needsReview: true,
 | 
			
		||||
    args: {
 | 
			
		||||
      selection: {
 | 
			
		||||
        inputType: 'selection',
 | 
			
		||||
        selectionTypes: ['solid2D', 'segment'],
 | 
			
		||||
        multiple: true,
 | 
			
		||||
        required: true,
 | 
			
		||||
        skip: true,
 | 
			
		||||
      },
 | 
			
		||||
    },
 | 
			
		||||
  },
 | 
			
		||||
  // TODO: Update this configuration, copied from extrude for MVP of revolve, specifically the args.selection
 | 
			
		||||
  Revolve: {
 | 
			
		||||
    description: 'Create a 3D body by rotating a sketch region about an axis.',
 | 
			
		||||
 | 
			
		||||
@ -139,9 +139,14 @@ export const toolbarConfig: Record<ToolbarModeName, ToolbarMode> = {
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        id: 'loft',
 | 
			
		||||
        onClick: () => console.error('Loft not yet implemented'),
 | 
			
		||||
        onClick: ({ commandBarSend }) =>
 | 
			
		||||
          commandBarSend({
 | 
			
		||||
            type: 'Find and select command',
 | 
			
		||||
            data: { name: 'Loft', groupId: 'modeling' },
 | 
			
		||||
          }),
 | 
			
		||||
        disabled: (state) => !state.can({ type: 'Extrude' }),
 | 
			
		||||
        icon: 'loft',
 | 
			
		||||
        status: 'kcl-only',
 | 
			
		||||
        status: 'available',
 | 
			
		||||
        title: 'Loft',
 | 
			
		||||
        hotkey: 'L',
 | 
			
		||||
        description:
 | 
			
		||||
 | 
			
		||||
@ -252,6 +252,7 @@ export type ModelingMachineEvent =
 | 
			
		||||
  | { type: 'Export'; data: ModelingCommandSchema['Export'] }
 | 
			
		||||
  | { type: 'Make'; data: ModelingCommandSchema['Make'] }
 | 
			
		||||
  | { type: 'Extrude'; data?: ModelingCommandSchema['Extrude'] }
 | 
			
		||||
  | { type: 'Loft'; data?: ModelingCommandSchema['Loft'] }
 | 
			
		||||
  | { type: 'Revolve'; data?: ModelingCommandSchema['Revolve'] }
 | 
			
		||||
  | { type: 'Fillet'; data?: ModelingCommandSchema['Fillet'] }
 | 
			
		||||
  | { type: 'Offset plane'; data: ModelingCommandSchema['Offset plane'] }
 | 
			
		||||
@ -705,6 +706,39 @@ export const modelingMachine = setup({
 | 
			
		||||
        }
 | 
			
		||||
      })().catch(reportRejection)
 | 
			
		||||
    },
 | 
			
		||||
    'AST loft': ({ context: { store }, event }) => {
 | 
			
		||||
      if (event.type !== 'Loft') return
 | 
			
		||||
      ;(async () => {
 | 
			
		||||
        if (!event.data) return
 | 
			
		||||
        const { selection } = event.data
 | 
			
		||||
        let ast = kclManager.ast
 | 
			
		||||
        const pathToNode = getNodePathFromSourceRange(
 | 
			
		||||
          ast,
 | 
			
		||||
          selection.graphSelections[0]?.codeRef.range
 | 
			
		||||
        )
 | 
			
		||||
        const loftSketchesRes = loftSketches(
 | 
			
		||||
          ast,
 | 
			
		||||
          pathToNode,
 | 
			
		||||
        )
 | 
			
		||||
        if (trap(loftSketchesRes)) return
 | 
			
		||||
        const { modifiedAst, pathToLoftArg } = loftSketchesRes 
 | 
			
		||||
 | 
			
		||||
        const updatedAst = await kclManager.updateAst(modifiedAst, true, {
 | 
			
		||||
          focusPath: [pathToLoftArg],
 | 
			
		||||
          zoomToFit: true,
 | 
			
		||||
          zoomOnRangeAndType: {
 | 
			
		||||
            range: selection.graphSelections[0]?.codeRef.range,
 | 
			
		||||
            type: 'path',
 | 
			
		||||
          },
 | 
			
		||||
        })
 | 
			
		||||
 | 
			
		||||
        await codeManager.updateEditorWithAstAndWriteToFile(updatedAst.newAst)
 | 
			
		||||
 | 
			
		||||
        if (updatedAst?.selections) {
 | 
			
		||||
          editorManager.selectRange(updatedAst?.selections)
 | 
			
		||||
        }
 | 
			
		||||
      })().catch(reportRejection)
 | 
			
		||||
    },
 | 
			
		||||
    'AST delete selection': ({ context: { selectionRanges } }) => {
 | 
			
		||||
      ;(async () => {
 | 
			
		||||
        let ast = kclManager.ast
 | 
			
		||||
@ -1561,6 +1595,13 @@ export const modelingMachine = setup({
 | 
			
		||||
          reenter: false,
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        Loft: {
 | 
			
		||||
          target: 'idle',
 | 
			
		||||
          guard: 'has valid sweep selection',
 | 
			
		||||
          actions: ['AST loft'],
 | 
			
		||||
          reenter: false,
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        Fillet: {
 | 
			
		||||
          target: 'idle',
 | 
			
		||||
          guard: 'has valid fillet selection', // TODO: fix selections
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user