initial set horz-vert distance constraint (#42)
inital set horz-vert distance constraint
This commit is contained in:
@ -3,6 +3,7 @@ import { extrudeSketch, sketchOnExtrudedFace } from './lang/modifyAst'
|
||||
import { getNodePathFromSourceRange } from './lang/queryAst'
|
||||
import { HorzVert } from './components/Toolbar/HorzVert'
|
||||
import { Equal } from './components/Toolbar/Equal'
|
||||
import { SetHorzDistance } from './components/Toolbar/SetHorzDistance'
|
||||
|
||||
export const Toolbar = () => {
|
||||
const {
|
||||
@ -156,6 +157,8 @@ export const Toolbar = () => {
|
||||
<HorzVert horOrVert="horizontal" />
|
||||
<HorzVert horOrVert="vertical" />
|
||||
<Equal />
|
||||
<SetHorzDistance horOrVert="setHorzDistance" />
|
||||
<SetHorzDistance horOrVert="setVertDistance" />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
97
src/components/Toolbar/SetHorzDistance.tsx
Normal file
97
src/components/Toolbar/SetHorzDistance.tsx
Normal file
@ -0,0 +1,97 @@
|
||||
import { useState, useEffect } from 'react'
|
||||
import { toolTips, useStore } from '../../useStore'
|
||||
import { Value, VariableDeclarator } from '../../lang/abstractSyntaxTree'
|
||||
import {
|
||||
getNodePathFromSourceRange,
|
||||
getNodeFromPath,
|
||||
} from '../../lang/queryAst'
|
||||
import { isSketchVariablesLinked } from '../../lang/std/sketchConstraints'
|
||||
import {
|
||||
TransformInfo,
|
||||
transformAstForSketchLines,
|
||||
getTransformInfos,
|
||||
} from '../../lang/std/sketchcombos'
|
||||
|
||||
export const SetHorzDistance = ({
|
||||
horOrVert,
|
||||
}: {
|
||||
horOrVert: 'setHorzDistance' | 'setVertDistance'
|
||||
}) => {
|
||||
const { guiMode, selectionRanges, ast, programMemory, updateAst } = useStore(
|
||||
(s) => ({
|
||||
guiMode: s.guiMode,
|
||||
ast: s.ast,
|
||||
updateAst: s.updateAst,
|
||||
selectionRanges: s.selectionRanges,
|
||||
programMemory: s.programMemory,
|
||||
})
|
||||
)
|
||||
const [enable, setEnable] = useState(false)
|
||||
const [transformInfos, setTransformInfos] = useState<TransformInfo[]>()
|
||||
useEffect(() => {
|
||||
if (!ast) return
|
||||
const paths = selectionRanges.map((selectionRange) =>
|
||||
getNodePathFromSourceRange(ast, selectionRange)
|
||||
)
|
||||
const nodes = paths.map(
|
||||
(pathToNode) => getNodeFromPath<Value>(ast, pathToNode).node
|
||||
)
|
||||
const varDecs = paths.map(
|
||||
(pathToNode) =>
|
||||
getNodeFromPath<VariableDeclarator>(
|
||||
ast,
|
||||
pathToNode,
|
||||
'VariableDeclarator'
|
||||
)?.node
|
||||
)
|
||||
const primaryLine = varDecs[0]
|
||||
const secondaryVarDecs = varDecs.slice(1)
|
||||
const isOthersLinkedToPrimary = secondaryVarDecs.every((secondary) =>
|
||||
isSketchVariablesLinked(secondary, primaryLine, ast)
|
||||
)
|
||||
const isAllTooltips = nodes.every(
|
||||
(node) =>
|
||||
node?.type === 'CallExpression' &&
|
||||
toolTips.includes(node.callee.name as any)
|
||||
)
|
||||
|
||||
const theTransforms = getTransformInfos(
|
||||
selectionRanges.slice(1),
|
||||
ast,
|
||||
horOrVert
|
||||
)
|
||||
setTransformInfos(theTransforms)
|
||||
|
||||
const _enableEqual =
|
||||
secondaryVarDecs.length === 1 &&
|
||||
isAllTooltips &&
|
||||
isOthersLinkedToPrimary &&
|
||||
theTransforms.every(Boolean)
|
||||
setEnable(_enableEqual)
|
||||
}, [guiMode, selectionRanges])
|
||||
if (guiMode.mode !== 'sketch') return null
|
||||
|
||||
return (
|
||||
<button
|
||||
onClick={() =>
|
||||
transformInfos &&
|
||||
ast &&
|
||||
updateAst(
|
||||
transformAstForSketchLines({
|
||||
ast,
|
||||
selectionRanges,
|
||||
transformInfos,
|
||||
programMemory,
|
||||
})?.modifiedAst
|
||||
)
|
||||
}
|
||||
className={`border m-1 px-1 rounded ${
|
||||
enable ? 'bg-gray-50 text-gray-800' : 'bg-gray-200 text-gray-400'
|
||||
}`}
|
||||
disabled={!enable}
|
||||
title="yo dawg"
|
||||
>
|
||||
{horOrVert}
|
||||
</button>
|
||||
)
|
||||
}
|
@ -89,12 +89,11 @@ export function createFirstArg(
|
||||
|
||||
export const lineTo: SketchLineHelper = {
|
||||
fn: (
|
||||
{ sourceRange, programMemory },
|
||||
{ sourceRange },
|
||||
data:
|
||||
| [number, number]
|
||||
| {
|
||||
to: [number, number]
|
||||
// name?: string
|
||||
tag?: string
|
||||
},
|
||||
previousSketch: SketchGroup
|
||||
@ -135,18 +134,38 @@ export const lineTo: SketchLineHelper = {
|
||||
value: [...sketchGroup.value, currentPath],
|
||||
}
|
||||
},
|
||||
add: ({ node, pathToNode, to }) => {
|
||||
add: ({
|
||||
node,
|
||||
pathToNode,
|
||||
to,
|
||||
createCallback,
|
||||
replaceExisting,
|
||||
referencedSegment,
|
||||
}) => {
|
||||
const _node = { ...node }
|
||||
const { node: pipe } = getNodeFromPath<PipeExpression>(
|
||||
_node,
|
||||
pathToNode,
|
||||
'PipeExpression'
|
||||
)
|
||||
const newLine = createCallExpression('lineTo', [
|
||||
createArrayExpression([createLiteral(to[0]), createLiteral(to[1])]),
|
||||
|
||||
const newVals: [Value, Value] = [
|
||||
createLiteral(roundOff(to[0], 2)),
|
||||
createLiteral(roundOff(to[1], 2)),
|
||||
]
|
||||
|
||||
const newLine = createCallback
|
||||
? createCallback(newVals, referencedSegment)
|
||||
: createCallExpression('lineTo', [
|
||||
createArrayExpression(newVals),
|
||||
createPipeSubstitution(),
|
||||
])
|
||||
const callIndex = getLastIndex(pathToNode)
|
||||
if (replaceExisting) {
|
||||
pipe.body[callIndex] = newLine
|
||||
} else {
|
||||
pipe.body = [...pipe.body, newLine]
|
||||
}
|
||||
return {
|
||||
modifiedAst: _node,
|
||||
pathToNode,
|
||||
@ -237,7 +256,6 @@ export const line: SketchLineHelper = {
|
||||
pathToNode,
|
||||
'PipeExpression'
|
||||
)
|
||||
if (!from) throw new Error('no from') // todo #29 remove
|
||||
const { node: varDec } = getNodeFromPath<VariableDeclarator>(
|
||||
_node,
|
||||
pathToNode,
|
||||
@ -431,7 +449,6 @@ export const xLine: SketchLineHelper = {
|
||||
add: ({ node, pathToNode, to, from, replaceExisting, createCallback }) => {
|
||||
const _node = { ...node }
|
||||
const getNode = getNodeFromPathCurry(_node, pathToNode)
|
||||
if (!from) throw new Error('no from') // todo #29 remove
|
||||
const { node: pipe } = getNode<PipeExpression>('PipeExpression')
|
||||
|
||||
const newVal = createLiteral(roundOff(to[0] - from[0], 2))
|
||||
@ -487,7 +504,6 @@ export const yLine: SketchLineHelper = {
|
||||
add: ({ node, pathToNode, to, from, replaceExisting, createCallback }) => {
|
||||
const _node = { ...node }
|
||||
const getNode = getNodeFromPathCurry(_node, pathToNode)
|
||||
if (!from) throw new Error('no from') // todo #29 remove
|
||||
const { node: pipe } = getNode<PipeExpression>('PipeExpression')
|
||||
const newVal = createLiteral(roundOff(to[1] - from[1], 2))
|
||||
const newLine = createCallback
|
||||
@ -577,7 +593,6 @@ export const angledLine: SketchLineHelper = {
|
||||
const getNode = getNodeFromPathCurry(_node, pathToNode)
|
||||
const { node: pipe } = getNode<PipeExpression>('PipeExpression')
|
||||
|
||||
if (!from) throw new Error('no from') // todo #29 remove
|
||||
const newAngleVal = createLiteral(roundOff(getAngle(from, to), 0))
|
||||
const newLengthVal = createLiteral(roundOff(getLength(from, to), 2))
|
||||
const newLine = createCallback
|
||||
@ -668,7 +683,6 @@ export const angledLineOfXLength: SketchLineHelper = {
|
||||
const variableName = varDec.id.name
|
||||
const sketch = previousProgramMemory?.root?.[variableName]
|
||||
if (sketch.type !== 'sketchGroup') throw new Error('not a sketchGroup')
|
||||
if (!from) throw new Error('no from') // todo #29 remove
|
||||
const angle = createLiteral(roundOff(getAngle(from, to), 0))
|
||||
const xLength = createLiteral(roundOff(Math.abs(from[0] - to[0]), 2) || 0.1)
|
||||
const newLine = createCallback
|
||||
@ -762,7 +776,6 @@ export const angledLineOfYLength: SketchLineHelper = {
|
||||
const variableName = varDec.id.name
|
||||
const sketch = previousProgramMemory?.root?.[variableName]
|
||||
if (sketch.type !== 'sketchGroup') throw new Error('not a sketchGroup')
|
||||
if (!from) throw new Error('no from') // todo #29 remove
|
||||
|
||||
const angle = createLiteral(roundOff(getAngle(from, to), 0))
|
||||
const yLength = createLiteral(roundOff(Math.abs(from[1] - to[1]), 2) || 0.1)
|
||||
@ -848,7 +861,6 @@ export const angledLineToX: SketchLineHelper = {
|
||||
pathToNode,
|
||||
'PipeExpression'
|
||||
)
|
||||
if (!from) throw new Error('no from') // todo #29 remove
|
||||
const angle = createLiteral(roundOff(getAngle(from, to), 0))
|
||||
const xArg = createLiteral(roundOff(to[0], 2))
|
||||
const newLine = createCallback
|
||||
@ -930,7 +942,6 @@ export const angledLineToY: SketchLineHelper = {
|
||||
pathToNode,
|
||||
'PipeExpression'
|
||||
)
|
||||
if (!from) throw new Error('no from') // todo #29 remove
|
||||
const angle = createLiteral(roundOff(getAngle(from, to), 0))
|
||||
const yArg = createLiteral(roundOff(to[1], 2))
|
||||
const newLine = createCallback
|
||||
@ -1067,6 +1078,7 @@ export function replaceSketchLine({
|
||||
to,
|
||||
from,
|
||||
createCallback,
|
||||
referencedSegment,
|
||||
}: {
|
||||
node: Program
|
||||
programMemory: ProgramMemory
|
||||
@ -1075,6 +1087,7 @@ export function replaceSketchLine({
|
||||
to: [number, number]
|
||||
from: [number, number]
|
||||
createCallback: TransformCallback
|
||||
referencedSegment?: Path
|
||||
}): { modifiedAst: Program } {
|
||||
if (!toolTips.includes(fnName)) throw new Error('not a tooltip')
|
||||
const _node = { ...node }
|
||||
@ -1085,6 +1098,7 @@ export function replaceSketchLine({
|
||||
node: _node,
|
||||
previousProgramMemory: programMemory,
|
||||
pathToNode: thePath,
|
||||
referencedSegment,
|
||||
to,
|
||||
from,
|
||||
replaceExisting: true,
|
||||
|
@ -33,6 +33,28 @@ export const segLen: InternalFn = (
|
||||
)
|
||||
}
|
||||
|
||||
function segEndFactory(which: 'x' | 'y'): InternalFn {
|
||||
return (_, segName: string, sketchGroup: SketchGroup): number => {
|
||||
const line = sketchGroup?.value.find((seg) => seg.name === segName)
|
||||
// maybe this should throw, but the language doesn't have a way to handle errors yet
|
||||
if (!line) return 0
|
||||
return which === 'x' ? line.to[0] : line.to[1]
|
||||
}
|
||||
}
|
||||
|
||||
export const segEndX: InternalFn = segEndFactory('x')
|
||||
export const segEndY: InternalFn = segEndFactory('y')
|
||||
|
||||
function lastSegFactory(which: 'x' | 'y'): InternalFn {
|
||||
return (_, sketchGroup: SketchGroup): number => {
|
||||
const lastLine = sketchGroup?.value[sketchGroup.value.length - 1]
|
||||
return which === 'x' ? lastLine.to[0] : lastLine.to[1]
|
||||
}
|
||||
}
|
||||
|
||||
export const lastSegX: InternalFn = lastSegFactory('x')
|
||||
export const lastSegY: InternalFn = lastSegFactory('y')
|
||||
|
||||
function angleToMatchLengthFactory(which: 'x' | 'y'): InternalFn {
|
||||
return (_, segName: string, to: number, sketchGroup: SketchGroup): number => {
|
||||
const isX = which === 'x'
|
||||
|
@ -5,9 +5,10 @@ import {
|
||||
getTransformInfos,
|
||||
transformAstForSketchLines,
|
||||
transformAstForHorzVert,
|
||||
ConstraintType,
|
||||
} from './sketchcombos'
|
||||
import { initPromise } from '../rust'
|
||||
import { Ranges, TooTip } from '../../useStore'
|
||||
import { TooTip } from '../../useStore'
|
||||
import { executor } from '../../lang/executor'
|
||||
import { recast } from '../../lang/recast'
|
||||
|
||||
@ -242,14 +243,6 @@ const part001 = startSketchAt([0, 0])
|
||||
|> angledLineToY([301, myVar], %) // select for vertical constraint 10
|
||||
show(part001)`
|
||||
it('It should transform horizontal lines the ast', () => {
|
||||
// const inputScript = `const myVar = 2
|
||||
// const part001 = startSketchAt([0, 0])
|
||||
// |> lineTo([1, 1], %)
|
||||
// |> line([-6.28, 1.4], %) // select for horizontal constraint 1
|
||||
// |> line([-1.07, myVar], %) // select for vertical constraint 1
|
||||
// |> line([myVar, 4.32], %) // select for horizontal constraint 2
|
||||
// |> line([6.35, -1.12], %) // select for vertical constraint 2
|
||||
// show(part001)`
|
||||
const expectModifiedScript = `const myVar = 2
|
||||
const myVar2 = 12
|
||||
const myVar3 = -10
|
||||
@ -348,3 +341,89 @@ show(part001)`
|
||||
expect(newCode).toBe(expectModifiedScript)
|
||||
})
|
||||
})
|
||||
|
||||
describe('testing transformAstForSketchLines for vertical and horizontal distance constraints', () => {
|
||||
describe('testing setHorzDistance for line', () => {
|
||||
const inputScript = `const myVar = 1
|
||||
const part001 = startSketchAt([0, 0])
|
||||
|> line([0.31, 1.67], %) // base selection
|
||||
|> line([0.45, 1.46], %)
|
||||
|> line([0.45, 1.46], %) // free
|
||||
|> line([myVar, 0.01], %) // xRelative
|
||||
|> line([0.7, myVar], %) // yRelative
|
||||
show(part001)`
|
||||
it('testing for free to horizontal and vertical distance', () => {
|
||||
const expectedHorizontalCode = helperThing(
|
||||
inputScript,
|
||||
['// base selection', '// free'],
|
||||
'setHorzDistance'
|
||||
)
|
||||
const expectedVerticalCode = helperThing(
|
||||
inputScript,
|
||||
['// base selection', '// free'],
|
||||
'setVertDistance'
|
||||
)
|
||||
expect(expectedHorizontalCode).toContain(
|
||||
`lineTo([segEndX('seg01', %) + 1.21, 4.59], %) // free`
|
||||
)
|
||||
expect(expectedVerticalCode).toContain(
|
||||
`lineTo([1.21, segEndY('seg01', %) + 4.59], %) // free`
|
||||
)
|
||||
})
|
||||
it('testing for xRelative to vertical distance', () => {
|
||||
const expectedCode = helperThing(
|
||||
inputScript,
|
||||
['// base selection', '// xRelative'],
|
||||
'setVertDistance'
|
||||
)
|
||||
expect(expectedCode).toContain(`|> lineTo([
|
||||
lastSegX(%) + myVar,
|
||||
segEndY('seg01', %) + 4.6
|
||||
], %) // xRelative`)
|
||||
})
|
||||
it('testing for yRelative to horizontal distance', () => {
|
||||
const expectedCode = helperThing(
|
||||
inputScript,
|
||||
['// base selection', '// yRelative'],
|
||||
'setHorzDistance'
|
||||
)
|
||||
expect(expectedCode).toContain(`|> lineTo([
|
||||
segEndX('seg01', %) + 2.91,
|
||||
lastSegY(%) + myVar
|
||||
], %) // yRelative`)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
function helperThing(
|
||||
inputScript: string,
|
||||
linesOfInterest: string[],
|
||||
constraint: ConstraintType
|
||||
): string {
|
||||
const ast = abstractSyntaxTree(lexer(inputScript))
|
||||
const selectionRanges = inputScript
|
||||
.split('\n')
|
||||
.filter((ln) =>
|
||||
linesOfInterest.some((lineOfInterest) => ln.includes(lineOfInterest))
|
||||
)
|
||||
.map((ln) => {
|
||||
const comment = ln.split('//')[1]
|
||||
const start = inputScript.indexOf('//' + comment) - 7
|
||||
return [start, start]
|
||||
}) as [number, number][]
|
||||
|
||||
const programMemory = executor(ast)
|
||||
const transformInfos = getTransformInfos(
|
||||
selectionRanges.slice(1),
|
||||
ast,
|
||||
constraint
|
||||
)
|
||||
|
||||
const newAst = transformAstForSketchLines({
|
||||
ast,
|
||||
selectionRanges,
|
||||
transformInfos,
|
||||
programMemory,
|
||||
})?.modifiedAst
|
||||
return recast(newAst)
|
||||
}
|
||||
|
@ -21,8 +21,9 @@ import {
|
||||
giveSketchFnCallTag,
|
||||
} from '../modifyAst'
|
||||
import { createFirstArg, getFirstArg, replaceSketchLine } from './sketch'
|
||||
import { ProgramMemory } from '../executor'
|
||||
import { Path, ProgramMemory } from '../executor'
|
||||
import { getSketchSegmentIndexFromSourceRange } from './sketchConstraints'
|
||||
import { roundOff } from '../../lib/utils'
|
||||
|
||||
type LineInputsType =
|
||||
| 'xAbsolute'
|
||||
@ -37,6 +38,8 @@ export type ConstraintType =
|
||||
| 'vertical'
|
||||
| 'horizontal'
|
||||
| 'equalangle'
|
||||
| 'setHorzDistance'
|
||||
| 'setVertDistance'
|
||||
|
||||
function createCallWrapper(
|
||||
a: TooTip,
|
||||
@ -54,7 +57,8 @@ export function replaceSketchCall(
|
||||
ast: Program,
|
||||
range: Range,
|
||||
transformTo: TooTip,
|
||||
createCallback: TransformCallback
|
||||
createCallback: TransformCallback,
|
||||
referenceSegName: string
|
||||
): { modifiedAst: Program } {
|
||||
const path = getNodePathFromSourceRange(ast, range)
|
||||
const getNode = getNodeFromPathCurry(ast, path)
|
||||
@ -65,11 +69,15 @@ export function replaceSketchCall(
|
||||
if (!sketchGroup || sketchGroup.type !== 'sketchGroup')
|
||||
throw new Error('not a sketch group')
|
||||
const seg = getSketchSegmentIndexFromSourceRange(sketchGroup, range)
|
||||
const referencedSegment = sketchGroup.value.find(
|
||||
(path) => path.name === referenceSegName
|
||||
)
|
||||
const { to, from } = seg
|
||||
const { modifiedAst } = replaceSketchLine({
|
||||
node: ast,
|
||||
programMemory,
|
||||
sourceRange: range,
|
||||
referencedSegment,
|
||||
fnName: transformTo || (callExp.callee.name as TooTip),
|
||||
to,
|
||||
from,
|
||||
@ -85,7 +93,7 @@ export type TransformInfo = {
|
||||
varValB: Value // y / length or x y for angledLineOfXlength etc
|
||||
referenceSegName: string
|
||||
tag?: Value
|
||||
}) => (args: [Value, Value]) => Value
|
||||
}) => (args: [Value, Value], referencedSegment?: Path) => Value
|
||||
}
|
||||
|
||||
type TransformMap = {
|
||||
@ -163,6 +171,57 @@ const getAngleLengthSign = (arg: Value, legAngleVal: BinaryPart) => {
|
||||
return normalisedAngle > 90 ? createUnaryExpression(legAngleVal) : legAngleVal
|
||||
}
|
||||
|
||||
const setHorzVertDistanceCreateNode =
|
||||
(isX = true): TransformInfo['createNode'] =>
|
||||
({ referenceSegName, tag }) => {
|
||||
return (args, referencedSegment) => {
|
||||
const makeBinExp = (index: 0 | 1) => {
|
||||
const arg = getArgLiteralVal(args?.[index])
|
||||
return createBinaryExpression([
|
||||
createSegEnd(referenceSegName, isX),
|
||||
'+',
|
||||
createLiteral(
|
||||
roundOff(arg - (referencedSegment?.to?.[index] || 0), 2)
|
||||
),
|
||||
])
|
||||
}
|
||||
return createCallWrapper(
|
||||
'lineTo',
|
||||
isX ? [makeBinExp(0), args[1]] : [args[0], makeBinExp(1)],
|
||||
tag
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
const setHorzVertDistanceConstraintLineCreateNode =
|
||||
(isX: boolean): TransformInfo['createNode'] =>
|
||||
({ referenceSegName, tag, varValA, varValB }) => {
|
||||
const varVal = (isX ? varValB : varValA) as BinaryPart
|
||||
const varValBinExp = createBinaryExpression([
|
||||
createLastSeg(!isX),
|
||||
'+',
|
||||
varVal,
|
||||
])
|
||||
|
||||
return (args, referencedSegment) => {
|
||||
const makeBinExp = (index: 0 | 1) => {
|
||||
const arg = getArgLiteralVal(args?.[index])
|
||||
return createBinaryExpression([
|
||||
createSegEnd(referenceSegName, isX),
|
||||
'+',
|
||||
createLiteral(
|
||||
roundOff(arg - (referencedSegment?.to?.[index] || 0), 2)
|
||||
),
|
||||
])
|
||||
}
|
||||
return createCallWrapper(
|
||||
'lineTo',
|
||||
isX ? [makeBinExp(0), varValBinExp] : [varValBinExp, makeBinExp(1)],
|
||||
tag
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
const transformMap: TransformMap = {
|
||||
line: {
|
||||
xRelative: {
|
||||
@ -188,6 +247,10 @@ const transformMap: TransformMap = {
|
||||
() =>
|
||||
createCallWrapper('xLine', varValA, tag),
|
||||
},
|
||||
setVertDistance: {
|
||||
tooltip: 'lineTo',
|
||||
createNode: setHorzVertDistanceConstraintLineCreateNode(false),
|
||||
},
|
||||
},
|
||||
yRelative: {
|
||||
equalLength: {
|
||||
@ -212,6 +275,10 @@ const transformMap: TransformMap = {
|
||||
() =>
|
||||
createCallWrapper('yLine', varValB, tag),
|
||||
},
|
||||
setHorzDistance: {
|
||||
tooltip: 'lineTo',
|
||||
createNode: setHorzVertDistanceConstraintLineCreateNode(true),
|
||||
},
|
||||
},
|
||||
free: {
|
||||
equalLength: {
|
||||
@ -232,6 +299,14 @@ const transformMap: TransformMap = {
|
||||
(args) =>
|
||||
createCallWrapper('yLine', args[1], tag),
|
||||
},
|
||||
setHorzDistance: {
|
||||
tooltip: 'lineTo',
|
||||
createNode: setHorzVertDistanceCreateNode(true),
|
||||
},
|
||||
setVertDistance: {
|
||||
tooltip: 'lineTo',
|
||||
createNode: setHorzVertDistanceCreateNode(false),
|
||||
},
|
||||
},
|
||||
},
|
||||
lineTo: {
|
||||
@ -792,7 +867,8 @@ export function transformAstForSketchLines({
|
||||
referenceSegName: tag,
|
||||
varValA,
|
||||
varValB,
|
||||
})
|
||||
}),
|
||||
tag
|
||||
)
|
||||
node = modifiedAst
|
||||
})
|
||||
@ -837,7 +913,8 @@ export function transformAstForHorzVert({
|
||||
varValA,
|
||||
varValB,
|
||||
tag,
|
||||
})
|
||||
}),
|
||||
tag?.type === 'Literal' ? String(tag.value) : ''
|
||||
)
|
||||
node = modifiedAst
|
||||
})
|
||||
@ -850,3 +927,20 @@ function createSegLen(referenceSegName: string): Value {
|
||||
createPipeSubstitution(),
|
||||
])
|
||||
}
|
||||
|
||||
function createSegEnd(referenceSegName: string, isX: boolean): CallExpression {
|
||||
return createCallExpression(isX ? 'segEndX' : 'segEndY', [
|
||||
createLiteral(referenceSegName),
|
||||
createPipeSubstitution(),
|
||||
])
|
||||
}
|
||||
|
||||
function createLastSeg(isX: boolean): CallExpression {
|
||||
return createCallExpression(isX ? 'lastSegX' : 'lastSegY', [
|
||||
createPipeSubstitution(),
|
||||
])
|
||||
}
|
||||
|
||||
function getArgLiteralVal(arg: Value): number {
|
||||
return arg?.type === 'Literal' ? Number(arg.value) : 0
|
||||
}
|
||||
|
@ -17,6 +17,10 @@ import {
|
||||
segLen,
|
||||
angleToMatchLengthX,
|
||||
angleToMatchLengthY,
|
||||
segEndX,
|
||||
segEndY,
|
||||
lastSegX,
|
||||
lastSegY,
|
||||
} from './sketchConstraints'
|
||||
import { extrude, getExtrudeWallTransform } from './extrude'
|
||||
import { Quaternion, Vector3 } from 'three'
|
||||
@ -100,6 +104,10 @@ export const internalFns: { [key in InternalFnNames]: InternalFn } = {
|
||||
legLen,
|
||||
legAngX,
|
||||
legAngY,
|
||||
segEndX,
|
||||
segEndY,
|
||||
lastSegX,
|
||||
lastSegY,
|
||||
segLen,
|
||||
angleToMatchLengthX,
|
||||
angleToMatchLengthY,
|
||||
|
@ -24,6 +24,10 @@ export type InternalFnNames =
|
||||
| 'legLen'
|
||||
| 'legAngX'
|
||||
| 'legAngY'
|
||||
| 'segEndX'
|
||||
| 'segEndY'
|
||||
| 'lastSegX'
|
||||
| 'lastSegY'
|
||||
| 'segLen'
|
||||
| 'angleToMatchLengthX'
|
||||
| 'angleToMatchLengthY'
|
||||
@ -52,7 +56,8 @@ export interface ModifyAstBase {
|
||||
|
||||
interface addCall extends ModifyAstBase {
|
||||
to: [number, number]
|
||||
from?: [number, number]
|
||||
from: [number, number]
|
||||
referencedSegment?: Path
|
||||
replaceExisting?: boolean
|
||||
createCallback?: TransformCallback // TODO: #29 probably should not be optional
|
||||
}
|
||||
@ -62,7 +67,10 @@ interface updateArgs extends ModifyAstBase {
|
||||
to: [number, number]
|
||||
}
|
||||
|
||||
export type TransformCallback = (args: [Value, Value]) => Value
|
||||
export type TransformCallback = (
|
||||
args: [Value, Value],
|
||||
referencedSegment?: Path
|
||||
) => Value
|
||||
|
||||
export type SketchCallTransfromMap = {
|
||||
[key in TooTip]: TransformCallback
|
||||
|
Reference in New Issue
Block a user