@ -19,7 +19,7 @@ import { CustomIcon } from '@src/components/CustomIcon'
|
|||||||
import { useModelingContext } from '@src/hooks/useModelingContext'
|
import { useModelingContext } from '@src/hooks/useModelingContext'
|
||||||
import { removeSingleConstraintInfo } from '@src/lang/modifyAst'
|
import { removeSingleConstraintInfo } from '@src/lang/modifyAst'
|
||||||
import { findUsesOfTagInPipe, getNodeFromPath } from '@src/lang/queryAst'
|
import { findUsesOfTagInPipe, getNodeFromPath } from '@src/lang/queryAst'
|
||||||
import { getConstraintInfo, getConstraintInfoKw } from '@src/lang/std/sketch'
|
import { getConstraintInfoKw } from '@src/lang/std/sketch'
|
||||||
import type { ConstrainInfo } from '@src/lang/std/stdTypes'
|
import type { ConstrainInfo } from '@src/lang/std/stdTypes'
|
||||||
import { topLevelRange } from '@src/lang/util'
|
import { topLevelRange } from '@src/lang/util'
|
||||||
import type {
|
import type {
|
||||||
@ -211,10 +211,10 @@ const Overlay = ({
|
|||||||
// It's possible for the pathToNode to request a newer AST node
|
// It's possible for the pathToNode to request a newer AST node
|
||||||
// than what's available in the AST at the moment of query.
|
// than what's available in the AST at the moment of query.
|
||||||
// It eventually settles on being updated.
|
// It eventually settles on being updated.
|
||||||
const _node1 = getNodeFromPath<Node<CallExpression | CallExpressionKw>>(
|
const _node1 = getNodeFromPath<Node<CallExpressionKw>>(
|
||||||
kclManager.ast,
|
kclManager.ast,
|
||||||
overlay.pathToNode,
|
overlay.pathToNode,
|
||||||
['CallExpression', 'CallExpressionKw']
|
['CallExpressionKw']
|
||||||
)
|
)
|
||||||
|
|
||||||
// For that reason, to prevent console noise, we do not use err here.
|
// For that reason, to prevent console noise, we do not use err here.
|
||||||
@ -224,20 +224,12 @@ const Overlay = ({
|
|||||||
}
|
}
|
||||||
const callExpression = _node1.node
|
const callExpression = _node1.node
|
||||||
|
|
||||||
const constraints =
|
const constraints = getConstraintInfoKw(
|
||||||
callExpression.type === 'CallExpression'
|
callExpression,
|
||||||
? getConstraintInfo(
|
codeManager.code,
|
||||||
callExpression,
|
overlay.pathToNode,
|
||||||
codeManager.code,
|
overlay.filterValue
|
||||||
overlay.pathToNode,
|
)
|
||||||
overlay.filterValue
|
|
||||||
)
|
|
||||||
: getConstraintInfoKw(
|
|
||||||
callExpression,
|
|
||||||
codeManager.code,
|
|
||||||
overlay.pathToNode,
|
|
||||||
overlay.filterValue
|
|
||||||
)
|
|
||||||
|
|
||||||
const offset = 20 // px
|
const offset = 20 // px
|
||||||
// We could put a boolean in settings that
|
// We could put a boolean in settings that
|
||||||
|
@ -38,7 +38,6 @@ import type { Artifact } from '@src/lang/std/artifactGraph'
|
|||||||
import { getPathsFromArtifact } from '@src/lang/std/artifactGraph'
|
import { getPathsFromArtifact } from '@src/lang/std/artifactGraph'
|
||||||
import {
|
import {
|
||||||
addTagForSketchOnFace,
|
addTagForSketchOnFace,
|
||||||
getConstraintInfo,
|
|
||||||
getConstraintInfoKw,
|
getConstraintInfoKw,
|
||||||
} from '@src/lang/std/sketch'
|
} from '@src/lang/std/sketch'
|
||||||
import type { PathToNodeMap } from '@src/lang/std/sketchcombos'
|
import type { PathToNodeMap } from '@src/lang/std/sketchcombos'
|
||||||
@ -70,7 +69,7 @@ import type {
|
|||||||
} from '@src/lib/commandTypes'
|
} from '@src/lib/commandTypes'
|
||||||
import { KCL_DEFAULT_CONSTANT_PREFIXES } from '@src/lib/constants'
|
import { KCL_DEFAULT_CONSTANT_PREFIXES } from '@src/lib/constants'
|
||||||
import type { DefaultPlaneStr } from '@src/lib/planes'
|
import type { DefaultPlaneStr } from '@src/lib/planes'
|
||||||
import type { Selection } from '@src/lib/selections'
|
|
||||||
import { err, trap } from '@src/lib/trap'
|
import { err, trap } from '@src/lib/trap'
|
||||||
import { isOverlap, roundOff } from '@src/lib/utils'
|
import { isOverlap, roundOff } from '@src/lib/utils'
|
||||||
import type { ExtrudeFacePlane } from '@src/machines/modelingMachine'
|
import type { ExtrudeFacePlane } from '@src/machines/modelingMachine'
|
||||||
@ -1195,22 +1194,17 @@ export function deleteSegmentFromPipeExpression(
|
|||||||
dependentRanges.forEach((range) => {
|
dependentRanges.forEach((range) => {
|
||||||
const path = getNodePathFromSourceRange(_modifiedAst, range)
|
const path = getNodePathFromSourceRange(_modifiedAst, range)
|
||||||
|
|
||||||
const callExp = getNodeFromPath<Node<CallExpression | CallExpressionKw>>(
|
const callExp = getNodeFromPath<Node<CallExpressionKw>>(
|
||||||
_modifiedAst,
|
_modifiedAst,
|
||||||
path,
|
path,
|
||||||
['CallExpression', 'CallExpressionKw'],
|
['CallExpressionKw'],
|
||||||
true
|
true
|
||||||
)
|
)
|
||||||
if (err(callExp)) return callExp
|
if (err(callExp)) return callExp
|
||||||
|
|
||||||
const constraintInfo =
|
const constraintInfo = getConstraintInfoKw(callExp.node, code, path).find(
|
||||||
callExp.node.type === 'CallExpression'
|
({ sourceRange }) => isOverlap(sourceRange, range)
|
||||||
? getConstraintInfo(callExp.node, code, path).find(({ sourceRange }) =>
|
)
|
||||||
isOverlap(sourceRange, range)
|
|
||||||
)
|
|
||||||
: getConstraintInfoKw(callExp.node, code, path).find(
|
|
||||||
({ sourceRange }) => isOverlap(sourceRange, range)
|
|
||||||
)
|
|
||||||
if (!constraintInfo) return
|
if (!constraintInfo) return
|
||||||
|
|
||||||
if (!constraintInfo.argPosition) return
|
if (!constraintInfo.argPosition) return
|
||||||
|
@ -11,7 +11,6 @@ import {
|
|||||||
deleteEdgeTreatment,
|
deleteEdgeTreatment,
|
||||||
getPathToExtrudeForSegmentSelection,
|
getPathToExtrudeForSegmentSelection,
|
||||||
hasValidEdgeTreatmentSelection,
|
hasValidEdgeTreatmentSelection,
|
||||||
isTagUsedInEdgeTreatment,
|
|
||||||
modifyAstWithEdgeTreatmentAndTag,
|
modifyAstWithEdgeTreatmentAndTag,
|
||||||
} from '@src/lang/modifyAst/addEdgeTreatment'
|
} from '@src/lang/modifyAst/addEdgeTreatment'
|
||||||
import { getNodeFromPath } from '@src/lang/queryAst'
|
import { getNodeFromPath } from '@src/lang/queryAst'
|
||||||
@ -942,78 +941,6 @@ chamfer001 = chamfer(extrude001, length = 5, tags = [getOppositeEdge(seg01)])`
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
describe('Testing isTagUsedInEdgeTreatment', () => {
|
|
||||||
const code = `sketch001 = startSketchOn(XZ)
|
|
||||||
|> startProfile(at = [7.72, 4.13])
|
|
||||||
|> line(end = [7.11, 3.48], tag = $seg01)
|
|
||||||
|> line(end = [-3.29, -13.85])
|
|
||||||
|> line(end = [-6.37, 3.88], tag = $seg02)
|
|
||||||
|> close()
|
|
||||||
extrude001 = extrude(sketch001, length = -5)
|
|
||||||
|> fillet(
|
|
||||||
radius = 1.11,
|
|
||||||
tags = [
|
|
||||||
getOppositeEdge(seg01),
|
|
||||||
seg01,
|
|
||||||
getPreviousAdjacentEdge(seg02)
|
|
||||||
]
|
|
||||||
)
|
|
||||||
`
|
|
||||||
it('should correctly identify getOppositeEdge and baseEdge edges', () => {
|
|
||||||
const ast = assertParse(code)
|
|
||||||
const lineOfInterest = `line(end = [7.11, 3.48], tag = $seg01)`
|
|
||||||
const range = topLevelRange(
|
|
||||||
code.indexOf(lineOfInterest),
|
|
||||||
code.indexOf(lineOfInterest) + lineOfInterest.length
|
|
||||||
)
|
|
||||||
const pathToNode = getNodePathFromSourceRange(ast, range)
|
|
||||||
if (err(pathToNode)) return
|
|
||||||
const callExp = getNodeFromPath<CallExpression | CallExpressionKw>(
|
|
||||||
ast,
|
|
||||||
pathToNode,
|
|
||||||
['CallExpression', 'CallExpressionKw']
|
|
||||||
)
|
|
||||||
if (err(callExp)) return
|
|
||||||
const edges = isTagUsedInEdgeTreatment({ ast, callExp: callExp.node })
|
|
||||||
expect(edges).toEqual(['getOppositeEdge', 'baseEdge'])
|
|
||||||
})
|
|
||||||
it('should correctly identify getPreviousAdjacentEdge edges', () => {
|
|
||||||
const ast = assertParse(code)
|
|
||||||
const lineOfInterest = `line(end = [-6.37, 3.88], tag = $seg02)`
|
|
||||||
const range = topLevelRange(
|
|
||||||
code.indexOf(lineOfInterest),
|
|
||||||
code.indexOf(lineOfInterest) + lineOfInterest.length
|
|
||||||
)
|
|
||||||
const pathToNode = getNodePathFromSourceRange(ast, range)
|
|
||||||
if (err(pathToNode)) return
|
|
||||||
const callExp = getNodeFromPath<CallExpression | CallExpressionKw>(
|
|
||||||
ast,
|
|
||||||
pathToNode,
|
|
||||||
['CallExpression', 'CallExpressionKw']
|
|
||||||
)
|
|
||||||
if (err(callExp)) return
|
|
||||||
const edges = isTagUsedInEdgeTreatment({ ast, callExp: callExp.node })
|
|
||||||
expect(edges).toEqual(['getPreviousAdjacentEdge'])
|
|
||||||
})
|
|
||||||
it('should correctly identify no edges', () => {
|
|
||||||
const ast = assertParse(code)
|
|
||||||
const lineOfInterest = `line(end = [-3.29, -13.85])`
|
|
||||||
const start = code.indexOf(lineOfInterest)
|
|
||||||
expect(start).toBeGreaterThan(-1)
|
|
||||||
const range = topLevelRange(start, start + lineOfInterest.length)
|
|
||||||
const pathToNode = getNodePathFromSourceRange(ast, range)
|
|
||||||
if (err(pathToNode)) return
|
|
||||||
const callExp = getNodeFromPath<CallExpressionKw>(
|
|
||||||
ast,
|
|
||||||
pathToNode,
|
|
||||||
'CallExpression'
|
|
||||||
)
|
|
||||||
if (err(callExp)) return
|
|
||||||
const edges = isTagUsedInEdgeTreatment({ ast, callExp: callExp.node })
|
|
||||||
expect(edges).toEqual([])
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
describe('Testing button states', () => {
|
describe('Testing button states', () => {
|
||||||
const runButtonStateTest = async (
|
const runButtonStateTest = async (
|
||||||
code: string,
|
code: string,
|
||||||
|
@ -24,8 +24,6 @@ import { getSweepArtifactFromSelection } from '@src/lang/std/artifactGraph'
|
|||||||
import type { EngineCommandManager } from '@src/lang/std/engineConnection'
|
import type { EngineCommandManager } from '@src/lang/std/engineConnection'
|
||||||
import {
|
import {
|
||||||
addTagForSketchOnFace,
|
addTagForSketchOnFace,
|
||||||
getTagFromCallExpression,
|
|
||||||
sketchLineHelperMap,
|
|
||||||
sketchLineHelperMapKw,
|
sketchLineHelperMapKw,
|
||||||
} from '@src/lang/std/sketch'
|
} from '@src/lang/std/sketch'
|
||||||
import { findKwArg } from '@src/lang/util'
|
import { findKwArg } from '@src/lang/util'
|
||||||
@ -338,10 +336,7 @@ export function mutateAstWithTagForSketchSegment(
|
|||||||
// Check whether selection is a valid segment
|
// Check whether selection is a valid segment
|
||||||
if (
|
if (
|
||||||
!segmentNode.node.callee ||
|
!segmentNode.node.callee ||
|
||||||
!(
|
!(segmentNode.node.callee.name.name in sketchLineHelperMapKw)
|
||||||
segmentNode.node.callee.name.name in sketchLineHelperMap ||
|
|
||||||
segmentNode.node.callee.name.name in sketchLineHelperMapKw
|
|
||||||
)
|
|
||||||
) {
|
) {
|
||||||
return new Error('Selection is not a sketch segment')
|
return new Error('Selection is not a sketch segment')
|
||||||
}
|
}
|
||||||
@ -554,13 +549,6 @@ function getParameterNameAndValue(
|
|||||||
function isEdgeTreatmentType(name: string): name is EdgeTreatmentType {
|
function isEdgeTreatmentType(name: string): name is EdgeTreatmentType {
|
||||||
return name === EdgeTreatmentType.Chamfer || name === EdgeTreatmentType.Fillet
|
return name === EdgeTreatmentType.Chamfer || name === EdgeTreatmentType.Fillet
|
||||||
}
|
}
|
||||||
function isEdgeType(name: string): name is EdgeTypes {
|
|
||||||
return (
|
|
||||||
name === 'getNextAdjacentEdge' ||
|
|
||||||
name === 'getPreviousAdjacentEdge' ||
|
|
||||||
name === 'getOppositeEdge'
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Button states
|
// Button states
|
||||||
export const hasValidEdgeTreatmentSelection = ({
|
export const hasValidEdgeTreatmentSelection = ({
|
||||||
@ -612,12 +600,7 @@ export const hasValidEdgeTreatmentSelection = ({
|
|||||||
) {
|
) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if (
|
if (!(segmentNode.node.callee.name.name in sketchLineHelperMapKw)) {
|
||||||
!(
|
|
||||||
segmentNode.node.callee.name.name in sketchLineHelperMap ||
|
|
||||||
segmentNode.node.callee.name.name in sketchLineHelperMapKw
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -687,142 +670,6 @@ export const hasValidEdgeTreatmentSelection = ({
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
type EdgeTypes =
|
|
||||||
| 'baseEdge'
|
|
||||||
| 'getNextAdjacentEdge'
|
|
||||||
| 'getPreviousAdjacentEdge'
|
|
||||||
| 'getOppositeEdge'
|
|
||||||
|
|
||||||
export const isTagUsedInEdgeTreatment = ({
|
|
||||||
ast,
|
|
||||||
callExp,
|
|
||||||
}: {
|
|
||||||
ast: Node<Program>
|
|
||||||
callExp: CallExpression | CallExpressionKw
|
|
||||||
}): Array<EdgeTypes> => {
|
|
||||||
const tag: string | undefined = (() => {
|
|
||||||
switch (callExp.type) {
|
|
||||||
case 'CallExpression': {
|
|
||||||
const tag = getTagFromCallExpression(callExp)
|
|
||||||
if (err(tag)) return undefined
|
|
||||||
return tag
|
|
||||||
}
|
|
||||||
case 'CallExpressionKw': {
|
|
||||||
const tag = findKwArg(ARG_TAG, callExp)
|
|
||||||
if (tag === undefined) {
|
|
||||||
return undefined
|
|
||||||
}
|
|
||||||
if (tag.type !== 'TagDeclarator') {
|
|
||||||
return undefined
|
|
||||||
}
|
|
||||||
return tag.value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})()
|
|
||||||
if (err(tag)) return []
|
|
||||||
|
|
||||||
let inEdgeTreatment = false
|
|
||||||
let inObj = false
|
|
||||||
let inTagHelper: EdgeTypes | '' = ''
|
|
||||||
const edges: Array<EdgeTypes> = []
|
|
||||||
|
|
||||||
traverse(ast, {
|
|
||||||
enter: (node) => {
|
|
||||||
// Check if we are entering an edge treatment call
|
|
||||||
if (
|
|
||||||
(node.type === 'CallExpression' || node.type === 'CallExpressionKw') &&
|
|
||||||
isEdgeTreatmentType(node.callee.name.name)
|
|
||||||
) {
|
|
||||||
inEdgeTreatment = true
|
|
||||||
}
|
|
||||||
if (inEdgeTreatment && node.type === 'CallExpressionKw') {
|
|
||||||
node.arguments.forEach((prop) => {
|
|
||||||
if (
|
|
||||||
prop.label.name === 'tags' &&
|
|
||||||
prop.arg.type === 'ArrayExpression'
|
|
||||||
) {
|
|
||||||
inObj = true
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
if (inEdgeTreatment && node.type === 'ObjectExpression') {
|
|
||||||
node.properties.forEach((prop) => {
|
|
||||||
if (
|
|
||||||
prop.key.name === 'tags' &&
|
|
||||||
prop.value.type === 'ArrayExpression'
|
|
||||||
) {
|
|
||||||
inObj = true
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
if (
|
|
||||||
inObj &&
|
|
||||||
inEdgeTreatment &&
|
|
||||||
(node.type === 'CallExpression' || node.type === 'CallExpressionKw') &&
|
|
||||||
isEdgeType(node.callee.name.name)
|
|
||||||
) {
|
|
||||||
inTagHelper = node.callee.name.name
|
|
||||||
}
|
|
||||||
if (
|
|
||||||
inObj &&
|
|
||||||
inEdgeTreatment &&
|
|
||||||
!inTagHelper &&
|
|
||||||
node.type === 'Name' &&
|
|
||||||
node.name.name === tag
|
|
||||||
) {
|
|
||||||
edges.push('baseEdge')
|
|
||||||
}
|
|
||||||
if (
|
|
||||||
inObj &&
|
|
||||||
inEdgeTreatment &&
|
|
||||||
inTagHelper &&
|
|
||||||
node.type === 'Name' &&
|
|
||||||
node.name.name === tag
|
|
||||||
) {
|
|
||||||
edges.push(inTagHelper)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
leave: (node) => {
|
|
||||||
if (
|
|
||||||
(node.type === 'CallExpression' || node.type === 'CallExpressionKw') &&
|
|
||||||
isEdgeTreatmentType(node.callee.name.name)
|
|
||||||
) {
|
|
||||||
inEdgeTreatment = false
|
|
||||||
}
|
|
||||||
if (inEdgeTreatment && node.type === 'CallExpressionKw') {
|
|
||||||
node.arguments.forEach((prop) => {
|
|
||||||
if (
|
|
||||||
prop.label.name === 'tags' &&
|
|
||||||
prop.arg.type === 'ArrayExpression'
|
|
||||||
) {
|
|
||||||
inObj = true
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
if (inEdgeTreatment && node.type === 'ObjectExpression') {
|
|
||||||
node.properties.forEach((prop) => {
|
|
||||||
if (
|
|
||||||
prop.key.name === 'tags' &&
|
|
||||||
prop.value.type === 'ArrayExpression'
|
|
||||||
) {
|
|
||||||
inObj = true
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
if (
|
|
||||||
inObj &&
|
|
||||||
inEdgeTreatment &&
|
|
||||||
(node.type === 'CallExpression' || node.type === 'CallExpressionKw') &&
|
|
||||||
isEdgeType(node.callee.name.name)
|
|
||||||
) {
|
|
||||||
inTagHelper = ''
|
|
||||||
}
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
return edges
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delete Edge Treatment
|
// Delete Edge Treatment
|
||||||
export async function deleteEdgeTreatment(
|
export async function deleteEdgeTreatment(
|
||||||
ast: Node<Program>,
|
ast: Node<Program>,
|
||||||
|
@ -16,7 +16,6 @@
|
|||||||
|
|
||||||
import type {
|
import type {
|
||||||
ArtifactGraph,
|
ArtifactGraph,
|
||||||
CallExpression,
|
|
||||||
CallExpressionKw,
|
CallExpressionKw,
|
||||||
Expr,
|
Expr,
|
||||||
PathToNode,
|
PathToNode,
|
||||||
@ -35,7 +34,6 @@ import { getNodeFromPath } from '@src/lang/queryAst'
|
|||||||
import { getNodePathFromSourceRange } from '@src/lang/queryAstNodePathUtils'
|
import { getNodePathFromSourceRange } from '@src/lang/queryAstNodePathUtils'
|
||||||
import {
|
import {
|
||||||
addTagForSketchOnFace,
|
addTagForSketchOnFace,
|
||||||
sketchLineHelperMap,
|
|
||||||
sketchLineHelperMapKw,
|
sketchLineHelperMapKw,
|
||||||
} from '@src/lang/std/sketch'
|
} from '@src/lang/std/sketch'
|
||||||
import { err } from '@src/lib/trap'
|
import { err } from '@src/lib/trap'
|
||||||
@ -313,20 +311,15 @@ function modifyAstWithTagsForEdgeSelection(
|
|||||||
)
|
)
|
||||||
if (err(pathToSegmentNode)) return pathToSegmentNode
|
if (err(pathToSegmentNode)) return pathToSegmentNode
|
||||||
|
|
||||||
const segmentNode = getNodeFromPath<CallExpression | CallExpressionKw>(
|
const segmentNode = getNodeFromPath<CallExpressionKw>(
|
||||||
astClone,
|
astClone,
|
||||||
pathToSegmentNode,
|
pathToSegmentNode,
|
||||||
['CallExpression', 'CallExpressionKw']
|
['CallExpressionKw']
|
||||||
)
|
)
|
||||||
if (err(segmentNode)) return segmentNode
|
if (err(segmentNode)) return segmentNode
|
||||||
|
|
||||||
// Check whether selection is a valid segment
|
// Check whether selection is a valid segment
|
||||||
if (
|
if (!(segmentNode.node.callee.name.name in sketchLineHelperMapKw)) {
|
||||||
!(
|
|
||||||
segmentNode.node.callee.name.name in sketchLineHelperMap ||
|
|
||||||
segmentNode.node.callee.name.name in sketchLineHelperMapKw
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
return new Error('Selection is not a sketch segment')
|
return new Error('Selection is not a sketch segment')
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -540,20 +533,15 @@ function modifyAstWithTagForSketchSegment(
|
|||||||
// Clone AST
|
// Clone AST
|
||||||
const astClone = structuredClone(ast)
|
const astClone = structuredClone(ast)
|
||||||
|
|
||||||
const segmentNode = getNodeFromPath<CallExpression | CallExpressionKw>(
|
const segmentNode = getNodeFromPath<CallExpressionKw>(
|
||||||
astClone,
|
astClone,
|
||||||
pathToSegmentNode,
|
pathToSegmentNode,
|
||||||
['CallExpression', 'CallExpressionKw']
|
['CallExpressionKw']
|
||||||
)
|
)
|
||||||
if (err(segmentNode)) return segmentNode
|
if (err(segmentNode)) return segmentNode
|
||||||
|
|
||||||
// Check whether selection is a valid sketch segment
|
// Check whether selection is a valid sketch segment
|
||||||
if (
|
if (!(segmentNode.node.callee.name.name in sketchLineHelperMapKw)) {
|
||||||
!(
|
|
||||||
segmentNode.node.callee.name.name in sketchLineHelperMap ||
|
|
||||||
segmentNode.node.callee.name.name in sketchLineHelperMapKw
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
return new Error('Selection is not a sketch segment')
|
return new Error('Selection is not a sketch segment')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,17 +3,14 @@ import type { Node } from '@rust/kcl-lib/bindings/Node'
|
|||||||
import { getNodeFromPath } from '@src/lang/queryAst'
|
import { getNodeFromPath } from '@src/lang/queryAst'
|
||||||
import { getNodePathFromSourceRange } from '@src/lang/queryAstNodePathUtils'
|
import { getNodePathFromSourceRange } from '@src/lang/queryAstNodePathUtils'
|
||||||
import {
|
import {
|
||||||
addCloseToPipe,
|
|
||||||
addNewSketchLn,
|
|
||||||
addTagForSketchOnFace,
|
addTagForSketchOnFace,
|
||||||
changeSketchArguments,
|
changeSketchArguments,
|
||||||
getConstraintInfo,
|
|
||||||
getConstraintInfoKw,
|
getConstraintInfoKw,
|
||||||
getXComponent,
|
getXComponent,
|
||||||
getYComponent,
|
getYComponent,
|
||||||
} from '@src/lang/std/sketch'
|
} from '@src/lang/std/sketch'
|
||||||
import { topLevelRange } from '@src/lang/util'
|
import { topLevelRange } from '@src/lang/util'
|
||||||
import type { CallExpression, CallExpressionKw } from '@src/lang/wasm'
|
import type { CallExpressionKw } from '@src/lang/wasm'
|
||||||
import { assertParse, recast } from '@src/lang/wasm'
|
import { assertParse, recast } from '@src/lang/wasm'
|
||||||
import { initPromise } from '@src/lang/wasmUtils'
|
import { initPromise } from '@src/lang/wasmUtils'
|
||||||
import { enginelessExecutor } from '@src/lib/testHelpers'
|
import { enginelessExecutor } from '@src/lib/testHelpers'
|
||||||
@ -140,74 +137,6 @@ describe('testing changeSketchArguments', () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('testing addNewSketchLn', () => {
|
|
||||||
const lineToChange = 'line(endAbsolute = [-1.59, -1.54])'
|
|
||||||
test('addNewSketchLn', async () => {
|
|
||||||
// Enable rotations #152
|
|
||||||
const code = `
|
|
||||||
mySketch001 = startSketchOn(XY)
|
|
||||||
|> startProfile(at = [0, 0])
|
|
||||||
// |> rx(45, %)
|
|
||||||
|> line(endAbsolute = [-1.59, -1.54])
|
|
||||||
|> line(endAbsolute = [0.46, -5.82])`
|
|
||||||
const ast = assertParse(code)
|
|
||||||
|
|
||||||
const execState = await enginelessExecutor(ast)
|
|
||||||
const sourceStart = code.indexOf(lineToChange)
|
|
||||||
expect(sourceStart).toBe(87)
|
|
||||||
const newSketchLnRetVal = addNewSketchLn({
|
|
||||||
node: ast,
|
|
||||||
variables: execState.variables,
|
|
||||||
input: {
|
|
||||||
type: 'straight-segment',
|
|
||||||
from: [0, 0],
|
|
||||||
to: [2, 3],
|
|
||||||
},
|
|
||||||
fnName: 'lineTo',
|
|
||||||
pathToNode: [
|
|
||||||
['body', ''],
|
|
||||||
[0, 'index'],
|
|
||||||
['declaration', 'VariableDeclaration'],
|
|
||||||
['init', 'VariableDeclarator'],
|
|
||||||
],
|
|
||||||
})
|
|
||||||
if (err(newSketchLnRetVal)) return newSketchLnRetVal
|
|
||||||
|
|
||||||
// Enable rotations #152
|
|
||||||
let expectedCode = `mySketch001 = startSketchOn(XY)
|
|
||||||
|> startProfile(at = [0, 0])
|
|
||||||
// |> rx(45, %)
|
|
||||||
|> line(endAbsolute = [-1.59, -1.54])
|
|
||||||
|> line(endAbsolute = [0.46, -5.82])
|
|
||||||
|> line(endAbsolute = [2, 3])
|
|
||||||
`
|
|
||||||
|
|
||||||
const { modifiedAst } = newSketchLnRetVal
|
|
||||||
expect(recast(modifiedAst)).toBe(expectedCode)
|
|
||||||
|
|
||||||
const modifiedAst2 = addCloseToPipe({
|
|
||||||
node: ast,
|
|
||||||
variables: execState.variables,
|
|
||||||
pathToNode: [
|
|
||||||
['body', ''],
|
|
||||||
[0, 'index'],
|
|
||||||
['declaration', 'VariableDeclaration'],
|
|
||||||
['init', 'VariableDeclarator'],
|
|
||||||
],
|
|
||||||
})
|
|
||||||
if (err(modifiedAst2)) return modifiedAst2
|
|
||||||
|
|
||||||
expectedCode = `mySketch001 = startSketchOn(XY)
|
|
||||||
|> startProfile(at = [0, 0])
|
|
||||||
// |> rx(45, %)
|
|
||||||
|> line(endAbsolute = [-1.59, -1.54])
|
|
||||||
|> line(endAbsolute = [0.46, -5.82])
|
|
||||||
|> close()
|
|
||||||
`
|
|
||||||
expect(recast(modifiedAst2)).toBe(expectedCode)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
describe('testing addTagForSketchOnFace', () => {
|
describe('testing addTagForSketchOnFace', () => {
|
||||||
it('needs to be in it', async () => {
|
it('needs to be in it', async () => {
|
||||||
const originalLine = 'line(endAbsolute = [-1.59, -1.54])'
|
const originalLine = 'line(endAbsolute = [-1.59, -1.54])'
|
||||||
@ -669,16 +598,11 @@ describe('testing getConstraintInfo', () => {
|
|||||||
const sourceRange = topLevelRange(start, start + functionName.length)
|
const sourceRange = topLevelRange(start, start + functionName.length)
|
||||||
if (err(ast)) return ast
|
if (err(ast)) return ast
|
||||||
const pathToNode = getNodePathFromSourceRange(ast, sourceRange)
|
const pathToNode = getNodePathFromSourceRange(ast, sourceRange)
|
||||||
const callExp = getNodeFromPath<Node<CallExpression | CallExpressionKw>>(
|
const callExp = getNodeFromPath<Node<CallExpressionKw>>(ast, pathToNode, [
|
||||||
ast,
|
'CallExpressionKw',
|
||||||
pathToNode,
|
])
|
||||||
['CallExpression', 'CallExpressionKw']
|
|
||||||
)
|
|
||||||
if (err(callExp)) return callExp
|
if (err(callExp)) return callExp
|
||||||
const result =
|
const result = getConstraintInfoKw(callExp.node, code, pathToNode)
|
||||||
callExp.node.type === 'CallExpression'
|
|
||||||
? getConstraintInfo(callExp.node, code, pathToNode)
|
|
||||||
: getConstraintInfoKw(callExp.node, code, pathToNode)
|
|
||||||
expect(result).toEqual(expected)
|
expect(result).toEqual(expected)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@ -830,16 +754,11 @@ describe('testing getConstraintInfo', () => {
|
|||||||
const sourceRange = topLevelRange(start, start + functionName.length)
|
const sourceRange = topLevelRange(start, start + functionName.length)
|
||||||
if (err(ast)) return ast
|
if (err(ast)) return ast
|
||||||
const pathToNode = getNodePathFromSourceRange(ast, sourceRange)
|
const pathToNode = getNodePathFromSourceRange(ast, sourceRange)
|
||||||
const callExp = getNodeFromPath<Node<CallExpression | CallExpressionKw>>(
|
const callExp = getNodeFromPath<Node<CallExpressionKw>>(ast, pathToNode, [
|
||||||
ast,
|
'CallExpressionKw',
|
||||||
pathToNode,
|
])
|
||||||
['CallExpression', 'CallExpressionKw']
|
|
||||||
)
|
|
||||||
if (err(callExp)) return callExp
|
if (err(callExp)) return callExp
|
||||||
const result =
|
const result = getConstraintInfoKw(callExp.node, code, pathToNode)
|
||||||
callExp.node.type === 'CallExpression'
|
|
||||||
? getConstraintInfo(callExp.node, code, pathToNode)
|
|
||||||
: getConstraintInfoKw(callExp.node, code, pathToNode)
|
|
||||||
expect(result).toEqual(expected)
|
expect(result).toEqual(expected)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@ -1193,17 +1112,12 @@ describe('testing getConstraintInfo', () => {
|
|||||||
const sourceRange = topLevelRange(start, start + functionName.length)
|
const sourceRange = topLevelRange(start, start + functionName.length)
|
||||||
if (err(ast)) return ast
|
if (err(ast)) return ast
|
||||||
const pathToNode = getNodePathFromSourceRange(ast, sourceRange)
|
const pathToNode = getNodePathFromSourceRange(ast, sourceRange)
|
||||||
const callExp = getNodeFromPath<Node<CallExpression | CallExpressionKw>>(
|
const callExp = getNodeFromPath<Node<CallExpressionKw>>(ast, pathToNode, [
|
||||||
ast,
|
'CallExpressionKw',
|
||||||
pathToNode,
|
])
|
||||||
['CallExpression', 'CallExpressionKw']
|
|
||||||
)
|
|
||||||
if (err(callExp)) return callExp
|
if (err(callExp)) return callExp
|
||||||
|
|
||||||
const result =
|
const result = getConstraintInfoKw(callExp.node, code, pathToNode)
|
||||||
callExp.node.type === 'CallExpression'
|
|
||||||
? getConstraintInfo(callExp.node, code, pathToNode)
|
|
||||||
: getConstraintInfoKw(callExp.node, code, pathToNode)
|
|
||||||
expect(result).toEqual(expected)
|
expect(result).toEqual(expected)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -60,7 +60,6 @@ import type {
|
|||||||
SegmentInputs,
|
SegmentInputs,
|
||||||
SimplifiedArgDetails,
|
SimplifiedArgDetails,
|
||||||
SingleValueInput,
|
SingleValueInput,
|
||||||
SketchLineHelper,
|
|
||||||
SketchLineHelperKw,
|
SketchLineHelperKw,
|
||||||
addCall,
|
addCall,
|
||||||
} from '@src/lang/std/stdTypes'
|
} from '@src/lang/std/stdTypes'
|
||||||
@ -430,18 +429,6 @@ const horzVertConstraintInfoHelper = (
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
function getTag(index = 2): SketchLineHelper['getTag'] {
|
|
||||||
return (callExp: CallExpression) => {
|
|
||||||
if (callExp.type !== 'CallExpression')
|
|
||||||
return new Error('Not a CallExpression')
|
|
||||||
const arg = callExp.arguments?.[index]
|
|
||||||
if (!arg) return new Error('No argument')
|
|
||||||
if (arg.type !== 'TagDeclarator')
|
|
||||||
return new Error('Tag not a TagDeclarator')
|
|
||||||
return arg.value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function getTagKwArg(): SketchLineHelperKw['getTag'] {
|
function getTagKwArg(): SketchLineHelperKw['getTag'] {
|
||||||
return (callExp: CallExpressionKw) => {
|
return (callExp: CallExpressionKw) => {
|
||||||
if (callExp.type !== 'CallExpressionKw')
|
if (callExp.type !== 'CallExpressionKw')
|
||||||
@ -2947,7 +2934,7 @@ export const angledLineThatIntersects: SketchLineHelperKw = {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
export const updateStartProfileAtArgs: SketchLineHelper['updateArgs'] = ({
|
export const updateStartProfileAtArgs: SketchLineHelperKw['updateArgs'] = ({
|
||||||
node,
|
node,
|
||||||
pathToNode,
|
pathToNode,
|
||||||
input,
|
input,
|
||||||
@ -2995,10 +2982,6 @@ export const updateStartProfileAtArgs: SketchLineHelper['updateArgs'] = ({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Just remove this.
|
|
||||||
export const sketchLineHelperMap: { [key: string]: SketchLineHelper } =
|
|
||||||
{} as const
|
|
||||||
|
|
||||||
export const sketchLineHelperMapKw: { [key: string]: SketchLineHelperKw } = {
|
export const sketchLineHelperMapKw: { [key: string]: SketchLineHelperKw } = {
|
||||||
arc,
|
arc,
|
||||||
arcTo,
|
arcTo,
|
||||||
@ -3045,19 +3028,6 @@ export function changeSketchArguments(
|
|||||||
const { node: callExpression, shallowPath } = nodeMeta
|
const { node: callExpression, shallowPath } = nodeMeta
|
||||||
|
|
||||||
const fnName = callExpression?.callee?.name.name
|
const fnName = callExpression?.callee?.name.name
|
||||||
if (fnName in sketchLineHelperMap) {
|
|
||||||
const { updateArgs } = sketchLineHelperMap[callExpression.callee.name.name]
|
|
||||||
if (!updateArgs) {
|
|
||||||
return new Error('not a sketch line helper')
|
|
||||||
}
|
|
||||||
|
|
||||||
return updateArgs({
|
|
||||||
node: _node,
|
|
||||||
variables,
|
|
||||||
pathToNode: shallowPath,
|
|
||||||
input,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
if (fnName in sketchLineHelperMapKw) {
|
if (fnName in sketchLineHelperMapKw) {
|
||||||
const correctFnName =
|
const correctFnName =
|
||||||
callExpression.type === 'CallExpressionKw'
|
callExpression.type === 'CallExpressionKw'
|
||||||
@ -3170,22 +3140,6 @@ export function tooltipToFnName(tooltip: ToolTip): string | Error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getConstraintInfo(
|
|
||||||
callExpression: Node<CallExpression>,
|
|
||||||
code: string,
|
|
||||||
pathToNode: PathToNode,
|
|
||||||
filterValue?: string
|
|
||||||
): ConstrainInfo[] {
|
|
||||||
const fnName = callExpression?.callee?.name.name || ''
|
|
||||||
if (!(fnName in sketchLineHelperMap)) return []
|
|
||||||
return sketchLineHelperMap[fnName].getConstraintInfo(
|
|
||||||
callExpression,
|
|
||||||
code,
|
|
||||||
pathToNode,
|
|
||||||
filterValue
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getConstraintInfoKw(
|
export function getConstraintInfoKw(
|
||||||
callExpression: Node<CallExpressionKw>,
|
callExpression: Node<CallExpressionKw>,
|
||||||
code: string,
|
code: string,
|
||||||
@ -3264,8 +3218,7 @@ export function addNewSketchLn({
|
|||||||
}
|
}
|
||||||
| Error {
|
| Error {
|
||||||
const node = structuredClone(_node)
|
const node = structuredClone(_node)
|
||||||
const { add, updateArgs } =
|
const { add, updateArgs } = sketchLineHelperMapKw?.[fnName] || {}
|
||||||
sketchLineHelperMap?.[fnName] || sketchLineHelperMapKw?.[fnName] || {}
|
|
||||||
if (!add || !updateArgs) {
|
if (!add || !updateArgs) {
|
||||||
return new Error(`${fnName} is not a sketch line helper`)
|
return new Error(`${fnName} is not a sketch line helper`)
|
||||||
}
|
}
|
||||||
@ -3275,7 +3228,7 @@ export function addNewSketchLn({
|
|||||||
pathToNode,
|
pathToNode,
|
||||||
'VariableDeclarator'
|
'VariableDeclarator'
|
||||||
)
|
)
|
||||||
getNodeFromPath<Node<PipeExpression | CallExpression | CallExpressionKw>>(
|
getNodeFromPath<Node<PipeExpression | CallExpressionKw>>(
|
||||||
node,
|
node,
|
||||||
pathToNode,
|
pathToNode,
|
||||||
'PipeExpression'
|
'PipeExpression'
|
||||||
@ -3289,7 +3242,6 @@ export function addNewSketchLn({
|
|||||||
snaps,
|
snaps,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export function addCallExpressionsToPipe({
|
export function addCallExpressionsToPipe({
|
||||||
node,
|
node,
|
||||||
pathToNode,
|
pathToNode,
|
||||||
@ -3367,10 +3319,7 @@ export function replaceSketchLine({
|
|||||||
}
|
}
|
||||||
const _node = { ...node }
|
const _node = { ...node }
|
||||||
|
|
||||||
const { add } =
|
const { add } = sketchLineHelperMapKw[fnName]
|
||||||
sketchLineHelperMap[fnName] === undefined
|
|
||||||
? sketchLineHelperMapKw[fnName]
|
|
||||||
: sketchLineHelperMap[fnName]
|
|
||||||
const addRetVal = add({
|
const addRetVal = add({
|
||||||
node: _node,
|
node: _node,
|
||||||
variables,
|
variables,
|
||||||
@ -3561,24 +3510,9 @@ export function addTagForSketchOnFace(
|
|||||||
const { addTag } = sketchLineHelperMapKw[expressionName]
|
const { addTag } = sketchLineHelperMapKw[expressionName]
|
||||||
return addTag(tagInfo)
|
return addTag(tagInfo)
|
||||||
}
|
}
|
||||||
if (expressionName in sketchLineHelperMap) {
|
|
||||||
const { addTag } = sketchLineHelperMap[expressionName]
|
|
||||||
return addTag(tagInfo)
|
|
||||||
}
|
|
||||||
return new Error(`"${expressionName}" is not a sketch line helper`)
|
return new Error(`"${expressionName}" is not a sketch line helper`)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getTagFromCallExpression(
|
|
||||||
callExp: CallExpression
|
|
||||||
): string | Error {
|
|
||||||
if (callExp.callee.name.name === 'close') return getTag(1)(callExp)
|
|
||||||
if (callExp.callee.name.name in sketchLineHelperMap) {
|
|
||||||
const { getTag } = sketchLineHelperMap[callExp.callee.name.name]
|
|
||||||
return getTag(callExp)
|
|
||||||
}
|
|
||||||
return new Error(`"${callExp.callee.name.name}" is not a sketch line helper`)
|
|
||||||
}
|
|
||||||
|
|
||||||
function isAngleLiteral(lineArgument: Expr): boolean {
|
function isAngleLiteral(lineArgument: Expr): boolean {
|
||||||
return isLiteralArrayOrStatic(lineArgument)
|
return isLiteralArrayOrStatic(lineArgument)
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,6 @@ import {
|
|||||||
getArc,
|
getArc,
|
||||||
getArgForEnd,
|
getArgForEnd,
|
||||||
getCircle,
|
getCircle,
|
||||||
getConstraintInfo,
|
|
||||||
getConstraintInfoKw,
|
getConstraintInfoKw,
|
||||||
getFirstArg,
|
getFirstArg,
|
||||||
isAbsoluteLine,
|
isAbsoluteLine,
|
||||||
@ -1996,38 +1995,14 @@ export function transformAstSketchLines({
|
|||||||
const getNode = getNodeFromPathCurry(node, _pathToNode)
|
const getNode = getNodeFromPathCurry(node, _pathToNode)
|
||||||
|
|
||||||
// Find `call` which could either be a positional-arg or keyword-arg call.
|
// Find `call` which could either be a positional-arg or keyword-arg call.
|
||||||
const callExp = getNode<Node<CallExpression>>('CallExpression')
|
const call = getNode<Node<CallExpressionKw>>('CallExpressionKw')
|
||||||
const callExpKw = getNode<Node<CallExpressionKw>>('CallExpressionKw')
|
|
||||||
const call =
|
|
||||||
!err(callExp) && callExp.node.type === 'CallExpression'
|
|
||||||
? callExp
|
|
||||||
: callExpKw
|
|
||||||
if (err(call)) return call
|
if (err(call)) return call
|
||||||
|
|
||||||
const varDec = getNode<VariableDeclarator>('VariableDeclarator')
|
const varDec = getNode<VariableDeclarator>('VariableDeclarator')
|
||||||
if (err(varDec)) return varDec
|
if (err(varDec)) return varDec
|
||||||
|
|
||||||
const callBackTag = (() => {
|
const callBackTag = findKwArg(ARG_TAG, call.node)
|
||||||
switch (call.node.type) {
|
const _referencedSegmentNameVal = findKwArg('intersectTag', call.node)
|
||||||
case 'CallExpression':
|
|
||||||
return call.node.arguments[2]
|
|
||||||
case 'CallExpressionKw':
|
|
||||||
return findKwArg(ARG_TAG, call.node)
|
|
||||||
}
|
|
||||||
})()
|
|
||||||
const _referencedSegmentNameVal = (() => {
|
|
||||||
switch (call.node.type) {
|
|
||||||
case 'CallExpressionKw':
|
|
||||||
return findKwArg('intersectTag', call.node)
|
|
||||||
case 'CallExpression':
|
|
||||||
return (
|
|
||||||
call.node.arguments[0]?.type === 'ObjectExpression' &&
|
|
||||||
call.node.arguments[0].properties?.find(
|
|
||||||
(prop) => prop.key.name === 'intersectTag'
|
|
||||||
)?.value
|
|
||||||
)
|
|
||||||
}
|
|
||||||
})()
|
|
||||||
const _referencedSegmentName =
|
const _referencedSegmentName =
|
||||||
referenceSegName ||
|
referenceSegName ||
|
||||||
(_referencedSegmentNameVal &&
|
(_referencedSegmentNameVal &&
|
||||||
@ -2036,14 +2011,7 @@ export function transformAstSketchLines({
|
|||||||
''
|
''
|
||||||
const inputs: InputArgs = []
|
const inputs: InputArgs = []
|
||||||
|
|
||||||
const constraints = (() => {
|
const constraints = getConstraintInfoKw(call.node, '', _pathToNode)
|
||||||
switch (call.node.type) {
|
|
||||||
case 'CallExpression':
|
|
||||||
return getConstraintInfo(call.node, '', _pathToNode)
|
|
||||||
case 'CallExpressionKw':
|
|
||||||
return getConstraintInfoKw(call.node, '', _pathToNode)
|
|
||||||
}
|
|
||||||
})()
|
|
||||||
constraints.forEach((a) => {
|
constraints.forEach((a) => {
|
||||||
if (
|
if (
|
||||||
a.type === 'tangentialWithPrevious' ||
|
a.type === 'tangentialWithPrevious' ||
|
||||||
|
Reference in New Issue
Block a user