diff --git a/src/Toolbar.tsx b/src/Toolbar.tsx
index fc0e3418d..5ddf9042f 100644
--- a/src/Toolbar.tsx
+++ b/src/Toolbar.tsx
@@ -2,6 +2,7 @@ import { useStore, toolTips } from './useStore'
import { extrudeSketch, sketchOnExtrudedFace } from './lang/modifyAst'
import { getNodePathFromSourceRange } from './lang/queryAst'
import { HorzVert } from './components/Toolbar/HorzVert'
+import { RemoveConstrainingValues } from './components/Toolbar/RemoveConstrainingValues'
import { EqualLength } from './components/Toolbar/EqualLength'
import { EqualAngle } from './components/Toolbar/EqualAngle'
import { Intersect } from './components/Toolbar/Intersect'
@@ -170,6 +171,7 @@ export const Toolbar = () => {
+
)
}
diff --git a/src/components/Toolbar/RemoveConstrainingValues.tsx b/src/components/Toolbar/RemoveConstrainingValues.tsx
new file mode 100644
index 000000000..3fd7c3ba5
--- /dev/null
+++ b/src/components/Toolbar/RemoveConstrainingValues.tsx
@@ -0,0 +1,76 @@
+import { useState, useEffect } from 'react'
+import { toolTips, useStore } from '../../useStore'
+import { Value } from '../../lang/abstractSyntaxTree'
+import {
+ getNodePathFromSourceRange,
+ getNodeFromPath,
+} from '../../lang/queryAst'
+import {
+ TransformInfo,
+ getRemoveConstraintsTransforms,
+ transformAstSketchLines,
+} from '../../lang/std/sketchcombos'
+
+export const RemoveConstrainingValues = () => {
+ const { guiMode, selectionRanges, ast, programMemory, updateAst } = useStore(
+ (s) => ({
+ guiMode: s.guiMode,
+ ast: s.ast,
+ updateAst: s.updateAst,
+ selectionRanges: s.selectionRanges,
+ programMemory: s.programMemory,
+ })
+ )
+ const [enableHorz, setEnableHorz] = useState(false)
+ const [transformInfos, setTransformInfos] = useState()
+ useEffect(() => {
+ if (!ast) return
+ const paths = selectionRanges.map((selectionRange) =>
+ getNodePathFromSourceRange(ast, selectionRange)
+ )
+ const nodes = paths.map(
+ (pathToNode) => getNodeFromPath(ast, pathToNode).node
+ )
+ const isAllTooltips = nodes.every(
+ (node) =>
+ node?.type === 'CallExpression' &&
+ toolTips.includes(node.callee.name as any)
+ )
+
+ const theTransforms = getRemoveConstraintsTransforms(
+ selectionRanges,
+ ast,
+ 'removeConstrainingValues'
+ )
+ setTransformInfos(theTransforms)
+
+ const _enableHorz = isAllTooltips && theTransforms.every(Boolean)
+ setEnableHorz(_enableHorz)
+ }, [guiMode, selectionRanges])
+ if (guiMode.mode !== 'sketch') return null
+
+ return (
+
+ )
+}
diff --git a/src/lang/std/sketch.ts b/src/lang/std/sketch.ts
index 5522bfd35..c73b7fccd 100644
--- a/src/lang/std/sketch.ts
+++ b/src/lang/std/sketch.ts
@@ -1666,7 +1666,10 @@ function getFirstArgValuesForXYLineFns(callExpression: CallExpression): {
if (length) {
return { val: length, tag }
}
- throw new Error('expected ArrayExpression or ObjectExpression')
+ console.warn('expected ArrayExpression or ObjectExpression')
+ return {
+ val: createLiteral(1),
+ }
}
const getAngledLineThatIntersects = (
diff --git a/src/lang/std/sketchcombos.ts b/src/lang/std/sketchcombos.ts
index 963ff2955..eea45bd72 100644
--- a/src/lang/std/sketchcombos.ts
+++ b/src/lang/std/sketchcombos.ts
@@ -45,6 +45,7 @@ export type ConstraintType =
| 'setAngle'
| 'setLength'
| 'intersect'
+ | 'removeConstrainingValues'
function createCallWrapper(
a: TooTip,
@@ -939,6 +940,86 @@ const transformMap: TransformMap = {
},
}
+export function getRemoveConstraintsTransform(
+ sketchFnExp: CallExpression,
+ constraintType: ConstraintType
+): TransformInfo | false {
+ let name = sketchFnExp.callee.name as TooTip
+ if (!toolTips.includes(name)) {
+ return false
+ }
+ const xyLineMap: {
+ [key in TooTip]?: TooTip
+ } = {
+ xLine: 'line',
+ yLine: 'line',
+ xLineTo: 'lineTo',
+ yLineTo: 'lineTo',
+ }
+
+ const _name = xyLineMap[name]
+ if (_name) {
+ name = _name
+ }
+
+ const transformInfo: TransformInfo = {
+ tooltip: 'line',
+ // tooltip: name,
+ createNode:
+ ({ tag, referenceSegName }) =>
+ (args) => {
+ return createCallWrapper('line', args, tag)
+ // The following commented changes values to hardcode, but keeps the line type the same, maybe that's useful?
+
+ // if (name === 'angledLineThatIntersects') {
+ // return intersectCallWrapper({
+ // fnName: name,
+ // angleVal: args[0],
+ // offsetVal: args[1],
+ // intersectTag: createLiteral(referenceSegName),
+ // tag,
+ // })
+ // }
+ // return createCallWrapper(name, args, tag)
+ },
+ }
+
+ // check if the function is locked down and so can't be transformed
+ const firstArg = getFirstArg(sketchFnExp)
+ if (Array.isArray(firstArg.val)) {
+ const [a, b] = firstArg.val
+ if (a?.type !== 'Literal' && b?.type !== 'Literal') {
+ return transformInfo
+ }
+ } else {
+ if (firstArg.val?.type !== 'Literal') {
+ return transformInfo
+ }
+ }
+
+ // check if the function has no constraints
+ const isTwoValFree =
+ Array.isArray(firstArg.val) &&
+ firstArg.val?.[0]?.type === 'Literal' &&
+ firstArg.val?.[1]?.type === 'Literal'
+ if (isTwoValFree) {
+ return false
+ }
+ const isOneValFree =
+ !Array.isArray(firstArg.val) && firstArg.val?.type === 'Literal'
+ if (isOneValFree) {
+ return transformInfo
+ }
+
+ // check what constraints the function has
+ const lineInputType = getConstraintType(firstArg.val, name)
+ if (lineInputType) {
+ return transformInfo
+ }
+
+ return false
+}
+
export function getTransformMapPath(
sketchFnExp: CallExpression,
constraintType: ConstraintType
@@ -1068,6 +1149,28 @@ export function getTransformInfos(
return theTransforms
}
+export function getRemoveConstraintsTransforms(
+ selectionRanges: Ranges,
+ ast: Program,
+ constraintType: ConstraintType
+): TransformInfo[] {
+ // return ()
+ const paths = selectionRanges.map((selectionRange) =>
+ getNodePathFromSourceRange(ast, selectionRange)
+ )
+ const nodes = paths.map(
+ (pathToNode) => getNodeFromPath(ast, pathToNode).node
+ )
+
+ const theTransforms = nodes.map((node) => {
+ if (node?.type === 'CallExpression')
+ return getRemoveConstraintsTransform(node, constraintType)
+
+ return false
+ }) as TransformInfo[]
+ return theTransforms
+}
+
export function transformSecondarySketchLinesTagFirst({
ast,
selectionRanges,
@@ -1151,6 +1254,17 @@ export function transformAstSketchLines({
const varDec = getNode('VariableDeclarator').node
const { val, tag: callBackTag } = getFirstArg(callExp)
+ const _referencedSegmentNameVal =
+ callExp.arguments[0]?.type === 'ObjectExpression' &&
+ callExp.arguments[0].properties?.find(
+ (prop) => prop.key.name === 'intersectTag'
+ )?.value
+ const _referencedSegmentName =
+ referenceSegName ||
+ (_referencedSegmentNameVal &&
+ _referencedSegmentNameVal.type === 'Literal' &&
+ String(_referencedSegmentNameVal.value)) ||
+ ''
const [varValA, varValB] = Array.isArray(val) ? val : [val, val]
const varName = varDec.id.name
@@ -1160,7 +1274,7 @@ export function transformAstSketchLines({
const seg = getSketchSegmentFromSourceRange(sketchGroup, range)
const referencedSegment = referencedSegmentRange
? getSketchSegmentFromSourceRange(sketchGroup, referencedSegmentRange)
- : sketchGroup.value.find((path) => path.name === referenceSegName)
+ : sketchGroup.value.find((path) => path.name === _referencedSegmentName)
const { to, from } = seg
const { modifiedAst, valueUsedInTransform } = replaceSketchLine({
node: node,
@@ -1171,7 +1285,7 @@ export function transformAstSketchLines({
to,
from,
createCallback: callBack({
- referenceSegName,
+ referenceSegName: _referencedSegmentName,
varValA,
varValB,
tag: callBackTag,