addNewSketchLn should close when latest point matches start (#479)
* addNewSketchLn should close when latest point matches start * Fix types * Include close in test case * Add handling for continuing to sketch * Fix types again * close line edits (#523) * add close to pipe * undo some previous changes --------- Co-authored-by: Kurt Hutten <k.hutten@protonmail.ch>
This commit is contained in:
@ -14,7 +14,13 @@ import { useGlobalStateContext } from 'hooks/useGlobalStateContext'
|
|||||||
import { CameraDragInteractionType_type } from '@kittycad/lib/dist/types/src/models'
|
import { CameraDragInteractionType_type } from '@kittycad/lib/dist/types/src/models'
|
||||||
import { Models } from '@kittycad/lib'
|
import { Models } from '@kittycad/lib'
|
||||||
import { addStartSketch } from 'lang/modifyAst'
|
import { addStartSketch } from 'lang/modifyAst'
|
||||||
import { addNewSketchLn } from 'lang/std/sketch'
|
import {
|
||||||
|
addCloseToPipe,
|
||||||
|
addNewSketchLn,
|
||||||
|
compareVec2Epsilon,
|
||||||
|
} from 'lang/std/sketch'
|
||||||
|
import { getNodeFromPath } from 'lang/queryAst'
|
||||||
|
import { Program, VariableDeclarator } from 'lang/abstractSyntaxTreeTypes'
|
||||||
|
|
||||||
export const Stream = ({ className = '' }) => {
|
export const Stream = ({ className = '' }) => {
|
||||||
const [isLoading, setIsLoading] = useState(true)
|
const [isLoading, setIsLoading] = useState(true)
|
||||||
@ -204,8 +210,8 @@ export const Stream = ({ className = '' }) => {
|
|||||||
window: { x, y },
|
window: { x, y },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
engineCommandManager?.sendSceneCommand(command).then(async ({ data }) => {
|
engineCommandManager?.sendSceneCommand(command).then(async (resp) => {
|
||||||
if (command.cmd.type !== 'mouse_click' || !ast) return
|
if (command?.cmd?.type !== 'mouse_click' || !ast) return
|
||||||
if (
|
if (
|
||||||
!(
|
!(
|
||||||
guiMode.mode === 'sketch' &&
|
guiMode.mode === 'sketch' &&
|
||||||
@ -214,13 +220,16 @@ export const Stream = ({ className = '' }) => {
|
|||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
if (data?.data?.entities_modified?.length && guiMode.waitingFirstClick) {
|
if (
|
||||||
|
resp?.data?.data?.entities_modified?.length &&
|
||||||
|
guiMode.waitingFirstClick
|
||||||
|
) {
|
||||||
const curve = await engineCommandManager?.sendSceneCommand({
|
const curve = await engineCommandManager?.sendSceneCommand({
|
||||||
type: 'modeling_cmd_req',
|
type: 'modeling_cmd_req',
|
||||||
cmd_id: uuidv4(),
|
cmd_id: uuidv4(),
|
||||||
cmd: {
|
cmd: {
|
||||||
type: 'curve_get_control_points',
|
type: 'curve_get_control_points',
|
||||||
curve_id: data?.data?.entities_modified[0],
|
curve_id: resp?.data?.data?.entities_modified[0],
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
const coords: { x: number; y: number }[] =
|
const coords: { x: number; y: number }[] =
|
||||||
@ -243,7 +252,7 @@ export const Stream = ({ className = '' }) => {
|
|||||||
})
|
})
|
||||||
updateAst(_modifiedAst)
|
updateAst(_modifiedAst)
|
||||||
} else if (
|
} else if (
|
||||||
data?.data?.entities_modified?.length &&
|
resp?.data?.data?.entities_modified?.length &&
|
||||||
!guiMode.waitingFirstClick
|
!guiMode.waitingFirstClick
|
||||||
) {
|
) {
|
||||||
const curve = await engineCommandManager?.sendSceneCommand({
|
const curve = await engineCommandManager?.sendSceneCommand({
|
||||||
@ -251,18 +260,46 @@ export const Stream = ({ className = '' }) => {
|
|||||||
cmd_id: uuidv4(),
|
cmd_id: uuidv4(),
|
||||||
cmd: {
|
cmd: {
|
||||||
type: 'curve_get_control_points',
|
type: 'curve_get_control_points',
|
||||||
curve_id: data?.data?.entities_modified[0],
|
curve_id: resp?.data?.data?.entities_modified[0],
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
const coords: { x: number; y: number }[] =
|
const coords: { x: number; y: number }[] =
|
||||||
curve.data.data.control_points
|
curve.data.data.control_points
|
||||||
const _modifiedAst = addNewSketchLn({
|
|
||||||
|
const { node: varDec } = getNodeFromPath<VariableDeclarator>(
|
||||||
|
ast,
|
||||||
|
guiMode.pathToNode,
|
||||||
|
'VariableDeclarator'
|
||||||
|
)
|
||||||
|
const variableName = varDec.id.name
|
||||||
|
const sketchGroup = programMemory.root[variableName]
|
||||||
|
if (!sketchGroup || sketchGroup.type !== 'SketchGroup') return
|
||||||
|
const initialCoords = sketchGroup.value[0].from
|
||||||
|
|
||||||
|
const isClose = compareVec2Epsilon(initialCoords, [
|
||||||
|
coords[1].x,
|
||||||
|
coords[1].y,
|
||||||
|
])
|
||||||
|
|
||||||
|
let _modifiedAst: Program
|
||||||
|
if (!isClose) {
|
||||||
|
_modifiedAst = addNewSketchLn({
|
||||||
node: ast,
|
node: ast,
|
||||||
programMemory,
|
programMemory,
|
||||||
to: [coords[1].x, coords[1].y],
|
to: [coords[1].x, coords[1].y],
|
||||||
fnName: 'line',
|
fnName: 'line',
|
||||||
pathToNode: guiMode.pathToNode,
|
pathToNode: guiMode.pathToNode,
|
||||||
}).modifiedAst
|
}).modifiedAst
|
||||||
|
} else {
|
||||||
|
_modifiedAst = addCloseToPipe({
|
||||||
|
node: ast,
|
||||||
|
programMemory,
|
||||||
|
pathToNode: guiMode.pathToNode,
|
||||||
|
})
|
||||||
|
setGuiMode({
|
||||||
|
mode: 'default',
|
||||||
|
})
|
||||||
|
}
|
||||||
updateAst(_modifiedAst)
|
updateAst(_modifiedAst)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -4,6 +4,7 @@ import {
|
|||||||
addNewSketchLn,
|
addNewSketchLn,
|
||||||
getYComponent,
|
getYComponent,
|
||||||
getXComponent,
|
getXComponent,
|
||||||
|
addCloseToPipe,
|
||||||
} from './sketch'
|
} from './sketch'
|
||||||
import { parser_wasm } from '../abstractSyntaxTree'
|
import { parser_wasm } from '../abstractSyntaxTree'
|
||||||
import { getNodePathFromSourceRange } from '../queryAst'
|
import { getNodePathFromSourceRange } from '../queryAst'
|
||||||
@ -146,7 +147,7 @@ show(mySketch001)`
|
|||||||
const programMemory = await enginelessExecutor(ast)
|
const programMemory = await enginelessExecutor(ast)
|
||||||
const sourceStart = code.indexOf(lineToChange)
|
const sourceStart = code.indexOf(lineToChange)
|
||||||
expect(sourceStart).toBe(66)
|
expect(sourceStart).toBe(66)
|
||||||
const { modifiedAst } = addNewSketchLn({
|
let { modifiedAst } = addNewSketchLn({
|
||||||
node: ast,
|
node: ast,
|
||||||
programMemory,
|
programMemory,
|
||||||
to: [2, 3],
|
to: [2, 3],
|
||||||
@ -160,12 +161,33 @@ show(mySketch001)`
|
|||||||
],
|
],
|
||||||
})
|
})
|
||||||
// Enable rotations #152
|
// Enable rotations #152
|
||||||
const expectedCode = `const mySketch001 = startSketchAt([0, 0])
|
let expectedCode = `const mySketch001 = startSketchAt([0, 0])
|
||||||
// |> rx(45, %)
|
// |> rx(45, %)
|
||||||
|> lineTo([-1.59, -1.54], %)
|
|> lineTo([-1.59, -1.54], %)
|
||||||
|> lineTo([0.46, -5.82], %)
|
|> lineTo([0.46, -5.82], %)
|
||||||
|> lineTo([2, 3], %)
|
|> lineTo([2, 3], %)
|
||||||
show(mySketch001)
|
show(mySketch001)
|
||||||
|
`
|
||||||
|
expect(recast(modifiedAst)).toBe(expectedCode)
|
||||||
|
|
||||||
|
modifiedAst = addCloseToPipe({
|
||||||
|
node: ast,
|
||||||
|
programMemory,
|
||||||
|
pathToNode: [
|
||||||
|
['body', ''],
|
||||||
|
[0, 'index'],
|
||||||
|
['declarations', 'VariableDeclaration'],
|
||||||
|
[0, 'index'],
|
||||||
|
['init', 'VariableDeclarator'],
|
||||||
|
],
|
||||||
|
})
|
||||||
|
|
||||||
|
expectedCode = `const mySketch001 = startSketchAt([0, 0])
|
||||||
|
// |> rx(45, %)
|
||||||
|
|> lineTo([-1.59, -1.54], %)
|
||||||
|
|> lineTo([0.46, -5.82], %)
|
||||||
|
|> close(%)
|
||||||
|
show(mySketch001)
|
||||||
`
|
`
|
||||||
expect(recast(modifiedAst)).toBe(expectedCode)
|
expect(recast(modifiedAst)).toBe(expectedCode)
|
||||||
})
|
})
|
||||||
|
@ -947,13 +947,25 @@ interface CreateLineFnCallArgs {
|
|||||||
pathToNode: PathToNode
|
pathToNode: PathToNode
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function compareVec2Epsilon(
|
||||||
|
vec1: [number, number],
|
||||||
|
vec2: [number, number]
|
||||||
|
) {
|
||||||
|
const compareEpsilon = 0.015625 // or 2^-6
|
||||||
|
const xDifference = Math.abs(vec1[0] - vec2[0])
|
||||||
|
const yDifference = Math.abs(vec1[0] - vec2[0])
|
||||||
|
return xDifference < compareEpsilon && yDifference < compareEpsilon
|
||||||
|
}
|
||||||
|
|
||||||
export function addNewSketchLn({
|
export function addNewSketchLn({
|
||||||
node: _node,
|
node: _node,
|
||||||
programMemory: previousProgramMemory,
|
programMemory: previousProgramMemory,
|
||||||
to,
|
to,
|
||||||
fnName,
|
fnName,
|
||||||
pathToNode,
|
pathToNode,
|
||||||
}: Omit<CreateLineFnCallArgs, 'from'>): { modifiedAst: Program } {
|
}: Omit<CreateLineFnCallArgs, 'from'>): {
|
||||||
|
modifiedAst: Program
|
||||||
|
} {
|
||||||
const node = JSON.parse(JSON.stringify(_node))
|
const node = JSON.parse(JSON.stringify(_node))
|
||||||
const { add, updateArgs } = sketchLineHelperMap?.[fnName] || {}
|
const { add, updateArgs } = sketchLineHelperMap?.[fnName] || {}
|
||||||
if (!add || !updateArgs) throw new Error('not a sketch line helper')
|
if (!add || !updateArgs) throw new Error('not a sketch line helper')
|
||||||
@ -971,7 +983,6 @@ export function addNewSketchLn({
|
|||||||
|
|
||||||
const last = sketch.value[sketch.value.length - 1] || sketch.start
|
const last = sketch.value[sketch.value.length - 1] || sketch.start
|
||||||
const from = last.to
|
const from = last.to
|
||||||
|
|
||||||
return add({
|
return add({
|
||||||
node,
|
node,
|
||||||
previousProgramMemory,
|
previousProgramMemory,
|
||||||
@ -982,6 +993,29 @@ export function addNewSketchLn({
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function addCloseToPipe({
|
||||||
|
node,
|
||||||
|
pathToNode,
|
||||||
|
}: {
|
||||||
|
node: Program
|
||||||
|
programMemory: ProgramMemory
|
||||||
|
pathToNode: PathToNode
|
||||||
|
}) {
|
||||||
|
const _node = { ...node }
|
||||||
|
const closeExpression = createCallExpression('close', [
|
||||||
|
createPipeSubstitution(),
|
||||||
|
])
|
||||||
|
const pipeExpression = getNodeFromPath<PipeExpression>(
|
||||||
|
_node,
|
||||||
|
pathToNode,
|
||||||
|
'PipeExpression'
|
||||||
|
).node
|
||||||
|
if (pipeExpression.type !== 'PipeExpression')
|
||||||
|
throw new Error('not a pipe expression')
|
||||||
|
pipeExpression.body = [...pipeExpression.body, closeExpression]
|
||||||
|
return _node
|
||||||
|
}
|
||||||
|
|
||||||
export function replaceSketchLine({
|
export function replaceSketchLine({
|
||||||
node,
|
node,
|
||||||
programMemory,
|
programMemory,
|
||||||
|
Reference in New Issue
Block a user