big refactor of var values for astMods

This commit is contained in:
Kurt Hutten Irev-Dev
2024-09-07 09:04:07 +10:00
parent 72e522dd51
commit 94b0510521
11 changed files with 1196 additions and 491 deletions

View File

@ -40,7 +40,6 @@ import { InstanceProps, create } from 'react-modal-promise'
import { executeAst } from 'lang/langHelpers'
import {
deleteSegmentFromPipeExpression,
makeRemoveSingleConstraintInput,
removeSingleConstraintInfo,
} from 'lang/modifyAst'
import { ActionButton } from 'components/ActionButton'
@ -515,6 +514,11 @@ const ConstraintSymbol = ({
displayName: 'Intersection Offset',
iconName: 'intersection-offset',
},
radius: {
varName: 'radius',
displayName: 'Radius',
iconName: 'dimension',
},
// implicit constraints
vertical: {
@ -605,13 +609,10 @@ const ConstraintSymbol = ({
if (trap(_node1)) return Promise.reject(_node1)
const shallowPath = _node1.shallowPath
const input = makeRemoveSingleConstraintInput(
argPosition,
shallowPath
)
if (!input || !context.sketchDetails) return
if (!context.sketchDetails || !argPosition) return
const transform = removeSingleConstraintInfo(
input,
shallowPath,
argPosition,
kclManager.ast,
kclManager.programMemory
)

View File

@ -89,6 +89,7 @@ import {
createArrayExpression,
createCallExpressionStdLib,
createLiteral,
createObjectExpression,
createPipeExpression,
createPipeSubstitution,
findUniqueName,
@ -108,6 +109,7 @@ import { getThemeColorForThreeJs } from 'lib/theme'
import { err, trap } from 'lib/trap'
import { CSS2DObject } from 'three/examples/jsm/renderers/CSS2DRenderer'
import { Point3d } from 'wasm-lib/kcl/bindings/Point3d'
import { c } from 'vite/dist/node/types.d-aGj9QkWt'
type DraftSegment = 'line' | 'tangentialArcTo'
@ -665,8 +667,11 @@ export class SceneEntities {
const mod = addNewSketchLn({
node: _ast,
programMemory: kclManager.programMemory,
to: [lastSeg.to[0], lastSeg.to[1]],
from: [lastSeg.to[0], lastSeg.to[1]],
input: {
type: 'straight-segment',
to: [lastSeg.to[0], lastSeg.to[1]],
from: [lastSeg.to[0], lastSeg.to[1]],
},
fnName: segmentName,
pathToNode: sketchPathToNode,
})
@ -736,8 +741,11 @@ export class SceneEntities {
const tmp = addNewSketchLn({
node: kclManager.ast,
programMemory: kclManager.programMemory,
to: [intersection2d.x, intersection2d.y],
from: [lastSegment.to[0], lastSegment.to[1]],
input: {
type: 'straight-segment',
to: [intersection2d.x, intersection2d.y],
from: [lastSegment.to[0], lastSegment.to[1]],
},
fnName:
lastSegment.type === 'TangentialArcTo'
? 'tangentialArcTo'
@ -962,11 +970,13 @@ export class SceneEntities {
startSketchOn[0].init = createPipeExpression([
startSketchOnInit,
createCallExpressionStdLib('circle', [
createArrayExpression([
createLiteral(roundOff(circleCenter[0])),
createLiteral(roundOff(circleCenter[1])),
]),
createLiteral(1),
createObjectExpression({
center: createArrayExpression([
createLiteral(roundOff(circleCenter[0])),
createLiteral(roundOff(circleCenter[1])),
]),
radius: createLiteral(1),
}),
createPipeSubstitution(),
]),
])
@ -1147,8 +1157,11 @@ export class SceneEntities {
const mod = addNewSketchLn({
node: kclManager.ast,
programMemory: kclManager.programMemory,
to: [intersectionPoint.twoD.x, intersectionPoint.twoD.y],
from: [prevSegment.from[0], prevSegment.from[1]],
input: {
type: 'straight-segment',
to: [intersectionPoint.twoD.x, intersectionPoint.twoD.y],
from: [prevSegment.from[0], prevSegment.from[1]],
},
// TODO assuming it's always a straight segments being added
// as this is easiest, and we'll need to add "tabbing" behavior
// to support other segment types
@ -1293,41 +1306,55 @@ export class SceneEntities {
modded = updateStartProfileAtArgs({
node: modifiedAst,
pathToNode,
to: dragTo,
from,
input: {
type: 'straight-segment',
to: dragTo,
from,
},
previousProgramMemory: kclManager.programMemory,
})
} else if (group.name === CIRCLE_SEGMENT && subGroup?.name === ARROWHEAD) {
// is dragging the radius handle
modded = changeCircleArguments(
modded = changeSketchArguments(
modifiedAst,
kclManager.programMemory,
getNodePathFromSourceRange(modifiedAst, [node.start, node.end]),
group.userData.center,
Math.sqrt(
(group.userData.center[0] - dragTo[0]) ** 2 +
(group.userData.center[0] - dragTo[0]) ** 2
)
[node.start, node.end],
{
type: 'arc-segment',
from,
center: group.userData.center,
radius: Math.sqrt(
(group.userData.center[0] - dragTo[0]) ** 2 +
(group.userData.center[0] - dragTo[0]) ** 2
),
}
)
} else if (
group.name === CIRCLE_SEGMENT &&
subGroup?.name === CIRCLE_CENTER_HANDLE
) {
// is dragging the center handle
modded = changeCircleArguments(
modded = changeSketchArguments(
modifiedAst,
kclManager.programMemory,
getNodePathFromSourceRange(modifiedAst, [node.start, node.end]),
dragTo,
group.userData.radius
[node.start, node.end],
{
type: 'arc-segment',
from,
center: dragTo,
radius: group.userData.radius,
}
)
} else {
modded = changeSketchArguments(
modifiedAst,
kclManager.programMemory,
[node.start, node.end],
dragTo,
from
{
type: 'straight-segment',
from,
to: dragTo,
}
)
}
if (trap(modded)) return
@ -1683,7 +1710,7 @@ export class SceneEntities {
arrowGroup,
group,
isHandlesVisible,
from,
from: to,
to: [center[0], center[1]],
angle,
})

View File

@ -24,11 +24,9 @@ export type ToolTip =
| 'yLineTo'
| 'angledLineThatIntersects'
| 'tangentialArcTo'
| 'circle'
export const toolTips = [
'sketch_line',
'move',
// original tooltips
export const toolTips: Array<ToolTip> = [
'line',
'lineTo',
'angledLine',
@ -42,7 +40,7 @@ export const toolTips = [
'yLineTo',
'angledLineThatIntersects',
'tangentialArcTo',
] as any as ToolTip[]
]
export async function executeAst({
ast,

View File

@ -20,6 +20,7 @@ import {
import { enginelessExecutor } from '../lib/testHelpers'
import { findUsesOfTagInPipe, getNodePathFromSourceRange } from './queryAst'
import { err } from 'lib/trap'
import { SimplifiedVarValue, VarValueKeys } from './std/stdTypes'
beforeAll(async () => {
await initPromise
@ -638,11 +639,21 @@ describe('Testing removeSingleConstraintInfo', () => {
code.indexOf(lineOfInterest) + lineOfInterest.length,
]
const pathToNode = getNodePathFromSourceRange(ast, range)
let argPosition: SimplifiedVarValue
if (key === 'arrayIndex' && typeof value === 'number') {
argPosition = { type: 'arrayItem', argIndex: 0, index: value ? 0 : 1 }
} else if (key === 'objectProperty' && typeof value === 'string') {
argPosition = {
type: 'objectProperty',
key: value as VarValueKeys,
argIndex: 0,
}
} else {
throw new Error('argPosition is undefined')
}
const mod = removeSingleConstraintInfo(
{
pathToCallExp: pathToNode,
[key]: value,
},
pathToNode,
argPosition,
ast,
programMemory
)
@ -675,12 +686,22 @@ describe('Testing removeSingleConstraintInfo', () => {
code.indexOf(lineOfInterest) + 1,
code.indexOf(lineOfInterest) + lineOfInterest.length,
]
let argPosition: SimplifiedVarValue
if (key === 'arrayIndex' && typeof value === 'number') {
argPosition = { type: 'arrayItem', argIndex: 0, index: value ? 0 : 1 }
} else if (key === 'objectProperty' && typeof value === 'string') {
argPosition = {
type: 'objectProperty',
key: value as VarValueKeys,
argIndex: 0,
}
} else {
throw new Error('argPosition is undefined')
}
const pathToNode = getNodePathFromSourceRange(ast, range)
const mod = removeSingleConstraintInfo(
{
pathToCallExp: pathToNode,
[key]: value,
},
pathToNode,
argPosition,
ast,
programMemory
)

View File

@ -38,7 +38,7 @@ import {
import { DefaultPlaneStr } from 'clientSideScene/sceneEntities'
import { isOverlap, roundOff } from 'lib/utils'
import { KCL_DEFAULT_CONSTANT_PREFIXES } from 'lib/constants'
import { ConstrainInfo } from './std/stdTypes'
import { SimplifiedVarValue } from './std/stdTypes'
import { TagDeclarator } from 'wasm-lib/kcl/bindings/TagDeclarator'
import { Models } from '@kittycad/lib'
@ -799,15 +799,10 @@ export function deleteSegmentFromPipeExpression(
)
if (!constraintInfo) return
const input = makeRemoveSingleConstraintInput(
constraintInfo.argPosition,
callExp.shallowPath
)
if (!input) return
if (!constraintInfo.argPosition) return
const transform = removeSingleConstraintInfo(
{
...input,
},
callExp.shallowPath,
constraintInfo.argPosition,
_modifiedAst,
programMemory
)
@ -834,37 +829,9 @@ export function deleteSegmentFromPipeExpression(
return _modifiedAst
}
export function makeRemoveSingleConstraintInput(
argPosition: ConstrainInfo['argPosition'],
pathToNode: PathToNode
): Parameters<typeof removeSingleConstraintInfo>[0] | false {
return argPosition?.type === 'singleValue'
? {
pathToCallExp: pathToNode,
}
: argPosition?.type === 'arrayItem'
? {
pathToCallExp: pathToNode,
arrayIndex: argPosition.index,
}
: argPosition?.type === 'objectProperty'
? {
pathToCallExp: pathToNode,
objectProperty: argPosition.key,
}
: false
}
export function removeSingleConstraintInfo(
{
pathToCallExp,
arrayIndex,
objectProperty,
}: {
pathToCallExp: PathToNode
arrayIndex?: number
objectProperty?: string
},
pathToCallExp: PathToNode,
varValue: SimplifiedVarValue,
ast: Program,
programMemory: ProgramMemory
):
@ -875,8 +842,7 @@ export function removeSingleConstraintInfo(
| false {
const transform = removeSingleConstraint({
pathToCallExp,
arrayIndex,
objectProperty,
inputDetails: varValue,
ast,
})
if (!transform) return false

View File

@ -16,6 +16,7 @@ import {
VariableDeclaration,
VariableDeclarator,
sketchGroupFromKclValue,
ObjectExpression,
} from './wasm'
import { createIdentifier, splitPathAtLastIndex } from './modifyAst'
import { getSketchSegmentFromSourceRange } from './std/sketchConstraints'
@ -934,3 +935,12 @@ export function hasExtrudableGeometry(ast: Program) {
})
return Object.keys(theMap).length > 0
}
export function getObjExpProperty(
node: ObjectExpression,
propName: string
): { exp: Expr; index: number } | null {
const index = node.properties.findIndex(({ key }) => key.name === propName)
if (index === -1) return null
return { exp: node.properties[index].value, index }
}

View File

@ -123,8 +123,11 @@ describe('testing changeSketchArguments', () => {
ast,
programMemory,
[sourceStart, sourceStart + lineToChange.length],
[2, 3],
[0, 0]
{
type: 'straight-segment',
from: [0, 0],
to: [2, 3],
}
)
if (err(changeSketchArgsRetVal)) return changeSketchArgsRetVal
expect(recast(changeSketchArgsRetVal.modifiedAst)).toBe(expectedCode)
@ -150,8 +153,11 @@ const mySketch001 = startSketchOn('XY')
const newSketchLnRetVal = addNewSketchLn({
node: ast,
programMemory,
to: [2, 3],
from: [0, 0],
input: {
type: 'straight-segment',
from: [0, 0],
to: [2, 3],
},
fnName: 'lineTo',
pathToNode: [
['body', ''],

File diff suppressed because it is too large Load Diff

View File

@ -43,6 +43,16 @@ export function getSketchSegmentFromSourceRange(
index: number
}
| Error {
const lineIndex = sketchGroup.value.findIndex(
({ __geoMeta: { sourceRange } }: Path) =>
sourceRange[0] <= rangeStart && sourceRange[1] >= rangeEnd
)
const line = sketchGroup.value[lineIndex]
if (line)
return {
segment: line,
index: lineIndex,
}
const startSourceRange = sketchGroup.start?.__geoMeta.sourceRange
if (
startSourceRange &&
@ -51,17 +61,7 @@ export function getSketchSegmentFromSourceRange(
sketchGroup.start
)
return { segment: { ...sketchGroup.start, type: 'Base' }, index: -1 }
const lineIndex = sketchGroup.value.findIndex(
({ __geoMeta: { sourceRange } }: Path) =>
sourceRange[0] <= rangeStart && sourceRange[1] >= rangeEnd
)
const line = sketchGroup.value[lineIndex]
if (!line) return new Error('could not find matching line')
return {
segment: line,
index: lineIndex,
}
return new Error('could not find matching segment')
}
export function isSketchVariablesLinked(

File diff suppressed because it is too large Load Diff

View File

@ -37,9 +37,36 @@ export interface AddTagInfo {
pathToNode: PathToNode
}
interface addCall extends ModifyAstBase {
to: [number, number]
/** Inputs for all straight segments, to and from are absolute values, as this gives a
* consistent base that can be converted to all of the line, angledLine, etc segment types
* One notable exception to "straight segment" is that tangentialArcTo is included in this
* Input type since it too only takes x-y values and is able to get extra info it needs
* to be tangential from the previous segment */
interface StraightSegmentInput {
type: 'straight-segment'
from: [number, number]
to: [number, number]
}
/** Inputs for arcs, excluding tangentialArcTo for reasons explain in
* the @straightSegmentInput comment */
interface ArcSegmentInput {
type: 'arc-segment'
from: [number, number]
center: [number, number]
radius: number
}
/**
* SegmentInputs is a union type that can be either a StraightSegmentInput or an ArcSegmentInput.
*
* - StraightSegmentInput: Represents a straight segment with a starting point (from) and an ending point (to).
* - ArcSegmentInput: Represents an arc segment with a starting point (from), a center point, and a radius.
*/
export type SegmentInputs = StraightSegmentInput | ArcSegmentInput
interface addCall extends ModifyAstBase {
input: SegmentInputs
referencedSegment?: Path
replaceExisting?: boolean
createCallback?: TransformCallback // TODO: #29 probably should not be optional
@ -48,35 +75,54 @@ interface addCall extends ModifyAstBase {
}
interface updateArgs extends ModifyAstBase {
from: [number, number]
to: [number, number]
input: SegmentInputs
}
export type VarValueKeys = 'angle' | 'offset' | 'length' | 'to' | 'intersectTag'
export type VarValueKeys =
| 'angle'
| 'offset'
| 'length'
| 'to'
| 'intersectTag'
| 'radius'
| 'center'
export interface SingleValueInput<T> {
type: 'singleValue'
argType: LineInputsType
argType: LineInputsType | 'radius'
value: T
argIndex: number
}
export interface ArrayItemInput<T> {
type: 'arrayItem'
index: 0 | 1
argType: LineInputsType
argType: LineInputsType | 'radius'
value: T
argIndex: number
}
export interface ObjectPropertyInput<T> {
type: 'objectProperty'
key: VarValueKeys
argType: LineInputsType
argType: LineInputsType | 'radius'
value: T
argIndex: number
}
export interface ArrayOrObjItemInput<T> {
type: 'arrayOrObjItem'
key: VarValueKeys
index: 0 | 1
argType: LineInputsType
argType: LineInputsType | 'radius'
value: T
argIndex: number
}
export interface ObjectPropertyArrayInput<T> {
type: 'objectPropertyArray'
key: VarValueKeys
argType: LineInputsType | 'radius'
index: 0 | 1
value: T
argIndex: number
}
export type _VarValue<T> =
@ -84,6 +130,7 @@ export type _VarValue<T> =
| ArrayItemInput<T>
| ObjectPropertyInput<T>
| ArrayOrObjItemInput<T>
| ObjectPropertyArrayInput<T>
export type VarValue = _VarValue<Expr>
export type RawValue = _VarValue<Literal>
@ -91,16 +138,25 @@ export type RawValue = _VarValue<Literal>
export type VarValues = Array<VarValue>
export type RawValues = Array<RawValue>
type SimplifiedVarValue =
export type SimplifiedVarValue =
| {
type: 'singleValue'
argIndex: number
}
| { type: 'arrayItem'; index: 0 | 1; argIndex: number }
| { type: 'objectProperty'; key: VarValueKeys; argIndex: number }
| {
type: 'arrayInObject'
key: VarValueKeys
index: 0 | 1
}
| { type: 'arrayItem'; index: 0 | 1 }
| { type: 'objectProperty'; key: VarValueKeys }
export type TransformCallback = (
args: [Expr, Expr],
literalValues: RawValues,
// args: Array<Expr>,
inputs: {
varExpression: Expr
varDetails: VarValue
}[],
referencedSegment?: Path
) => {
callExp: Expr
@ -109,7 +165,12 @@ export type TransformCallback = (
export interface ConstrainInfo {
stdLibFnName: ToolTip
type: LineInputsType | 'vertical' | 'horizontal' | 'tangentialWithPrevious'
type:
| LineInputsType
| 'vertical'
| 'horizontal'
| 'tangentialWithPrevious'
| 'radius'
isConstrained: boolean
sourceRange: SourceRange
pathToNode: PathToNode