add Equal angle constraint + more cases for existing constraints (#69)
* add more setLength and horz vert distance constraints * rename equal to equalLength * Add equalAngle constraint
This commit is contained in:
@ -2,7 +2,8 @@ import { useStore, toolTips } from './useStore'
|
|||||||
import { extrudeSketch, sketchOnExtrudedFace } from './lang/modifyAst'
|
import { extrudeSketch, sketchOnExtrudedFace } from './lang/modifyAst'
|
||||||
import { getNodePathFromSourceRange } from './lang/queryAst'
|
import { getNodePathFromSourceRange } from './lang/queryAst'
|
||||||
import { HorzVert } from './components/Toolbar/HorzVert'
|
import { HorzVert } from './components/Toolbar/HorzVert'
|
||||||
import { Equal } from './components/Toolbar/Equal'
|
import { EqualLength } from './components/Toolbar/EqualLength'
|
||||||
|
import { EqualAngle } from './components/Toolbar/EqualAngle'
|
||||||
import { SetHorzDistance } from './components/Toolbar/SetHorzDistance'
|
import { SetHorzDistance } from './components/Toolbar/SetHorzDistance'
|
||||||
import { SetAngleLength } from './components/Toolbar/SetAngleLength'
|
import { SetAngleLength } from './components/Toolbar/SetAngleLength'
|
||||||
|
|
||||||
@ -157,7 +158,8 @@ export const Toolbar = () => {
|
|||||||
<br></br>
|
<br></br>
|
||||||
<HorzVert horOrVert="horizontal" />
|
<HorzVert horOrVert="horizontal" />
|
||||||
<HorzVert horOrVert="vertical" />
|
<HorzVert horOrVert="vertical" />
|
||||||
<Equal />
|
<EqualLength />
|
||||||
|
<EqualAngle />
|
||||||
<SetHorzDistance horOrVert="setHorzDistance" />
|
<SetHorzDistance horOrVert="setHorzDistance" />
|
||||||
<SetHorzDistance horOrVert="setVertDistance" />
|
<SetHorzDistance horOrVert="setVertDistance" />
|
||||||
<SetAngleLength angleOrLength="setAngle" />
|
<SetAngleLength angleOrLength="setAngle" />
|
||||||
|
93
src/components/Toolbar/EqualAngle.tsx
Normal file
93
src/components/Toolbar/EqualAngle.tsx
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
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,
|
||||||
|
transformSecondarySketchLinesTagFirst,
|
||||||
|
getTransformInfos,
|
||||||
|
} from '../../lang/std/sketchcombos'
|
||||||
|
|
||||||
|
export const EqualAngle = () => {
|
||||||
|
const { guiMode, selectionRanges, ast, programMemory, updateAst } = useStore(
|
||||||
|
(s) => ({
|
||||||
|
guiMode: s.guiMode,
|
||||||
|
ast: s.ast,
|
||||||
|
updateAst: s.updateAst,
|
||||||
|
selectionRanges: s.selectionRanges,
|
||||||
|
programMemory: s.programMemory,
|
||||||
|
})
|
||||||
|
)
|
||||||
|
const [enableEqual, setEnableEqual] = 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,
|
||||||
|
'equalAngle'
|
||||||
|
)
|
||||||
|
setTransformInfos(theTransforms)
|
||||||
|
|
||||||
|
const _enableEqual =
|
||||||
|
!!secondaryVarDecs.length &&
|
||||||
|
isAllTooltips &&
|
||||||
|
isOthersLinkedToPrimary &&
|
||||||
|
theTransforms.every(Boolean)
|
||||||
|
setEnableEqual(_enableEqual)
|
||||||
|
}, [guiMode, selectionRanges])
|
||||||
|
if (guiMode.mode !== 'sketch') return null
|
||||||
|
|
||||||
|
return (
|
||||||
|
<button
|
||||||
|
onClick={() =>
|
||||||
|
transformInfos &&
|
||||||
|
ast &&
|
||||||
|
updateAst(
|
||||||
|
transformSecondarySketchLinesTagFirst({
|
||||||
|
ast,
|
||||||
|
selectionRanges,
|
||||||
|
transformInfos,
|
||||||
|
programMemory,
|
||||||
|
})?.modifiedAst
|
||||||
|
)
|
||||||
|
}
|
||||||
|
className={`border m-1 px-1 rounded text-xs ${
|
||||||
|
enableEqual ? 'bg-gray-50 text-gray-800' : 'bg-gray-200 text-gray-400'
|
||||||
|
}`}
|
||||||
|
disabled={!enableEqual}
|
||||||
|
title="yo dawg"
|
||||||
|
>
|
||||||
|
EqualAngle
|
||||||
|
</button>
|
||||||
|
)
|
||||||
|
}
|
@ -12,7 +12,7 @@ import {
|
|||||||
getTransformInfos,
|
getTransformInfos,
|
||||||
} from '../../lang/std/sketchcombos'
|
} from '../../lang/std/sketchcombos'
|
||||||
|
|
||||||
export const Equal = () => {
|
export const EqualLength = () => {
|
||||||
const { guiMode, selectionRanges, ast, programMemory, updateAst } = useStore(
|
const { guiMode, selectionRanges, ast, programMemory, updateAst } = useStore(
|
||||||
(s) => ({
|
(s) => ({
|
||||||
guiMode: s.guiMode,
|
guiMode: s.guiMode,
|
||||||
@ -87,7 +87,7 @@ export const Equal = () => {
|
|||||||
disabled={!enableEqual}
|
disabled={!enableEqual}
|
||||||
title="yo dawg"
|
title="yo dawg"
|
||||||
>
|
>
|
||||||
Equal
|
EqualLength
|
||||||
</button>
|
</button>
|
||||||
)
|
)
|
||||||
}
|
}
|
@ -265,6 +265,7 @@ export const line: SketchLineHelper = {
|
|||||||
to,
|
to,
|
||||||
from,
|
from,
|
||||||
replaceExisting,
|
replaceExisting,
|
||||||
|
referencedSegment,
|
||||||
createCallback,
|
createCallback,
|
||||||
}) => {
|
}) => {
|
||||||
const _node = { ...node }
|
const _node = { ...node }
|
||||||
@ -285,19 +286,25 @@ export const line: SketchLineHelper = {
|
|||||||
const newXVal = createLiteral(roundOff(to[0] - from[0], 2))
|
const newXVal = createLiteral(roundOff(to[0] - from[0], 2))
|
||||||
const newYVal = createLiteral(roundOff(to[1] - from[1], 2))
|
const newYVal = createLiteral(roundOff(to[1] - from[1], 2))
|
||||||
|
|
||||||
const newLine = createCallback
|
if (replaceExisting && createCallback) {
|
||||||
? createCallback([newXVal, newYVal]).callExp
|
const callIndex = getLastIndex(pathToNode)
|
||||||
: createCallExpression('line', [
|
const { callExp, valueUsedInTransform } = createCallback(
|
||||||
createArrayExpression([newXVal, newYVal]),
|
[newXVal, newYVal],
|
||||||
createPipeSubstitution(),
|
referencedSegment
|
||||||
])
|
)
|
||||||
const callIndex = getLastIndex(pathToNode)
|
pipe.body[callIndex] = callExp
|
||||||
if (replaceExisting) {
|
return {
|
||||||
pipe.body[callIndex] = newLine
|
modifiedAst: _node,
|
||||||
} else {
|
pathToNode,
|
||||||
pipe.body = [...pipe.body, newLine]
|
valueUsedInTransform,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const callExp = createCallExpression('line', [
|
||||||
|
createArrayExpression([newXVal, newYVal]),
|
||||||
|
createPipeSubstitution(),
|
||||||
|
])
|
||||||
|
pipe.body = [...pipe.body, callExp]
|
||||||
return {
|
return {
|
||||||
modifiedAst: _node,
|
modifiedAst: _node,
|
||||||
pathToNode,
|
pathToNode,
|
||||||
@ -369,16 +376,22 @@ export const xLineTo: SketchLineHelper = {
|
|||||||
const { node: pipe } = getNode<PipeExpression>('PipeExpression')
|
const { node: pipe } = getNode<PipeExpression>('PipeExpression')
|
||||||
|
|
||||||
const newVal = createLiteral(roundOff(to[0], 2))
|
const newVal = createLiteral(roundOff(to[0], 2))
|
||||||
const newLine = createCallback
|
|
||||||
? createCallback([newVal, newVal]).callExp
|
|
||||||
: createCallExpression('xLineTo', [newVal, createPipeSubstitution()])
|
|
||||||
|
|
||||||
const callIndex = getLastIndex(pathToNode)
|
if (replaceExisting && createCallback) {
|
||||||
if (replaceExisting) {
|
const callIndex = getLastIndex(pathToNode)
|
||||||
pipe.body[callIndex] = newLine
|
const { callExp, valueUsedInTransform } = createCallback([newVal, newVal])
|
||||||
} else {
|
pipe.body[callIndex] = callExp
|
||||||
pipe.body = [...pipe.body, newLine]
|
return {
|
||||||
|
modifiedAst: _node,
|
||||||
|
pathToNode,
|
||||||
|
valueUsedInTransform,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
const callExp = createCallExpression('xLineTo', [
|
||||||
|
newVal,
|
||||||
|
createPipeSubstitution(),
|
||||||
|
])
|
||||||
|
pipe.body = [...pipe.body, callExp]
|
||||||
return {
|
return {
|
||||||
modifiedAst: _node,
|
modifiedAst: _node,
|
||||||
pathToNode,
|
pathToNode,
|
||||||
@ -430,15 +443,22 @@ export const yLineTo: SketchLineHelper = {
|
|||||||
const { node: pipe } = getNode<PipeExpression>('PipeExpression')
|
const { node: pipe } = getNode<PipeExpression>('PipeExpression')
|
||||||
|
|
||||||
const newVal = createLiteral(roundOff(to[1], 2))
|
const newVal = createLiteral(roundOff(to[1], 2))
|
||||||
const newLine = createCallback
|
|
||||||
? createCallback([newVal, newVal]).callExp
|
if (replaceExisting && createCallback) {
|
||||||
: createCallExpression('yLineTo', [newVal, createPipeSubstitution()])
|
const callIndex = getLastIndex(pathToNode)
|
||||||
const callIndex = getLastIndex(pathToNode)
|
const { callExp, valueUsedInTransform } = createCallback([newVal, newVal])
|
||||||
if (replaceExisting) {
|
pipe.body[callIndex] = callExp
|
||||||
pipe.body[callIndex] = newLine
|
return {
|
||||||
} else {
|
modifiedAst: _node,
|
||||||
pipe.body = [...pipe.body, newLine]
|
pathToNode,
|
||||||
|
valueUsedInTransform,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
const callExp = createCallExpression('yLineTo', [
|
||||||
|
newVal,
|
||||||
|
createPipeSubstitution(),
|
||||||
|
])
|
||||||
|
pipe.body = [...pipe.body, callExp]
|
||||||
return {
|
return {
|
||||||
modifiedAst: _node,
|
modifiedAst: _node,
|
||||||
pathToNode,
|
pathToNode,
|
||||||
@ -640,7 +660,15 @@ export const angledLine: SketchLineHelper = {
|
|||||||
value: [...sketchGroup.value, currentPath],
|
value: [...sketchGroup.value, currentPath],
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
add: ({ node, pathToNode, to, from, createCallback, replaceExisting }) => {
|
add: ({
|
||||||
|
node,
|
||||||
|
pathToNode,
|
||||||
|
to,
|
||||||
|
from,
|
||||||
|
createCallback,
|
||||||
|
replaceExisting,
|
||||||
|
referencedSegment,
|
||||||
|
}) => {
|
||||||
const _node = { ...node }
|
const _node = { ...node }
|
||||||
const getNode = getNodeFromPathCurry(_node, pathToNode)
|
const getNode = getNodeFromPathCurry(_node, pathToNode)
|
||||||
const { node: pipe } = getNode<PipeExpression>('PipeExpression')
|
const { node: pipe } = getNode<PipeExpression>('PipeExpression')
|
||||||
@ -652,12 +680,12 @@ export const angledLine: SketchLineHelper = {
|
|||||||
createPipeSubstitution(),
|
createPipeSubstitution(),
|
||||||
])
|
])
|
||||||
|
|
||||||
const callIndex = getLastIndex(pathToNode)
|
|
||||||
if (replaceExisting && createCallback) {
|
if (replaceExisting && createCallback) {
|
||||||
const { callExp, valueUsedInTransform } = createCallback([
|
const callIndex = getLastIndex(pathToNode)
|
||||||
newAngleVal,
|
const { callExp, valueUsedInTransform } = createCallback(
|
||||||
newLengthVal,
|
[newAngleVal, newLengthVal],
|
||||||
])
|
referencedSegment
|
||||||
|
)
|
||||||
pipe.body[callIndex] = callExp
|
pipe.body[callIndex] = callExp
|
||||||
return {
|
return {
|
||||||
modifiedAst: _node,
|
modifiedAst: _node,
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import { getAngle } from '../../lib/utils'
|
||||||
import { Range, TooTip, toolTips } from '../../useStore'
|
import { Range, TooTip, toolTips } from '../../useStore'
|
||||||
import {
|
import {
|
||||||
Program,
|
Program,
|
||||||
@ -33,6 +34,17 @@ export const segLen: InternalFn = (
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const segAng: InternalFn = (
|
||||||
|
_,
|
||||||
|
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 getAngle(line.from, line.to)
|
||||||
|
}
|
||||||
|
|
||||||
function segEndFactory(which: 'x' | 'y'): InternalFn {
|
function segEndFactory(which: 'x' | 'y'): InternalFn {
|
||||||
return (_, segName: string, sketchGroup: SketchGroup): number => {
|
return (_, segName: string, sketchGroup: SketchGroup): number => {
|
||||||
const line =
|
const line =
|
||||||
|
@ -366,10 +366,10 @@ show(part001)`
|
|||||||
'setVertDistance'
|
'setVertDistance'
|
||||||
)
|
)
|
||||||
expect(expectedHorizontalCode).toContain(
|
expect(expectedHorizontalCode).toContain(
|
||||||
`lineTo([segEndX('seg01', %) + 1.21, 4.59], %) // free`
|
`lineTo([segEndX('seg01', %) + 0.9, 4.59], %) // free`
|
||||||
)
|
)
|
||||||
expect(expectedVerticalCode).toContain(
|
expect(expectedVerticalCode).toContain(
|
||||||
`lineTo([1.21, segEndY('seg01', %) + 4.59], %) // free`
|
`lineTo([1.21, segEndY('seg01', %) + 2.92], %) // free`
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
it('testing for xRelative to vertical distance', () => {
|
it('testing for xRelative to vertical distance', () => {
|
||||||
@ -380,7 +380,7 @@ show(part001)`
|
|||||||
)
|
)
|
||||||
expect(expectedCode).toContain(`|> lineTo([
|
expect(expectedCode).toContain(`|> lineTo([
|
||||||
lastSegX(%) + myVar,
|
lastSegX(%) + myVar,
|
||||||
segEndY('seg01', %) + 4.6
|
segEndY('seg01', %) + 2.93
|
||||||
], %) // xRelative`)
|
], %) // xRelative`)
|
||||||
})
|
})
|
||||||
it('testing for yRelative to horizontal distance', () => {
|
it('testing for yRelative to horizontal distance', () => {
|
||||||
@ -390,7 +390,7 @@ show(part001)`
|
|||||||
'setHorzDistance'
|
'setHorzDistance'
|
||||||
)
|
)
|
||||||
expect(expectedCode).toContain(`|> lineTo([
|
expect(expectedCode).toContain(`|> lineTo([
|
||||||
segEndX('seg01', %) + 2.91,
|
segEndX('seg01', %) + 2.6,
|
||||||
lastSegY(%) + myVar
|
lastSegY(%) + myVar
|
||||||
], %) // yRelative`)
|
], %) // yRelative`)
|
||||||
})
|
})
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { TransformCallback } from './stdTypes'
|
import { TransformCallback } from './stdTypes'
|
||||||
import { Ranges, toolTips, TooTip } from '../../useStore'
|
import { Ranges, toolTips, TooTip, Range } from '../../useStore'
|
||||||
import {
|
import {
|
||||||
BinaryPart,
|
BinaryPart,
|
||||||
CallExpression,
|
CallExpression,
|
||||||
@ -24,7 +24,7 @@ import {
|
|||||||
import { createFirstArg, getFirstArg, replaceSketchLine } from './sketch'
|
import { createFirstArg, getFirstArg, replaceSketchLine } from './sketch'
|
||||||
import { ProgramMemory } from '../executor'
|
import { ProgramMemory } from '../executor'
|
||||||
import { getSketchSegmentIndexFromSourceRange } from './sketchConstraints'
|
import { getSketchSegmentIndexFromSourceRange } from './sketchConstraints'
|
||||||
import { roundOff } from '../../lib/utils'
|
import { getAngle, roundOff } from '../../lib/utils'
|
||||||
|
|
||||||
type LineInputsType =
|
type LineInputsType =
|
||||||
| 'xAbsolute'
|
| 'xAbsolute'
|
||||||
@ -38,7 +38,7 @@ export type ConstraintType =
|
|||||||
| 'equalLength'
|
| 'equalLength'
|
||||||
| 'vertical'
|
| 'vertical'
|
||||||
| 'horizontal'
|
| 'horizontal'
|
||||||
| 'equalangle'
|
| 'equalAngle'
|
||||||
| 'setHorzDistance'
|
| 'setHorzDistance'
|
||||||
| 'setVertDistance'
|
| 'setVertDistance'
|
||||||
| 'setAngle'
|
| 'setAngle'
|
||||||
@ -85,7 +85,6 @@ const xyLineSetLength =
|
|||||||
): TransformInfo['createNode'] =>
|
): TransformInfo['createNode'] =>
|
||||||
({ referenceSegName, tag, forceValueUsedInTransform }) =>
|
({ referenceSegName, tag, forceValueUsedInTransform }) =>
|
||||||
(args) => {
|
(args) => {
|
||||||
console.log('args', args)
|
|
||||||
const segRef = createSegLen(referenceSegName)
|
const segRef = createSegLen(referenceSegName)
|
||||||
const lineVal = forceValueUsedInTransform
|
const lineVal = forceValueUsedInTransform
|
||||||
? forceValueUsedInTransform
|
? forceValueUsedInTransform
|
||||||
@ -102,12 +101,17 @@ const basicAngledLineCreateNode =
|
|||||||
varValToUse: 'ang' | 'len' | 'none' = 'none'
|
varValToUse: 'ang' | 'len' | 'none' = 'none'
|
||||||
): TransformInfo['createNode'] =>
|
): TransformInfo['createNode'] =>
|
||||||
({ referenceSegName, tag, forceValueUsedInTransform, varValA, varValB }) =>
|
({ referenceSegName, tag, forceValueUsedInTransform, varValA, varValB }) =>
|
||||||
(args) => {
|
(args, path) => {
|
||||||
|
const refAng = path ? getAngle(path?.from, path?.to) : 0
|
||||||
const nonForcedAng =
|
const nonForcedAng =
|
||||||
varValToUse === 'ang'
|
varValToUse === 'ang'
|
||||||
? varValA
|
? varValA
|
||||||
: referenceSeg === 'ang'
|
: referenceSeg === 'ang'
|
||||||
? createSegAngle(referenceSegName)
|
? getClosesAngleDirection(
|
||||||
|
args[0],
|
||||||
|
refAng,
|
||||||
|
createSegAngle(referenceSegName) as BinaryPart
|
||||||
|
)
|
||||||
: args[0]
|
: args[0]
|
||||||
const nonForcedLen =
|
const nonForcedLen =
|
||||||
varValToUse === 'len'
|
varValToUse === 'len'
|
||||||
@ -186,6 +190,19 @@ const getAngleLengthSign = (arg: Value, legAngleVal: BinaryPart) => {
|
|||||||
return normalisedAngle > 90 ? createUnaryExpression(legAngleVal) : legAngleVal
|
return normalisedAngle > 90 ? createUnaryExpression(legAngleVal) : legAngleVal
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getClosesAngleDirection(
|
||||||
|
arg: Value,
|
||||||
|
refAngle: number,
|
||||||
|
angleVal: BinaryPart
|
||||||
|
) {
|
||||||
|
const currentAng = (arg.type === 'Literal' && Number(arg.value)) || 0
|
||||||
|
const angDiff = Math.abs(currentAng - refAngle)
|
||||||
|
const normalisedAngle = ((angDiff % 360) + 360) % 360 // between 0 and 180
|
||||||
|
return normalisedAngle > 90
|
||||||
|
? createBinaryExpression([angleVal, '+', createLiteral(180)])
|
||||||
|
: angleVal
|
||||||
|
}
|
||||||
|
|
||||||
const setHorzVertDistanceCreateNode =
|
const setHorzVertDistanceCreateNode =
|
||||||
(
|
(
|
||||||
xOrY: 'x' | 'y',
|
xOrY: 'x' | 'y',
|
||||||
@ -211,6 +228,55 @@ const setHorzVertDistanceCreateNode =
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
const setHorzVertDistanceForAngleLineCreateNode =
|
||||||
|
(
|
||||||
|
xOrY: 'x' | 'y',
|
||||||
|
index = xOrY === 'x' ? 0 : 1
|
||||||
|
): TransformInfo['createNode'] =>
|
||||||
|
({ referenceSegName, tag, forceValueUsedInTransform, varValA }) => {
|
||||||
|
return (args, referencedSegment) => {
|
||||||
|
const valueUsedInTransform = roundOff(
|
||||||
|
getArgLiteralVal(args?.[1]) - (referencedSegment?.to?.[index] || 0),
|
||||||
|
2
|
||||||
|
)
|
||||||
|
const makeBinExp = createBinaryExpression([
|
||||||
|
createSegEnd(referenceSegName, !index),
|
||||||
|
'+',
|
||||||
|
(forceValueUsedInTransform as BinaryPart) ||
|
||||||
|
createLiteral(valueUsedInTransform),
|
||||||
|
])
|
||||||
|
return createCallWrapper(
|
||||||
|
xOrY === 'x' ? 'angledLineToX' : 'angledLineToY',
|
||||||
|
[varValA, makeBinExp],
|
||||||
|
tag,
|
||||||
|
valueUsedInTransform
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const setHorVertDistanceForXYLines =
|
||||||
|
(xOrY: 'x' | 'y'): TransformInfo['createNode'] =>
|
||||||
|
({ referenceSegName, tag, forceValueUsedInTransform }) => {
|
||||||
|
return (args, referencedSegment) => {
|
||||||
|
const index = xOrY === 'x' ? 0 : 1
|
||||||
|
const valueUsedInTransform = roundOff(
|
||||||
|
getArgLiteralVal(args?.[index]) - (referencedSegment?.to?.[index] || 0),
|
||||||
|
2
|
||||||
|
)
|
||||||
|
const makeBinExp = createBinaryExpression([
|
||||||
|
createSegEnd(referenceSegName, xOrY === 'x'),
|
||||||
|
'+',
|
||||||
|
(forceValueUsedInTransform as BinaryPart) ||
|
||||||
|
createLiteral(valueUsedInTransform),
|
||||||
|
])
|
||||||
|
return createCallWrapper(
|
||||||
|
xOrY === 'x' ? 'xLineTo' : 'yLineTo',
|
||||||
|
makeBinExp,
|
||||||
|
tag,
|
||||||
|
valueUsedInTransform
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const setHorzVertDistanceConstraintLineCreateNode =
|
const setHorzVertDistanceConstraintLineCreateNode =
|
||||||
(isX: boolean): TransformInfo['createNode'] =>
|
(isX: boolean): TransformInfo['createNode'] =>
|
||||||
@ -334,6 +400,10 @@ const transformMap: TransformMap = {
|
|||||||
tooltip: 'angledLine',
|
tooltip: 'angledLine',
|
||||||
createNode: basicAngledLineCreateNode('none', 'len'),
|
createNode: basicAngledLineCreateNode('none', 'len'),
|
||||||
},
|
},
|
||||||
|
equalAngle: {
|
||||||
|
tooltip: 'angledLine',
|
||||||
|
createNode: basicAngledLineCreateNode('ang'),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
lineTo: {
|
lineTo: {
|
||||||
@ -419,7 +489,6 @@ const transformMap: TransformMap = {
|
|||||||
createNode:
|
createNode:
|
||||||
({ varValB, tag, forceValueUsedInTransform }) =>
|
({ varValB, tag, forceValueUsedInTransform }) =>
|
||||||
(args) => {
|
(args) => {
|
||||||
console.log(getArgLiteralVal(args[0]))
|
|
||||||
return createCallWrapper(
|
return createCallWrapper(
|
||||||
'angledLineToY',
|
'angledLineToY',
|
||||||
[forceValueUsedInTransform || args[0], varValB],
|
[forceValueUsedInTransform || args[0], varValB],
|
||||||
@ -447,6 +516,14 @@ const transformMap: TransformMap = {
|
|||||||
tooltip: 'angledLine',
|
tooltip: 'angledLine',
|
||||||
createNode: basicAngledLineCreateNode('none', 'len', 'ang'),
|
createNode: basicAngledLineCreateNode('none', 'len', 'ang'),
|
||||||
},
|
},
|
||||||
|
setVertDistance: {
|
||||||
|
tooltip: 'angledLineToY',
|
||||||
|
createNode: setHorzVertDistanceForAngleLineCreateNode('y'),
|
||||||
|
},
|
||||||
|
setHorzDistance: {
|
||||||
|
tooltip: 'angledLineToX',
|
||||||
|
createNode: setHorzVertDistanceForAngleLineCreateNode('x'),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
free: {
|
free: {
|
||||||
equalLength: {
|
equalLength: {
|
||||||
@ -715,27 +792,7 @@ const transformMap: TransformMap = {
|
|||||||
},
|
},
|
||||||
setHorzDistance: {
|
setHorzDistance: {
|
||||||
tooltip: 'xLineTo',
|
tooltip: 'xLineTo',
|
||||||
createNode: ({ referenceSegName, tag, forceValueUsedInTransform }) => {
|
createNode: setHorVertDistanceForXYLines('x'),
|
||||||
return (args, referencedSegment) => {
|
|
||||||
console.log('args', args)
|
|
||||||
const valueUsedInTransform = roundOff(
|
|
||||||
getArgLiteralVal(args?.[0]) - (referencedSegment?.to?.[0] || 0),
|
|
||||||
2
|
|
||||||
)
|
|
||||||
const makeBinExp = createBinaryExpression([
|
|
||||||
createSegEnd(referenceSegName, true),
|
|
||||||
'+',
|
|
||||||
(forceValueUsedInTransform as BinaryPart) ||
|
|
||||||
createLiteral(valueUsedInTransform),
|
|
||||||
])
|
|
||||||
return createCallWrapper(
|
|
||||||
'xLineTo',
|
|
||||||
makeBinExp,
|
|
||||||
tag,
|
|
||||||
valueUsedInTransform
|
|
||||||
)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
setLength: {
|
setLength: {
|
||||||
tooltip: 'xLine',
|
tooltip: 'xLine',
|
||||||
@ -756,6 +813,10 @@ const transformMap: TransformMap = {
|
|||||||
tooltip: 'yLine',
|
tooltip: 'yLine',
|
||||||
createNode: xyLineSetLength('yLine'),
|
createNode: xyLineSetLength('yLine'),
|
||||||
},
|
},
|
||||||
|
setVertDistance: {
|
||||||
|
tooltip: 'yLineTo',
|
||||||
|
createNode: setHorVertDistanceForXYLines('y'),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
xLineTo: {
|
xLineTo: {
|
||||||
@ -767,6 +828,10 @@ const transformMap: TransformMap = {
|
|||||||
() =>
|
() =>
|
||||||
createCallWrapper('xLine', createSegLen(referenceSegName), tag),
|
createCallWrapper('xLine', createSegLen(referenceSegName), tag),
|
||||||
},
|
},
|
||||||
|
setLength: {
|
||||||
|
tooltip: 'xLine',
|
||||||
|
createNode: xyLineSetLength('xLine'),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
yLineTo: {
|
yLineTo: {
|
||||||
@ -778,6 +843,10 @@ const transformMap: TransformMap = {
|
|||||||
() =>
|
() =>
|
||||||
createCallWrapper('yLine', createSegLen(referenceSegName), tag),
|
createCallWrapper('yLine', createSegLen(referenceSegName), tag),
|
||||||
},
|
},
|
||||||
|
setLength: {
|
||||||
|
tooltip: 'yLine',
|
||||||
|
createNode: xyLineSetLength('yLine'),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -946,6 +1015,7 @@ export function transformSecondarySketchLinesTagFirst({
|
|||||||
...transformAstSketchLines({
|
...transformAstSketchLines({
|
||||||
ast: modifiedAst,
|
ast: modifiedAst,
|
||||||
selectionRanges: selectionRanges.slice(1),
|
selectionRanges: selectionRanges.slice(1),
|
||||||
|
referencedSegmentRange: primarySelection,
|
||||||
transformInfos,
|
transformInfos,
|
||||||
programMemory,
|
programMemory,
|
||||||
referenceSegName: tag,
|
referenceSegName: tag,
|
||||||
@ -965,6 +1035,7 @@ export function transformAstSketchLines({
|
|||||||
programMemory,
|
programMemory,
|
||||||
referenceSegName,
|
referenceSegName,
|
||||||
forceValueUsedInTransform,
|
forceValueUsedInTransform,
|
||||||
|
referencedSegmentRange,
|
||||||
}: {
|
}: {
|
||||||
ast: Program
|
ast: Program
|
||||||
selectionRanges: Ranges
|
selectionRanges: Ranges
|
||||||
@ -972,6 +1043,7 @@ export function transformAstSketchLines({
|
|||||||
programMemory: ProgramMemory
|
programMemory: ProgramMemory
|
||||||
referenceSegName: string
|
referenceSegName: string
|
||||||
forceValueUsedInTransform?: Value
|
forceValueUsedInTransform?: Value
|
||||||
|
referencedSegmentRange?: Range
|
||||||
}): { modifiedAst: Program; valueUsedInTransform?: number } {
|
}): { modifiedAst: Program; valueUsedInTransform?: number } {
|
||||||
// deep clone since we are mutating in a loop, of which any could fail
|
// deep clone since we are mutating in a loop, of which any could fail
|
||||||
let node = JSON.parse(JSON.stringify(ast))
|
let node = JSON.parse(JSON.stringify(ast))
|
||||||
@ -998,9 +1070,12 @@ export function transformAstSketchLines({
|
|||||||
if (!sketchGroup || sketchGroup.type !== 'sketchGroup')
|
if (!sketchGroup || sketchGroup.type !== 'sketchGroup')
|
||||||
throw new Error('not a sketch group')
|
throw new Error('not a sketch group')
|
||||||
const seg = getSketchSegmentIndexFromSourceRange(sketchGroup, range)
|
const seg = getSketchSegmentIndexFromSourceRange(sketchGroup, range)
|
||||||
const referencedSegment = sketchGroup.value.find(
|
const referencedSegment = referencedSegmentRange
|
||||||
(path) => path.name === referenceSegName
|
? getSketchSegmentIndexFromSourceRange(
|
||||||
)
|
sketchGroup,
|
||||||
|
referencedSegmentRange
|
||||||
|
)
|
||||||
|
: sketchGroup.value.find((path) => path.name === referenceSegName)
|
||||||
const { to, from } = seg
|
const { to, from } = seg
|
||||||
const { modifiedAst, valueUsedInTransform } = replaceSketchLine({
|
const { modifiedAst, valueUsedInTransform } = replaceSketchLine({
|
||||||
node: node,
|
node: node,
|
||||||
@ -1035,7 +1110,7 @@ function createSegLen(referenceSegName: string): Value {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function createSegAngle(referenceSegName: string): Value {
|
function createSegAngle(referenceSegName: string): Value {
|
||||||
return createCallExpression('segAngle', [
|
return createCallExpression('segAng', [
|
||||||
createLiteral(referenceSegName),
|
createLiteral(referenceSegName),
|
||||||
createPipeSubstitution(),
|
createPipeSubstitution(),
|
||||||
])
|
])
|
||||||
|
@ -16,6 +16,7 @@ import {
|
|||||||
} from './sketch'
|
} from './sketch'
|
||||||
import {
|
import {
|
||||||
segLen,
|
segLen,
|
||||||
|
segAng,
|
||||||
angleToMatchLengthX,
|
angleToMatchLengthX,
|
||||||
angleToMatchLengthY,
|
angleToMatchLengthY,
|
||||||
segEndX,
|
segEndX,
|
||||||
@ -143,6 +144,7 @@ export const internalFns: { [key in InternalFnNames]: InternalFn } = {
|
|||||||
lastSegX,
|
lastSegX,
|
||||||
lastSegY,
|
lastSegY,
|
||||||
segLen,
|
segLen,
|
||||||
|
segAng,
|
||||||
angleToMatchLengthX,
|
angleToMatchLengthX,
|
||||||
angleToMatchLengthY,
|
angleToMatchLengthY,
|
||||||
lineTo: lineTo.fn,
|
lineTo: lineTo.fn,
|
||||||
|
@ -29,6 +29,7 @@ export type InternalFnNames =
|
|||||||
| 'lastSegX'
|
| 'lastSegX'
|
||||||
| 'lastSegY'
|
| 'lastSegY'
|
||||||
| 'segLen'
|
| 'segLen'
|
||||||
|
| 'segAng'
|
||||||
| 'angleToMatchLengthX'
|
| 'angleToMatchLengthX'
|
||||||
| 'angleToMatchLengthY'
|
| 'angleToMatchLengthY'
|
||||||
| 'rx'
|
| 'rx'
|
||||||
|
Reference in New Issue
Block a user