Generate angle suffixes in the frontend

Signed-off-by: Nick Cameron <nrc@ncameron.org>
This commit is contained in:
Nick Cameron
2025-06-17 16:00:45 +12:00
parent 77e5d6e3a5
commit 8c36105113
29 changed files with 404 additions and 398 deletions

1
package-lock.json generated
View File

@ -2495,6 +2495,7 @@
},
"node_modules/@clack/prompts/node_modules/is-unicode-supported": {
"version": "1.3.0",
"extraneous": true,
"inBundle": true,
"license": "MIT",
"engines": {

View File

@ -231,10 +231,9 @@ impl Program {
pub fn change_default_units(
&self,
length_units: Option<execution::types::UnitLen>,
angle_units: Option<execution::types::UnitAngle>,
) -> Result<Self, KclError> {
Ok(Self {
ast: self.ast.change_default_units(length_units, angle_units)?,
ast: self.ast.change_default_units(length_units)?,
original_file_contents: self.original_file_contents.clone(),
})
}

View File

@ -28,7 +28,7 @@ use crate::{
errors::KclError,
execution::{
annotations,
types::{ArrayLen, UnitAngle, UnitLen},
types::{ArrayLen, UnitLen},
KclValue, Metadata, TagIdentifier,
},
parsing::{ast::digest::Digest, token::NumericSuffix, PIPE_OPERATOR},
@ -360,7 +360,6 @@ impl Node<Program> {
pub fn change_default_units(
&self,
length_units: Option<UnitLen>,
angle_units: Option<UnitAngle>,
) -> Result<Self, KclError> {
let mut new_program = self.clone();
let mut found = false;
@ -372,13 +371,6 @@ impl Node<Program> {
Expr::Name(Box::new(Name::new(&len.to_string()))),
);
}
if let Some(angle) = angle_units {
node.inner.add_or_update(
annotations::SETTINGS_UNIT_ANGLE,
Expr::Name(Box::new(Name::new(&angle.to_string()))),
);
}
// Previous source range no longer makes sense, but we want to
// preserve other things like comments.
node.reset_source();
@ -395,12 +387,6 @@ impl Node<Program> {
Expr::Name(Box::new(Name::new(&len.to_string()))),
);
}
if let Some(angle) = angle_units {
settings.inner.add_or_update(
annotations::SETTINGS_UNIT_ANGLE,
Expr::Name(Box::new(Name::new(&angle.to_string()))),
);
}
new_program.inner_attrs.push(settings);
}
@ -4256,7 +4242,7 @@ startSketchOn(XY)"#;
// Edit the ast.
let new_program = program
.change_default_units(Some(crate::execution::types::UnitLen::Mm), None)
.change_default_units(Some(crate::execution::types::UnitLen::Mm))
.unwrap();
let result = new_program.meta_settings().unwrap();
@ -4285,7 +4271,7 @@ startSketchOn(XY)
// Edit the ast.
let new_program = program
.change_default_units(Some(crate::execution::types::UnitLen::Mm), None)
.change_default_units(Some(crate::execution::types::UnitLen::Mm))
.unwrap();
let result = new_program.meta_settings().unwrap();
@ -4320,7 +4306,7 @@ startSketchOn(XY)
let program = crate::parsing::top_level_parse(code).unwrap();
let new_program = program
.change_default_units(Some(crate::execution::types::UnitLen::Cm), None)
.change_default_units(Some(crate::execution::types::UnitLen::Cm))
.unwrap();
let result = new_program.meta_settings().unwrap();

View File

@ -289,14 +289,13 @@ pub fn kcl_settings(program_json: &str) -> Result<JsValue, String> {
/// Takes a kcl string and Meta settings and changes the meta settings in the kcl string.
#[wasm_bindgen]
pub fn change_default_units(code: &str, len_str: &str, angle_str: &str) -> Result<String, String> {
pub fn change_default_units(code: &str, len_str: &str) -> Result<String, String> {
console_error_panic_hook::set_once();
let len: Option<kcl_lib::UnitLen> = serde_json::from_str(len_str).map_err(|e| e.to_string())?;
let angle: Option<kcl_lib::UnitAngle> = serde_json::from_str(angle_str).map_err(|e| e.to_string())?;
let program = Program::parse_no_errs(code).map_err(|e| e.to_string())?;
let new_program = program.change_default_units(len, angle).map_err(|e| e.to_string())?;
let new_program = program.change_default_units(len).map_err(|e| e.to_string())?;
let formatted = new_program.recast();

View File

@ -22,7 +22,7 @@ type ModalResolve = {
type ModalReject = boolean
type SetAngleLengthModalProps = InstanceProps<ModalResolve, ModalReject> & {
value: number
value: string
valueName: string
shouldCreateVariable?: boolean
}
@ -41,8 +41,10 @@ export const SetAngleLengthModal = ({
valueName,
shouldCreateVariable: initialShouldCreateVariable = false,
}: SetAngleLengthModalProps) => {
const [sign, setSign] = useState(Math.sign(Number(initialValue)))
const [value, setValue] = useState(String(initialValue * sign))
const [sign, setSign] = useState(initialValue.startsWith('-') ? -1 : 1)
const [value, setValue] = useState(
initialValue.startsWith('-') ? initialValue.substring(1) : initialValue
)
const [shouldCreateVariable, setShouldCreateVariable] = useState(
initialShouldCreateVariable
)

View File

@ -25,7 +25,7 @@ type ModalReject = boolean
type GetInfoModalProps = InstanceProps<ModalResolve, ModalReject> & {
segName: string
isSegNameEditable: boolean
value?: number
value?: string
initialVariableName: string
}
@ -44,10 +44,12 @@ export const GetInfoModal = ({
value: initialValue,
initialVariableName,
}: GetInfoModalProps) => {
const [sign, setSign] = useState(Math.sign(Number(initialValue)))
const [sign, setSign] = useState(initialValue?.startsWith('-') ? -1 : 1)
const [segName, setSegName] = useState(initialSegName)
const [value, setValue] = useState(
initialValue === undefined ? '' : String(Math.abs(initialValue))
initialValue?.startsWith('-')
? initialValue.substring(1)
: initialValue || ''
)
const [shouldCreateVariable, setShouldCreateVariable] = useState(false)

View File

@ -171,7 +171,7 @@ export async function applyConstraintIntersect({
if (
!variableName &&
segName === tagInfo?.tag &&
Number(value) === valueUsedInTransform
value === valueUsedInTransform
) {
return {
modifiedAst,

View File

@ -108,7 +108,7 @@ export async function applyConstraintAbsDistance({
if (err(transform1)) return Promise.reject(transform1)
const { valueUsedInTransform } = transform1
let forceVal = valueUsedInTransform || 0
let forceVal = valueUsedInTransform || ''
const { valueNode, variableName, newVariableInsertIndex, sign } =
await getModalInfo({
value: forceVal,

View File

@ -120,7 +120,7 @@ export async function applyConstraintAngleBetween({
} as any)
if (
segName === tagInfo?.tag &&
Number(value) === valueUsedInTransform &&
value === valueUsedInTransform &&
!variableName
) {
return {

View File

@ -127,7 +127,7 @@ export async function applyConstraintHorzVertDistance({
if (
!variableName &&
segName === tagInfo?.tag &&
Number(value) === valueUsedInTransform
value === valueUsedInTransform
) {
return {
modifiedAst,

View File

@ -122,25 +122,36 @@ export async function applyConstraintAngleLength({
const isReferencingXAxisAngle =
isReferencingXAxis && angleOrLength === 'setAngle'
let forceVal = valueUsedInTransform || 0
let forceVal = valueUsedInTransform || ''
// TODO it would be better to preserve the units, but its an edge case for now.
let degrees
if (forceVal.endsWith('rad')) {
degrees =
Number(forceVal.substring(0, forceVal.length - 3)) * (180 / Math.PI)
} else {
if (forceVal.endsWith('deg')) {
forceVal = forceVal.substring(0, forceVal.length - 3)
}
degrees = Number(forceVal)
}
let calcIdentifier = createName(['turns'], 'ZERO')
if (isReferencingYAxisAngle) {
calcIdentifier = createName(
['turns'],
forceVal < 0 ? 'THREE_QUARTER_TURN' : 'QUARTER_TURN'
degrees < 0 ? 'THREE_QUARTER_TURN' : 'QUARTER_TURN'
)
forceVal = normaliseAngle(forceVal + (forceVal < 0 ? 90 : -90))
degrees = normaliseAngle(degrees + (degrees < 0 ? 90 : -90))
} else if (isReferencingXAxisAngle) {
calcIdentifier = createName(
['turns'],
Math.abs(forceVal) > 90 ? 'HALF_TURN' : 'ZERO'
Math.abs(degrees) > 90 ? 'HALF_TURN' : 'ZERO'
)
forceVal =
Math.abs(forceVal) > 90 ? normaliseAngle(forceVal - 180) : forceVal
degrees = Math.abs(degrees) > 90 ? normaliseAngle(degrees - 180) : forceVal
}
const { valueNode, variableName, newVariableInsertIndex, sign } =
await getModalInfo({
value: forceVal,
value: String(degrees) + 'deg',
valueName: angleOrLength === 'setAngle' ? 'angle' : 'length',
shouldCreateVariable: true,
})

View File

@ -2,11 +2,7 @@ import { Popover } from '@headlessui/react'
import { useEffect, useState } from 'react'
import toast from 'react-hot-toast'
import {
changeDefaultUnits,
unitAngleToUnitAng,
unitLengthToUnitLen,
} from '@src/lang/wasm'
import { changeDefaultUnits, unitLengthToUnitLen } from '@src/lang/wasm'
import { DEFAULT_DEFAULT_LENGTH_UNIT } from '@src/lib/constants'
import { baseUnitLabels, baseUnitsUnion } from '@src/lib/settings/settingsTypes'
import { codeManager, kclManager } from '@src/lib/singletons'
@ -48,8 +44,7 @@ export function UnitsMenu() {
onClick={() => {
const newCode = changeDefaultUnits(
codeManager.code,
unitLengthToUnitLen(unit),
unitAngleToUnitAng(undefined)
unitLengthToUnitLen(unit)
)
if (err(newCode)) {
toast.error(

View File

@ -20,7 +20,7 @@ import type {
Identifier,
LabeledArg,
Literal,
LiteralValue,
NumericSuffix,
ObjectExpression,
PathToNode,
PipeExpression,
@ -31,60 +31,77 @@ import type {
VariableDeclaration,
VariableDeclarator,
} from '@src/lang/wasm'
import { formatNumberLiteral } from '@src/lang/wasm'
import { err } from '@src/lib/trap'
export function createLiteral(value: number | string | boolean): Node<Literal> {
export function createLiteral(
value: number | string | boolean,
suffix?: NumericSuffix
): Node<Literal> {
// TODO: Should we handle string escape sequences?
return {
type: 'Literal',
start: 0,
end: 0,
moduleId: 0,
value: typeof value === 'number' ? { value, suffix: 'None' } : value,
raw: `${value}`,
value:
typeof value === 'number'
? { value, suffix: suffix ? suffix : 'None' }
: value,
raw: createRawStr(value, suffix),
outerAttrs: [],
preComments: [],
commentStart: 0,
}
}
/**
* Note: This depends on WASM, but it's not async. Callers are responsible for
* awaiting init of the WASM module.
*/
export function createLiteralMaybeSuffix(
value: LiteralValue
): Node<Literal> | Error {
if (typeof value === 'string' || typeof value === 'boolean') {
return createLiteral(value)
function createRawStr(
value: number | string | boolean,
suffix?: NumericSuffix
): string {
if (typeof value !== 'number' || !suffix) {
return `${value}`
}
let raw: string
if (typeof value.value === 'number' && value.suffix === 'None') {
// Fast path for numbers when there are no units.
raw = `${value.value}`
} else {
const formatted = formatNumberLiteral(value.value, value.suffix)
if (err(formatted)) {
return new Error(
`Invalid number literal: value=${value.value}, suffix=${value.suffix}`,
{ cause: formatted }
)
}
raw = formatted
}
return {
type: 'Literal',
start: 0,
end: 0,
moduleId: 0,
value,
raw,
outerAttrs: [],
preComments: [],
commentStart: 0,
let sufStr
switch (suffix) {
case 'None':
case 'Length':
case 'Angle':
sufStr = ''
break
case 'Count':
sufStr = '_'
break
case 'Mm':
sufStr = 'mm'
break
case 'Cm':
sufStr = 'cm'
break
case 'M':
sufStr = 'm'
break
case 'Inch':
sufStr = 'in'
break
case 'Ft':
sufStr = 'ft'
break
case 'Yd':
sufStr = 'yd'
break
case 'Deg':
sufStr = 'deg'
break
case 'Rad':
sufStr = 'rad'
break
case 'Unknown':
sufStr = '_?'
break
}
return `${value}${sufStr}`
}
export function createTagDeclarator(value: string): Node<TagDeclarator> {

View File

@ -4,7 +4,6 @@ import {
createArrayExpression,
createIdentifier,
createLiteral,
createLiteralMaybeSuffix,
createObjectExpression,
createPipeExpression,
createPipeSubstitution,
@ -24,13 +23,12 @@ import { getNodePathFromSourceRange } from '@src/lang/queryAstNodePathUtils'
import type { Artifact } from '@src/lang/std/artifactGraph'
import { codeRefFromRange } from '@src/lang/std/artifactGraph'
import { topLevelRange } from '@src/lang/util'
import type { Identifier, Literal, LiteralValue } from '@src/lang/wasm'
import type { Identifier, Literal } from '@src/lang/wasm'
import { assertParse, recast } from '@src/lang/wasm'
import { initPromise } from '@src/lang/wasmUtils'
import { enginelessExecutor } from '@src/lib/testHelpers'
import { err } from '@src/lib/trap'
import { deleteFromSelection } from '@src/lang/modifyAst/deleteFromSelection'
import { assertNotErr } from '@src/unitTestUtils'
beforeAll(async () => {
await initPromise
@ -45,9 +43,7 @@ describe('Testing createLiteral', () => {
expect((result as Literal).raw).toBe('5')
})
it('should create a literal number with units', () => {
const lit: LiteralValue = { value: 5, suffix: 'Mm' }
const result = createLiteralMaybeSuffix(lit)
assertNotErr(result)
const result = createLiteral(5, 'Mm')
expect(result.type).toBe('Literal')
expect((result as any).value.value).toBe(5)
expect((result as any).value.suffix).toBe('Mm')
@ -305,24 +301,24 @@ describe('Testing moveValueIntoNewVariable', () => {
`
const code = `${fn('def')}${fn('jkl')}${fn('hmm')}
fn ghi(@x) {
return 2
return 2deg
}
abc = 3
abc = 3deg
identifierGuy = 5
yo = 5 + 6
yo = 5deg + 6deg
part001 = startSketchOn(XY)
|> startProfile(at = [-1.2, 4.83])
|> line(end = [2.8, 0])
|> angledLine(angle = 100 + 100, length = 3.09)
|> angledLine(angle = 100deg + 100deg, length = 3.09)
|> angledLine(angle = abc, length = 3.09)
|> angledLine(angle = def(yo), length = 3.09)
|> angledLine(angle = ghi(%), length = 3.09)
|> angledLine(angle = jkl(yo) + 2, length = 3.09)
|> angledLine(angle = jkl(yo) + 2deg, length = 3.09)
yo2 = hmm([identifierGuy + 5])`
it('should move a binary expression into a new variable', async () => {
const ast = assertParse(code)
const execState = await enginelessExecutor(ast)
const startIndex = code.indexOf('100 + 100') + 1
const startIndex = code.indexOf('100deg + 100deg') + 1
const { modifiedAst } = moveValueIntoNewVariable(
ast,
execState.variables,
@ -330,7 +326,7 @@ yo2 = hmm([identifierGuy + 5])`
'newVar'
)
const newCode = recast(modifiedAst)
expect(newCode).toContain(`newVar = 100 + 100`)
expect(newCode).toContain(`newVar = 100deg + 100deg`)
expect(newCode).toContain(`angledLine(angle = newVar, length = 3.09)`)
})
it('should move a value into a new variable', async () => {
@ -372,7 +368,7 @@ yo2 = hmm([identifierGuy + 5])`
'newVar'
)
const newCode = recast(modifiedAst)
expect(newCode).toContain(`newVar = jkl(yo) + 2`)
expect(newCode).toContain(`newVar = jkl(yo) + 2deg`)
expect(newCode).toContain(`angledLine(angle = newVar, length = 3.09)`)
})
it('should move a identifier into a new variable', async () => {
@ -587,7 +583,7 @@ describe('Testing deleteSegmentFromPipeExpression', () => {
) => `part001 = startSketchOn(-XZ)
|> startProfile(at = [54.78, -95.91])
|> line(end = [306.21, 198.82], tag = $b)
${!replace1 ? ` |> ${line}\n` : ''} |> angledLine(angle = -65, length = ${
${!replace1 ? ` |> ${line}\n` : ''} |> angledLine(angle = -65deg, length = ${
!replace1 ? 'segLen(a)' : replace1
})
|> line(end = [306.21, 198.87])
@ -595,45 +591,49 @@ ${!replace1 ? ` |> ${line}\n` : ''} |> angledLine(angle = -65, length = ${
|> line(end = [-963.39, -154.67])
`
test.each([
['line', 'line(end = [306.21, 198.85], tag = $a)', ['365.11', '33']],
['line', 'line(end = [306.21, 198.85], tag = $a)', ['365.11', '33deg']],
[
'lineTo',
'line(endAbsolute = [306.21, 198.85], tag = $a)',
['110.48', '120'],
['110.48', '120deg'],
],
['yLine', 'yLine(length = 198.85, tag = $a)', ['198.85', '90']],
['xLine', 'xLine(length = 198.85, tag = $a)', ['198.85', '0']],
['yLineTo', 'yLine(endAbsolute = 198.85, tag = $a)', ['95.94', '90']],
['xLineTo', 'xLine(endAbsolute = 198.85, tag = $a)', ['162.14', '180']],
['yLine', 'yLine(length = 198.85, tag = $a)', ['198.85', '90deg']],
['xLine', 'xLine(length = 198.85, tag = $a)', ['198.85', '0deg']],
['yLineTo', 'yLine(endAbsolute = 198.85, tag = $a)', ['95.94', '90deg']],
[
'angledLine',
'angledLine(angle = 45.5, length = 198.85, tag = $a)',
['198.85', '46'],
'xLineTo',
'xLine(endAbsolute = 198.85, tag = $a)',
['162.14', '180deg'],
],
[
'angledLine',
'angledLine(angle = 45.5, lengthX = 198.85, tag = $a)',
['283.7', '46'],
'angledLine(angle = 45.5deg, length = 198.85, tag = $a)',
['198.85', '46deg'],
],
[
'angledLine',
'angledLine(angle = 45.5, lengthY = 198.85, tag = $a)',
['278.79', '46'],
'angledLine(angle = 45.5deg, lengthX = 198.85, tag = $a)',
['283.7', '46deg'],
],
[
'angledLine',
'angledLine(angle = 45.5, endAbsoluteX = 198.85, tag = $a)',
['231.33', '-134'],
'angledLine(angle = 45.5deg, lengthY = 198.85, tag = $a)',
['278.79', '46deg'],
],
[
'angledLine',
'angledLine(angle = 45.5, endAbsoluteY = 198.85, tag = $a)',
['134.51', '46'],
'angledLine(angle = 45.5deg, endAbsoluteX = 198.85, tag = $a)',
['231.33', '-134deg'],
],
[
'angledLine',
'angledLine(angle = 45.5deg, endAbsoluteY = 198.85, tag = $a)',
['134.51', '46deg'],
],
[
'angledLineThatIntersects',
`angledLineThatIntersects(angle = 45.5, intersectTag = b, offset = 198.85, tag = $a)`,
['918.4', '46'],
`angledLineThatIntersects(angle = 45.5deg, intersectTag = b, offset = 198.85, tag = $a)`,
['918.4', '46deg'],
],
])(`%s`, async (_, line, [replace1, replace2]) => {
const code = makeCode(line)
@ -724,7 +724,7 @@ sketch003 = startSketchOn(XZ)
// |> startProfile(at = [-12.55, 2.89])
// |> line(end = [3.02, 1.9])
// |> line(end = [1.82, -1.49], tag = $seg02)
// |> angledLine(angle = -86, length = segLen(seg02))
// |> angledLine(angle = -86deg, length = segLen(seg02))
// |> line(end = [-3.97, -0.53])
// |> line(end = [0.3, 0.84])
// |> line(endAbsolute = [profileStartX(%), profileStartY(%)])
@ -749,7 +749,7 @@ sketch003 = startSketchOn(XZ)
// |> startProfile(at = [-12.55, 2.89])
// |> line(end = [3.02, 1.9])
// |> line(end = [1.82, -1.49], tag = $seg02)
// |> angledLine(angle = -86, length = segLen(seg02))
// |> angledLine(angle = -86deg, length = segLen(seg02))
// |> line(end = [-3.97, -0.53])
// |> line(end = [0.3, 0.84])
// |> line(endAbsolute = [profileStartX(%), profileStartY(%)])
@ -778,7 +778,7 @@ sketch003 = startSketchOn(XZ)
// |> startProfile(at = [-12.55, 2.89])
// |> line(end = [3.02, 1.9])
// |> line(end = [1.82, -1.49], tag = $seg02)
// |> angledLine(angle = -86, length = segLen(seg02))
// |> angledLine(angle = -86deg, length = segLen(seg02))
// |> line(end = [-3.97, -0.53])
// |> line(end = [0.3, 0.84])
// |> line(endAbsolute = [profileStartX(%), profileStartY(%)])
@ -803,7 +803,7 @@ sketch003 = startSketchOn(XZ)
// |> startProfile(at = [-12.55, 2.89])
// |> line(end = [3.02, 1.9])
// |> line(end = [1.82, -1.49], tag = $seg02)
// |> angledLine(angle = -86, length = segLen(seg02))
// |> angledLine(angle = -86deg, length = segLen(seg02))
// |> line(end = [-3.97, -0.53])
// |> line(end = [0.3, 0.84])
// |> line(endAbsolute = [profileStartX(%), profileStartY(%)])

View File

@ -1,10 +1,6 @@
import type { UnitLength } from '@rust/kcl-lib/bindings/ModelingCmd'
import {
changeDefaultUnits,
unitAngleToUnitAng,
unitLengthToUnitLen,
} from '@src/lang/wasm'
import { changeDefaultUnits, unitLengthToUnitLen } from '@src/lang/wasm'
import { DEFAULT_DEFAULT_LENGTH_UNIT } from '@src/lib/constants'
/**
@ -26,9 +22,5 @@ export function newKclFile(
return ''
}
return changeDefaultUnits(
'',
unitLengthToUnitLen(defaultLengthUnit),
unitAngleToUnitAng(undefined)
)
return changeDefaultUnits('', unitLengthToUnitLen(defaultLengthUnit))
}

View File

@ -204,7 +204,7 @@ describe('testing addTagForSketchOnFace', () => {
const genCode = (insertCode: string) => `sketch001 = startSketchOn(XZ)
|> startProfile(at = [75.8, 317.2]) // [$startCapTag, $EndCapTag]
|> angledLine(angle = 0, length = 268.43, tag = $rectangleSegmentA001)
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 217.26, tag = $seg01)
|> angledLine(angle = segAng(rectangleSegmentA001) - 90deg, length = 217.26, tag = $seg01)
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001))
|> line(endAbsolute = [profileStartX(%), profileStartY(%)], tag = $seg02)
|> close()
@ -281,18 +281,18 @@ describe('testing getConstraintInfo', () => {
const code = `part001 = startSketchOn(-XZ)
|> startProfile(at = [0,0])
|> line(end = [3, 4])
|> angledLine(angle = 3.14, length = 3.14)
|> angledLine(angle = 3.14deg, length = 3.14)
|> line(endAbsolute = [6.14, 3.14])
|> xLine(endAbsolute = 8)
|> yLine(endAbsolute = 5)
|> yLine(length = 3.14, tag = $a)
|> xLine(length = 3.14)
|> angledLine(angle = 3.14, lengthX = 3.14)
|> angledLine(angle = 30, lengthY = 3)
|> angledLine(angle = 12.14, endAbsoluteX = 12)
|> angledLine(angle = 30, endAbsoluteY = 10.14)
|> angledLine(angle = 3.14deg, lengthX = 3.14)
|> angledLine(angle = 30deg, lengthY = 3)
|> angledLine(angle = 12.14deg, endAbsoluteX = 12)
|> angledLine(angle = 30deg, endAbsoluteY = 10.14)
|> angledLineThatIntersects(
angle = 3.14,
angle = 3.14deg,
intersectTag = a,
offset = 0,
)
@ -327,7 +327,7 @@ describe('testing getConstraintInfo', () => {
{
type: 'angle',
isConstrained: false,
value: '3.14',
value: '3.14deg',
sourceRange: [expect.any(Number), expect.any(Number), 0],
argPosition: { type: 'labeledArg', key: 'angle' },
pathToNode: expect.any(Array),
@ -473,7 +473,7 @@ describe('testing getConstraintInfo', () => {
{
type: 'angle',
isConstrained: false,
value: '3.14',
value: '3.14deg',
sourceRange: [expect.any(Number), expect.any(Number), 0],
argPosition: { type: 'labeledArg', key: 'angle' },
pathToNode: expect.any(Array),
@ -496,7 +496,7 @@ describe('testing getConstraintInfo', () => {
{
type: 'angle',
isConstrained: false,
value: '30',
value: '30deg',
sourceRange: [expect.any(Number), expect.any(Number), 0],
argPosition: { type: 'labeledArg', key: 'angle' },
pathToNode: expect.any(Array),
@ -519,7 +519,7 @@ describe('testing getConstraintInfo', () => {
{
type: 'angle',
isConstrained: false,
value: '12.14',
value: '12.14deg',
sourceRange: [expect.any(Number), expect.any(Number), 0],
argPosition: { type: 'labeledArg', key: 'angle' },
pathToNode: expect.any(Array),
@ -542,7 +542,7 @@ describe('testing getConstraintInfo', () => {
{
type: 'angle',
isConstrained: false,
value: '30',
value: '30deg',
sourceRange: [expect.any(Number), expect.any(Number), 0],
argPosition: { type: 'labeledArg', key: 'angle' },
pathToNode: expect.any(Array),
@ -565,7 +565,7 @@ describe('testing getConstraintInfo', () => {
{
type: 'angle',
isConstrained: false,
value: '3.14',
value: '3.14deg',
sourceRange: [expect.any(Number), expect.any(Number), 0],
argPosition: { type: 'labeledArg', key: 'angle' },
pathToNode: expect.any(Array),
@ -658,18 +658,18 @@ describe('testing getConstraintInfo', () => {
const code = `part001 = startSketchOn(-XZ)
|> startProfile(at = [0, 0])
|> line(end = [3, 4])
|> angledLine(angle = 3.14, length = 3.14)
|> angledLine(angle = 3.14deg, length = 3.14)
|> line(endAbsolute = [6.14, 3.14])
|> xLine(endAbsolute = 8)
|> yLine(endAbsolute = 5)
|> yLine(length = 3.14, tag = $a)
|> xLine(length = 3.14)
|> angledLine(angle = 3.14, lengthX = 3.14)
|> angledLine(angle = 30, lengthY = 3)
|> angledLine(angle = 12, endAbsoluteX = 12)
|> angledLine(angle = 30, endAbsoluteY = 10)
|> angledLine(angle = 3.14deg, lengthX = 3.14)
|> angledLine(angle = 30deg, lengthY = 3)
|> angledLine(angle = 12deg, endAbsoluteX = 12)
|> angledLine(angle = 30deg, endAbsoluteY = 10)
|> angledLineThatIntersects(
angle = 3.14,
angle = 3.14deg,
intersectTag = a,
offset = 0,
)
@ -681,7 +681,7 @@ describe('testing getConstraintInfo', () => {
{
type: 'angle',
isConstrained: false,
value: '3.14',
value: '3.14deg',
sourceRange: [expect.any(Number), expect.any(Number), 0],
argPosition: { type: 'labeledArg', key: 'angle' },
pathToNode: expect.any(Array),
@ -704,7 +704,7 @@ describe('testing getConstraintInfo', () => {
{
type: 'angle',
isConstrained: false,
value: '3.14',
value: '3.14deg',
sourceRange: [expect.any(Number), expect.any(Number), 0],
argPosition: { type: 'labeledArg', key: 'angle' },
pathToNode: expect.any(Array),
@ -727,7 +727,7 @@ describe('testing getConstraintInfo', () => {
{
type: 'angle',
isConstrained: false,
value: '30',
value: '30deg',
sourceRange: [expect.any(Number), expect.any(Number), 0],
argPosition: { type: 'labeledArg', key: 'angle' },
pathToNode: expect.any(Array),
@ -750,7 +750,7 @@ describe('testing getConstraintInfo', () => {
{
type: 'angle',
isConstrained: false,
value: '12',
value: '12deg',
sourceRange: [expect.any(Number), expect.any(Number), 0],
argPosition: { type: 'labeledArg', key: 'angle' },
pathToNode: expect.any(Array),
@ -773,7 +773,7 @@ describe('testing getConstraintInfo', () => {
{
type: 'angle',
isConstrained: false,
value: '30',
value: '30deg',
sourceRange: [expect.any(Number), expect.any(Number), 0],
argPosition: { type: 'labeledArg', key: 'angle' },
pathToNode: expect.any(Array),
@ -814,18 +814,18 @@ describe('testing getConstraintInfo', () => {
const code = `part001 = startSketchOn(-XZ)
|> startProfile(at = [0, 0])
|> line(end = [3 + 0, 4 + 0])
|> angledLine(angle = 3.14 + 0, length = 3.14 + 0 )
|> angledLine(angle = 3.14deg + 0, length = 3.14 + 0 )
|> line(endAbsolute = [6.14 + 0, 3.14 + 0])
|> xLine(endAbsolute = 8 + 0)
|> yLine(endAbsolute = 5 + 0)
|> yLine(length = 3.14 + 0, tag = $a)
|> xLine(length = 3.14 + 0)
|> angledLine(angle = 3.14 + 0, lengthX = 3.14 + 0)
|> angledLine(angle = 30 + 0, lengthY = 3 + 0)
|> angledLine(angle = 12.14 + 0, endAbsoluteX = 12 + 0)
|> angledLine(angle = 30 + 0, endAbsoluteY = 10.14 + 0)
|> angledLine(angle = 3.14deg + 0, lengthX = 3.14 + 0)
|> angledLine(angle = 30deg + 0, lengthY = 3 + 0)
|> angledLine(angle = 12.14deg + 0, endAbsoluteX = 12 + 0)
|> angledLine(angle = 30deg + 0, endAbsoluteY = 10.14 + 0)
|> angledLineThatIntersects(
angle = 3.14 + 0,
angle = 3.14deg + 0,
intersectTag = a,
offset = 0 + 0,
)
@ -860,7 +860,7 @@ describe('testing getConstraintInfo', () => {
{
type: 'angle',
isConstrained: true,
value: '3.14 + 0',
value: '3.14deg + 0',
sourceRange: [expect.any(Number), expect.any(Number), 0],
argPosition: { type: 'labeledArg', key: 'angle' },
pathToNode: expect.any(Array),
@ -1006,7 +1006,7 @@ describe('testing getConstraintInfo', () => {
{
type: 'angle',
isConstrained: true,
value: '3.14 + 0',
value: '3.14deg + 0',
sourceRange: [expect.any(Number), expect.any(Number), 0],
argPosition: { type: 'labeledArg', key: 'angle' },
pathToNode: expect.any(Array),
@ -1029,7 +1029,7 @@ describe('testing getConstraintInfo', () => {
{
type: 'angle',
isConstrained: true,
value: '30 + 0',
value: '30deg + 0',
sourceRange: [expect.any(Number), expect.any(Number), 0],
argPosition: { type: 'labeledArg', key: 'angle' },
pathToNode: expect.any(Array),
@ -1052,7 +1052,7 @@ describe('testing getConstraintInfo', () => {
{
type: 'angle',
isConstrained: true,
value: '12.14 + 0',
value: '12.14deg + 0',
sourceRange: [expect.any(Number), expect.any(Number), 0],
argPosition: { type: 'labeledArg', key: 'angle' },
pathToNode: expect.any(Array),
@ -1075,7 +1075,7 @@ describe('testing getConstraintInfo', () => {
{
type: 'angle',
isConstrained: true,
value: '30 + 0',
value: '30deg + 0',
sourceRange: [expect.any(Number), expect.any(Number), 0],
argPosition: { type: 'labeledArg', key: 'angle' },
pathToNode: expect.any(Array),
@ -1098,7 +1098,7 @@ describe('testing getConstraintInfo', () => {
{
type: 'angle',
isConstrained: true,
value: '3.14 + 0',
value: '3.14deg + 0',
sourceRange: [expect.any(Number), expect.any(Number), 0],
argPosition: { type: 'labeledArg', key: 'angle' },
pathToNode: expect.any(Array),

View File

@ -1570,9 +1570,12 @@ export const arc: SketchLineHelperKw = {
createLabeledArg('radius', createLiteral(roundOff(radius))),
createLabeledArg(
'angleStart',
createLiteral(roundOff(startAngleDegrees))
createLiteral(roundOff(startAngleDegrees), 'Deg')
),
createLabeledArg(
'angleEnd',
createLiteral(roundOff(endAngleDegrees), 'Deg')
),
createLabeledArg('angleEnd', createLiteral(roundOff(endAngleDegrees))),
])
if (
@ -1623,13 +1626,13 @@ export const arc: SketchLineHelperKw = {
type: 'objectProperty',
key: 'angle',
argType: 'angle',
expr: createLiteral(roundOff(startAngleDegrees)),
expr: createLiteral(roundOff(startAngleDegrees), 'Deg'),
},
{
type: 'objectProperty',
key: 'angle',
argType: 'angle',
expr: createLiteral(roundOff(endAngleDegrees)),
expr: createLiteral(roundOff(endAngleDegrees), 'Deg'),
},
])
if (err(result)) return result
@ -1689,8 +1692,8 @@ export const arc: SketchLineHelperKw = {
const endAngleDegrees = (endAngle * 180) / Math.PI
const newRadius = createLiteral(roundOff(radius))
const newAngleStart = createLiteral(roundOff(startAngleDegrees))
const newAngleEnd = createLiteral(roundOff(endAngleDegrees))
const newAngleStart = createLiteral(roundOff(startAngleDegrees), 'Deg')
const newAngleEnd = createLiteral(roundOff(endAngleDegrees), 'Deg')
mutateKwArg('radius', callExpression, newRadius)
mutateKwArg('angleStart', callExpression, newAngleStart)
mutateKwArg('angleEnd', callExpression, newAngleEnd)
@ -2409,7 +2412,7 @@ export const angledLine: SketchLineHelperKw = {
createLocalName(snaps?.previousArcTag),
[]
)
: createLiteral(roundOff(getAngle(from, to), 0))
: createLiteral(roundOff(getAngle(from, to), 0), 'Deg')
const newLengthVal = createLiteral(roundOff(getLength(from, to), 2))
const newLine = createCallExpressionStdLibKw('angledLine', null, [
createLabeledArg(ARG_ANGLE, newAngleVal),
@ -2463,7 +2466,7 @@ export const angledLine: SketchLineHelperKw = {
const angle = roundOff(getAngle(from, to), 0)
const lineLength = roundOff(getLength(from, to), 2)
const angleLit = createLiteral(angle)
const angleLit = createLiteral(angle, 'Deg')
const lengthLit = createLiteral(lineLength)
mutateKwArg(ARG_ANGLE, callExpression, angleLit)
@ -2520,7 +2523,7 @@ export const angledLineOfXLength: SketchLineHelperKw = {
if (err(sketch)) {
return sketch
}
const angle = createLiteral(roundOff(getAngle(from, to), 0))
const angle = createLiteral(roundOff(getAngle(from, to), 0), 'Deg')
const xLength = createLiteral(roundOff(Math.abs(from[0] - to[0]), 2) || 0.1)
let newLine: Expr
if (replaceExistingCallback) {
@ -2579,7 +2582,7 @@ export const angledLineOfXLength: SketchLineHelperKw = {
? Math.abs(xLength)
: xLength // todo make work for variable angle > 180
const angleLit = createLiteral(angle)
const angleLit = createLiteral(angle, 'Deg')
const lengthLit = createLiteral(adjustedXLength)
removeDeterminingArgs(callExpression)
@ -2632,7 +2635,7 @@ export const angledLineOfYLength: SketchLineHelperKw = {
const sketch = sketchFromKclValue(variables[variableName], variableName)
if (err(sketch)) return sketch
const angle = createLiteral(roundOff(getAngle(from, to), 0))
const angle = createLiteral(roundOff(getAngle(from, to), 0), 'Deg')
const yLength = createLiteral(roundOff(Math.abs(from[1] - to[1]), 2) || 0.1)
let newLine: Expr
if (replaceExistingCallback) {
@ -2691,7 +2694,7 @@ export const angledLineOfYLength: SketchLineHelperKw = {
? Math.abs(yLength)
: yLength // todo make work for variable angle > 180
const angleLit = createLiteral(angle)
const angleLit = createLiteral(angle, 'Deg')
const lengthLit = createLiteral(adjustedYLength)
removeDeterminingArgs(callExpression)
@ -2728,7 +2731,7 @@ export const angledLineToX: SketchLineHelperKw = {
if (err(nodeMeta)) return nodeMeta
const { node: pipe } = nodeMeta
const angle = createLiteral(roundOff(getAngle(from, to), 0))
const angle = createLiteral(roundOff(getAngle(from, to), 0), 'Deg')
const xArg = createLiteral(roundOff(to[0], 2))
if (replaceExistingCallback) {
const result = replaceExistingCallback([
@ -2779,7 +2782,7 @@ export const angledLineToX: SketchLineHelperKw = {
const adjustedXLength = xLength
const angleLit = createLiteral(angle)
const angleLit = createLiteral(angle, 'Deg')
const lengthLit = createLiteral(adjustedXLength)
removeDeterminingArgs(callExpression)
@ -2816,7 +2819,7 @@ export const angledLineToY: SketchLineHelperKw = {
const { node: pipe } = nodeMeta
const angle = createLiteral(roundOff(getAngle(from, to), 0))
const angle = createLiteral(roundOff(getAngle(from, to), 0), 'Deg')
const yArg = createLiteral(roundOff(to[1], 2))
if (replaceExistingCallback) {
@ -2868,7 +2871,7 @@ export const angledLineToY: SketchLineHelperKw = {
const adjustedXLength = xLength
const angleLit = createLiteral(angle)
const angleLit = createLiteral(angle, 'Deg')
const lengthLit = createLiteral(adjustedXLength)
removeDeterminingArgs(callExpression)
@ -2911,7 +2914,7 @@ export const angledLineThatIntersects: SketchLineHelperKw = {
const { node: pipe } = nodeMeta
const angle = createLiteral(roundOff(getAngle(from, to), 0))
const angle = createLiteral(roundOff(getAngle(from, to), 0), 'Deg')
if (!referencedSegment) {
return new Error('referencedSegment must be provided')
}
@ -2994,7 +2997,7 @@ export const angledLineThatIntersects: SketchLineHelperKw = {
)
}
mutateKwArg(ARG_ANGLE, callExpression, createLiteral(angle))
mutateKwArg(ARG_ANGLE, callExpression, createLiteral(angle, 'Deg'))
mutateKwArg(ARG_OFFSET, callExpression, createLiteral(offset))
return {
modifiedAst: _node,
@ -3504,7 +3507,7 @@ export function replaceSketchLine({
}):
| {
modifiedAst: Node<Program>
valueUsedInTransform?: number
valueUsedInTransform?: string
pathToNode: PathToNode
}
| Error {

View File

@ -72,22 +72,22 @@ describe('testing swapping out sketch calls with xLine/xLineTo', () => {
` |> startProfile(at = [0, 0])`,
` |> line(endAbsolute = [1, 1], tag = $abc1)`,
` |> line(end = [-2.04, -0.7], tag = $abc2)`,
` |> angledLine(angle = 157, length = 1.69, tag = $abc3)`,
` |> angledLine(angle = 217, lengthX = 0.86, tag = $abc4)`,
` |> angledLine(angle = 104, lengthY = 1.58, tag = $abc5)`,
` |> angledLine(angle = 55, endAbsoluteX = -2.89, tag = $abc6)`,
` |> angledLine(angle = 330, endAbsoluteY = 2.53, tag = $abc7)`,
` |> angledLine(angle = 157deg, length = 1.69, tag = $abc3)`,
` |> angledLine(angle = 217deg, lengthX = 0.86, tag = $abc4)`,
` |> angledLine(angle = 104deg, lengthY = 1.58, tag = $abc5)`,
` |> angledLine(angle = 55deg, endAbsoluteX = -2.89, tag = $abc6)`,
` |> angledLine(angle = 330deg, endAbsoluteY = 2.53, tag = $abc7)`,
` |> xLine(length = 1.47, tag = $abc8)`,
` |> yLine(length = 1.57, tag = $abc9)`,
` |> xLine(endAbsolute = 1.49, tag = $abc10)`,
` |> yLine(endAbsolute = 2.64, tag = $abc11)`,
` |> line(endAbsolute = [2.55, 3.58]) // lineTo`,
` |> line(end = [0.73, -0.75])`,
` |> angledLine(angle = 63, length = 1.38) // angledLine`,
` |> angledLine(angle = 319, lengthX = 1.15) // angledLineOfXLength`,
` |> angledLine(angle = 50, lengthY = 1.35) // angledLineOfYLength`,
` |> angledLine(angle = 291, endAbsoluteX = 6.66) // angledLineToX`,
` |> angledLine(angle = 228, endAbsoluteY = 2.14) // angledLineToY`,
` |> angledLine(angle = 63deg, length = 1.38) // angledLine`,
` |> angledLine(angle = 319deg, lengthX = 1.15) // angledLineOfXLength`,
` |> angledLine(angle = 50deg, lengthY = 1.35) // angledLineOfYLength`,
` |> angledLine(angle = 291deg, endAbsoluteX = 6.66) // angledLineToX`,
` |> angledLine(angle = 228deg, endAbsoluteY = 2.14) // angledLineToY`,
` |> xLine(length = -1.33)`,
` |> yLine(length = -1.07)`,
` |> xLine(endAbsolute = 3.27)`,
@ -143,7 +143,7 @@ describe('testing swapping out sketch calls with xLine/xLineTo', () => {
it('angledLine with tag converts to xLine', async () => {
const { newCode, originalRange } = await testingSwapSketchFnCall({
inputCode: bigExample,
callToSwap: 'angledLine(angle = 157, length = 1.69, tag = $abc3)',
callToSwap: 'angledLine(angle = 157deg, length = 1.69, tag = $abc3)',
constraintType: 'horizontal',
})
const expectedLine = 'xLine(length = -1.56, tag = $abc3)'
@ -154,7 +154,7 @@ describe('testing swapping out sketch calls with xLine/xLineTo', () => {
it('angledLine w/o tag converts to xLine', async () => {
const { newCode, originalRange } = await testingSwapSketchFnCall({
inputCode: bigExample,
callToSwap: 'angledLine(angle = 63, length = 1.38)',
callToSwap: 'angledLine(angle = 63deg, length = 1.38)',
constraintType: 'horizontal',
})
const expectedLine = 'xLine(length = 0.63) // angledLine'
@ -165,7 +165,7 @@ describe('testing swapping out sketch calls with xLine/xLineTo', () => {
it('angledLineOfXLength with tag converts to xLine', async () => {
const { newCode, originalRange } = await testingSwapSketchFnCall({
inputCode: bigExample,
callToSwap: 'angledLine(angle = 217, lengthX = 0.86, tag = $abc4)',
callToSwap: 'angledLine(angle = 217deg, lengthX = 0.86, tag = $abc4)',
constraintType: 'horizontal',
})
const expectedLine = 'xLine(length = -0.86, tag = $abc4)'
@ -177,7 +177,7 @@ describe('testing swapping out sketch calls with xLine/xLineTo', () => {
it('angledLineOfXLength w/o tag converts to xLine', async () => {
const { newCode, originalRange } = await testingSwapSketchFnCall({
inputCode: bigExample,
callToSwap: 'angledLine(angle = 319, lengthX = 1.15)',
callToSwap: 'angledLine(angle = 319deg, lengthX = 1.15)',
constraintType: 'horizontal',
})
const expectedLine = 'xLine(length = 1.15) // angledLineOfXLength'
@ -188,7 +188,7 @@ describe('testing swapping out sketch calls with xLine/xLineTo', () => {
it('angledLineOfYLength with tag converts to yLine', async () => {
const { newCode, originalRange } = await testingSwapSketchFnCall({
inputCode: bigExample,
callToSwap: 'angledLine(angle = 104, lengthY = 1.58, tag = $abc5)',
callToSwap: 'angledLine(angle = 104deg, lengthY = 1.58, tag = $abc5)',
constraintType: 'vertical',
})
const expectedLine = 'yLine(length = 1.58, tag = $abc5)'
@ -199,7 +199,7 @@ describe('testing swapping out sketch calls with xLine/xLineTo', () => {
it('angledLineOfYLength w/o tag converts to yLine', async () => {
const { newCode, originalRange } = await testingSwapSketchFnCall({
inputCode: bigExample,
callToSwap: 'angledLine(angle = 50, lengthY = 1.35)',
callToSwap: 'angledLine(angle = 50deg, lengthY = 1.35)',
constraintType: 'vertical',
})
const expectedLine = 'yLine(length = 1.35) // angledLineOfYLength'
@ -210,7 +210,8 @@ describe('testing swapping out sketch calls with xLine/xLineTo', () => {
it('angledLineToX with tag converts to xLineTo', async () => {
const { newCode, originalRange } = await testingSwapSketchFnCall({
inputCode: bigExample,
callToSwap: 'angledLine(angle = 55, endAbsoluteX = -2.89, tag = $abc6)',
callToSwap:
'angledLine(angle = 55deg, endAbsoluteX = -2.89, tag = $abc6)',
constraintType: 'horizontal',
})
const expectedLine = 'xLine(endAbsolute = -2.89, tag = $abc6)'
@ -221,7 +222,7 @@ describe('testing swapping out sketch calls with xLine/xLineTo', () => {
it('angledLineToX w/o tag converts to xLineTo', async () => {
const { newCode, originalRange } = await testingSwapSketchFnCall({
inputCode: bigExample,
callToSwap: 'angledLine(angle = 291, endAbsoluteX = 6.66)',
callToSwap: 'angledLine(angle = 291deg, endAbsoluteX = 6.66)',
constraintType: 'horizontal',
})
const expectedLine = 'xLine(endAbsolute = 6.66) // angledLineToX'
@ -232,7 +233,8 @@ describe('testing swapping out sketch calls with xLine/xLineTo', () => {
it('angledLineToY with tag converts to yLineTo', async () => {
const { newCode, originalRange } = await testingSwapSketchFnCall({
inputCode: bigExample,
callToSwap: 'angledLine(angle = 330, endAbsoluteY = 2.53, tag = $abc7)',
callToSwap:
'angledLine(angle = 330deg, endAbsoluteY = 2.53, tag = $abc7)',
constraintType: 'vertical',
})
const expectedLine = 'yLine(endAbsolute = 2.53, tag = $abc7)'
@ -243,7 +245,7 @@ describe('testing swapping out sketch calls with xLine/xLineTo', () => {
it('angledLineToY w/o tag converts to yLineTo', async () => {
const { newCode, originalRange } = await testingSwapSketchFnCall({
inputCode: bigExample,
callToSwap: 'angledLine(angle = 228, endAbsoluteY = 2.14)',
callToSwap: 'angledLine(angle = 228deg, endAbsoluteY = 2.14)',
constraintType: 'vertical',
})
const expectedLine = 'yLine(endAbsolute = 2.14) // angledLineToY'
@ -258,7 +260,7 @@ describe('testing swapping out sketch calls with xLine/xLineTo while keeping var
const variablesExampleArr = [
`lineX = -1`,
`lineToX = -1.3`,
`angledLineAngle = 207`,
`angledLineAngle = 207deg`,
`angledLineOfXLengthX = 0.8`,
`angledLineOfYLengthY = 0.89`,
`angledLineToXx = -1.86`,
@ -270,10 +272,10 @@ describe('testing swapping out sketch calls with xLine/xLineTo while keeping var
` |> line(end = [lineX, 2.13])`,
` |> line(endAbsolute = [lineToX, 2.85])`,
` |> angledLine(angle = angledLineAngle, length = 1.64)`,
` |> angledLine(angle = 329, lengthX = angledLineOfXLengthX)`,
` |> angledLine(angle = 222, lengthY = angledLineOfYLengthY)`,
` |> angledLine(angle = 330, endAbsoluteX = angledLineToXx)`,
` |> angledLine(angle = 217, endAbsoluteY = angledLineToYy)`,
` |> angledLine(angle = 329deg, lengthX = angledLineOfXLengthX)`,
` |> angledLine(angle = 222deg, lengthY = angledLineOfYLengthY)`,
` |> angledLine(angle = 330deg, endAbsoluteX = angledLineToXx)`,
` |> angledLine(angle = 217deg, endAbsoluteY = angledLineToYy)`,
` |> line(end = [0.89, -0.1])`,
]
const varExample = variablesExampleArr.join('\n')
@ -302,7 +304,7 @@ describe('testing swapping out sketch calls with xLine/xLineTo while keeping var
it('angledLineOfXLength keeps variable when converted to xLine', async () => {
const { newCode, originalRange } = await testingSwapSketchFnCall({
inputCode: varExample,
callToSwap: 'angledLine(angle = 329, lengthX = angledLineOfXLengthX)',
callToSwap: 'angledLine(angle = 329deg, lengthX = angledLineOfXLengthX)',
constraintType: 'horizontal',
})
const expectedLine = 'xLine(length = angledLineOfXLengthX)'
@ -313,7 +315,7 @@ describe('testing swapping out sketch calls with xLine/xLineTo while keeping var
it('angledLineOfYLength keeps variable when converted to yLine', async () => {
const { newCode, originalRange } = await testingSwapSketchFnCall({
inputCode: varExample,
callToSwap: 'angledLine(angle = 222, lengthY = angledLineOfYLengthY)',
callToSwap: 'angledLine(angle = 222deg, lengthY = angledLineOfYLengthY)',
constraintType: 'vertical',
})
const expectedLine = 'yLine(length = -angledLineOfYLengthY)'
@ -324,7 +326,7 @@ describe('testing swapping out sketch calls with xLine/xLineTo while keeping var
it('angledLineToX keeps variable when converted to xLineTo', async () => {
const { newCode, originalRange } = await testingSwapSketchFnCall({
inputCode: varExample,
callToSwap: 'angledLine(angle = 330, endAbsoluteX = angledLineToXx)',
callToSwap: 'angledLine(angle = 330deg, endAbsoluteX = angledLineToXx)',
constraintType: 'horizontal',
})
const expectedLine = 'xLine(endAbsolute = angledLineToXx)'
@ -335,7 +337,7 @@ describe('testing swapping out sketch calls with xLine/xLineTo while keeping var
it('angledLineToY keeps variable when converted to yLineTo', async () => {
const { newCode, originalRange } = await testingSwapSketchFnCall({
inputCode: varExample,
callToSwap: 'angledLine(angle = 217, endAbsoluteY = angledLineToYy)',
callToSwap: 'angledLine(angle = 217deg, endAbsoluteY = angledLineToYy)',
constraintType: 'vertical',
})
const expectedLine = 'yLine(endAbsolute = angledLineToYy)'
@ -348,7 +350,7 @@ describe('testing swapping out sketch calls with xLine/xLineTo while keeping var
const illegalConvert = () =>
testingSwapSketchFnCall({
inputCode: varExample,
callToSwap: 'angledLine(angle = 217, endAbsoluteY = angledLineToYy)',
callToSwap: 'angledLine(angle = 217deg, endAbsoluteY = angledLineToYy)',
constraintType: 'horizontal',
})
await expect(illegalConvert).rejects.toThrowError('no callback helper')

View File

@ -99,7 +99,7 @@ export function isSketchVariablesLinked(
|> line(end = [myVar, 0.38]) // ❗ <- cursor in this fn call (the primary)
|> line(end = [0.41, baz])
|> xLine(length = 0.91)
|> angledLine(angle = 37, length = 2)
|> angledLine(angle = 37deg, length = 2)
const yo = line(end = [myVar, 0.38], tag = part001)
|> line(end = [1, 1])
const yo2 = line(end = [myVar, 0.38], tag = yo)

View File

@ -42,25 +42,29 @@ describe('testing getConstraintType', () => {
expect(helper(`line(endAbsolute = [myVar, 5])`)).toBe('xAbsolute')
})
it('testing angledLine', () => {
expect(helper(`angledLine(angle = 5, length = myVar)`)).toBe('length')
expect(helper(`angledLine(angle = 5deg, length = myVar)`)).toBe('length')
expect(helper(`angledLine(angle = myVar, length = 5)`)).toBe('angle')
})
it('testing angledLineOfXLength', () => {
expect(helper(`angledLine(angle = 5, lengthX = myVar)`)).toBe('xRelative')
expect(helper(`angledLine(angle = 5deg, lengthX = myVar)`)).toBe(
'xRelative'
)
expect(helper(`angledLine(angle = myVar, lengthX = 5)`)).toBe('angle')
})
it('testing angledLineToX', () => {
expect(helper(`angledLine(angle = 5, endAbsoluteX = myVar)`)).toBe(
expect(helper(`angledLine(angle = 5deg, endAbsoluteX = myVar)`)).toBe(
'xAbsolute'
)
expect(helper(`angledLine(angle = myVar, endAbsoluteX = 5)`)).toBe('angle')
})
it('testing angledLineOfYLength', () => {
expect(helper(`angledLine(angle = 5, lengthY = myVar)`)).toBe('yRelative')
expect(helper(`angledLine(angle = 5deg, lengthY = myVar)`)).toBe(
'yRelative'
)
expect(helper(`angledLine(angle = myVar, lengthY = 5)`)).toBe('angle')
})
it('testing angledLineToY', () => {
expect(helper(`angledLine(angle = 5, endAbsoluteY = myVar)`)).toBe(
expect(helper(`angledLine(angle = 5deg, endAbsoluteY = myVar)`)).toBe(
'yAbsolute'
)
expect(helper(`angledLine(angle = myVar, endAbsoluteY = 5)`)).toBe('angle')
@ -172,7 +176,7 @@ describe('testing transformAstForSketchLines for equal length constraint', () =>
const expectedModifiedScript = `sketch001 = startSketchOn(XZ)
|> startProfile(at = [0, 0])
|> line(end = [5, 5], tag = $seg01)
|> angledLine(angle = 112, length = segLen(seg01))
|> angledLine(angle = 112deg, length = segLen(seg01))
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
`
@ -248,30 +252,30 @@ describe('testing transformAstForSketchLines for equal length constraint', () =>
const inputScript = `myVar = 3
myVar2 = 5
myVar3 = 6
myAng = 40
myAng2 = 134
myAng = 40deg
myAng2 = 134deg
part001 = startSketchOn(XY)
|> startProfile(at = [0, 0])
|> line(end = [1, 3.82]) // ln-should-get-tag
|> line(endAbsolute = [2, 4]) // ln-lineTo-free should become angledLine
|> angledLine(angle = 45, endAbsoluteX = 2.5) // ln-angledLineToX-free should become angledLine
|> angledLine(angle = 45deg, endAbsoluteX = 2.5) // ln-angledLineToX-free should become angledLine
|> angledLine(angle = myAng, endAbsoluteX = 3) // ln-angledLineToX-angle should become angledLine
|> angledLine(angle = 135, endAbsoluteY = 5) // ln-angledLineToY-free should become angledLine
|> angledLine(angle = 135deg, endAbsoluteY = 5) // ln-angledLineToY-free should become angledLine
|> angledLine(angle = myAng2, endAbsoluteY = 4) // ln-angledLineToY-angle should become angledLine
|> line(end = [myVar, 1]) // ln-should use legLen for y
|> line(end = [myVar, -1]) // ln-legLen but negative
|> line(end = [-0.62, -1.54]) // ln-should become angledLine
|> angledLine(angle = myVar, length = 1.04) // ln-use segLen for second arg
|> angledLine(angle = 45, length = 1.04) // ln-segLen again
|> angledLine(angle = 54, lengthX = 2.35) // ln-should be transformed to angledLine
|> angledLine(angle = 50, lengthX = myVar) // ln-should use legAngX to calculate angle
|> angledLine(angle = 209, lengthX = myVar) // ln-same as above but should have + 180 to match original quadrant
|> angledLine(angle = 45deg, length = 1.04) // ln-segLen again
|> angledLine(angle = 54deg, lengthX = 2.35) // ln-should be transformed to angledLine
|> angledLine(angle = 50deg, lengthX = myVar) // ln-should use legAngX to calculate angle
|> angledLine(angle = 209deg, lengthX = myVar) // ln-same as above but should have + 180 to match original quadrant
|> line(end = [1, myVar]) // ln-legLen again but yRelative
|> line(end = [-1, myVar]) // ln-negative legLen yRelative
|> angledLine(angle = 58, lengthY = 0.7) // ln-angledLineOfYLength-free should become angledLine
|> angledLine(angle = 58deg, lengthY = 0.7) // ln-angledLineOfYLength-free should become angledLine
|> angledLine(angle = myAng, lengthY = 0.7) // ln-angledLineOfYLength-angle should become angledLine
|> angledLine(angle = 35, lengthY = myVar) // ln-angledLineOfYLength-yRelative use legAngY
|> angledLine(angle = 305, lengthY = myVar) // ln-angledLineOfYLength-yRelative with angle > 90 use binExp
|> angledLine(angle = 35deg, lengthY = myVar) // ln-angledLineOfYLength-yRelative use legAngY
|> angledLine(angle = 305deg, lengthY = myVar) // ln-angledLineOfYLength-yRelative with angle > 90 use binExp
|> xLine(length = 1.03) // ln-xLine-free should sub in segLen
|> yLine(length = 1.04) // ln-yLine-free should sub in segLen
|> xLine(endAbsolute = 30) // ln-xLineTo-free should convert to xLine
@ -280,15 +284,15 @@ part001 = startSketchOn(XY)
const expectModifiedScript = `myVar = 3
myVar2 = 5
myVar3 = 6
myAng = 40
myAng2 = 134
myAng = 40deg
myAng2 = 134deg
part001 = startSketchOn(XY)
|> startProfile(at = [0, 0])
|> line(end = [1, 3.82], tag = $seg01) // ln-should-get-tag
|> angledLine(angle = 10, length = segLen(seg01)) // ln-lineTo-free should become angledLine
|> angledLine(angle = 45, length = segLen(seg01)) // ln-angledLineToX-free should become angledLine
|> angledLine(angle = 10deg, length = segLen(seg01)) // ln-lineTo-free should become angledLine
|> angledLine(angle = 45deg, length = segLen(seg01)) // ln-angledLineToX-free should become angledLine
|> angledLine(angle = myAng, length = segLen(seg01)) // ln-angledLineToX-angle should become angledLine
|> angledLine(angle = 135, length = segLen(seg01)) // ln-angledLineToY-free should become angledLine
|> angledLine(angle = 135deg, length = segLen(seg01)) // ln-angledLineToY-free should become angledLine
|> angledLine(angle = myAng2, length = segLen(seg01)) // ln-angledLineToY-angle should become angledLine
|> line(end = [
min([segLen(seg01), myVar]),
@ -298,12 +302,12 @@ part001 = startSketchOn(XY)
min([segLen(seg01), myVar]),
-legLen(hypotenuse = segLen(seg01), leg = myVar)
]) // ln-legLen but negative
|> angledLine(angle = -112, length = segLen(seg01)) // ln-should become angledLine
|> angledLine(angle = -112deg, length = segLen(seg01)) // ln-should become angledLine
|> angledLine(angle = myVar, length = segLen(seg01)) // ln-use segLen for second arg
|> angledLine(angle = 45, length = segLen(seg01)) // ln-segLen again
|> angledLine(angle = 54, length = segLen(seg01)) // ln-should be transformed to angledLine
|> angledLine(angle = 45deg, length = segLen(seg01)) // ln-segLen again
|> angledLine(angle = 54deg, length = segLen(seg01)) // ln-should be transformed to angledLine
|> angledLine(angle = legAngX(hypotenuse = segLen(seg01), leg = myVar), lengthX = min([segLen(seg01), myVar])) // ln-should use legAngX to calculate angle
|> angledLine(angle = 180 + legAngX(hypotenuse = segLen(seg01), leg = myVar), lengthX = min([segLen(seg01), myVar])) // ln-same as above but should have + 180 to match original quadrant
|> angledLine(angle = 180deg + legAngX(hypotenuse = segLen(seg01), leg = myVar), lengthX = min([segLen(seg01), myVar])) // ln-same as above but should have + 180 to match original quadrant
|> line(end = [
legLen(hypotenuse = segLen(seg01), leg = myVar),
min([segLen(seg01), myVar])
@ -312,10 +316,10 @@ part001 = startSketchOn(XY)
-legLen(hypotenuse = segLen(seg01), leg = myVar),
min([segLen(seg01), myVar])
]) // ln-negative legLen yRelative
|> angledLine(angle = 58, length = segLen(seg01)) // ln-angledLineOfYLength-free should become angledLine
|> angledLine(angle = 58deg, length = segLen(seg01)) // ln-angledLineOfYLength-free should become angledLine
|> angledLine(angle = myAng, length = segLen(seg01)) // ln-angledLineOfYLength-angle should become angledLine
|> angledLine(angle = legAngY(hypotenuse = segLen(seg01), leg = myVar), lengthX = min([segLen(seg01), myVar])) // ln-angledLineOfYLength-yRelative use legAngY
|> angledLine(angle = 270 + legAngY(hypotenuse = segLen(seg01), leg = myVar), lengthX = min([segLen(seg01), myVar])) // ln-angledLineOfYLength-yRelative with angle > 90 use binExp
|> angledLine(angle = 270deg + legAngY(hypotenuse = segLen(seg01), leg = myVar), lengthX = min([segLen(seg01), myVar])) // ln-angledLineOfYLength-yRelative with angle > 90 use binExp
|> xLine(length = segLen(seg01)) // ln-xLine-free should sub in segLen
|> yLine(length = segLen(seg01)) // ln-yLine-free should sub in segLen
|> xLine(length = segLen(seg01)) // ln-xLineTo-free should convert to xLine
@ -370,18 +374,18 @@ part001 = startSketchOn(XY)
|> line(endAbsolute = [3, 11]) // select for vertical constraint 3
|> line(endAbsolute = [myVar2, 12.63]) // select for horizontal constraint 4
|> line(endAbsolute = [4.08, myVar2]) // select for vertical constraint 4
|> angledLine(angle = 156, length = 1.34) // select for horizontal constraint 5
|> angledLine(angle = 103, length = 1.44) // select for vertical constraint 5
|> angledLine(angle = -178, length = myVar) // select for horizontal constraint 6
|> angledLine(angle = 129, length = myVar) // select for vertical constraint 6
|> angledLine(angle = 237, lengthX = 1.05) // select for horizontal constraint 7
|> angledLine(angle = 196, lengthY = 1.11) // select for vertical constraint 7
|> angledLine(angle = 194, lengthX = myVar) // select for horizontal constraint 8
|> angledLine(angle = 248, lengthY = myVar) // select for vertical constraint 8
|> angledLine(angle = 202, endAbsoluteX = -10.92) // select for horizontal constraint 9
|> angledLine(angle = 223, endAbsoluteY = 7.68) // select for vertical constraint 9
|> angledLine(angle = 333, endAbsoluteX = myVar3) // select for horizontal constraint 10
|> angledLine(angle = 301, endAbsoluteY = myVar) // select for vertical constraint 10
|> angledLine(angle = 156deg, length = 1.34) // select for horizontal constraint 5
|> angledLine(angle = 103deg, length = 1.44) // select for vertical constraint 5
|> angledLine(angle = -178deg, length = myVar) // select for horizontal constraint 6
|> angledLine(angle = 129deg, length = myVar) // select for vertical constraint 6
|> angledLine(angle = 237deg, lengthX = 1.05) // select for horizontal constraint 7
|> angledLine(angle = 196deg, lengthY = 1.11) // select for vertical constraint 7
|> angledLine(angle = 194deg, lengthX = myVar) // select for horizontal constraint 8
|> angledLine(angle = 248deg, lengthY = myVar) // select for vertical constraint 8
|> angledLine(angle = 202deg, endAbsoluteX = -10.92) // select for horizontal constraint 9
|> angledLine(angle = 223deg, endAbsoluteY = 7.68) // select for vertical constraint 9
|> angledLine(angle = 333deg, endAbsoluteX = myVar3) // select for horizontal constraint 10
|> angledLine(angle = 301deg, endAbsoluteY = myVar) // select for vertical constraint 10
`
it('should transform horizontal lines the ast', async () => {
const expectModifiedScript = `myVar = 2
@ -399,17 +403,17 @@ part001 = startSketchOn(XY)
|> xLine(endAbsolute = myVar2) // select for horizontal constraint 4
|> line(endAbsolute = [4.08, myVar2]) // select for vertical constraint 4
|> xLine(length = -1.22) // select for horizontal constraint 5
|> angledLine(angle = 103, length = 1.44) // select for vertical constraint 5
|> angledLine(angle = 103deg, length = 1.44) // select for vertical constraint 5
|> xLine(length = -myVar) // select for horizontal constraint 6
|> angledLine(angle = 129, length = myVar) // select for vertical constraint 6
|> angledLine(angle = 129deg, length = myVar) // select for vertical constraint 6
|> xLine(length = -1.05) // select for horizontal constraint 7
|> angledLine(angle = 196, lengthY = 1.11) // select for vertical constraint 7
|> angledLine(angle = 196deg, lengthY = 1.11) // select for vertical constraint 7
|> xLine(length = -myVar) // select for horizontal constraint 8
|> angledLine(angle = 248, lengthY = myVar) // select for vertical constraint 8
|> angledLine(angle = 248deg, lengthY = myVar) // select for vertical constraint 8
|> xLine(endAbsolute = -10.92) // select for horizontal constraint 9
|> angledLine(angle = 223, endAbsoluteY = 7.68) // select for vertical constraint 9
|> angledLine(angle = 223deg, endAbsoluteY = 7.68) // select for vertical constraint 9
|> xLine(endAbsolute = myVar3) // select for horizontal constraint 10
|> angledLine(angle = 301, endAbsoluteY = myVar) // select for vertical constraint 10
|> angledLine(angle = 301deg, endAbsoluteY = myVar) // select for vertical constraint 10
`
const ast = assertParse(inputScript)
@ -458,17 +462,17 @@ part001 = startSketchOn(XY)
|> yLine(endAbsolute = 11) // select for vertical constraint 3
|> line(endAbsolute = [myVar2, 12.63]) // select for horizontal constraint 4
|> yLine(endAbsolute = myVar2) // select for vertical constraint 4
|> angledLine(angle = 156, length = 1.34) // select for horizontal constraint 5
|> angledLine(angle = 156deg, length = 1.34) // select for horizontal constraint 5
|> yLine(length = 1.4) // select for vertical constraint 5
|> angledLine(angle = -178, length = myVar) // select for horizontal constraint 6
|> angledLine(angle = -178deg, length = myVar) // select for horizontal constraint 6
|> yLine(length = myVar) // select for vertical constraint 6
|> angledLine(angle = 237, lengthX = 1.05) // select for horizontal constraint 7
|> angledLine(angle = 237deg, lengthX = 1.05) // select for horizontal constraint 7
|> yLine(length = -1.11) // select for vertical constraint 7
|> angledLine(angle = 194, lengthX = myVar) // select for horizontal constraint 8
|> angledLine(angle = 194deg, lengthX = myVar) // select for horizontal constraint 8
|> yLine(length = -myVar) // select for vertical constraint 8
|> angledLine(angle = 202, endAbsoluteX = -10.92) // select for horizontal constraint 9
|> angledLine(angle = 202deg, endAbsoluteX = -10.92) // select for horizontal constraint 9
|> yLine(endAbsolute = 7.68) // select for vertical constraint 9
|> angledLine(angle = 333, endAbsoluteX = myVar3) // select for horizontal constraint 10
|> angledLine(angle = 333deg, endAbsoluteX = myVar3) // select for horizontal constraint 10
|> yLine(endAbsolute = myVar) // select for vertical constraint 10
`
const ast = assertParse(inputScript)
@ -606,7 +610,7 @@ describe('testing getConstraintLevelFromSourceRange', () => {
baseThick = 1
armThick = 0.5
totalHeight = 4
armAngle = 60
armAngle = 60deg
totalLength = 9.74
yDatum = 0
@ -622,12 +626,12 @@ part001 = startSketchOn(XY)
|> xLine(length = 4.4) // partial
|> yLine(length = -1) // partial
|> xLine(length = -4.2 + 0) // full
|> angledLine(angle = segAng(seg01bing) + 180, length = 1.79) // partial
|> angledLine(angle = segAng(seg01bing) + 180deg, length = 1.79) // partial
|> line(end = [1.44, -0.74]) // free
|> xLine(length = 3.36) // partial
|> line(end = [1.49, 1.06]) // free
|> xLine(length = -3.43 + 0) // full
|> angledLine(angle = 243 + 0, lengthX = 1.2 + 0) // full`
|> angledLine(angle = 243deg + 0, lengthX = 1.2 + 0) // full`
const ast = assertParse(code)
const constraintLevels: ConstraintLevel[] = ['full', 'partial', 'free']
constraintLevels.forEach((constraintLevel) => {

View File

@ -144,7 +144,7 @@ function createCallWrapper(
tooltip: ToolTip,
val: [Expr, Expr] | Expr,
tag?: Expr,
valueUsedInTransform?: number
valueUsedInTransform?: string
): CreatedSketchExprResult | Error {
if (isArray(val)) {
if (tooltip === 'line') {
@ -237,7 +237,7 @@ function createCallWrapper(
console.error(fnName)
return {
callExp: createCallExpressionStdLibKw('', null, []),
valueUsedInTransform: 0,
valueUsedInTransform: '',
}
}
return {
@ -270,7 +270,7 @@ function createStdlibCallExpressionKw(
tool: ToolTip,
labeled: LabeledArg[],
tag?: Expr,
valueUsedInTransform?: number,
valueUsedInTransform?: string,
unlabeled?: Expr,
noncode?: NonCodeMeta
): CreatedSketchExprResult {
@ -302,7 +302,7 @@ function intersectCallWrapper({
offsetVal: Expr
intersectTag: Expr
tag?: Expr
valueUsedInTransform?: number
valueUsedInTransform?: string
}): CreatedSketchExprResult {
const args: LabeledArg[] = [
createLabeledArg(ARG_ANGLE, angleVal),
@ -335,9 +335,8 @@ const xyLineSetLength =
: referenceSeg
? segRef
: args[0].expr
const literalArg = asNum(args[0].expr.value)
if (err(literalArg)) return literalArg
return createCallWrapper(xOrY, lineVal, tag, literalArg)
return createCallWrapper(xOrY, lineVal, tag, args[0].expr.raw)
}
type AngLenNone = 'ang' | 'len' | 'none'
@ -376,10 +375,9 @@ const basicAngledLineCreateNode =
: args[1].expr
const shouldForceAng = valToForce === 'ang' && forceValueUsedInTransform
const shouldForceLen = valToForce === 'len' && forceValueUsedInTransform
const literalArg = asNum(
valToForce === 'ang' ? args[0].expr.value : args[1].expr.value
)
if (err(literalArg)) return literalArg
const literalArg =
valToForce === 'ang' ? args[0].expr.raw : args[1].expr.raw
return createCallWrapper(
'angledLine',
[
@ -443,7 +441,7 @@ const getLegAng = (ang: number, legAngleVal: BinaryPart) => {
const normalisedAngle = ((ang % 360) + 360) % 360 // between 0 and 360
const truncatedTo90 = Math.floor(normalisedAngle / 90) * 90
const binExp = createBinaryExpressionWithUnary([
createLiteral(truncatedTo90),
createLiteral(truncatedTo90, 'Deg'),
legAngleVal,
])
return truncatedTo90 === 0 ? legAngleVal : binExp
@ -457,7 +455,7 @@ function getClosesAngleDirection(
const angDiff = Math.abs(currentAng - refAngle)
const normalisedAngle = ((angDiff % 360) + 360) % 360 // between 0 and 180
return normalisedAngle > 90
? createBinaryExpressionWithUnary([angleVal, createLiteral(180)])
? createBinaryExpressionWithUnary([angleVal, createLiteral(180, 'Deg')])
: angleVal
}
@ -486,7 +484,7 @@ const setHorzVertDistanceCreateNode =
'lineTo',
!index ? [finalValue, args[1].expr] : [args[0].expr, finalValue],
tag,
valueUsedInTransform
String(valueUsedInTransform)
)
}
const setHorzVertDistanceForAngleLineCreateNode =
@ -511,7 +509,7 @@ const setHorzVertDistanceForAngleLineCreateNode =
xOrY === 'x' ? 'angledLineToX' : 'angledLineToY',
[inputs[0].expr, binExp],
tag,
valueUsedInTransform
String(valueUsedInTransform)
)
}
@ -531,14 +529,14 @@ const setAbsDistanceCreateNode =
xOrY === 'x' ? 'xLineTo' : 'yLineTo',
val,
tag,
valueUsedInTransform
String(valueUsedInTransform)
)
}
return createCallWrapper(
'lineTo',
!index ? [val, args[1].expr] : [args[0].expr, val],
tag,
valueUsedInTransform
String(valueUsedInTransform)
)
}
const setAbsDistanceForAngleLineCreateNode =
@ -552,7 +550,7 @@ const setAbsDistanceForAngleLineCreateNode =
xOrY === 'x' ? 'angledLineToX' : 'angledLineToY',
[inputs[0].expr, val],
tag,
valueUsedInTransform
String(valueUsedInTransform)
)
}
@ -578,7 +576,7 @@ const setHorVertDistanceForXYLines =
xOrY === 'x' ? 'xLineTo' : 'yLineTo',
makeBinExp,
tag,
valueUsedInTransform
String(valueUsedInTransform)
)
}
@ -628,14 +626,14 @@ const setAngledIntersectLineForLines: CreateStdLibSketchCallExpr = ({
}
const angleVal = [0, 90, 180, 270].includes(angle)
? createName(['turns'], varNameMap[angle])
: createLiteral(angle)
: createLiteral(angle, 'Deg')
return intersectCallWrapper({
fnName: 'angledLineThatIntersects',
angleVal,
offsetVal: forceValueUsedInTransform || createLiteral(valueUsedInTransform),
intersectTag: createLocalName(referenceSegName),
tag,
valueUsedInTransform,
valueUsedInTransform: String(valueUsedInTransform),
})
}
@ -655,7 +653,7 @@ const setAngledIntersectForAngledLines: CreateStdLibSketchCallExpr = ({
offsetVal: forceValueUsedInTransform || createLiteral(valueUsedInTransform),
intersectTag: createLocalName(referenceSegName),
tag,
valueUsedInTransform,
valueUsedInTransform: String(valueUsedInTransform),
})
}
@ -686,7 +684,7 @@ const setAngleBetweenCreateNode =
}
const binExp = createBinaryExpressionWithUnary([
firstHalfValue,
forceValueUsedInTransform || createLiteral(valueUsedInTransform),
forceValueUsedInTransform || createLiteral(valueUsedInTransform, 'Deg'),
])
return createCallWrapper(
transformToType === 'none'
@ -700,7 +698,7 @@ const setAngleBetweenCreateNode =
? [binExp, inputs[0].expr]
: [binExp, inputs[1].expr],
tag,
valueUsedInTransform
String(valueUsedInTransform) + 'deg'
)
}
@ -883,7 +881,7 @@ const transformMap: TransformMap = {
'angledLineToY',
[forceValueUsedInTransform || args[0].expr, inputs[1].expr],
tag,
val
String(val)
)
},
},
@ -1155,16 +1153,17 @@ const transformMap: TransformMap = {
const argVal = asNum(args[0].expr.value)
if (err(argVal)) return argVal
const segLen = createSegLen(referenceSegName)
if (argVal > 0) return createCallWrapper('xLine', segLen, tag, argVal)
if (argVal > 0)
return createCallWrapper('xLine', segLen, tag, String(argVal))
if (isExprBinaryPart(segLen))
return createCallWrapper(
'xLine',
createUnaryExpression(segLen),
tag,
argVal
String(argVal)
)
// should probably return error here instead
return createCallWrapper('xLine', segLen, tag, argVal)
return createCallWrapper('xLine', segLen, tag, String(argVal))
},
},
setHorzDistance: {
@ -1194,7 +1193,7 @@ const transformMap: TransformMap = {
if (err(argVal)) return argVal
let segLen = createSegLen(referenceSegName)
if (argVal < 0) segLen = createUnaryExpression(segLen)
return createCallWrapper('yLine', segLen, tag, argVal)
return createCallWrapper('yLine', segLen, tag, String(argVal))
},
},
setLength: {
@ -1825,7 +1824,7 @@ export function transformSecondarySketchLinesTagFirst({
}):
| {
modifiedAst: Node<Program>
valueUsedInTransform?: number
valueUsedInTransform?: string
pathToNodeMap: PathToNodeMap
tagInfo: {
tag: string
@ -1904,7 +1903,7 @@ export function transformAstSketchLines({
}):
| {
modifiedAst: Node<Program>
valueUsedInTransform?: number
valueUsedInTransform?: string
pathToNodeMap: PathToNodeMap
}
| Error {
@ -2090,7 +2089,7 @@ export function transformAstSketchLines({
const { modifiedAst, valueUsedInTransform, pathToNode } = replacedSketchLine
node = modifiedAst
pathToNodeMap[index] = pathToNode
if (typeof valueUsedInTransform === 'number') {
if (typeof valueUsedInTransform === 'string') {
_valueUsedInTransform = valueUsedInTransform
}
}

View File

@ -13,7 +13,7 @@ describe('testing angledLineThatIntersects', () => {
|> line(endAbsolute = [2, 2], tag = $yo)
|> line(endAbsolute = [3, 1])
|> angledLineThatIntersects(
angle = 180,
angle = 180deg,
intersectTag = yo,
offset = ${offset},
tag = $yo2,

View File

@ -250,7 +250,7 @@ export type SimplifiedArgDetails =
*/
export interface CreatedSketchExprResult {
callExp: Expr
valueUsedInTransform?: number
valueUsedInTransform?: string
}
export type CreateStdLibSketchCallExpr = (args: {
@ -288,7 +288,7 @@ export interface SketchLineHelperKw {
| {
modifiedAst: Node<Program>
pathToNode: PathToNode
valueUsedInTransform?: number
valueUsedInTransform?: string
}
| Error
updateArgs: (a: updateArgs) =>

View File

@ -764,11 +764,10 @@ export function kclSettings(
*/
export function changeDefaultUnits(
kcl: string,
len: UnitLen | null,
angle: UnitAng | null
len: UnitLen | null
): string | Error {
try {
return change_default_units(kcl, JSON.stringify(len), JSON.stringify(angle))
return change_default_units(kcl, JSON.stringify(len))
} catch (e) {
console.error('Caught error changing kcl settings', e)
return new Error('Caught error changing kcl settings', { cause: e })

View File

@ -61,7 +61,7 @@ export const KCL_DEFAULT_LENGTH = `5`
export const KCL_DEFAULT_TRANSFORM = `0`
/** The default KCL degree expression */
export const KCL_DEFAULT_DEGREE = `360`
export const KCL_DEFAULT_DEGREE = `360deg`
/** The default KCL color expression */
export const KCL_DEFAULT_COLOR = `#3c73ff`

View File

@ -70,7 +70,7 @@ import * from "parameters.kcl"
bottomFaceSketch = startSketchOn(XY)
|> startProfile(at = [-fanSize / 2, -fanSize / 2])
|> angledLine(angle = 0, length = fanSize, tag = $rectangleSegmentA001)
|> angledLine(angle = segAng(rectangleSegmentA001) + 90, length = fanSize, tag = $rectangleSegmentB001)
|> angledLine(angle = segAng(rectangleSegmentA001) + 90deg, length = fanSize, tag = $rectangleSegmentB001)
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001), tag = $rectangleSegmentC001)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)], tag = $rectangleSegmentD001)
|> close()
@ -108,19 +108,19 @@ bottomFaceSketch = startSketchOn(XY)
// Add large openings to the bottom face to allow airflow through the fan
airflowPattern = startSketchOn(bottomFaceSketch, face = END)
|> startProfile(at = [fanSize * 7 / 25, -fanSize * 9 / 25])
|> angledLine(angle = 140, length = fanSize * 12 / 25, tag = $seg01)
|> tangentialArc(radius = fanSize * 1 / 50, angle = 90)
|> angledLine(angle = -130, length = fanSize * 8 / 25)
|> tangentialArc(radius = fanSize * 1 / 50, angle = 90)
|> angledLine(angle = segAng(seg01) + 180, length = fanSize * 2 / 25)
|> tangentialArc(radius = fanSize * 8 / 25, angle = 40)
|> angledLine(angle = 140deg, length = fanSize * 12 / 25, tag = $seg01)
|> tangentialArc(radius = fanSize * 1 / 50, angle = 90deg)
|> angledLine(angle = -130deg, length = fanSize * 8 / 25)
|> tangentialArc(radius = fanSize * 1 / 50, angle = 90deg)
|> angledLine(angle = segAng(seg01) + 180deg, length = fanSize * 2 / 25)
|> tangentialArc(radius = fanSize * 8 / 25, angle = 40deg)
|> xLine(length = fanSize * 3 / 25)
|> tangentialArc(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
|> patternCircular2d(
instances = 4,
center = [0, 0],
arcDegrees = 360,
arcDegrees = 360deg,
rotateDuplicates = true,
)
|> extrude(length = -4)
@ -133,13 +133,13 @@ bodyMiddle = startSketchOn(bottomFaceSketch, face = END)
housingMiddleLength / 2,
-housingMiddleLength / 2 - housingMiddleRadius
])
|> tangentialArc(radius = housingMiddleRadius, angle = 90)
|> tangentialArc(radius = housingMiddleRadius, angle = 90deg)
|> yLine(length = housingMiddleLength)
|> tangentialArc(radius = housingMiddleRadius, angle = 90)
|> tangentialArc(radius = housingMiddleRadius, angle = 90deg)
|> xLine(length = -housingMiddleLength)
|> tangentialArc(radius = housingMiddleRadius, angle = 90)
|> tangentialArc(radius = housingMiddleRadius, angle = 90deg)
|> yLine(length = -housingMiddleLength)
|> tangentialArc(radius = housingMiddleRadius, angle = 90)
|> tangentialArc(radius = housingMiddleRadius, angle = 90deg)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> extrude(length = fanHeight - 4 - 4)
@ -152,7 +152,7 @@ bodyFanHole = startSketchOn(bodyMiddle, face = END)
topFaceSketch = startSketchOn(bodyMiddle, face = END)
topHoles = startProfile(topFaceSketch, at = [-fanSize / 2, -fanSize / 2])
|> angledLine(angle = 0, length = fanSize, tag = $rectangleSegmentA002)
|> angledLine(angle = segAng(rectangleSegmentA002) + 90, length = fanSize, tag = $rectangleSegmentB002)
|> angledLine(angle = segAng(rectangleSegmentA002) + 90deg, length = fanSize, tag = $rectangleSegmentB002)
|> angledLine(angle = segAng(rectangleSegmentA002), length = -segLen(rectangleSegmentA002), tag = $rectangleSegmentC002)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)], tag = $rectangleSegmentD002)
|> close()
@ -229,7 +229,7 @@ export mountingHoleSize = 4.5
bottomFaceSketch = startSketchOn(XY)
|> startProfile(at = [-fanSize / 2, -fanSize / 2])
|> angledLine(angle = 0, length = fanSize, tag = $rectangleSegmentA001)
|> angledLine(angle = segAng(rectangleSegmentA001) + 90, length = fanSize, tag = $rectangleSegmentB001)
|> angledLine(angle = segAng(rectangleSegmentA001) + 90deg, length = fanSize, tag = $rectangleSegmentB001)
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001), tag = $rectangleSegmentC001)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)], tag = $rectangleSegmentD001)
|> close()
@ -267,19 +267,19 @@ bottomFaceSketch = startSketchOn(XY)
// Add large openings to the bottom face to allow airflow through the fan
airflowPattern = startSketchOn(bottomFaceSketch, face = END)
|> startProfile(at = [fanSize * 7 / 25, -fanSize * 9 / 25])
|> angledLine(angle = 140, length = fanSize * 12 / 25, tag = $seg01)
|> tangentialArc(radius = fanSize * 1 / 50, angle = 90)
|> angledLine(angle = -130, length = fanSize * 8 / 25)
|> tangentialArc(radius = fanSize * 1 / 50, angle = 90)
|> angledLine(angle = segAng(seg01) + 180, length = fanSize * 2 / 25)
|> tangentialArc(radius = fanSize * 8 / 25, angle = 40)
|> angledLine(angle = 140deg, length = fanSize * 12 / 25, tag = $seg01)
|> tangentialArc(radius = fanSize * 1 / 50, angle = 90deg)
|> angledLine(angle = -130deg, length = fanSize * 8 / 25)
|> tangentialArc(radius = fanSize * 1 / 50, angle = 90deg)
|> angledLine(angle = segAng(seg01) + 180deg, length = fanSize * 2 / 25)
|> tangentialArc(radius = fanSize * 8 / 25, angle = 40deg)
|> xLine(length = fanSize * 3 / 25)
|> tangentialArc(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
|> patternCircular2d(
instances = 4,
center = [0, 0],
arcDegrees = 360,
arcDegrees = 360deg,
rotateDuplicates = true,
)
|> extrude(length = -4)
@ -292,13 +292,13 @@ bodyMiddle = startSketchOn(bottomFaceSketch, face = END)
housingMiddleLength / 2,
-housingMiddleLength / 2 - housingMiddleRadius
])
|> tangentialArc(radius = housingMiddleRadius, angle = 90)
|> tangentialArc(radius = housingMiddleRadius, angle = 90deg)
|> yLine(length = housingMiddleLength)
|> tangentialArc(radius = housingMiddleRadius, angle = 90)
|> tangentialArc(radius = housingMiddleRadius, angle = 90deg)
|> xLine(length = -housingMiddleLength)
|> tangentialArc(radius = housingMiddleRadius, angle = 90)
|> tangentialArc(radius = housingMiddleRadius, angle = 90deg)
|> yLine(length = -housingMiddleLength)
|> tangentialArc(radius = housingMiddleRadius, angle = 90)
|> tangentialArc(radius = housingMiddleRadius, angle = 90deg)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> extrude(length = fanHeight - 4 - 4)
@ -311,7 +311,7 @@ bodyFanHole = startSketchOn(bodyMiddle, face = END)
topFaceSketch = startSketchOn(bodyMiddle, face = END)
topHoles = startProfile(topFaceSketch, at = [-fanSize / 2, -fanSize / 2])
|> angledLine(angle = 0, length = fanSize, tag = $rectangleSegmentA002)
|> angledLine(angle = segAng(rectangleSegmentA002) + 90, length = fanSize, tag = $rectangleSegmentB002)
|> angledLine(angle = segAng(rectangleSegmentA002) + 90deg, length = fanSize, tag = $rectangleSegmentB002)
|> angledLine(angle = segAng(rectangleSegmentA002), length = -segLen(rectangleSegmentA002), tag = $rectangleSegmentC002)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)], tag = $rectangleSegmentD002)
|> close()
@ -387,7 +387,7 @@ export mountingHoleSize = 4.5
bottomFaceSketch = startSketchOn(XY)
|> startProfile(at = [-fanSize / 2, -fanSize / 2])
|> angledLine(angle = 0, length = fanSize, tag = $rectangleSegmentA001)
|> angledLine(angle = segAng(rectangleSegmentA001) + 90, length = fanSize, tag = $rectangleSegmentB001)
|> angledLine(angle = segAng(rectangleSegmentA001) + 90deg, length = fanSize, tag = $rectangleSegmentB001)
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001), tag = $rectangleSegmentC001)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)], tag = $rectangleSegmentD001)
|> close()
@ -425,19 +425,19 @@ bottomFaceSketch = startSketchOn(XY)
// Add large openings to the bottom face to allow airflow through the fan
airflowPattern = startSketchOn(bottomFaceSketch, face = END)
|> startProfile(at = [fanSize * 7 / 25, -fanSize * 9 / 25])
|> angledLine(angle = 140, length = fanSize * 12 / 25, tag = $seg01)
|> tangentialArc(radius = fanSize * 1 / 50, angle = 90)
|> angledLine(angle = -130, length = fanSize * 8 / 25)
|> tangentialArc(radius = fanSize * 1 / 50, angle = 90)
|> angledLine(angle = segAng(seg01) + 180, length = fanSize * 2 / 25)
|> tangentialArc(radius = fanSize * 8 / 25, angle = 40)
|> angledLine(angle = 140deg, length = fanSize * 12 / 25, tag = $seg01)
|> tangentialArc(radius = fanSize * 1 / 50, angle = 90deg)
|> angledLine(angle = -130deg, length = fanSize * 8 / 25)
|> tangentialArc(radius = fanSize * 1 / 50, angle = 90deg)
|> angledLine(angle = segAng(seg01) + 180deg, length = fanSize * 2 / 25)
|> tangentialArc(radius = fanSize * 8 / 25, angle = 40deg)
|> xLine(length = fanSize * 3 / 25)
|> tangentialArc(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
|> patternCircular2d(
instances = 4,
center = [0, 0],
arcDegrees = 360,
arcDegrees = 360deg,
rotateDuplicates = true,
)
|> extrude(length = -4)
@ -450,13 +450,13 @@ bodyMiddle = startSketchOn(bottomFaceSketch, face = END)
housingMiddleLength / 2,
-housingMiddleLength / 2 - housingMiddleRadius
])
|> tangentialArc(radius = housingMiddleRadius, angle = 90)
|> tangentialArc(radius = housingMiddleRadius, angle = 90deg)
|> yLine(length = housingMiddleLength)
|> tangentialArc(radius = housingMiddleRadius, angle = 90)
|> tangentialArc(radius = housingMiddleRadius, angle = 90deg)
|> xLine(length = -housingMiddleLength)
|> tangentialArc(radius = housingMiddleRadius, angle = 90)
|> tangentialArc(radius = housingMiddleRadius, angle = 90deg)
|> yLine(length = -housingMiddleLength)
|> tangentialArc(radius = housingMiddleRadius, angle = 90)
|> tangentialArc(radius = housingMiddleRadius, angle = 90deg)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> extrude(length = fanHeight - 4 - 4)
@ -469,7 +469,7 @@ bodyFanHole = startSketchOn(bodyMiddle, face = END)
topFaceSketch = startSketchOn(bodyMiddle, face = END)
topHoles = startProfile(topFaceSketch, at = [-fanSize / 2, -fanSize / 2])
|> angledLine(angle = 0, length = fanSize, tag = $rectangleSegmentA002)
|> angledLine(angle = segAng(rectangleSegmentA002) + 90, length = fanSize, tag = $rectangleSegmentB002)
|> angledLine(angle = segAng(rectangleSegmentA002) + 90deg, length = fanSize, tag = $rectangleSegmentB002)
|> angledLine(angle = segAng(rectangleSegmentA002), length = -segLen(rectangleSegmentA002), tag = $rectangleSegmentC002)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)], tag = $rectangleSegmentD002)
|> close()
@ -543,11 +543,11 @@ ${fanHousingBrowser}
fanCenter = startSketchOn(XZ)
|> startProfile(at = [-0.0001, fanHeight])
|> xLine(endAbsolute = -15 + 1.5)
|> tangentialArc(radius = 1.5, angle = 90)
|> tangentialArc(radius = 1.5, angle = 90deg)
|> yLine(endAbsolute = 4.5)
|> xLine(endAbsolute = -13)
|> yLine(endAbsolute = profileStartY(%) - 5)
|> tangentialArc(radius = 1, angle = -90)
|> tangentialArc(radius = 1, angle = -90deg)
|> xLine(endAbsolute = -1)
|> yLine(length = 2)
|> xLine(length = -0.15)
@ -571,32 +571,32 @@ fn fanBlade(offsetHeight, startAngle: number(deg)) {
15 * cos(startAngle),
15 * sin(startAngle)
])
|> arc(angleStart = startAngle, angleEnd = startAngle + 14, radius = 15)
|> arc(angleStart = startAngle, angleEnd = startAngle + 14deg, radius = 15)
|> arc(
endAbsolute = [
fanSize * 22 / 50 * cos(startAngle - 20),
fanSize * 22 / 50 * sin(startAngle - 20)
fanSize * 22 / 50 * cos(startAngle - 20deg),
fanSize * 22 / 50 * sin(startAngle - 20deg)
],
interiorAbsolute = [
fanSize * 11 / 50 * cos(startAngle + 3),
fanSize * 11 / 50 * sin(startAngle + 3)
fanSize * 11 / 50 * cos(startAngle + 3deg),
fanSize * 11 / 50 * sin(startAngle + 3deg)
],
)
|> arc(
endAbsolute = [
fanSize * 22 / 50 * cos(startAngle - 24),
fanSize * 22 / 50 * sin(startAngle - 24)
fanSize * 22 / 50 * cos(startAngle - 24deg),
fanSize * 22 / 50 * sin(startAngle - 24deg)
],
interiorAbsolute = [
fanSize * 22 / 50 * cos(startAngle - 22),
fanSize * 22 / 50 * sin(startAngle - 22)
fanSize * 22 / 50 * cos(startAngle - 22deg),
fanSize * 22 / 50 * sin(startAngle - 22deg)
],
)
|> arc(
endAbsolute = [profileStartX(%), profileStartY(%)],
interiorAbsolute = [
fanSize * 11 / 50 * cos(startAngle - 5),
fanSize * 11 / 50 * sin(startAngle - 5)
fanSize * 11 / 50 * cos(startAngle - 5deg),
fanSize * 11 / 50 * sin(startAngle - 5deg)
],
)
|> close()
@ -605,8 +605,8 @@ fn fanBlade(offsetHeight, startAngle: number(deg)) {
// Loft the fan blade cross sections into a single blade, then pattern them about the fan center
crossSections = [
fanBlade(offsetHeight = 4.5, startAngle = 50),
fanBlade(offsetHeight = (fanHeight - 2 - 4) / 2, startAngle = 30),
fanBlade(offsetHeight = 4.5, startAngle = 50deg),
fanBlade(offsetHeight = (fanHeight - 2 - 4) / 2, startAngle = 30deg),
fanBlade(offsetHeight = fanHeight - 2, startAngle = 0)
]
loft(crossSections)
@ -615,7 +615,7 @@ loft(crossSections)
instances = 9,
axis = [0, 0, 1],
center = [0, 0, 0],
arcDegrees = 360,
arcDegrees = 360deg,
rotateDuplicates = true,
)
@ -650,11 +650,11 @@ ${modifiedFanHousingBrowser}
fanCenter = startSketchOn(XZ)
|> startProfile(at = [-0.0001, fanHeight])
|> xLine(endAbsolute = -15 + 1.5)
|> tangentialArc(radius = 1.5, angle = 90)
|> tangentialArc(radius = 1.5, angle = 90deg)
|> yLine(endAbsolute = 4.5)
|> xLine(endAbsolute = -13)
|> yLine(endAbsolute = profileStartY(%) - 5)
|> tangentialArc(radius = 1, angle = -90)
|> tangentialArc(radius = 1, angle = -90deg)
|> xLine(endAbsolute = -1)
|> yLine(length = 2)
|> xLine(length = -0.15)
@ -678,32 +678,32 @@ fn fanBlade(offsetHeight, startAngle: number(deg)) {
15 * cos(startAngle),
15 * sin(startAngle)
])
|> arc(angleStart = startAngle, angleEnd = startAngle + 14, radius = 15)
|> arc(angleStart = startAngle, angleEnd = startAngle + 14deg, radius = 15)
|> arc(
endAbsolute = [
fanSize * 22 / 50 * cos(startAngle - 20),
fanSize * 22 / 50 * sin(startAngle - 20)
fanSize * 22 / 50 * cos(startAngle - 20deg),
fanSize * 22 / 50 * sin(startAngle - 20deg)
],
interiorAbsolute = [
fanSize * 11 / 50 * cos(startAngle + 3),
fanSize * 11 / 50 * sin(startAngle + 3)
fanSize * 11 / 50 * cos(startAngle + 3deg),
fanSize * 11 / 50 * sin(startAngle + 3deg)
],
)
|> arc(
endAbsolute = [
fanSize * 22 / 50 * cos(startAngle - 24),
fanSize * 22 / 50 * sin(startAngle - 24)
fanSize * 22 / 50 * cos(startAngle - 24deg),
fanSize * 22 / 50 * sin(startAngle - 24deg)
],
interiorAbsolute = [
fanSize * 22 / 50 * cos(startAngle - 22),
fanSize * 22 / 50 * sin(startAngle - 22)
fanSize * 22 / 50 * cos(startAngle - 22deg),
fanSize * 22 / 50 * sin(startAngle - 22deg)
],
)
|> arc(
endAbsolute = [profileStartX(%), profileStartY(%)],
interiorAbsolute = [
fanSize * 11 / 50 * cos(startAngle - 5),
fanSize * 11 / 50 * sin(startAngle - 5)
fanSize * 11 / 50 * cos(startAngle - 5deg),
fanSize * 11 / 50 * sin(startAngle - 5deg)
],
)
|> close()
@ -712,8 +712,8 @@ fn fanBlade(offsetHeight, startAngle: number(deg)) {
// Loft the fan blade cross sections into a single blade, then pattern them about the fan center
crossSections = [
fanBlade(offsetHeight = 4.5, startAngle = 50),
fanBlade(offsetHeight = (fanHeight - 2 - 4) / 2, startAngle = 30),
fanBlade(offsetHeight = 4.5, startAngle = 50deg),
fanBlade(offsetHeight = (fanHeight - 2 - 4) / 2, startAngle = 30deg),
fanBlade(offsetHeight = fanHeight - 2, startAngle = 0)
]
loft(crossSections)
@ -722,7 +722,7 @@ loft(crossSections)
instances = 9,
axis = [0, 0, 1],
center = [0, 0, 0],
arcDegrees = 360,
arcDegrees = 360deg,
rotateDuplicates = true,
)

View File

@ -3,11 +3,7 @@ import toast from 'react-hot-toast'
import { updateModelingState } from '@src/lang/modelingWorkflows'
import { addModuleImport } from '@src/lang/modifyAst'
import {
changeDefaultUnits,
unitAngleToUnitAng,
unitLengthToUnitLen,
} from '@src/lang/wasm'
import { changeDefaultUnits, unitLengthToUnitLen } from '@src/lang/wasm'
import type { Command, CommandArgumentOption } from '@src/lib/commandTypes'
import {
DEFAULT_DEFAULT_LENGTH_UNIT,
@ -69,8 +65,7 @@ export function kclCommands(commandProps: KclCommandConfig): Command[] {
if (typeof data === 'object' && 'unit' in data) {
const newCode = changeDefaultUnits(
codeManager.code,
unitLengthToUnitLen(data.unit),
unitAngleToUnitAng(undefined)
unitLengthToUnitLen(data.unit)
)
if (err(newCode)) {
toast.error(`Failed to set per-file units: ${newCode.message}`)

View File

@ -21,7 +21,7 @@ describe('library rectangleTool helper functions', () => {
const sourceCode = `sketch001 = startSketchOn(XZ)
profile001 = startProfile(at = [120.37, 162.76])
|> angledLine(angle = 0, length = 0, tag = $rectangleSegmentA001)
|> angledLine(angle = segAng(rectangleSegmentA001) + 90, length = 0, tag = $rectangleSegmentB001)
|> angledLine(angle = segAng(rectangleSegmentA001) + 90deg, length = 0, tag = $rectangleSegmentB001)
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001), tag = $rectangleSegmentC001)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
@ -71,7 +71,7 @@ profile001 = startProfile(at = [120.37, 162.76])
const expectedSourceCode = `sketch001 = startSketchOn(XZ)
profile001 = startProfile(at = [80, 120])
|> angledLine(angle = 0, length = 80, tag = $rectangleSegmentA001)
|> angledLine(angle = segAng(rectangleSegmentA001) + 90, length = 120, tag = $rectangleSegmentB001)
|> angledLine(angle = segAng(rectangleSegmentA001) + 90deg, length = 120, tag = $rectangleSegmentB001)
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001), tag = $rectangleSegmentC001)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()

View File

@ -54,7 +54,7 @@ function angledLine(
export const getRectangleCallExpressions = (tag: string) => {
return [
angledLine(
createLiteral(0), // 0 deg
createLiteral(0, 'Deg'), // 0 deg
createLiteral(0), // This will be the width of the rectangle
tag
),
@ -62,7 +62,7 @@ export const getRectangleCallExpressions = (tag: string) => {
createBinaryExpression([
createCallExpressionStdLibKw('segAng', createLocalName(tag), []),
'+',
createLiteral(90),
createLiteral(90, 'Deg'),
]), // 90 offset from the previous line
createLiteral(0) // This will be the height of the rectangle
),
@ -108,7 +108,7 @@ export function updateRectangleSketch(
tag: string
) {
const firstEdge = pipeExpression.body[1] as CallExpressionKw
mutateKwArgOnly('angle', firstEdge, createLiteral(x >= 0 ? 0 : 180))
mutateKwArgOnly('angle', firstEdge, createLiteral(x >= 0 ? 0 : 180, 'Deg'))
mutateKwArgOnly('length', firstEdge, createLiteral(Math.abs(x)))
const secondEdge = pipeExpression.body[2] as CallExpressionKw
// 90 offset from the previous line
@ -118,7 +118,7 @@ export function updateRectangleSketch(
createBinaryExpression([
createCallExpressionStdLibKw('segAng', createLocalName(tag), []),
Math.sign(y) === Math.sign(x) ? '+' : '-',
createLiteral(90),
createLiteral(90, 'Deg'),
])
)
// This will be the height of the rectangle
@ -196,7 +196,7 @@ export function updateCenterRectangleSketch(
const newAngle = createBinaryExpression([
createCallExpressionStdLibKw('segAng', createLocalName(tag), []),
oldAngleOperator,
createLiteral(90),
createLiteral(90, 'Deg'),
])
// Calculate new height.