Compare commits
6 Commits
jtran/plus
...
franknoiro
Author | SHA1 | Date | |
---|---|---|---|
117e696430 | |||
c18a2223f3 | |||
c5492a7937 | |||
19a3c255c3 | |||
f93979c648 | |||
6288ab5f2f |
@ -4,8 +4,12 @@ excerpt: "Converts a number from centimeters to the current default unit."
|
|||||||
layout: manual
|
layout: manual
|
||||||
---
|
---
|
||||||
|
|
||||||
|
**WARNING:** This function is deprecated.
|
||||||
|
|
||||||
Converts a number from centimeters to the current default unit.
|
Converts a number from centimeters to the current default unit.
|
||||||
|
|
||||||
|
*DEPRECATED* prefer using explicit numeric suffixes (e.g., `42cm`) or the `to...` conversion functions.
|
||||||
|
|
||||||
No matter what units the current file uses, this function will always return a number equivalent to the input in centimeters.
|
No matter what units the current file uses, this function will always return a number equivalent to the input in centimeters.
|
||||||
|
|
||||||
For example, if the current file uses inches, `fromCm(1)` will return `0.393701`. If the current file uses millimeters, `fromCm(1)` will return `10`. If the current file uses centimeters, `fromCm(1)` will return `1`.
|
For example, if the current file uses inches, `fromCm(1)` will return `0.393701`. If the current file uses millimeters, `fromCm(1)` will return `10`. If the current file uses centimeters, `fromCm(1)` will return `1`.
|
||||||
|
@ -4,8 +4,12 @@ excerpt: "Converts a number from feet to the current default unit."
|
|||||||
layout: manual
|
layout: manual
|
||||||
---
|
---
|
||||||
|
|
||||||
|
**WARNING:** This function is deprecated.
|
||||||
|
|
||||||
Converts a number from feet to the current default unit.
|
Converts a number from feet to the current default unit.
|
||||||
|
|
||||||
|
*DEPRECATED* prefer using explicit numeric suffixes (e.g., `42ft`) or the `to...` conversion functions.
|
||||||
|
|
||||||
No matter what units the current file uses, this function will always return a number equivalent to the input in feet.
|
No matter what units the current file uses, this function will always return a number equivalent to the input in feet.
|
||||||
|
|
||||||
For example, if the current file uses inches, `fromFt(1)` will return `12`. If the current file uses millimeters, `fromFt(1)` will return `304.8`. If the current file uses feet, `fromFt(1)` will return `1`.
|
For example, if the current file uses inches, `fromFt(1)` will return `12`. If the current file uses millimeters, `fromFt(1)` will return `304.8`. If the current file uses feet, `fromFt(1)` will return `1`.
|
||||||
|
@ -4,8 +4,12 @@ excerpt: "Converts a number from inches to the current default unit."
|
|||||||
layout: manual
|
layout: manual
|
||||||
---
|
---
|
||||||
|
|
||||||
|
**WARNING:** This function is deprecated.
|
||||||
|
|
||||||
Converts a number from inches to the current default unit.
|
Converts a number from inches to the current default unit.
|
||||||
|
|
||||||
|
*DEPRECATED* prefer using explicit numeric suffixes (e.g., `42inch`) or the `to...` conversion functions.
|
||||||
|
|
||||||
No matter what units the current file uses, this function will always return a number equivalent to the input in inches.
|
No matter what units the current file uses, this function will always return a number equivalent to the input in inches.
|
||||||
|
|
||||||
For example, if the current file uses inches, `fromInches(1)` will return `1`. If the current file uses millimeters, `fromInches(1)` will return `25.4`.
|
For example, if the current file uses inches, `fromInches(1)` will return `1`. If the current file uses millimeters, `fromInches(1)` will return `25.4`.
|
||||||
|
@ -4,8 +4,12 @@ excerpt: "Converts a number from meters to the current default unit."
|
|||||||
layout: manual
|
layout: manual
|
||||||
---
|
---
|
||||||
|
|
||||||
|
**WARNING:** This function is deprecated.
|
||||||
|
|
||||||
Converts a number from meters to the current default unit.
|
Converts a number from meters to the current default unit.
|
||||||
|
|
||||||
|
*DEPRECATED* prefer using explicit numeric suffixes (e.g., `42m`) or the `to...` conversion functions.
|
||||||
|
|
||||||
No matter what units the current file uses, this function will always return a number equivalent to the input in meters.
|
No matter what units the current file uses, this function will always return a number equivalent to the input in meters.
|
||||||
|
|
||||||
For example, if the current file uses inches, `fromM(1)` will return `39.3701`. If the current file uses millimeters, `fromM(1)` will return `1000`. If the current file uses meters, `fromM(1)` will return `1`.
|
For example, if the current file uses inches, `fromM(1)` will return `39.3701`. If the current file uses millimeters, `fromM(1)` will return `1000`. If the current file uses meters, `fromM(1)` will return `1`.
|
||||||
|
@ -4,8 +4,12 @@ excerpt: "Converts a number from mm to the current default unit."
|
|||||||
layout: manual
|
layout: manual
|
||||||
---
|
---
|
||||||
|
|
||||||
|
**WARNING:** This function is deprecated.
|
||||||
|
|
||||||
Converts a number from mm to the current default unit.
|
Converts a number from mm to the current default unit.
|
||||||
|
|
||||||
|
*DEPRECATED* prefer using explicit numeric suffixes (e.g., `42mm`) or the `to...` conversion functions.
|
||||||
|
|
||||||
No matter what units the current file uses, this function will always return a number equivalent to the input in millimeters.
|
No matter what units the current file uses, this function will always return a number equivalent to the input in millimeters.
|
||||||
|
|
||||||
For example, if the current file uses inches, `fromMm(1)` will return `1/25.4`. If the current file uses millimeters, `fromMm(1)` will return `1`.
|
For example, if the current file uses inches, `fromMm(1)` will return `1/25.4`. If the current file uses millimeters, `fromMm(1)` will return `1`.
|
||||||
|
@ -4,8 +4,12 @@ excerpt: "Converts a number from yards to the current default unit."
|
|||||||
layout: manual
|
layout: manual
|
||||||
---
|
---
|
||||||
|
|
||||||
|
**WARNING:** This function is deprecated.
|
||||||
|
|
||||||
Converts a number from yards to the current default unit.
|
Converts a number from yards to the current default unit.
|
||||||
|
|
||||||
|
*DEPRECATED* prefer using explicit numeric suffixes (e.g., `42yd`) or the `to...` conversion functions.
|
||||||
|
|
||||||
No matter what units the current file uses, this function will always return a number equivalent to the input in yards.
|
No matter what units the current file uses, this function will always return a number equivalent to the input in yards.
|
||||||
|
|
||||||
For example, if the current file uses inches, `fromYd(1)` will return `36`. If the current file uses millimeters, `fromYd(1)` will return `914.4`. If the current file uses yards, `fromYd(1)` will return `1`.
|
For example, if the current file uses inches, `fromYd(1)` will return `36`. If the current file uses millimeters, `fromYd(1)` will return `914.4`. If the current file uses yards, `fromYd(1)` will return `1`.
|
||||||
|
@ -55,12 +55,6 @@ layout: manual
|
|||||||
* [`extrude`](kcl/extrude)
|
* [`extrude`](kcl/extrude)
|
||||||
* [`fillet`](kcl/fillet)
|
* [`fillet`](kcl/fillet)
|
||||||
* [`floor`](kcl/floor)
|
* [`floor`](kcl/floor)
|
||||||
* [`fromCm`](kcl/fromCm)
|
|
||||||
* [`fromFt`](kcl/fromFt)
|
|
||||||
* [`fromInches`](kcl/fromInches)
|
|
||||||
* [`fromM`](kcl/fromM)
|
|
||||||
* [`fromMm`](kcl/fromMm)
|
|
||||||
* [`fromYd`](kcl/fromYd)
|
|
||||||
* [`getCommonEdge`](kcl/getCommonEdge)
|
* [`getCommonEdge`](kcl/getCommonEdge)
|
||||||
* [`getNextAdjacentEdge`](kcl/getNextAdjacentEdge)
|
* [`getNextAdjacentEdge`](kcl/getNextAdjacentEdge)
|
||||||
* [`getOppositeEdge`](kcl/getOppositeEdge)
|
* [`getOppositeEdge`](kcl/getOppositeEdge)
|
||||||
@ -120,8 +114,14 @@ layout: manual
|
|||||||
* [`sweep`](kcl/sweep)
|
* [`sweep`](kcl/sweep)
|
||||||
* [`tangentToEnd`](kcl/tangentToEnd)
|
* [`tangentToEnd`](kcl/tangentToEnd)
|
||||||
* [`tangentialArc`](kcl/tangentialArc)
|
* [`tangentialArc`](kcl/tangentialArc)
|
||||||
* [`toDegrees`](kcl/toDegrees)
|
* [`toCentimeters`](kcl/std-toCentimeters)
|
||||||
* [`toRadians`](kcl/toRadians)
|
* [`toDegrees`](kcl/std-toDegrees)
|
||||||
|
* [`toFeet`](kcl/std-toFeet)
|
||||||
|
* [`toInches`](kcl/std-toInches)
|
||||||
|
* [`toMeters`](kcl/std-toMeters)
|
||||||
|
* [`toMillimeters`](kcl/std-toMillimeters)
|
||||||
|
* [`toRadians`](kcl/std-toRadians)
|
||||||
|
* [`toYards`](kcl/std-toYards)
|
||||||
* [`translate`](kcl/translate)
|
* [`translate`](kcl/translate)
|
||||||
* [`union`](kcl/union)
|
* [`union`](kcl/union)
|
||||||
* [`xLine`](kcl/xLine)
|
* [`xLine`](kcl/xLine)
|
||||||
|
@ -174,7 +174,7 @@ t = 0.005 // taper factor [0-1)
|
|||||||
// Defines how to modify each layer of the vase.
|
// Defines how to modify each layer of the vase.
|
||||||
// Each replica is shifted up the Z axis, and has a smoothly-varying radius
|
// Each replica is shifted up the Z axis, and has a smoothly-varying radius
|
||||||
fn transform(replicaId) {
|
fn transform(replicaId) {
|
||||||
scale = r * abs(1 - (t * replicaId)) * (5 + cos(replicaId / 8))
|
scale = r * abs(1 - (t * replicaId)) * (5 + cos(replicaId / 8: number(rad)))
|
||||||
return {
|
return {
|
||||||
translate = [0, 0, replicaId * 10],
|
translate = [0, 0, replicaId * 10],
|
||||||
scale = [scale, scale, 0]
|
scale = [scale, scale, 0]
|
||||||
|
@ -26,7 +26,7 @@ helix(
|
|||||||
| Name | Type | Description | Required |
|
| Name | Type | Description | Required |
|
||||||
|----------|------|-------------|----------|
|
|----------|------|-------------|----------|
|
||||||
| `revolutions` | `number(_)` | Number of revolutions. | Yes |
|
| `revolutions` | `number(_)` | Number of revolutions. | Yes |
|
||||||
| `angleStart` | `number(Angle)` | Start angle (in degrees). | Yes |
|
| `angleStart` | `number(Angle)` | Start angle. | Yes |
|
||||||
| `ccw` | [`bool`](/docs/kcl/types/bool) | Is the helix rotation counter clockwise? The default is `false`. | No |
|
| `ccw` | [`bool`](/docs/kcl/types/bool) | Is the helix rotation counter clockwise? The default is `false`. | No |
|
||||||
| `radius` | `number(Length)` | Radius of the helix. | No |
|
| `radius` | `number(Length)` | Radius of the helix. | No |
|
||||||
| `axis` | `Axis3d | Edge` | Axis to use for the helix. | No |
|
| `axis` | `Axis3d | Edge` | Axis to use for the helix. | No |
|
||||||
|
@ -31,7 +31,7 @@ exampleSketch = startSketchOn(XZ)
|
|||||||
|> startProfileAt([0, 0], %)
|
|> startProfileAt([0, 0], %)
|
||||||
|> angledLine(
|
|> angledLine(
|
||||||
angle = 30,
|
angle = 30,
|
||||||
length = 3 / cos(toRadians(30)),
|
length = 3 / cos(30deg),
|
||||||
)
|
)
|
||||||
|> yLine(endAbsolute = 0)
|
|> yLine(endAbsolute = 0)
|
||||||
|> close()
|
|> close()
|
||||||
|
@ -11,7 +11,7 @@ cartesian (x/y/z grid) coordinates.
|
|||||||
|
|
||||||
```js
|
```js
|
||||||
polar(
|
polar(
|
||||||
angle: number(Angle),
|
angle: number(rad),
|
||||||
length: number(Length),
|
length: number(Length),
|
||||||
): Point2d
|
): Point2d
|
||||||
```
|
```
|
||||||
@ -21,7 +21,7 @@ polar(
|
|||||||
|
|
||||||
| Name | Type | Description | Required |
|
| Name | Type | Description | Required |
|
||||||
|----------|------|-------------|----------|
|
|----------|------|-------------|----------|
|
||||||
| `angle` | `number(Angle)` | | Yes |
|
| `angle` | `number(rad)` | | Yes |
|
||||||
| `length` | `number(Length)` | | Yes |
|
| `length` | `number(Length)` | | Yes |
|
||||||
|
|
||||||
### Returns
|
### Returns
|
||||||
|
@ -31,7 +31,7 @@ exampleSketch = startSketchOn(XZ)
|
|||||||
|> startProfileAt([0, 0], %)
|
|> startProfileAt([0, 0], %)
|
||||||
|> angledLine(
|
|> angledLine(
|
||||||
angle = 50,
|
angle = 50,
|
||||||
length = 15 / sin(toRadians(135)),
|
length = 15 / sin(135deg),
|
||||||
)
|
)
|
||||||
|> yLine(endAbsolute = 0)
|
|> yLine(endAbsolute = 0)
|
||||||
|> close()
|
|> close()
|
||||||
|
@ -31,7 +31,7 @@ exampleSketch = startSketchOn(XZ)
|
|||||||
|> startProfileAt([0, 0], %)
|
|> startProfileAt([0, 0], %)
|
||||||
|> angledLine(
|
|> angledLine(
|
||||||
angle = 50,
|
angle = 50,
|
||||||
length = 50 * tan(1/2),
|
length = 50 * tan((1/2): number(rad)),
|
||||||
)
|
)
|
||||||
|> yLine(endAbsolute = 0)
|
|> yLine(endAbsolute = 0)
|
||||||
|> close()
|
|> close()
|
||||||
|
27
docs/kcl/std-toCentimeters.md
Normal file
27
docs/kcl/std-toCentimeters.md
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
---
|
||||||
|
title: "std::toCentimeters"
|
||||||
|
excerpt: "Convert a number to centimeters from its current units."
|
||||||
|
layout: manual
|
||||||
|
---
|
||||||
|
|
||||||
|
Convert a number to centimeters from its current units.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
```js
|
||||||
|
toCentimeters(@num: number(cm)): number(cm)
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### Arguments
|
||||||
|
|
||||||
|
| Name | Type | Description | Required |
|
||||||
|
|----------|------|-------------|----------|
|
||||||
|
| `num` | `number(cm)` | | Yes |
|
||||||
|
|
||||||
|
### Returns
|
||||||
|
|
||||||
|
`number(cm)`
|
||||||
|
|
||||||
|
|
||||||
|
|
44
docs/kcl/std-toDegrees.md
Normal file
44
docs/kcl/std-toDegrees.md
Normal file
File diff suppressed because one or more lines are too long
27
docs/kcl/std-toFeet.md
Normal file
27
docs/kcl/std-toFeet.md
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
---
|
||||||
|
title: "std::toFeet"
|
||||||
|
excerpt: "Convert a number to feet from its current units."
|
||||||
|
layout: manual
|
||||||
|
---
|
||||||
|
|
||||||
|
Convert a number to feet from its current units.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
```js
|
||||||
|
toFeet(@num: number(ft)): number(ft)
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### Arguments
|
||||||
|
|
||||||
|
| Name | Type | Description | Required |
|
||||||
|
|----------|------|-------------|----------|
|
||||||
|
| `num` | `number(ft)` | | Yes |
|
||||||
|
|
||||||
|
### Returns
|
||||||
|
|
||||||
|
`number(ft)`
|
||||||
|
|
||||||
|
|
||||||
|
|
27
docs/kcl/std-toInches.md
Normal file
27
docs/kcl/std-toInches.md
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
---
|
||||||
|
title: "std::toInches"
|
||||||
|
excerpt: "Convert a number to inches from its current units."
|
||||||
|
layout: manual
|
||||||
|
---
|
||||||
|
|
||||||
|
Convert a number to inches from its current units.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
```js
|
||||||
|
toInches(@num: number(in)): number(in)
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### Arguments
|
||||||
|
|
||||||
|
| Name | Type | Description | Required |
|
||||||
|
|----------|------|-------------|----------|
|
||||||
|
| `num` | `number(in)` | | Yes |
|
||||||
|
|
||||||
|
### Returns
|
||||||
|
|
||||||
|
`number(in)`
|
||||||
|
|
||||||
|
|
||||||
|
|
27
docs/kcl/std-toMeters.md
Normal file
27
docs/kcl/std-toMeters.md
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
---
|
||||||
|
title: "std::toMeters"
|
||||||
|
excerpt: "Convert a number to meters from its current units."
|
||||||
|
layout: manual
|
||||||
|
---
|
||||||
|
|
||||||
|
Convert a number to meters from its current units.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
```js
|
||||||
|
toMeters(@num: number(m)): number(m)
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### Arguments
|
||||||
|
|
||||||
|
| Name | Type | Description | Required |
|
||||||
|
|----------|------|-------------|----------|
|
||||||
|
| `num` | `number(m)` | | Yes |
|
||||||
|
|
||||||
|
### Returns
|
||||||
|
|
||||||
|
`number(m)`
|
||||||
|
|
||||||
|
|
||||||
|
|
27
docs/kcl/std-toMillimeters.md
Normal file
27
docs/kcl/std-toMillimeters.md
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
---
|
||||||
|
title: "std::toMillimeters"
|
||||||
|
excerpt: "Convert a number to millimeters from its current units."
|
||||||
|
layout: manual
|
||||||
|
---
|
||||||
|
|
||||||
|
Convert a number to millimeters from its current units.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
```js
|
||||||
|
toMillimeters(@num: number(mm)): number(mm)
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### Arguments
|
||||||
|
|
||||||
|
| Name | Type | Description | Required |
|
||||||
|
|----------|------|-------------|----------|
|
||||||
|
| `num` | `number(mm)` | | Yes |
|
||||||
|
|
||||||
|
### Returns
|
||||||
|
|
||||||
|
`number(mm)`
|
||||||
|
|
||||||
|
|
||||||
|
|
44
docs/kcl/std-toRadians.md
Normal file
44
docs/kcl/std-toRadians.md
Normal file
File diff suppressed because one or more lines are too long
27
docs/kcl/std-toYards.md
Normal file
27
docs/kcl/std-toYards.md
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
---
|
||||||
|
title: "std::toYards"
|
||||||
|
excerpt: "Converts a number to yards from its current units."
|
||||||
|
layout: manual
|
||||||
|
---
|
||||||
|
|
||||||
|
Converts a number to yards from its current units.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
```js
|
||||||
|
toYards(@num: number(yd)): number(yd)
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### Arguments
|
||||||
|
|
||||||
|
| Name | Type | Description | Required |
|
||||||
|
|----------|------|-------------|----------|
|
||||||
|
| `num` | `number(yd)` | | Yes |
|
||||||
|
|
||||||
|
### Returns
|
||||||
|
|
||||||
|
`number(yd)`
|
||||||
|
|
||||||
|
|
||||||
|
|
1275
docs/kcl/std.json
1275
docs/kcl/std.json
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -31,7 +31,6 @@ A sketch type.
|
|||||||
| `xAxis` |[`Point3d`](/docs/kcl/types/Point3d)| What should the plane's X axis be? | No |
|
| `xAxis` |[`Point3d`](/docs/kcl/types/Point3d)| What should the plane's X axis be? | No |
|
||||||
| `yAxis` |[`Point3d`](/docs/kcl/types/Point3d)| What should the plane's Y axis be? | No |
|
| `yAxis` |[`Point3d`](/docs/kcl/types/Point3d)| What should the plane's Y axis be? | No |
|
||||||
| `zAxis` |[`Point3d`](/docs/kcl/types/Point3d)| The z-axis (normal). | No |
|
| `zAxis` |[`Point3d`](/docs/kcl/types/Point3d)| The z-axis (normal). | No |
|
||||||
| `units` |[`UnitLen`](/docs/kcl/types/UnitLen)| A unit of length. | No |
|
|
||||||
|
|
||||||
|
|
||||||
----
|
----
|
||||||
|
@ -63,7 +63,7 @@ test.describe('Onboarding tests', () => {
|
|||||||
{
|
{
|
||||||
tag: '@electron',
|
tag: '@electron',
|
||||||
},
|
},
|
||||||
async ({ page, tronApp }) => {
|
async ({ page, tronApp, scene }) => {
|
||||||
if (!tronApp) {
|
if (!tronApp) {
|
||||||
fail()
|
fail()
|
||||||
}
|
}
|
||||||
@ -72,7 +72,6 @@ test.describe('Onboarding tests', () => {
|
|||||||
onboarding_status: '',
|
onboarding_status: '',
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
const u = await getUtils(page)
|
|
||||||
|
|
||||||
const viewportSize = { width: 1200, height: 500 }
|
const viewportSize = { width: 1200, height: 500 }
|
||||||
await page.setBodyDimensions(viewportSize)
|
await page.setBodyDimensions(viewportSize)
|
||||||
@ -80,7 +79,7 @@ test.describe('Onboarding tests', () => {
|
|||||||
await test.step(`Create a project and open to the onboarding`, async () => {
|
await test.step(`Create a project and open to the onboarding`, async () => {
|
||||||
await createProject({ name: 'project-link', page })
|
await createProject({ name: 'project-link', page })
|
||||||
await test.step(`Ensure the engine connection works by testing the sketch button`, async () => {
|
await test.step(`Ensure the engine connection works by testing the sketch button`, async () => {
|
||||||
await u.waitForPageLoad()
|
await scene.connectionEstablished()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -278,7 +278,7 @@ test.describe('Point-and-click assemblies tests', () => {
|
|||||||
highlightedHeaderArg: 'x',
|
highlightedHeaderArg: 'x',
|
||||||
commandName: 'Translate',
|
commandName: 'Translate',
|
||||||
})
|
})
|
||||||
await page.keyboard.insertText('5')
|
await page.keyboard.insertText('100')
|
||||||
await cmdBar.progressCmdBar()
|
await cmdBar.progressCmdBar()
|
||||||
await page.keyboard.insertText('0.1')
|
await page.keyboard.insertText('0.1')
|
||||||
await cmdBar.progressCmdBar()
|
await cmdBar.progressCmdBar()
|
||||||
@ -287,7 +287,7 @@ test.describe('Point-and-click assemblies tests', () => {
|
|||||||
await cmdBar.expectState({
|
await cmdBar.expectState({
|
||||||
stage: 'review',
|
stage: 'review',
|
||||||
headerArguments: {
|
headerArguments: {
|
||||||
X: '5',
|
X: '100',
|
||||||
Y: '0.1',
|
Y: '0.1',
|
||||||
Z: '0.2',
|
Z: '0.2',
|
||||||
},
|
},
|
||||||
@ -299,7 +299,7 @@ test.describe('Point-and-click assemblies tests', () => {
|
|||||||
await editor.expectEditor.toContain(
|
await editor.expectEditor.toContain(
|
||||||
`
|
`
|
||||||
bracket
|
bracket
|
||||||
|> translate(x = 5, y = 0.1, z = 0.2)
|
|> translate(x = 100, y = 0.1, z = 0.2)
|
||||||
`,
|
`,
|
||||||
{ shouldNormalise: true }
|
{ shouldNormalise: true }
|
||||||
)
|
)
|
||||||
@ -348,7 +348,7 @@ test.describe('Point-and-click assemblies tests', () => {
|
|||||||
await editor.expectEditor.toContain(
|
await editor.expectEditor.toContain(
|
||||||
`
|
`
|
||||||
bracket
|
bracket
|
||||||
|> translate(x = 5, y = 0.1, z = 0.2)
|
|> translate(x = 100, y = 0.1, z = 0.2)
|
||||||
|> rotate(roll = 0.1, pitch = 0.2, yaw = 0.3)
|
|> rotate(roll = 0.1, pitch = 0.2, yaw = 0.3)
|
||||||
`,
|
`,
|
||||||
{ shouldNormalise: true }
|
{ shouldNormalise: true }
|
||||||
|
@ -33,11 +33,11 @@ invas = map(angles, fn(a) {
|
|||||||
|
|
||||||
// Map the involute curve
|
// Map the involute curve
|
||||||
xs = map([0..cmo], fn(i) {
|
xs = map([0..cmo], fn(i) {
|
||||||
return rs[i] * cos(invas[i])
|
return rs[i] * cos(invas[i]: number(rad))
|
||||||
})
|
})
|
||||||
|
|
||||||
ys = map([0..cmo], fn(i) {
|
ys = map([0..cmo], fn(i) {
|
||||||
return rs[i] * sin(invas[i])
|
return rs[i] * sin(invas[i]: number(rad))
|
||||||
})
|
})
|
||||||
|
|
||||||
// Extrude the gear body
|
// Extrude the gear body
|
||||||
|
@ -29,7 +29,7 @@ sketch001 = startSketchOn(XZ)
|
|||||||
)
|
)
|
||||||
|> yLine(endAbsolute = -templateThickness, tag = $seg03)
|
|> yLine(endAbsolute = -templateThickness, tag = $seg03)
|
||||||
|> xLine(length = templateThickness, tag = $seg07)
|
|> xLine(length = templateThickness, tag = $seg07)
|
||||||
|> yLine(endAbsolute = (segEndY(seg01) + templateThickness) / 2 - templateThickness, tag = $seg02)
|
|> yLine(endAbsolute = (segEndY(seg01) + templateThickness) / 2_ - templateThickness, tag = $seg02)
|
||||||
|> xLine(endAbsolute = segEndX(seg03) + minClampingDistance, tag = $seg06)
|
|> xLine(endAbsolute = segEndX(seg03) + minClampingDistance, tag = $seg06)
|
||||||
|> yLine(length = templateThickness * 2, tag = $seg08)
|
|> yLine(length = templateThickness * 2, tag = $seg08)
|
||||||
|> xLine(endAbsolute = segEndX(seg02) + 0, tag = $seg05)
|
|> xLine(endAbsolute = segEndX(seg02) + 0, tag = $seg05)
|
||||||
|
@ -5,7 +5,7 @@ const t = 0.005 // taper factor [0-1)
|
|||||||
// Defines how to modify each layer of the vase.
|
// Defines how to modify each layer of the vase.
|
||||||
// Each replica is shifted up the Z axis, and has a smoothly-varying radius
|
// Each replica is shifted up the Z axis, and has a smoothly-varying radius
|
||||||
fn transform = (replicaId) => {
|
fn transform = (replicaId) => {
|
||||||
let scale = r * abs(1 - (t * replicaId)) * (5 + cos(replicaId / 8))
|
let scale = r * abs(1 - (t * replicaId)) * (5 + cos((replicaId / 8): number(rad)))
|
||||||
return {
|
return {
|
||||||
translate: [0, 0, replicaId * 10],
|
translate: [0, 0, replicaId * 10],
|
||||||
scale: [scale, scale, 0],
|
scale: [scale, scale, 0],
|
||||||
|
@ -180,10 +180,6 @@ pub trait EngineManager: std::fmt::Debug + Send + Sync + 'static {
|
|||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
// Reset to the default units. Modules assume the engine starts in the
|
|
||||||
// default state.
|
|
||||||
self.set_units(Default::default(), source_range, id_generator).await?;
|
|
||||||
|
|
||||||
// Flush the batch queue, so clear is run right away.
|
// Flush the batch queue, so clear is run right away.
|
||||||
// Otherwise the hooks below won't work.
|
// Otherwise the hooks below won't work.
|
||||||
self.flush_batch(false, source_range).await?;
|
self.flush_batch(false, source_range).await?;
|
||||||
@ -298,23 +294,6 @@ pub trait EngineManager: std::fmt::Debug + Send + Sync + 'static {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn set_units(
|
|
||||||
&self,
|
|
||||||
units: crate::UnitLength,
|
|
||||||
source_range: SourceRange,
|
|
||||||
id_generator: &mut IdGenerator,
|
|
||||||
) -> Result<(), crate::errors::KclError> {
|
|
||||||
// Before we even start executing the program, set the units.
|
|
||||||
self.batch_modeling_cmd(
|
|
||||||
id_generator.next_uuid(),
|
|
||||||
source_range,
|
|
||||||
&ModelingCmd::from(mcmd::SetSceneUnits { unit: units.into() }),
|
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Re-run the command to apply the settings.
|
/// Re-run the command to apply the settings.
|
||||||
async fn reapply_settings(
|
async fn reapply_settings(
|
||||||
&self,
|
&self,
|
||||||
|
@ -3,11 +3,7 @@ use std::collections::HashMap;
|
|||||||
use async_recursion::async_recursion;
|
use async_recursion::async_recursion;
|
||||||
use indexmap::IndexMap;
|
use indexmap::IndexMap;
|
||||||
|
|
||||||
use super::{
|
use super::{cad_op::Group, kcl_value::TypeDef, types::PrimitiveType};
|
||||||
cad_op::Group,
|
|
||||||
kcl_value::TypeDef,
|
|
||||||
types::{PrimitiveType, CHECK_NUMERIC_TYPES},
|
|
||||||
};
|
|
||||||
use crate::{
|
use crate::{
|
||||||
errors::{KclError, KclErrorDetails},
|
errors::{KclError, KclErrorDetails},
|
||||||
execution::{
|
execution::{
|
||||||
@ -64,14 +60,6 @@ impl ExecutorContext {
|
|||||||
if exec_state.mod_local.settings.update_from_annotation(annotation)? {
|
if exec_state.mod_local.settings.update_from_annotation(annotation)? {
|
||||||
exec_state.mod_local.explicit_length_units = true;
|
exec_state.mod_local.explicit_length_units = true;
|
||||||
}
|
}
|
||||||
let new_units = exec_state.length_unit();
|
|
||||||
self.engine
|
|
||||||
.set_units(
|
|
||||||
new_units.into(),
|
|
||||||
annotation.as_source_range(),
|
|
||||||
exec_state.id_generator(),
|
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
} else {
|
} else {
|
||||||
exec_state.err(CompilationError::err(
|
exec_state.err(CompilationError::err(
|
||||||
annotation.as_source_range(),
|
annotation.as_source_range(),
|
||||||
@ -873,7 +861,10 @@ impl Node<MemberExpression> {
|
|||||||
source_ranges: vec![self.clone().into()],
|
source_ranges: vec![self.clone().into()],
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
(KclValue::MixedArray { value: arr, meta: _ }, Property::UInt(index)) => {
|
(
|
||||||
|
KclValue::MixedArray { value: arr, .. } | KclValue::HomArray { value: arr, .. },
|
||||||
|
Property::UInt(index),
|
||||||
|
) => {
|
||||||
let value_of_arr = arr.get(index);
|
let value_of_arr = arr.get(index);
|
||||||
if let Some(value) = value_of_arr {
|
if let Some(value) = value_of_arr {
|
||||||
Ok(value.to_owned())
|
Ok(value.to_owned())
|
||||||
@ -884,7 +875,7 @@ impl Node<MemberExpression> {
|
|||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(KclValue::MixedArray { .. }, p) => {
|
(KclValue::MixedArray { .. } | KclValue::HomArray { .. }, p) => {
|
||||||
let t = p.type_name();
|
let t = p.type_name();
|
||||||
let article = article_for(t);
|
let article = article_for(t);
|
||||||
Err(KclError::Semantic(KclErrorDetails {
|
Err(KclError::Semantic(KclErrorDetails {
|
||||||
@ -1051,7 +1042,7 @@ impl Node<BinaryExpression> {
|
|||||||
BinaryOperator::Pow => KclValue::Number {
|
BinaryOperator::Pow => KclValue::Number {
|
||||||
value: left.n.powf(right.n),
|
value: left.n.powf(right.n),
|
||||||
meta,
|
meta,
|
||||||
ty: NumericType::Unknown,
|
ty: exec_state.current_default_units(),
|
||||||
},
|
},
|
||||||
BinaryOperator::Neq => {
|
BinaryOperator::Neq => {
|
||||||
let (l, r, ty) = NumericType::combine_eq(left, right);
|
let (l, r, ty) = NumericType::combine_eq(left, right);
|
||||||
@ -1090,7 +1081,7 @@ impl Node<BinaryExpression> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn warn_on_unknown(&self, ty: &NumericType, verb: &str, exec_state: &mut ExecState) {
|
fn warn_on_unknown(&self, ty: &NumericType, verb: &str, exec_state: &mut ExecState) {
|
||||||
if *CHECK_NUMERIC_TYPES && ty == &NumericType::Unknown {
|
if ty == &NumericType::Unknown {
|
||||||
// TODO suggest how to fix this
|
// TODO suggest how to fix this
|
||||||
exec_state.warn(CompilationError::err(
|
exec_state.warn(CompilationError::err(
|
||||||
self.as_source_range(),
|
self.as_source_range(),
|
||||||
@ -1999,11 +1990,39 @@ fn assign_args_to_params(
|
|||||||
for (index, param) in function_expression.params.iter().enumerate() {
|
for (index, param) in function_expression.params.iter().enumerate() {
|
||||||
if let Some(arg) = args.get(index) {
|
if let Some(arg) = args.get(index) {
|
||||||
// Argument was provided.
|
// Argument was provided.
|
||||||
exec_state.mut_stack().add(
|
|
||||||
param.identifier.name.clone(),
|
if let Some(ty) = ¶m.type_ {
|
||||||
arg.value.clone(),
|
let value = arg
|
||||||
(¶m.identifier).into(),
|
.value
|
||||||
)?;
|
.coerce(
|
||||||
|
&RuntimeType::from_parsed(ty.inner.clone(), exec_state, arg.source_range).unwrap(),
|
||||||
|
exec_state,
|
||||||
|
)
|
||||||
|
.map_err(|e| {
|
||||||
|
let mut message = format!(
|
||||||
|
"Argument requires a value with type `{}`, but found {}",
|
||||||
|
ty.inner,
|
||||||
|
arg.value.human_friendly_type(),
|
||||||
|
);
|
||||||
|
if let Some(ty) = e.explicit_coercion {
|
||||||
|
// TODO if we have access to the AST for the argument we could choose which example to suggest.
|
||||||
|
message = format!("{message}\n\nYou may need to add information about the type of the argument, for example:\n using a numeric suffix: `42{ty}`\n or using type ascription: `foo(): number({ty})`");
|
||||||
|
}
|
||||||
|
KclError::Semantic(KclErrorDetails {
|
||||||
|
message,
|
||||||
|
source_ranges: vec![arg.source_range],
|
||||||
|
})
|
||||||
|
})?;
|
||||||
|
exec_state
|
||||||
|
.mut_stack()
|
||||||
|
.add(param.identifier.name.clone(), value, (¶m.identifier).into())?;
|
||||||
|
} else {
|
||||||
|
exec_state.mut_stack().add(
|
||||||
|
param.identifier.name.clone(),
|
||||||
|
arg.value.clone(),
|
||||||
|
(¶m.identifier).into(),
|
||||||
|
)?;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// Argument was not provided.
|
// Argument was not provided.
|
||||||
if let Some(ref default_val) = param.default_value {
|
if let Some(ref default_val) = param.default_value {
|
||||||
|
@ -10,14 +10,13 @@ use serde::{Deserialize, Serialize};
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
errors::KclError,
|
errors::KclError,
|
||||||
execution::{types::NumericType, ArtifactId, ExecState, Metadata, TagEngineInfo, TagIdentifier, UnitLen},
|
execution::{
|
||||||
|
types::NumericType, ArtifactId, ExecState, ExecutorContext, Metadata, TagEngineInfo, TagIdentifier, UnitLen,
|
||||||
|
},
|
||||||
parsing::ast::types::{Node, NodeRef, TagDeclarator, TagNode},
|
parsing::ast::types::{Node, NodeRef, TagDeclarator, TagNode},
|
||||||
std::{args::TyF64, sketch::PlaneData},
|
std::{args::TyF64, sketch::PlaneData},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::ExecutorContext;
|
|
||||||
|
|
||||||
type Point2D = kcmc::shared::Point2d<f64>;
|
|
||||||
type Point3D = kcmc::shared::Point3d<f64>;
|
type Point3D = kcmc::shared::Point3d<f64>;
|
||||||
|
|
||||||
/// A geometry.
|
/// A geometry.
|
||||||
@ -265,7 +264,6 @@ pub struct Plane {
|
|||||||
pub y_axis: Point3d,
|
pub y_axis: Point3d,
|
||||||
/// The z-axis (normal).
|
/// The z-axis (normal).
|
||||||
pub z_axis: Point3d,
|
pub z_axis: Point3d,
|
||||||
pub units: UnitLen,
|
|
||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
pub meta: Vec<Metadata>,
|
pub meta: Vec<Metadata>,
|
||||||
}
|
}
|
||||||
@ -287,6 +285,8 @@ impl Plane {
|
|||||||
x: 1.0,
|
x: 1.0,
|
||||||
y: 0.0,
|
y: 0.0,
|
||||||
z: 0.0,
|
z: 0.0,
|
||||||
|
// TODO axes must be normalized, so maybe these should all be count
|
||||||
|
// rather than mm?
|
||||||
units: UnitLen::Mm,
|
units: UnitLen::Mm,
|
||||||
},
|
},
|
||||||
y_axis:
|
y_axis:
|
||||||
@ -483,7 +483,6 @@ impl Plane {
|
|||||||
y_axis: Point3d::new(0.0, 1.0, 0.0, UnitLen::Mm),
|
y_axis: Point3d::new(0.0, 1.0, 0.0, UnitLen::Mm),
|
||||||
z_axis: Point3d::new(0.0, 0.0, 1.0, UnitLen::Mm),
|
z_axis: Point3d::new(0.0, 0.0, 1.0, UnitLen::Mm),
|
||||||
value: PlaneType::XY,
|
value: PlaneType::XY,
|
||||||
units: exec_state.length_unit(),
|
|
||||||
meta: vec![],
|
meta: vec![],
|
||||||
},
|
},
|
||||||
PlaneData::NegXY => Plane {
|
PlaneData::NegXY => Plane {
|
||||||
@ -494,7 +493,6 @@ impl Plane {
|
|||||||
y_axis: Point3d::new(0.0, 1.0, 0.0, UnitLen::Mm),
|
y_axis: Point3d::new(0.0, 1.0, 0.0, UnitLen::Mm),
|
||||||
z_axis: Point3d::new(0.0, 0.0, -1.0, UnitLen::Mm),
|
z_axis: Point3d::new(0.0, 0.0, -1.0, UnitLen::Mm),
|
||||||
value: PlaneType::XY,
|
value: PlaneType::XY,
|
||||||
units: exec_state.length_unit(),
|
|
||||||
meta: vec![],
|
meta: vec![],
|
||||||
},
|
},
|
||||||
PlaneData::XZ => Plane {
|
PlaneData::XZ => Plane {
|
||||||
@ -505,7 +503,6 @@ impl Plane {
|
|||||||
y_axis: Point3d::new(0.0, 0.0, 1.0, UnitLen::Mm),
|
y_axis: Point3d::new(0.0, 0.0, 1.0, UnitLen::Mm),
|
||||||
z_axis: Point3d::new(0.0, -1.0, 0.0, UnitLen::Mm),
|
z_axis: Point3d::new(0.0, -1.0, 0.0, UnitLen::Mm),
|
||||||
value: PlaneType::XZ,
|
value: PlaneType::XZ,
|
||||||
units: exec_state.length_unit(),
|
|
||||||
meta: vec![],
|
meta: vec![],
|
||||||
},
|
},
|
||||||
PlaneData::NegXZ => Plane {
|
PlaneData::NegXZ => Plane {
|
||||||
@ -516,7 +513,6 @@ impl Plane {
|
|||||||
y_axis: Point3d::new(0.0, 0.0, 1.0, UnitLen::Mm),
|
y_axis: Point3d::new(0.0, 0.0, 1.0, UnitLen::Mm),
|
||||||
z_axis: Point3d::new(0.0, 1.0, 0.0, UnitLen::Mm),
|
z_axis: Point3d::new(0.0, 1.0, 0.0, UnitLen::Mm),
|
||||||
value: PlaneType::XZ,
|
value: PlaneType::XZ,
|
||||||
units: exec_state.length_unit(),
|
|
||||||
meta: vec![],
|
meta: vec![],
|
||||||
},
|
},
|
||||||
PlaneData::YZ => Plane {
|
PlaneData::YZ => Plane {
|
||||||
@ -527,7 +523,6 @@ impl Plane {
|
|||||||
y_axis: Point3d::new(0.0, 0.0, 1.0, UnitLen::Mm),
|
y_axis: Point3d::new(0.0, 0.0, 1.0, UnitLen::Mm),
|
||||||
z_axis: Point3d::new(1.0, 0.0, 0.0, UnitLen::Mm),
|
z_axis: Point3d::new(1.0, 0.0, 0.0, UnitLen::Mm),
|
||||||
value: PlaneType::YZ,
|
value: PlaneType::YZ,
|
||||||
units: exec_state.length_unit(),
|
|
||||||
meta: vec![],
|
meta: vec![],
|
||||||
},
|
},
|
||||||
PlaneData::NegYZ => Plane {
|
PlaneData::NegYZ => Plane {
|
||||||
@ -538,7 +533,6 @@ impl Plane {
|
|||||||
y_axis: Point3d::new(0.0, 0.0, 1.0, UnitLen::Mm),
|
y_axis: Point3d::new(0.0, 0.0, 1.0, UnitLen::Mm),
|
||||||
z_axis: Point3d::new(-1.0, 0.0, 0.0, UnitLen::Mm),
|
z_axis: Point3d::new(-1.0, 0.0, 0.0, UnitLen::Mm),
|
||||||
value: PlaneType::YZ,
|
value: PlaneType::YZ,
|
||||||
units: exec_state.length_unit(),
|
|
||||||
meta: vec![],
|
meta: vec![],
|
||||||
},
|
},
|
||||||
PlaneData::Plane {
|
PlaneData::Plane {
|
||||||
@ -556,7 +550,6 @@ impl Plane {
|
|||||||
y_axis,
|
y_axis,
|
||||||
z_axis,
|
z_axis,
|
||||||
value: PlaneType::Custom,
|
value: PlaneType::Custom,
|
||||||
units: exec_state.length_unit(),
|
|
||||||
meta: vec![],
|
meta: vec![],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -713,12 +706,6 @@ impl SketchSurface {
|
|||||||
SketchSurface::Face(face) => face.z_axis,
|
SketchSurface::Face(face) => face.z_axis,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub(crate) fn units(&self) -> UnitLen {
|
|
||||||
match self {
|
|
||||||
SketchSurface::Plane(plane) => plane.units,
|
|
||||||
SketchSurface::Face(face) => face.units,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
@ -787,7 +774,8 @@ impl Sketch {
|
|||||||
return Ok(Point2d::new(self.start.to[0], self.start.to[1], self.start.units));
|
return Ok(Point2d::new(self.start.to[0], self.start.to[1], self.start.units));
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(path.get_to().into())
|
let to = path.get_base().to;
|
||||||
|
Ok(Point2d::new(to[0], to[1], path.get_base().units))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn get_tangential_info_from_paths(&self) -> GetTangentialInfoFromPathsResult {
|
pub(crate) fn get_tangential_info_from_paths(&self) -> GetTangentialInfoFromPathsResult {
|
||||||
@ -829,6 +817,10 @@ impl Solid {
|
|||||||
pub(crate) fn get_all_edge_cut_ids(&self) -> impl Iterator<Item = uuid::Uuid> + '_ {
|
pub(crate) fn get_all_edge_cut_ids(&self) -> impl Iterator<Item = uuid::Uuid> + '_ {
|
||||||
self.edge_cuts.iter().map(|foc| foc.id())
|
self.edge_cuts.iter().map(|foc| foc.id())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn height_in_mm(&self) -> f64 {
|
||||||
|
self.units.adjust_to(self.height, UnitLen::Mm).0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A fillet or a chamfer.
|
/// A fillet or a chamfer.
|
||||||
@ -889,28 +881,6 @@ pub struct Point2d {
|
|||||||
pub units: UnitLen,
|
pub units: UnitLen,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<[TyF64; 2]> for Point2d {
|
|
||||||
fn from(p: [TyF64; 2]) -> Self {
|
|
||||||
Self {
|
|
||||||
x: p[0].n,
|
|
||||||
y: p[1].n,
|
|
||||||
units: p[0].ty.expect_length(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<Point2d> for [f64; 2] {
|
|
||||||
fn from(p: Point2d) -> Self {
|
|
||||||
[p.x, p.y]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<Point2d> for Point2D {
|
|
||||||
fn from(p: Point2d) -> Self {
|
|
||||||
Self { x: p.x, y: p.y }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Point2d {
|
impl Point2d {
|
||||||
pub const ZERO: Self = Self {
|
pub const ZERO: Self = Self {
|
||||||
x: 0.0,
|
x: 0.0,
|
||||||
@ -921,6 +891,18 @@ impl Point2d {
|
|||||||
pub fn new(x: f64, y: f64, units: UnitLen) -> Self {
|
pub fn new(x: f64, y: f64, units: UnitLen) -> Self {
|
||||||
Self { x, y, units }
|
Self { x, y, units }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn into_x(self) -> TyF64 {
|
||||||
|
TyF64::new(self.x, self.units.into())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn into_y(self) -> TyF64 {
|
||||||
|
TyF64::new(self.y, self.units.into())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn ignore_units(self) -> [f64; 2] {
|
||||||
|
[self.x, self.y]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, Serialize, PartialEq, Clone, Copy, ts_rs::TS, JsonSchema, Default)]
|
#[derive(Debug, Deserialize, Serialize, PartialEq, Clone, Copy, ts_rs::TS, JsonSchema, Default)]
|
||||||
@ -968,9 +950,9 @@ impl From<Point3d> for Point3D {
|
|||||||
impl From<Point3d> for kittycad_modeling_cmds::shared::Point3d<LengthUnit> {
|
impl From<Point3d> for kittycad_modeling_cmds::shared::Point3d<LengthUnit> {
|
||||||
fn from(p: Point3d) -> Self {
|
fn from(p: Point3d) -> Self {
|
||||||
Self {
|
Self {
|
||||||
x: LengthUnit(p.x),
|
x: LengthUnit(p.units.adjust_to(p.x, UnitLen::Mm).0),
|
||||||
y: LengthUnit(p.y),
|
y: LengthUnit(p.units.adjust_to(p.y, UnitLen::Mm).0),
|
||||||
z: LengthUnit(p.z),
|
z: LengthUnit(p.units.adjust_to(p.z, UnitLen::Mm).0),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1318,9 +1300,9 @@ impl Path {
|
|||||||
ccw: *ccw,
|
ccw: *ccw,
|
||||||
},
|
},
|
||||||
Path::ArcThreePoint { p1, p2, p3, .. } => {
|
Path::ArcThreePoint { p1, p2, p3, .. } => {
|
||||||
let circle_center = crate::std::utils::calculate_circle_from_3_points([*p1, *p2, *p3]);
|
let circle = crate::std::utils::calculate_circle_from_3_points([*p1, *p2, *p3]);
|
||||||
GetTangentialInfoFromPathsResult::Arc {
|
GetTangentialInfoFromPathsResult::Arc {
|
||||||
center: circle_center.center,
|
center: circle.center,
|
||||||
ccw: crate::std::utils::is_points_ccw(&[*p1, *p2, *p3]) > 0,
|
ccw: crate::std::utils::is_points_ccw(&[*p1, *p2, *p3]) > 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1332,14 +1314,13 @@ impl Path {
|
|||||||
radius: *radius,
|
radius: *radius,
|
||||||
},
|
},
|
||||||
Path::CircleThreePoint { p1, p2, p3, .. } => {
|
Path::CircleThreePoint { p1, p2, p3, .. } => {
|
||||||
let circle_center = crate::std::utils::calculate_circle_from_3_points([*p1, *p2, *p3]);
|
let circle = crate::std::utils::calculate_circle_from_3_points([*p1, *p2, *p3]);
|
||||||
let radius = linear_distance(&[circle_center.center[0], circle_center.center[1]], p1);
|
let center_point = [circle.center[0], circle.center[1]];
|
||||||
let center_point = [circle_center.center[0], circle_center.center[1]];
|
|
||||||
GetTangentialInfoFromPathsResult::Circle {
|
GetTangentialInfoFromPathsResult::Circle {
|
||||||
center: center_point,
|
center: center_point,
|
||||||
// Note: a circle is always ccw regardless of the order of points
|
// Note: a circle is always ccw regardless of the order of points
|
||||||
ccw: true,
|
ccw: true,
|
||||||
radius,
|
radius: circle.radius,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Path::ToPoint { .. } | Path::Horizontal { .. } | Path::AngledLineTo { .. } | Path::Base { .. } => {
|
Path::ToPoint { .. } | Path::Horizontal { .. } | Path::AngledLineTo { .. } | Path::Base { .. } => {
|
||||||
|
@ -18,16 +18,6 @@ use crate::{
|
|||||||
CompilationError, SourceRange,
|
CompilationError, SourceRange,
|
||||||
};
|
};
|
||||||
|
|
||||||
lazy_static::lazy_static! {
|
|
||||||
pub(crate) static ref CHECK_NUMERIC_TYPES: bool = {
|
|
||||||
let env_var = std::env::var("ZOO_NUM_TYS");
|
|
||||||
let Ok(env_var) = env_var else {
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
!env_var.is_empty()
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub enum RuntimeType {
|
pub enum RuntimeType {
|
||||||
Primitive(PrimitiveType),
|
Primitive(PrimitiveType),
|
||||||
@ -62,6 +52,10 @@ impl RuntimeType {
|
|||||||
RuntimeType::Primitive(PrimitiveType::Solid)
|
RuntimeType::Primitive(PrimitiveType::Solid)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn helix() -> Self {
|
||||||
|
RuntimeType::Primitive(PrimitiveType::Helix)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn plane() -> Self {
|
pub fn plane() -> Self {
|
||||||
RuntimeType::Primitive(PrimitiveType::Plane)
|
RuntimeType::Primitive(PrimitiveType::Plane)
|
||||||
}
|
}
|
||||||
@ -94,6 +88,10 @@ impl RuntimeType {
|
|||||||
))))
|
))))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn known_length(len: UnitLen) -> Self {
|
||||||
|
RuntimeType::Primitive(PrimitiveType::Number(NumericType::Known(UnitType::Length(len))))
|
||||||
|
}
|
||||||
|
|
||||||
pub fn angle() -> Self {
|
pub fn angle() -> Self {
|
||||||
RuntimeType::Primitive(PrimitiveType::Number(NumericType::Known(UnitType::Angle(
|
RuntimeType::Primitive(PrimitiveType::Number(NumericType::Known(UnitType::Angle(
|
||||||
UnitAngle::Unknown,
|
UnitAngle::Unknown,
|
||||||
@ -370,6 +368,7 @@ impl fmt::Display for PrimitiveType {
|
|||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
PrimitiveType::Number(NumericType::Known(unit)) => write!(f, "number({unit})"),
|
PrimitiveType::Number(NumericType::Known(unit)) => write!(f, "number({unit})"),
|
||||||
|
PrimitiveType::Number(NumericType::Unknown) => write!(f, "number(unknown units)"),
|
||||||
PrimitiveType::Number(_) => write!(f, "number"),
|
PrimitiveType::Number(_) => write!(f, "number"),
|
||||||
PrimitiveType::String => write!(f, "string"),
|
PrimitiveType::String => write!(f, "string"),
|
||||||
PrimitiveType::Boolean => write!(f, "bool"),
|
PrimitiveType::Boolean => write!(f, "bool"),
|
||||||
@ -427,13 +426,61 @@ impl NumericType {
|
|||||||
NumericType::Known(UnitType::Angle(UnitAngle::Degrees))
|
NumericType::Known(UnitType::Angle(UnitAngle::Degrees))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Combine two types when we expect them to be equal.
|
pub fn expect_default_length(&self) -> Self {
|
||||||
|
match self {
|
||||||
|
NumericType::Default { len, .. } => NumericType::Known(UnitType::Length(*len)),
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn expect_default_angle(&self) -> Self {
|
||||||
|
match self {
|
||||||
|
NumericType::Default { angle, .. } => NumericType::Known(UnitType::Angle(*angle)),
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Combine two types when we expect them to be equal, erring on the side of less coercion. To be
|
||||||
|
/// precise, only adjusting one number or the other when they are of known types.
|
||||||
|
///
|
||||||
|
/// This combinator function is suitable for comparisons or arithmetic where uncertainty should
|
||||||
|
/// be handled by the user.
|
||||||
pub fn combine_eq(a: TyF64, b: TyF64) -> (f64, f64, NumericType) {
|
pub fn combine_eq(a: TyF64, b: TyF64) -> (f64, f64, NumericType) {
|
||||||
use NumericType::*;
|
use NumericType::*;
|
||||||
match (a.ty, b.ty) {
|
match (a.ty, b.ty) {
|
||||||
(at, bt) if at == bt => (a.n, b.n, at),
|
(at, bt) if at == bt => (a.n, b.n, at),
|
||||||
(at, Any) => (a.n, b.n, at),
|
(at, Any) => (a.n, b.n, at),
|
||||||
(Any, bt) => (a.n, b.n, bt),
|
(Any, bt) => (a.n, b.n, bt),
|
||||||
|
|
||||||
|
(t @ Known(UnitType::Length(l1)), Known(UnitType::Length(l2))) => (a.n, l2.adjust_to(b.n, l1).0, t),
|
||||||
|
(t @ Known(UnitType::Angle(a1)), Known(UnitType::Angle(a2))) => (a.n, a2.adjust_to(b.n, a1).0, t),
|
||||||
|
|
||||||
|
(Known(UnitType::Count), Default { .. }) | (Default { .. }, Known(UnitType::Count)) => {
|
||||||
|
(a.n, b.n, Known(UnitType::Count))
|
||||||
|
}
|
||||||
|
(t @ Known(UnitType::Length(l1)), Default { len: l2, .. }) if l1 == l2 => (a.n, b.n, t),
|
||||||
|
(Default { len: l1, .. }, t @ Known(UnitType::Length(l2))) if l1 == l2 => (a.n, b.n, t),
|
||||||
|
(t @ Known(UnitType::Angle(a1)), Default { angle: a2, .. }) if a1 == a2 => (a.n, b.n, t),
|
||||||
|
(Default { angle: a1, .. }, t @ Known(UnitType::Angle(a2))) if a1 == a2 => (a.n, b.n, t),
|
||||||
|
|
||||||
|
_ => (a.n, b.n, Unknown),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Combine two types when we expect them to be equal, erring on the side of more coercion. Including adjusting when
|
||||||
|
/// we are certain about only one type.
|
||||||
|
///
|
||||||
|
/// This combinator function is suitable for situations where the user would almost certainly want the types to be
|
||||||
|
/// coerced together, for example two arguments to the same function or two numbers in an array being used as a point.
|
||||||
|
///
|
||||||
|
/// Prefer to use `combine_eq` if possible since using that prioritises correctness over ergonomics.
|
||||||
|
pub fn combine_eq_coerce(a: TyF64, b: TyF64) -> (f64, f64, NumericType) {
|
||||||
|
use NumericType::*;
|
||||||
|
match (a.ty, b.ty) {
|
||||||
|
(at, bt) if at == bt => (a.n, b.n, at),
|
||||||
|
(at, Any) => (a.n, b.n, at),
|
||||||
|
(Any, bt) => (a.n, b.n, bt),
|
||||||
|
|
||||||
(Default { .. }, Default { .. }) | (_, Unknown) | (Unknown, _) => (a.n, b.n, Unknown),
|
(Default { .. }, Default { .. }) | (_, Unknown) | (Unknown, _) => (a.n, b.n, Unknown),
|
||||||
|
|
||||||
// Known types and compatible, but needs adjustment.
|
// Known types and compatible, but needs adjustment.
|
||||||
@ -458,12 +505,9 @@ impl NumericType {
|
|||||||
|
|
||||||
pub fn combine_eq_array(input: &[TyF64]) -> (Vec<f64>, NumericType) {
|
pub fn combine_eq_array(input: &[TyF64]) -> (Vec<f64>, NumericType) {
|
||||||
use NumericType::*;
|
use NumericType::*;
|
||||||
|
let result = input.iter().map(|t| t.n).collect();
|
||||||
let mut result = input.iter().map(|t| t.n).collect();
|
|
||||||
|
|
||||||
let mut ty = Any;
|
let mut ty = Any;
|
||||||
// Invariant mismatch is true => ty is fully known
|
|
||||||
let mut mismatch = false;
|
|
||||||
for i in input {
|
for i in input {
|
||||||
if i.ty == Any || ty == i.ty {
|
if i.ty == Any || ty == i.ty {
|
||||||
continue;
|
continue;
|
||||||
@ -475,58 +519,24 @@ impl NumericType {
|
|||||||
}
|
}
|
||||||
(_, Unknown) | (Default { .. }, Default { .. }) => return (result, Unknown),
|
(_, Unknown) | (Default { .. }, Default { .. }) => return (result, Unknown),
|
||||||
|
|
||||||
// Known types and compatible, but needs adjustment.
|
|
||||||
(Known(UnitType::Length(_)), Known(UnitType::Length(_)))
|
|
||||||
| (Known(UnitType::Angle(_)), Known(UnitType::Angle(_))) => {
|
|
||||||
mismatch = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Known but incompatible.
|
|
||||||
(Known(_), Known(_)) => return (result, Unknown),
|
|
||||||
|
|
||||||
// Known and unknown, no adjustment for counting numbers.
|
|
||||||
(Known(UnitType::Count), Default { .. }) | (Default { .. }, Known(UnitType::Count)) => {
|
(Known(UnitType::Count), Default { .. }) | (Default { .. }, Known(UnitType::Count)) => {
|
||||||
ty = Known(UnitType::Count);
|
ty = Known(UnitType::Count);
|
||||||
}
|
}
|
||||||
|
|
||||||
(Known(UnitType::Length(l1)), Default { len: l2, .. }) => {
|
(Known(UnitType::Length(l1)), Default { len: l2, .. }) if l1 == l2 => {}
|
||||||
mismatch |= l1 != l2;
|
(Known(UnitType::Angle(a1)), Default { angle: a2, .. }) if a1 == a2 => {}
|
||||||
}
|
|
||||||
(Known(UnitType::Angle(a1)), Default { angle: a2, .. }) => {
|
|
||||||
mismatch |= a1 != a2;
|
|
||||||
}
|
|
||||||
|
|
||||||
(Default { len: l1, .. }, Known(UnitType::Length(l2))) => {
|
(Default { len: l1, .. }, Known(UnitType::Length(l2))) if l1 == l2 => {
|
||||||
mismatch |= l1 != l2;
|
|
||||||
ty = Known(UnitType::Length(*l2));
|
ty = Known(UnitType::Length(*l2));
|
||||||
}
|
}
|
||||||
(Default { angle: a1, .. }, Known(UnitType::Angle(a2))) => {
|
(Default { angle: a1, .. }, Known(UnitType::Angle(a2))) if a1 == a2 => {
|
||||||
mismatch |= a1 != a2;
|
|
||||||
ty = Known(UnitType::Angle(*a2));
|
ty = Known(UnitType::Angle(*a2));
|
||||||
}
|
}
|
||||||
|
|
||||||
(Unknown, _) | (_, Any) => unreachable!(),
|
_ => return (result, Unknown),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !mismatch {
|
|
||||||
return (result, ty);
|
|
||||||
}
|
|
||||||
|
|
||||||
result = result
|
|
||||||
.into_iter()
|
|
||||||
.zip(input)
|
|
||||||
.map(|(n, i)| match (&ty, &i.ty) {
|
|
||||||
(Known(UnitType::Length(l1)), Known(UnitType::Length(l2)) | Default { len: l2, .. }) => {
|
|
||||||
l2.adjust_to(n, *l1).0
|
|
||||||
}
|
|
||||||
(Known(UnitType::Angle(a1)), Known(UnitType::Angle(a2)) | Default { angle: a2, .. }) => {
|
|
||||||
a2.adjust_to(n, *a1).0
|
|
||||||
}
|
|
||||||
_ => unreachable!(),
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
(result, ty)
|
(result, ty)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -534,11 +544,11 @@ impl NumericType {
|
|||||||
pub fn combine_mul(a: TyF64, b: TyF64) -> (f64, f64, NumericType) {
|
pub fn combine_mul(a: TyF64, b: TyF64) -> (f64, f64, NumericType) {
|
||||||
use NumericType::*;
|
use NumericType::*;
|
||||||
match (a.ty, b.ty) {
|
match (a.ty, b.ty) {
|
||||||
(at @ Default { .. }, bt @ Default { .. }) if at != bt => (a.n, b.n, Unknown),
|
(at @ Default { .. }, bt @ Default { .. }) if at == bt => (a.n, b.n, at),
|
||||||
|
(Default { .. }, Default { .. }) => (a.n, b.n, Unknown),
|
||||||
(Known(UnitType::Count), bt) => (a.n, b.n, bt),
|
(Known(UnitType::Count), bt) => (a.n, b.n, bt),
|
||||||
(at, Known(UnitType::Count)) => (a.n, b.n, at),
|
(at, Known(UnitType::Count)) => (a.n, b.n, at),
|
||||||
(Default { .. }, bt) => (a.n, b.n, bt),
|
(at @ Known(_), Default { .. }) | (Default { .. }, at @ Known(_)) => (a.n, b.n, at),
|
||||||
(at, Default { .. }) => (a.n, b.n, at),
|
|
||||||
(Any, Any) => (a.n, b.n, Any),
|
(Any, Any) => (a.n, b.n, Any),
|
||||||
_ => (a.n, b.n, Unknown),
|
_ => (a.n, b.n, Unknown),
|
||||||
}
|
}
|
||||||
@ -552,18 +562,7 @@ impl NumericType {
|
|||||||
(at, bt) if at == bt => (a.n, b.n, Known(UnitType::Count)),
|
(at, bt) if at == bt => (a.n, b.n, Known(UnitType::Count)),
|
||||||
(Default { .. }, Default { .. }) => (a.n, b.n, Unknown),
|
(Default { .. }, Default { .. }) => (a.n, b.n, Unknown),
|
||||||
(at, Known(UnitType::Count) | Any) => (a.n, b.n, at),
|
(at, Known(UnitType::Count) | Any) => (a.n, b.n, at),
|
||||||
(Known(UnitType::Length(l1)), Known(UnitType::Length(l2))) => {
|
(at @ Known(_), Default { .. }) => (a.n, b.n, at),
|
||||||
(a.n, l2.adjust_to(b.n, l1).0, Known(UnitType::Count))
|
|
||||||
}
|
|
||||||
(Known(UnitType::Angle(a1)), Known(UnitType::Angle(a2))) => {
|
|
||||||
(a.n, a2.adjust_to(b.n, a1).0, Known(UnitType::Count))
|
|
||||||
}
|
|
||||||
(Default { len: l1, .. }, Known(UnitType::Length(l2))) => {
|
|
||||||
(l1.adjust_to(a.n, l2).0, b.n, Known(UnitType::Count))
|
|
||||||
}
|
|
||||||
(Default { angle: a1, .. }, Known(UnitType::Angle(a2))) => {
|
|
||||||
(a1.adjust_to(a.n, a2).0, b.n, Known(UnitType::Count))
|
|
||||||
}
|
|
||||||
(Known(UnitType::Count), _) => (a.n, b.n, Known(UnitType::Count)),
|
(Known(UnitType::Count), _) => (a.n, b.n, Known(UnitType::Count)),
|
||||||
_ => (a.n, b.n, Unknown),
|
_ => (a.n, b.n, Unknown),
|
||||||
}
|
}
|
||||||
@ -608,9 +607,18 @@ impl NumericType {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_unknown(&self) -> bool {
|
||||||
|
matches!(
|
||||||
|
self,
|
||||||
|
NumericType::Unknown
|
||||||
|
| NumericType::Known(UnitType::Angle(UnitAngle::Unknown))
|
||||||
|
| NumericType::Known(UnitType::Length(UnitLen::Unknown))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
fn example_ty(&self) -> Option<String> {
|
fn example_ty(&self) -> Option<String> {
|
||||||
match self {
|
match self {
|
||||||
Self::Known(t) => Some(t.to_string()),
|
Self::Known(t) if !self.is_unknown() => Some(t.to_string()),
|
||||||
Self::Default { len, .. } => Some(len.to_string()),
|
Self::Default { len, .. } => Some(len.to_string()),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
@ -621,10 +629,6 @@ impl NumericType {
|
|||||||
return Err(val.into());
|
return Err(val.into());
|
||||||
};
|
};
|
||||||
|
|
||||||
if !*CHECK_NUMERIC_TYPES {
|
|
||||||
return Ok(val.clone());
|
|
||||||
}
|
|
||||||
|
|
||||||
if ty.subtype(self) {
|
if ty.subtype(self) {
|
||||||
return Ok(KclValue::Number {
|
return Ok(KclValue::Number {
|
||||||
value: *value,
|
value: *value,
|
||||||
@ -775,10 +779,10 @@ pub enum UnitLen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl UnitLen {
|
impl UnitLen {
|
||||||
fn adjust_to(self, value: f64, to: UnitLen) -> (f64, UnitLen) {
|
pub fn adjust_to(self, value: f64, to: UnitLen) -> (f64, UnitLen) {
|
||||||
use UnitLen::*;
|
use UnitLen::*;
|
||||||
|
|
||||||
if !*CHECK_NUMERIC_TYPES || self == to {
|
if self == to {
|
||||||
return (value, to);
|
return (value, to);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -898,15 +902,11 @@ pub enum UnitAngle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl UnitAngle {
|
impl UnitAngle {
|
||||||
fn adjust_to(self, value: f64, to: UnitAngle) -> (f64, UnitAngle) {
|
pub fn adjust_to(self, value: f64, to: UnitAngle) -> (f64, UnitAngle) {
|
||||||
use std::f64::consts::PI;
|
use std::f64::consts::PI;
|
||||||
|
|
||||||
use UnitAngle::*;
|
use UnitAngle::*;
|
||||||
|
|
||||||
if !*CHECK_NUMERIC_TYPES {
|
|
||||||
return (value, to);
|
|
||||||
}
|
|
||||||
|
|
||||||
if to == Unknown {
|
if to == Unknown {
|
||||||
return (value, self);
|
return (value, self);
|
||||||
}
|
}
|
||||||
@ -1057,8 +1057,6 @@ impl KclValue {
|
|||||||
y_axis,
|
y_axis,
|
||||||
z_axis,
|
z_axis,
|
||||||
value: super::PlaneType::Uninit,
|
value: super::PlaneType::Uninit,
|
||||||
// TODO use length unit from origin
|
|
||||||
units: exec_state.length_unit(),
|
|
||||||
meta: meta.clone(),
|
meta: meta.clone(),
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1952,10 +1950,6 @@ mod test {
|
|||||||
assert_coerce_results(&unknown, &NumericType::Any.into(), &unknown, &mut exec_state);
|
assert_coerce_results(&unknown, &NumericType::Any.into(), &unknown, &mut exec_state);
|
||||||
assert_coerce_results(&default, &NumericType::Any.into(), &default, &mut exec_state);
|
assert_coerce_results(&default, &NumericType::Any.into(), &default, &mut exec_state);
|
||||||
|
|
||||||
if !*CHECK_NUMERIC_TYPES {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
default
|
default
|
||||||
.coerce(
|
.coerce(
|
||||||
@ -2068,20 +2062,14 @@ u = min(3rad, 4in)
|
|||||||
"#;
|
"#;
|
||||||
|
|
||||||
let result = parse_execute(program).await.unwrap();
|
let result = parse_execute(program).await.unwrap();
|
||||||
if *CHECK_NUMERIC_TYPES {
|
assert_eq!(result.exec_state.errors().len(), 5);
|
||||||
assert_eq!(result.exec_state.errors().len(), 3);
|
|
||||||
} else {
|
|
||||||
assert!(result.exec_state.errors().is_empty());
|
|
||||||
}
|
|
||||||
|
|
||||||
assert_value_and_type("a", &result, 9.0, NumericType::default());
|
assert_value_and_type("a", &result, 9.0, NumericType::default());
|
||||||
assert_value_and_type("b", &result, 3.0, NumericType::default());
|
assert_value_and_type("b", &result, 3.0, NumericType::default());
|
||||||
assert_value_and_type("c", &result, 13.0, NumericType::mm());
|
assert_value_and_type("c", &result, 13.0, NumericType::mm());
|
||||||
assert_value_and_type("d", &result, 13.0, NumericType::mm());
|
assert_value_and_type("d", &result, 13.0, NumericType::mm());
|
||||||
assert_value_and_type("e", &result, 13.0, NumericType::mm());
|
assert_value_and_type("e", &result, 13.0, NumericType::mm());
|
||||||
if *CHECK_NUMERIC_TYPES {
|
assert_value_and_type("f", &result, 5.0, NumericType::mm());
|
||||||
assert_value_and_type("f", &result, 5.0, NumericType::mm());
|
|
||||||
}
|
|
||||||
|
|
||||||
assert_value_and_type("g", &result, 20.0, NumericType::default());
|
assert_value_and_type("g", &result, 20.0, NumericType::default());
|
||||||
assert_value_and_type("h", &result, 20.0, NumericType::mm());
|
assert_value_and_type("h", &result, 20.0, NumericType::mm());
|
||||||
@ -2091,16 +2079,14 @@ u = min(3rad, 4in)
|
|||||||
|
|
||||||
assert_value_and_type("l", &result, 0.0, NumericType::default());
|
assert_value_and_type("l", &result, 0.0, NumericType::default());
|
||||||
assert_value_and_type("m", &result, 2.0, NumericType::count());
|
assert_value_and_type("m", &result, 2.0, NumericType::count());
|
||||||
if *CHECK_NUMERIC_TYPES {
|
assert_value_and_type("n", &result, 5.0, NumericType::Unknown);
|
||||||
assert_value_and_type("n", &result, 127.0, NumericType::count());
|
assert_value_and_type("o", &result, 1.0, NumericType::mm());
|
||||||
}
|
|
||||||
assert_value_and_type("o", &result, 1.0, NumericType::Unknown);
|
|
||||||
assert_value_and_type("p", &result, 1.0, NumericType::count());
|
assert_value_and_type("p", &result, 1.0, NumericType::count());
|
||||||
assert_value_and_type("q", &result, 2.0, NumericType::Known(UnitType::Length(UnitLen::Inches)));
|
assert_value_and_type("q", &result, 2.0, NumericType::Known(UnitType::Length(UnitLen::Inches)));
|
||||||
|
|
||||||
assert_value_and_type("r", &result, 0.0, NumericType::default());
|
assert_value_and_type("r", &result, 0.0, NumericType::default());
|
||||||
assert_value_and_type("s", &result, -42.0, NumericType::mm());
|
assert_value_and_type("s", &result, -42.0, NumericType::mm());
|
||||||
assert_value_and_type("t", &result, 3.0, NumericType::Known(UnitType::Length(UnitLen::Inches)));
|
assert_value_and_type("t", &result, 3.0, NumericType::Unknown);
|
||||||
assert_value_and_type("u", &result, 3.0, NumericType::Unknown);
|
assert_value_and_type("u", &result, 3.0, NumericType::Unknown);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2114,7 +2100,24 @@ b = 180 / PI * a + 360
|
|||||||
let result = parse_execute(program).await.unwrap();
|
let result = parse_execute(program).await.unwrap();
|
||||||
|
|
||||||
assert_value_and_type("a", &result, 1.0, NumericType::radians());
|
assert_value_and_type("a", &result, 1.0, NumericType::radians());
|
||||||
// TODO type is not ideal
|
assert_value_and_type("b", &result, 417.0, NumericType::Unknown);
|
||||||
assert_value_and_type("b", &result, 417.0, NumericType::radians());
|
}
|
||||||
|
|
||||||
|
#[tokio::test(flavor = "multi_thread")]
|
||||||
|
async fn cos_coercions() {
|
||||||
|
let program = r#"
|
||||||
|
a = cos(toRadians(30))
|
||||||
|
b = 3 / a
|
||||||
|
c = cos(30deg)
|
||||||
|
d = cos(30)
|
||||||
|
"#;
|
||||||
|
|
||||||
|
let result = parse_execute(program).await.unwrap();
|
||||||
|
assert_eq!(result.exec_state.errors().len(), 1);
|
||||||
|
|
||||||
|
assert_value_and_type("a", &result, 1.0, NumericType::count());
|
||||||
|
assert_value_and_type("b", &result, 3.0, NumericType::default());
|
||||||
|
assert_value_and_type("c", &result, 1.0, NumericType::count());
|
||||||
|
assert_value_and_type("d", &result, 0.0, NumericType::count());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use sha2::{Digest as DigestTrait, Sha256};
|
use sha2::{Digest as DigestTrait, Sha256};
|
||||||
|
|
||||||
use crate::parsing::ast::types::{
|
use crate::parsing::ast::types::{
|
||||||
Annotation, ArrayExpression, ArrayRangeExpression, Ascription, BinaryExpression, BinaryPart, BodyItem,
|
Annotation, ArrayExpression, ArrayRangeExpression, AscribedExpression, BinaryExpression, BinaryPart, BodyItem,
|
||||||
CallExpression, CallExpressionKw, DefaultParamVal, ElseIf, Expr, ExpressionStatement, FunctionExpression,
|
CallExpression, CallExpressionKw, DefaultParamVal, ElseIf, Expr, ExpressionStatement, FunctionExpression,
|
||||||
Identifier, IfExpression, ImportItem, ImportSelector, ImportStatement, ItemVisibility, KclNone, LabelledExpression,
|
Identifier, IfExpression, ImportItem, ImportSelector, ImportStatement, ItemVisibility, KclNone, LabelledExpression,
|
||||||
Literal, LiteralIdentifier, LiteralValue, MemberExpression, MemberObject, Name, ObjectExpression, ObjectProperty,
|
Literal, LiteralIdentifier, LiteralValue, MemberExpression, MemberObject, Name, ObjectExpression, ObjectProperty,
|
||||||
@ -464,7 +464,7 @@ impl LabelledExpression {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Ascription {
|
impl AscribedExpression {
|
||||||
compute_digest!(|slf, hasher| {
|
compute_digest!(|slf, hasher| {
|
||||||
hasher.update(slf.expr.compute_digest());
|
hasher.update(slf.expr.compute_digest());
|
||||||
hasher.update(slf.ty.compute_digest());
|
hasher.update(slf.ty.compute_digest());
|
||||||
|
@ -819,7 +819,7 @@ pub enum Expr {
|
|||||||
UnaryExpression(BoxNode<UnaryExpression>),
|
UnaryExpression(BoxNode<UnaryExpression>),
|
||||||
IfExpression(BoxNode<IfExpression>),
|
IfExpression(BoxNode<IfExpression>),
|
||||||
LabelledExpression(BoxNode<LabelledExpression>),
|
LabelledExpression(BoxNode<LabelledExpression>),
|
||||||
AscribedExpression(BoxNode<Ascription>),
|
AscribedExpression(BoxNode<AscribedExpression>),
|
||||||
None(Node<KclNone>),
|
None(Node<KclNone>),
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1092,7 +1092,7 @@ impl LabelledExpression {
|
|||||||
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
|
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
|
||||||
#[ts(export)]
|
#[ts(export)]
|
||||||
#[serde(tag = "type")]
|
#[serde(tag = "type")]
|
||||||
pub struct Ascription {
|
pub struct AscribedExpression {
|
||||||
pub expr: Expr,
|
pub expr: Expr,
|
||||||
pub ty: Node<Type>,
|
pub ty: Node<Type>,
|
||||||
|
|
||||||
@ -1101,12 +1101,12 @@ pub struct Ascription {
|
|||||||
pub digest: Option<Digest>,
|
pub digest: Option<Digest>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Ascription {
|
impl AscribedExpression {
|
||||||
pub(crate) fn new(expr: Expr, ty: Node<Type>) -> Node<Ascription> {
|
pub(crate) fn new(expr: Expr, ty: Node<Type>) -> Node<AscribedExpression> {
|
||||||
let start = expr.start();
|
let start = expr.start();
|
||||||
let end = ty.end;
|
let end = ty.end;
|
||||||
let module_id = expr.module_id();
|
let module_id = expr.module_id();
|
||||||
Node::new(Ascription { expr, ty, digest: None }, start, end, module_id)
|
Node::new(AscribedExpression { expr, ty, digest: None }, start, end, module_id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3080,7 +3080,7 @@ impl PipeExpression {
|
|||||||
#[allow(clippy::large_enum_variant)]
|
#[allow(clippy::large_enum_variant)]
|
||||||
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
|
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
|
||||||
#[ts(export)]
|
#[ts(export)]
|
||||||
#[serde(tag = "type")]
|
#[serde(tag = "p_type")]
|
||||||
pub enum PrimitiveType {
|
pub enum PrimitiveType {
|
||||||
/// A string type.
|
/// A string type.
|
||||||
String,
|
String,
|
||||||
|
@ -14,7 +14,7 @@ use winnow::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
ast::types::{Ascription, ImportPath, LabelledExpression},
|
ast::types::{AscribedExpression, ImportPath, LabelledExpression},
|
||||||
token::{NumericSuffix, RESERVED_WORDS},
|
token::{NumericSuffix, RESERVED_WORDS},
|
||||||
DeprecationKind,
|
DeprecationKind,
|
||||||
};
|
};
|
||||||
@ -530,13 +530,6 @@ pub(crate) fn unsigned_number_literal(i: &mut TokenSlice) -> PResult<Node<Litera
|
|||||||
CompilationError::fatal(token.as_source_range(), format!("Invalid float: {}", token.value))
|
CompilationError::fatal(token.as_source_range(), format!("Invalid float: {}", token.value))
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
if token.numeric_suffix().is_some() {
|
|
||||||
ParseContext::warn(CompilationError::err(
|
|
||||||
(&token).into(),
|
|
||||||
"Unit of Measure suffixes are experimental and currently do nothing.",
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok((
|
Ok((
|
||||||
LiteralValue::Number {
|
LiteralValue::Number {
|
||||||
value,
|
value,
|
||||||
@ -2015,9 +2008,7 @@ fn expression_but_not_pipe(i: &mut TokenSlice) -> PResult<Expr> {
|
|||||||
|
|
||||||
let ty = opt((colon, opt(whitespace), argument_type)).parse_next(i)?;
|
let ty = opt((colon, opt(whitespace), argument_type)).parse_next(i)?;
|
||||||
if let Some((_, _, ty)) = ty {
|
if let Some((_, _, ty)) = ty {
|
||||||
ParseContext::warn(CompilationError::err((&ty).into(), "Type ascription is experimental."));
|
expr = Expr::AscribedExpression(Box::new(AscribedExpression::new(expr, ty)))
|
||||||
|
|
||||||
expr = Expr::AscribedExpression(Box::new(Ascription::new(expr, ty)))
|
|
||||||
}
|
}
|
||||||
let label = opt(label).parse_next(i)?;
|
let label = opt(label).parse_next(i)?;
|
||||||
match label {
|
match label {
|
||||||
@ -2811,13 +2802,6 @@ fn primitive_type(i: &mut TokenSlice) -> PResult<Node<PrimitiveType>> {
|
|||||||
let mut result = Node::new(PrimitiveType::Boolean, ident.start, ident.end, ident.module_id);
|
let mut result = Node::new(PrimitiveType::Boolean, ident.start, ident.end, ident.module_id);
|
||||||
result.inner = PrimitiveType::primitive_from_str(&ident.name, suffix).unwrap_or(PrimitiveType::Named(ident));
|
result.inner = PrimitiveType::primitive_from_str(&ident.name, suffix).unwrap_or(PrimitiveType::Named(ident));
|
||||||
|
|
||||||
if suffix.is_some() {
|
|
||||||
ParseContext::warn(CompilationError::err(
|
|
||||||
result.as_source_range(),
|
|
||||||
"Unit of Measure types are experimental and currently do nothing.",
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(result)
|
Ok(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4532,19 +4516,19 @@ export fn cos(num: number(rad)): number(_) {}"#;
|
|||||||
fn fn_decl_uom_ty() {
|
fn fn_decl_uom_ty() {
|
||||||
let some_program_string = r#"fn foo(x: number(mm)): number(_) { return 1 }"#;
|
let some_program_string = r#"fn foo(x: number(mm)): number(_) { return 1 }"#;
|
||||||
let (_, errs) = assert_no_fatal(some_program_string);
|
let (_, errs) = assert_no_fatal(some_program_string);
|
||||||
assert_eq!(errs.len(), 2);
|
assert!(errs.is_empty(), "Expected no errors, found: {errs:?}");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn error_underscore() {
|
fn error_underscore() {
|
||||||
let (_, errs) = assert_no_fatal("_foo(_blah, _)");
|
let (_, errs) = assert_no_fatal("_foo(_blah, _)");
|
||||||
assert_eq!(errs.len(), 3, "found: {:#?}", errs);
|
assert_eq!(errs.len(), 3, "found: {errs:#?}");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn error_type_ascription() {
|
fn error_type_ascription() {
|
||||||
let (_, errs) = assert_no_fatal("a + b: number");
|
let (_, errs) = assert_no_fatal("a + b: number");
|
||||||
assert_eq!(errs.len(), 1, "found: {:#?}", errs);
|
assert!(errs.is_empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -11,10 +11,7 @@ use serde::Serialize;
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
errors::{KclError, KclErrorDetails},
|
errors::{KclError, KclErrorDetails},
|
||||||
execution::{
|
execution::{types::RuntimeType, ExecState, KclValue, SolidOrImportedGeometry},
|
||||||
types::{NumericType, PrimitiveType, RuntimeType},
|
|
||||||
ExecState, KclValue, SolidOrImportedGeometry,
|
|
||||||
},
|
|
||||||
std::Args,
|
std::Args,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -50,9 +47,8 @@ pub async fn appearance(exec_state: &mut ExecState, args: Args) -> Result<KclVal
|
|||||||
)?;
|
)?;
|
||||||
|
|
||||||
let color: String = args.get_kw_arg("color")?;
|
let color: String = args.get_kw_arg("color")?;
|
||||||
let count_ty = RuntimeType::Primitive(PrimitiveType::Number(NumericType::count()));
|
let metalness: Option<TyF64> = args.get_kw_arg_opt_typed("metalness", &RuntimeType::count(), exec_state)?;
|
||||||
let metalness: Option<TyF64> = args.get_kw_arg_opt_typed("metalness", &count_ty, exec_state)?;
|
let roughness: Option<TyF64> = args.get_kw_arg_opt_typed("roughness", &RuntimeType::count(), exec_state)?;
|
||||||
let roughness: Option<TyF64> = args.get_kw_arg_opt_typed("roughness", &count_ty, exec_state)?;
|
|
||||||
let data = AppearanceData {
|
let data = AppearanceData {
|
||||||
color,
|
color,
|
||||||
metalness,
|
metalness,
|
||||||
|
@ -14,7 +14,7 @@ use crate::{
|
|||||||
errors::{KclError, KclErrorDetails},
|
errors::{KclError, KclErrorDetails},
|
||||||
execution::{
|
execution::{
|
||||||
kcl_value::FunctionSource,
|
kcl_value::FunctionSource,
|
||||||
types::{NumericType, PrimitiveType, RuntimeType, UnitLen},
|
types::{NumericType, PrimitiveType, RuntimeType, UnitAngle, UnitLen, UnitType},
|
||||||
ExecState, ExecutorContext, ExtrudeSurface, Helix, KclObjectFields, KclValue, Metadata, Sketch, SketchSurface,
|
ExecState, ExecutorContext, ExtrudeSurface, Helix, KclObjectFields, KclValue, Metadata, Sketch, SketchSurface,
|
||||||
Solid, TagIdentifier,
|
Solid, TagIdentifier,
|
||||||
},
|
},
|
||||||
@ -88,6 +88,34 @@ impl TyF64 {
|
|||||||
Self { n, ty }
|
Self { n, ty }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn to_mm(&self) -> f64 {
|
||||||
|
self.to_length_units(UnitLen::Mm)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn to_length_units(&self, units: UnitLen) -> f64 {
|
||||||
|
let len = match &self.ty {
|
||||||
|
NumericType::Default { len, .. } => *len,
|
||||||
|
NumericType::Known(UnitType::Length(len)) => *len,
|
||||||
|
t => unreachable!("expected length, found {t:?}"),
|
||||||
|
};
|
||||||
|
|
||||||
|
assert_ne!(len, UnitLen::Unknown);
|
||||||
|
|
||||||
|
len.adjust_to(self.n, units).0
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn to_degrees(&self) -> f64 {
|
||||||
|
let angle = match self.ty {
|
||||||
|
NumericType::Default { angle, .. } => angle,
|
||||||
|
NumericType::Known(UnitType::Angle(angle)) => angle,
|
||||||
|
_ => unreachable!(),
|
||||||
|
};
|
||||||
|
|
||||||
|
assert_ne!(angle, UnitAngle::Unknown);
|
||||||
|
|
||||||
|
angle.adjust_to(self.n, UnitAngle::Degrees).0
|
||||||
|
}
|
||||||
|
|
||||||
pub fn count(n: f64) -> Self {
|
pub fn count(n: f64) -> Self {
|
||||||
Self {
|
Self {
|
||||||
n,
|
n,
|
||||||
@ -547,6 +575,29 @@ impl Args {
|
|||||||
FromArgs::from_args(self, 0)
|
FromArgs::from_args(self, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn get_number_typed(&self, ty: &RuntimeType, exec_state: &mut ExecState) -> Result<f64, KclError> {
|
||||||
|
let Some(arg) = self.args.first() else {
|
||||||
|
return Err(KclError::Semantic(KclErrorDetails {
|
||||||
|
message: "Expected an argument".to_owned(),
|
||||||
|
source_ranges: vec![self.source_range],
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
|
arg.value.coerce(ty, exec_state).map_err(|_| {
|
||||||
|
let actual_type_name = arg.value.human_friendly_type();
|
||||||
|
let message = format!(
|
||||||
|
"This function expected the input argument to be {} but it's actually of type {actual_type_name}",
|
||||||
|
ty.human_friendly_type(),
|
||||||
|
);
|
||||||
|
KclError::Semantic(KclErrorDetails {
|
||||||
|
source_ranges: arg.source_ranges(),
|
||||||
|
message,
|
||||||
|
})
|
||||||
|
})?;
|
||||||
|
|
||||||
|
Ok(TyF64::from_kcl_val(&arg.value).unwrap().n)
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn get_number_array_with_types(&self) -> Result<Vec<TyF64>, KclError> {
|
pub(crate) fn get_number_array_with_types(&self) -> Result<Vec<TyF64>, KclError> {
|
||||||
let numbers = self
|
let numbers = self
|
||||||
.args
|
.args
|
||||||
@ -577,7 +628,7 @@ impl Args {
|
|||||||
let mut numbers = numbers.into_iter();
|
let mut numbers = numbers.into_iter();
|
||||||
let a = numbers.next().unwrap();
|
let a = numbers.next().unwrap();
|
||||||
let b = numbers.next().unwrap();
|
let b = numbers.next().unwrap();
|
||||||
Ok(NumericType::combine_eq(a, b))
|
Ok(NumericType::combine_eq_coerce(a, b))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn get_sketches(&self, exec_state: &mut ExecState) -> Result<(Vec<Sketch>, Sketch), KclError> {
|
pub(crate) fn get_sketches(&self, exec_state: &mut ExecState) -> Result<(Vec<Sketch>, Sketch), KclError> {
|
||||||
@ -657,8 +708,24 @@ impl Args {
|
|||||||
FromArgs::from_args(self, 0)
|
FromArgs::from_args(self, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn get_data_and_solid(&self, exec_state: &mut ExecState) -> Result<(TyF64, Box<Solid>), KclError> {
|
pub(crate) fn get_length_and_solid(&self, exec_state: &mut ExecState) -> Result<(TyF64, Box<Solid>), KclError> {
|
||||||
let data = FromArgs::from_args(self, 0)?;
|
let Some(arg0) = self.args.first() else {
|
||||||
|
return Err(KclError::Semantic(KclErrorDetails {
|
||||||
|
message: "Expected a `number(Length)` for first argument".to_owned(),
|
||||||
|
source_ranges: vec![self.source_range],
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
let val0 = arg0.value.coerce(&RuntimeType::length(), exec_state).map_err(|_| {
|
||||||
|
KclError::Type(KclErrorDetails {
|
||||||
|
message: format!(
|
||||||
|
"Expected a `number(Length)` for first argument, found {}",
|
||||||
|
arg0.value.human_friendly_type()
|
||||||
|
),
|
||||||
|
source_ranges: vec![self.source_range],
|
||||||
|
})
|
||||||
|
})?;
|
||||||
|
let data = TyF64::from_kcl_val(&val0).unwrap();
|
||||||
|
|
||||||
let Some(arg1) = self.args.get(1) else {
|
let Some(arg1) = self.args.get(1) else {
|
||||||
return Err(KclError::Semantic(KclErrorDetails {
|
return Err(KclError::Semantic(KclErrorDetails {
|
||||||
message: "Expected a solid for second argument".to_owned(),
|
message: "Expected a solid for second argument".to_owned(),
|
||||||
|
@ -137,7 +137,7 @@ async fn inner_chamfer(
|
|||||||
ModelingCmd::from(mcmd::Solid3dFilletEdge {
|
ModelingCmd::from(mcmd::Solid3dFilletEdge {
|
||||||
edge_id,
|
edge_id,
|
||||||
object_id: solid.id,
|
object_id: solid.id,
|
||||||
radius: LengthUnit(length.n),
|
radius: LengthUnit(length.to_mm()),
|
||||||
tolerance: LengthUnit(DEFAULT_TOLERANCE), // We can let the user set this in the future.
|
tolerance: LengthUnit(DEFAULT_TOLERANCE), // We can let the user set this in the future.
|
||||||
cut_type: CutType::Chamfer,
|
cut_type: CutType::Chamfer,
|
||||||
}),
|
}),
|
||||||
|
@ -40,9 +40,9 @@ pub async fn extrude(exec_state: &mut ExecState, args: Args) -> Result<KclValue,
|
|||||||
|
|
||||||
let result = inner_extrude(
|
let result = inner_extrude(
|
||||||
sketches,
|
sketches,
|
||||||
length.n,
|
length,
|
||||||
symmetric,
|
symmetric,
|
||||||
bidirectional_length.map(|t| t.n),
|
bidirectional_length,
|
||||||
tag_start,
|
tag_start,
|
||||||
tag_end,
|
tag_end,
|
||||||
exec_state,
|
exec_state,
|
||||||
@ -164,9 +164,9 @@ pub async fn extrude(exec_state: &mut ExecState, args: Args) -> Result<KclValue,
|
|||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
async fn inner_extrude(
|
async fn inner_extrude(
|
||||||
sketches: Vec<Sketch>,
|
sketches: Vec<Sketch>,
|
||||||
length: f64,
|
length: TyF64,
|
||||||
symmetric: Option<bool>,
|
symmetric: Option<bool>,
|
||||||
bidirectional_length: Option<f64>,
|
bidirectional_length: Option<TyF64>,
|
||||||
tag_start: Option<TagNode>,
|
tag_start: Option<TagNode>,
|
||||||
tag_end: Option<TagNode>,
|
tag_end: Option<TagNode>,
|
||||||
exec_state: &mut ExecState,
|
exec_state: &mut ExecState,
|
||||||
@ -183,7 +183,7 @@ async fn inner_extrude(
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
let bidirection = bidirectional_length.map(LengthUnit);
|
let bidirection = bidirectional_length.map(|l| LengthUnit(l.to_mm()));
|
||||||
|
|
||||||
let opposite = match (symmetric, bidirection) {
|
let opposite = match (symmetric, bidirection) {
|
||||||
(Some(true), _) => Opposite::Symmetric,
|
(Some(true), _) => Opposite::Symmetric,
|
||||||
@ -201,7 +201,7 @@ async fn inner_extrude(
|
|||||||
cmd_id: id.into(),
|
cmd_id: id.into(),
|
||||||
cmd: ModelingCmd::from(mcmd::Extrude {
|
cmd: ModelingCmd::from(mcmd::Extrude {
|
||||||
target: sketch.id.into(),
|
target: sketch.id.into(),
|
||||||
distance: LengthUnit(length),
|
distance: LengthUnit(length.to_mm()),
|
||||||
faces: Default::default(),
|
faces: Default::default(),
|
||||||
opposite: opposite.clone(),
|
opposite: opposite.clone(),
|
||||||
}),
|
}),
|
||||||
@ -213,7 +213,7 @@ async fn inner_extrude(
|
|||||||
do_post_extrude(
|
do_post_extrude(
|
||||||
sketch,
|
sketch,
|
||||||
id.into(),
|
id.into(),
|
||||||
length,
|
length.clone(),
|
||||||
false,
|
false,
|
||||||
&NamedCapTags {
|
&NamedCapTags {
|
||||||
start: tag_start.as_ref(),
|
start: tag_start.as_ref(),
|
||||||
@ -238,7 +238,7 @@ pub(crate) struct NamedCapTags<'a> {
|
|||||||
pub(crate) async fn do_post_extrude<'a>(
|
pub(crate) async fn do_post_extrude<'a>(
|
||||||
sketch: &Sketch,
|
sketch: &Sketch,
|
||||||
solid_id: ArtifactId,
|
solid_id: ArtifactId,
|
||||||
length: f64,
|
length: TyF64,
|
||||||
sectional: bool,
|
sectional: bool,
|
||||||
named_cap_tags: &'a NamedCapTags<'a>,
|
named_cap_tags: &'a NamedCapTags<'a>,
|
||||||
exec_state: &mut ExecState,
|
exec_state: &mut ExecState,
|
||||||
@ -470,8 +470,8 @@ pub(crate) async fn do_post_extrude<'a>(
|
|||||||
value: new_value,
|
value: new_value,
|
||||||
meta: sketch.meta.clone(),
|
meta: sketch.meta.clone(),
|
||||||
units: sketch.units,
|
units: sketch.units,
|
||||||
|
height: length.to_length_units(sketch.units),
|
||||||
sketch,
|
sketch,
|
||||||
height: length,
|
|
||||||
start_cap_id,
|
start_cap_id,
|
||||||
end_cap_id,
|
end_cap_id,
|
||||||
edge_cuts: vec![],
|
edge_cuts: vec![],
|
||||||
|
@ -64,14 +64,14 @@ pub(super) fn validate_unique<T: Eq + std::hash::Hash>(tags: &[(T, SourceRange)]
|
|||||||
pub async fn fillet(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
pub async fn fillet(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
||||||
let solid = args.get_unlabeled_kw_arg_typed("solid", &RuntimeType::solid(), exec_state)?;
|
let solid = args.get_unlabeled_kw_arg_typed("solid", &RuntimeType::solid(), exec_state)?;
|
||||||
let radius: TyF64 = args.get_kw_arg_typed("radius", &RuntimeType::length(), exec_state)?;
|
let radius: TyF64 = args.get_kw_arg_typed("radius", &RuntimeType::length(), exec_state)?;
|
||||||
let tolerance: Option<TyF64> = args.get_kw_arg_opt_typed("tolerance", &RuntimeType::count(), exec_state)?;
|
let tolerance: Option<TyF64> = args.get_kw_arg_opt_typed("tolerance", &RuntimeType::length(), exec_state)?;
|
||||||
let tags = args.kw_arg_array_and_source::<EdgeReference>("tags")?;
|
let tags = args.kw_arg_array_and_source::<EdgeReference>("tags")?;
|
||||||
let tag = args.get_kw_arg_opt("tag")?;
|
let tag = args.get_kw_arg_opt("tag")?;
|
||||||
|
|
||||||
// Run the function.
|
// Run the function.
|
||||||
validate_unique(&tags)?;
|
validate_unique(&tags)?;
|
||||||
let tags: Vec<EdgeReference> = tags.into_iter().map(|item| item.0).collect();
|
let tags: Vec<EdgeReference> = tags.into_iter().map(|item| item.0).collect();
|
||||||
let value = inner_fillet(solid, radius, tags, tolerance.map(|t| t.n), tag, exec_state, args).await?;
|
let value = inner_fillet(solid, radius, tags, tolerance, tag, exec_state, args).await?;
|
||||||
Ok(KclValue::Solid { value })
|
Ok(KclValue::Solid { value })
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -148,7 +148,7 @@ async fn inner_fillet(
|
|||||||
solid: Box<Solid>,
|
solid: Box<Solid>,
|
||||||
radius: TyF64,
|
radius: TyF64,
|
||||||
tags: Vec<EdgeReference>,
|
tags: Vec<EdgeReference>,
|
||||||
tolerance: Option<f64>,
|
tolerance: Option<TyF64>,
|
||||||
tag: Option<TagNode>,
|
tag: Option<TagNode>,
|
||||||
exec_state: &mut ExecState,
|
exec_state: &mut ExecState,
|
||||||
args: Args,
|
args: Args,
|
||||||
@ -163,8 +163,8 @@ async fn inner_fillet(
|
|||||||
ModelingCmd::from(mcmd::Solid3dFilletEdge {
|
ModelingCmd::from(mcmd::Solid3dFilletEdge {
|
||||||
edge_id,
|
edge_id,
|
||||||
object_id: solid.id,
|
object_id: solid.id,
|
||||||
radius: LengthUnit(radius.n),
|
radius: LengthUnit(radius.to_mm()),
|
||||||
tolerance: LengthUnit(tolerance.unwrap_or(DEFAULT_TOLERANCE)),
|
tolerance: LengthUnit(tolerance.as_ref().map(|t| t.to_mm()).unwrap_or(DEFAULT_TOLERANCE)),
|
||||||
cut_type: CutType::Fillet,
|
cut_type: CutType::Fillet,
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
@ -17,7 +17,7 @@ use super::args::TyF64;
|
|||||||
|
|
||||||
/// Create a helix.
|
/// Create a helix.
|
||||||
pub async fn helix(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
pub async fn helix(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
||||||
let angle_start: TyF64 = args.get_kw_arg_typed("angleStart", &RuntimeType::angle(), exec_state)?;
|
let angle_start: TyF64 = args.get_kw_arg_typed("angleStart", &RuntimeType::degrees(), exec_state)?;
|
||||||
let revolutions: TyF64 = args.get_kw_arg_typed("revolutions", &RuntimeType::count(), exec_state)?;
|
let revolutions: TyF64 = args.get_kw_arg_typed("revolutions", &RuntimeType::count(), exec_state)?;
|
||||||
let ccw = args.get_kw_arg_opt("ccw")?;
|
let ccw = args.get_kw_arg_opt("ccw")?;
|
||||||
let radius: Option<TyF64> = args.get_kw_arg_opt_typed("radius", &RuntimeType::length(), exec_state)?;
|
let radius: Option<TyF64> = args.get_kw_arg_opt_typed("radius", &RuntimeType::length(), exec_state)?;
|
||||||
@ -84,9 +84,9 @@ pub async fn helix(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K
|
|||||||
revolutions.n,
|
revolutions.n,
|
||||||
angle_start.n,
|
angle_start.n,
|
||||||
ccw,
|
ccw,
|
||||||
radius.map(|t| t.n),
|
radius,
|
||||||
axis,
|
axis,
|
||||||
length.map(|t| t.n),
|
length,
|
||||||
cylinder,
|
cylinder,
|
||||||
exec_state,
|
exec_state,
|
||||||
args,
|
args,
|
||||||
@ -100,9 +100,9 @@ async fn inner_helix(
|
|||||||
revolutions: f64,
|
revolutions: f64,
|
||||||
angle_start: f64,
|
angle_start: f64,
|
||||||
ccw: Option<bool>,
|
ccw: Option<bool>,
|
||||||
radius: Option<f64>,
|
radius: Option<TyF64>,
|
||||||
axis: Option<Axis3dOrEdgeReference>,
|
axis: Option<Axis3dOrEdgeReference>,
|
||||||
length: Option<f64>,
|
length: Option<TyF64>,
|
||||||
cylinder: Option<Solid>,
|
cylinder: Option<Solid>,
|
||||||
exec_state: &mut ExecState,
|
exec_state: &mut ExecState,
|
||||||
args: Args,
|
args: Args,
|
||||||
@ -130,7 +130,7 @@ async fn inner_helix(
|
|||||||
ModelingCmd::from(mcmd::EntityMakeHelix {
|
ModelingCmd::from(mcmd::EntityMakeHelix {
|
||||||
cylinder_id: cylinder.id,
|
cylinder_id: cylinder.id,
|
||||||
is_clockwise: !helix_result.ccw,
|
is_clockwise: !helix_result.ccw,
|
||||||
length: LengthUnit(length.unwrap_or(cylinder.height)),
|
length: LengthUnit(length.as_ref().map(|t| t.to_mm()).unwrap_or(cylinder.height_in_mm())),
|
||||||
revolutions,
|
revolutions,
|
||||||
start_angle: Angle::from_degrees(angle_start),
|
start_angle: Angle::from_degrees(angle_start),
|
||||||
}),
|
}),
|
||||||
@ -150,20 +150,20 @@ async fn inner_helix(
|
|||||||
args.batch_modeling_cmd(
|
args.batch_modeling_cmd(
|
||||||
id,
|
id,
|
||||||
ModelingCmd::from(mcmd::EntityMakeHelixFromParams {
|
ModelingCmd::from(mcmd::EntityMakeHelixFromParams {
|
||||||
radius: LengthUnit(radius),
|
radius: LengthUnit(radius.to_mm()),
|
||||||
is_clockwise: !helix_result.ccw,
|
is_clockwise: !helix_result.ccw,
|
||||||
length: LengthUnit(length),
|
length: LengthUnit(length.to_mm()),
|
||||||
revolutions,
|
revolutions,
|
||||||
start_angle: Angle::from_degrees(angle_start),
|
start_angle: Angle::from_degrees(angle_start),
|
||||||
axis: Point3d {
|
axis: Point3d {
|
||||||
x: direction[0].n,
|
x: direction[0].to_mm(),
|
||||||
y: direction[1].n,
|
y: direction[1].to_mm(),
|
||||||
z: direction[2].n,
|
z: direction[2].to_mm(),
|
||||||
},
|
},
|
||||||
center: Point3d {
|
center: Point3d {
|
||||||
x: LengthUnit(origin[0].n),
|
x: LengthUnit(origin[0].to_mm()),
|
||||||
y: LengthUnit(origin[1].n),
|
y: LengthUnit(origin[1].to_mm()),
|
||||||
z: LengthUnit(origin[2].n),
|
z: LengthUnit(origin[2].to_mm()),
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
@ -175,9 +175,9 @@ async fn inner_helix(
|
|||||||
args.batch_modeling_cmd(
|
args.batch_modeling_cmd(
|
||||||
id,
|
id,
|
||||||
ModelingCmd::from(mcmd::EntityMakeHelixFromEdge {
|
ModelingCmd::from(mcmd::EntityMakeHelixFromEdge {
|
||||||
radius: LengthUnit(radius),
|
radius: LengthUnit(radius.to_mm()),
|
||||||
is_clockwise: !helix_result.ccw,
|
is_clockwise: !helix_result.ccw,
|
||||||
length: length.map(LengthUnit),
|
length: length.map(|t| LengthUnit(t.to_mm())),
|
||||||
revolutions,
|
revolutions,
|
||||||
start_angle: Angle::from_degrees(angle_start),
|
start_angle: Angle::from_degrees(angle_start),
|
||||||
edge_id,
|
edge_id,
|
||||||
|
@ -10,7 +10,10 @@ use kittycad_modeling_cmds as kcmc;
|
|||||||
use super::{args::TyF64, DEFAULT_TOLERANCE};
|
use super::{args::TyF64, DEFAULT_TOLERANCE};
|
||||||
use crate::{
|
use crate::{
|
||||||
errors::{KclError, KclErrorDetails},
|
errors::{KclError, KclErrorDetails},
|
||||||
execution::{types::RuntimeType, ExecState, KclValue, Sketch, Solid},
|
execution::{
|
||||||
|
types::{NumericType, RuntimeType},
|
||||||
|
ExecState, KclValue, Sketch, Solid,
|
||||||
|
},
|
||||||
parsing::ast::types::TagNode,
|
parsing::ast::types::TagNode,
|
||||||
std::{extrude::do_post_extrude, Args},
|
std::{extrude::do_post_extrude, Args},
|
||||||
};
|
};
|
||||||
@ -30,7 +33,7 @@ pub async fn loft(exec_state: &mut ExecState, args: Args) -> Result<KclValue, Kc
|
|||||||
// This can be set to override the automatically determined topological base curve, which is usually the first section encountered.
|
// This can be set to override the automatically determined topological base curve, which is usually the first section encountered.
|
||||||
let base_curve_index: Option<u32> = args.get_kw_arg_opt("baseCurveIndex")?;
|
let base_curve_index: Option<u32> = args.get_kw_arg_opt("baseCurveIndex")?;
|
||||||
// Tolerance for the loft operation.
|
// Tolerance for the loft operation.
|
||||||
let tolerance: Option<TyF64> = args.get_kw_arg_opt_typed("tolerance", &RuntimeType::count(), exec_state)?;
|
let tolerance: Option<TyF64> = args.get_kw_arg_opt_typed("tolerance", &RuntimeType::length(), exec_state)?;
|
||||||
let tag_start = args.get_kw_arg_opt("tagStart")?;
|
let tag_start = args.get_kw_arg_opt("tagStart")?;
|
||||||
let tag_end = args.get_kw_arg_opt("tagEnd")?;
|
let tag_end = args.get_kw_arg_opt("tagEnd")?;
|
||||||
|
|
||||||
@ -39,7 +42,7 @@ pub async fn loft(exec_state: &mut ExecState, args: Args) -> Result<KclValue, Kc
|
|||||||
v_degree,
|
v_degree,
|
||||||
bez_approximate_rational,
|
bez_approximate_rational,
|
||||||
base_curve_index,
|
base_curve_index,
|
||||||
tolerance.map(|t| t.n),
|
tolerance,
|
||||||
tag_start,
|
tag_start,
|
||||||
tag_end,
|
tag_end,
|
||||||
exec_state,
|
exec_state,
|
||||||
@ -136,7 +139,7 @@ async fn inner_loft(
|
|||||||
v_degree: NonZeroU32,
|
v_degree: NonZeroU32,
|
||||||
bez_approximate_rational: bool,
|
bez_approximate_rational: bool,
|
||||||
base_curve_index: Option<u32>,
|
base_curve_index: Option<u32>,
|
||||||
tolerance: Option<f64>,
|
tolerance: Option<TyF64>,
|
||||||
tag_start: Option<TagNode>,
|
tag_start: Option<TagNode>,
|
||||||
tag_end: Option<TagNode>,
|
tag_end: Option<TagNode>,
|
||||||
exec_state: &mut ExecState,
|
exec_state: &mut ExecState,
|
||||||
@ -160,7 +163,7 @@ async fn inner_loft(
|
|||||||
section_ids: sketches.iter().map(|group| group.id).collect(),
|
section_ids: sketches.iter().map(|group| group.id).collect(),
|
||||||
base_curve_index,
|
base_curve_index,
|
||||||
bez_approximate_rational,
|
bez_approximate_rational,
|
||||||
tolerance: LengthUnit(tolerance.unwrap_or(DEFAULT_TOLERANCE)),
|
tolerance: LengthUnit(tolerance.as_ref().map(|t| t.to_mm()).unwrap_or(DEFAULT_TOLERANCE)),
|
||||||
v_degree,
|
v_degree,
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
@ -174,7 +177,7 @@ async fn inner_loft(
|
|||||||
do_post_extrude(
|
do_post_extrude(
|
||||||
&sketch,
|
&sketch,
|
||||||
id.into(),
|
id.into(),
|
||||||
0.0,
|
TyF64::new(0.0, NumericType::mm()),
|
||||||
false,
|
false,
|
||||||
&super::extrude::NamedCapTags {
|
&super::extrude::NamedCapTags {
|
||||||
start: tag_start.as_ref(),
|
start: tag_start.as_ref(),
|
||||||
|
@ -6,7 +6,7 @@ use kcl_derive_docs::stdlib;
|
|||||||
use crate::{
|
use crate::{
|
||||||
errors::{KclError, KclErrorDetails},
|
errors::{KclError, KclErrorDetails},
|
||||||
execution::{
|
execution::{
|
||||||
types::{self, NumericType, RuntimeType},
|
types::{NumericType, RuntimeType, UnitAngle, UnitType},
|
||||||
ExecState, KclValue,
|
ExecState, KclValue,
|
||||||
},
|
},
|
||||||
std::args::{Args, TyF64},
|
std::args::{Args, TyF64},
|
||||||
@ -20,11 +20,10 @@ pub async fn rem(exec_state: &mut ExecState, args: Args) -> Result<KclValue, Kcl
|
|||||||
let d: TyF64 = args.get_kw_arg_typed("divisor", &RuntimeType::num_any(), exec_state)?;
|
let d: TyF64 = args.get_kw_arg_typed("divisor", &RuntimeType::num_any(), exec_state)?;
|
||||||
|
|
||||||
let (n, d, ty) = NumericType::combine_div(n, d);
|
let (n, d, ty) = NumericType::combine_div(n, d);
|
||||||
if *types::CHECK_NUMERIC_TYPES && ty == NumericType::Unknown {
|
if ty == NumericType::Unknown {
|
||||||
// TODO suggest how to fix this
|
|
||||||
exec_state.warn(CompilationError::err(
|
exec_state.warn(CompilationError::err(
|
||||||
args.source_range,
|
args.source_range,
|
||||||
"Remainder of numbers which have unknown or incompatible units.",
|
"Calling `rem` on numbers which have unknown or incompatible units.\n\nYou may need to add information about the type of the argument, for example:\n using a numeric suffix: `42{ty}`\n or using type ascription: `foo(): number({ty})`"
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
let remainder = inner_rem(n, d);
|
let remainder = inner_rem(n, d);
|
||||||
@ -59,20 +58,63 @@ fn inner_rem(num: f64, divisor: f64) -> f64 {
|
|||||||
|
|
||||||
/// Compute the cosine of a number (in radians).
|
/// Compute the cosine of a number (in radians).
|
||||||
pub async fn cos(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
pub async fn cos(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
||||||
let num: TyF64 = args.get_unlabeled_kw_arg_typed("input", &RuntimeType::radians(), exec_state)?;
|
let num: TyF64 = args.get_unlabeled_kw_arg_typed("input", &RuntimeType::angle(), exec_state)?;
|
||||||
Ok(args.make_user_val_from_f64_with_type(TyF64::count(num.n.cos())))
|
let num = match num.ty {
|
||||||
|
NumericType::Default {
|
||||||
|
angle: UnitAngle::Degrees,
|
||||||
|
..
|
||||||
|
} => {
|
||||||
|
exec_state.warn(CompilationError::err(
|
||||||
|
args.source_range,
|
||||||
|
"`cos` requires its input in radians, but the input is assumed to be in degrees. You can use a numeric suffix (e.g., `0rad`) or type ascription (e.g., `(1/2): number(rad)`) to show the number is in radians, or `toRadians` to convert from degrees to radians",
|
||||||
|
));
|
||||||
|
num.n
|
||||||
|
}
|
||||||
|
NumericType::Known(UnitType::Angle(UnitAngle::Degrees)) => num.n.to_radians(),
|
||||||
|
_ => num.n,
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(args.make_user_val_from_f64_with_type(TyF64::count(num.cos())))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Compute the sine of a number (in radians).
|
/// Compute the sine of a number (in radians).
|
||||||
pub async fn sin(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
pub async fn sin(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
||||||
let num: TyF64 = args.get_unlabeled_kw_arg_typed("input", &RuntimeType::radians(), exec_state)?;
|
let num: TyF64 = args.get_unlabeled_kw_arg_typed("input", &RuntimeType::angle(), exec_state)?;
|
||||||
Ok(args.make_user_val_from_f64_with_type(TyF64::count(num.n.sin())))
|
let num = match num.ty {
|
||||||
|
NumericType::Default {
|
||||||
|
angle: UnitAngle::Degrees,
|
||||||
|
..
|
||||||
|
} => {
|
||||||
|
exec_state.warn(CompilationError::err(
|
||||||
|
args.source_range,
|
||||||
|
"`sin` requires its input in radians, but the input is assumed to be in degrees. You can use a numeric suffix (e.g., `0rad`) or type ascription (e.g., `(1/2): number(rad)`) to show the number is in radians, or `toRadians` to convert from degrees to radians",
|
||||||
|
));
|
||||||
|
num.n
|
||||||
|
}
|
||||||
|
NumericType::Known(UnitType::Angle(UnitAngle::Degrees)) => num.n.to_radians(),
|
||||||
|
_ => num.n,
|
||||||
|
};
|
||||||
|
Ok(args.make_user_val_from_f64_with_type(TyF64::count(num.sin())))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Compute the tangent of a number (in radians).
|
/// Compute the tangent of a number (in radians).
|
||||||
pub async fn tan(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
pub async fn tan(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
||||||
let num: TyF64 = args.get_unlabeled_kw_arg_typed("input", &RuntimeType::radians(), exec_state)?;
|
let num: TyF64 = args.get_unlabeled_kw_arg_typed("input", &RuntimeType::angle(), exec_state)?;
|
||||||
Ok(args.make_user_val_from_f64_with_type(TyF64::count(num.n.tan())))
|
let num = match num.ty {
|
||||||
|
NumericType::Default {
|
||||||
|
angle: UnitAngle::Degrees,
|
||||||
|
..
|
||||||
|
} => {
|
||||||
|
exec_state.warn(CompilationError::err(
|
||||||
|
args.source_range,
|
||||||
|
"`tan` requires its input in radians, but the input is assumed to be in degrees. You can use a numeric suffix (e.g., `0rad`) or type ascription (e.g., `(1/2): number(rad)`) to show the number is in radians, or `toRadians` to convert from degrees to radians",
|
||||||
|
));
|
||||||
|
num.n
|
||||||
|
}
|
||||||
|
NumericType::Known(UnitType::Angle(UnitAngle::Degrees)) => num.n.to_radians(),
|
||||||
|
_ => num.n,
|
||||||
|
};
|
||||||
|
Ok(args.make_user_val_from_f64_with_type(TyF64::count(num.tan())))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the value of `pi`. Archimedes’ constant (π).
|
/// Return the value of `pi`. Archimedes’ constant (π).
|
||||||
@ -258,11 +300,10 @@ fn inner_ceil(num: f64) -> Result<f64, KclError> {
|
|||||||
pub async fn min(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
pub async fn min(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
||||||
let nums = args.get_number_array_with_types()?;
|
let nums = args.get_number_array_with_types()?;
|
||||||
let (nums, ty) = NumericType::combine_eq_array(&nums);
|
let (nums, ty) = NumericType::combine_eq_array(&nums);
|
||||||
if *types::CHECK_NUMERIC_TYPES && ty == NumericType::Unknown {
|
if ty == NumericType::Unknown {
|
||||||
// TODO suggest how to fix this
|
|
||||||
exec_state.warn(CompilationError::err(
|
exec_state.warn(CompilationError::err(
|
||||||
args.source_range,
|
args.source_range,
|
||||||
"Calling `min` on numbers which have unknown or incompatible units.",
|
"Calling `min` on numbers which have unknown or incompatible units.\n\nYou may need to add information about the type of the argument, for example:\n using a numeric suffix: `42{ty}`\n or using type ascription: `foo(): number({ty})`",
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
let result = inner_min(nums);
|
let result = inner_min(nums);
|
||||||
@ -303,11 +344,10 @@ fn inner_min(args: Vec<f64>) -> f64 {
|
|||||||
pub async fn max(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
pub async fn max(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
||||||
let nums = args.get_number_array_with_types()?;
|
let nums = args.get_number_array_with_types()?;
|
||||||
let (nums, ty) = NumericType::combine_eq_array(&nums);
|
let (nums, ty) = NumericType::combine_eq_array(&nums);
|
||||||
if *types::CHECK_NUMERIC_TYPES && ty == NumericType::Unknown {
|
if ty == NumericType::Unknown {
|
||||||
// TODO suggest how to fix this
|
|
||||||
exec_state.warn(CompilationError::err(
|
exec_state.warn(CompilationError::err(
|
||||||
args.source_range,
|
args.source_range,
|
||||||
"Calling `max` on numbers which have unknown or incompatible units.",
|
"Calling `max` on numbers which have unknown or incompatible units.\n\nYou may need to add information about the type of the argument, for example:\n using a numeric suffix: `42{ty}`\n or using type ascription: `foo(): number({ty})`",
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
let result = inner_max(nums);
|
let result = inner_max(nums);
|
||||||
@ -389,8 +429,20 @@ fn inner_pow(num: f64, pow: f64) -> Result<f64, KclError> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Compute the arccosine of a number (in radians).
|
/// Compute the arccosine of a number (in radians).
|
||||||
pub async fn acos(_exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
pub async fn acos(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
||||||
let num = args.get_number_with_type()?;
|
let num = args.get_number_with_type()?;
|
||||||
|
if matches!(
|
||||||
|
num.ty,
|
||||||
|
NumericType::Default {
|
||||||
|
angle: UnitAngle::Degrees,
|
||||||
|
..
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
exec_state.warn(CompilationError::err(
|
||||||
|
args.source_range,
|
||||||
|
"`acos` requires its input in radians, but the input is assumed to be in degrees. You can use a numeric suffix (e.g., `0rad`) or type ascription (e.g., `(1/2): number(rad)`) to show the number is in radians, or `toRadians` to convert from degrees to radians",
|
||||||
|
));
|
||||||
|
}
|
||||||
let result = inner_acos(num.n)?;
|
let result = inner_acos(num.n)?;
|
||||||
|
|
||||||
Ok(args.make_user_val_from_f64_with_type(TyF64::new(result, NumericType::radians())))
|
Ok(args.make_user_val_from_f64_with_type(TyF64::new(result, NumericType::radians())))
|
||||||
@ -420,8 +472,20 @@ fn inner_acos(num: f64) -> Result<f64, KclError> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Compute the arcsine of a number (in radians).
|
/// Compute the arcsine of a number (in radians).
|
||||||
pub async fn asin(_exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
pub async fn asin(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
||||||
let num = args.get_number_with_type()?;
|
let num = args.get_number_with_type()?;
|
||||||
|
if matches!(
|
||||||
|
num.ty,
|
||||||
|
NumericType::Default {
|
||||||
|
angle: UnitAngle::Degrees,
|
||||||
|
..
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
exec_state.warn(CompilationError::err(
|
||||||
|
args.source_range,
|
||||||
|
"`asin` requires its input in radians, but the input is assumed to be in degrees. You can use a numeric suffix (e.g., `0rad`) or type ascription (e.g., `(1/2): number(rad)`) to show the number is in radians, or `toRadians` to convert from degrees to radians",
|
||||||
|
));
|
||||||
|
}
|
||||||
let result = inner_asin(num.n)?;
|
let result = inner_asin(num.n)?;
|
||||||
|
|
||||||
Ok(args.make_user_val_from_f64_with_type(TyF64::new(result, NumericType::radians())))
|
Ok(args.make_user_val_from_f64_with_type(TyF64::new(result, NumericType::radians())))
|
||||||
@ -450,8 +514,20 @@ fn inner_asin(num: f64) -> Result<f64, KclError> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Compute the arctangent of a number (in radians).
|
/// Compute the arctangent of a number (in radians).
|
||||||
pub async fn atan(_exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
pub async fn atan(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
||||||
let num = args.get_number_with_type()?;
|
let num = args.get_number_with_type()?;
|
||||||
|
if matches!(
|
||||||
|
num.ty,
|
||||||
|
NumericType::Default {
|
||||||
|
angle: UnitAngle::Degrees,
|
||||||
|
..
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
exec_state.warn(CompilationError::err(
|
||||||
|
args.source_range,
|
||||||
|
"`atan` requires its input in radians, but the input is assumed to be in degrees. You can use a numeric suffix (e.g., `0rad`) or type ascription (e.g., `(1/2): number(rad)`) to show the number is in radians, or `toRadians` to convert from degrees to radians",
|
||||||
|
));
|
||||||
|
}
|
||||||
let result = inner_atan(num.n)?;
|
let result = inner_atan(num.n)?;
|
||||||
|
|
||||||
Ok(args.make_user_val_from_f64_with_type(TyF64::new(result, NumericType::radians())))
|
Ok(args.make_user_val_from_f64_with_type(TyF64::new(result, NumericType::radians())))
|
||||||
@ -483,7 +559,7 @@ fn inner_atan(num: f64) -> Result<f64, KclError> {
|
|||||||
pub async fn atan2(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
pub async fn atan2(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
||||||
let y = args.get_kw_arg_typed("y", &RuntimeType::length(), exec_state)?;
|
let y = args.get_kw_arg_typed("y", &RuntimeType::length(), exec_state)?;
|
||||||
let x = args.get_kw_arg_typed("x", &RuntimeType::length(), exec_state)?;
|
let x = args.get_kw_arg_typed("x", &RuntimeType::length(), exec_state)?;
|
||||||
let (y, x, _) = NumericType::combine_eq(y, x);
|
let (y, x, _) = NumericType::combine_eq_coerce(y, x);
|
||||||
let result = inner_atan2(y, x)?;
|
let result = inner_atan2(y, x)?;
|
||||||
|
|
||||||
Ok(args.make_user_val_from_f64_with_type(TyF64::new(result, NumericType::radians())))
|
Ok(args.make_user_val_from_f64_with_type(TyF64::new(result, NumericType::radians())))
|
||||||
@ -714,66 +790,6 @@ fn inner_tau() -> Result<f64, KclError> {
|
|||||||
Ok(std::f64::consts::TAU)
|
Ok(std::f64::consts::TAU)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Converts a number from degrees to radians.
|
|
||||||
pub async fn to_radians(_exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
|
||||||
let num = args.get_number_with_type()?;
|
|
||||||
let result = inner_to_radians(num.n)?;
|
|
||||||
|
|
||||||
Ok(args.make_user_val_from_f64_with_type(TyF64::new(result, NumericType::radians())))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Converts a number from degrees to radians.
|
|
||||||
///
|
|
||||||
/// ```no_run
|
|
||||||
/// exampleSketch = startSketchOn("XZ")
|
|
||||||
/// |> startProfileAt([0, 0], %)
|
|
||||||
/// |> angledLine(
|
|
||||||
/// angle = 50,
|
|
||||||
/// length = 70 * cos(toRadians(45)),
|
|
||||||
/// )
|
|
||||||
/// |> yLine(endAbsolute = 0)
|
|
||||||
/// |> close()
|
|
||||||
///
|
|
||||||
/// example = extrude(exampleSketch, length = 5)
|
|
||||||
/// ```
|
|
||||||
#[stdlib {
|
|
||||||
name = "toRadians",
|
|
||||||
tags = ["math"],
|
|
||||||
}]
|
|
||||||
fn inner_to_radians(num: f64) -> Result<f64, KclError> {
|
|
||||||
Ok(num.to_radians())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Converts a number from radians to degrees.
|
|
||||||
pub async fn to_degrees(_exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
|
||||||
let num = args.get_number_with_type()?;
|
|
||||||
let result = inner_to_degrees(num.n)?;
|
|
||||||
|
|
||||||
Ok(args.make_user_val_from_f64_with_type(TyF64::new(result, NumericType::degrees())))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Converts a number from radians to degrees.
|
|
||||||
///
|
|
||||||
/// ```no_run
|
|
||||||
/// exampleSketch = startSketchOn("XZ")
|
|
||||||
/// |> startProfileAt([0, 0], %)
|
|
||||||
/// |> angledLine(
|
|
||||||
/// angle = 50,
|
|
||||||
/// length = 70 * cos(toDegrees(pi()/4)),
|
|
||||||
/// )
|
|
||||||
/// |> yLine(endAbsolute = 0)
|
|
||||||
/// |> close()
|
|
||||||
///
|
|
||||||
/// example = extrude(exampleSketch, length = 5)
|
|
||||||
/// ```
|
|
||||||
#[stdlib {
|
|
||||||
name = "toDegrees",
|
|
||||||
tags = ["math"],
|
|
||||||
}]
|
|
||||||
fn inner_to_degrees(num: f64) -> Result<f64, KclError> {
|
|
||||||
Ok(num.to_degrees())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use pretty_assertions::assert_eq;
|
use pretty_assertions::assert_eq;
|
||||||
|
@ -61,13 +61,13 @@ async fn inner_mirror_2d(
|
|||||||
ModelingCmd::from(mcmd::EntityMirror {
|
ModelingCmd::from(mcmd::EntityMirror {
|
||||||
ids: starting_sketches.iter().map(|sketch| sketch.id).collect(),
|
ids: starting_sketches.iter().map(|sketch| sketch.id).collect(),
|
||||||
axis: Point3d {
|
axis: Point3d {
|
||||||
x: direction[0].n,
|
x: direction[0].to_mm(),
|
||||||
y: direction[1].n,
|
y: direction[1].to_mm(),
|
||||||
z: 0.0,
|
z: 0.0,
|
||||||
},
|
},
|
||||||
point: Point3d {
|
point: Point3d {
|
||||||
x: LengthUnit(origin[0].n),
|
x: LengthUnit(origin[0].to_mm()),
|
||||||
y: LengthUnit(origin[1].n),
|
y: LengthUnit(origin[1].to_mm()),
|
||||||
z: LengthUnit(0.0),
|
z: LengthUnit(0.0),
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
|
@ -128,8 +128,6 @@ lazy_static! {
|
|||||||
Box::new(crate::std::math::Log2),
|
Box::new(crate::std::math::Log2),
|
||||||
Box::new(crate::std::math::Log10),
|
Box::new(crate::std::math::Log10),
|
||||||
Box::new(crate::std::math::Ln),
|
Box::new(crate::std::math::Ln),
|
||||||
Box::new(crate::std::math::ToDegrees),
|
|
||||||
Box::new(crate::std::math::ToRadians),
|
|
||||||
Box::new(crate::std::units::FromMm),
|
Box::new(crate::std::units::FromMm),
|
||||||
Box::new(crate::std::units::FromInches),
|
Box::new(crate::std::units::FromInches),
|
||||||
Box::new(crate::std::units::FromFt),
|
Box::new(crate::std::units::FromFt),
|
||||||
|
@ -13,12 +13,12 @@ use kittycad_modeling_cmds::{
|
|||||||
shared::{Angle, OriginType, Rotation},
|
shared::{Angle, OriginType, Rotation},
|
||||||
};
|
};
|
||||||
use schemars::JsonSchema;
|
use schemars::JsonSchema;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::Serialize;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
args::Arg,
|
args::Arg,
|
||||||
utils::{untype_point, untype_point_3d},
|
utils::{point_3d_to_mm, point_to_mm},
|
||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
errors::{KclError, KclErrorDetails},
|
errors::{KclError, KclErrorDetails},
|
||||||
@ -34,7 +34,7 @@ use crate::{
|
|||||||
const MUST_HAVE_ONE_INSTANCE: &str = "There must be at least 1 instance of your geometry";
|
const MUST_HAVE_ONE_INSTANCE: &str = "There must be at least 1 instance of your geometry";
|
||||||
|
|
||||||
/// Data for a linear pattern on a 3D model.
|
/// Data for a linear pattern on a 3D model.
|
||||||
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
|
#[derive(Debug, Clone, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
|
||||||
#[ts(export)]
|
#[ts(export)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct LinearPattern3dData {
|
pub struct LinearPattern3dData {
|
||||||
@ -44,9 +44,9 @@ pub struct LinearPattern3dData {
|
|||||||
/// If instances is 1, this has no effect.
|
/// If instances is 1, this has no effect.
|
||||||
pub instances: u32,
|
pub instances: u32,
|
||||||
/// The distance between each repetition. This can also be referred to as spacing.
|
/// The distance between each repetition. This can also be referred to as spacing.
|
||||||
pub distance: f64,
|
pub distance: TyF64,
|
||||||
/// The axis of the pattern.
|
/// The axis of the pattern.
|
||||||
pub axis: [f64; 3],
|
pub axis: [TyF64; 3],
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Repeat some 3D solid, changing each repetition slightly.
|
/// Repeat some 3D solid, changing each repetition slightly.
|
||||||
@ -219,7 +219,7 @@ pub async fn pattern_transform_2d(exec_state: &mut ExecState, args: Args) -> Res
|
|||||||
/// // Defines how to modify each layer of the vase.
|
/// // Defines how to modify each layer of the vase.
|
||||||
/// // Each replica is shifted up the Z axis, and has a smoothly-varying radius
|
/// // Each replica is shifted up the Z axis, and has a smoothly-varying radius
|
||||||
/// fn transform(replicaId) {
|
/// fn transform(replicaId) {
|
||||||
/// scale = r * abs(1 - (t * replicaId)) * (5 + cos(replicaId / 8))
|
/// scale = r * abs(1 - (t * replicaId)) * (5 + cos((replicaId / 8): number(rad)))
|
||||||
/// return {
|
/// return {
|
||||||
/// translate = [0, 0, replicaId * 10],
|
/// translate = [0, 0, replicaId * 10],
|
||||||
/// scale = [scale, scale, 0],
|
/// scale = [scale, scale, 0],
|
||||||
@ -498,15 +498,13 @@ fn transform_from_obj_fields<T: GeometryTrait>(
|
|||||||
};
|
};
|
||||||
|
|
||||||
let scale = match transform.get("scale") {
|
let scale = match transform.get("scale") {
|
||||||
Some(x) => untype_point_3d(T::array_to_point3d(x, source_ranges.clone(), exec_state)?)
|
Some(x) => point_3d_to_mm(T::array_to_point3d(x, source_ranges.clone(), exec_state)?).into(),
|
||||||
.0
|
|
||||||
.into(),
|
|
||||||
None => kcmc::shared::Point3d { x: 1.0, y: 1.0, z: 1.0 },
|
None => kcmc::shared::Point3d { x: 1.0, y: 1.0, z: 1.0 },
|
||||||
};
|
};
|
||||||
|
|
||||||
let translate = match transform.get("translate") {
|
let translate = match transform.get("translate") {
|
||||||
Some(x) => {
|
Some(x) => {
|
||||||
let (arr, _) = untype_point_3d(T::array_to_point3d(x, source_ranges.clone(), exec_state)?);
|
let arr = point_3d_to_mm(T::array_to_point3d(x, source_ranges.clone(), exec_state)?);
|
||||||
kcmc::shared::Point3d::<LengthUnit> {
|
kcmc::shared::Point3d::<LengthUnit> {
|
||||||
x: LengthUnit(arr[0]),
|
x: LengthUnit(arr[0]),
|
||||||
y: LengthUnit(arr[1]),
|
y: LengthUnit(arr[1]),
|
||||||
@ -530,9 +528,7 @@ fn transform_from_obj_fields<T: GeometryTrait>(
|
|||||||
}));
|
}));
|
||||||
};
|
};
|
||||||
if let Some(axis) = rot.get("axis") {
|
if let Some(axis) = rot.get("axis") {
|
||||||
rotation.axis = untype_point_3d(T::array_to_point3d(axis, source_ranges.clone(), exec_state)?)
|
rotation.axis = point_3d_to_mm(T::array_to_point3d(axis, source_ranges.clone(), exec_state)?).into();
|
||||||
.0
|
|
||||||
.into();
|
|
||||||
}
|
}
|
||||||
if let Some(angle) = rot.get("angle") {
|
if let Some(angle) = rot.get("angle") {
|
||||||
match angle {
|
match angle {
|
||||||
@ -552,9 +548,7 @@ fn transform_from_obj_fields<T: GeometryTrait>(
|
|||||||
KclValue::String { value: s, meta: _ } if s == "local" => OriginType::Local,
|
KclValue::String { value: s, meta: _ } if s == "local" => OriginType::Local,
|
||||||
KclValue::String { value: s, meta: _ } if s == "global" => OriginType::Global,
|
KclValue::String { value: s, meta: _ } if s == "global" => OriginType::Global,
|
||||||
other => {
|
other => {
|
||||||
let origin = untype_point_3d(T::array_to_point3d(other, source_ranges.clone(), exec_state)?)
|
let origin = point_3d_to_mm(T::array_to_point3d(other, source_ranges.clone(), exec_state)?).into();
|
||||||
.0
|
|
||||||
.into();
|
|
||||||
OriginType::Custom { origin }
|
OriginType::Custom { origin }
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -721,8 +715,7 @@ pub async fn pattern_linear_2d(exec_state: &mut ExecState, args: Args) -> Result
|
|||||||
let axis: [TyF64; 2] = args.get_kw_arg_typed("axis", &RuntimeType::point2d(), exec_state)?;
|
let axis: [TyF64; 2] = args.get_kw_arg_typed("axis", &RuntimeType::point2d(), exec_state)?;
|
||||||
let use_original: Option<bool> = args.get_kw_arg_opt("useOriginal")?;
|
let use_original: Option<bool> = args.get_kw_arg_opt("useOriginal")?;
|
||||||
|
|
||||||
let axis = untype_point(axis).0;
|
if axis[0].n == 0.0 && axis[1].n == 0.0 {
|
||||||
if axis == [0.0, 0.0] {
|
|
||||||
return Err(KclError::Semantic(KclErrorDetails {
|
return Err(KclError::Semantic(KclErrorDetails {
|
||||||
message:
|
message:
|
||||||
"The axis of the linear pattern cannot be the zero vector. Otherwise they will just duplicate in place."
|
"The axis of the linear pattern cannot be the zero vector. Otherwise they will just duplicate in place."
|
||||||
@ -731,8 +724,7 @@ pub async fn pattern_linear_2d(exec_state: &mut ExecState, args: Args) -> Result
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
let sketches =
|
let sketches = inner_pattern_linear_2d(sketches, instances, distance, axis, use_original, exec_state, args).await?;
|
||||||
inner_pattern_linear_2d(sketches, instances, distance.n, axis, use_original, exec_state, args).await?;
|
|
||||||
Ok(sketches.into())
|
Ok(sketches.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -765,18 +757,18 @@ pub async fn pattern_linear_2d(exec_state: &mut ExecState, args: Args) -> Result
|
|||||||
async fn inner_pattern_linear_2d(
|
async fn inner_pattern_linear_2d(
|
||||||
sketches: Vec<Sketch>,
|
sketches: Vec<Sketch>,
|
||||||
instances: u32,
|
instances: u32,
|
||||||
distance: f64,
|
distance: TyF64,
|
||||||
axis: [f64; 2],
|
axis: [TyF64; 2],
|
||||||
use_original: Option<bool>,
|
use_original: Option<bool>,
|
||||||
exec_state: &mut ExecState,
|
exec_state: &mut ExecState,
|
||||||
args: Args,
|
args: Args,
|
||||||
) -> Result<Vec<Sketch>, KclError> {
|
) -> Result<Vec<Sketch>, KclError> {
|
||||||
let [x, y] = axis;
|
let [x, y] = point_to_mm(axis);
|
||||||
let axis_len = f64::sqrt(x * x + y * y);
|
let axis_len = f64::sqrt(x * x + y * y);
|
||||||
let normalized_axis = kcmc::shared::Point2d::from([x / axis_len, y / axis_len]);
|
let normalized_axis = kcmc::shared::Point2d::from([x / axis_len, y / axis_len]);
|
||||||
let transforms: Vec<_> = (1..instances)
|
let transforms: Vec<_> = (1..instances)
|
||||||
.map(|i| {
|
.map(|i| {
|
||||||
let d = distance * (i as f64);
|
let d = distance.to_mm() * (i as f64);
|
||||||
let translate = (normalized_axis * d).with_z(0.0).map(LengthUnit);
|
let translate = (normalized_axis * d).with_z(0.0).map(LengthUnit);
|
||||||
vec![Transform {
|
vec![Transform {
|
||||||
translate,
|
translate,
|
||||||
@ -802,8 +794,7 @@ pub async fn pattern_linear_3d(exec_state: &mut ExecState, args: Args) -> Result
|
|||||||
let axis: [TyF64; 3] = args.get_kw_arg_typed("axis", &RuntimeType::point3d(), exec_state)?;
|
let axis: [TyF64; 3] = args.get_kw_arg_typed("axis", &RuntimeType::point3d(), exec_state)?;
|
||||||
let use_original: Option<bool> = args.get_kw_arg_opt("useOriginal")?;
|
let use_original: Option<bool> = args.get_kw_arg_opt("useOriginal")?;
|
||||||
|
|
||||||
let (axis, _) = untype_point_3d(axis);
|
if axis[0].n == 0.0 && axis[1].n == 0.0 && axis[2].n == 0.0 {
|
||||||
if axis == [0.0, 0.0, 0.0] {
|
|
||||||
return Err(KclError::Semantic(KclErrorDetails {
|
return Err(KclError::Semantic(KclErrorDetails {
|
||||||
message:
|
message:
|
||||||
"The axis of the linear pattern cannot be the zero vector. Otherwise they will just duplicate in place."
|
"The axis of the linear pattern cannot be the zero vector. Otherwise they will just duplicate in place."
|
||||||
@ -812,7 +803,7 @@ pub async fn pattern_linear_3d(exec_state: &mut ExecState, args: Args) -> Result
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
let solids = inner_pattern_linear_3d(solids, instances, distance.n, axis, use_original, exec_state, args).await?;
|
let solids = inner_pattern_linear_3d(solids, instances, distance, axis, use_original, exec_state, args).await?;
|
||||||
Ok(solids.into())
|
Ok(solids.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -903,18 +894,18 @@ pub async fn pattern_linear_3d(exec_state: &mut ExecState, args: Args) -> Result
|
|||||||
async fn inner_pattern_linear_3d(
|
async fn inner_pattern_linear_3d(
|
||||||
solids: Vec<Solid>,
|
solids: Vec<Solid>,
|
||||||
instances: u32,
|
instances: u32,
|
||||||
distance: f64,
|
distance: TyF64,
|
||||||
axis: [f64; 3],
|
axis: [TyF64; 3],
|
||||||
use_original: Option<bool>,
|
use_original: Option<bool>,
|
||||||
exec_state: &mut ExecState,
|
exec_state: &mut ExecState,
|
||||||
args: Args,
|
args: Args,
|
||||||
) -> Result<Vec<Solid>, KclError> {
|
) -> Result<Vec<Solid>, KclError> {
|
||||||
let [x, y, z] = axis;
|
let [x, y, z] = point_3d_to_mm(axis);
|
||||||
let axis_len = f64::sqrt(x * x + y * y + z * z);
|
let axis_len = f64::sqrt(x * x + y * y + z * z);
|
||||||
let normalized_axis = kcmc::shared::Point3d::from([x / axis_len, y / axis_len, z / axis_len]);
|
let normalized_axis = kcmc::shared::Point3d::from([x / axis_len, y / axis_len, z / axis_len]);
|
||||||
let transforms: Vec<_> = (1..instances)
|
let transforms: Vec<_> = (1..instances)
|
||||||
.map(|i| {
|
.map(|i| {
|
||||||
let d = distance * (i as f64);
|
let d = distance.to_mm() * (i as f64);
|
||||||
let translate = (normalized_axis * d).map(LengthUnit);
|
let translate = (normalized_axis * d).map(LengthUnit);
|
||||||
vec![Transform {
|
vec![Transform {
|
||||||
translate,
|
translate,
|
||||||
@ -926,7 +917,7 @@ async fn inner_pattern_linear_3d(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Data for a circular pattern on a 2D sketch.
|
/// Data for a circular pattern on a 2D sketch.
|
||||||
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
|
#[derive(Debug, Clone, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
|
||||||
#[ts(export)]
|
#[ts(export)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
struct CircularPattern2dData {
|
struct CircularPattern2dData {
|
||||||
@ -936,7 +927,7 @@ struct CircularPattern2dData {
|
|||||||
/// If instances is 1, this has no effect.
|
/// If instances is 1, this has no effect.
|
||||||
pub instances: u32,
|
pub instances: u32,
|
||||||
/// The center about which to make the pattern. This is a 2D vector.
|
/// The center about which to make the pattern. This is a 2D vector.
|
||||||
pub center: [f64; 2],
|
pub center: [TyF64; 2],
|
||||||
/// The arc angle (in degrees) to place the repetitions. Must be greater than 0.
|
/// The arc angle (in degrees) to place the repetitions. Must be greater than 0.
|
||||||
pub arc_degrees: f64,
|
pub arc_degrees: f64,
|
||||||
/// Whether or not to rotate the duplicates as they are copied.
|
/// Whether or not to rotate the duplicates as they are copied.
|
||||||
@ -948,7 +939,7 @@ struct CircularPattern2dData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Data for a circular pattern on a 3D model.
|
/// Data for a circular pattern on a 3D model.
|
||||||
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
|
#[derive(Debug, Clone, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
|
||||||
#[ts(export)]
|
#[ts(export)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct CircularPattern3dData {
|
pub struct CircularPattern3dData {
|
||||||
@ -958,9 +949,10 @@ pub struct CircularPattern3dData {
|
|||||||
/// If instances is 1, this has no effect.
|
/// If instances is 1, this has no effect.
|
||||||
pub instances: u32,
|
pub instances: u32,
|
||||||
/// The axis around which to make the pattern. This is a 3D vector.
|
/// The axis around which to make the pattern. This is a 3D vector.
|
||||||
|
// Only the direction should matter, not the magnitude so don't adjust units to avoid normalisation issues.
|
||||||
pub axis: [f64; 3],
|
pub axis: [f64; 3],
|
||||||
/// The center about which to make the pattern. This is a 3D vector.
|
/// The center about which to make the pattern. This is a 3D vector.
|
||||||
pub center: [f64; 3],
|
pub center: [TyF64; 3],
|
||||||
/// The arc angle (in degrees) to place the repetitions. Must be greater than 0.
|
/// The arc angle (in degrees) to place the repetitions. Must be greater than 0.
|
||||||
pub arc_degrees: f64,
|
pub arc_degrees: f64,
|
||||||
/// Whether or not to rotate the duplicates as they are copied.
|
/// Whether or not to rotate the duplicates as they are copied.
|
||||||
@ -971,6 +963,7 @@ pub struct CircularPattern3dData {
|
|||||||
pub use_original: Option<bool>,
|
pub use_original: Option<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::large_enum_variant)]
|
||||||
enum CircularPattern {
|
enum CircularPattern {
|
||||||
ThreeD(CircularPattern3dData),
|
ThreeD(CircularPattern3dData),
|
||||||
TwoD(CircularPattern2dData),
|
TwoD(CircularPattern2dData),
|
||||||
@ -999,14 +992,14 @@ impl CircularPattern {
|
|||||||
pub fn axis(&self) -> [f64; 3] {
|
pub fn axis(&self) -> [f64; 3] {
|
||||||
match self {
|
match self {
|
||||||
CircularPattern::TwoD(_lp) => [0.0, 0.0, 0.0],
|
CircularPattern::TwoD(_lp) => [0.0, 0.0, 0.0],
|
||||||
CircularPattern::ThreeD(lp) => lp.axis,
|
CircularPattern::ThreeD(lp) => [lp.axis[0], lp.axis[1], lp.axis[2]],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn center(&self) -> [f64; 3] {
|
pub fn center_mm(&self) -> [f64; 3] {
|
||||||
match self {
|
match self {
|
||||||
CircularPattern::TwoD(lp) => [lp.center[0], lp.center[1], 0.0],
|
CircularPattern::TwoD(lp) => [lp.center[0].to_mm(), lp.center[1].to_mm(), 0.0],
|
||||||
CircularPattern::ThreeD(lp) => lp.center,
|
CircularPattern::ThreeD(lp) => [lp.center[0].to_mm(), lp.center[1].to_mm(), lp.center[2].to_mm()],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1045,14 +1038,14 @@ pub async fn pattern_circular_2d(exec_state: &mut ExecState, args: Args) -> Resu
|
|||||||
let sketches = args.get_unlabeled_kw_arg_typed("sketches", &RuntimeType::sketches(), exec_state)?;
|
let sketches = args.get_unlabeled_kw_arg_typed("sketches", &RuntimeType::sketches(), exec_state)?;
|
||||||
let instances: u32 = args.get_kw_arg("instances")?;
|
let instances: u32 = args.get_kw_arg("instances")?;
|
||||||
let center: [TyF64; 2] = args.get_kw_arg_typed("center", &RuntimeType::point2d(), exec_state)?;
|
let center: [TyF64; 2] = args.get_kw_arg_typed("center", &RuntimeType::point2d(), exec_state)?;
|
||||||
let arc_degrees: TyF64 = args.get_kw_arg_typed("arcDegrees", &RuntimeType::angle(), exec_state)?;
|
let arc_degrees: TyF64 = args.get_kw_arg_typed("arcDegrees", &RuntimeType::degrees(), exec_state)?;
|
||||||
let rotate_duplicates: bool = args.get_kw_arg("rotateDuplicates")?;
|
let rotate_duplicates: bool = args.get_kw_arg("rotateDuplicates")?;
|
||||||
let use_original: Option<bool> = args.get_kw_arg_opt("useOriginal")?;
|
let use_original: Option<bool> = args.get_kw_arg_opt("useOriginal")?;
|
||||||
|
|
||||||
let sketches = inner_pattern_circular_2d(
|
let sketches = inner_pattern_circular_2d(
|
||||||
sketches,
|
sketches,
|
||||||
instances,
|
instances,
|
||||||
untype_point(center).0,
|
center,
|
||||||
arc_degrees.n,
|
arc_degrees.n,
|
||||||
rotate_duplicates,
|
rotate_duplicates,
|
||||||
use_original,
|
use_original,
|
||||||
@ -1101,7 +1094,7 @@ pub async fn pattern_circular_2d(exec_state: &mut ExecState, args: Args) -> Resu
|
|||||||
async fn inner_pattern_circular_2d(
|
async fn inner_pattern_circular_2d(
|
||||||
sketch_set: Vec<Sketch>,
|
sketch_set: Vec<Sketch>,
|
||||||
instances: u32,
|
instances: u32,
|
||||||
center: [f64; 2],
|
center: [TyF64; 2],
|
||||||
arc_degrees: f64,
|
arc_degrees: f64,
|
||||||
rotate_duplicates: bool,
|
rotate_duplicates: bool,
|
||||||
use_original: Option<bool>,
|
use_original: Option<bool>,
|
||||||
@ -1151,13 +1144,13 @@ pub async fn pattern_circular_3d(exec_state: &mut ExecState, args: Args) -> Resu
|
|||||||
// This includes the original entity. For example, if instances is 2,
|
// This includes the original entity. For example, if instances is 2,
|
||||||
// there will be two copies -- the original, and one new copy.
|
// there will be two copies -- the original, and one new copy.
|
||||||
// If instances is 1, this has no effect.
|
// If instances is 1, this has no effect.
|
||||||
let instances: u32 = args.get_kw_arg("instances")?;
|
let instances: u32 = args.get_kw_arg_typed("instances", &RuntimeType::count(), exec_state)?;
|
||||||
// The axis around which to make the pattern. This is a 3D vector.
|
// The axis around which to make the pattern. This is a 3D vector.
|
||||||
let axis: [TyF64; 3] = args.get_kw_arg_typed("axis", &RuntimeType::point3d(), exec_state)?;
|
let axis: [TyF64; 3] = args.get_kw_arg_typed("axis", &RuntimeType::point3d(), exec_state)?;
|
||||||
// The center about which to make the pattern. This is a 3D vector.
|
// The center about which to make the pattern. This is a 3D vector.
|
||||||
let center: [TyF64; 3] = args.get_kw_arg_typed("center", &RuntimeType::point3d(), exec_state)?;
|
let center: [TyF64; 3] = args.get_kw_arg_typed("center", &RuntimeType::point3d(), exec_state)?;
|
||||||
// The arc angle (in degrees) to place the repetitions. Must be greater than 0.
|
// The arc angle (in degrees) to place the repetitions. Must be greater than 0.
|
||||||
let arc_degrees: TyF64 = args.get_kw_arg_typed("arcDegrees", &RuntimeType::angle(), exec_state)?;
|
let arc_degrees: TyF64 = args.get_kw_arg_typed("arcDegrees", &RuntimeType::degrees(), exec_state)?;
|
||||||
// Whether or not to rotate the duplicates as they are copied.
|
// Whether or not to rotate the duplicates as they are copied.
|
||||||
let rotate_duplicates: bool = args.get_kw_arg("rotateDuplicates")?;
|
let rotate_duplicates: bool = args.get_kw_arg("rotateDuplicates")?;
|
||||||
// If the target being patterned is itself a pattern, then, should you use the original solid,
|
// If the target being patterned is itself a pattern, then, should you use the original solid,
|
||||||
@ -1167,8 +1160,8 @@ pub async fn pattern_circular_3d(exec_state: &mut ExecState, args: Args) -> Resu
|
|||||||
let solids = inner_pattern_circular_3d(
|
let solids = inner_pattern_circular_3d(
|
||||||
solids,
|
solids,
|
||||||
instances,
|
instances,
|
||||||
untype_point_3d(axis).0,
|
[axis[0].n, axis[1].n, axis[2].n],
|
||||||
untype_point_3d(center).0,
|
center,
|
||||||
arc_degrees.n,
|
arc_degrees.n,
|
||||||
rotate_duplicates,
|
rotate_duplicates,
|
||||||
use_original,
|
use_original,
|
||||||
@ -1217,7 +1210,7 @@ async fn inner_pattern_circular_3d(
|
|||||||
solids: Vec<Solid>,
|
solids: Vec<Solid>,
|
||||||
instances: u32,
|
instances: u32,
|
||||||
axis: [f64; 3],
|
axis: [f64; 3],
|
||||||
center: [f64; 3],
|
center: [TyF64; 3],
|
||||||
arc_degrees: f64,
|
arc_degrees: f64,
|
||||||
rotate_duplicates: bool,
|
rotate_duplicates: bool,
|
||||||
use_original: Option<bool>,
|
use_original: Option<bool>,
|
||||||
@ -1286,7 +1279,7 @@ async fn pattern_circular(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let center = data.center();
|
let center = data.center_mm();
|
||||||
let resp = args
|
let resp = args
|
||||||
.send_modeling_cmd(
|
.send_modeling_cmd(
|
||||||
id,
|
id,
|
||||||
|
@ -15,8 +15,7 @@ use crate::{
|
|||||||
pub async fn offset_plane(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
pub async fn offset_plane(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
||||||
let std_plane = args.get_unlabeled_kw_arg("plane")?;
|
let std_plane = args.get_unlabeled_kw_arg("plane")?;
|
||||||
let offset: TyF64 = args.get_kw_arg_typed("offset", &RuntimeType::length(), exec_state)?;
|
let offset: TyF64 = args.get_kw_arg_typed("offset", &RuntimeType::length(), exec_state)?;
|
||||||
let plane = inner_offset_plane(std_plane, offset.n, exec_state).await?;
|
let plane = inner_offset_plane(std_plane, offset, exec_state, &args).await?;
|
||||||
make_offset_plane_in_engine(&plane, exec_state, &args).await?;
|
|
||||||
Ok(KclValue::Plane { value: Box::new(plane) })
|
Ok(KclValue::Plane { value: Box::new(plane) })
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -112,13 +111,19 @@ pub async fn offset_plane(exec_state: &mut ExecState, args: Args) -> Result<KclV
|
|||||||
offset = { docs = "Distance from the standard plane this new plane will be created at." },
|
offset = { docs = "Distance from the standard plane this new plane will be created at." },
|
||||||
}
|
}
|
||||||
}]
|
}]
|
||||||
async fn inner_offset_plane(plane: PlaneData, offset: f64, exec_state: &mut ExecState) -> Result<Plane, KclError> {
|
async fn inner_offset_plane(
|
||||||
|
plane: PlaneData,
|
||||||
|
offset: TyF64,
|
||||||
|
exec_state: &mut ExecState,
|
||||||
|
args: &Args,
|
||||||
|
) -> Result<Plane, KclError> {
|
||||||
let mut plane = Plane::from_plane_data(plane, exec_state);
|
let mut plane = Plane::from_plane_data(plane, exec_state);
|
||||||
// Though offset planes might be derived from standard planes, they are not
|
// Though offset planes might be derived from standard planes, they are not
|
||||||
// standard planes themselves.
|
// standard planes themselves.
|
||||||
plane.value = PlaneType::Custom;
|
plane.value = PlaneType::Custom;
|
||||||
|
|
||||||
plane.origin += plane.z_axis * offset;
|
plane.origin += plane.z_axis * offset.to_length_units(plane.origin.units);
|
||||||
|
make_offset_plane_in_engine(&plane, exec_state, args).await?;
|
||||||
|
|
||||||
Ok(plane)
|
Ok(plane)
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@ use super::{args::TyF64, DEFAULT_TOLERANCE};
|
|||||||
use crate::{
|
use crate::{
|
||||||
errors::{KclError, KclErrorDetails},
|
errors::{KclError, KclErrorDetails},
|
||||||
execution::{
|
execution::{
|
||||||
types::{PrimitiveType, RuntimeType},
|
types::{NumericType, PrimitiveType, RuntimeType},
|
||||||
ExecState, KclValue, Sketch, Solid,
|
ExecState, KclValue, Sketch, Solid,
|
||||||
},
|
},
|
||||||
parsing::ast::types::TagNode,
|
parsing::ast::types::TagNode,
|
||||||
@ -31,8 +31,8 @@ pub async fn revolve(exec_state: &mut ExecState, args: Args) -> Result<KclValue,
|
|||||||
]),
|
]),
|
||||||
exec_state,
|
exec_state,
|
||||||
)?;
|
)?;
|
||||||
let angle: Option<TyF64> = args.get_kw_arg_opt_typed("angle", &RuntimeType::angle(), exec_state)?;
|
let angle: Option<TyF64> = args.get_kw_arg_opt_typed("angle", &RuntimeType::degrees(), exec_state)?;
|
||||||
let tolerance: Option<TyF64> = args.get_kw_arg_opt_typed("tolerance", &RuntimeType::count(), exec_state)?;
|
let tolerance: Option<TyF64> = args.get_kw_arg_opt_typed("tolerance", &RuntimeType::length(), exec_state)?;
|
||||||
let tag_start = args.get_kw_arg_opt("tagStart")?;
|
let tag_start = args.get_kw_arg_opt("tagStart")?;
|
||||||
let tag_end = args.get_kw_arg_opt("tagEnd")?;
|
let tag_end = args.get_kw_arg_opt("tagEnd")?;
|
||||||
let symmetric = args.get_kw_arg_opt("symmetric")?;
|
let symmetric = args.get_kw_arg_opt("symmetric")?;
|
||||||
@ -43,7 +43,7 @@ pub async fn revolve(exec_state: &mut ExecState, args: Args) -> Result<KclValue,
|
|||||||
sketches,
|
sketches,
|
||||||
axis,
|
axis,
|
||||||
angle.map(|t| t.n),
|
angle.map(|t| t.n),
|
||||||
tolerance.map(|t| t.n),
|
tolerance,
|
||||||
tag_start,
|
tag_start,
|
||||||
tag_end,
|
tag_end,
|
||||||
symmetric,
|
symmetric,
|
||||||
@ -60,7 +60,7 @@ async fn inner_revolve(
|
|||||||
sketches: Vec<Sketch>,
|
sketches: Vec<Sketch>,
|
||||||
axis: Axis2dOrEdgeReference,
|
axis: Axis2dOrEdgeReference,
|
||||||
angle: Option<f64>,
|
angle: Option<f64>,
|
||||||
tolerance: Option<f64>,
|
tolerance: Option<TyF64>,
|
||||||
tag_start: Option<TagNode>,
|
tag_start: Option<TagNode>,
|
||||||
tag_end: Option<TagNode>,
|
tag_end: Option<TagNode>,
|
||||||
symmetric: Option<bool>,
|
symmetric: Option<bool>,
|
||||||
@ -140,16 +140,16 @@ async fn inner_revolve(
|
|||||||
angle,
|
angle,
|
||||||
target: sketch.id.into(),
|
target: sketch.id.into(),
|
||||||
axis: Point3d {
|
axis: Point3d {
|
||||||
x: direction[0].n,
|
x: direction[0].to_mm(),
|
||||||
y: direction[1].n,
|
y: direction[1].to_mm(),
|
||||||
z: 0.0,
|
z: 0.0,
|
||||||
},
|
},
|
||||||
origin: Point3d {
|
origin: Point3d {
|
||||||
x: LengthUnit(origin[0].n),
|
x: LengthUnit(origin[0].to_mm()),
|
||||||
y: LengthUnit(origin[1].n),
|
y: LengthUnit(origin[1].to_mm()),
|
||||||
z: LengthUnit(0.0),
|
z: LengthUnit(0.0),
|
||||||
},
|
},
|
||||||
tolerance: LengthUnit(tolerance.unwrap_or(DEFAULT_TOLERANCE)),
|
tolerance: LengthUnit(tolerance.as_ref().map(|t| t.to_mm()).unwrap_or(DEFAULT_TOLERANCE)),
|
||||||
axis_is_2d: true,
|
axis_is_2d: true,
|
||||||
opposite: opposite.clone(),
|
opposite: opposite.clone(),
|
||||||
}),
|
}),
|
||||||
@ -164,7 +164,7 @@ async fn inner_revolve(
|
|||||||
angle,
|
angle,
|
||||||
target: sketch.id.into(),
|
target: sketch.id.into(),
|
||||||
edge_id,
|
edge_id,
|
||||||
tolerance: LengthUnit(tolerance.unwrap_or(DEFAULT_TOLERANCE)),
|
tolerance: LengthUnit(tolerance.as_ref().map(|t| t.to_mm()).unwrap_or(DEFAULT_TOLERANCE)),
|
||||||
opposite: opposite.clone(),
|
opposite: opposite.clone(),
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
@ -176,7 +176,7 @@ async fn inner_revolve(
|
|||||||
do_post_extrude(
|
do_post_extrude(
|
||||||
sketch,
|
sketch,
|
||||||
id.into(),
|
id.into(),
|
||||||
0.0,
|
TyF64::new(0.0, NumericType::mm()),
|
||||||
false,
|
false,
|
||||||
&super::extrude::NamedCapTags {
|
&super::extrude::NamedCapTags {
|
||||||
start: tag_start.as_ref(),
|
start: tag_start.as_ref(),
|
||||||
|
@ -464,7 +464,7 @@ fn inner_segment_angle(tag: &TagIdentifier, exec_state: &mut ExecState, args: Ar
|
|||||||
})
|
})
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
let result = between(path.get_from().into(), path.get_to().into());
|
let result = between(path.get_base().from, path.get_base().to);
|
||||||
|
|
||||||
Ok(result.to_degrees())
|
Ok(result.to_degrees())
|
||||||
}
|
}
|
||||||
@ -584,7 +584,7 @@ async fn inner_tangent_to_end(tag: &TagIdentifier, exec_state: &mut ExecState, a
|
|||||||
/// Returns the angle to match the given length for x.
|
/// Returns the angle to match the given length for x.
|
||||||
pub async fn angle_to_match_length_x(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
pub async fn angle_to_match_length_x(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
||||||
let (tag, to, sketch) = args.get_tag_to_number_sketch()?;
|
let (tag, to, sketch) = args.get_tag_to_number_sketch()?;
|
||||||
let result = inner_angle_to_match_length_x(&tag, to.n, sketch, exec_state, args.clone())?;
|
let result = inner_angle_to_match_length_x(&tag, to, sketch, exec_state, args.clone())?;
|
||||||
Ok(args.make_user_val_from_f64_with_type(TyF64::new(result, NumericType::degrees())))
|
Ok(args.make_user_val_from_f64_with_type(TyF64::new(result, NumericType::degrees())))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -607,7 +607,7 @@ pub async fn angle_to_match_length_x(exec_state: &mut ExecState, args: Args) ->
|
|||||||
}]
|
}]
|
||||||
fn inner_angle_to_match_length_x(
|
fn inner_angle_to_match_length_x(
|
||||||
tag: &TagIdentifier,
|
tag: &TagIdentifier,
|
||||||
to: f64,
|
to: TyF64,
|
||||||
sketch: Sketch,
|
sketch: Sketch,
|
||||||
exec_state: &mut ExecState,
|
exec_state: &mut ExecState,
|
||||||
args: Args,
|
args: Args,
|
||||||
@ -633,8 +633,7 @@ fn inner_angle_to_match_length_x(
|
|||||||
})?
|
})?
|
||||||
.get_base();
|
.get_base();
|
||||||
|
|
||||||
// TODO assumption about the units of to
|
let diff = (to.to_length_units(sketch.units) - last_line.to[0]).abs();
|
||||||
let diff = (to - last_line.to[0]).abs();
|
|
||||||
|
|
||||||
let angle_r = (diff / length).acos();
|
let angle_r = (diff / length).acos();
|
||||||
|
|
||||||
@ -648,7 +647,7 @@ fn inner_angle_to_match_length_x(
|
|||||||
/// Returns the angle to match the given length for y.
|
/// Returns the angle to match the given length for y.
|
||||||
pub async fn angle_to_match_length_y(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
pub async fn angle_to_match_length_y(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
||||||
let (tag, to, sketch) = args.get_tag_to_number_sketch()?;
|
let (tag, to, sketch) = args.get_tag_to_number_sketch()?;
|
||||||
let result = inner_angle_to_match_length_y(&tag, to.n, sketch, exec_state, args.clone())?;
|
let result = inner_angle_to_match_length_y(&tag, to, sketch, exec_state, args.clone())?;
|
||||||
Ok(args.make_user_val_from_f64_with_type(TyF64::new(result, NumericType::degrees())))
|
Ok(args.make_user_val_from_f64_with_type(TyF64::new(result, NumericType::degrees())))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -672,7 +671,7 @@ pub async fn angle_to_match_length_y(exec_state: &mut ExecState, args: Args) ->
|
|||||||
}]
|
}]
|
||||||
fn inner_angle_to_match_length_y(
|
fn inner_angle_to_match_length_y(
|
||||||
tag: &TagIdentifier,
|
tag: &TagIdentifier,
|
||||||
to: f64,
|
to: TyF64,
|
||||||
sketch: Sketch,
|
sketch: Sketch,
|
||||||
exec_state: &mut ExecState,
|
exec_state: &mut ExecState,
|
||||||
args: Args,
|
args: Args,
|
||||||
@ -698,8 +697,7 @@ fn inner_angle_to_match_length_y(
|
|||||||
})?
|
})?
|
||||||
.get_base();
|
.get_base();
|
||||||
|
|
||||||
// TODO assumption about the units of to
|
let diff = (to.to_length_units(sketch.units) - last_line.to[1]).abs();
|
||||||
let diff = (to - last_line.to[1]).abs();
|
|
||||||
|
|
||||||
let angle_r = (diff / length).asin();
|
let angle_r = (diff / length).asin();
|
||||||
|
|
||||||
|
@ -13,10 +13,16 @@ use kittycad_modeling_cmds::shared::PathSegment;
|
|||||||
use schemars::JsonSchema;
|
use schemars::JsonSchema;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
|
||||||
use super::{args::TyF64, utils::untype_point};
|
use super::{
|
||||||
|
args::TyF64,
|
||||||
|
utils::{point_to_len_unit, point_to_mm, point_to_typed, untype_point, untyped_point_to_mm},
|
||||||
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
errors::{KclError, KclErrorDetails},
|
errors::{KclError, KclErrorDetails},
|
||||||
execution::{types::RuntimeType, BasePath, ExecState, GeoMeta, KclValue, Path, Sketch, SketchSurface},
|
execution::{
|
||||||
|
types::{RuntimeType, UnitLen},
|
||||||
|
BasePath, ExecState, GeoMeta, KclValue, Path, Sketch, SketchSurface,
|
||||||
|
},
|
||||||
parsing::ast::types::TagNode,
|
parsing::ast::types::TagNode,
|
||||||
std::{
|
std::{
|
||||||
sketch::NEW_TAG_KW,
|
sketch::NEW_TAG_KW,
|
||||||
@ -41,15 +47,7 @@ pub async fn circle(exec_state: &mut ExecState, args: Args) -> Result<KclValue,
|
|||||||
let radius: TyF64 = args.get_kw_arg_typed("radius", &RuntimeType::length(), exec_state)?;
|
let radius: TyF64 = args.get_kw_arg_typed("radius", &RuntimeType::length(), exec_state)?;
|
||||||
let tag = args.get_kw_arg_opt(NEW_TAG_KW)?;
|
let tag = args.get_kw_arg_opt(NEW_TAG_KW)?;
|
||||||
|
|
||||||
let sketch = inner_circle(
|
let sketch = inner_circle(sketch_or_surface, center, radius, tag, exec_state, args).await?;
|
||||||
sketch_or_surface,
|
|
||||||
untype_point(center).0,
|
|
||||||
radius.n,
|
|
||||||
tag,
|
|
||||||
exec_state,
|
|
||||||
args,
|
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
Ok(KclValue::Sketch {
|
Ok(KclValue::Sketch {
|
||||||
value: Box::new(sketch),
|
value: Box::new(sketch),
|
||||||
})
|
})
|
||||||
@ -57,8 +55,8 @@ pub async fn circle(exec_state: &mut ExecState, args: Args) -> Result<KclValue,
|
|||||||
|
|
||||||
async fn inner_circle(
|
async fn inner_circle(
|
||||||
sketch_or_surface: SketchOrSurface,
|
sketch_or_surface: SketchOrSurface,
|
||||||
center: [f64; 2],
|
center: [TyF64; 2],
|
||||||
radius: f64,
|
radius: TyF64,
|
||||||
tag: Option<TagNode>,
|
tag: Option<TagNode>,
|
||||||
exec_state: &mut ExecState,
|
exec_state: &mut ExecState,
|
||||||
args: Args,
|
args: Args,
|
||||||
@ -67,17 +65,15 @@ async fn inner_circle(
|
|||||||
SketchOrSurface::SketchSurface(surface) => surface,
|
SketchOrSurface::SketchSurface(surface) => surface,
|
||||||
SketchOrSurface::Sketch(s) => s.on,
|
SketchOrSurface::Sketch(s) => s.on,
|
||||||
};
|
};
|
||||||
let units = sketch_surface.units();
|
let (center_u, ty) = untype_point(center.clone());
|
||||||
let sketch = crate::std::sketch::inner_start_profile_at(
|
let units = ty.expect_length();
|
||||||
[center[0] + radius, center[1]],
|
|
||||||
sketch_surface,
|
let from = [center_u[0] + radius.to_length_units(units), center_u[1]];
|
||||||
None,
|
let from_t = [TyF64::new(from[0], ty.clone()), TyF64::new(from[1], ty)];
|
||||||
exec_state,
|
|
||||||
args.clone(),
|
let sketch =
|
||||||
)
|
crate::std::sketch::inner_start_profile_at(from_t, sketch_surface, None, exec_state, args.clone()).await?;
|
||||||
.await?;
|
|
||||||
|
|
||||||
let from = [center[0] + radius, center[1]];
|
|
||||||
let angle_start = Angle::zero();
|
let angle_start = Angle::zero();
|
||||||
let angle_end = Angle::turn();
|
let angle_end = Angle::turn();
|
||||||
|
|
||||||
@ -90,8 +86,8 @@ async fn inner_circle(
|
|||||||
segment: PathSegment::Arc {
|
segment: PathSegment::Arc {
|
||||||
start: angle_start,
|
start: angle_start,
|
||||||
end: angle_end,
|
end: angle_end,
|
||||||
center: KPoint2d::from(center).map(LengthUnit),
|
center: KPoint2d::from(point_to_mm(center)).map(LengthUnit),
|
||||||
radius: radius.into(),
|
radius: LengthUnit(radius.to_mm()),
|
||||||
relative: false,
|
relative: false,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
@ -109,8 +105,8 @@ async fn inner_circle(
|
|||||||
metadata: args.source_range.into(),
|
metadata: args.source_range.into(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
radius,
|
radius: radius.to_length_units(units),
|
||||||
center,
|
center: center_u,
|
||||||
ccw: angle_start < angle_end,
|
ccw: angle_start < angle_end,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -135,16 +131,7 @@ pub async fn circle_three_point(exec_state: &mut ExecState, args: Args) -> Resul
|
|||||||
let p3 = args.get_kw_arg_typed("p3", &RuntimeType::point2d(), exec_state)?;
|
let p3 = args.get_kw_arg_typed("p3", &RuntimeType::point2d(), exec_state)?;
|
||||||
let tag = args.get_kw_arg_opt("tag")?;
|
let tag = args.get_kw_arg_opt("tag")?;
|
||||||
|
|
||||||
let sketch = inner_circle_three_point(
|
let sketch = inner_circle_three_point(sketch_surface_or_group, p1, p2, p3, tag, exec_state, args).await?;
|
||||||
sketch_surface_or_group,
|
|
||||||
untype_point(p1).0,
|
|
||||||
untype_point(p2).0,
|
|
||||||
untype_point(p3).0,
|
|
||||||
tag,
|
|
||||||
exec_state,
|
|
||||||
args,
|
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
Ok(KclValue::Sketch {
|
Ok(KclValue::Sketch {
|
||||||
value: Box::new(sketch),
|
value: Box::new(sketch),
|
||||||
})
|
})
|
||||||
@ -174,13 +161,20 @@ pub async fn circle_three_point(exec_state: &mut ExecState, args: Args) -> Resul
|
|||||||
// path so it can be used for other features, otherwise it's lost.
|
// path so it can be used for other features, otherwise it's lost.
|
||||||
async fn inner_circle_three_point(
|
async fn inner_circle_three_point(
|
||||||
sketch_surface_or_group: SketchOrSurface,
|
sketch_surface_or_group: SketchOrSurface,
|
||||||
p1: [f64; 2],
|
p1: [TyF64; 2],
|
||||||
p2: [f64; 2],
|
p2: [TyF64; 2],
|
||||||
p3: [f64; 2],
|
p3: [TyF64; 2],
|
||||||
tag: Option<TagNode>,
|
tag: Option<TagNode>,
|
||||||
exec_state: &mut ExecState,
|
exec_state: &mut ExecState,
|
||||||
args: Args,
|
args: Args,
|
||||||
) -> Result<Sketch, KclError> {
|
) -> Result<Sketch, KclError> {
|
||||||
|
let ty = p1[0].ty.clone();
|
||||||
|
let units = ty.expect_length();
|
||||||
|
|
||||||
|
let p1 = point_to_len_unit(p1, units);
|
||||||
|
let p2 = point_to_len_unit(p2, units);
|
||||||
|
let p3 = point_to_len_unit(p3, units);
|
||||||
|
|
||||||
let center = calculate_circle_center(p1, p2, p3);
|
let center = calculate_circle_center(p1, p2, p3);
|
||||||
// It can be the distance to any of the 3 points - they all lay on the circumference.
|
// It can be the distance to any of the 3 points - they all lay on the circumference.
|
||||||
let radius = distance(center, p2);
|
let radius = distance(center, p2);
|
||||||
@ -189,16 +183,15 @@ async fn inner_circle_three_point(
|
|||||||
SketchOrSurface::SketchSurface(surface) => surface,
|
SketchOrSurface::SketchSurface(surface) => surface,
|
||||||
SketchOrSurface::Sketch(group) => group.on,
|
SketchOrSurface::Sketch(group) => group.on,
|
||||||
};
|
};
|
||||||
let sketch = crate::std::sketch::inner_start_profile_at(
|
|
||||||
[center[0] + radius, center[1]],
|
|
||||||
sketch_surface,
|
|
||||||
None,
|
|
||||||
exec_state,
|
|
||||||
args.clone(),
|
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
let from = [center[0] + radius, center[1]];
|
let from = [
|
||||||
|
TyF64::new(center[0] + radius, ty.clone()),
|
||||||
|
TyF64::new(center[1], ty.clone()),
|
||||||
|
];
|
||||||
|
let sketch =
|
||||||
|
crate::std::sketch::inner_start_profile_at(from.clone(), sketch_surface, None, exec_state, args.clone())
|
||||||
|
.await?;
|
||||||
|
|
||||||
let angle_start = Angle::zero();
|
let angle_start = Angle::zero();
|
||||||
let angle_end = Angle::turn();
|
let angle_end = Angle::turn();
|
||||||
|
|
||||||
@ -211,8 +204,8 @@ async fn inner_circle_three_point(
|
|||||||
segment: PathSegment::Arc {
|
segment: PathSegment::Arc {
|
||||||
start: angle_start,
|
start: angle_start,
|
||||||
end: angle_end,
|
end: angle_end,
|
||||||
center: KPoint2d::from(center).map(LengthUnit),
|
center: KPoint2d::from(untyped_point_to_mm(center, units)).map(LengthUnit),
|
||||||
radius: radius.into(),
|
radius: units.adjust_to(radius, UnitLen::Mm).0.into(),
|
||||||
relative: false,
|
relative: false,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
@ -221,10 +214,11 @@ async fn inner_circle_three_point(
|
|||||||
|
|
||||||
let current_path = Path::CircleThreePoint {
|
let current_path = Path::CircleThreePoint {
|
||||||
base: BasePath {
|
base: BasePath {
|
||||||
from,
|
// It's fine to untype here because we know `from` has units as its units.
|
||||||
to: from,
|
from: untype_point(from.clone()).0,
|
||||||
|
to: untype_point(from).0,
|
||||||
tag: tag.clone(),
|
tag: tag.clone(),
|
||||||
units: sketch.units,
|
units,
|
||||||
geo_meta: GeoMeta {
|
geo_meta: GeoMeta {
|
||||||
id,
|
id,
|
||||||
metadata: args.source_range.into(),
|
metadata: args.source_range.into(),
|
||||||
@ -270,7 +264,7 @@ pub async fn polygon(exec_state: &mut ExecState, args: Args) -> Result<KclValue,
|
|||||||
sketch_surface_or_group,
|
sketch_surface_or_group,
|
||||||
radius,
|
radius,
|
||||||
num_sides.n as u64,
|
num_sides.n as u64,
|
||||||
untype_point(center).0,
|
center,
|
||||||
inscribed,
|
inscribed,
|
||||||
exec_state,
|
exec_state,
|
||||||
args,
|
args,
|
||||||
@ -324,7 +318,7 @@ async fn inner_polygon(
|
|||||||
sketch_surface_or_group: SketchOrSurface,
|
sketch_surface_or_group: SketchOrSurface,
|
||||||
radius: TyF64,
|
radius: TyF64,
|
||||||
num_sides: u64,
|
num_sides: u64,
|
||||||
center: [f64; 2],
|
center: [TyF64; 2],
|
||||||
inscribed: Option<bool>,
|
inscribed: Option<bool>,
|
||||||
exec_state: &mut ExecState,
|
exec_state: &mut ExecState,
|
||||||
args: Args,
|
args: Args,
|
||||||
@ -343,9 +337,9 @@ async fn inner_polygon(
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
let sketch_surface = match sketch_surface_or_group {
|
let (sketch_surface, units) = match sketch_surface_or_group {
|
||||||
SketchOrSurface::SketchSurface(surface) => surface,
|
SketchOrSurface::SketchSurface(surface) => (surface, radius.ty.expect_length()),
|
||||||
SketchOrSurface::Sketch(group) => group.on,
|
SketchOrSurface::Sketch(group) => (group.on, group.units),
|
||||||
};
|
};
|
||||||
|
|
||||||
let half_angle = std::f64::consts::PI / num_sides as f64;
|
let half_angle = std::f64::consts::PI / num_sides as f64;
|
||||||
@ -360,18 +354,26 @@ async fn inner_polygon(
|
|||||||
|
|
||||||
let angle_step = std::f64::consts::TAU / num_sides as f64;
|
let angle_step = std::f64::consts::TAU / num_sides as f64;
|
||||||
|
|
||||||
|
let center_u = point_to_len_unit(center, units);
|
||||||
|
|
||||||
let vertices: Vec<[f64; 2]> = (0..num_sides)
|
let vertices: Vec<[f64; 2]> = (0..num_sides)
|
||||||
.map(|i| {
|
.map(|i| {
|
||||||
let angle = angle_step * i as f64;
|
let angle = angle_step * i as f64;
|
||||||
[
|
[
|
||||||
center[0] + radius_to_vertices * angle.cos(),
|
center_u[0] + radius_to_vertices * angle.cos(),
|
||||||
center[1] + radius_to_vertices * angle.sin(),
|
center_u[1] + radius_to_vertices * angle.sin(),
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let mut sketch =
|
let mut sketch = crate::std::sketch::inner_start_profile_at(
|
||||||
crate::std::sketch::inner_start_profile_at(vertices[0], sketch_surface, None, exec_state, args.clone()).await?;
|
point_to_typed(vertices[0], units),
|
||||||
|
sketch_surface,
|
||||||
|
None,
|
||||||
|
exec_state,
|
||||||
|
args.clone(),
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
// Draw all the lines with unique IDs and modified tags
|
// Draw all the lines with unique IDs and modified tags
|
||||||
for vertex in vertices.iter().skip(1) {
|
for vertex in vertices.iter().skip(1) {
|
||||||
@ -383,7 +385,9 @@ async fn inner_polygon(
|
|||||||
ModelingCmd::from(mcmd::ExtendPath {
|
ModelingCmd::from(mcmd::ExtendPath {
|
||||||
path: sketch.id.into(),
|
path: sketch.id.into(),
|
||||||
segment: PathSegment::Line {
|
segment: PathSegment::Line {
|
||||||
end: KPoint2d::from(*vertex).with_z(0.0).map(LengthUnit),
|
end: KPoint2d::from(untyped_point_to_mm(*vertex, units))
|
||||||
|
.with_z(0.0)
|
||||||
|
.map(LengthUnit),
|
||||||
relative: false,
|
relative: false,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
@ -392,7 +396,7 @@ async fn inner_polygon(
|
|||||||
|
|
||||||
let current_path = Path::ToPoint {
|
let current_path = Path::ToPoint {
|
||||||
base: BasePath {
|
base: BasePath {
|
||||||
from: from.into(),
|
from: from.ignore_units(),
|
||||||
to: *vertex,
|
to: *vertex,
|
||||||
tag: None,
|
tag: None,
|
||||||
units: sketch.units,
|
units: sketch.units,
|
||||||
@ -415,7 +419,9 @@ async fn inner_polygon(
|
|||||||
ModelingCmd::from(mcmd::ExtendPath {
|
ModelingCmd::from(mcmd::ExtendPath {
|
||||||
path: sketch.id.into(),
|
path: sketch.id.into(),
|
||||||
segment: PathSegment::Line {
|
segment: PathSegment::Line {
|
||||||
end: KPoint2d::from(vertices[0]).with_z(0.0).map(LengthUnit),
|
end: KPoint2d::from(untyped_point_to_mm(vertices[0], units))
|
||||||
|
.with_z(0.0)
|
||||||
|
.map(LengthUnit),
|
||||||
relative: false,
|
relative: false,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
@ -424,7 +430,7 @@ async fn inner_polygon(
|
|||||||
|
|
||||||
let current_path = Path::ToPoint {
|
let current_path = Path::ToPoint {
|
||||||
base: BasePath {
|
base: BasePath {
|
||||||
from: from.into(),
|
from: from.ignore_units(),
|
||||||
to: vertices[0],
|
to: vertices[0],
|
||||||
tag: None,
|
tag: None,
|
||||||
units: sketch.units,
|
units: sketch.units,
|
||||||
|
@ -16,10 +16,10 @@ use super::args::TyF64;
|
|||||||
/// Create a shell.
|
/// Create a shell.
|
||||||
pub async fn shell(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
pub async fn shell(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
||||||
let solids = args.get_unlabeled_kw_arg_typed("solids", &RuntimeType::solids(), exec_state)?;
|
let solids = args.get_unlabeled_kw_arg_typed("solids", &RuntimeType::solids(), exec_state)?;
|
||||||
let thickness: TyF64 = args.get_kw_arg_typed("thickness", &RuntimeType::count(), exec_state)?;
|
let thickness: TyF64 = args.get_kw_arg_typed("thickness", &RuntimeType::length(), exec_state)?;
|
||||||
let faces = args.get_kw_arg("faces")?;
|
let faces = args.get_kw_arg("faces")?;
|
||||||
|
|
||||||
let result = inner_shell(solids, thickness.n, faces, exec_state, args).await?;
|
let result = inner_shell(solids, thickness, faces, exec_state, args).await?;
|
||||||
Ok(result.into())
|
Ok(result.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -182,7 +182,7 @@ pub async fn shell(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K
|
|||||||
}]
|
}]
|
||||||
async fn inner_shell(
|
async fn inner_shell(
|
||||||
solids: Vec<Solid>,
|
solids: Vec<Solid>,
|
||||||
thickness: f64,
|
thickness: TyF64,
|
||||||
faces: Vec<FaceTag>,
|
faces: Vec<FaceTag>,
|
||||||
exec_state: &mut ExecState,
|
exec_state: &mut ExecState,
|
||||||
args: Args,
|
args: Args,
|
||||||
@ -237,7 +237,7 @@ async fn inner_shell(
|
|||||||
hollow: false,
|
hollow: false,
|
||||||
face_ids,
|
face_ids,
|
||||||
object_id: solids[0].id,
|
object_id: solids[0].id,
|
||||||
shell_thickness: LengthUnit(thickness),
|
shell_thickness: LengthUnit(thickness.to_mm()),
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
@ -247,9 +247,9 @@ async fn inner_shell(
|
|||||||
|
|
||||||
/// Make the inside of a 3D object hollow.
|
/// Make the inside of a 3D object hollow.
|
||||||
pub async fn hollow(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
pub async fn hollow(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
||||||
let (thickness, solid) = args.get_data_and_solid(exec_state)?;
|
let (thickness, solid) = args.get_length_and_solid(exec_state)?;
|
||||||
|
|
||||||
let value = inner_hollow(thickness.n, solid, exec_state, args).await?;
|
let value = inner_hollow(thickness, solid, exec_state, args).await?;
|
||||||
Ok(KclValue::Solid { value })
|
Ok(KclValue::Solid { value })
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -308,7 +308,7 @@ pub async fn hollow(exec_state: &mut ExecState, args: Args) -> Result<KclValue,
|
|||||||
feature_tree_operation = true,
|
feature_tree_operation = true,
|
||||||
}]
|
}]
|
||||||
async fn inner_hollow(
|
async fn inner_hollow(
|
||||||
thickness: f64,
|
thickness: TyF64,
|
||||||
solid: Box<Solid>,
|
solid: Box<Solid>,
|
||||||
exec_state: &mut ExecState,
|
exec_state: &mut ExecState,
|
||||||
args: Args,
|
args: Args,
|
||||||
@ -323,7 +323,7 @@ async fn inner_hollow(
|
|||||||
hollow: true,
|
hollow: true,
|
||||||
face_ids: Vec::new(), // This is empty because we want to hollow the entire object.
|
face_ids: Vec::new(), // This is empty because we want to hollow the entire object.
|
||||||
object_id: solid.id,
|
object_id: solid.id,
|
||||||
shell_thickness: LengthUnit(thickness),
|
shell_thickness: LengthUnit(thickness.to_mm()),
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
@ -12,11 +12,11 @@ use parse_display::{Display, FromStr};
|
|||||||
use schemars::JsonSchema;
|
use schemars::JsonSchema;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use super::utils::untype_point;
|
use super::utils::{point_to_len_unit, point_to_mm, untype_point, untyped_point_to_mm};
|
||||||
use crate::{
|
use crate::{
|
||||||
errors::{KclError, KclErrorDetails},
|
errors::{KclError, KclErrorDetails},
|
||||||
execution::{
|
execution::{
|
||||||
types::{PrimitiveType, RuntimeType, UnitLen},
|
types::{NumericType, PrimitiveType, RuntimeType, UnitLen},
|
||||||
Artifact, ArtifactId, BasePath, CodeRef, ExecState, Face, GeoMeta, KclValue, Path, Plane, Point2d, Point3d,
|
Artifact, ArtifactId, BasePath, CodeRef, ExecState, Face, GeoMeta, KclValue, Path, Plane, Point2d, Point3d,
|
||||||
Sketch, SketchSurface, Solid, StartSketchOnFace, StartSketchOnPlane, TagEngineInfo, TagIdentifier,
|
Sketch, SketchSurface, Solid, StartSketchOnFace, StartSketchOnPlane, TagEngineInfo, TagIdentifier,
|
||||||
},
|
},
|
||||||
@ -200,7 +200,7 @@ async fn inner_involute_circular(
|
|||||||
|
|
||||||
let current_path = Path::ToPoint {
|
let current_path = Path::ToPoint {
|
||||||
base: BasePath {
|
base: BasePath {
|
||||||
from: from.into(),
|
from: from.ignore_units(),
|
||||||
to: [end.x, end.y],
|
to: [end.x, end.y],
|
||||||
tag: tag.clone(),
|
tag: tag.clone(),
|
||||||
units: sketch.units,
|
units: sketch.units,
|
||||||
@ -226,15 +226,7 @@ pub async fn line(exec_state: &mut ExecState, args: Args) -> Result<KclValue, Kc
|
|||||||
let end_absolute = args.get_kw_arg_opt_typed("endAbsolute", &RuntimeType::point2d(), exec_state)?;
|
let end_absolute = args.get_kw_arg_opt_typed("endAbsolute", &RuntimeType::point2d(), exec_state)?;
|
||||||
let tag = args.get_kw_arg_opt(NEW_TAG_KW)?;
|
let tag = args.get_kw_arg_opt(NEW_TAG_KW)?;
|
||||||
|
|
||||||
let new_sketch = inner_line(
|
let new_sketch = inner_line(sketch, end_absolute, end, tag, exec_state, args).await?;
|
||||||
sketch,
|
|
||||||
end_absolute.map(|p| untype_point(p).0),
|
|
||||||
end.map(|p| untype_point(p).0),
|
|
||||||
tag,
|
|
||||||
exec_state,
|
|
||||||
args,
|
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
Ok(KclValue::Sketch {
|
Ok(KclValue::Sketch {
|
||||||
value: Box::new(new_sketch),
|
value: Box::new(new_sketch),
|
||||||
})
|
})
|
||||||
@ -277,8 +269,8 @@ pub async fn line(exec_state: &mut ExecState, args: Args) -> Result<KclValue, Kc
|
|||||||
}]
|
}]
|
||||||
async fn inner_line(
|
async fn inner_line(
|
||||||
sketch: Sketch,
|
sketch: Sketch,
|
||||||
end_absolute: Option<[f64; 2]>,
|
end_absolute: Option<[TyF64; 2]>,
|
||||||
end: Option<[f64; 2]>,
|
end: Option<[TyF64; 2]>,
|
||||||
tag: Option<TagNode>,
|
tag: Option<TagNode>,
|
||||||
exec_state: &mut ExecState,
|
exec_state: &mut ExecState,
|
||||||
args: Args,
|
args: Args,
|
||||||
@ -298,13 +290,13 @@ async fn inner_line(
|
|||||||
|
|
||||||
struct StraightLineParams {
|
struct StraightLineParams {
|
||||||
sketch: Sketch,
|
sketch: Sketch,
|
||||||
end_absolute: Option<[f64; 2]>,
|
end_absolute: Option<[TyF64; 2]>,
|
||||||
end: Option<[f64; 2]>,
|
end: Option<[TyF64; 2]>,
|
||||||
tag: Option<TagNode>,
|
tag: Option<TagNode>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl StraightLineParams {
|
impl StraightLineParams {
|
||||||
fn relative(p: [f64; 2], sketch: Sketch, tag: Option<TagNode>) -> Self {
|
fn relative(p: [TyF64; 2], sketch: Sketch, tag: Option<TagNode>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
sketch,
|
sketch,
|
||||||
tag,
|
tag,
|
||||||
@ -312,7 +304,7 @@ impl StraightLineParams {
|
|||||||
end_absolute: None,
|
end_absolute: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn absolute(p: [f64; 2], sketch: Sketch, tag: Option<TagNode>) -> Self {
|
fn absolute(p: [TyF64; 2], sketch: Sketch, tag: Option<TagNode>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
sketch,
|
sketch,
|
||||||
tag,
|
tag,
|
||||||
@ -357,7 +349,7 @@ async fn straight_line(
|
|||||||
ModelingCmd::from(mcmd::ExtendPath {
|
ModelingCmd::from(mcmd::ExtendPath {
|
||||||
path: sketch.id.into(),
|
path: sketch.id.into(),
|
||||||
segment: PathSegment::Line {
|
segment: PathSegment::Line {
|
||||||
end: KPoint2d::from(point).with_z(0.0).map(LengthUnit),
|
end: KPoint2d::from(point_to_mm(point.clone())).with_z(0.0).map(LengthUnit),
|
||||||
relative: !is_absolute,
|
relative: !is_absolute,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
@ -365,15 +357,16 @@ async fn straight_line(
|
|||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
let end = if is_absolute {
|
let end = if is_absolute {
|
||||||
point
|
point_to_len_unit(point, from.units)
|
||||||
} else {
|
} else {
|
||||||
let from = sketch.current_pen_position()?;
|
let from = sketch.current_pen_position()?;
|
||||||
|
let point = point_to_len_unit(point, from.units);
|
||||||
[from.x + point[0], from.y + point[1]]
|
[from.x + point[0], from.y + point[1]]
|
||||||
};
|
};
|
||||||
|
|
||||||
let current_path = Path::ToPoint {
|
let current_path = Path::ToPoint {
|
||||||
base: BasePath {
|
base: BasePath {
|
||||||
from: from.into(),
|
from: from.ignore_units(),
|
||||||
to: end,
|
to: end,
|
||||||
tag: tag.clone(),
|
tag: tag.clone(),
|
||||||
units: sketch.units,
|
units: sketch.units,
|
||||||
@ -402,15 +395,7 @@ pub async fn x_line(exec_state: &mut ExecState, args: Args) -> Result<KclValue,
|
|||||||
let end_absolute: Option<TyF64> = args.get_kw_arg_opt_typed("endAbsolute", &RuntimeType::length(), exec_state)?;
|
let end_absolute: Option<TyF64> = args.get_kw_arg_opt_typed("endAbsolute", &RuntimeType::length(), exec_state)?;
|
||||||
let tag = args.get_kw_arg_opt(NEW_TAG_KW)?;
|
let tag = args.get_kw_arg_opt(NEW_TAG_KW)?;
|
||||||
|
|
||||||
let new_sketch = inner_x_line(
|
let new_sketch = inner_x_line(sketch, length, end_absolute, tag, exec_state, args).await?;
|
||||||
sketch,
|
|
||||||
length.map(|t| t.n),
|
|
||||||
end_absolute.map(|t| t.n),
|
|
||||||
tag,
|
|
||||||
exec_state,
|
|
||||||
args,
|
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
Ok(KclValue::Sketch {
|
Ok(KclValue::Sketch {
|
||||||
value: Box::new(new_sketch),
|
value: Box::new(new_sketch),
|
||||||
})
|
})
|
||||||
@ -451,8 +436,8 @@ pub async fn x_line(exec_state: &mut ExecState, args: Args) -> Result<KclValue,
|
|||||||
}]
|
}]
|
||||||
async fn inner_x_line(
|
async fn inner_x_line(
|
||||||
sketch: Sketch,
|
sketch: Sketch,
|
||||||
length: Option<f64>,
|
length: Option<TyF64>,
|
||||||
end_absolute: Option<f64>,
|
end_absolute: Option<TyF64>,
|
||||||
tag: Option<TagNode>,
|
tag: Option<TagNode>,
|
||||||
exec_state: &mut ExecState,
|
exec_state: &mut ExecState,
|
||||||
args: Args,
|
args: Args,
|
||||||
@ -461,8 +446,8 @@ async fn inner_x_line(
|
|||||||
straight_line(
|
straight_line(
|
||||||
StraightLineParams {
|
StraightLineParams {
|
||||||
sketch,
|
sketch,
|
||||||
end_absolute: end_absolute.map(|x| [x, from.y]),
|
end_absolute: end_absolute.map(|x| [x, from.into_y()]),
|
||||||
end: length.map(|x| [x, 0.0]),
|
end: length.map(|x| [x, TyF64::new(0.0, NumericType::mm())]),
|
||||||
tag,
|
tag,
|
||||||
},
|
},
|
||||||
exec_state,
|
exec_state,
|
||||||
@ -479,15 +464,7 @@ pub async fn y_line(exec_state: &mut ExecState, args: Args) -> Result<KclValue,
|
|||||||
let end_absolute: Option<TyF64> = args.get_kw_arg_opt_typed("endAbsolute", &RuntimeType::length(), exec_state)?;
|
let end_absolute: Option<TyF64> = args.get_kw_arg_opt_typed("endAbsolute", &RuntimeType::length(), exec_state)?;
|
||||||
let tag = args.get_kw_arg_opt(NEW_TAG_KW)?;
|
let tag = args.get_kw_arg_opt(NEW_TAG_KW)?;
|
||||||
|
|
||||||
let new_sketch = inner_y_line(
|
let new_sketch = inner_y_line(sketch, length, end_absolute, tag, exec_state, args).await?;
|
||||||
sketch,
|
|
||||||
length.map(|t| t.n),
|
|
||||||
end_absolute.map(|t| t.n),
|
|
||||||
tag,
|
|
||||||
exec_state,
|
|
||||||
args,
|
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
Ok(KclValue::Sketch {
|
Ok(KclValue::Sketch {
|
||||||
value: Box::new(new_sketch),
|
value: Box::new(new_sketch),
|
||||||
})
|
})
|
||||||
@ -523,8 +500,8 @@ pub async fn y_line(exec_state: &mut ExecState, args: Args) -> Result<KclValue,
|
|||||||
}]
|
}]
|
||||||
async fn inner_y_line(
|
async fn inner_y_line(
|
||||||
sketch: Sketch,
|
sketch: Sketch,
|
||||||
length: Option<f64>,
|
length: Option<TyF64>,
|
||||||
end_absolute: Option<f64>,
|
end_absolute: Option<TyF64>,
|
||||||
tag: Option<TagNode>,
|
tag: Option<TagNode>,
|
||||||
exec_state: &mut ExecState,
|
exec_state: &mut ExecState,
|
||||||
args: Args,
|
args: Args,
|
||||||
@ -533,8 +510,8 @@ async fn inner_y_line(
|
|||||||
straight_line(
|
straight_line(
|
||||||
StraightLineParams {
|
StraightLineParams {
|
||||||
sketch,
|
sketch,
|
||||||
end_absolute: end_absolute.map(|y| [from.x, y]),
|
end_absolute: end_absolute.map(|y| [from.into_x(), y]),
|
||||||
end: length.map(|y| [0.0, y]),
|
end: length.map(|y| [TyF64::new(0.0, NumericType::mm()), y]),
|
||||||
tag,
|
tag,
|
||||||
},
|
},
|
||||||
exec_state,
|
exec_state,
|
||||||
@ -559,11 +536,11 @@ pub async fn angled_line(exec_state: &mut ExecState, args: Args) -> Result<KclVa
|
|||||||
let new_sketch = inner_angled_line(
|
let new_sketch = inner_angled_line(
|
||||||
sketch,
|
sketch,
|
||||||
angle.n,
|
angle.n,
|
||||||
length.map(|t| t.n),
|
length,
|
||||||
length_x.map(|t| t.n),
|
length_x,
|
||||||
length_y.map(|t| t.n),
|
length_y,
|
||||||
end_absolute_x.map(|t| t.n),
|
end_absolute_x,
|
||||||
end_absolute_y.map(|t| t.n),
|
end_absolute_y,
|
||||||
tag,
|
tag,
|
||||||
exec_state,
|
exec_state,
|
||||||
args,
|
args,
|
||||||
@ -610,16 +587,16 @@ pub async fn angled_line(exec_state: &mut ExecState, args: Args) -> Result<KclVa
|
|||||||
async fn inner_angled_line(
|
async fn inner_angled_line(
|
||||||
sketch: Sketch,
|
sketch: Sketch,
|
||||||
angle: f64,
|
angle: f64,
|
||||||
length: Option<f64>,
|
length: Option<TyF64>,
|
||||||
length_x: Option<f64>,
|
length_x: Option<TyF64>,
|
||||||
length_y: Option<f64>,
|
length_y: Option<TyF64>,
|
||||||
end_absolute_x: Option<f64>,
|
end_absolute_x: Option<TyF64>,
|
||||||
end_absolute_y: Option<f64>,
|
end_absolute_y: Option<TyF64>,
|
||||||
tag: Option<TagNode>,
|
tag: Option<TagNode>,
|
||||||
exec_state: &mut ExecState,
|
exec_state: &mut ExecState,
|
||||||
args: Args,
|
args: Args,
|
||||||
) -> Result<Sketch, KclError> {
|
) -> Result<Sketch, KclError> {
|
||||||
let options_given = [length, length_x, length_y, end_absolute_x, end_absolute_y]
|
let options_given = [&length, &length_x, &length_y, &end_absolute_x, &end_absolute_y]
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|x| x.is_some())
|
.filter(|x| x.is_some())
|
||||||
.count();
|
.count();
|
||||||
@ -667,12 +644,13 @@ async fn inner_angled_line(
|
|||||||
async fn inner_angled_line_length(
|
async fn inner_angled_line_length(
|
||||||
sketch: Sketch,
|
sketch: Sketch,
|
||||||
angle_degrees: f64,
|
angle_degrees: f64,
|
||||||
length: f64,
|
length: TyF64,
|
||||||
tag: Option<TagNode>,
|
tag: Option<TagNode>,
|
||||||
exec_state: &mut ExecState,
|
exec_state: &mut ExecState,
|
||||||
args: Args,
|
args: Args,
|
||||||
) -> Result<Sketch, KclError> {
|
) -> Result<Sketch, KclError> {
|
||||||
let from = sketch.current_pen_position()?;
|
let from = sketch.current_pen_position()?;
|
||||||
|
let length = length.to_length_units(from.units);
|
||||||
|
|
||||||
//double check me on this one - mike
|
//double check me on this one - mike
|
||||||
let delta: [f64; 2] = [
|
let delta: [f64; 2] = [
|
||||||
@ -690,7 +668,9 @@ async fn inner_angled_line_length(
|
|||||||
ModelingCmd::from(mcmd::ExtendPath {
|
ModelingCmd::from(mcmd::ExtendPath {
|
||||||
path: sketch.id.into(),
|
path: sketch.id.into(),
|
||||||
segment: PathSegment::Line {
|
segment: PathSegment::Line {
|
||||||
end: KPoint2d::from(delta).with_z(0.0).map(LengthUnit),
|
end: KPoint2d::from(untyped_point_to_mm(delta, from.units))
|
||||||
|
.with_z(0.0)
|
||||||
|
.map(LengthUnit),
|
||||||
relative,
|
relative,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
@ -699,7 +679,7 @@ async fn inner_angled_line_length(
|
|||||||
|
|
||||||
let current_path = Path::ToPoint {
|
let current_path = Path::ToPoint {
|
||||||
base: BasePath {
|
base: BasePath {
|
||||||
from: from.into(),
|
from: from.ignore_units(),
|
||||||
to,
|
to,
|
||||||
tag: tag.clone(),
|
tag: tag.clone(),
|
||||||
units: sketch.units,
|
units: sketch.units,
|
||||||
@ -721,7 +701,7 @@ async fn inner_angled_line_length(
|
|||||||
|
|
||||||
async fn inner_angled_line_of_x_length(
|
async fn inner_angled_line_of_x_length(
|
||||||
angle_degrees: f64,
|
angle_degrees: f64,
|
||||||
length: f64,
|
length: TyF64,
|
||||||
sketch: Sketch,
|
sketch: Sketch,
|
||||||
tag: Option<TagNode>,
|
tag: Option<TagNode>,
|
||||||
exec_state: &mut ExecState,
|
exec_state: &mut ExecState,
|
||||||
@ -741,7 +721,8 @@ async fn inner_angled_line_of_x_length(
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
let to = get_y_component(Angle::from_degrees(angle_degrees), length);
|
let to = get_y_component(Angle::from_degrees(angle_degrees), length.n);
|
||||||
|
let to = [TyF64::new(to[0], length.ty.clone()), TyF64::new(to[1], length.ty)];
|
||||||
|
|
||||||
let new_sketch = straight_line(StraightLineParams::relative(to, sketch, tag), exec_state, args).await?;
|
let new_sketch = straight_line(StraightLineParams::relative(to, sketch, tag), exec_state, args).await?;
|
||||||
|
|
||||||
@ -750,7 +731,7 @@ async fn inner_angled_line_of_x_length(
|
|||||||
|
|
||||||
async fn inner_angled_line_to_x(
|
async fn inner_angled_line_to_x(
|
||||||
angle_degrees: f64,
|
angle_degrees: f64,
|
||||||
x_to: f64,
|
x_to: TyF64,
|
||||||
sketch: Sketch,
|
sketch: Sketch,
|
||||||
tag: Option<TagNode>,
|
tag: Option<TagNode>,
|
||||||
exec_state: &mut ExecState,
|
exec_state: &mut ExecState,
|
||||||
@ -772,12 +753,12 @@ async fn inner_angled_line_to_x(
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
let x_component = x_to - from.x;
|
let x_component = x_to.to_length_units(from.units) - from.x;
|
||||||
let y_component = x_component * f64::tan(angle_degrees.to_radians());
|
let y_component = x_component * f64::tan(angle_degrees.to_radians());
|
||||||
let y_to = from.y + y_component;
|
let y_to = from.y + y_component;
|
||||||
|
|
||||||
let new_sketch = straight_line(
|
let new_sketch = straight_line(
|
||||||
StraightLineParams::absolute([x_to, y_to], sketch, tag),
|
StraightLineParams::absolute([x_to, TyF64::new(y_to, from.units.into())], sketch, tag),
|
||||||
exec_state,
|
exec_state,
|
||||||
args,
|
args,
|
||||||
)
|
)
|
||||||
@ -787,7 +768,7 @@ async fn inner_angled_line_to_x(
|
|||||||
|
|
||||||
async fn inner_angled_line_of_y_length(
|
async fn inner_angled_line_of_y_length(
|
||||||
angle_degrees: f64,
|
angle_degrees: f64,
|
||||||
length: f64,
|
length: TyF64,
|
||||||
sketch: Sketch,
|
sketch: Sketch,
|
||||||
tag: Option<TagNode>,
|
tag: Option<TagNode>,
|
||||||
exec_state: &mut ExecState,
|
exec_state: &mut ExecState,
|
||||||
@ -807,7 +788,8 @@ async fn inner_angled_line_of_y_length(
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
let to = get_x_component(Angle::from_degrees(angle_degrees), length);
|
let to = get_x_component(Angle::from_degrees(angle_degrees), length.n);
|
||||||
|
let to = [TyF64::new(to[0], length.ty.clone()), TyF64::new(to[1], length.ty)];
|
||||||
|
|
||||||
let new_sketch = straight_line(StraightLineParams::relative(to, sketch, tag), exec_state, args).await?;
|
let new_sketch = straight_line(StraightLineParams::relative(to, sketch, tag), exec_state, args).await?;
|
||||||
|
|
||||||
@ -816,7 +798,7 @@ async fn inner_angled_line_of_y_length(
|
|||||||
|
|
||||||
async fn inner_angled_line_to_y(
|
async fn inner_angled_line_to_y(
|
||||||
angle_degrees: f64,
|
angle_degrees: f64,
|
||||||
y_to: f64,
|
y_to: TyF64,
|
||||||
sketch: Sketch,
|
sketch: Sketch,
|
||||||
tag: Option<TagNode>,
|
tag: Option<TagNode>,
|
||||||
exec_state: &mut ExecState,
|
exec_state: &mut ExecState,
|
||||||
@ -838,12 +820,12 @@ async fn inner_angled_line_to_y(
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
let y_component = y_to - from.y;
|
let y_component = y_to.to_length_units(from.units) - from.y;
|
||||||
let x_component = y_component / f64::tan(angle_degrees.to_radians());
|
let x_component = y_component / f64::tan(angle_degrees.to_radians());
|
||||||
let x_to = from.x + x_component;
|
let x_to = from.x + x_component;
|
||||||
|
|
||||||
let new_sketch = straight_line(
|
let new_sketch = straight_line(
|
||||||
StraightLineParams::absolute([x_to, y_to], sketch, tag),
|
StraightLineParams::absolute([TyF64::new(x_to, from.units.into()), y_to], sketch, tag),
|
||||||
exec_state,
|
exec_state,
|
||||||
args,
|
args,
|
||||||
)
|
)
|
||||||
@ -916,11 +898,18 @@ pub async fn inner_angled_line_that_intersects(
|
|||||||
|
|
||||||
let from = sketch.current_pen_position()?;
|
let from = sketch.current_pen_position()?;
|
||||||
let to = intersection_with_parallel_line(
|
let to = intersection_with_parallel_line(
|
||||||
&[untype_point(path.get_from()).0, untype_point(path.get_to()).0],
|
&[
|
||||||
offset.map(|t| t.n).unwrap_or_default(),
|
point_to_len_unit(path.get_from(), from.units),
|
||||||
angle.n,
|
point_to_len_unit(path.get_to(), from.units),
|
||||||
from.into(),
|
],
|
||||||
|
offset.map(|t| t.to_length_units(from.units)).unwrap_or_default(),
|
||||||
|
angle.to_degrees(),
|
||||||
|
from.ignore_units(),
|
||||||
);
|
);
|
||||||
|
let to = [
|
||||||
|
TyF64::new(to[0], from.units.into()),
|
||||||
|
TyF64::new(to[1], from.units.into()),
|
||||||
|
];
|
||||||
|
|
||||||
straight_line(StraightLineParams::absolute(to, sketch, tag), exec_state, args).await
|
straight_line(StraightLineParams::absolute(to, sketch, tag), exec_state, args).await
|
||||||
}
|
}
|
||||||
@ -1309,7 +1298,7 @@ async fn make_sketch_plane_from_orientation(
|
|||||||
pub async fn start_profile_at(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
pub async fn start_profile_at(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
||||||
let (start, sketch_surface, tag) = args.get_data_and_sketch_surface()?;
|
let (start, sketch_surface, tag) = args.get_data_and_sketch_surface()?;
|
||||||
|
|
||||||
let sketch = inner_start_profile_at([start[0].n, start[1].n], sketch_surface, tag, exec_state, args).await?;
|
let sketch = inner_start_profile_at(start, sketch_surface, tag, exec_state, args).await?;
|
||||||
Ok(KclValue::Sketch {
|
Ok(KclValue::Sketch {
|
||||||
value: Box::new(sketch),
|
value: Box::new(sketch),
|
||||||
})
|
})
|
||||||
@ -1353,7 +1342,7 @@ pub async fn start_profile_at(exec_state: &mut ExecState, args: Args) -> Result<
|
|||||||
name = "startProfileAt",
|
name = "startProfileAt",
|
||||||
}]
|
}]
|
||||||
pub(crate) async fn inner_start_profile_at(
|
pub(crate) async fn inner_start_profile_at(
|
||||||
to: [f64; 2],
|
to: [TyF64; 2],
|
||||||
sketch_surface: SketchSurface,
|
sketch_surface: SketchSurface,
|
||||||
tag: Option<TagNode>,
|
tag: Option<TagNode>,
|
||||||
exec_state: &mut ExecState,
|
exec_state: &mut ExecState,
|
||||||
@ -1409,7 +1398,7 @@ pub(crate) async fn inner_start_profile_at(
|
|||||||
ModelingCmdReq {
|
ModelingCmdReq {
|
||||||
cmd: ModelingCmd::from(mcmd::MovePathPen {
|
cmd: ModelingCmd::from(mcmd::MovePathPen {
|
||||||
path: path_id.into(),
|
path: path_id.into(),
|
||||||
to: KPoint2d::from(to).with_z(0.0).map(LengthUnit),
|
to: KPoint2d::from(point_to_mm(to.clone())).with_z(0.0).map(LengthUnit),
|
||||||
}),
|
}),
|
||||||
cmd_id: move_pen_id.into(),
|
cmd_id: move_pen_id.into(),
|
||||||
},
|
},
|
||||||
@ -1420,11 +1409,12 @@ pub(crate) async fn inner_start_profile_at(
|
|||||||
])
|
])
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
let (to, ty) = untype_point(to);
|
||||||
let current_path = BasePath {
|
let current_path = BasePath {
|
||||||
from: to,
|
from: to,
|
||||||
to,
|
to,
|
||||||
tag: tag.clone(),
|
tag: tag.clone(),
|
||||||
units: sketch_surface.units(),
|
units: ty.expect_length(),
|
||||||
geo_meta: GeoMeta {
|
geo_meta: GeoMeta {
|
||||||
id: move_pen_id,
|
id: move_pen_id,
|
||||||
metadata: args.source_range.into(),
|
metadata: args.source_range.into(),
|
||||||
@ -1437,7 +1427,7 @@ pub(crate) async fn inner_start_profile_at(
|
|||||||
artifact_id: path_id.into(),
|
artifact_id: path_id.into(),
|
||||||
on: sketch_surface.clone(),
|
on: sketch_surface.clone(),
|
||||||
paths: vec![],
|
paths: vec![],
|
||||||
units: sketch_surface.units(),
|
units: ty.expect_length(),
|
||||||
mirror: Default::default(),
|
mirror: Default::default(),
|
||||||
meta: vec![args.source_range.into()],
|
meta: vec![args.source_range.into()],
|
||||||
tags: if let Some(tag) = &tag {
|
tags: if let Some(tag) = &tag {
|
||||||
@ -1586,7 +1576,7 @@ pub(crate) async fn inner_close(
|
|||||||
args: Args,
|
args: Args,
|
||||||
) -> Result<Sketch, KclError> {
|
) -> Result<Sketch, KclError> {
|
||||||
let from = sketch.current_pen_position()?;
|
let from = sketch.current_pen_position()?;
|
||||||
let to: Point2d = sketch.start.get_from().into();
|
let to = point_to_len_unit(sketch.start.get_from(), from.units);
|
||||||
|
|
||||||
let id = exec_state.next_uuid();
|
let id = exec_state.next_uuid();
|
||||||
|
|
||||||
@ -1595,8 +1585,8 @@ pub(crate) async fn inner_close(
|
|||||||
|
|
||||||
let current_path = Path::ToPoint {
|
let current_path = Path::ToPoint {
|
||||||
base: BasePath {
|
base: BasePath {
|
||||||
from: from.into(),
|
from: from.ignore_units(),
|
||||||
to: to.into(),
|
to,
|
||||||
tag: tag.clone(),
|
tag: tag.clone(),
|
||||||
units: sketch.units,
|
units: sketch.units,
|
||||||
geo_meta: GeoMeta {
|
geo_meta: GeoMeta {
|
||||||
@ -1708,7 +1698,6 @@ pub(crate) async fn inner_arc(
|
|||||||
let from: Point2d = sketch.current_pen_position()?;
|
let from: Point2d = sketch.current_pen_position()?;
|
||||||
let id = exec_state.next_uuid();
|
let id = exec_state.next_uuid();
|
||||||
|
|
||||||
// Relative case
|
|
||||||
match (angle_start, angle_end, radius, interior_absolute, end_absolute) {
|
match (angle_start, angle_end, radius, interior_absolute, end_absolute) {
|
||||||
(Some(angle_start), Some(angle_end), Some(radius), None, None) => {
|
(Some(angle_start), Some(angle_end), Some(radius), None, None) => {
|
||||||
relative_arc(&args, id, exec_state, sketch, from, angle_start, angle_end, radius, tag).await
|
relative_arc(&args, id, exec_state, sketch, from, angle_start, angle_end, radius, tag).await
|
||||||
@ -1745,13 +1734,13 @@ pub async fn absolute_arc(
|
|||||||
path: sketch.id.into(),
|
path: sketch.id.into(),
|
||||||
segment: PathSegment::ArcTo {
|
segment: PathSegment::ArcTo {
|
||||||
end: kcmc::shared::Point3d {
|
end: kcmc::shared::Point3d {
|
||||||
x: LengthUnit(end_absolute[0].n),
|
x: LengthUnit(end_absolute[0].to_mm()),
|
||||||
y: LengthUnit(end_absolute[1].n),
|
y: LengthUnit(end_absolute[1].to_mm()),
|
||||||
z: LengthUnit(0.0),
|
z: LengthUnit(0.0),
|
||||||
},
|
},
|
||||||
interior: kcmc::shared::Point3d {
|
interior: kcmc::shared::Point3d {
|
||||||
x: LengthUnit(interior_absolute[0].n),
|
x: LengthUnit(interior_absolute[0].to_mm()),
|
||||||
y: LengthUnit(interior_absolute[1].n),
|
y: LengthUnit(interior_absolute[1].to_mm()),
|
||||||
z: LengthUnit(0.0),
|
z: LengthUnit(0.0),
|
||||||
},
|
},
|
||||||
relative: false,
|
relative: false,
|
||||||
@ -1761,13 +1750,12 @@ pub async fn absolute_arc(
|
|||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
let start = [from.x, from.y];
|
let start = [from.x, from.y];
|
||||||
let end = end_absolute.clone();
|
let end = point_to_len_unit(end_absolute, from.units);
|
||||||
let untyped_end = untype_point(end);
|
|
||||||
|
|
||||||
let current_path = Path::ArcThreePoint {
|
let current_path = Path::ArcThreePoint {
|
||||||
base: BasePath {
|
base: BasePath {
|
||||||
from: from.into(),
|
from: from.ignore_units(),
|
||||||
to: untyped_end.0,
|
to: end,
|
||||||
tag: tag.clone(),
|
tag: tag.clone(),
|
||||||
units: sketch.units,
|
units: sketch.units,
|
||||||
geo_meta: GeoMeta {
|
geo_meta: GeoMeta {
|
||||||
@ -1776,8 +1764,8 @@ pub async fn absolute_arc(
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
p1: start,
|
p1: start,
|
||||||
p2: untype_point(interior_absolute).0,
|
p2: point_to_len_unit(interior_absolute, from.units),
|
||||||
p3: untyped_end.0,
|
p3: end,
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut new_sketch = sketch.clone();
|
let mut new_sketch = sketch.clone();
|
||||||
@ -1802,16 +1790,17 @@ pub async fn relative_arc(
|
|||||||
radius: TyF64,
|
radius: TyF64,
|
||||||
tag: Option<TagNode>,
|
tag: Option<TagNode>,
|
||||||
) -> Result<Sketch, KclError> {
|
) -> Result<Sketch, KclError> {
|
||||||
let a_start = Angle::from_degrees(angle_start.n);
|
let a_start = Angle::from_degrees(angle_start.to_degrees());
|
||||||
let a_end = Angle::from_degrees(angle_end.n);
|
let a_end = Angle::from_degrees(angle_end.to_degrees());
|
||||||
let (center, end) = arc_center_and_end(from.into(), a_start, a_end, radius.n);
|
let radius = radius.to_length_units(from.units);
|
||||||
if angle_start == angle_end {
|
let (center, end) = arc_center_and_end(from.ignore_units(), a_start, a_end, radius);
|
||||||
|
if a_start == a_end {
|
||||||
return Err(KclError::Type(KclErrorDetails {
|
return Err(KclError::Type(KclErrorDetails {
|
||||||
message: "Arc start and end angles must be different".to_string(),
|
message: "Arc start and end angles must be different".to_string(),
|
||||||
source_ranges: vec![args.source_range],
|
source_ranges: vec![args.source_range],
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
let ccw = angle_start.n < angle_end.n;
|
let ccw = a_start < a_end;
|
||||||
|
|
||||||
args.batch_modeling_cmd(
|
args.batch_modeling_cmd(
|
||||||
id,
|
id,
|
||||||
@ -1820,8 +1809,8 @@ pub async fn relative_arc(
|
|||||||
segment: PathSegment::Arc {
|
segment: PathSegment::Arc {
|
||||||
start: a_start,
|
start: a_start,
|
||||||
end: a_end,
|
end: a_end,
|
||||||
center: KPoint2d::from(center).map(LengthUnit),
|
center: KPoint2d::from(untyped_point_to_mm(center, from.units)).map(LengthUnit),
|
||||||
radius: LengthUnit(radius.n),
|
radius: LengthUnit(from.units.adjust_to(radius, UnitLen::Mm).0),
|
||||||
relative: false,
|
relative: false,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
@ -1830,17 +1819,17 @@ pub async fn relative_arc(
|
|||||||
|
|
||||||
let current_path = Path::Arc {
|
let current_path = Path::Arc {
|
||||||
base: BasePath {
|
base: BasePath {
|
||||||
from: from.into(),
|
from: from.ignore_units(),
|
||||||
to: end,
|
to: end,
|
||||||
tag: tag.clone(),
|
tag: tag.clone(),
|
||||||
units: sketch.units,
|
units: from.units,
|
||||||
geo_meta: GeoMeta {
|
geo_meta: GeoMeta {
|
||||||
id,
|
id,
|
||||||
metadata: args.source_range.into(),
|
metadata: args.source_range.into(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
center,
|
center,
|
||||||
radius: radius.n,
|
radius,
|
||||||
ccw,
|
ccw,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1853,6 +1842,7 @@ pub async fn relative_arc(
|
|||||||
|
|
||||||
Ok(new_sketch)
|
Ok(new_sketch)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Draw a tangential arc to a specific point.
|
/// Draw a tangential arc to a specific point.
|
||||||
pub async fn tangential_arc(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
pub async fn tangential_arc(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
||||||
let sketch =
|
let sketch =
|
||||||
@ -1863,17 +1853,7 @@ pub async fn tangential_arc(exec_state: &mut ExecState, args: Args) -> Result<Kc
|
|||||||
let angle = args.get_kw_arg_opt_typed("angle", &RuntimeType::angle(), exec_state)?;
|
let angle = args.get_kw_arg_opt_typed("angle", &RuntimeType::angle(), exec_state)?;
|
||||||
let tag = args.get_kw_arg_opt(NEW_TAG_KW)?;
|
let tag = args.get_kw_arg_opt(NEW_TAG_KW)?;
|
||||||
|
|
||||||
let new_sketch = inner_tangential_arc(
|
let new_sketch = inner_tangential_arc(sketch, end_absolute, end, radius, angle, tag, exec_state, args).await?;
|
||||||
sketch,
|
|
||||||
end_absolute.map(|p| untype_point(p).0),
|
|
||||||
end.map(|p| untype_point(p).0),
|
|
||||||
radius,
|
|
||||||
angle,
|
|
||||||
tag,
|
|
||||||
exec_state,
|
|
||||||
args,
|
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
Ok(KclValue::Sketch {
|
Ok(KclValue::Sketch {
|
||||||
value: Box::new(new_sketch),
|
value: Box::new(new_sketch),
|
||||||
})
|
})
|
||||||
@ -1949,8 +1929,8 @@ pub async fn tangential_arc(exec_state: &mut ExecState, args: Args) -> Result<Kc
|
|||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
async fn inner_tangential_arc(
|
async fn inner_tangential_arc(
|
||||||
sketch: Sketch,
|
sketch: Sketch,
|
||||||
end_absolute: Option<[f64; 2]>,
|
end_absolute: Option<[TyF64; 2]>,
|
||||||
end: Option<[f64; 2]>,
|
end: Option<[TyF64; 2]>,
|
||||||
radius: Option<TyF64>,
|
radius: Option<TyF64>,
|
||||||
angle: Option<TyF64>,
|
angle: Option<TyF64>,
|
||||||
tag: Option<TagNode>,
|
tag: Option<TagNode>,
|
||||||
@ -2014,14 +1994,14 @@ async fn inner_tangential_arc_radius_angle(
|
|||||||
let from: Point2d = sketch.current_pen_position()?;
|
let from: Point2d = sketch.current_pen_position()?;
|
||||||
// next set of lines is some undocumented voodoo from get_tangential_arc_to_info
|
// next set of lines is some undocumented voodoo from get_tangential_arc_to_info
|
||||||
let tangent_info = sketch.get_tangential_info_from_paths(); //this function desperately needs some documentation
|
let tangent_info = sketch.get_tangential_info_from_paths(); //this function desperately needs some documentation
|
||||||
let tan_previous_point = tangent_info.tan_previous_point(from.into());
|
let tan_previous_point = tangent_info.tan_previous_point(from.ignore_units());
|
||||||
|
|
||||||
let id = exec_state.next_uuid();
|
let id = exec_state.next_uuid();
|
||||||
|
|
||||||
let (center, to, ccw) = match data {
|
let (center, to, ccw) = match data {
|
||||||
TangentialArcData::RadiusAndOffset { radius, offset } => {
|
TangentialArcData::RadiusAndOffset { radius, offset } => {
|
||||||
// KCL stdlib types use degrees.
|
// KCL stdlib types use degrees.
|
||||||
let offset = Angle::from_degrees(offset.n);
|
let offset = Angle::from_degrees(offset.to_degrees());
|
||||||
|
|
||||||
// Calculate the end point from the angle and radius.
|
// Calculate the end point from the angle and radius.
|
||||||
// atan2 outputs radians.
|
// atan2 outputs radians.
|
||||||
@ -2043,14 +2023,19 @@ async fn inner_tangential_arc_radius_angle(
|
|||||||
// but the above logic *should* capture that behavior
|
// but the above logic *should* capture that behavior
|
||||||
let start_angle = previous_end_tangent + tangent_to_arc_start_angle;
|
let start_angle = previous_end_tangent + tangent_to_arc_start_angle;
|
||||||
let end_angle = start_angle + offset;
|
let end_angle = start_angle + offset;
|
||||||
let (center, to) = arc_center_and_end(from.into(), start_angle, end_angle, radius.n);
|
let (center, to) = arc_center_and_end(
|
||||||
|
from.ignore_units(),
|
||||||
|
start_angle,
|
||||||
|
end_angle,
|
||||||
|
radius.to_length_units(from.units),
|
||||||
|
);
|
||||||
|
|
||||||
args.batch_modeling_cmd(
|
args.batch_modeling_cmd(
|
||||||
id,
|
id,
|
||||||
ModelingCmd::from(mcmd::ExtendPath {
|
ModelingCmd::from(mcmd::ExtendPath {
|
||||||
path: sketch.id.into(),
|
path: sketch.id.into(),
|
||||||
segment: PathSegment::TangentialArc {
|
segment: PathSegment::TangentialArc {
|
||||||
radius: LengthUnit(radius.n),
|
radius: LengthUnit(radius.to_mm()),
|
||||||
offset,
|
offset,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
@ -2064,7 +2049,7 @@ async fn inner_tangential_arc_radius_angle(
|
|||||||
ccw,
|
ccw,
|
||||||
center,
|
center,
|
||||||
base: BasePath {
|
base: BasePath {
|
||||||
from: from.into(),
|
from: from.ignore_units(),
|
||||||
to,
|
to,
|
||||||
tag: tag.clone(),
|
tag: tag.clone(),
|
||||||
units: sketch.units,
|
units: sketch.units,
|
||||||
@ -2085,19 +2070,22 @@ async fn inner_tangential_arc_radius_angle(
|
|||||||
Ok(new_sketch)
|
Ok(new_sketch)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tan_arc_to(sketch: &Sketch, to: &[f64; 2]) -> ModelingCmd {
|
// `to` must be in sketch.units
|
||||||
|
fn tan_arc_to(sketch: &Sketch, to: [f64; 2]) -> ModelingCmd {
|
||||||
ModelingCmd::from(mcmd::ExtendPath {
|
ModelingCmd::from(mcmd::ExtendPath {
|
||||||
path: sketch.id.into(),
|
path: sketch.id.into(),
|
||||||
segment: PathSegment::TangentialArcTo {
|
segment: PathSegment::TangentialArcTo {
|
||||||
angle_snap_increment: None,
|
angle_snap_increment: None,
|
||||||
to: KPoint2d::from(*to).with_z(0.0).map(LengthUnit),
|
to: KPoint2d::from(untyped_point_to_mm(to, sketch.units))
|
||||||
|
.with_z(0.0)
|
||||||
|
.map(LengthUnit),
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn inner_tangential_arc_to_point(
|
async fn inner_tangential_arc_to_point(
|
||||||
sketch: Sketch,
|
sketch: Sketch,
|
||||||
point: [f64; 2],
|
point: [TyF64; 2],
|
||||||
is_absolute: bool,
|
is_absolute: bool,
|
||||||
tag: Option<TagNode>,
|
tag: Option<TagNode>,
|
||||||
exec_state: &mut ExecState,
|
exec_state: &mut ExecState,
|
||||||
@ -2105,7 +2093,9 @@ async fn inner_tangential_arc_to_point(
|
|||||||
) -> Result<Sketch, KclError> {
|
) -> Result<Sketch, KclError> {
|
||||||
let from: Point2d = sketch.current_pen_position()?;
|
let from: Point2d = sketch.current_pen_position()?;
|
||||||
let tangent_info = sketch.get_tangential_info_from_paths();
|
let tangent_info = sketch.get_tangential_info_from_paths();
|
||||||
let tan_previous_point = tangent_info.tan_previous_point(from.into());
|
let tan_previous_point = tangent_info.tan_previous_point(from.ignore_units());
|
||||||
|
|
||||||
|
let point = point_to_len_unit(point, from.units);
|
||||||
|
|
||||||
let to = if is_absolute {
|
let to = if is_absolute {
|
||||||
point
|
point
|
||||||
@ -2115,7 +2105,7 @@ async fn inner_tangential_arc_to_point(
|
|||||||
let [to_x, to_y] = to;
|
let [to_x, to_y] = to;
|
||||||
let result = get_tangential_arc_to_info(TangentialArcInfoInput {
|
let result = get_tangential_arc_to_info(TangentialArcInfoInput {
|
||||||
arc_start_point: [from.x, from.y],
|
arc_start_point: [from.x, from.y],
|
||||||
arc_end_point: to,
|
arc_end_point: [to_x, to_y],
|
||||||
tan_previous_point,
|
tan_previous_point,
|
||||||
obtuse: true,
|
obtuse: true,
|
||||||
});
|
});
|
||||||
@ -2142,11 +2132,11 @@ async fn inner_tangential_arc_to_point(
|
|||||||
point
|
point
|
||||||
};
|
};
|
||||||
let id = exec_state.next_uuid();
|
let id = exec_state.next_uuid();
|
||||||
args.batch_modeling_cmd(id, tan_arc_to(&sketch, &delta)).await?;
|
args.batch_modeling_cmd(id, tan_arc_to(&sketch, delta)).await?;
|
||||||
|
|
||||||
let current_path = Path::TangentialArcTo {
|
let current_path = Path::TangentialArcTo {
|
||||||
base: BasePath {
|
base: BasePath {
|
||||||
from: from.into(),
|
from: from.ignore_units(),
|
||||||
to,
|
to,
|
||||||
tag: tag.clone(),
|
tag: tag.clone(),
|
||||||
units: sketch.units,
|
units: sketch.units,
|
||||||
@ -2227,7 +2217,10 @@ async fn inner_bezier_curve(
|
|||||||
|
|
||||||
let relative = true;
|
let relative = true;
|
||||||
let delta = end.clone();
|
let delta = end.clone();
|
||||||
let to = [from.x + end[0].n, from.y + end[1].n];
|
let to = [
|
||||||
|
from.x + end[0].to_length_units(from.units),
|
||||||
|
from.y + end[1].to_length_units(from.units),
|
||||||
|
];
|
||||||
|
|
||||||
let id = exec_state.next_uuid();
|
let id = exec_state.next_uuid();
|
||||||
|
|
||||||
@ -2236,9 +2229,9 @@ async fn inner_bezier_curve(
|
|||||||
ModelingCmd::from(mcmd::ExtendPath {
|
ModelingCmd::from(mcmd::ExtendPath {
|
||||||
path: sketch.id.into(),
|
path: sketch.id.into(),
|
||||||
segment: PathSegment::Bezier {
|
segment: PathSegment::Bezier {
|
||||||
control1: KPoint2d::from(untype_point(control1).0).with_z(0.0).map(LengthUnit),
|
control1: KPoint2d::from(point_to_mm(control1)).with_z(0.0).map(LengthUnit),
|
||||||
control2: KPoint2d::from(untype_point(control2).0).with_z(0.0).map(LengthUnit),
|
control2: KPoint2d::from(point_to_mm(control2)).with_z(0.0).map(LengthUnit),
|
||||||
end: KPoint2d::from(untype_point(delta).0).with_z(0.0).map(LengthUnit),
|
end: KPoint2d::from(point_to_mm(delta)).with_z(0.0).map(LengthUnit),
|
||||||
relative,
|
relative,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
@ -2247,7 +2240,7 @@ async fn inner_bezier_curve(
|
|||||||
|
|
||||||
let current_path = Path::ToPoint {
|
let current_path = Path::ToPoint {
|
||||||
base: BasePath {
|
base: BasePath {
|
||||||
from: from.into(),
|
from: from.ignore_units(),
|
||||||
to,
|
to,
|
||||||
tag: tag.clone(),
|
tag: tag.clone(),
|
||||||
units: sketch.units,
|
units: sketch.units,
|
||||||
|
@ -10,7 +10,10 @@ use serde::Serialize;
|
|||||||
use super::{args::TyF64, DEFAULT_TOLERANCE};
|
use super::{args::TyF64, DEFAULT_TOLERANCE};
|
||||||
use crate::{
|
use crate::{
|
||||||
errors::KclError,
|
errors::KclError,
|
||||||
execution::{types::RuntimeType, ExecState, Helix, KclValue, Sketch, Solid},
|
execution::{
|
||||||
|
types::{NumericType, RuntimeType},
|
||||||
|
ExecState, Helix, KclValue, Sketch, Solid,
|
||||||
|
},
|
||||||
parsing::ast::types::TagNode,
|
parsing::ast::types::TagNode,
|
||||||
std::{extrude::do_post_extrude, Args},
|
std::{extrude::do_post_extrude, Args},
|
||||||
};
|
};
|
||||||
@ -27,21 +30,18 @@ pub enum SweepPath {
|
|||||||
/// Extrude a sketch along a path.
|
/// Extrude a sketch along a path.
|
||||||
pub async fn sweep(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
pub async fn sweep(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
||||||
let sketches = args.get_unlabeled_kw_arg_typed("sketches", &RuntimeType::sketches(), exec_state)?;
|
let sketches = args.get_unlabeled_kw_arg_typed("sketches", &RuntimeType::sketches(), exec_state)?;
|
||||||
let path: SweepPath = args.get_kw_arg("path")?;
|
let path: SweepPath = args.get_kw_arg_typed(
|
||||||
|
"path",
|
||||||
|
&RuntimeType::Union(vec![RuntimeType::sketch(), RuntimeType::helix()]),
|
||||||
|
exec_state,
|
||||||
|
)?;
|
||||||
let sectional = args.get_kw_arg_opt("sectional")?;
|
let sectional = args.get_kw_arg_opt("sectional")?;
|
||||||
let tolerance: Option<TyF64> = args.get_kw_arg_opt_typed("tolerance", &RuntimeType::count(), exec_state)?;
|
let tolerance: Option<TyF64> = args.get_kw_arg_opt_typed("tolerance", &RuntimeType::length(), exec_state)?;
|
||||||
let tag_start = args.get_kw_arg_opt("tagStart")?;
|
let tag_start = args.get_kw_arg_opt("tagStart")?;
|
||||||
let tag_end = args.get_kw_arg_opt("tagEnd")?;
|
let tag_end = args.get_kw_arg_opt("tagEnd")?;
|
||||||
|
|
||||||
let value = inner_sweep(
|
let value = inner_sweep(
|
||||||
sketches,
|
sketches, path, sectional, tolerance, tag_start, tag_end, exec_state, args,
|
||||||
path,
|
|
||||||
sectional,
|
|
||||||
tolerance.map(|t| t.n),
|
|
||||||
tag_start,
|
|
||||||
tag_end,
|
|
||||||
exec_state,
|
|
||||||
args,
|
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
Ok(value.into())
|
Ok(value.into())
|
||||||
@ -167,7 +167,7 @@ async fn inner_sweep(
|
|||||||
sketches: Vec<Sketch>,
|
sketches: Vec<Sketch>,
|
||||||
path: SweepPath,
|
path: SweepPath,
|
||||||
sectional: Option<bool>,
|
sectional: Option<bool>,
|
||||||
tolerance: Option<f64>,
|
tolerance: Option<TyF64>,
|
||||||
tag_start: Option<TagNode>,
|
tag_start: Option<TagNode>,
|
||||||
tag_end: Option<TagNode>,
|
tag_end: Option<TagNode>,
|
||||||
exec_state: &mut ExecState,
|
exec_state: &mut ExecState,
|
||||||
@ -187,7 +187,7 @@ async fn inner_sweep(
|
|||||||
target: sketch.id.into(),
|
target: sketch.id.into(),
|
||||||
trajectory,
|
trajectory,
|
||||||
sectional: sectional.unwrap_or(false),
|
sectional: sectional.unwrap_or(false),
|
||||||
tolerance: LengthUnit(tolerance.unwrap_or(DEFAULT_TOLERANCE)),
|
tolerance: LengthUnit(tolerance.as_ref().map(|t| t.to_mm()).unwrap_or(DEFAULT_TOLERANCE)),
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
@ -196,7 +196,7 @@ async fn inner_sweep(
|
|||||||
do_post_extrude(
|
do_post_extrude(
|
||||||
sketch,
|
sketch,
|
||||||
id.into(),
|
id.into(),
|
||||||
0.0,
|
TyF64::new(0.0, NumericType::mm()),
|
||||||
sectional.unwrap_or(false),
|
sectional.unwrap_or(false),
|
||||||
&super::extrude::NamedCapTags {
|
&super::extrude::NamedCapTags {
|
||||||
start: tag_start.as_ref(),
|
start: tag_start.as_ref(),
|
||||||
|
@ -225,16 +225,7 @@ pub async fn translate(exec_state: &mut ExecState, args: Args) -> Result<KclValu
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
let objects = inner_translate(
|
let objects = inner_translate(objects, translate_x, translate_y, translate_z, global, exec_state, args).await?;
|
||||||
objects,
|
|
||||||
translate_x.map(|t| t.n),
|
|
||||||
translate_y.map(|t| t.n),
|
|
||||||
translate_z.map(|t| t.n),
|
|
||||||
global,
|
|
||||||
exec_state,
|
|
||||||
args,
|
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
Ok(objects.into())
|
Ok(objects.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -397,9 +388,9 @@ pub async fn translate(exec_state: &mut ExecState, args: Args) -> Result<KclValu
|
|||||||
}]
|
}]
|
||||||
async fn inner_translate(
|
async fn inner_translate(
|
||||||
objects: SolidOrSketchOrImportedGeometry,
|
objects: SolidOrSketchOrImportedGeometry,
|
||||||
x: Option<f64>,
|
x: Option<TyF64>,
|
||||||
y: Option<f64>,
|
y: Option<TyF64>,
|
||||||
z: Option<f64>,
|
z: Option<TyF64>,
|
||||||
global: Option<bool>,
|
global: Option<bool>,
|
||||||
exec_state: &mut ExecState,
|
exec_state: &mut ExecState,
|
||||||
args: Args,
|
args: Args,
|
||||||
@ -421,9 +412,9 @@ async fn inner_translate(
|
|||||||
transforms: vec![shared::ComponentTransform {
|
transforms: vec![shared::ComponentTransform {
|
||||||
translate: Some(shared::TransformBy::<Point3d<LengthUnit>> {
|
translate: Some(shared::TransformBy::<Point3d<LengthUnit>> {
|
||||||
property: shared::Point3d {
|
property: shared::Point3d {
|
||||||
x: LengthUnit(x.unwrap_or_default()),
|
x: LengthUnit(x.as_ref().map(|t| t.to_mm()).unwrap_or_default()),
|
||||||
y: LengthUnit(y.unwrap_or_default()),
|
y: LengthUnit(y.as_ref().map(|t| t.to_mm()).unwrap_or_default()),
|
||||||
z: LengthUnit(z.unwrap_or_default()),
|
z: LengthUnit(z.as_ref().map(|t| t.to_mm()).unwrap_or_default()),
|
||||||
},
|
},
|
||||||
set: false,
|
set: false,
|
||||||
is_local: !global.unwrap_or(false),
|
is_local: !global.unwrap_or(false),
|
||||||
@ -451,11 +442,11 @@ pub async fn rotate(exec_state: &mut ExecState, args: Args) -> Result<KclValue,
|
|||||||
]),
|
]),
|
||||||
exec_state,
|
exec_state,
|
||||||
)?;
|
)?;
|
||||||
let roll: Option<TyF64> = args.get_kw_arg_opt_typed("roll", &RuntimeType::angle(), exec_state)?;
|
let roll: Option<TyF64> = args.get_kw_arg_opt_typed("roll", &RuntimeType::degrees(), exec_state)?;
|
||||||
let pitch: Option<TyF64> = args.get_kw_arg_opt_typed("pitch", &RuntimeType::angle(), exec_state)?;
|
let pitch: Option<TyF64> = args.get_kw_arg_opt_typed("pitch", &RuntimeType::degrees(), exec_state)?;
|
||||||
let yaw: Option<TyF64> = args.get_kw_arg_opt_typed("yaw", &RuntimeType::angle(), exec_state)?;
|
let yaw: Option<TyF64> = args.get_kw_arg_opt_typed("yaw", &RuntimeType::degrees(), exec_state)?;
|
||||||
let axis: Option<[TyF64; 3]> = args.get_kw_arg_opt_typed("axis", &RuntimeType::point3d(), exec_state)?;
|
let axis: Option<[TyF64; 3]> = args.get_kw_arg_opt_typed("axis", &RuntimeType::point3d(), exec_state)?;
|
||||||
let angle: Option<TyF64> = args.get_kw_arg_opt_typed("angle", &RuntimeType::angle(), exec_state)?;
|
let angle: Option<TyF64> = args.get_kw_arg_opt_typed("angle", &RuntimeType::degrees(), exec_state)?;
|
||||||
let global = args.get_kw_arg_opt("global")?;
|
let global = args.get_kw_arg_opt("global")?;
|
||||||
|
|
||||||
// Check if no rotation values are provided.
|
// Check if no rotation values are provided.
|
||||||
@ -544,7 +535,9 @@ pub async fn rotate(exec_state: &mut ExecState, args: Args) -> Result<KclValue,
|
|||||||
roll.map(|t| t.n),
|
roll.map(|t| t.n),
|
||||||
pitch.map(|t| t.n),
|
pitch.map(|t| t.n),
|
||||||
yaw.map(|t| t.n),
|
yaw.map(|t| t.n),
|
||||||
axis.map(|p| [p[0].n, p[1].n, p[2].n]),
|
// Don't adjust axis units since the axis must be normalized and only the direction
|
||||||
|
// should be significant, not the magnitude.
|
||||||
|
axis.map(|a| [a[0].n, a[1].n, a[2].n]),
|
||||||
angle.map(|t| t.n),
|
angle.map(|t| t.n),
|
||||||
global,
|
global,
|
||||||
exec_state,
|
exec_state,
|
||||||
@ -780,7 +773,7 @@ async fn inner_rotate(
|
|||||||
for object_id in objects.ids(&args.ctx).await? {
|
for object_id in objects.ids(&args.ctx).await? {
|
||||||
let id = exec_state.next_uuid();
|
let id = exec_state.next_uuid();
|
||||||
|
|
||||||
if let (Some(axis), Some(angle)) = (axis, angle) {
|
if let (Some(axis), Some(angle)) = (&axis, angle) {
|
||||||
args.batch_modeling_cmd(
|
args.batch_modeling_cmd(
|
||||||
id,
|
id,
|
||||||
ModelingCmd::from(mcmd::SetObjectTransform {
|
ModelingCmd::from(mcmd::SetObjectTransform {
|
||||||
|
@ -5,20 +5,28 @@ use kcl_derive_docs::stdlib;
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
errors::KclError,
|
errors::KclError,
|
||||||
execution::{types::UnitLen, ExecState, KclValue},
|
execution::{
|
||||||
|
types::{RuntimeType, UnitLen},
|
||||||
|
ExecState, KclValue,
|
||||||
|
},
|
||||||
std::{args::TyF64, Args},
|
std::{args::TyF64, Args},
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Millimeters conversion factor for current files units.
|
/// Millimeters conversion factor for current files units.
|
||||||
pub async fn from_mm(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
pub async fn from_mm(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
||||||
let input = args.get_number_with_type()?;
|
let input = args.get_number_typed(&RuntimeType::known_length(UnitLen::Mm), exec_state)?;
|
||||||
let result = inner_from_mm(input.n, exec_state)?;
|
let result = inner_from_mm(input, exec_state)?;
|
||||||
|
|
||||||
Ok(args.make_user_val_from_f64_with_type(TyF64::new(result, exec_state.current_default_units())))
|
Ok(args.make_user_val_from_f64_with_type(TyF64::new(
|
||||||
|
result,
|
||||||
|
exec_state.current_default_units().expect_default_length(),
|
||||||
|
)))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Converts a number from mm to the current default unit.
|
/// Converts a number from mm to the current default unit.
|
||||||
///
|
///
|
||||||
|
/// *DEPRECATED* prefer using explicit numeric suffixes (e.g., `42mm`) or the `to...` conversion functions.
|
||||||
|
///
|
||||||
/// No matter what units the current file uses, this function will always return a number equivalent
|
/// No matter what units the current file uses, this function will always return a number equivalent
|
||||||
/// to the input in millimeters.
|
/// to the input in millimeters.
|
||||||
///
|
///
|
||||||
@ -39,6 +47,7 @@ pub async fn from_mm(exec_state: &mut ExecState, args: Args) -> Result<KclValue,
|
|||||||
#[stdlib {
|
#[stdlib {
|
||||||
name = "fromMm",
|
name = "fromMm",
|
||||||
tags = ["units"],
|
tags = ["units"],
|
||||||
|
deprecated = true,
|
||||||
}]
|
}]
|
||||||
fn inner_from_mm(input: f64, exec_state: &ExecState) -> Result<f64, KclError> {
|
fn inner_from_mm(input: f64, exec_state: &ExecState) -> Result<f64, KclError> {
|
||||||
Ok(match exec_state.length_unit() {
|
Ok(match exec_state.length_unit() {
|
||||||
@ -54,14 +63,19 @@ fn inner_from_mm(input: f64, exec_state: &ExecState) -> Result<f64, KclError> {
|
|||||||
|
|
||||||
/// Inches conversion factor for current files units.
|
/// Inches conversion factor for current files units.
|
||||||
pub async fn from_inches(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
pub async fn from_inches(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
||||||
let input = args.get_number_with_type()?;
|
let input = args.get_number_typed(&RuntimeType::known_length(UnitLen::Inches), exec_state)?;
|
||||||
let result = inner_from_inches(input.n, exec_state)?;
|
let result = inner_from_inches(input, exec_state)?;
|
||||||
|
|
||||||
Ok(args.make_user_val_from_f64_with_type(TyF64::new(result, exec_state.current_default_units())))
|
Ok(args.make_user_val_from_f64_with_type(TyF64::new(
|
||||||
|
result,
|
||||||
|
exec_state.current_default_units().expect_default_length(),
|
||||||
|
)))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Converts a number from inches to the current default unit.
|
/// Converts a number from inches to the current default unit.
|
||||||
///
|
///
|
||||||
|
/// *DEPRECATED* prefer using explicit numeric suffixes (e.g., `42inch`) or the `to...` conversion functions.
|
||||||
|
///
|
||||||
/// No matter what units the current file uses, this function will always return a number equivalent
|
/// No matter what units the current file uses, this function will always return a number equivalent
|
||||||
/// to the input in inches.
|
/// to the input in inches.
|
||||||
///
|
///
|
||||||
@ -82,6 +96,7 @@ pub async fn from_inches(exec_state: &mut ExecState, args: Args) -> Result<KclVa
|
|||||||
#[stdlib {
|
#[stdlib {
|
||||||
name = "fromInches",
|
name = "fromInches",
|
||||||
tags = ["units"],
|
tags = ["units"],
|
||||||
|
deprecated = true,
|
||||||
}]
|
}]
|
||||||
fn inner_from_inches(input: f64, exec_state: &ExecState) -> Result<f64, KclError> {
|
fn inner_from_inches(input: f64, exec_state: &ExecState) -> Result<f64, KclError> {
|
||||||
match exec_state.length_unit() {
|
match exec_state.length_unit() {
|
||||||
@ -97,14 +112,19 @@ fn inner_from_inches(input: f64, exec_state: &ExecState) -> Result<f64, KclError
|
|||||||
|
|
||||||
/// Feet conversion factor for current files units.
|
/// Feet conversion factor for current files units.
|
||||||
pub async fn from_ft(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
pub async fn from_ft(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
||||||
let input = args.get_number_with_type()?;
|
let input = args.get_number_typed(&RuntimeType::known_length(UnitLen::Feet), exec_state)?;
|
||||||
let result = inner_from_ft(input.n, exec_state)?;
|
let result = inner_from_ft(input, exec_state)?;
|
||||||
|
|
||||||
Ok(args.make_user_val_from_f64_with_type(TyF64::new(result, exec_state.current_default_units())))
|
Ok(args.make_user_val_from_f64_with_type(TyF64::new(
|
||||||
|
result,
|
||||||
|
exec_state.current_default_units().expect_default_length(),
|
||||||
|
)))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Converts a number from feet to the current default unit.
|
/// Converts a number from feet to the current default unit.
|
||||||
///
|
///
|
||||||
|
/// *DEPRECATED* prefer using explicit numeric suffixes (e.g., `42ft`) or the `to...` conversion functions.
|
||||||
|
///
|
||||||
/// No matter what units the current file uses, this function will always return a number equivalent
|
/// No matter what units the current file uses, this function will always return a number equivalent
|
||||||
/// to the input in feet.
|
/// to the input in feet.
|
||||||
///
|
///
|
||||||
@ -126,6 +146,7 @@ pub async fn from_ft(exec_state: &mut ExecState, args: Args) -> Result<KclValue,
|
|||||||
#[stdlib {
|
#[stdlib {
|
||||||
name = "fromFt",
|
name = "fromFt",
|
||||||
tags = ["units"],
|
tags = ["units"],
|
||||||
|
deprecated = true,
|
||||||
}]
|
}]
|
||||||
fn inner_from_ft(input: f64, exec_state: &ExecState) -> Result<f64, KclError> {
|
fn inner_from_ft(input: f64, exec_state: &ExecState) -> Result<f64, KclError> {
|
||||||
match exec_state.length_unit() {
|
match exec_state.length_unit() {
|
||||||
@ -141,14 +162,19 @@ fn inner_from_ft(input: f64, exec_state: &ExecState) -> Result<f64, KclError> {
|
|||||||
|
|
||||||
/// Meters conversion factor for current files units.
|
/// Meters conversion factor for current files units.
|
||||||
pub async fn from_m(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
pub async fn from_m(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
||||||
let input = args.get_number_with_type()?;
|
let input = args.get_number_typed(&RuntimeType::known_length(UnitLen::M), exec_state)?;
|
||||||
let result = inner_from_m(input.n, exec_state)?;
|
let result = inner_from_m(input, exec_state)?;
|
||||||
|
|
||||||
Ok(args.make_user_val_from_f64_with_type(TyF64::new(result, exec_state.current_default_units())))
|
Ok(args.make_user_val_from_f64_with_type(TyF64::new(
|
||||||
|
result,
|
||||||
|
exec_state.current_default_units().expect_default_length(),
|
||||||
|
)))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Converts a number from meters to the current default unit.
|
/// Converts a number from meters to the current default unit.
|
||||||
///
|
///
|
||||||
|
/// *DEPRECATED* prefer using explicit numeric suffixes (e.g., `42m`) or the `to...` conversion functions.
|
||||||
|
///
|
||||||
/// No matter what units the current file uses, this function will always return a number equivalent
|
/// No matter what units the current file uses, this function will always return a number equivalent
|
||||||
/// to the input in meters.
|
/// to the input in meters.
|
||||||
///
|
///
|
||||||
@ -170,6 +196,7 @@ pub async fn from_m(exec_state: &mut ExecState, args: Args) -> Result<KclValue,
|
|||||||
#[stdlib {
|
#[stdlib {
|
||||||
name = "fromM",
|
name = "fromM",
|
||||||
tags = ["units"],
|
tags = ["units"],
|
||||||
|
deprecated = true,
|
||||||
}]
|
}]
|
||||||
fn inner_from_m(input: f64, exec_state: &ExecState) -> Result<f64, KclError> {
|
fn inner_from_m(input: f64, exec_state: &ExecState) -> Result<f64, KclError> {
|
||||||
match exec_state.length_unit() {
|
match exec_state.length_unit() {
|
||||||
@ -185,14 +212,19 @@ fn inner_from_m(input: f64, exec_state: &ExecState) -> Result<f64, KclError> {
|
|||||||
|
|
||||||
/// Centimeters conversion factor for current files units.
|
/// Centimeters conversion factor for current files units.
|
||||||
pub async fn from_cm(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
pub async fn from_cm(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
||||||
let input = args.get_number_with_type()?;
|
let input = args.get_number_typed(&RuntimeType::known_length(UnitLen::Cm), exec_state)?;
|
||||||
let result = inner_from_cm(input.n, exec_state)?;
|
let result = inner_from_cm(input, exec_state)?;
|
||||||
|
|
||||||
Ok(args.make_user_val_from_f64_with_type(TyF64::new(result, exec_state.current_default_units())))
|
Ok(args.make_user_val_from_f64_with_type(TyF64::new(
|
||||||
|
result,
|
||||||
|
exec_state.current_default_units().expect_default_length(),
|
||||||
|
)))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Converts a number from centimeters to the current default unit.
|
/// Converts a number from centimeters to the current default unit.
|
||||||
///
|
///
|
||||||
|
/// *DEPRECATED* prefer using explicit numeric suffixes (e.g., `42cm`) or the `to...` conversion functions.
|
||||||
|
///
|
||||||
/// No matter what units the current file uses, this function will always return a number equivalent
|
/// No matter what units the current file uses, this function will always return a number equivalent
|
||||||
/// to the input in centimeters.
|
/// to the input in centimeters.
|
||||||
///
|
///
|
||||||
@ -214,6 +246,7 @@ pub async fn from_cm(exec_state: &mut ExecState, args: Args) -> Result<KclValue,
|
|||||||
#[stdlib {
|
#[stdlib {
|
||||||
name = "fromCm",
|
name = "fromCm",
|
||||||
tags = ["units"],
|
tags = ["units"],
|
||||||
|
deprecated = true,
|
||||||
}]
|
}]
|
||||||
fn inner_from_cm(input: f64, exec_state: &ExecState) -> Result<f64, KclError> {
|
fn inner_from_cm(input: f64, exec_state: &ExecState) -> Result<f64, KclError> {
|
||||||
match exec_state.length_unit() {
|
match exec_state.length_unit() {
|
||||||
@ -229,14 +262,19 @@ fn inner_from_cm(input: f64, exec_state: &ExecState) -> Result<f64, KclError> {
|
|||||||
|
|
||||||
/// Yards conversion factor for current files units.
|
/// Yards conversion factor for current files units.
|
||||||
pub async fn from_yd(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
pub async fn from_yd(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
||||||
let input = args.get_number_with_type()?;
|
let input = args.get_number_typed(&RuntimeType::known_length(UnitLen::Yards), exec_state)?;
|
||||||
let result = inner_from_yd(input.n, exec_state)?;
|
let result = inner_from_yd(input, exec_state)?;
|
||||||
|
|
||||||
Ok(args.make_user_val_from_f64_with_type(TyF64::new(result, exec_state.current_default_units())))
|
Ok(args.make_user_val_from_f64_with_type(TyF64::new(
|
||||||
|
result,
|
||||||
|
exec_state.current_default_units().expect_default_length(),
|
||||||
|
)))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Converts a number from yards to the current default unit.
|
/// Converts a number from yards to the current default unit.
|
||||||
///
|
///
|
||||||
|
/// *DEPRECATED* prefer using explicit numeric suffixes (e.g., `42yd`) or the `to...` conversion functions.
|
||||||
|
///
|
||||||
/// No matter what units the current file uses, this function will always return a number equivalent
|
/// No matter what units the current file uses, this function will always return a number equivalent
|
||||||
/// to the input in yards.
|
/// to the input in yards.
|
||||||
///
|
///
|
||||||
@ -258,6 +296,7 @@ pub async fn from_yd(exec_state: &mut ExecState, args: Args) -> Result<KclValue,
|
|||||||
#[stdlib {
|
#[stdlib {
|
||||||
name = "fromYd",
|
name = "fromYd",
|
||||||
tags = ["units"],
|
tags = ["units"],
|
||||||
|
deprecated = true,
|
||||||
}]
|
}]
|
||||||
fn inner_from_yd(input: f64, exec_state: &ExecState) -> Result<f64, KclError> {
|
fn inner_from_yd(input: f64, exec_state: &ExecState) -> Result<f64, KclError> {
|
||||||
match exec_state.length_unit() {
|
match exec_state.length_unit() {
|
||||||
|
@ -2,39 +2,54 @@ use std::f64::consts::PI;
|
|||||||
|
|
||||||
use kittycad_modeling_cmds::shared::Angle;
|
use kittycad_modeling_cmds::shared::Angle;
|
||||||
|
|
||||||
use crate::{
|
use crate::execution::types::{NumericType, UnitLen};
|
||||||
errors::{KclError, KclErrorDetails},
|
|
||||||
execution::{types::NumericType, Point2d},
|
|
||||||
source_range::SourceRange,
|
|
||||||
};
|
|
||||||
|
|
||||||
use super::args::TyF64;
|
use super::args::TyF64;
|
||||||
|
|
||||||
pub fn untype_point(p: [TyF64; 2]) -> ([f64; 2], NumericType) {
|
pub(crate) fn untype_point(p: [TyF64; 2]) -> ([f64; 2], NumericType) {
|
||||||
let (x, y, ty) = NumericType::combine_eq(p[0].clone(), p[1].clone());
|
let (x, y, ty) = NumericType::combine_eq(p[0].clone(), p[1].clone());
|
||||||
([x, y], ty)
|
([x, y], ty)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn untype_point_3d(p: [TyF64; 3]) -> ([f64; 3], NumericType) {
|
pub(crate) fn point_to_mm(p: [TyF64; 2]) -> [f64; 2] {
|
||||||
let (arr, ty) = NumericType::combine_eq_array(&[p[0].clone(), p[1].clone(), p[2].clone()]);
|
[p[0].to_mm(), p[1].to_mm()]
|
||||||
let mut iter = arr.into_iter();
|
}
|
||||||
([iter.next().unwrap(), iter.next().unwrap(), iter.next().unwrap()], ty)
|
|
||||||
|
pub(crate) fn untyped_point_to_mm(p: [f64; 2], units: UnitLen) -> [f64; 2] {
|
||||||
|
assert_ne!(units, UnitLen::Unknown);
|
||||||
|
[
|
||||||
|
units.adjust_to(p[0], UnitLen::Mm).0,
|
||||||
|
units.adjust_to(p[1], UnitLen::Mm).0,
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn point_to_len_unit(p: [TyF64; 2], len: UnitLen) -> [f64; 2] {
|
||||||
|
[p[0].to_length_units(len), p[1].to_length_units(len)]
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Precondition, `p` must be in `len` units (this function does no conversion).
|
||||||
|
pub(crate) fn point_to_typed(p: [f64; 2], len: UnitLen) -> [TyF64; 2] {
|
||||||
|
[TyF64::new(p[0], len.into()), TyF64::new(p[1], len.into())]
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn point_3d_to_mm(p: [TyF64; 3]) -> [f64; 3] {
|
||||||
|
[p[0].to_mm(), p[1].to_mm(), p[2].to_mm()]
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the distance between two points.
|
/// Get the distance between two points.
|
||||||
pub fn distance(a: Coords2d, b: Coords2d) -> f64 {
|
pub(crate) fn distance(a: Coords2d, b: Coords2d) -> f64 {
|
||||||
((b[0] - a[0]).powi(2) + (b[1] - a[1]).powi(2)).sqrt()
|
((b[0] - a[0]).powi(2) + (b[1] - a[1]).powi(2)).sqrt()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the angle between these points
|
/// Get the angle between these points
|
||||||
pub fn between(a: Point2d, b: Point2d) -> Angle {
|
pub(crate) fn between(a: Coords2d, b: Coords2d) -> Angle {
|
||||||
let x = b.x - a.x;
|
let x = b[0] - a[0];
|
||||||
let y = b.y - a.y;
|
let y = b[1] - a[1];
|
||||||
normalize(Angle::from_radians(y.atan2(x)))
|
normalize(Angle::from_radians(y.atan2(x)))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Normalize the angle
|
/// Normalize the angle
|
||||||
pub fn normalize(angle: Angle) -> Angle {
|
pub(crate) fn normalize(angle: Angle) -> Angle {
|
||||||
let deg = angle.to_degrees();
|
let deg = angle.to_degrees();
|
||||||
let result = ((deg % 360.0) + 360.0) % 360.0;
|
let result = ((deg % 360.0) + 360.0) % 360.0;
|
||||||
Angle::from_degrees(if result > 180.0 { result - 360.0 } else { result })
|
Angle::from_degrees(if result > 180.0 { result - 360.0 } else { result })
|
||||||
@ -55,7 +70,7 @@ pub fn normalize(angle: Angle) -> Angle {
|
|||||||
/// Angle::from_radians(PI / 8.0)
|
/// Angle::from_radians(PI / 8.0)
|
||||||
/// );
|
/// );
|
||||||
/// ```
|
/// ```
|
||||||
pub fn delta(from_angle: Angle, to_angle: Angle) -> Angle {
|
pub(crate) fn delta(from_angle: Angle, to_angle: Angle) -> Angle {
|
||||||
let norm_from_angle = normalize_rad(from_angle.to_radians());
|
let norm_from_angle = normalize_rad(from_angle.to_radians());
|
||||||
let norm_to_angle = normalize_rad(to_angle.to_radians());
|
let norm_to_angle = normalize_rad(to_angle.to_radians());
|
||||||
let provisional = norm_to_angle - norm_from_angle;
|
let provisional = norm_to_angle - norm_from_angle;
|
||||||
@ -72,7 +87,7 @@ pub fn delta(from_angle: Angle, to_angle: Angle) -> Angle {
|
|||||||
Angle::default()
|
Angle::default()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn normalize_rad(angle: f64) -> f64 {
|
pub(crate) fn normalize_rad(angle: f64) -> f64 {
|
||||||
let draft = angle % (2.0 * PI);
|
let draft = angle % (2.0 * PI);
|
||||||
if draft < 0.0 {
|
if draft < 0.0 {
|
||||||
draft + 2.0 * PI
|
draft + 2.0 * PI
|
||||||
@ -106,7 +121,7 @@ fn intersect(p1: Coords2d, p2: Coords2d, p3: Coords2d, p4: Coords2d) -> Coords2d
|
|||||||
[x, y]
|
[x, y]
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn intersection_with_parallel_line(
|
pub(crate) fn intersection_with_parallel_line(
|
||||||
line1: &[Coords2d; 2],
|
line1: &[Coords2d; 2],
|
||||||
line1_offset: f64,
|
line1_offset: f64,
|
||||||
line2_angle: f64,
|
line2_angle: f64,
|
||||||
@ -128,7 +143,7 @@ fn offset_line(offset: f64, p1: Coords2d, p2: Coords2d) -> [Coords2d; 2] {
|
|||||||
[[p1[0] + x_offset, p1[1]], [p2[0] + x_offset, p2[1]]]
|
[[p1[0] + x_offset, p1[1]], [p2[0] + x_offset, p2[1]]]
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_y_component(angle: Angle, x: f64) -> Coords2d {
|
pub(crate) fn get_y_component(angle: Angle, x: f64) -> Coords2d {
|
||||||
let normalised_angle = ((angle.to_degrees() % 360.0) + 360.0) % 360.0; // between 0 and 360
|
let normalised_angle = ((angle.to_degrees() % 360.0) + 360.0) % 360.0; // between 0 and 360
|
||||||
let y = x * f64::tan(normalised_angle.to_radians());
|
let y = x * f64::tan(normalised_angle.to_radians());
|
||||||
let sign = if normalised_angle > 90.0 && normalised_angle <= 270.0 {
|
let sign = if normalised_angle > 90.0 && normalised_angle <= 270.0 {
|
||||||
@ -139,7 +154,7 @@ pub fn get_y_component(angle: Angle, x: f64) -> Coords2d {
|
|||||||
[x * sign, y * sign]
|
[x * sign, y * sign]
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_x_component(angle: Angle, y: f64) -> Coords2d {
|
pub(crate) fn get_x_component(angle: Angle, y: f64) -> Coords2d {
|
||||||
let normalised_angle = ((angle.to_degrees() % 360.0) + 360.0) % 360.0; // between 0 and 360
|
let normalised_angle = ((angle.to_degrees() % 360.0) + 360.0) % 360.0; // between 0 and 360
|
||||||
let x = y / f64::tan(normalised_angle.to_radians());
|
let x = y / f64::tan(normalised_angle.to_radians());
|
||||||
let sign = if normalised_angle > 180.0 && normalised_angle <= 360.0 {
|
let sign = if normalised_angle > 180.0 && normalised_angle <= 360.0 {
|
||||||
@ -150,7 +165,12 @@ pub fn get_x_component(angle: Angle, y: f64) -> Coords2d {
|
|||||||
[x * sign, y * sign]
|
[x * sign, y * sign]
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn arc_center_and_end(from: Coords2d, start_angle: Angle, end_angle: Angle, radius: f64) -> (Coords2d, Coords2d) {
|
pub(crate) fn arc_center_and_end(
|
||||||
|
from: Coords2d,
|
||||||
|
start_angle: Angle,
|
||||||
|
end_angle: Angle,
|
||||||
|
radius: f64,
|
||||||
|
) -> (Coords2d, Coords2d) {
|
||||||
let start_angle = start_angle.to_radians();
|
let start_angle = start_angle.to_radians();
|
||||||
let end_angle = end_angle.to_radians();
|
let end_angle = end_angle.to_radians();
|
||||||
|
|
||||||
@ -167,56 +187,9 @@ pub fn arc_center_and_end(from: Coords2d, start_angle: Angle, end_angle: Angle,
|
|||||||
(center, end)
|
(center, end)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn arc_angles(
|
|
||||||
from: Coords2d,
|
|
||||||
to: Coords2d,
|
|
||||||
center: Coords2d,
|
|
||||||
radius: f64,
|
|
||||||
source_range: SourceRange,
|
|
||||||
) -> Result<(Angle, Angle), KclError> {
|
|
||||||
// First make sure that the points are on the circumference of the circle.
|
|
||||||
// If not, we'll return an error.
|
|
||||||
if !is_on_circumference(center, from, radius) {
|
|
||||||
return Err(KclError::Semantic(KclErrorDetails {
|
|
||||||
message: format!(
|
|
||||||
"Point {:?} is not on the circumference of the circle with center {:?} and radius {}.",
|
|
||||||
from, center, radius
|
|
||||||
),
|
|
||||||
source_ranges: vec![source_range],
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
if !is_on_circumference(center, to, radius) {
|
|
||||||
return Err(KclError::Semantic(KclErrorDetails {
|
|
||||||
message: format!(
|
|
||||||
"Point {:?} is not on the circumference of the circle with center {:?} and radius {}.",
|
|
||||||
to, center, radius
|
|
||||||
),
|
|
||||||
source_ranges: vec![source_range],
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
let start_angle = (from[1] - center[1]).atan2(from[0] - center[0]);
|
|
||||||
let end_angle = (to[1] - center[1]).atan2(to[0] - center[0]);
|
|
||||||
|
|
||||||
Ok((Angle::from_radians(start_angle), Angle::from_radians(end_angle)))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn is_on_circumference(center: Coords2d, point: Coords2d, radius: f64) -> bool {
|
|
||||||
let dx = point[0] - center[0];
|
|
||||||
let dy = point[1] - center[1];
|
|
||||||
|
|
||||||
let distance_squared = dx.powi(2) + dy.powi(2);
|
|
||||||
|
|
||||||
// We'll check if the distance squared is approximately equal to radius squared.
|
|
||||||
// Due to potential floating point inaccuracies, we'll check if the difference
|
|
||||||
// is very small (e.g., 1e-9) rather than checking for strict equality.
|
|
||||||
(distance_squared - radius.powi(2)).abs() < 1e-9
|
|
||||||
}
|
|
||||||
|
|
||||||
// Calculate the center of 3 points using an algebraic method
|
// Calculate the center of 3 points using an algebraic method
|
||||||
// Handles if 3 points lie on the same line (collinear) by returning the average of the points (could return None instead..)
|
// Handles if 3 points lie on the same line (collinear) by returning the average of the points (could return None instead..)
|
||||||
pub fn calculate_circle_center(p1: [f64; 2], p2: [f64; 2], p3: [f64; 2]) -> [f64; 2] {
|
pub(crate) fn calculate_circle_center(p1: [f64; 2], p2: [f64; 2], p3: [f64; 2]) -> [f64; 2] {
|
||||||
let (x1, y1) = (p1[0], p1[1]);
|
let (x1, y1) = (p1[0], p1[1]);
|
||||||
let (x2, y2) = (p2[0], p2[1]);
|
let (x2, y2) = (p2[0], p2[1]);
|
||||||
let (x3, y3) = (p3[0], p3[1]);
|
let (x3, y3) = (p3[0], p3[1]);
|
||||||
@ -268,7 +241,6 @@ mod tests {
|
|||||||
use std::f64::consts::TAU;
|
use std::f64::consts::TAU;
|
||||||
|
|
||||||
use super::{calculate_circle_center, get_x_component, get_y_component, Angle};
|
use super::{calculate_circle_center, get_x_component, get_y_component, Angle};
|
||||||
use crate::SourceRange;
|
|
||||||
|
|
||||||
static EACH_QUAD: [(i32, [i32; 2]); 12] = [
|
static EACH_QUAD: [(i32, [i32; 2]); 12] = [
|
||||||
(-315, [1, 1]),
|
(-315, [1, 1]),
|
||||||
@ -366,34 +338,6 @@ mod tests {
|
|||||||
assert_eq!(end[1].round(), 0.0);
|
assert_eq!(end[1].round(), 0.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_arc_angles() {
|
|
||||||
let (angle_start, angle_end) =
|
|
||||||
super::arc_angles([0.0, 0.0], [-1.0, 1.0], [-1.0, 0.0], 1.0, SourceRange::default()).unwrap();
|
|
||||||
assert_eq!(angle_start.to_degrees().round(), 0.0);
|
|
||||||
assert_eq!(angle_end.to_degrees().round(), 90.0);
|
|
||||||
|
|
||||||
let (angle_start, angle_end) =
|
|
||||||
super::arc_angles([0.0, 0.0], [-2.0, 0.0], [-1.0, 0.0], 1.0, SourceRange::default()).unwrap();
|
|
||||||
assert_eq!(angle_start.to_degrees().round(), 0.0);
|
|
||||||
assert_eq!(angle_end.to_degrees().round(), 180.0);
|
|
||||||
|
|
||||||
let (angle_start, angle_end) =
|
|
||||||
super::arc_angles([0.0, 0.0], [-20.0, 0.0], [-10.0, 0.0], 10.0, SourceRange::default()).unwrap();
|
|
||||||
assert_eq!(angle_start.to_degrees().round(), 0.0);
|
|
||||||
assert_eq!(angle_end.to_degrees().round(), 180.0);
|
|
||||||
|
|
||||||
let result = super::arc_angles([0.0, 5.0], [5.0, 5.0], [10.0, -10.0], 10.0, SourceRange::default());
|
|
||||||
|
|
||||||
if let Err(err) = result {
|
|
||||||
assert!(err.to_string().contains("Point [0.0, 5.0] is not on the circumference of the circle with center [10.0, -10.0] and radius 10."), "found: `{}`", err);
|
|
||||||
} else {
|
|
||||||
panic!("Expected error");
|
|
||||||
}
|
|
||||||
assert_eq!(angle_start.to_degrees().round(), 0.0);
|
|
||||||
assert_eq!(angle_end.to_degrees().round(), 180.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_calculate_circle_center() {
|
fn test_calculate_circle_center() {
|
||||||
const EPS: f64 = 1e-4;
|
const EPS: f64 = 1e-4;
|
||||||
@ -464,7 +408,7 @@ mod tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type Coords2d = [f64; 2];
|
pub(crate) type Coords2d = [f64; 2];
|
||||||
|
|
||||||
pub fn is_points_ccw_wasm(points: &[f64]) -> i32 {
|
pub fn is_points_ccw_wasm(points: &[f64]) -> i32 {
|
||||||
// CCW is positive as that the Math convention
|
// CCW is positive as that the Math convention
|
||||||
@ -478,7 +422,7 @@ pub fn is_points_ccw_wasm(points: &[f64]) -> i32 {
|
|||||||
sum.signum() as i32
|
sum.signum() as i32
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_points_ccw(points: &[Coords2d]) -> i32 {
|
pub(crate) fn is_points_ccw(points: &[Coords2d]) -> i32 {
|
||||||
let flattened_points: Vec<f64> = points.iter().flat_map(|&p| vec![p[0], p[1]]).collect();
|
let flattened_points: Vec<f64> = points.iter().flat_map(|&p| vec![p[0], p[1]]).collect();
|
||||||
is_points_ccw_wasm(&flattened_points)
|
is_points_ccw_wasm(&flattened_points)
|
||||||
}
|
}
|
||||||
@ -587,7 +531,6 @@ pub struct TangentialArcInfoInput {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Structure to hold the output data from calculating tangential arc information.
|
/// Structure to hold the output data from calculating tangential arc information.
|
||||||
#[allow(dead_code)]
|
|
||||||
pub struct TangentialArcInfoOutput {
|
pub struct TangentialArcInfoOutput {
|
||||||
/// The center point of the arc.
|
/// The center point of the arc.
|
||||||
pub center: Coords2d,
|
pub center: Coords2d,
|
||||||
@ -851,7 +794,7 @@ mod get_tangential_arc_to_info_tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_tangent_point_from_previous_arc(
|
pub(crate) fn get_tangent_point_from_previous_arc(
|
||||||
last_arc_center: Coords2d,
|
last_arc_center: Coords2d,
|
||||||
last_arc_ccw: bool,
|
last_arc_ccw: bool,
|
||||||
last_arc_end: Coords2d,
|
last_arc_end: Coords2d,
|
||||||
|
@ -35,7 +35,7 @@ pub enum Node<'a> {
|
|||||||
IfExpression(NodeRef<'a, types::IfExpression>),
|
IfExpression(NodeRef<'a, types::IfExpression>),
|
||||||
ElseIf(&'a types::ElseIf),
|
ElseIf(&'a types::ElseIf),
|
||||||
LabelledExpression(NodeRef<'a, types::LabelledExpression>),
|
LabelledExpression(NodeRef<'a, types::LabelledExpression>),
|
||||||
Ascription(NodeRef<'a, types::Ascription>),
|
AscribedExpression(NodeRef<'a, types::AscribedExpression>),
|
||||||
|
|
||||||
Parameter(&'a types::Parameter),
|
Parameter(&'a types::Parameter),
|
||||||
|
|
||||||
@ -79,7 +79,7 @@ impl Node<'_> {
|
|||||||
Node::ElseIf(n) => n.digest,
|
Node::ElseIf(n) => n.digest,
|
||||||
Node::KclNone(n) => n.digest,
|
Node::KclNone(n) => n.digest,
|
||||||
Node::LabelledExpression(n) => n.digest,
|
Node::LabelledExpression(n) => n.digest,
|
||||||
Node::Ascription(n) => n.digest,
|
Node::AscribedExpression(n) => n.digest,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,7 +124,7 @@ impl Node<'_> {
|
|||||||
Node::ElseIf(n) => *n as *const _ as *const (),
|
Node::ElseIf(n) => *n as *const _ as *const (),
|
||||||
Node::KclNone(n) => *n as *const _ as *const (),
|
Node::KclNone(n) => *n as *const _ as *const (),
|
||||||
Node::LabelledExpression(n) => *n as *const _ as *const (),
|
Node::LabelledExpression(n) => *n as *const _ as *const (),
|
||||||
Node::Ascription(n) => *n as *const _ as *const (),
|
Node::AscribedExpression(n) => *n as *const _ as *const (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -167,7 +167,7 @@ impl TryFrom<&Node<'_>> for SourceRange {
|
|||||||
Node::ObjectProperty(n) => SourceRange::from(*n),
|
Node::ObjectProperty(n) => SourceRange::from(*n),
|
||||||
Node::IfExpression(n) => SourceRange::from(*n),
|
Node::IfExpression(n) => SourceRange::from(*n),
|
||||||
Node::LabelledExpression(n) => SourceRange::from(*n),
|
Node::LabelledExpression(n) => SourceRange::from(*n),
|
||||||
Node::Ascription(n) => SourceRange::from(*n),
|
Node::AscribedExpression(n) => SourceRange::from(*n),
|
||||||
|
|
||||||
// This is broken too
|
// This is broken too
|
||||||
Node::ElseIf(n) => SourceRange::new(n.cond.start(), n.cond.end(), n.cond.module_id()),
|
Node::ElseIf(n) => SourceRange::new(n.cond.start(), n.cond.end(), n.cond.module_id()),
|
||||||
@ -296,7 +296,7 @@ impl_from_ref!(Node, Parameter);
|
|||||||
impl_from!(Node, IfExpression);
|
impl_from!(Node, IfExpression);
|
||||||
impl_from!(Node, ElseIf);
|
impl_from!(Node, ElseIf);
|
||||||
impl_from!(Node, LabelledExpression);
|
impl_from!(Node, LabelledExpression);
|
||||||
impl_from!(Node, Ascription);
|
impl_from!(Node, AscribedExpression);
|
||||||
impl_from!(Node, KclNone);
|
impl_from!(Node, KclNone);
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -131,7 +131,7 @@ impl<'tree> Visitable<'tree> for Node<'tree> {
|
|||||||
Node::LabelledExpression(e) => {
|
Node::LabelledExpression(e) => {
|
||||||
vec![(&e.expr).into(), (&e.label).into()]
|
vec![(&e.expr).into(), (&e.label).into()]
|
||||||
}
|
}
|
||||||
Node::Ascription(e) => {
|
Node::AscribedExpression(e) => {
|
||||||
vec![(&e.expr).into()]
|
vec![(&e.expr).into()]
|
||||||
}
|
}
|
||||||
Node::Name(n) => Some((&n.name).into())
|
Node::Name(n) => Some((&n.name).into())
|
||||||
|
@ -54,7 +54,7 @@ export TAU = 6.28318530717958647692528676655900577_
|
|||||||
/// |> startProfileAt([0, 0], %)
|
/// |> startProfileAt([0, 0], %)
|
||||||
/// |> angledLine(
|
/// |> angledLine(
|
||||||
/// angle = 30,
|
/// angle = 30,
|
||||||
/// length = 3 / cos(toRadians(30)),
|
/// length = 3 / cos(30deg),
|
||||||
/// )
|
/// )
|
||||||
/// |> yLine(endAbsolute = 0)
|
/// |> yLine(endAbsolute = 0)
|
||||||
/// |> close()
|
/// |> close()
|
||||||
@ -71,7 +71,7 @@ export fn cos(@num: number(Angle)): number(_) {}
|
|||||||
/// |> startProfileAt([0, 0], %)
|
/// |> startProfileAt([0, 0], %)
|
||||||
/// |> angledLine(
|
/// |> angledLine(
|
||||||
/// angle = 50,
|
/// angle = 50,
|
||||||
/// length = 15 / sin(toRadians(135)),
|
/// length = 15 / sin(135deg),
|
||||||
/// )
|
/// )
|
||||||
/// |> yLine(endAbsolute = 0)
|
/// |> yLine(endAbsolute = 0)
|
||||||
/// |> close()
|
/// |> close()
|
||||||
@ -88,7 +88,7 @@ export fn sin(@num: number(Angle)): number(_) {}
|
|||||||
/// |> startProfileAt([0, 0], %)
|
/// |> startProfileAt([0, 0], %)
|
||||||
/// |> angledLine(
|
/// |> angledLine(
|
||||||
/// angle = 50,
|
/// angle = 50,
|
||||||
/// length = 50 * tan(1/2),
|
/// length = 50 * tan((1/2): number(rad)),
|
||||||
/// )
|
/// )
|
||||||
/// |> yLine(endAbsolute = 0)
|
/// |> yLine(endAbsolute = 0)
|
||||||
/// |> close()
|
/// |> close()
|
||||||
@ -112,10 +112,8 @@ export fn tan(@num: number(Angle)): number(_) {}
|
|||||||
///
|
///
|
||||||
/// example = extrude(exampleSketch, length = 5)
|
/// example = extrude(exampleSketch, length = 5)
|
||||||
/// ```
|
/// ```
|
||||||
export fn polar(angle: number(Angle), length: number(Length)): Point2d {
|
export fn polar(angle: number(rad), length: number(Length)): Point2d {
|
||||||
// TODO could be done by implicit conversion when UoM coercions are activated.
|
x = length * cos(angle)
|
||||||
rads = toRadians(angle)
|
y = length * sin(angle)
|
||||||
x = length * cos(rads)
|
|
||||||
y = length * sin(rads)
|
|
||||||
return [x, y]
|
return [x, y]
|
||||||
}
|
}
|
||||||
|
@ -128,7 +128,7 @@ export END = 'end'
|
|||||||
export fn helix(
|
export fn helix(
|
||||||
/// Number of revolutions.
|
/// Number of revolutions.
|
||||||
revolutions: number(_),
|
revolutions: number(_),
|
||||||
/// Start angle (in degrees).
|
/// Start angle.
|
||||||
angleStart: number(Angle),
|
angleStart: number(Angle),
|
||||||
/// Is the helix rotation counter clockwise? The default is `false`.
|
/// Is the helix rotation counter clockwise? The default is `false`.
|
||||||
ccw?: bool,
|
ccw?: bool,
|
||||||
@ -383,3 +383,69 @@ export fn revolve(
|
|||||||
/// A named tag for the face at the end of the revolve.
|
/// A named tag for the face at the end of the revolve.
|
||||||
tagEnd?: tag,
|
tagEnd?: tag,
|
||||||
): Solid {}
|
): Solid {}
|
||||||
|
|
||||||
|
/// Convert a number to millimeters from its current units.
|
||||||
|
export fn toMillimeters(@num: number(mm)): number(mm) {
|
||||||
|
return num
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Convert a number to centimeters from its current units.
|
||||||
|
export fn toCentimeters(@num: number(cm)): number(cm) {
|
||||||
|
return num
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Convert a number to meters from its current units.
|
||||||
|
export fn toMeters(@num: number(m)): number(m) {
|
||||||
|
return num
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Convert a number to inches from its current units.
|
||||||
|
export fn toInches(@num: number(in)): number(in) {
|
||||||
|
return num
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Convert a number to feet from its current units.
|
||||||
|
export fn toFeet(@num: number(ft)): number(ft) {
|
||||||
|
return num
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Converts a number to yards from its current units.
|
||||||
|
export fn toYards(@num: number(yd)): number(yd) {
|
||||||
|
return num
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Converts a number to radians from its current units.
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// exampleSketch = startSketchOn(XZ)
|
||||||
|
/// |> startProfileAt([0, 0], %)
|
||||||
|
/// |> angledLine(
|
||||||
|
/// angle = 50,
|
||||||
|
/// length = 70 * cos(toRadians(45)),
|
||||||
|
/// )
|
||||||
|
/// |> yLine(endAbsolute = 0)
|
||||||
|
/// |> close()
|
||||||
|
///
|
||||||
|
/// example = extrude(exampleSketch, length = 5)
|
||||||
|
/// ```
|
||||||
|
export fn toRadians(@num: number(rad)): number(rad) {
|
||||||
|
return num
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Converts a number to degrees from its current units.
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// exampleSketch = startSketchOn(XZ)
|
||||||
|
/// |> startProfileAt([0, 0], %)
|
||||||
|
/// |> angledLine(
|
||||||
|
/// angle = 50,
|
||||||
|
/// length = 70 * cos(toDegrees((PI/4): number(rad))),
|
||||||
|
/// )
|
||||||
|
/// |> yLine(endAbsolute = 0)
|
||||||
|
/// |> close()
|
||||||
|
///
|
||||||
|
/// example = extrude(exampleSketch, length = 5)
|
||||||
|
/// ```
|
||||||
|
export fn toDegrees(@num: number(deg)): number(deg) {
|
||||||
|
return num
|
||||||
|
}
|
||||||
|
@ -28,37 +28,5 @@ description: Artifact commands add_lots.kcl
|
|||||||
"object_id": "[uuid]",
|
"object_id": "[uuid]",
|
||||||
"hidden": true
|
"hidden": true
|
||||||
}
|
}
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -360,37 +360,5 @@ description: Artifact commands angled_line.kcl
|
|||||||
"edge_id": "[uuid]",
|
"edge_id": "[uuid]",
|
||||||
"face_id": "[uuid]"
|
"face_id": "[uuid]"
|
||||||
}
|
}
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -220,9 +220,6 @@ description: Variables in memory after executing angled_line.kcl
|
|||||||
"units": {
|
"units": {
|
||||||
"type": "Mm"
|
"type": "Mm"
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"units": {
|
|
||||||
"type": "Mm"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"start": {
|
"start": {
|
||||||
|
@ -28,37 +28,5 @@ description: Artifact commands argument_error.kcl
|
|||||||
"object_id": "[uuid]",
|
"object_id": "[uuid]",
|
||||||
"hidden": true
|
"hidden": true
|
||||||
}
|
}
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -28,37 +28,5 @@ description: Artifact commands array_elem_pop.kcl
|
|||||||
"object_id": "[uuid]",
|
"object_id": "[uuid]",
|
||||||
"hidden": true
|
"hidden": true
|
||||||
}
|
}
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -28,37 +28,5 @@ description: Artifact commands array_elem_pop_empty_fail.kcl
|
|||||||
"object_id": "[uuid]",
|
"object_id": "[uuid]",
|
||||||
"hidden": true
|
"hidden": true
|
||||||
}
|
}
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -28,37 +28,5 @@ description: Artifact commands array_elem_pop_fail.kcl
|
|||||||
"object_id": "[uuid]",
|
"object_id": "[uuid]",
|
||||||
"hidden": true
|
"hidden": true
|
||||||
}
|
}
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -28,37 +28,5 @@ description: Artifact commands array_elem_push.kcl
|
|||||||
"object_id": "[uuid]",
|
"object_id": "[uuid]",
|
||||||
"hidden": true
|
"hidden": true
|
||||||
}
|
}
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -28,37 +28,5 @@ description: Artifact commands array_elem_push_fail.kcl
|
|||||||
"object_id": "[uuid]",
|
"object_id": "[uuid]",
|
||||||
"hidden": true
|
"hidden": true
|
||||||
}
|
}
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -28,37 +28,5 @@ description: Artifact commands array_index_oob.kcl
|
|||||||
"object_id": "[uuid]",
|
"object_id": "[uuid]",
|
||||||
"hidden": true
|
"hidden": true
|
||||||
}
|
}
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -28,37 +28,5 @@ description: Artifact commands array_range_expr.kcl
|
|||||||
"object_id": "[uuid]",
|
"object_id": "[uuid]",
|
||||||
"hidden": true
|
"hidden": true
|
||||||
}
|
}
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -28,37 +28,5 @@ description: Artifact commands array_range_negative_expr.kcl
|
|||||||
"object_id": "[uuid]",
|
"object_id": "[uuid]",
|
||||||
"hidden": true
|
"hidden": true
|
||||||
}
|
}
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -520,37 +520,5 @@ description: Artifact commands artifact_graph_example_code1.kcl
|
|||||||
"edge_id": "[uuid]",
|
"edge_id": "[uuid]",
|
||||||
"face_id": "[uuid]"
|
"face_id": "[uuid]"
|
||||||
}
|
}
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -199,9 +199,6 @@ description: Variables in memory after executing artifact_graph_example_code1.kc
|
|||||||
"units": {
|
"units": {
|
||||||
"type": "Mm"
|
"type": "Mm"
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"units": {
|
|
||||||
"type": "Mm"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"start": {
|
"start": {
|
||||||
@ -599,9 +596,6 @@ description: Variables in memory after executing artifact_graph_example_code1.kc
|
|||||||
"units": {
|
"units": {
|
||||||
"type": "Mm"
|
"type": "Mm"
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"units": {
|
|
||||||
"type": "Mm"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"start": {
|
"start": {
|
||||||
@ -861,9 +855,6 @@ description: Variables in memory after executing artifact_graph_example_code1.kc
|
|||||||
"units": {
|
"units": {
|
||||||
"type": "Mm"
|
"type": "Mm"
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"units": {
|
|
||||||
"type": "Mm"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"start": {
|
"start": {
|
||||||
@ -1207,9 +1198,6 @@ description: Variables in memory after executing artifact_graph_example_code1.kc
|
|||||||
"units": {
|
"units": {
|
||||||
"type": "Mm"
|
"type": "Mm"
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"units": {
|
|
||||||
"type": "Mm"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"start": {
|
"start": {
|
||||||
|
@ -291,37 +291,5 @@ description: Artifact commands artifact_graph_example_code_no_3d.kcl
|
|||||||
"angle_snap_increment": null
|
"angle_snap_increment": null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -174,9 +174,6 @@ description: Variables in memory after executing artifact_graph_example_code_no_
|
|||||||
"units": {
|
"units": {
|
||||||
"type": "Mm"
|
"type": "Mm"
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"units": {
|
|
||||||
"type": "Mm"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"start": {
|
"start": {
|
||||||
@ -328,9 +325,6 @@ description: Variables in memory after executing artifact_graph_example_code_no_
|
|||||||
"units": {
|
"units": {
|
||||||
"type": "Mm"
|
"type": "Mm"
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"units": {
|
|
||||||
"type": "Mm"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"start": {
|
"start": {
|
||||||
|
@ -214,37 +214,5 @@ description: Artifact commands artifact_graph_example_code_offset_planes.kcl
|
|||||||
"object_id": "[uuid]",
|
"object_id": "[uuid]",
|
||||||
"hidden": true
|
"hidden": true
|
||||||
}
|
}
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -40,9 +40,6 @@ description: Variables in memory after executing artifact_graph_example_code_off
|
|||||||
"units": {
|
"units": {
|
||||||
"type": "Mm"
|
"type": "Mm"
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"units": {
|
|
||||||
"type": "Mm"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -83,9 +80,6 @@ description: Variables in memory after executing artifact_graph_example_code_off
|
|||||||
"units": {
|
"units": {
|
||||||
"type": "Mm"
|
"type": "Mm"
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"units": {
|
|
||||||
"type": "Mm"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -126,9 +120,6 @@ description: Variables in memory after executing artifact_graph_example_code_off
|
|||||||
"units": {
|
"units": {
|
||||||
"type": "Mm"
|
"type": "Mm"
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"units": {
|
|
||||||
"type": "Mm"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -194,9 +185,6 @@ description: Variables in memory after executing artifact_graph_example_code_off
|
|||||||
"units": {
|
"units": {
|
||||||
"type": "Mm"
|
"type": "Mm"
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"units": {
|
|
||||||
"type": "Mm"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"start": {
|
"start": {
|
||||||
|
@ -881,37 +881,5 @@ description: Artifact commands artifact_graph_sketch_on_face_etc.kcl
|
|||||||
"edge_id": "[uuid]",
|
"edge_id": "[uuid]",
|
||||||
"face_id": "[uuid]"
|
"face_id": "[uuid]"
|
||||||
}
|
}
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -161,9 +161,6 @@ description: Variables in memory after executing artifact_graph_sketch_on_face_e
|
|||||||
"units": {
|
"units": {
|
||||||
"type": "Mm"
|
"type": "Mm"
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"units": {
|
|
||||||
"type": "Mm"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"start": {
|
"start": {
|
||||||
@ -499,9 +496,6 @@ description: Variables in memory after executing artifact_graph_sketch_on_face_e
|
|||||||
"units": {
|
"units": {
|
||||||
"type": "Mm"
|
"type": "Mm"
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"units": {
|
|
||||||
"type": "Mm"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"start": {
|
"start": {
|
||||||
@ -1021,9 +1015,6 @@ description: Variables in memory after executing artifact_graph_sketch_on_face_e
|
|||||||
"units": {
|
"units": {
|
||||||
"type": "Mm"
|
"type": "Mm"
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"units": {
|
|
||||||
"type": "Mm"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"start": {
|
"start": {
|
||||||
@ -1721,9 +1712,6 @@ description: Variables in memory after executing artifact_graph_sketch_on_face_e
|
|||||||
"units": {
|
"units": {
|
||||||
"type": "Mm"
|
"type": "Mm"
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"units": {
|
|
||||||
"type": "Mm"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"start": {
|
"start": {
|
||||||
@ -2010,9 +1998,6 @@ description: Variables in memory after executing artifact_graph_sketch_on_face_e
|
|||||||
"units": {
|
"units": {
|
||||||
"type": "Mm"
|
"type": "Mm"
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"units": {
|
|
||||||
"type": "Mm"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"start": {
|
"start": {
|
||||||
@ -2314,9 +2299,6 @@ description: Variables in memory after executing artifact_graph_sketch_on_face_e
|
|||||||
"units": {
|
"units": {
|
||||||
"type": "Mm"
|
"type": "Mm"
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"units": {
|
|
||||||
"type": "Mm"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"start": {
|
"start": {
|
||||||
@ -2796,9 +2778,6 @@ description: Variables in memory after executing artifact_graph_sketch_on_face_e
|
|||||||
"units": {
|
"units": {
|
||||||
"type": "Mm"
|
"type": "Mm"
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"units": {
|
|
||||||
"type": "Mm"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"start": {
|
"start": {
|
||||||
@ -3462,9 +3441,6 @@ description: Variables in memory after executing artifact_graph_sketch_on_face_e
|
|||||||
"units": {
|
"units": {
|
||||||
"type": "Mm"
|
"type": "Mm"
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"units": {
|
|
||||||
"type": "Mm"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"start": {
|
"start": {
|
||||||
|
@ -29,54 +29,6 @@ description: Artifact commands assembly_mixed_units_cubes.kcl
|
|||||||
"hidden": true
|
"hidden": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "in"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "in"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"cmdId": "[uuid]",
|
"cmdId": "[uuid]",
|
||||||
"range": [],
|
"range": [],
|
||||||
@ -132,8 +84,8 @@ description: Artifact commands assembly_mixed_units_cubes.kcl
|
|||||||
"type": "move_path_pen",
|
"type": "move_path_pen",
|
||||||
"path": "[uuid]",
|
"path": "[uuid]",
|
||||||
"to": {
|
"to": {
|
||||||
"x": -10.0,
|
"x": -254.0,
|
||||||
"y": -10.0,
|
"y": -254.0,
|
||||||
"z": 0.0
|
"z": 0.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -154,7 +106,7 @@ description: Artifact commands assembly_mixed_units_cubes.kcl
|
|||||||
"segment": {
|
"segment": {
|
||||||
"type": "line",
|
"type": "line",
|
||||||
"end": {
|
"end": {
|
||||||
"x": 5.0,
|
"x": 127.0,
|
||||||
"y": 0.0,
|
"y": 0.0,
|
||||||
"z": 0.0
|
"z": 0.0
|
||||||
},
|
},
|
||||||
@ -172,7 +124,7 @@ description: Artifact commands assembly_mixed_units_cubes.kcl
|
|||||||
"type": "line",
|
"type": "line",
|
||||||
"end": {
|
"end": {
|
||||||
"x": 0.0,
|
"x": 0.0,
|
||||||
"y": -5.0,
|
"y": -127.0,
|
||||||
"z": 0.0
|
"z": 0.0
|
||||||
},
|
},
|
||||||
"relative": true
|
"relative": true
|
||||||
@ -188,7 +140,7 @@ description: Artifact commands assembly_mixed_units_cubes.kcl
|
|||||||
"segment": {
|
"segment": {
|
||||||
"type": "line",
|
"type": "line",
|
||||||
"end": {
|
"end": {
|
||||||
"x": -5.0,
|
"x": -127.0,
|
||||||
"y": 0.0,
|
"y": 0.0,
|
||||||
"z": 0.0
|
"z": 0.0
|
||||||
},
|
},
|
||||||
@ -205,8 +157,8 @@ description: Artifact commands assembly_mixed_units_cubes.kcl
|
|||||||
"segment": {
|
"segment": {
|
||||||
"type": "line",
|
"type": "line",
|
||||||
"end": {
|
"end": {
|
||||||
"x": -10.0,
|
"x": -254.0,
|
||||||
"y": -10.0,
|
"y": -254.0,
|
||||||
"z": 0.0
|
"z": 0.0
|
||||||
},
|
},
|
||||||
"relative": false
|
"relative": false
|
||||||
@ -243,7 +195,7 @@ description: Artifact commands assembly_mixed_units_cubes.kcl
|
|||||||
"command": {
|
"command": {
|
||||||
"type": "extrude",
|
"type": "extrude",
|
||||||
"target": "[uuid]",
|
"target": "[uuid]",
|
||||||
"distance": 5.0,
|
"distance": 127.0,
|
||||||
"faces": null,
|
"faces": null,
|
||||||
"opposite": "None"
|
"opposite": "None"
|
||||||
}
|
}
|
||||||
@ -352,14 +304,6 @@ description: Artifact commands assembly_mixed_units_cubes.kcl
|
|||||||
"face_id": "[uuid]"
|
"face_id": "[uuid]"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"cmdId": "[uuid]",
|
"cmdId": "[uuid]",
|
||||||
"range": [],
|
"range": [],
|
||||||
|
@ -29,54 +29,6 @@ description: Artifact commands assembly_non_default_units.kcl
|
|||||||
"hidden": true
|
"hidden": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "in"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "in"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"cmdId": "[uuid]",
|
"cmdId": "[uuid]",
|
||||||
"range": [],
|
"range": [],
|
||||||
@ -132,7 +84,7 @@ description: Artifact commands assembly_non_default_units.kcl
|
|||||||
"type": "move_path_pen",
|
"type": "move_path_pen",
|
||||||
"path": "[uuid]",
|
"path": "[uuid]",
|
||||||
"to": {
|
"to": {
|
||||||
"x": 1.0,
|
"x": 25.4,
|
||||||
"y": 0.0,
|
"y": 0.0,
|
||||||
"z": 0.0
|
"z": 0.0
|
||||||
}
|
}
|
||||||
@ -157,7 +109,7 @@ description: Artifact commands assembly_non_default_units.kcl
|
|||||||
"x": 0.0,
|
"x": 0.0,
|
||||||
"y": 0.0
|
"y": 0.0
|
||||||
},
|
},
|
||||||
"radius": 1.0,
|
"radius": 25.4,
|
||||||
"start": {
|
"start": {
|
||||||
"unit": "degrees",
|
"unit": "degrees",
|
||||||
"value": 0.0
|
"value": 0.0
|
||||||
@ -178,14 +130,6 @@ description: Artifact commands assembly_non_default_units.kcl
|
|||||||
"path_id": "[uuid]"
|
"path_id": "[uuid]"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "in"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"cmdId": "[uuid]",
|
"cmdId": "[uuid]",
|
||||||
"range": [],
|
"range": [],
|
||||||
@ -241,8 +185,8 @@ description: Artifact commands assembly_non_default_units.kcl
|
|||||||
"type": "move_path_pen",
|
"type": "move_path_pen",
|
||||||
"path": "[uuid]",
|
"path": "[uuid]",
|
||||||
"to": {
|
"to": {
|
||||||
"x": 1.0,
|
"x": 25.4,
|
||||||
"y": 2.0,
|
"y": 50.8,
|
||||||
"z": 0.0
|
"z": 0.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -264,9 +208,9 @@ description: Artifact commands assembly_non_default_units.kcl
|
|||||||
"type": "arc",
|
"type": "arc",
|
||||||
"center": {
|
"center": {
|
||||||
"x": 0.0,
|
"x": 0.0,
|
||||||
"y": 2.0
|
"y": 50.8
|
||||||
},
|
},
|
||||||
"radius": 1.0,
|
"radius": 25.4,
|
||||||
"start": {
|
"start": {
|
||||||
"unit": "degrees",
|
"unit": "degrees",
|
||||||
"value": 0.0
|
"value": 0.0
|
||||||
@ -286,13 +230,5 @@ description: Artifact commands assembly_non_default_units.kcl
|
|||||||
"type": "close_path",
|
"type": "close_path",
|
||||||
"path_id": "[uuid]"
|
"path_id": "[uuid]"
|
||||||
}
|
}
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "in"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -28,37 +28,5 @@ description: Artifact commands bad_units_in_annotation.kcl
|
|||||||
"object_id": "[uuid]",
|
"object_id": "[uuid]",
|
||||||
"hidden": true
|
"hidden": true
|
||||||
}
|
}
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -320,37 +320,5 @@ description: Artifact commands basic_fillet_cube_close_opposite.kcl
|
|||||||
"tolerance": 0.0000001,
|
"tolerance": 0.0000001,
|
||||||
"cut_type": "fillet"
|
"cut_type": "fillet"
|
||||||
}
|
}
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -192,9 +192,6 @@ description: Variables in memory after executing basic_fillet_cube_close_opposit
|
|||||||
"units": {
|
"units": {
|
||||||
"type": "Mm"
|
"type": "Mm"
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"units": {
|
|
||||||
"type": "Mm"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"start": {
|
"start": {
|
||||||
|
@ -320,37 +320,5 @@ description: Artifact commands basic_fillet_cube_end.kcl
|
|||||||
"tolerance": 0.0000001,
|
"tolerance": 0.0000001,
|
||||||
"cut_type": "fillet"
|
"cut_type": "fillet"
|
||||||
}
|
}
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -180,9 +180,6 @@ description: Variables in memory after executing basic_fillet_cube_end.kcl
|
|||||||
"units": {
|
"units": {
|
||||||
"type": "Mm"
|
"type": "Mm"
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"units": {
|
|
||||||
"type": "Mm"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"start": {
|
"start": {
|
||||||
|
@ -308,37 +308,5 @@ description: Artifact commands basic_fillet_cube_next_adjacent.kcl
|
|||||||
"tolerance": 0.0000001,
|
"tolerance": 0.0000001,
|
||||||
"cut_type": "fillet"
|
"cut_type": "fillet"
|
||||||
}
|
}
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -204,9 +204,6 @@ description: Variables in memory after executing basic_fillet_cube_next_adjacent
|
|||||||
"units": {
|
"units": {
|
||||||
"type": "Mm"
|
"type": "Mm"
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"units": {
|
|
||||||
"type": "Mm"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"start": {
|
"start": {
|
||||||
|
@ -308,37 +308,5 @@ description: Artifact commands basic_fillet_cube_previous_adjacent.kcl
|
|||||||
"tolerance": 0.0000001,
|
"tolerance": 0.0000001,
|
||||||
"cut_type": "fillet"
|
"cut_type": "fillet"
|
||||||
}
|
}
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -204,9 +204,6 @@ description: Variables in memory after executing basic_fillet_cube_previous_adja
|
|||||||
"units": {
|
"units": {
|
||||||
"type": "Mm"
|
"type": "Mm"
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"units": {
|
|
||||||
"type": "Mm"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"start": {
|
"start": {
|
||||||
|
@ -310,37 +310,5 @@ description: Artifact commands basic_fillet_cube_start.kcl
|
|||||||
"tolerance": 0.0000001,
|
"tolerance": 0.0000001,
|
||||||
"cut_type": "fillet"
|
"cut_type": "fillet"
|
||||||
}
|
}
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -180,9 +180,6 @@ description: Variables in memory after executing basic_fillet_cube_start.kcl
|
|||||||
"units": {
|
"units": {
|
||||||
"type": "Mm"
|
"type": "Mm"
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"units": {
|
|
||||||
"type": "Mm"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"start": {
|
"start": {
|
||||||
|
@ -249,37 +249,5 @@ description: Artifact commands big_number_angle_to_match_length_x.kcl
|
|||||||
"edge_id": "[uuid]",
|
"edge_id": "[uuid]",
|
||||||
"face_id": "[uuid]"
|
"face_id": "[uuid]"
|
||||||
}
|
}
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -142,9 +142,6 @@ description: Variables in memory after executing big_number_angle_to_match_lengt
|
|||||||
"units": {
|
"units": {
|
||||||
"type": "Mm"
|
"type": "Mm"
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"units": {
|
|
||||||
"type": "Mm"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"start": {
|
"start": {
|
||||||
|
@ -249,37 +249,5 @@ description: Artifact commands big_number_angle_to_match_length_y.kcl
|
|||||||
"edge_id": "[uuid]",
|
"edge_id": "[uuid]",
|
||||||
"face_id": "[uuid]"
|
"face_id": "[uuid]"
|
||||||
}
|
}
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -142,9 +142,6 @@ description: Variables in memory after executing big_number_angle_to_match_lengt
|
|||||||
"units": {
|
"units": {
|
||||||
"type": "Mm"
|
"type": "Mm"
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"units": {
|
|
||||||
"type": "Mm"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"start": {
|
"start": {
|
||||||
|
@ -28,37 +28,5 @@ description: Artifact commands boolean_logical_and.kcl
|
|||||||
"object_id": "[uuid]",
|
"object_id": "[uuid]",
|
||||||
"hidden": true
|
"hidden": true
|
||||||
}
|
}
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user