Compare commits

..

33 Commits

Author SHA1 Message Date
495727d617 hacky shit
Signed-off-by: Jess Frazelle <github@jessfraz.com>
2025-04-05 13:05:04 -07:00
e943303434 logs
Signed-off-by: Jess Frazelle <github@jessfraz.com>
2025-04-05 10:20:35 -07:00
8ce175f006 clippy
Signed-off-by: Jess Frazelle <github@jessfraz.com>
2025-04-05 09:48:45 -07:00
13aa178734 get rid of execution kind
Signed-off-by: Jess Frazelle <github@jessfraz.com>
2025-04-05 09:44:18 -07:00
de137ff13b Merge remote-tracking branch 'origin/main' into jess/changes-import
* origin/main: (26 commits)
  attempt to import win-ca on windows (#6136)
  Upgrade e2e-tests windows runner from 4 cores to 8 (#6166)
  Follow-up fixes after bearing sample rename (#6164)
  Add test for #5799: "Only showing axis planes when there are no errors" (#6007)
  Wait for export button to make test more reliable (#6143)
  sketching on a mirror2d thats been extruded fixed! (#6149)
  Bump vite from 5.4.16 to 5.4.17 in /packages/codemirror-lang-kcl in the security group (#6150)
  Bump vite from 5.4.16 to 5.4.17 in the security group (#6151)
  Update all KCL-Samples to be more ME friendly (#6132)
  Shorten feedback cycle for legitimate failures (#6146)
  Remove the camera projection toggle from the UI (#6077)
  Use all available CPUs to run tests on CI (#6138)
  [fix] Get rid of risky useEffect in restart onboarding flow (#6133)
  Feature: Traditional menu actions in desktop application part II (#6030)
  [Bug] fix some UI friction from imports (#6139)
  Use scene fixture to make test more reliable on macOS (#6140)
  Fix: function composition during playwright setup created a massive page.reload loop (#6137)
  Alternative way to make appMachine spawned children type safe (#5890)
  [BUG] mutate ast to keep comments for pipe split ast-mod (#6128)
  Rename the app to Zoo Design Studio (#5974)
  ...
2025-04-05 09:33:50 -07:00
3504b9246f Merge remote-tracking branch 'origin/main' into paultag/import 2025-04-03 10:15:28 -04:00
a035f7879b Merge remote-tracking branch 'origin/main' into paultag/import 2025-04-02 11:36:59 -04:00
d122d7a224 fix rebase add feature flag
Signed-off-by: Jess Frazelle <github@jessfraz.com>
2025-04-01 12:34:42 -07:00
198e7c4bd2 Merge remote-tracking branch 'origin/main' into paultag/import 2025-04-01 15:18:23 -04:00
14d8903acc man this is bad 2025-04-01 15:16:59 -04:00
275c23f294 chip away more 2025-04-01 13:35:50 -04:00
0ac9ac3896 Reapply "this was a bad idea"
This reverts commit fafdf41093.
2025-04-01 11:56:36 -04:00
0220d0f9de ok 2025-04-01 11:55:08 -04:00
4523dc209b Merge remote-tracking branch 'origin/main' into paultag/import 2025-04-01 11:55:02 -04:00
ea73eb011c :( 2025-03-31 16:51:46 -04:00
0aa2824c20 yike 2025-03-31 16:20:29 -04:00
e66893c5d0 poop 2025-03-31 16:17:35 -04:00
60274127df error 2025-03-31 15:57:13 -04:00
a0d1750829 prepare prelude before spawning 2025-03-31 15:54:35 -04:00
00ffa8c0bf Merge remote-tracking branch 'origin/main' into paultag/import 2025-03-31 15:46:26 -04:00
fafdf41093 Revert "this was a bad idea"
This reverts commit a2092e7ed6.
2025-03-28 17:07:29 -04:00
a2092e7ed6 this was a bad idea 2025-03-28 15:03:13 -04:00
aa103d299c Merge branch 'main' into paultag/import 2025-03-28 14:40:34 -04:00
aaaab495bc Merge remote-tracking branch 'origin' into paultag/import 2025-03-18 16:24:05 -04:00
364e38fda2 Merge remote-tracking branch 'origin' into paultag/import 2025-03-18 09:17:51 -04:00
b085af139b lock start things 2025-03-13 14:58:24 -04:00
ec537cd8dc Merge remote-tracking branch 'origin/main' into paultag/import 2025-03-13 11:17:34 -04:00
8debbc5241 wip 2025-03-13 11:17:22 -04:00
a590ed99cf Merge branch 'main' of github.com:KittyCAD/modeling-app into paultag/import 2025-03-12 12:00:46 -04:00
a002bb60a0 Merge remote-tracking branch 'origin/main' into paultag/import 2025-03-11 16:18:58 -04:00
6ba01b8dfa sketch a bit more; going to pull this out of tests next 2025-03-10 15:43:43 -04:00
ca9e6e0944 Merge remote-tracking branch 'origin/main' into paultag/import 2025-03-10 12:27:50 -04:00
e85e54215c wip 2025-03-10 12:27:47 -04:00
116 changed files with 3804 additions and 5173 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

40
docs/kcl/inch.md Normal file

File diff suppressed because one or more lines are too long

View File

@ -65,15 +65,11 @@ layout: manual
* [`chamfer`](kcl/chamfer)
* [`circleThreePoint`](kcl/circleThreePoint)
* [`close`](kcl/close)
* [`cm`](kcl/cm)
* [`extrude`](kcl/extrude)
* [`fillet`](kcl/fillet)
* [`floor`](kcl/floor)
* [`fromCm`](kcl/fromCm)
* [`fromFt`](kcl/fromFt)
* [`fromInches`](kcl/fromInches)
* [`fromM`](kcl/fromM)
* [`fromMm`](kcl/fromMm)
* [`fromYd`](kcl/fromYd)
* [`ft`](kcl/ft)
* [`getCommonEdge`](kcl/getCommonEdge)
* [`getNextAdjacentEdge`](kcl/getNextAdjacentEdge)
* [`getOppositeEdge`](kcl/getOppositeEdge)
@ -81,6 +77,7 @@ layout: manual
* [`helix`](kcl/std-helix)
* [`hole`](kcl/hole)
* [`hollow`](kcl/hollow)
* [`inch`](kcl/inch)
* [`lastSegX`](kcl/lastSegX)
* [`lastSegY`](kcl/lastSegY)
* [`legAngX`](kcl/legAngX)
@ -92,9 +89,11 @@ layout: manual
* [`log`](kcl/log)
* [`log10`](kcl/log10)
* [`log2`](kcl/log2)
* [`m`](kcl/m)
* [`map`](kcl/map)
* [`max`](kcl/max)
* [`min`](kcl/min)
* [`mm`](kcl/mm)
* [`offsetPlane`](kcl/offsetPlane)
* [`patternCircular2d`](kcl/patternCircular2d)
* [`patternCircular3d`](kcl/patternCircular3d)
@ -138,6 +137,7 @@ layout: manual
* [`translate`](kcl/translate)
* [`xLine`](kcl/xLine)
* [`yLine`](kcl/yLine)
* [`yd`](kcl/yd)
* **std::math**
* [`E`](kcl/consts/std-math-E)
* [`PI`](kcl/consts/std-math-PI)

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -79599,6 +79599,34 @@
"exampleSketch = startSketchOn(-XZ)\n |> startProfileAt([0, 0], %)\n |> line(end = [10, 0])\n |> line(end = [0, 10])\n |> close()\n\nexample = extrude(exampleSketch, length = 10)"
]
},
{
"name": "cm",
"summary": "Centimeters conversion factor for current projects units.",
"description": "No matter what units the current project uses, this function will always return the conversion factor to centimeters.\n\nFor example, if the current project uses inches, this function will return `0.393701`. If the current project uses millimeters, this function will return `10`. If the current project uses centimeters, this function will return `1`.\n\n**Caution**: This function is only intended to be used when you absolutely MUST have different units in your code than the project settings. Otherwise, it is a bad pattern to use this function.\n\nWe merely provide these functions for convenience and readability, as `10 * cm()` is more readable that your intent is \"I want 10 centimeters\" than `10 * 10`, if the project settings are in millimeters.",
"tags": [
"units"
],
"keywordArguments": false,
"args": [],
"returnValue": {
"name": "",
"type": "number",
"schema": {
"$schema": "https://spec.openapis.org/oas/3.0/schema/2019-04-02#/definitions/Schema",
"title": "double",
"type": "number",
"format": "double"
},
"required": true,
"includeInSnippet": true,
"labelRequired": true
},
"unpublished": false,
"deprecated": false,
"examples": [
"totalWidth = 10 * cm()"
]
},
{
"name": "e",
"summary": "Return the value of Eulers number `e`.",
@ -97462,28 +97490,14 @@
]
},
{
"name": "fromCm",
"summary": "Converts a number from centimeters to the current default unit.",
"description": "No matter what units the current file uses, this function will always return a number equivalent to the input in centimeters.\n\nFor example, if the current project uses inches, `fromCm` will return `0.393701`. If the current project uses millimeters, `fromCm` will return `10`. If the current project uses centimeters, `fromCm` will return `1`.\n\n**Caution**: This function is only intended to be used when you absolutely MUST have different units in your code than the project settings. Otherwise, it is a bad pattern to use this function.\n\nWe merely provide these functions for convenience and readability, as `fromCm(10)` is more readable that your intent is \"I want 10 centimeters\" than `10 * 10`, if the project settings are in millimeters.",
"name": "ft",
"summary": "Feet conversion factor for current projects units.",
"description": "No matter what units the current project uses, this function will always return the conversion factor to feet.\n\nFor example, if the current project uses inches, this function will return `12`. If the current project uses millimeters, this function will return `304.8`. If the current project uses feet, this function will return `1`.\n\n**Caution**: This function is only intended to be used when you absolutely MUST have different units in your code than the project settings. Otherwise, it is a bad pattern to use this function.\n\nWe merely provide these functions for convenience and readability, as `10 * ft()` is more readable that your intent is \"I want 10 feet\" than `10 * 304.8`, if the project settings are in millimeters.",
"tags": [
"units"
],
"keywordArguments": false,
"args": [
{
"name": "input",
"type": "number",
"schema": {
"$schema": "https://spec.openapis.org/oas/3.0/schema/2019-04-02#/definitions/Schema",
"title": "double",
"type": "number",
"format": "double"
},
"required": true,
"includeInSnippet": true,
"labelRequired": true
}
],
"args": [],
"returnValue": {
"name": "",
"type": "number",
@ -97500,217 +97514,7 @@
"unpublished": false,
"deprecated": false,
"examples": [
"totalWidth = fromCm(10)"
]
},
{
"name": "fromFt",
"summary": "Converts a number from feet to the current default unit.",
"description": "No matter what units the current file uses, this function will always return a number equivalent to the input in feet.\n\nFor example, if the current project uses inches, `fromFt(1)` will return `12`. If the current project uses millimeters, `fromFt(1)` will return `304.8`. If the current project uses feet, `fromFt(1)` will return `1`.\n\n**Caution**: This function is only intended to be used when you absolutely MUST have different units in your code than the project settings. Otherwise, it is a bad pattern to use this function.\n\nWe merely provide these functions for convenience and readability, as `fromFt(10)` is more readable that your intent is \"I want 10 feet\" than `10 * 304.8`, if the project settings are in millimeters.",
"tags": [
"units"
],
"keywordArguments": false,
"args": [
{
"name": "input",
"type": "number",
"schema": {
"$schema": "https://spec.openapis.org/oas/3.0/schema/2019-04-02#/definitions/Schema",
"title": "double",
"type": "number",
"format": "double"
},
"required": true,
"includeInSnippet": true,
"labelRequired": true
}
],
"returnValue": {
"name": "",
"type": "number",
"schema": {
"$schema": "https://spec.openapis.org/oas/3.0/schema/2019-04-02#/definitions/Schema",
"title": "double",
"type": "number",
"format": "double"
},
"required": true,
"includeInSnippet": true,
"labelRequired": true
},
"unpublished": false,
"deprecated": false,
"examples": [
"totalWidth = fromFt(10)"
]
},
{
"name": "fromInches",
"summary": "Converts a number from inches to the current default unit.",
"description": "No matter what units the current file uses, this function will always return a number equivalent to the input in inches.\n\nFor example, if the current project uses inches, `fromInches(1)` will return `1`. If the current project uses millimeters, `fromInches(1)` will return `25.4`.\n\n**Caution**: This function is only intended to be used when you absolutely MUST have different units in your code than the project settings. Otherwise, it is a bad pattern to use this function.\n\nWe merely provide these functions for convenience and readability, as `fromInches(10)` is more readable that your intent is \"I want 10 inches\" than `10 * 25.4`, if the project settings are in millimeters.",
"tags": [
"units"
],
"keywordArguments": false,
"args": [
{
"name": "input",
"type": "number",
"schema": {
"$schema": "https://spec.openapis.org/oas/3.0/schema/2019-04-02#/definitions/Schema",
"title": "double",
"type": "number",
"format": "double"
},
"required": true,
"includeInSnippet": true,
"labelRequired": true
}
],
"returnValue": {
"name": "",
"type": "number",
"schema": {
"$schema": "https://spec.openapis.org/oas/3.0/schema/2019-04-02#/definitions/Schema",
"title": "double",
"type": "number",
"format": "double"
},
"required": true,
"includeInSnippet": true,
"labelRequired": true
},
"unpublished": false,
"deprecated": false,
"examples": [
"totalWidth = fromInches(10)"
]
},
{
"name": "fromM",
"summary": "Converts a number from meters to the current default unit.",
"description": "No matter what units the current file uses, this function will always return a number equivalent to the input in meters.\n\nFor example, if the current project uses inches, `fromM` will return `39.3701`. If the current project uses millimeters, `fromM` will return `1000`. If the current project uses meters, `fromM` will return `1`.\n\n**Caution**: This function is only intended to be used when you absolutely MUST have different units in your code than the project settings. Otherwise, it is a bad pattern to use this function.\n\nWe merely provide these functions for convenience and readability, as `fromM(10)` is more readable that your intent is \"I want 10 meters\" than `10 * 1000`, if the project settings are in millimeters.",
"tags": [
"units"
],
"keywordArguments": false,
"args": [
{
"name": "input",
"type": "number",
"schema": {
"$schema": "https://spec.openapis.org/oas/3.0/schema/2019-04-02#/definitions/Schema",
"title": "double",
"type": "number",
"format": "double"
},
"required": true,
"includeInSnippet": true,
"labelRequired": true
}
],
"returnValue": {
"name": "",
"type": "number",
"schema": {
"$schema": "https://spec.openapis.org/oas/3.0/schema/2019-04-02#/definitions/Schema",
"title": "double",
"type": "number",
"format": "double"
},
"required": true,
"includeInSnippet": true,
"labelRequired": true
},
"unpublished": false,
"deprecated": false,
"examples": [
"totalWidth = 10 * fromM(10)"
]
},
{
"name": "fromMm",
"summary": "Converts a number from mm to the current default unit.",
"description": "No matter what units the current file uses, this function will always return a number equivalent to the input in millimeters.\n\nFor example, if the current project uses inches, `fromMm(1)` will return `1/25.4`. If the current project uses millimeters, `fromMm(1)` will return `1`.\n\n**Caution**: This function is only intended to be used when you absolutely MUST have different units in your code than the project settings. Otherwise, it is a bad pattern to use this function.\n\nWe merely provide these functions for convenience and readability, as `fromMm(10)` is more readable that your intent is \"I want 10 millimeters\" than `10 * (1/25.4)`, if the project settings are in inches.",
"tags": [
"units"
],
"keywordArguments": false,
"args": [
{
"name": "input",
"type": "number",
"schema": {
"$schema": "https://spec.openapis.org/oas/3.0/schema/2019-04-02#/definitions/Schema",
"title": "double",
"type": "number",
"format": "double"
},
"required": true,
"includeInSnippet": true,
"labelRequired": true
}
],
"returnValue": {
"name": "",
"type": "number",
"schema": {
"$schema": "https://spec.openapis.org/oas/3.0/schema/2019-04-02#/definitions/Schema",
"title": "double",
"type": "number",
"format": "double"
},
"required": true,
"includeInSnippet": true,
"labelRequired": true
},
"unpublished": false,
"deprecated": false,
"examples": [
"totalWidth = fromMm(10)"
]
},
{
"name": "fromYd",
"summary": "Converts a number from yards to the current default unit.",
"description": "No matter what units the current file uses, this function will always return a number equivalent to the input in yards.\n\nFor example, if the current project uses inches, `fromYd` will return `36`. If the current project uses millimeters, `fromYd` will return `914.4`. If the current project uses yards, `fromYd` will return `1`.\n\n**Caution**: This function is only intended to be used when you absolutely MUST have different units in your code than the project settings. Otherwise, it is a bad pattern to use this function.\n\nWe merely provide these functions for convenience and readability, as `fromYd(10)` is more readable that your intent is \"I want 10 yards\" than `10 * 914.4`, if the project settings are in millimeters.",
"tags": [
"units"
],
"keywordArguments": false,
"args": [
{
"name": "input",
"type": "number",
"schema": {
"$schema": "https://spec.openapis.org/oas/3.0/schema/2019-04-02#/definitions/Schema",
"title": "double",
"type": "number",
"format": "double"
},
"required": true,
"includeInSnippet": true,
"labelRequired": true
}
],
"returnValue": {
"name": "",
"type": "number",
"schema": {
"$schema": "https://spec.openapis.org/oas/3.0/schema/2019-04-02#/definitions/Schema",
"title": "double",
"type": "number",
"format": "double"
},
"required": true,
"includeInSnippet": true,
"labelRequired": true
},
"unpublished": false,
"deprecated": false,
"examples": [
"totalWidth = fromYd(10)"
"totalWidth = 10 * ft()"
]
},
{
@ -106565,6 +106369,34 @@
"import height, buildSketch from \"common.kcl\"\n\nplane = XZ\nmargin = 2\ns1 = buildSketch(plane, [0, 0])\ns2 = buildSketch(plane, [0, height() + margin])"
]
},
{
"name": "inch",
"summary": "Inches conversion factor for current projects units.",
"description": "No matter what units the current project uses, this function will always return the conversion factor to inches.\n\nFor example, if the current project uses inches, this function will return `1`. If the current project uses millimeters, this function will return `25.4`.\n\n**Caution**: This function is only intended to be used when you absolutely MUST have different units in your code than the project settings. Otherwise, it is a bad pattern to use this function.\n\nWe merely provide these functions for convenience and readability, as `10 * inch()` is more readable that your intent is \"I want 10 inches\" than `10 * 25.4`, if the project settings are in millimeters.",
"tags": [
"units"
],
"keywordArguments": false,
"args": [],
"returnValue": {
"name": "",
"type": "number",
"schema": {
"$schema": "https://spec.openapis.org/oas/3.0/schema/2019-04-02#/definitions/Schema",
"title": "double",
"type": "number",
"format": "double"
},
"required": true,
"includeInSnippet": true,
"labelRequired": true
},
"unpublished": false,
"deprecated": false,
"examples": [
"totalWidth = 10 * inch()"
]
},
{
"name": "int",
"summary": "Convert a number to an integer.",
@ -134529,6 +134361,34 @@
"exampleSketch = startSketchOn(XZ)\n |> startProfileAt([0, 0], %)\n |> line(end = [log2(100), 0])\n |> line(end = [5, 8])\n |> line(end = [-10, 0])\n |> close()\n\nexample = extrude(exampleSketch, length = 5)"
]
},
{
"name": "m",
"summary": "Meters conversion factor for current projects units.",
"description": "No matter what units the current project uses, this function will always return the conversion factor to meters.\n\nFor example, if the current project uses inches, this function will return `39.3701`. If the current project uses millimeters, this function will return `1000`. If the current project uses meters, this function will return `1`.\n\n**Caution**: This function is only intended to be used when you absolutely MUST have different units in your code than the project settings. Otherwise, it is a bad pattern to use this function.\n\nWe merely provide these functions for convenience and readability, as `10 * m()` is more readable that your intent is \"I want 10 meters\" than `10 * 1000`, if the project settings are in millimeters.",
"tags": [
"units"
],
"keywordArguments": false,
"args": [],
"returnValue": {
"name": "",
"type": "number",
"schema": {
"$schema": "https://spec.openapis.org/oas/3.0/schema/2019-04-02#/definitions/Schema",
"title": "double",
"type": "number",
"format": "double"
},
"required": true,
"includeInSnippet": true,
"labelRequired": true
},
"unpublished": false,
"deprecated": false,
"examples": [
"totalWidth = 10 * m()"
]
},
{
"name": "map",
"summary": "Apply a function to every element of a list.",
@ -141993,6 +141853,34 @@
"exampleSketch = startSketchOn(XZ)\n |> startProfileAt([0, 0], %)\n |> angledLine({\n angle = 70,\n length = min(15, 31, 4, 13, 22)\n }, %)\n |> line(end = [20, 0])\n |> close()\n\nexample = extrude(exampleSketch, length = 5)"
]
},
{
"name": "mm",
"summary": "Millimeters conversion factor for current projects units.",
"description": "No matter what units the current project uses, this function will always return the conversion factor to millimeters.\n\nFor example, if the current project uses inches, this function will return `(1/25.4)`. If the current project uses millimeters, this function will return `1`.\n\n**Caution**: This function is only intended to be used when you absolutely MUST have different units in your code than the project settings. Otherwise, it is a bad pattern to use this function.\n\nWe merely provide these functions for convenience and readability, as `10 * mm()` is more readable that your intent is \"I want 10 millimeters\" than `10 * (1/25.4)`, if the project settings are in inches.",
"tags": [
"units"
],
"keywordArguments": false,
"args": [],
"returnValue": {
"name": "",
"type": "number",
"schema": {
"$schema": "https://spec.openapis.org/oas/3.0/schema/2019-04-02#/definitions/Schema",
"title": "double",
"type": "number",
"format": "double"
},
"required": true,
"includeInSnippet": true,
"labelRequired": true
},
"unpublished": false,
"deprecated": false,
"examples": [
"totalWidth = 10 * mm()"
]
},
{
"name": "offsetPlane",
"summary": "Offset a plane by a distance along its normal.",
@ -201676,6 +201564,15 @@
},
"length": {
"description": "The length of the line.",
"allOf": [
{
"$ref": "#/components/schemas/TyF64"
}
]
}
},
"definitions": {
"TyF64": {
"type": "number",
"format": "double"
}
@ -336274,5 +336171,33 @@
"examples": [
"exampleSketch = startSketchOn(XZ)\n |> startProfileAt([0, 0], %)\n |> yLine(length = 15)\n |> angledLine({ angle = 30, length = 15 }, %)\n |> line(end = [8, -10])\n |> yLine(length = -5)\n |> close()\n\nexample = extrude(exampleSketch, length = 10)"
]
},
{
"name": "yd",
"summary": "Yards conversion factor for current projects units.",
"description": "No matter what units the current project uses, this function will always return the conversion factor to yards.\n\nFor example, if the current project uses inches, this function will return `36`. If the current project uses millimeters, this function will return `914.4`. If the current project uses yards, this function will return `1`.\n\n**Caution**: This function is only intended to be used when you absolutely MUST have different units in your code than the project settings. Otherwise, it is a bad pattern to use this function.\n\nWe merely provide these functions for convenience and readability, as `10 * yd()` is more readable that your intent is \"I want 10 yards\" than `10 * 914.4`, if the project settings are in millimeters.",
"tags": [
"units"
],
"keywordArguments": false,
"args": [],
"returnValue": {
"name": "",
"type": "number",
"schema": {
"$schema": "https://spec.openapis.org/oas/3.0/schema/2019-04-02#/definitions/Schema",
"title": "double",
"type": "number",
"format": "double"
},
"required": true,
"includeInSnippet": true,
"labelRequired": true
},
"unpublished": false,
"deprecated": false,
"examples": [
"totalWidth = 10 * yd()"
]
}
]

File diff suppressed because one or more lines are too long

View File

@ -32,7 +32,7 @@ lugClearance = startSketchOn(lugExtrusion, 'END')
// Create the circular pattern for the lug holes
lugHoles = startSketchOn(lugBase, 'END')
|> circle(center = [lugSpacing / 2, 0], radius = fromMm(16) / 2)
|> circle(center = [lugSpacing / 2, 0], radius = 16 * mm() / 2)
|> patternCircular2d(
arcDegrees = 360,
center = [0, 0],

View File

@ -11,7 +11,7 @@ customPlane = {
plane = {
origin = {
x = lugSpacing / 2,
y = fromMm(-30),
y = -30 * mm(),
z = 0
},
xAxis = { x = 1, y = 0, z = 0 },
@ -26,7 +26,7 @@ fn lug(plane, length, diameter) {
|> angledLineOfYLength({ angle = 70, length = lugHeadLength }, %)
|> xLine(endAbsolute = lugDiameter / 2)
|> yLine(endAbsolute = lugLength)
|> tangentialArc({ offset = 90, radius = fromMm(3) }, %)
|> tangentialArc({ offset = 90, radius = 3 * mm() }, %)
|> xLine(endAbsolute = 0 + .001, tag = $c1)
|> yLine(endAbsolute = lugThreadDepth)
|> xLine(endAbsolute = lugThreadDiameter)

View File

@ -5,8 +5,8 @@
// Car wheel
export lugCount = 5
export lugSpacing = fromMm(114.3)
export offset = fromMm(-35)
export lugSpacing = 114.3 * mm()
export offset = -35 * mm()
export backSpacing = 6.38
export wheelWidth = 9.5
export wheelDiameter = 19
@ -16,11 +16,11 @@ export spokeAngle = 0.02
export spokeThickness = 0.95
// Lug Nut
export lugDiameter = fromMm(24)
export lugDiameter = 24 * mm()
export lugHeadLength = lugDiameter * .5
export lugThreadDiameter = lugDiameter / 2 * .85
export lugLength = fromMm(30)
export lugThreadDepth = lugLength - fromMm(12.7)
export lugLength = 30 * mm()
export lugThreadDepth = lugLength - (12.7 * mm())
// Car rotor
export rotorDiameter = 12

View File

@ -5,7 +5,7 @@
@settings(defaultLengthUnit = in)
// Define parameters
beamLength = fromFt(6)
beamLength = 6 * ft()
beamHeight = 4
flangeWidth = 2.663
flangeThickness = 0.293

View File

@ -6,7 +6,7 @@
// Define parameters
routerDiameter = 12.7
templateDiameter = fromInches(11 / 16)
templateDiameter = 11 / 16 * inch()
slateWidthHalf = 41.5 / 2
minClampingDistance = 50 + 30
templateThickness = 10

View File

@ -6,7 +6,7 @@
// Define parameters
routerDiameter = 12.7
templateDiameter = fromInches(11 / 16)
templateDiameter = 11 / 16 * inch()
slateWidthHalf = 41.5 / 2
minClampingDistance = 50 + 30
templateThickness = 10

20
rust/Cargo.lock generated
View File

@ -1907,6 +1907,7 @@ dependencies = [
"serde_json",
"sha2",
"tabled",
"tempdir",
"thiserror 2.0.12",
"tokio",
"tokio-tungstenite",
@ -3084,6 +3085,15 @@ version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
[[package]]
name = "remove_dir_all"
version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7"
dependencies = [
"winapi",
]
[[package]]
name = "reqwest"
version = "0.12.15"
@ -3779,6 +3789,16 @@ version = "0.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e502f78cdbb8ba4718f566c418c52bc729126ffd16baee5baa718cf25dd5a69a"
[[package]]
name = "tempdir"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8"
dependencies = [
"rand 0.4.6",
"remove_dir_all",
]
[[package]]
name = "tempfile"
version = "3.19.0"

View File

@ -22,7 +22,6 @@ debug = 0
[profile.dev.package]
insta = { opt-level = 3 }
similar = { opt-level = 3 }
[profile.test]
debug = "line-tables-only"

View File

@ -69,6 +69,7 @@ serde = { workspace = true }
serde_json = { workspace = true }
sha2 = "0.10.8"
tabled = { version = "0.18.0", optional = true }
tempdir = "0.3.7"
thiserror = "2.0.0"
toml = "0.8.19"
ts-rs = { version = "10.1.0", features = [

View File

@ -18,7 +18,7 @@ use tokio::sync::{mpsc, oneshot, RwLock};
use tokio_tungstenite::tungstenite::Message as WsMsg;
use uuid::Uuid;
use super::{EngineStats, ExecutionKind};
use super::EngineStats;
use crate::{
engine::EngineManager,
errors::{KclError, KclErrorDetails},
@ -51,7 +51,6 @@ pub struct EngineConnection {
/// If the server sends session data, it'll be copied to here.
session_data: Arc<RwLock<Option<ModelingSessionData>>>,
execution_kind: Arc<RwLock<ExecutionKind>>,
stats: EngineStats,
}
@ -344,7 +343,6 @@ impl EngineConnection {
artifact_commands: Arc::new(RwLock::new(Vec::new())),
default_planes: Default::default(),
session_data,
execution_kind: Default::default(),
stats: Default::default(),
})
}
@ -368,18 +366,6 @@ impl EngineManager for EngineConnection {
self.artifact_commands.clone()
}
async fn execution_kind(&self) -> ExecutionKind {
let guard = self.execution_kind.read().await;
*guard
}
async fn replace_execution_kind(&self, execution_kind: ExecutionKind) -> ExecutionKind {
let mut guard = self.execution_kind.write().await;
let original = *guard;
*guard = execution_kind;
original
}
fn stats(&self) -> &EngineStats {
&self.stats
}

View File

@ -16,7 +16,7 @@ use kittycad_modeling_cmds::{self as kcmc};
use tokio::sync::RwLock;
use uuid::Uuid;
use super::{EngineStats, ExecutionKind};
use super::EngineStats;
use crate::{
errors::KclError,
exec::DefaultPlanes,
@ -29,7 +29,6 @@ pub struct EngineConnection {
batch: Arc<RwLock<Vec<(WebSocketRequest, SourceRange)>>>,
batch_end: Arc<RwLock<IndexMap<uuid::Uuid, (WebSocketRequest, SourceRange)>>>,
artifact_commands: Arc<RwLock<Vec<ArtifactCommand>>>,
execution_kind: Arc<RwLock<ExecutionKind>>,
/// The default planes for the scene.
default_planes: Arc<RwLock<Option<DefaultPlanes>>>,
stats: EngineStats,
@ -41,7 +40,6 @@ impl EngineConnection {
batch: Arc::new(RwLock::new(Vec::new())),
batch_end: Arc::new(RwLock::new(IndexMap::new())),
artifact_commands: Arc::new(RwLock::new(Vec::new())),
execution_kind: Default::default(),
default_planes: Default::default(),
stats: Default::default(),
})
@ -70,18 +68,6 @@ impl crate::engine::EngineManager for EngineConnection {
self.artifact_commands.clone()
}
async fn execution_kind(&self) -> ExecutionKind {
let guard = self.execution_kind.read().await;
*guard
}
async fn replace_execution_kind(&self, execution_kind: ExecutionKind) -> ExecutionKind {
let mut guard = self.execution_kind.write().await;
let original = *guard;
*guard = execution_kind;
original
}
fn get_default_planes(&self) -> Arc<RwLock<Option<DefaultPlanes>>> {
self.default_planes.clone()
}

View File

@ -11,7 +11,7 @@ use uuid::Uuid;
use wasm_bindgen::prelude::*;
use crate::{
engine::{EngineStats, ExecutionKind},
engine::EngineStats,
errors::{KclError, KclErrorDetails},
execution::{ArtifactCommand, DefaultPlanes, IdGenerator},
SourceRange,
@ -42,7 +42,6 @@ pub struct EngineConnection {
batch_end: Arc<RwLock<IndexMap<uuid::Uuid, (WebSocketRequest, SourceRange)>>>,
responses: Arc<RwLock<IndexMap<Uuid, WebSocketResponse>>>,
artifact_commands: Arc<RwLock<Vec<ArtifactCommand>>>,
execution_kind: Arc<RwLock<ExecutionKind>>,
/// The default planes for the scene.
default_planes: Arc<RwLock<Option<DefaultPlanes>>>,
stats: EngineStats,
@ -61,7 +60,6 @@ impl EngineConnection {
batch_end: Arc::new(RwLock::new(IndexMap::new())),
responses: Arc::new(RwLock::new(IndexMap::new())),
artifact_commands: Arc::new(RwLock::new(Vec::new())),
execution_kind: Default::default(),
default_planes: Default::default(),
stats: Default::default(),
})
@ -164,18 +162,6 @@ impl crate::engine::EngineManager for EngineConnection {
self.artifact_commands.clone()
}
async fn execution_kind(&self) -> ExecutionKind {
let guard = self.execution_kind.read().await;
*guard
}
async fn replace_execution_kind(&self, execution_kind: ExecutionKind) -> ExecutionKind {
let mut guard = self.execution_kind.write().await;
let original = *guard;
*guard = execution_kind;
original
}
fn get_default_planes(&self) -> Arc<RwLock<Option<DefaultPlanes>>> {
self.default_planes.clone()
}
@ -218,11 +204,6 @@ impl crate::engine::EngineManager for EngineConnection {
.do_send_modeling_cmd(id, source_range, cmd, id_to_source_range)
.await?;
// In isolated mode, we don't save the response.
if self.execution_kind().await.is_isolated() {
return Ok(ws_result);
}
let mut responses = self.responses.write().await;
responses.insert(id, ws_result.clone());
drop(responses);

View File

@ -47,23 +47,6 @@ lazy_static::lazy_static! {
pub static ref GRID_SCALE_TEXT_OBJECT_ID: uuid::Uuid = uuid::Uuid::parse_str("10782f33-f588-4668-8bcd-040502d26590").unwrap();
}
/// The mode of execution. When isolated, like during an import, attempting to
/// send a command results in an error.
#[derive(Debug, Default, Clone, Copy, Deserialize, Serialize, PartialEq, Eq, ts_rs::TS, JsonSchema)]
#[ts(export)]
#[serde(rename_all = "camelCase")]
pub enum ExecutionKind {
#[default]
Normal,
Isolated,
}
impl ExecutionKind {
pub fn is_isolated(&self) -> bool {
matches!(self, ExecutionKind::Isolated)
}
}
#[derive(Default, Debug)]
pub struct EngineStats {
pub commands_batched: AtomicUsize,
@ -93,16 +76,6 @@ pub trait EngineManager: std::fmt::Debug + Send + Sync + 'static {
/// Get the artifact commands that have accumulated so far.
fn artifact_commands(&self) -> Arc<RwLock<Vec<ArtifactCommand>>>;
/// Take the batch of commands that have accumulated so far and clear them.
async fn take_batch(&self) -> Vec<(WebSocketRequest, SourceRange)> {
std::mem::take(&mut *self.batch().write().await)
}
/// Take the batch of end commands that have accumulated so far and clear them.
async fn take_batch_end(&self) -> IndexMap<Uuid, (WebSocketRequest, SourceRange)> {
std::mem::take(&mut *self.batch_end().write().await)
}
/// Clear all artifact commands that have accumulated so far.
async fn clear_artifact_commands(&self) {
self.artifact_commands().write().await.clear();
@ -118,13 +91,6 @@ pub trait EngineManager: std::fmt::Debug + Send + Sync + 'static {
std::mem::take(&mut *self.responses().write().await)
}
/// Get the current execution kind.
async fn execution_kind(&self) -> ExecutionKind;
/// Replace the current execution kind with a new value and return the
/// existing value.
async fn replace_execution_kind(&self, execution_kind: ExecutionKind) -> ExecutionKind;
/// Get the default planes.
fn get_default_planes(&self) -> Arc<RwLock<Option<DefaultPlanes>>>;
@ -289,11 +255,6 @@ pub trait EngineManager: std::fmt::Debug + Send + Sync + 'static {
source_range: SourceRange,
cmd: &ModelingCmd,
) -> Result<(), crate::errors::KclError> {
// In isolated mode, we don't send the command to the engine.
if self.execution_kind().await.is_isolated() {
return Ok(());
}
let req = WebSocketRequest::ModelingCmdReq(ModelingCmdReq {
cmd: cmd.clone(),
cmd_id: id.into(),
@ -315,11 +276,6 @@ pub trait EngineManager: std::fmt::Debug + Send + Sync + 'static {
source_range: SourceRange,
cmds: &[ModelingCmdReq],
) -> Result<(), crate::errors::KclError> {
// In isolated mode, we don't send the command to the engine.
if self.execution_kind().await.is_isolated() {
return Ok(());
}
// Add cmds to the batch.
let mut extended_cmds = Vec::with_capacity(cmds.len());
for cmd in cmds {
@ -342,11 +298,6 @@ pub trait EngineManager: std::fmt::Debug + Send + Sync + 'static {
source_range: SourceRange,
cmd: &ModelingCmd,
) -> Result<(), crate::errors::KclError> {
// In isolated mode, we don't send the command to the engine.
if self.execution_kind().await.is_isolated() {
return Ok(());
}
let req = WebSocketRequest::ModelingCmdReq(ModelingCmdReq {
cmd: cmd.clone(),
cmd_id: id.into(),
@ -380,11 +331,11 @@ pub trait EngineManager: std::fmt::Debug + Send + Sync + 'static {
source_range: SourceRange,
) -> Result<OkWebSocketResponseData, crate::errors::KclError> {
let all_requests = if batch_end {
let mut requests = self.take_batch().await.clone();
requests.extend(self.take_batch_end().await.values().cloned());
let mut requests = self.batch().read().await.clone();
requests.extend(self.batch_end().read().await.values().cloned());
requests
} else {
self.take_batch().await.clone()
self.batch().read().await.clone()
};
// Return early if we have no commands to send.
@ -452,6 +403,11 @@ pub trait EngineManager: std::fmt::Debug + Send + Sync + 'static {
}
}
// Throw away the old batch queue.
self.batch().write().await.clear();
if batch_end {
self.batch_end().write().await.clear();
}
self.stats().batches_sent.fetch_add(1, Ordering::Relaxed);
// We pop off the responses to cleanup our mappings.

View File

@ -120,7 +120,7 @@ impl From<KclErrorWithOutputs> for KclError {
}
}
#[derive(Error, Debug, Serialize, ts_rs::TS, Clone, PartialEq)]
#[derive(Error, Debug, Serialize, Deserialize, ts_rs::TS, Clone, PartialEq)]
#[error("{error}")]
#[ts(export)]
#[serde(rename_all = "camelCase")]

View File

@ -3,11 +3,11 @@ use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use super::{types::NumericType, ArtifactId, KclValue};
use crate::{docs::StdLibFn, ModuleId, SourceRange};
use crate::{docs::StdLibFn, std::get_stdlib_fn, ModuleId, SourceRange};
/// A CAD modeling operation for display in the feature tree, AKA operations
/// timeline.
#[derive(Debug, Clone, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
#[ts(export_to = "Operation.ts")]
#[serde(tag = "type")]
pub enum Operation {
@ -60,7 +60,7 @@ impl Operation {
}
}
#[derive(Debug, Clone, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
#[ts(export_to = "Operation.ts")]
#[serde(tag = "type")]
#[expect(clippy::large_enum_variant)]
@ -90,7 +90,7 @@ pub enum Group {
}
/// An argument to a CAD modeling operation.
#[derive(Debug, Clone, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
#[ts(export_to = "Operation.ts")]
#[serde(rename_all = "camelCase")]
pub struct OpArg {
@ -110,7 +110,7 @@ impl OpArg {
/// A reference to a standard library function. This exists to implement
/// `PartialEq` and `Eq` for `Operation`.
#[derive(Debug, Clone, Serialize, ts_rs::TS, JsonSchema)]
#[derive(Debug, Clone, Deserialize, Serialize, ts_rs::TS, JsonSchema)]
#[ts(export_to = "Operation.ts")]
#[serde(rename_all = "camelCase")]
pub struct StdLibFnRef {
@ -156,13 +156,25 @@ where
serializer.serialize_str(&name)
}
fn std_lib_fn_from_name<'de, D>(deserializer: D) -> Result<Box<dyn StdLibFn>, D::Error>
where
D: serde::Deserializer<'de>,
{
let s = String::deserialize(deserializer)?;
if let Some(std_lib_fn) = get_stdlib_fn(&s) {
Ok(std_lib_fn)
} else {
Err(serde::de::Error::custom(format!("not a KCL stdlib function: {}", s)))
}
}
fn is_false(b: &bool) -> bool {
!*b
}
/// A KCL value used in Operations. `ArtifactId`s are used to refer to the
/// actual scene objects. Any data not needed in the UI may be omitted.
#[derive(Debug, Clone, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
#[ts(export_to = "Operation.ts")]
#[serde(tag = "type")]
pub enum OpKclValue {

View File

@ -3,13 +3,8 @@ use std::collections::HashMap;
use async_recursion::async_recursion;
use indexmap::IndexMap;
use super::{
cad_op::Group,
kcl_value::TypeDef,
types::{PrimitiveType, CHECK_NUMERIC_TYPES},
};
use super::{cad_op::Group, kcl_value::TypeDef, types::PrimitiveType};
use crate::{
engine::ExecutionKind,
errors::{KclError, KclErrorDetails},
execution::{
annotations,
@ -30,7 +25,7 @@ use crate::{
},
source_range::SourceRange,
std::{
args::{Arg, KwArgs, TyF64},
args::{Arg, KwArgs},
FunctionKind,
},
CompilationError,
@ -66,7 +61,6 @@ impl ExecutorContext {
exec_state.mod_local.explicit_length_units = true;
}
let new_units = exec_state.length_unit();
if !self.engine.execution_kind().await.is_isolated() {
self.engine
.set_units(
new_units.into(),
@ -74,7 +68,6 @@ impl ExecutorContext {
exec_state.id_generator(),
)
.await?;
}
} else {
exec_state.err(CompilationError::err(
annotation.as_source_range(),
@ -104,15 +97,13 @@ impl ExecutorContext {
&self,
program: &Node<Program>,
exec_state: &mut ExecState,
exec_kind: ExecutionKind,
preserve_mem: bool,
module_id: ModuleId,
path: &ModulePath,
) -> Result<(Option<KclValue>, EnvironmentRef, Vec<String>), KclError> {
crate::log::log(format!("enter module {path} {} {exec_kind:?}", exec_state.stack()));
crate::log::log(format!("enter module {path} {}", exec_state.stack()));
let old_units = exec_state.length_unit();
let original_execution = self.engine.replace_execution_kind(exec_kind).await;
let mut local_state = ModuleState::new(path.std_path(), exec_state.stack().memory.clone(), Some(module_id));
if !preserve_mem {
@ -145,23 +136,71 @@ impl ExecutorContext {
// If we reset at the end of the main path, then we just add on an extra
// command and we'd need to flush the batch again.
// This avoids that.
if !exec_kind.is_isolated() && new_units != old_units && *path != ModulePath::Main {
if new_units != old_units && *path != ModulePath::Main {
self.engine
.set_units(old_units.into(), Default::default(), exec_state.id_generator())
.await?;
}
self.engine.replace_execution_kind(original_execution).await;
crate::log::log(format!("leave {path}"));
result.map(|result| (result, env_ref, local_state.module_exports))
}
/// Execute an AST's program.
#[async_recursion]
pub(super) async fn preload_all_modules<'a>(
&'a self,
modules: &mut HashMap<String, Program>,
program: NodeRef<'a, Program>,
exec_state: &mut ExecState,
) -> Result<(), KclError> {
for statement in &program.body {
if let BodyItem::ImportStatement(import_stmt) = statement {
let path_str = import_stmt.path.to_string();
if modules.contains_key(&path_str) {
// don't waste our time if we've already loaded the
// module.
continue;
}
let source_range = SourceRange::from(import_stmt);
let attrs = &import_stmt.outer_attrs;
let module_id = self
.open_module(&import_stmt.path, attrs, exec_state, source_range)
.await?;
let Some(module) = exec_state.get_module(module_id) else {
crate::log::log("we got back a module id that doesn't exist");
unreachable!();
};
let progn = {
// this dance is to avoid taking out a mut borrow
// below on exec_state after borrowing here. As a
// result, we need to clone (ugh) the program for
// now.
let ModuleRepr::Kcl(ref progn, _) = module.repr else {
// not a kcl file, we can skip this
continue;
};
progn.clone()
};
modules.insert(path_str, progn.clone().inner);
self.preload_all_modules(modules, &progn, exec_state).await?;
};
}
Ok(())
}
/// Execute an AST's program.
#[async_recursion]
pub(super) async fn exec_block<'a>(
&'a self,
program: NodeRef<'a, crate::parsing::ast::types::Program>,
program: NodeRef<'a, Program>,
exec_state: &mut ExecState,
body_type: BodyType,
) -> Result<Option<KclValue>, KclError> {
@ -185,9 +224,9 @@ impl ExecutorContext {
match &import_stmt.selector {
ImportSelector::List { items } => {
let (env_ref, module_exports) = self
.exec_module_for_items(module_id, exec_state, ExecutionKind::Isolated, source_range)
.await?;
println!("Importing items from module {}", import_stmt.path,);
let (env_ref, module_exports) =
self.exec_module_for_items(module_id, exec_state, source_range).await?;
for import_item in items {
// Extract the item from the module.
let item = exec_state
@ -228,9 +267,9 @@ impl ExecutorContext {
}
}
ImportSelector::Glob(_) => {
let (env_ref, module_exports) = self
.exec_module_for_items(module_id, exec_state, ExecutionKind::Isolated, source_range)
.await?;
println!("Importing all items from module {}", import_stmt.path);
let (env_ref, module_exports) =
self.exec_module_for_items(module_id, exec_state, source_range).await?;
for name in module_exports.iter() {
let item = exec_state
.stack()
@ -421,7 +460,7 @@ impl ExecutorContext {
Ok(last_expr)
}
pub(super) async fn open_module(
pub async fn open_module(
&self,
path: &ImportPath,
attrs: &[Node<Annotation>],
@ -429,6 +468,7 @@ impl ExecutorContext {
source_range: SourceRange,
) -> Result<ModuleId, KclError> {
let resolved_path = ModulePath::from_import_path(path, &self.settings.project_directory);
match path {
ImportPath::Kcl { .. } => {
exec_state.global.mod_loader.cycle_check(&resolved_path, source_range)?;
@ -485,7 +525,6 @@ impl ExecutorContext {
&self,
module_id: ModuleId,
exec_state: &mut ExecState,
exec_kind: ExecutionKind,
source_range: SourceRange,
) -> Result<(EnvironmentRef, Vec<String>), KclError> {
let path = exec_state.global.module_infos[&module_id].path.clone();
@ -496,7 +535,7 @@ impl ExecutorContext {
ModuleRepr::Root => Err(exec_state.circular_import_error(&path, source_range)),
ModuleRepr::Kcl(_, Some((env_ref, items))) => Ok((*env_ref, items.clone())),
ModuleRepr::Kcl(program, cache) => self
.exec_module_from_ast(program, module_id, &path, exec_state, exec_kind, source_range)
.exec_module_from_ast(program, module_id, &path, exec_state, source_range)
.await
.map(|(_, er, items)| {
*cache = Some((er, items.clone()));
@ -518,7 +557,6 @@ impl ExecutorContext {
module_id: ModuleId,
module_name: &BoxNode<Name>,
exec_state: &mut ExecState,
exec_kind: ExecutionKind,
source_range: SourceRange,
) -> Result<Option<KclValue>, KclError> {
exec_state.global.operations.push(Operation::GroupBegin {
@ -537,7 +575,7 @@ impl ExecutorContext {
ModuleRepr::Root => Err(exec_state.circular_import_error(&path, source_range)),
ModuleRepr::Kcl(program, cached_items) => {
let result = self
.exec_module_from_ast(program, module_id, &path, exec_state, exec_kind, source_range)
.exec_module_from_ast(program, module_id, &path, exec_state, source_range)
.await;
match result {
Ok((val, env, items)) => {
@ -560,19 +598,17 @@ impl ExecutorContext {
result
}
async fn exec_module_from_ast(
pub async fn exec_module_from_ast(
&self,
program: &Node<Program>,
module_id: ModuleId,
path: &ModulePath,
exec_state: &mut ExecState,
exec_kind: ExecutionKind,
source_range: SourceRange,
) -> Result<(Option<KclValue>, EnvironmentRef, Vec<String>), KclError> {
println!("exec_module_from_ast {path}");
exec_state.global.mod_loader.enter_module(path);
let result = self
.exec_module_body(program, exec_state, exec_kind, false, module_id, path)
.await;
let result = self.exec_module_body(program, exec_state, false, module_id, path).await;
exec_state.global.mod_loader.leave_module(path);
result.map_err(|err| {
@ -608,7 +644,7 @@ impl ExecutorContext {
Expr::Name(name) => {
let value = name.get_result(exec_state, self).await?.clone();
if let KclValue::Module { value: module_id, meta } = value {
self.exec_module_for_result(module_id, name, exec_state, ExecutionKind::Normal, metadata.source_range)
self.exec_module_for_result(module_id, name, exec_state, metadata.source_range)
.await?
.unwrap_or_else(|| {
exec_state.warn(CompilationError::err(
@ -709,14 +745,14 @@ impl ExecutorContext {
let result = self
.execute_expr(&expr.expr, exec_state, metadata, &[], statement_kind)
.await?;
apply_ascription(&result, &expr.ty, exec_state, expr.into())?
coerce(&result, &expr.ty, exec_state, expr.into())?
}
};
Ok(item)
}
}
fn apply_ascription(
fn coerce(
value: &KclValue,
ty: &Node<Type>,
exec_state: &mut ExecState,
@ -725,24 +761,7 @@ fn apply_ascription(
let ty = RuntimeType::from_parsed(ty.inner.clone(), exec_state, value.into())
.map_err(|e| KclError::Semantic(e.into()))?;
if let KclValue::Number {
ty: NumericType::Unknown,
value,
meta,
} = value
{
// If the number has unknown units but the user is explicitly specifying them, treat the value as having had it's units erased,
// rather than forcing the user to explicitly erase them.
KclValue::Number {
ty: NumericType::Any,
value: *value,
meta: meta.clone(),
}
.coerce(&ty, exec_state)
} else {
value.coerce(&ty, exec_state)
}
.map_err(|_| {
value.coerce(&ty, exec_state).ok_or_else(|| {
KclError::Semantic(KclErrorDetails {
message: format!("could not coerce {} value to type {}", value.human_friendly_type(), ty),
source_ranges: vec![source_range],
@ -813,7 +832,7 @@ impl Node<Name> {
};
mem_spec = Some(
ctx.exec_module_for_items(*module_id, exec_state, ExecutionKind::Normal, p.as_source_range())
ctx.exec_module_for_items(*module_id, exec_state, p.as_source_range())
.await?,
);
}
@ -998,85 +1017,69 @@ impl Node<BinaryExpression> {
return Ok(KclValue::Bool { value: raw_value, meta });
}
let left = number_as_f64(&left_value, self.left.clone().into())?;
let right = number_as_f64(&right_value, self.right.clone().into())?;
let (left, lty) = parse_number_as_f64(&left_value, self.left.clone().into())?;
let (right, rty) = parse_number_as_f64(&right_value, self.right.clone().into())?;
let value = match self.operator {
BinaryOperator::Add => {
let (l, r, ty) = NumericType::combine_eq(left, right);
self.warn_on_unknown(&ty, "Adding", exec_state);
KclValue::Number { value: l + r, meta, ty }
}
BinaryOperator::Sub => {
let (l, r, ty) = NumericType::combine_eq(left, right);
self.warn_on_unknown(&ty, "Subtracting", exec_state);
KclValue::Number { value: l - r, meta, ty }
}
BinaryOperator::Mul => {
let (l, r, ty) = NumericType::combine_mul(left, right);
self.warn_on_unknown(&ty, "Multiplying", exec_state);
KclValue::Number { value: l * r, meta, ty }
}
BinaryOperator::Div => {
let (l, r, ty) = NumericType::combine_div(left, right);
self.warn_on_unknown(&ty, "Dividing", exec_state);
KclValue::Number { value: l / r, meta, ty }
}
BinaryOperator::Mod => {
let (l, r, ty) = NumericType::combine_div(left, right);
self.warn_on_unknown(&ty, "Modulo of", exec_state);
KclValue::Number { value: l % r, meta, ty }
}
BinaryOperator::Add => KclValue::Number {
value: left + right,
meta,
ty: NumericType::combine_add(lty, rty),
},
BinaryOperator::Sub => KclValue::Number {
value: left - right,
meta,
ty: NumericType::combine_add(lty, rty),
},
BinaryOperator::Mul => KclValue::Number {
value: left * right,
meta,
ty: NumericType::combine_mul(lty, rty),
},
BinaryOperator::Div => KclValue::Number {
value: left / right,
meta,
ty: NumericType::combine_div(lty, rty),
},
BinaryOperator::Mod => KclValue::Number {
value: left % right,
meta,
ty: NumericType::combine_div(lty, rty),
},
BinaryOperator::Pow => KclValue::Number {
value: left.n.powf(right.n),
value: left.powf(right),
meta,
ty: NumericType::Unknown,
},
BinaryOperator::Neq => {
let (l, r, ty) = NumericType::combine_eq(left, right);
self.warn_on_unknown(&ty, "Comparing", exec_state);
KclValue::Bool { value: l != r, meta }
}
BinaryOperator::Gt => {
let (l, r, ty) = NumericType::combine_eq(left, right);
self.warn_on_unknown(&ty, "Comparing", exec_state);
KclValue::Bool { value: l > r, meta }
}
BinaryOperator::Gte => {
let (l, r, ty) = NumericType::combine_eq(left, right);
self.warn_on_unknown(&ty, "Comparing", exec_state);
KclValue::Bool { value: l >= r, meta }
}
BinaryOperator::Lt => {
let (l, r, ty) = NumericType::combine_eq(left, right);
self.warn_on_unknown(&ty, "Comparing", exec_state);
KclValue::Bool { value: l < r, meta }
}
BinaryOperator::Lte => {
let (l, r, ty) = NumericType::combine_eq(left, right);
self.warn_on_unknown(&ty, "Comparing", exec_state);
KclValue::Bool { value: l <= r, meta }
}
BinaryOperator::Eq => {
let (l, r, ty) = NumericType::combine_eq(left, right);
self.warn_on_unknown(&ty, "Comparing", exec_state);
KclValue::Bool { value: l == r, meta }
}
BinaryOperator::Neq => KclValue::Bool {
value: left != right,
meta,
},
BinaryOperator::Gt => KclValue::Bool {
value: left > right,
meta,
},
BinaryOperator::Gte => KclValue::Bool {
value: left >= right,
meta,
},
BinaryOperator::Lt => KclValue::Bool {
value: left < right,
meta,
},
BinaryOperator::Lte => KclValue::Bool {
value: left <= right,
meta,
},
BinaryOperator::Eq => KclValue::Bool {
value: left == right,
meta,
},
BinaryOperator::And | BinaryOperator::Or => unreachable!(),
};
Ok(value)
}
fn warn_on_unknown(&self, ty: &NumericType, verb: &str, exec_state: &mut ExecState) {
if *CHECK_NUMERIC_TYPES && ty == &NumericType::Unknown {
// TODO suggest how to fix this
exec_state.warn(CompilationError::err(
self.as_source_range(),
format!("{} numbers which have unknown or incompatible units.", verb),
));
}
}
}
impl Node<UnaryExpression> {
@ -1310,7 +1313,7 @@ impl Node<CallExpressionKw> {
));
}
let op = if func.feature_tree_operation() && !ctx.is_isolated_execution().await {
let op = if func.feature_tree_operation() {
let op_labeled_args = args
.kw_args
.labeled
@ -1396,7 +1399,7 @@ impl Node<CallExpressionKw> {
e.add_source_ranges(vec![callsite])
})?;
if matches!(fn_src, FunctionSource::User { .. }) && !ctx.is_isolated_execution().await {
if matches!(fn_src, FunctionSource::User { .. }) {
// Track return operation.
exec_state.global.operations.push(Operation::GroupEnd);
}
@ -1448,7 +1451,7 @@ impl Node<CallExpression> {
));
}
let op = if func.feature_tree_operation() && !ctx.is_isolated_execution().await {
let op = if func.feature_tree_operation() {
let op_labeled_args = func
.args(false)
.iter()
@ -1506,7 +1509,6 @@ impl Node<CallExpression> {
// exec_state.
let func = fn_name.get_result(exec_state, ctx).await?.clone();
if !ctx.is_isolated_execution().await {
// Track call operation.
exec_state.global.operations.push(Operation::GroupBegin {
group: Group::FunctionCall {
@ -1518,7 +1520,6 @@ impl Node<CallExpression> {
},
source_range: callsite,
});
}
let Some(fn_src) = func.as_fn() else {
return Err(KclError::Semantic(KclErrorDetails {
@ -1547,10 +1548,8 @@ impl Node<CallExpression> {
})
})?;
if !ctx.is_isolated_execution().await {
// Track return operation.
exec_state.global.operations.push(Operation::GroupEnd);
}
Ok(result)
}
@ -1796,15 +1795,21 @@ fn article_for(s: &str) -> &'static str {
}
}
fn number_as_f64(v: &KclValue, source_range: SourceRange) -> Result<TyF64, KclError> {
v.as_ty_f64().ok_or_else(|| {
pub fn parse_number_as_f64(v: &KclValue, source_range: SourceRange) -> Result<(f64, NumericType), KclError> {
if let KclValue::Number { value: n, ty, .. } = &v {
Ok((*n, ty.clone()))
} else {
let actual_type = v.human_friendly_type();
let article = article_for(actual_type);
KclError::Semantic(KclErrorDetails {
let article = if actual_type.starts_with(['a', 'e', 'i', 'o', 'u']) {
"an"
} else {
"a"
};
Err(KclError::Semantic(KclErrorDetails {
source_ranges: vec![source_range],
message: format!("Expected a number, but found {article} {actual_type}",),
})
})
}))
}
}
impl Node<IfExpression> {
@ -2227,18 +2232,13 @@ impl FunctionSource {
.unwrap(),
exec_state,
)
.map_err(|e| {
let mut message = format!(
.ok_or_else(|| {
KclError::Semantic(KclErrorDetails {
message: format!(
"{label} 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,
arg.value.human_friendly_type()
),
source_ranges: vec![callsite],
})
})?;
@ -2262,13 +2262,13 @@ impl FunctionSource {
&RuntimeType::from_parsed(ty.inner.clone(), exec_state, arg.source_range).unwrap(),
exec_state,
)
.map_err(|_| {
.ok_or_else(|| {
KclError::Semantic(KclErrorDetails {
message: format!(
"The input argument of {} requires a value with type `{}`, but found {}",
props.name,
ty.inner,
arg.value.human_friendly_type(),
arg.value.human_friendly_type()
),
source_ranges: vec![callsite],
})
@ -2277,7 +2277,7 @@ impl FunctionSource {
}
}
let op = if props.include_in_feature_tree && !ctx.is_isolated_execution().await {
let op = if props.include_in_feature_tree {
let op_labeled_args = args
.kw_args
.labeled
@ -2321,7 +2321,6 @@ impl FunctionSource {
Ok(Some(result))
}
FunctionSource::User { ast, memory, .. } => {
if !ctx.is_isolated_execution().await {
// Track call operation.
let op_labeled_args = args
.kw_args
@ -2342,7 +2341,6 @@ impl FunctionSource {
},
source_range: callsite,
});
}
call_user_defined_function_kw(args.kw_args, *memory, ast, exec_state, ctx).await
}
@ -2353,13 +2351,14 @@ impl FunctionSource {
#[cfg(test)]
mod test {
use std::sync::Arc;
use super::*;
use crate::{
execution::{memory::Stack, parse_execute, ContextType},
parsing::ast::types::{DefaultParamVal, Identifier, Parameter},
ExecutorSettings,
};
use std::sync::Arc;
use tokio::io::AsyncWriteExt;
#[tokio::test(flavor = "multi_thread")]
async fn test_assign_args_to_params() {
@ -2468,7 +2467,7 @@ mod test {
// Run each test.
let func_expr = &Node::no_src(FunctionExpression {
params,
body: crate::parsing::ast::types::Program::empty(),
body: Program::empty(),
return_type: None,
digest: None,
});
@ -2570,4 +2569,100 @@ a = foo()
let result = parse_execute(program).await;
assert!(result.unwrap_err().to_string().contains("return"));
}
#[tokio::test(flavor = "multi_thread")]
async fn load_all_modules() {
// program a.kcl
let programa_kcl = r#"
export a = 1
"#;
// program b.kcl
let programb_kcl = r#"
import a from 'a.kcl'
export b = a + 1
"#;
// program c.kcl
let programc_kcl = r#"
import a from 'a.kcl'
export c = a + 2
"#;
// program main.kcl
let main_kcl = r#"
import b from 'b.kcl'
import c from 'c.kcl'
d = b + c
"#;
let main = crate::parsing::parse_str(main_kcl, ModuleId::default())
.parse_errs_as_err()
.unwrap();
let tmpdir = tempdir::TempDir::new("zma_kcl_load_all_modules").unwrap();
tokio::fs::File::create(tmpdir.path().join("main.kcl"))
.await
.unwrap()
.write_all(main_kcl.as_bytes())
.await
.unwrap();
tokio::fs::File::create(tmpdir.path().join("a.kcl"))
.await
.unwrap()
.write_all(programa_kcl.as_bytes())
.await
.unwrap();
tokio::fs::File::create(tmpdir.path().join("b.kcl"))
.await
.unwrap()
.write_all(programb_kcl.as_bytes())
.await
.unwrap();
tokio::fs::File::create(tmpdir.path().join("c.kcl"))
.await
.unwrap()
.write_all(programc_kcl.as_bytes())
.await
.unwrap();
let exec_ctxt = ExecutorContext {
engine: Arc::new(Box::new(
crate::engine::conn_mock::EngineConnection::new()
.await
.map_err(|err| {
KclError::Internal(crate::errors::KclErrorDetails {
message: format!("Failed to create mock engine connection: {}", err),
source_ranges: vec![SourceRange::default()],
})
})
.unwrap(),
)),
fs: Arc::new(crate::fs::FileManager::new()),
settings: ExecutorSettings {
project_directory: Some(tmpdir.path().into()),
..Default::default()
},
stdlib: Arc::new(crate::std::StdLib::new()),
context_type: ContextType::Mock,
};
let mut exec_state = ExecState::new(&exec_ctxt);
exec_ctxt
.run_concurrent(
&crate::Program {
ast: main.clone(),
original_file_contents: "".to_owned(),
},
&mut exec_state,
false,
)
.await
.unwrap();
}
}

View File

@ -15,7 +15,7 @@ use crate::{
parsing::ast::types::{
DefaultParamVal, FunctionExpression, KclNone, Literal, LiteralValue, Node, TagDeclarator, TagNode,
},
std::{args::TyF64, StdFnProps},
std::StdFnProps,
CompilationError, KclError, ModuleId, SourceRange,
};
@ -495,7 +495,6 @@ impl KclValue {
None
}
}
pub fn as_f64(&self) -> Option<f64> {
if let KclValue::Number { value, .. } = &self {
Some(*value)
@ -504,14 +503,6 @@ impl KclValue {
}
}
pub fn as_ty_f64(&self) -> Option<TyF64> {
if let KclValue::Number { value, ty, .. } = &self {
Some(TyF64::new(*value, ty.clone()))
} else {
None
}
}
pub fn as_bool(&self) -> Option<bool> {
if let KclValue::Bool { value, meta: _ } = &self {
Some(*value)

View File

@ -27,21 +27,22 @@ pub use memory::EnvironmentRef;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
pub use state::{ExecState, MetaSettings};
use tokio::task::JoinSet;
use crate::{
engine::EngineManager,
errors::KclError,
errors::{KclError, KclErrorDetails},
execution::{
artifact::build_artifact_graph,
cache::{CacheInformation, CacheResult},
types::{UnitAngle, UnitLen},
},
fs::FileManager,
modules::{ModuleId, ModulePath},
modules::{ModuleId, ModulePath, ModuleRepr},
parsing::ast::types::{Expr, ImportPath, NodeRef},
source_range::SourceRange,
std::StdLib,
CompilationError, ExecError, ExecutionKind, KclErrorWithOutputs,
CompilationError, ExecError, KclErrorWithOutputs,
};
pub(crate) mod annotations;
@ -497,13 +498,9 @@ impl ExecutorContext {
self.context_type == ContextType::Mock || self.context_type == ContextType::MockCustomForwarded
}
pub async fn is_isolated_execution(&self) -> bool {
self.engine.execution_kind().await.is_isolated()
}
/// Returns true if we should not send engine commands for any reason.
pub async fn no_engine_commands(&self) -> bool {
self.is_mock() || self.is_isolated_execution().await
self.is_mock()
}
pub async fn send_clear_scene(
@ -674,7 +671,7 @@ impl ExecutorContext {
(program, exec_state, false)
};
let result = self.inner_run(&program, &mut exec_state, preserve_mem).await;
let result = self.run_concurrent(&program, &mut exec_state, preserve_mem).await;
if result.is_err() {
cache::bust_cache().await;
@ -707,7 +704,124 @@ impl ExecutorContext {
program: &crate::Program,
exec_state: &mut ExecState,
) -> Result<(EnvironmentRef, Option<ModelingSessionData>), KclErrorWithOutputs> {
self.inner_run(program, exec_state, false).await
self.run_concurrent(program, exec_state, false).await
}
/// Perform the execution of a program using an (experimental!) concurrent
/// execution model. This has the same signature as [Self::run].
///
/// For now -- do not use this unless you're willing to accept some
/// breakage.
///
/// You can optionally pass in some initialization memory for partial
/// execution.
///
/// To access non-fatal errors and warnings, extract them from the `ExecState`.
pub async fn run_concurrent(
&self,
program: &crate::Program,
exec_state: &mut ExecState,
preserve_mem: bool,
) -> Result<(EnvironmentRef, Option<ModelingSessionData>), KclErrorWithOutputs> {
self.prepare_mem(exec_state).await.unwrap();
let mut universe = std::collections::HashMap::new();
let mut out_id_map = std::collections::HashMap::new();
crate::walk::import_universe(self, &program.ast, &mut universe, &mut out_id_map, exec_state)
.await
.unwrap();
for modules in crate::walk::import_graph(&universe).unwrap().into_iter() {
println!("Running module {modules:?}");
//let mut set = JoinSet::new();
println!("AFTER Running module {modules:?}");
let (results_tx, mut results_rx): (
tokio::sync::mpsc::Sender<(
String,
Result<(Option<KclValue>, EnvironmentRef, Vec<String>), KclError>,
)>,
tokio::sync::mpsc::Receiver<_>,
) = tokio::sync::mpsc::channel(1);
for module in modules {
let program = universe.get(&module).unwrap().clone();
let Some(module_id) = out_id_map.get(&module) else {
panic!("Module {module} not found in exec_state");
};
let module_id = module_id.clone();
let module_path = {
let module_info = exec_state.get_module(module_id).unwrap();
let module_path = module_info.path.clone();
module_path
};
let exec_state = exec_state.clone();
let exec_ctxt = self.clone();
let results_tx = results_tx.clone();
println!("before spawn");
#[cfg(target_arch = "wasm32")]
{
wasm_bindgen_futures::spawn_local(async move {
//set.spawn(async move {
println!("Running module {module} from run_concurrent");
let mut exec_state = exec_state;
let exec_ctxt = exec_ctxt;
let program = program;
let result = exec_ctxt
.exec_module_from_ast(
&program,
module_id,
&module_path,
&mut exec_state,
Default::default(),
)
.await;
results_tx.send((module, result)).await.unwrap();
});
}
}
drop(results_tx);
while let Some((module, result)) = results_rx.recv().await {
match result {
Ok((env_ref, session_data, variables)) => {
println!("{module} {:?}", variables);
let Some(module_id) = out_id_map.get(&module) else {
//let snapshot_png_bytes = self.prepare_snapshot().await.unwrap().contents.0;
// Save to a file.
//tokio::fs::write("snapshot.png", snapshot_png_bytes).await.unwrap();
return Err(KclErrorWithOutputs::no_outputs(KclError::Internal(KclErrorDetails {
message: format!("Module {module} not found in exec_state"),
source_ranges: Default::default(),
})));
};
let path = exec_state.global.module_infos[module_id].path.clone();
let mut repr = exec_state.global.module_infos[module_id].take_repr();
let ModuleRepr::Kcl(program, cache) = &mut repr else {
continue;
};
*cache = Some((session_data, variables.clone()));
exec_state.global.module_infos[module_id].restore_repr(repr);
}
Err(e) => {
//let snapshot_png_bytes = self.prepare_snapshot().await.unwrap().contents.0;
// Save to a file.
//tokio::fs::write("snapshot.png", snapshot_png_bytes).await.unwrap();
return Err(KclErrorWithOutputs::no_outputs(e));
}
}
}
}
self.inner_run(program, exec_state, preserve_mem).await
}
/// Perform the execution of a program. Accept all possible parameters and
@ -758,11 +872,11 @@ impl ExecutorContext {
)
})?;
if !self.is_mock() {
/* if !self.is_mock() {
let mut mem = exec_state.stack().deep_clone();
mem.restore_env(env_ref);
cache::write_old_memory((mem, exec_state.global.module_infos.clone())).await;
}
}*/
let session_data = self.engine.get_session_data().await;
Ok((env_ref, session_data))
}
@ -785,7 +899,6 @@ impl ExecutorContext {
.exec_module_body(
program,
exec_state,
ExecutionKind::Normal,
preserve_mem,
ModuleId::default(),
&ModulePath::Main,
@ -839,9 +952,7 @@ impl ExecutorContext {
source_range,
)
.await?;
let (module_memory, _) = self
.exec_module_for_items(id, exec_state, ExecutionKind::Isolated, source_range)
.await?;
let (module_memory, _) = self.exec_module_for_items(id, exec_state, source_range).await?;
exec_state.mut_stack().memory.set_std(module_memory);
}
@ -1534,8 +1645,8 @@ let shape = layer() |> patternTransform(instances = 10, transform = transform)
#[tokio::test(flavor = "multi_thread")]
async fn test_unit_default() {
let ast = r#"const inMm = fromMm(25.4)
const inInches = fromInches(1)"#;
let ast = r#"const inMm = 25.4 * mm()
const inInches = 1.0 * inch()"#;
let result = parse_execute(ast).await.unwrap();
assert_eq!(
25.4,
@ -1554,8 +1665,8 @@ const inInches = fromInches(1)"#;
#[tokio::test(flavor = "multi_thread")]
async fn test_unit_overriden() {
let ast = r#"@settings(defaultLengthUnit = inch)
const inMm = fromMm(25.4)
const inInches = fromInches(1)"#;
const inMm = 25.4 * mm()
const inInches = 1.0 * inch()"#;
let result = parse_execute(ast).await.unwrap();
assert_eq!(
1.0,
@ -1575,8 +1686,8 @@ const inInches = fromInches(1)"#;
#[tokio::test(flavor = "multi_thread")]
async fn test_unit_overriden_in() {
let ast = r#"@settings(defaultLengthUnit = in)
const inMm = fromMm(25.4)
const inInches = fromInches(2)"#;
const inMm = 25.4 * mm()
const inInches = 2.0 * inch()"#;
let result = parse_execute(ast).await.unwrap();
assert_eq!(
1.0,

View File

@ -228,6 +228,10 @@ impl ExecState {
self.global.module_infos.insert(id, module_info);
}
pub fn get_module(&mut self, id: ModuleId) -> Option<&ModuleInfo> {
self.global.module_infos.get(&id)
}
pub fn length_unit(&self) -> UnitLen {
self.mod_local.settings.default_length_units
}

View File

@ -14,20 +14,10 @@ use crate::{
ast::types::{PrimitiveType as AstPrimitiveType, Type},
token::NumericSuffix,
},
std::args::{FromKclValue, TyF64},
std::args::FromKclValue,
CompilationError, SourceRange,
};
lazy_static::lazy_static! {
pub(super) 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)]
pub enum RuntimeType {
Primitive(PrimitiveType),
@ -347,7 +337,7 @@ impl fmt::Display for PrimitiveType {
}
}
#[derive(Debug, Clone, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
#[ts(export)]
#[serde(tag = "type")]
pub enum NumericType {
@ -361,15 +351,6 @@ pub enum NumericType {
Any,
}
impl Default for NumericType {
fn default() -> Self {
NumericType::Default {
len: UnitLen::default(),
angle: UnitAngle::default(),
}
}
}
impl NumericType {
pub fn count() -> Self {
NumericType::Known(UnitType::Count)
@ -380,67 +361,52 @@ impl NumericType {
}
/// Combine two types when we expect them to be equal.
pub fn combine_eq(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),
// Known types and compatible, but needs adjustment.
(t @ Known(UnitType::Length(l1)), Known(UnitType::Length(l2))) => (a.n, l2.adjust_to(b.n, l1), t),
(t @ Known(UnitType::Angle(a1)), Known(UnitType::Angle(a2))) => (a.n, a2.adjust_to(b.n, a1), t),
// Known but incompatible.
(Known(_), Known(_)) => (a.n, b.n, Unknown),
// Known and unknown => we assume the known one, possibly with adjustment
(Known(UnitType::Count), Default { .. }) | (Default { .. }, Known(UnitType::Count)) => {
(a.n, b.n, Known(UnitType::Count))
}
(t @ Known(UnitType::Length(l1)), Default { len: l2, .. }) => (a.n, l2.adjust_to(b.n, l1), t),
(Default { len: l1, .. }, t @ Known(UnitType::Length(l2))) => (l1.adjust_to(a.n, l2), b.n, t),
(t @ Known(UnitType::Angle(a1)), Default { angle: a2, .. }) => (a.n, a2.adjust_to(b.n, a1), t),
(Default { angle: a1, .. }, t @ Known(UnitType::Angle(a2))) => (a1.adjust_to(a.n, a2), b.n, t),
pub fn combine_eq(self, other: &NumericType) -> NumericType {
if &self == other {
self
} else {
NumericType::Unknown
}
}
/// Combine two types for multiplication-like operations.
pub fn combine_mul(a: TyF64, b: TyF64) -> (f64, f64, NumericType) {
use NumericType::*;
match (a.ty, b.ty) {
(at @ Default { .. }, bt @ Default { .. }) if at != bt => (a.n, b.n, Unknown),
(Known(UnitType::Count) | Default { .. }, bt) => (a.n, b.n, bt),
(at, Known(UnitType::Count) | Default { .. }) => (a.n, b.n, at),
(Any, Any) => (a.n, b.n, Any),
_ => (a.n, b.n, Unknown),
/// Combine n types when we expect them to be equal.
///
/// Precondition: tys.len() > 0
pub fn combine_n_eq(tys: &[NumericType]) -> NumericType {
let ty0 = tys[0].clone();
for t in &tys[1..] {
if t != &ty0 {
return NumericType::Unknown;
}
}
ty0
}
/// Combine two types for division-like operations.
pub fn combine_div(a: TyF64, b: TyF64) -> (f64, f64, NumericType) {
use NumericType::*;
match (a.ty, b.ty) {
(at, bt) if at == bt => (a.n, b.n, Known(UnitType::Count)),
(Default { .. }, Default { .. }) => (a.n, b.n, Unknown),
(at, Known(UnitType::Count) | Default { .. } | Any) => (a.n, b.n, at),
(Known(UnitType::Length(l1)), Known(UnitType::Length(l2))) => {
(a.n, l2.adjust_to(b.n, l1), Known(UnitType::Count))
/// Combine two types in addition-like operations.
pub fn combine_add(a: NumericType, b: NumericType) -> NumericType {
if a == b {
return a;
}
(Known(UnitType::Angle(a1)), Known(UnitType::Angle(a2))) => {
(a.n, a2.adjust_to(b.n, a1), Known(UnitType::Count))
NumericType::Unknown
}
(Default { len: l1, .. }, Known(UnitType::Length(l2))) => {
(l1.adjust_to(a.n, l2), b.n, Known(UnitType::Count))
/// Combine two types in multiplication-like operations.
pub fn combine_mul(a: NumericType, b: NumericType) -> NumericType {
if a == NumericType::count() {
return b;
}
(Default { angle: a1, .. }, Known(UnitType::Angle(a2))) => {
(a1.adjust_to(a.n, a2), b.n, Known(UnitType::Count))
if b == NumericType::count() {
return a;
}
_ => (a.n, b.n, Unknown),
NumericType::Unknown
}
/// Combine two types in division-like operations.
pub fn combine_div(a: NumericType, b: NumericType) -> NumericType {
if b == NumericType::count() {
return a;
}
NumericType::Unknown
}
pub fn from_parsed(suffix: NumericSuffix, settings: &super::MetaSettings) -> Self {
@ -465,104 +431,12 @@ impl NumericType {
use NumericType::*;
match (self, other) {
(_, Any) => true,
(a, b) if a == b => true,
(Unknown, _) | (_, Unknown) => false,
(a, b) if a == b => true,
(_, Any) => true,
(_, _) => false,
}
}
fn example_ty(&self) -> Option<String> {
match self {
Self::Known(t) => Some(t.to_string()),
Self::Default { len, .. } => Some(len.to_string()),
_ => None,
}
}
fn coerce(&self, val: &KclValue) -> Result<KclValue, CoercionError> {
let KclValue::Number { value, ty, meta } = val else {
return Err(val.into());
};
if !*CHECK_NUMERIC_TYPES {
return Ok(val.clone());
}
if ty.subtype(self) {
return Ok(KclValue::Number {
value: *value,
ty: ty.clone(),
meta: meta.clone(),
});
}
// Not subtypes, but might be able to coerce
use NumericType::*;
match (ty, self) {
// We don't have enough information to coerce.
(Unknown, _) => Err(CoercionError::from(val).with_explicit(self.example_ty().unwrap_or("mm".to_owned()))),
(_, Unknown) => Err(val.into()),
(Any, _) => Ok(KclValue::Number {
value: *value,
ty: self.clone(),
meta: meta.clone(),
}),
// We don't actually need to coerce, since we just keep the partially-known type with the value.
(Default { .. }, Default { .. }) => Ok(KclValue::Number {
value: *value,
ty: ty.clone(),
meta: meta.clone(),
}),
// Known types and compatible, but needs adjustment.
(Known(UnitType::Length(l1)), Known(UnitType::Length(l2))) => Ok(KclValue::Number {
value: l1.adjust_to(*value, *l2),
ty: self.clone(),
meta: meta.clone(),
}),
(Known(UnitType::Angle(a1)), Known(UnitType::Angle(a2))) => Ok(KclValue::Number {
value: a1.adjust_to(*value, *a2),
ty: self.clone(),
meta: meta.clone(),
}),
// Known but incompatible.
(Known(_), Known(_)) => Err(val.into()),
// Known and unknown => we assume the rhs, possibly with adjustment
(Known(UnitType::Count), Default { .. }) | (Default { .. }, Known(UnitType::Count)) => {
Ok(KclValue::Number {
value: *value,
ty: Known(UnitType::Count),
meta: meta.clone(),
})
}
(Known(UnitType::Length(l1)), Default { len: l2, .. })
| (Default { len: l1, .. }, Known(UnitType::Length(l2))) => Ok(KclValue::Number {
value: l1.adjust_to(*value, *l2),
ty: Known(UnitType::Length(*l2)),
meta: meta.clone(),
}),
(Known(UnitType::Angle(a1)), Default { angle: a2, .. })
| (Default { angle: a1, .. }, Known(UnitType::Angle(a2))) => Ok(KclValue::Number {
value: a1.adjust_to(*value, *a2),
ty: Known(UnitType::Angle(*a2)),
meta: meta.clone(),
}),
(_, _) => unreachable!(),
}
}
}
impl From<NumericType> for RuntimeType {
fn from(t: NumericType) -> RuntimeType {
RuntimeType::Primitive(PrimitiveType::Number(t))
}
}
impl From<UnitLen> for NumericType {
@ -611,39 +485,6 @@ pub enum UnitLen {
Yards,
}
impl UnitLen {
fn adjust_to(self, value: f64, to: UnitLen) -> f64 {
if self == to {
return value;
}
use UnitLen::*;
let (base, base_unit) = match self {
Mm => (value, Mm),
Cm => (value * 10.0, Mm),
M => (value * 1000.0, Mm),
Inches => (value, Inches),
Feet => (value * 12.0, Inches),
Yards => (value * 36.0, Inches),
};
let (base, base_unit) = match (base_unit, to) {
(Mm, Inches) | (Mm, Feet) | (Mm, Yards) => (base / 25.4, Inches),
(Inches, Mm) | (Inches, Cm) | (Inches, M) => (base * 25.4, Mm),
_ => (base, base_unit),
};
match (base_unit, to) {
(Mm, Mm) => base,
(Mm, Cm) => base / 10.0,
(Mm, M) => base / 1000.0,
(Inches, Inches) => base,
(Inches, Feet) => base / 12.0,
(Inches, Yards) => base / 36.0,
_ => unreachable!(),
}
}
}
impl std::fmt::Display for UnitLen {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
@ -722,19 +563,6 @@ pub enum UnitAngle {
Radians,
}
impl UnitAngle {
fn adjust_to(self, value: f64, to: UnitAngle) -> f64 {
use std::f64::consts::PI;
use UnitAngle::*;
match (self, to) {
(Degrees, Degrees) => value,
(Degrees, Radians) => (value / 180.0) * PI,
(Radians, Degrees) => 180.0 * value / PI,
(Radians, Radians) => value,
}
}
}
impl std::fmt::Display for UnitAngle {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
@ -756,28 +584,6 @@ impl TryFrom<NumericSuffix> for UnitAngle {
}
}
#[derive(Debug, Clone)]
pub struct CoercionError {
pub found: Option<RuntimeType>,
pub explicit_coercion: Option<String>,
}
impl CoercionError {
fn with_explicit(mut self, c: String) -> Self {
self.explicit_coercion = Some(c);
self
}
}
impl From<&'_ KclValue> for CoercionError {
fn from(value: &'_ KclValue) -> Self {
CoercionError {
found: value.principal_type(),
explicit_coercion: None,
}
}
}
impl KclValue {
/// True if `self` has a type which is a subtype of `ty` without coercion.
pub fn has_type(&self, ty: &RuntimeType) -> bool {
@ -794,7 +600,7 @@ impl KclValue {
/// - result.principal_type().unwrap().subtype(ty)
///
/// If self.principal_type() == ty then result == self
pub fn coerce(&self, ty: &RuntimeType, exec_state: &mut ExecState) -> Result<KclValue, CoercionError> {
pub fn coerce(&self, ty: &RuntimeType, exec_state: &mut ExecState) -> Option<KclValue> {
match ty {
RuntimeType::Primitive(ty) => self.coerce_to_primitive_type(ty, exec_state),
RuntimeType::Array(ty, len) => self.coerce_to_array_type(ty, *len, exec_state, false),
@ -804,52 +610,40 @@ impl KclValue {
}
}
fn coerce_to_primitive_type(
&self,
ty: &PrimitiveType,
exec_state: &mut ExecState,
) -> Result<KclValue, CoercionError> {
fn coerce_to_primitive_type(&self, ty: &PrimitiveType, exec_state: &mut ExecState) -> Option<KclValue> {
let value = match self {
KclValue::MixedArray { value, .. } | KclValue::HomArray { value, .. } if value.len() == 1 => &value[0],
_ => self,
};
match ty {
PrimitiveType::Number(ty) => ty.coerce(value),
// TODO numeric type coercions
PrimitiveType::Number(_ty) => match value {
KclValue::Number { .. } => Some(value.clone()),
_ => None,
},
PrimitiveType::String => match value {
KclValue::String { .. } => Ok(value.clone()),
_ => Err(self.into()),
KclValue::String { .. } => Some(value.clone()),
_ => None,
},
PrimitiveType::Boolean => match value {
KclValue::Bool { .. } => Ok(value.clone()),
_ => Err(self.into()),
KclValue::Bool { .. } => Some(value.clone()),
_ => None,
},
PrimitiveType::Sketch => match value {
KclValue::Sketch { .. } => Ok(value.clone()),
_ => Err(self.into()),
KclValue::Sketch { .. } => Some(value.clone()),
_ => None,
},
PrimitiveType::Solid => match value {
KclValue::Solid { .. } => Ok(value.clone()),
_ => Err(self.into()),
KclValue::Solid { .. } => Some(value.clone()),
_ => None,
},
PrimitiveType::Plane => match value {
KclValue::Plane { .. } => Ok(value.clone()),
KclValue::Plane { .. } => Some(value.clone()),
KclValue::Object { value, meta } => {
let origin = value
.get("origin")
.and_then(Point3d::from_kcl_val)
.ok_or(CoercionError::from(self))?;
let x_axis = value
.get("xAxis")
.and_then(Point3d::from_kcl_val)
.ok_or(CoercionError::from(self))?;
let y_axis = value
.get("yAxis")
.and_then(Point3d::from_kcl_val)
.ok_or(CoercionError::from(self))?;
let z_axis = value
.get("zAxis")
.and_then(Point3d::from_kcl_val)
.ok_or(CoercionError::from(self))?;
let origin = value.get("origin").and_then(Point3d::from_kcl_val)?;
let x_axis = value.get("xAxis").and_then(Point3d::from_kcl_val)?;
let y_axis = value.get("yAxis").and_then(Point3d::from_kcl_val)?;
let z_axis = value.get("zAxis").and_then(Point3d::from_kcl_val)?;
let id = exec_state.mod_local.id_generator.next_uuid();
let plane = Plane {
@ -865,87 +659,75 @@ impl KclValue {
meta: meta.clone(),
};
Ok(KclValue::Plane { value: Box::new(plane) })
Some(KclValue::Plane { value: Box::new(plane) })
}
_ => Err(self.into()),
_ => None,
},
PrimitiveType::Face => match value {
KclValue::Face { .. } => Ok(value.clone()),
_ => Err(self.into()),
KclValue::Face { .. } => Some(value.clone()),
_ => None,
},
PrimitiveType::Helix => match value {
KclValue::Helix { .. } => Ok(value.clone()),
_ => Err(self.into()),
KclValue::Helix { .. } => Some(value.clone()),
_ => None,
},
PrimitiveType::Edge => match value {
KclValue::Uuid { .. } => Ok(value.clone()),
KclValue::TagIdentifier { .. } => Ok(value.clone()),
_ => Err(self.into()),
KclValue::Uuid { .. } => Some(value.clone()),
KclValue::TagIdentifier { .. } => Some(value.clone()),
_ => None,
},
PrimitiveType::Axis2d => match value {
KclValue::Object { value: values, meta } => {
if values
.get("origin")
.ok_or(CoercionError::from(self))?
.has_type(&RuntimeType::point2d())
&& values
.get("direction")
.ok_or(CoercionError::from(self))?
.has_type(&RuntimeType::point2d())
if values.get("origin")?.has_type(&RuntimeType::point2d())
&& values.get("direction")?.has_type(&RuntimeType::point2d())
{
return Ok(value.clone());
return Some(value.clone());
}
let origin = values.get("origin").ok_or(self.into()).and_then(|p| {
let origin = values.get("origin").and_then(|p| {
p.coerce_to_array_type(&RuntimeType::number_any(), ArrayLen::Known(2), exec_state, true)
})?;
let direction = values.get("direction").ok_or(self.into()).and_then(|p| {
let direction = values.get("direction").and_then(|p| {
p.coerce_to_array_type(&RuntimeType::number_any(), ArrayLen::Known(2), exec_state, true)
})?;
Ok(KclValue::Object {
Some(KclValue::Object {
value: [("origin".to_owned(), origin), ("direction".to_owned(), direction)].into(),
meta: meta.clone(),
})
}
_ => Err(self.into()),
_ => None,
},
PrimitiveType::Axis3d => match value {
KclValue::Object { value: values, meta } => {
if values
.get("origin")
.ok_or(CoercionError::from(self))?
.has_type(&RuntimeType::point3d())
&& values
.get("direction")
.ok_or(CoercionError::from(self))?
.has_type(&RuntimeType::point3d())
if values.get("origin")?.has_type(&RuntimeType::point3d())
&& values.get("direction")?.has_type(&RuntimeType::point3d())
{
return Ok(value.clone());
return Some(value.clone());
}
let origin = values.get("origin").ok_or(self.into()).and_then(|p| {
let origin = values.get("origin").and_then(|p| {
p.coerce_to_array_type(&RuntimeType::number_any(), ArrayLen::Known(3), exec_state, true)
})?;
let direction = values.get("direction").ok_or(self.into()).and_then(|p| {
let direction = values.get("direction").and_then(|p| {
p.coerce_to_array_type(&RuntimeType::number_any(), ArrayLen::Known(3), exec_state, true)
})?;
Ok(KclValue::Object {
Some(KclValue::Object {
value: [("origin".to_owned(), origin), ("direction".to_owned(), direction)].into(),
meta: meta.clone(),
})
}
_ => Err(self.into()),
_ => None,
},
PrimitiveType::ImportedGeometry => match value {
KclValue::ImportedGeometry { .. } => Ok(value.clone()),
_ => Err(self.into()),
KclValue::ImportedGeometry { .. } => Some(value.clone()),
_ => None,
},
PrimitiveType::Tag => match value {
KclValue::TagDeclarator { .. } => Ok(value.clone()),
KclValue::TagIdentifier { .. } => Ok(value.clone()),
_ => Err(self.into()),
KclValue::TagDeclarator { .. } => Some(value.clone()),
KclValue::TagIdentifier { .. } => Some(value.clone()),
_ => None,
},
}
}
@ -956,40 +738,37 @@ impl KclValue {
len: ArrayLen,
exec_state: &mut ExecState,
allow_shrink: bool,
) -> Result<KclValue, CoercionError> {
) -> Option<KclValue> {
match self {
KclValue::HomArray { value, ty: aty } if aty.subtype(ty) => len
.satisfied(value.len(), allow_shrink)
.map(|len| KclValue::HomArray {
KclValue::HomArray { value, ty: aty } if aty.subtype(ty) => {
len.satisfied(value.len(), allow_shrink).map(|len| KclValue::HomArray {
value: value[..len].to_vec(),
ty: aty.clone(),
})
.ok_or(self.into()),
value if len.satisfied(1, false).is_some() && value.has_type(ty) => Ok(KclValue::HomArray {
}
value if len.satisfied(1, false).is_some() && value.has_type(ty) => Some(KclValue::HomArray {
value: vec![value.clone()],
ty: ty.clone(),
}),
KclValue::MixedArray { value, .. } => {
let len = len
.satisfied(value.len(), allow_shrink)
.ok_or(CoercionError::from(self))?;
let len = len.satisfied(value.len(), allow_shrink)?;
let value = value[..len]
.iter()
.map(|v| v.coerce(ty, exec_state))
.collect::<Result<Vec<_>, _>>()?;
.collect::<Option<Vec<_>>>()?;
Ok(KclValue::HomArray { value, ty: ty.clone() })
Some(KclValue::HomArray { value, ty: ty.clone() })
}
KclValue::KclNone { .. } if len.satisfied(0, false).is_some() => Ok(KclValue::HomArray {
KclValue::KclNone { .. } if len.satisfied(0, false).is_some() => Some(KclValue::HomArray {
value: Vec::new(),
ty: ty.clone(),
}),
_ => Err(self.into()),
_ => None,
}
}
fn coerce_to_tuple_type(&self, tys: &[RuntimeType], exec_state: &mut ExecState) -> Result<KclValue, CoercionError> {
fn coerce_to_tuple_type(&self, tys: &[RuntimeType], exec_state: &mut ExecState) -> Option<KclValue> {
match self {
KclValue::MixedArray { value, .. } | KclValue::HomArray { value, .. } if value.len() == tys.len() => {
let mut result = Vec::new();
@ -997,54 +776,50 @@ impl KclValue {
result.push(value[i].coerce(t, exec_state)?);
}
Ok(KclValue::MixedArray {
Some(KclValue::MixedArray {
value: result,
meta: Vec::new(),
})
}
KclValue::KclNone { meta, .. } if tys.is_empty() => Ok(KclValue::MixedArray {
KclValue::KclNone { meta, .. } if tys.is_empty() => Some(KclValue::MixedArray {
value: Vec::new(),
meta: meta.clone(),
}),
value if tys.len() == 1 && value.has_type(&tys[0]) => Ok(KclValue::MixedArray {
value if tys.len() == 1 && value.has_type(&tys[0]) => Some(KclValue::MixedArray {
value: vec![value.clone()],
meta: Vec::new(),
}),
_ => Err(self.into()),
_ => None,
}
}
fn coerce_to_union_type(&self, tys: &[RuntimeType], exec_state: &mut ExecState) -> Result<KclValue, CoercionError> {
fn coerce_to_union_type(&self, tys: &[RuntimeType], exec_state: &mut ExecState) -> Option<KclValue> {
for t in tys {
if let Ok(v) = self.coerce(t, exec_state) {
return Ok(v);
if let Some(v) = self.coerce(t, exec_state) {
return Some(v);
}
}
Err(self.into())
None
}
fn coerce_to_object_type(
&self,
tys: &[(String, RuntimeType)],
_exec_state: &mut ExecState,
) -> Result<KclValue, CoercionError> {
fn coerce_to_object_type(&self, tys: &[(String, RuntimeType)], _exec_state: &mut ExecState) -> Option<KclValue> {
match self {
KclValue::Object { value, .. } => {
for (s, t) in tys {
// TODO coerce fields
if !value.get(s).ok_or(CoercionError::from(self))?.has_type(t) {
return Err(self.into());
if !value.get(s)?.has_type(t) {
return None;
}
}
// TODO remove non-required fields
Ok(self.clone())
Some(self.clone())
}
KclValue::KclNone { meta, .. } if tys.is_empty() => Ok(KclValue::Object {
KclValue::KclNone { meta, .. } if tys.is_empty() => Some(KclValue::Object {
value: HashMap::new(),
meta: meta.clone(),
}),
_ => Err(self.into()),
_ => None,
}
}
@ -1084,8 +859,6 @@ impl KclValue {
#[cfg(test)]
mod test {
use crate::execution::{parse_execute, ExecTestResults};
use super::*;
fn values(exec_state: &mut ExecState) -> Vec<KclValue> {
@ -1217,7 +990,7 @@ mod test {
// Not a subtype
assert!(v
.coerce(&RuntimeType::Primitive(PrimitiveType::Boolean), &mut exec_state)
.is_err());
.is_none());
}
}
@ -1251,8 +1024,8 @@ mod test {
},
&mut exec_state,
);
assert!(none.coerce(&aty1, &mut exec_state).is_err());
assert!(none.coerce(&aty1p, &mut exec_state).is_err());
assert!(none.coerce(&aty1, &mut exec_state).is_none());
assert!(none.coerce(&aty1p, &mut exec_state).is_none());
let tty = RuntimeType::Tuple(vec![]);
let tty1 = RuntimeType::Tuple(vec![RuntimeType::solid()]);
@ -1265,7 +1038,7 @@ mod test {
},
&mut exec_state,
);
assert!(none.coerce(&tty1, &mut exec_state).is_err());
assert!(none.coerce(&tty1, &mut exec_state).is_none());
let oty = RuntimeType::Object(vec![]);
assert_coerce_results(
@ -1334,7 +1107,7 @@ mod test {
assert_coerce_results(&obj2, &ty0, &obj2, &mut exec_state);
let ty1 = RuntimeType::Object(vec![("foo".to_owned(), RuntimeType::Primitive(PrimitiveType::Boolean))]);
assert!(&obj0.coerce(&ty1, &mut exec_state).is_err());
assert!(&obj0.coerce(&ty1, &mut exec_state).is_none());
assert_coerce_results(&obj1, &ty1, &obj1, &mut exec_state);
assert_coerce_results(&obj2, &ty1, &obj2, &mut exec_state);
@ -1346,19 +1119,19 @@ mod test {
),
("foo".to_owned(), RuntimeType::Primitive(PrimitiveType::Boolean)),
]);
assert!(&obj0.coerce(&ty2, &mut exec_state).is_err());
assert!(&obj1.coerce(&ty2, &mut exec_state).is_err());
assert!(&obj0.coerce(&ty2, &mut exec_state).is_none());
assert!(&obj1.coerce(&ty2, &mut exec_state).is_none());
assert_coerce_results(&obj2, &ty2, &obj2, &mut exec_state);
// field not present
let tyq = RuntimeType::Object(vec![("qux".to_owned(), RuntimeType::Primitive(PrimitiveType::Boolean))]);
assert!(&obj0.coerce(&tyq, &mut exec_state).is_err());
assert!(&obj1.coerce(&tyq, &mut exec_state).is_err());
assert!(&obj2.coerce(&tyq, &mut exec_state).is_err());
assert!(&obj0.coerce(&tyq, &mut exec_state).is_none());
assert!(&obj1.coerce(&tyq, &mut exec_state).is_none());
assert!(&obj2.coerce(&tyq, &mut exec_state).is_none());
// field with different type
let ty1 = RuntimeType::Object(vec![("bar".to_owned(), RuntimeType::Primitive(PrimitiveType::Boolean))]);
assert!(&obj2.coerce(&ty1, &mut exec_state).is_err());
assert!(&obj2.coerce(&ty1, &mut exec_state).is_none());
}
#[tokio::test(flavor = "multi_thread")]
@ -1436,8 +1209,8 @@ mod test {
assert_coerce_results(&hom_arr, &tyh, &hom_arr, &mut exec_state);
assert_coerce_results(&mixed1, &tym1, &mixed1, &mut exec_state);
assert_coerce_results(&mixed2, &tym2, &mixed2, &mut exec_state);
assert!(&mixed1.coerce(&tym2, &mut exec_state).is_err());
assert!(&mixed2.coerce(&tym1, &mut exec_state).is_err());
assert!(&mixed1.coerce(&tym2, &mut exec_state).is_none());
assert!(&mixed2.coerce(&tym1, &mut exec_state).is_none());
// Length subtyping
let tyhn = RuntimeType::Array(
@ -1454,15 +1227,15 @@ mod test {
);
assert_coerce_results(&hom_arr, &tyhn, &hom_arr, &mut exec_state);
assert_coerce_results(&hom_arr, &tyh1, &hom_arr, &mut exec_state);
assert!(&hom_arr.coerce(&tyh3, &mut exec_state).is_err());
assert!(&hom_arr.coerce(&tyh3, &mut exec_state).is_none());
let hom_arr0 = KclValue::HomArray {
value: vec![],
ty: RuntimeType::Primitive(PrimitiveType::Number(NumericType::count())),
};
assert_coerce_results(&hom_arr0, &tyhn, &hom_arr0, &mut exec_state);
assert!(&hom_arr0.coerce(&tyh1, &mut exec_state).is_err());
assert!(&hom_arr0.coerce(&tyh3, &mut exec_state).is_err());
assert!(&hom_arr0.coerce(&tyh1, &mut exec_state).is_none());
assert!(&hom_arr0.coerce(&tyh3, &mut exec_state).is_none());
// Covariance
// let tyh = RuntimeType::Array(Box::new(RuntimeType::Primitive(PrimitiveType::Number(NumericType::Any))), ArrayLen::Known(4));
@ -1502,16 +1275,16 @@ mod test {
assert_coerce_results(&mixed1, &tyhn, &hom_arr_2, &mut exec_state);
assert_coerce_results(&mixed1, &tyh1, &hom_arr_2, &mut exec_state);
assert_coerce_results(&mixed0, &tyhn, &hom_arr0, &mut exec_state);
assert!(&mixed0.coerce(&tyh, &mut exec_state).is_err());
assert!(&mixed0.coerce(&tyh1, &mut exec_state).is_err());
assert!(&mixed0.coerce(&tyh, &mut exec_state).is_none());
assert!(&mixed0.coerce(&tyh1, &mut exec_state).is_none());
// Homogehous to mixed
assert_coerce_results(&hom_arr_2, &tym1, &mixed1, &mut exec_state);
assert!(&hom_arr.coerce(&tym1, &mut exec_state).is_err());
assert!(&hom_arr_2.coerce(&tym2, &mut exec_state).is_err());
assert!(&hom_arr.coerce(&tym1, &mut exec_state).is_none());
assert!(&hom_arr_2.coerce(&tym2, &mut exec_state).is_none());
assert!(&mixed0.coerce(&tym1, &mut exec_state).is_err());
assert!(&mixed0.coerce(&tym2, &mut exec_state).is_err());
assert!(&mixed0.coerce(&tym1, &mut exec_state).is_none());
assert!(&mixed0.coerce(&tym2, &mut exec_state).is_none());
}
#[tokio::test(flavor = "multi_thread")]
@ -1561,8 +1334,8 @@ mod test {
RuntimeType::Primitive(PrimitiveType::Boolean),
RuntimeType::Primitive(PrimitiveType::String),
]);
assert!(count.coerce(&tyb, &mut exec_state).is_err());
assert!(count.coerce(&tyb2, &mut exec_state).is_err());
assert!(count.coerce(&tyb, &mut exec_state).is_none());
assert!(count.coerce(&tyb2, &mut exec_state).is_none());
}
#[tokio::test(flavor = "multi_thread")]
@ -1677,192 +1450,6 @@ mod test {
assert_coerce_results(&a2d, &ty2d, &a2d, &mut exec_state);
assert_coerce_results(&a3d, &ty3d, &a3d, &mut exec_state);
assert_coerce_results(&a3d, &ty2d, &a2d, &mut exec_state);
assert!(a2d.coerce(&ty3d, &mut exec_state).is_err());
}
#[tokio::test(flavor = "multi_thread")]
async fn coerce_numeric() {
let mut exec_state = ExecState::new(&crate::ExecutorContext::new_mock().await);
let count = KclValue::Number {
value: 1.0,
ty: NumericType::count(),
meta: Vec::new(),
};
let mm = KclValue::Number {
value: 1.0,
ty: NumericType::mm(),
meta: Vec::new(),
};
let inches = KclValue::Number {
value: 1.0,
ty: NumericType::Known(UnitType::Length(UnitLen::Inches)),
meta: Vec::new(),
};
let rads = KclValue::Number {
value: 1.0,
ty: NumericType::Known(UnitType::Angle(UnitAngle::Radians)),
meta: Vec::new(),
};
let default = KclValue::Number {
value: 1.0,
ty: NumericType::default(),
meta: Vec::new(),
};
let any = KclValue::Number {
value: 1.0,
ty: NumericType::Any,
meta: Vec::new(),
};
let unknown = KclValue::Number {
value: 1.0,
ty: NumericType::Unknown,
meta: Vec::new(),
};
// Trivial coercions
assert_coerce_results(&count, &NumericType::count().into(), &count, &mut exec_state);
assert_coerce_results(&mm, &NumericType::mm().into(), &mm, &mut exec_state);
assert_coerce_results(&any, &NumericType::Any.into(), &any, &mut exec_state);
assert_coerce_results(&unknown, &NumericType::Unknown.into(), &unknown, &mut exec_state);
assert_coerce_results(&default, &NumericType::default().into(), &default, &mut exec_state);
assert_coerce_results(&count, &NumericType::Any.into(), &count, &mut exec_state);
assert_coerce_results(&mm, &NumericType::Any.into(), &mm, &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);
if !*CHECK_NUMERIC_TYPES {
return;
}
assert_eq!(
default
.coerce(
&NumericType::Default {
len: UnitLen::Yards,
angle: UnitAngle::default()
}
.into(),
&mut exec_state
)
.unwrap(),
default
);
// No coercion
assert!(count.coerce(&NumericType::mm().into(), &mut exec_state).is_err());
assert!(mm.coerce(&NumericType::count().into(), &mut exec_state).is_err());
assert!(unknown.coerce(&NumericType::mm().into(), &mut exec_state).is_err());
assert!(unknown.coerce(&NumericType::default().into(), &mut exec_state).is_err());
assert!(count.coerce(&NumericType::Unknown.into(), &mut exec_state).is_err());
assert!(mm.coerce(&NumericType::Unknown.into(), &mut exec_state).is_err());
assert!(default.coerce(&NumericType::Unknown.into(), &mut exec_state).is_err());
assert_eq!(
inches
.coerce(&NumericType::mm().into(), &mut exec_state)
.unwrap()
.as_f64()
.unwrap()
.round(),
25.0
);
assert_eq!(
rads.coerce(
&NumericType::Known(UnitType::Angle(UnitAngle::Degrees)).into(),
&mut exec_state
)
.unwrap()
.as_f64()
.unwrap()
.round(),
57.0
);
assert_eq!(
inches
.coerce(&NumericType::default().into(), &mut exec_state)
.unwrap()
.as_f64()
.unwrap()
.round(),
25.0
);
assert_eq!(
rads.coerce(&NumericType::default().into(), &mut exec_state)
.unwrap()
.as_f64()
.unwrap()
.round(),
57.0
);
}
#[track_caller]
fn assert_value_and_type(name: &str, result: &ExecTestResults, expected: f64, expected_ty: NumericType) {
let mem = result.exec_state.stack();
match mem
.memory
.get_from(name, result.mem_env, SourceRange::default(), 0)
.unwrap()
{
KclValue::Number { value, ty, .. } => {
assert_eq!(value.round(), expected);
assert_eq!(*ty, expected_ty);
}
_ => unreachable!(),
}
}
#[tokio::test(flavor = "multi_thread")]
async fn combine_numeric() {
let program = r#"a = 5 + 4
b = 5 - 2
c = 5mm - 2mm + 10mm
d = 5mm - 2 + 10
e = 5 - 2mm + 10
f = 30mm - 1inch
g = 2 * 10
h = 2 * 10mm
i = 2mm * 10mm
j = 2_ * 10
k = 2_ * 3mm * 3mm
l = 1 / 10
m = 2mm / 1mm
n = 10inch / 2mm
o = 3mm / 3
p = 3_ / 4
q = 4inch / 2_
"#;
let result = parse_execute(program).await.unwrap();
if *CHECK_NUMERIC_TYPES {
assert_eq!(result.exec_state.errors().len(), 2);
} else {
assert!(result.exec_state.errors().is_empty());
}
assert_value_and_type("a", &result, 9.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("d", &result, 13.0, NumericType::mm());
assert_value_and_type("e", &result, 13.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("h", &result, 20.0, NumericType::mm());
assert_value_and_type("i", &result, 20.0, NumericType::Unknown);
assert_value_and_type("j", &result, 20.0, NumericType::default());
assert_value_and_type("k", &result, 18.0, NumericType::Unknown);
assert_value_and_type("l", &result, 0.0, NumericType::count());
assert_value_and_type("m", &result, 2.0, NumericType::count());
assert_value_and_type("n", &result, 127.0, NumericType::count());
assert_value_and_type("o", &result, 1.0, NumericType::mm());
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!(a2d.coerce(&ty3d, &mut exec_state).is_none());
}
}

View File

@ -76,12 +76,12 @@ pub mod std;
pub mod test_server;
mod thread;
mod unparser;
mod walk;
pub mod walk;
#[cfg(target_arch = "wasm32")]
mod wasm;
pub use coredump::CoreDump;
pub use engine::{EngineManager, EngineStats, ExecutionKind};
pub use engine::{EngineManager, EngineStats};
pub use errors::{
CompilationError, ConnectionError, ExecError, KclError, KclErrorWithOutputs, Report, ReportWithOutputs,
};

View File

@ -8,7 +8,7 @@ use kcmc::{
};
use kittycad_modeling_cmds as kcmc;
use schemars::JsonSchema;
use serde::Serialize;
use serde::{Deserialize, Serialize};
use crate::{
errors::{KclError, KclErrorDetails},
@ -72,7 +72,7 @@ impl KwArgs {
}
}
#[derive(Debug, Clone, Serialize, PartialEq, ts_rs::TS)]
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS)]
#[ts(export)]
#[serde(rename_all = "camelCase")]
pub struct TyF64 {
@ -92,7 +92,7 @@ impl TyF64 {
}
}
pub fn map_value(mut self, n: f64) -> Self {
pub fn map(mut self, n: f64) -> Self {
self.n = n;
self
}
@ -209,7 +209,7 @@ impl Args {
}));
};
let arg = arg.value.coerce(ty, exec_state).map_err(|_| {
let arg = arg.value.coerce(ty, exec_state).ok_or_else(|| {
let actual_type_name = arg.value.human_friendly_type();
let msg_base = format!(
"This function expected the input argument to be {} but it's actually of type {actual_type_name}",
@ -332,7 +332,7 @@ impl Args {
message: format!("This function requires a value for the special unlabeled first parameter, '{label}'"),
}))?;
let arg = arg.value.coerce(ty, exec_state).map_err(|_| {
let arg = arg.value.coerce(ty, exec_state).ok_or_else(|| {
let actual_type_name = arg.value.human_friendly_type();
let msg_base = format!(
"This function expected the input argument to be {} but it's actually of type {actual_type_name}",
@ -523,7 +523,7 @@ impl Args {
})
}
pub(super) fn make_user_val_from_f64(&self, f: f64) -> KclValue {
pub(crate) fn make_user_val_from_f64(&self, f: f64) -> KclValue {
KclValue::from_number(
f,
vec![Metadata {
@ -532,7 +532,7 @@ impl Args {
)
}
pub(super) fn make_user_val_from_f64_with_type(&self, f: TyF64) -> KclValue {
pub(crate) fn make_user_val_from_f64_with_type(&self, f: TyF64) -> KclValue {
KclValue::from_number_with_type(
f.n,
f.ty,
@ -542,7 +542,7 @@ impl Args {
)
}
pub(super) fn make_user_val_from_f64_array(&self, f: Vec<f64>, ty: &NumericType) -> Result<KclValue, KclError> {
pub(crate) fn make_user_val_from_f64_array(&self, f: Vec<f64>, ty: &NumericType) -> Result<KclValue, KclError> {
let array = f
.into_iter()
.map(|n| KclValue::Number {
@ -616,7 +616,8 @@ impl Args {
let mut numbers = numbers.into_iter();
let a = numbers.next().unwrap();
let b = numbers.next().unwrap();
Ok(NumericType::combine_eq(a, b))
let ty = a.ty.combine_eq(&b.ty);
Ok((a.n, b.n, ty))
}
pub(crate) fn get_sketches(&self, exec_state: &mut ExecState) -> Result<(Vec<Sketch>, Sketch), KclError> {
@ -626,15 +627,16 @@ impl Args {
source_ranges: vec![self.source_range],
}));
};
let sarg = arg0.value.coerce(&RuntimeType::sketches(), exec_state).map_err(|_| {
KclError::Type(KclErrorDetails {
let sarg = arg0
.value
.coerce(&RuntimeType::sketches(), exec_state)
.ok_or(KclError::Type(KclErrorDetails {
message: format!(
"Expected an array of sketches, found {}",
arg0.value.human_friendly_type()
),
source_ranges: vec![self.source_range],
})
})?;
}))?;
let sketches = match sarg {
KclValue::HomArray { value, .. } => value.iter().map(|v| v.as_sketch().unwrap().clone()).collect(),
_ => unreachable!(),
@ -649,12 +651,10 @@ impl Args {
let sarg = arg1
.value
.coerce(&RuntimeType::Primitive(PrimitiveType::Sketch), exec_state)
.map_err(|_| {
KclError::Type(KclErrorDetails {
.ok_or(KclError::Type(KclErrorDetails {
message: format!("Expected a sketch, found {}", arg1.value.human_friendly_type()),
source_ranges: vec![self.source_range],
})
})?;
}))?;
let sketch = match sarg {
KclValue::Sketch { value } => *value,
_ => unreachable!(),
@ -673,12 +673,10 @@ impl Args {
let sarg = arg0
.value
.coerce(&RuntimeType::Primitive(PrimitiveType::Sketch), exec_state)
.map_err(|_| {
KclError::Type(KclErrorDetails {
.ok_or(KclError::Type(KclErrorDetails {
message: format!("Expected a sketch, found {}", arg0.value.human_friendly_type()),
source_ranges: vec![self.source_range],
})
})?;
}))?;
match sarg {
KclValue::Sketch { value } => Ok(*value),
_ => unreachable!(),
@ -720,15 +718,13 @@ impl Args {
let sarg = arg1
.value
.coerce(&RuntimeType::Primitive(PrimitiveType::Sketch), exec_state)
.map_err(|_| {
KclError::Type(KclErrorDetails {
.ok_or(KclError::Type(KclErrorDetails {
message: format!(
"Expected a sketch for second argument, found {}",
arg1.value.human_friendly_type()
),
source_ranges: vec![self.source_range],
})
})?;
}))?;
let sketch = match sarg {
KclValue::Sketch { value } => *value,
_ => unreachable!(),
@ -758,15 +754,13 @@ impl Args {
let sarg = arg1
.value
.coerce(&RuntimeType::Primitive(PrimitiveType::Solid), exec_state)
.map_err(|_| {
KclError::Type(KclErrorDetails {
.ok_or(KclError::Type(KclErrorDetails {
message: format!(
"Expected a solid for second argument, found {}",
arg1.value.human_friendly_type()
),
source_ranges: vec![self.source_range],
})
})?;
}))?;
let solid = match sarg {
KclValue::Solid { value } => value,
_ => unreachable!(),

View File

@ -13,7 +13,7 @@ pub async fn int(_exec_state: &mut ExecState, args: Args) -> Result<KclValue, Kc
let num = args.get_number_with_type()?;
let converted = inner_int(num.n)?;
Ok(args.make_user_val_from_f64_with_type(num.map_value(converted)))
Ok(args.make_user_val_from_f64_with_type(num.map(converted)))
}
/// Convert a number to an integer.

View File

@ -139,12 +139,12 @@ lazy_static! {
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::FromInches),
Box::new(crate::std::units::FromFt),
Box::new(crate::std::units::FromM),
Box::new(crate::std::units::FromCm),
Box::new(crate::std::units::FromYd),
Box::new(crate::std::units::Mm),
Box::new(crate::std::units::Inch),
Box::new(crate::std::units::Ft),
Box::new(crate::std::units::M),
Box::new(crate::std::units::Cm),
Box::new(crate::std::units::Yd),
Box::new(crate::std::polar::Polar),
Box::new(crate::std::assert::Assert),
Box::new(crate::std::assert::AssertEqual),

View File

@ -8,7 +8,7 @@ use serde::{Deserialize, Serialize};
use crate::{
errors::KclError,
execution::{ExecState, KclValue},
std::args::Args,
std::args::{Args, TyF64},
};
/// Data for polar coordinates.
@ -19,7 +19,7 @@ pub struct PolarCoordsData {
/// The angle of the line (in degrees).
pub angle: f64,
/// The length of the line.
pub length: f64,
pub length: TyF64,
}
/// Convert from polar/sphere coordinates to cartesian coordinates.
@ -27,7 +27,7 @@ pub async fn polar(_exec_state: &mut ExecState, args: Args) -> Result<KclValue,
let data: PolarCoordsData = args.get_data()?;
let result = inner_polar(&data)?;
args.make_user_val_from_f64_array(result.to_vec(), &crate::execution::types::NumericType::Unknown)
args.make_user_val_from_f64_array(result.to_vec(), &data.length.ty)
}
/// Convert polar/sphere (azimuth, elevation, distance) coordinates to
@ -49,7 +49,7 @@ pub async fn polar(_exec_state: &mut ExecState, args: Args) -> Result<KclValue,
}]
fn inner_polar(data: &PolarCoordsData) -> Result<[f64; 2], KclError> {
let angle = data.angle.to_radians();
let x = data.length * angle.cos();
let y = data.length * angle.sin();
let x = data.length.n * angle.cos();
let y = data.length.n * angle.sin();
Ok([x, y])
}

View File

@ -10,257 +10,251 @@ use crate::{
};
/// Millimeters conversion factor for current projects units.
pub async fn from_mm(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let input = args.get_number()?;
let result = inner_from_mm(input, exec_state)?;
pub async fn mm(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let result = inner_mm(exec_state)?;
Ok(args.make_user_val_from_f64(result))
}
/// Converts a number from mm to the current default unit.
/// Millimeters conversion factor for current projects units.
///
/// 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 project uses, this function will always return the conversion
/// factor to millimeters.
///
/// For example, if the current project uses inches, `fromMm(1)` will return `1/25.4`.
/// If the current project uses millimeters, `fromMm(1)` will return `1`.
/// For example, if the current project uses inches, this function will return `(1/25.4)`.
/// If the current project uses millimeters, this function will return `1`.
///
/// **Caution**: This function is only intended to be used when you absolutely MUST
/// have different units in your code than the project settings. Otherwise, it is
/// a bad pattern to use this function.
///
/// We merely provide these functions for convenience and readability, as
/// `fromMm(10)` is more readable that your intent is "I want 10 millimeters" than
/// `10 * mm()` is more readable that your intent is "I want 10 millimeters" than
/// `10 * (1/25.4)`, if the project settings are in inches.
///
/// ```no_run
/// totalWidth = fromMm(10)
/// totalWidth = 10 * mm()
/// ```
#[stdlib {
name = "fromMm",
name = "mm",
tags = ["units"],
}]
fn inner_from_mm(input: f64, exec_state: &ExecState) -> Result<f64, KclError> {
Ok(match exec_state.length_unit() {
UnitLen::Mm => input,
UnitLen::Inches => measurements::Length::from_millimeters(input).as_inches(),
UnitLen::Feet => measurements::Length::from_millimeters(input).as_feet(),
UnitLen::M => measurements::Length::from_millimeters(input).as_meters(),
UnitLen::Cm => measurements::Length::from_millimeters(input).as_centimeters(),
UnitLen::Yards => measurements::Length::from_millimeters(input).as_yards(),
})
fn inner_mm(exec_state: &ExecState) -> Result<f64, KclError> {
match exec_state.length_unit() {
UnitLen::Mm => Ok(1.0),
UnitLen::Inches => Ok(measurements::Length::from_millimeters(1.0).as_inches()),
UnitLen::Feet => Ok(measurements::Length::from_millimeters(1.0).as_feet()),
UnitLen::M => Ok(measurements::Length::from_millimeters(1.0).as_meters()),
UnitLen::Cm => Ok(measurements::Length::from_millimeters(1.0).as_centimeters()),
UnitLen::Yards => Ok(measurements::Length::from_millimeters(1.0).as_yards()),
}
}
/// Inches conversion factor for current projects units.
pub async fn from_inches(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let input = args.get_number()?;
let result = inner_from_inches(input, exec_state)?;
pub async fn inch(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let result = inner_inch(exec_state)?;
Ok(args.make_user_val_from_f64(result))
}
/// Converts a number from inches to the current default unit.
/// Inches conversion factor for current projects units.
///
/// 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 project uses, this function will always return the conversion
/// factor to inches.
///
/// For example, if the current project uses inches, `fromInches(1)` will return `1`.
/// If the current project uses millimeters, `fromInches(1)` will return `25.4`.
/// For example, if the current project uses inches, this function will return `1`.
/// If the current project uses millimeters, this function will return `25.4`.
///
/// **Caution**: This function is only intended to be used when you absolutely MUST
/// have different units in your code than the project settings. Otherwise, it is
/// a bad pattern to use this function.
///
/// We merely provide these functions for convenience and readability, as
/// `fromInches(10)` is more readable that your intent is "I want 10 inches" than
/// `10 * inch()` is more readable that your intent is "I want 10 inches" than
/// `10 * 25.4`, if the project settings are in millimeters.
///
/// ```no_run
/// totalWidth = fromInches(10)
/// totalWidth = 10 * inch()
/// ```
#[stdlib {
name = "fromInches",
name = "inch",
tags = ["units"],
}]
fn inner_from_inches(input: f64, exec_state: &ExecState) -> Result<f64, KclError> {
fn inner_inch(exec_state: &ExecState) -> Result<f64, KclError> {
match exec_state.length_unit() {
UnitLen::Mm => Ok(measurements::Length::from_inches(input).as_millimeters()),
UnitLen::Inches => Ok(input),
UnitLen::Feet => Ok(measurements::Length::from_inches(input).as_feet()),
UnitLen::M => Ok(measurements::Length::from_inches(input).as_meters()),
UnitLen::Cm => Ok(measurements::Length::from_inches(input).as_centimeters()),
UnitLen::Yards => Ok(measurements::Length::from_inches(input).as_yards()),
UnitLen::Mm => Ok(measurements::Length::from_inches(1.0).as_millimeters()),
UnitLen::Inches => Ok(1.0),
UnitLen::Feet => Ok(measurements::Length::from_inches(1.0).as_feet()),
UnitLen::M => Ok(measurements::Length::from_inches(1.0).as_meters()),
UnitLen::Cm => Ok(measurements::Length::from_inches(1.0).as_centimeters()),
UnitLen::Yards => Ok(measurements::Length::from_inches(1.0).as_yards()),
}
}
/// Feet conversion factor for current projects units.
pub async fn from_ft(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let input = args.get_number()?;
let result = inner_from_ft(input, exec_state)?;
pub async fn ft(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let result = inner_ft(exec_state)?;
Ok(args.make_user_val_from_f64(result))
}
/// Converts a number from feet to the current default unit.
/// Feet conversion factor for current projects units.
///
/// 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 project uses, this function will always return the conversion
/// factor to feet.
///
/// For example, if the current project uses inches, `fromFt(1)` will return `12`.
/// If the current project uses millimeters, `fromFt(1)` will return `304.8`.
/// If the current project uses feet, `fromFt(1)` will return `1`.
/// For example, if the current project uses inches, this function will return `12`.
/// If the current project uses millimeters, this function will return `304.8`.
/// If the current project uses feet, this function will return `1`.
///
/// **Caution**: This function is only intended to be used when you absolutely MUST
/// have different units in your code than the project settings. Otherwise, it is
/// a bad pattern to use this function.
///
/// We merely provide these functions for convenience and readability, as
/// `fromFt(10)` is more readable that your intent is "I want 10 feet" than
/// `10 * ft()` is more readable that your intent is "I want 10 feet" than
/// `10 * 304.8`, if the project settings are in millimeters.
///
/// ```no_run
/// totalWidth = fromFt(10)
/// totalWidth = 10 * ft()
/// ```
#[stdlib {
name = "fromFt",
name = "ft",
tags = ["units"],
}]
fn inner_from_ft(input: f64, exec_state: &ExecState) -> Result<f64, KclError> {
fn inner_ft(exec_state: &ExecState) -> Result<f64, KclError> {
match exec_state.length_unit() {
UnitLen::Mm => Ok(measurements::Length::from_feet(input).as_millimeters()),
UnitLen::Inches => Ok(measurements::Length::from_feet(input).as_inches()),
UnitLen::Feet => Ok(input),
UnitLen::M => Ok(measurements::Length::from_feet(input).as_meters()),
UnitLen::Cm => Ok(measurements::Length::from_feet(input).as_centimeters()),
UnitLen::Yards => Ok(measurements::Length::from_feet(input).as_yards()),
UnitLen::Mm => Ok(measurements::Length::from_feet(1.0).as_millimeters()),
UnitLen::Inches => Ok(measurements::Length::from_feet(1.0).as_inches()),
UnitLen::Feet => Ok(1.0),
UnitLen::M => Ok(measurements::Length::from_feet(1.0).as_meters()),
UnitLen::Cm => Ok(measurements::Length::from_feet(1.0).as_centimeters()),
UnitLen::Yards => Ok(measurements::Length::from_feet(1.0).as_yards()),
}
}
/// Meters conversion factor for current projects units.
pub async fn from_m(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let input = args.get_number()?;
let result = inner_from_m(input, exec_state)?;
pub async fn m(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let result = inner_m(exec_state)?;
Ok(args.make_user_val_from_f64(result))
}
/// Converts a number from meters to the current default unit.
/// Meters conversion factor for current projects units.
///
/// 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 project uses, this function will always return the conversion
/// factor to meters.
///
/// For example, if the current project uses inches, `fromM` will return `39.3701`.
/// If the current project uses millimeters, `fromM` will return `1000`.
/// If the current project uses meters, `fromM` will return `1`.
/// For example, if the current project uses inches, this function will return `39.3701`.
/// If the current project uses millimeters, this function will return `1000`.
/// If the current project uses meters, this function will return `1`.
///
/// **Caution**: This function is only intended to be used when you absolutely MUST
/// have different units in your code than the project settings. Otherwise, it is
/// a bad pattern to use this function.
///
/// We merely provide these functions for convenience and readability, as
/// `fromM(10)` is more readable that your intent is "I want 10 meters" than
/// `10 * m()` is more readable that your intent is "I want 10 meters" than
/// `10 * 1000`, if the project settings are in millimeters.
///
/// ```no_run
/// totalWidth = 10 * fromM(10)
/// totalWidth = 10 * m()
/// ```
#[stdlib {
name = "fromM",
name = "m",
tags = ["units"],
}]
fn inner_from_m(input: f64, exec_state: &ExecState) -> Result<f64, KclError> {
fn inner_m(exec_state: &ExecState) -> Result<f64, KclError> {
match exec_state.length_unit() {
UnitLen::Mm => Ok(measurements::Length::from_meters(input).as_millimeters()),
UnitLen::Inches => Ok(measurements::Length::from_meters(input).as_inches()),
UnitLen::Feet => Ok(measurements::Length::from_meters(input).as_feet()),
UnitLen::M => Ok(input),
UnitLen::Cm => Ok(measurements::Length::from_meters(input).as_centimeters()),
UnitLen::Yards => Ok(measurements::Length::from_meters(input).as_yards()),
UnitLen::Mm => Ok(measurements::Length::from_meters(1.0).as_millimeters()),
UnitLen::Inches => Ok(measurements::Length::from_meters(1.0).as_inches()),
UnitLen::Feet => Ok(measurements::Length::from_meters(1.0).as_feet()),
UnitLen::M => Ok(1.0),
UnitLen::Cm => Ok(measurements::Length::from_meters(1.0).as_centimeters()),
UnitLen::Yards => Ok(measurements::Length::from_meters(1.0).as_yards()),
}
}
/// Centimeters conversion factor for current projects units.
pub async fn from_cm(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let input = args.get_number()?;
let result = inner_from_cm(input, exec_state)?;
pub async fn cm(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let result = inner_cm(exec_state)?;
Ok(args.make_user_val_from_f64(result))
}
/// Converts a number from centimeters to the current default unit.
/// Centimeters conversion factor for current projects units.
///
/// 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 project uses, this function will always return the conversion
/// factor to centimeters.
///
/// For example, if the current project uses inches, `fromCm` will return `0.393701`.
/// If the current project uses millimeters, `fromCm` will return `10`.
/// If the current project uses centimeters, `fromCm` will return `1`.
/// For example, if the current project uses inches, this function will return `0.393701`.
/// If the current project uses millimeters, this function will return `10`.
/// If the current project uses centimeters, this function will return `1`.
///
/// **Caution**: This function is only intended to be used when you absolutely MUST
/// have different units in your code than the project settings. Otherwise, it is
/// a bad pattern to use this function.
///
/// We merely provide these functions for convenience and readability, as
/// `fromCm(10)` is more readable that your intent is "I want 10 centimeters" than
/// `10 * cm()` is more readable that your intent is "I want 10 centimeters" than
/// `10 * 10`, if the project settings are in millimeters.
///
/// ```no_run
/// totalWidth = fromCm(10)
/// totalWidth = 10 * cm()
/// ```
#[stdlib {
name = "fromCm",
name = "cm",
tags = ["units"],
}]
fn inner_from_cm(input: f64, exec_state: &ExecState) -> Result<f64, KclError> {
fn inner_cm(exec_state: &ExecState) -> Result<f64, KclError> {
match exec_state.length_unit() {
UnitLen::Mm => Ok(measurements::Length::from_centimeters(input).as_millimeters()),
UnitLen::Inches => Ok(measurements::Length::from_centimeters(input).as_inches()),
UnitLen::Feet => Ok(measurements::Length::from_centimeters(input).as_feet()),
UnitLen::M => Ok(measurements::Length::from_centimeters(input).as_meters()),
UnitLen::Cm => Ok(input),
UnitLen::Yards => Ok(measurements::Length::from_centimeters(input).as_yards()),
UnitLen::Mm => Ok(measurements::Length::from_centimeters(1.0).as_millimeters()),
UnitLen::Inches => Ok(measurements::Length::from_centimeters(1.0).as_inches()),
UnitLen::Feet => Ok(measurements::Length::from_centimeters(1.0).as_feet()),
UnitLen::M => Ok(measurements::Length::from_centimeters(1.0).as_meters()),
UnitLen::Cm => Ok(1.0),
UnitLen::Yards => Ok(measurements::Length::from_centimeters(1.0).as_yards()),
}
}
/// Yards conversion factor for current projects units.
pub async fn from_yd(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let input = args.get_number()?;
let result = inner_from_yd(input, exec_state)?;
pub async fn yd(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let result = inner_yd(exec_state)?;
Ok(args.make_user_val_from_f64(result))
}
/// Converts a number from yards to the current default unit.
/// Yards conversion factor for current projects units.
///
/// 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 project uses, this function will always return the conversion
/// factor to yards.
///
/// For example, if the current project uses inches, `fromYd` will return `36`.
/// If the current project uses millimeters, `fromYd` will return `914.4`.
/// If the current project uses yards, `fromYd` will return `1`.
/// For example, if the current project uses inches, this function will return `36`.
/// If the current project uses millimeters, this function will return `914.4`.
/// If the current project uses yards, this function will return `1`.
///
/// **Caution**: This function is only intended to be used when you absolutely MUST
/// have different units in your code than the project settings. Otherwise, it is
/// a bad pattern to use this function.
///
/// We merely provide these functions for convenience and readability, as
/// `fromYd(10)` is more readable that your intent is "I want 10 yards" than
/// `10 * yd()` is more readable that your intent is "I want 10 yards" than
/// `10 * 914.4`, if the project settings are in millimeters.
///
/// ```no_run
/// totalWidth = fromYd(10)
/// totalWidth = 10 * yd()
/// ```
#[stdlib {
name = "fromYd",
name = "yd",
tags = ["units"],
}]
fn inner_from_yd(input: f64, exec_state: &ExecState) -> Result<f64, KclError> {
fn inner_yd(exec_state: &ExecState) -> Result<f64, KclError> {
match exec_state.length_unit() {
UnitLen::Mm => Ok(measurements::Length::from_yards(input).as_millimeters()),
UnitLen::Inches => Ok(measurements::Length::from_yards(input).as_inches()),
UnitLen::Feet => Ok(measurements::Length::from_yards(input).as_feet()),
UnitLen::M => Ok(measurements::Length::from_yards(input).as_meters()),
UnitLen::Cm => Ok(measurements::Length::from_yards(input).as_centimeters()),
UnitLen::Yards => Ok(input),
UnitLen::Mm => Ok(measurements::Length::from_yards(1.0).as_millimeters()),
UnitLen::Inches => Ok(measurements::Length::from_yards(1.0).as_inches()),
UnitLen::Feet => Ok(measurements::Length::from_yards(1.0).as_feet()),
UnitLen::M => Ok(measurements::Length::from_yards(1.0).as_meters()),
UnitLen::Cm => Ok(measurements::Length::from_yards(1.0).as_centimeters()),
UnitLen::Yards => Ok(1.0),
}
}

View File

@ -6,8 +6,10 @@ use std::{
use anyhow::Result;
use crate::{
parsing::ast::types::{ImportPath, NodeRef, Program},
modules::ModuleRepr,
parsing::ast::types::{ImportPath, Node as AstNode, NodeRef, Program},
walk::{Node, Visitable},
ExecState, ExecutorContext, ModuleId,
};
/// Specific dependency between two modules. The 0th element of this tuple
@ -23,7 +25,7 @@ type Graph = Vec<Dependency>;
/// run concurrently. Each "stage" is blocking in this model, which will
/// change in the future. Don't use this function widely, yet.
#[allow(clippy::iter_over_hash_type)]
pub fn import_graph(progs: HashMap<String, NodeRef<'_, Program>>) -> Result<Vec<Vec<String>>> {
pub fn import_graph(progs: &HashMap<String, AstNode<Program>>) -> Result<Vec<Vec<String>>> {
let mut graph = Graph::new();
for (name, program) in progs.iter() {
@ -41,6 +43,9 @@ pub fn import_graph(progs: HashMap<String, NodeRef<'_, Program>>) -> Result<Vec<
#[allow(clippy::iter_over_hash_type)]
fn topsort(all_modules: &[&str], graph: Graph) -> Result<Vec<Vec<String>>> {
if all_modules.is_empty() {
return Ok(vec![]);
}
let mut dep_map = HashMap::<String, Vec<String>>::new();
for (dependent, dependency) in graph.iter() {
@ -57,6 +62,7 @@ fn topsort(all_modules: &[&str], graph: Graph) -> Result<Vec<Vec<String>>> {
let mut order = vec![];
loop {
println!("waiting_modules: {:?}", waiting_modules);
// Each pass through we need to find any modules which have nothing
// "pointing at it" -- so-called reverse dependencies. This is an entry
// that is either not in the dep_map OR an empty list.
@ -101,7 +107,7 @@ fn topsort(all_modules: &[&str], graph: Graph) -> Result<Vec<Vec<String>>> {
Ok(order)
}
pub(crate) fn import_dependencies(prog: NodeRef<'_, Program>) -> Result<Vec<String>> {
pub(crate) fn import_dependencies(prog: NodeRef<Program>) -> Result<Vec<String>> {
let ret = Arc::new(Mutex::new(vec![]));
fn walk(ret: Arc<Mutex<Vec<String>>>, node: Node<'_>) {
@ -125,6 +131,51 @@ pub(crate) fn import_dependencies(prog: NodeRef<'_, Program>) -> Result<Vec<Stri
Ok(ret)
}
pub(crate) async fn import_universe<'prog>(
ctx: &ExecutorContext,
prog: NodeRef<'prog, Program>,
out: &mut HashMap<String, AstNode<Program>>,
out_id_map: &mut HashMap<String, ModuleId>,
exec_state: &mut ExecState,
) -> Result<()> {
let modules = import_dependencies(prog)?;
for module in modules {
eprintln!("{:?}", module);
if out.contains_key(&module) {
continue;
}
let module_id = ctx
.open_module(
&ImportPath::Kcl {
filename: module.to_string(),
},
&[],
exec_state,
Default::default(),
)
.await?;
out_id_map.insert(module.clone(), module_id);
let program = {
let Some(module_info) = exec_state.get_module(module_id) else {
// We should never get here we just fucking added it.
anyhow::bail!("Module {} not found", module);
};
let ModuleRepr::Kcl(program, _) = &module_info.repr else {
anyhow::bail!("Module {} is not a KCL program", module);
};
program.clone()
};
out.insert(module.clone(), program.clone());
Box::pin(import_universe(ctx, &program, out, out_id_map, exec_state)).await?;
}
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
@ -140,16 +191,16 @@ mod tests {
let mut modules = HashMap::new();
let a = kcl!("");
modules.insert("a.kcl".to_owned(), &a);
modules.insert("a.kcl".to_owned(), a);
let b = kcl!(
"
import \"a.kcl\"
"
);
modules.insert("b.kcl".to_owned(), &b);
modules.insert("b.kcl".to_owned(), b);
let order = import_graph(modules).unwrap();
let order = import_graph(&modules).unwrap();
assert_eq!(vec![vec!["a.kcl".to_owned()], vec!["b.kcl".to_owned()]], order);
}
@ -162,16 +213,16 @@ import \"a.kcl\"
y = 2
"
);
modules.insert("a.kcl".to_owned(), &a);
modules.insert("a.kcl".to_owned(), a);
let b = kcl!(
"
x = 1
"
);
modules.insert("b.kcl".to_owned(), &b);
modules.insert("b.kcl".to_owned(), b);
let order = import_graph(modules).unwrap();
let order = import_graph(&modules).unwrap();
assert_eq!(vec![vec!["a.kcl".to_owned(), "b.kcl".to_owned()]], order);
}
@ -180,23 +231,23 @@ x = 1
let mut modules = HashMap::new();
let a = kcl!("");
modules.insert("a.kcl".to_owned(), &a);
modules.insert("a.kcl".to_owned(), a);
let b = kcl!(
"
import \"a.kcl\"
"
);
modules.insert("b.kcl".to_owned(), &b);
modules.insert("b.kcl".to_owned(), b);
let c = kcl!(
"
import \"a.kcl\"
"
);
modules.insert("c.kcl".to_owned(), &c);
modules.insert("c.kcl".to_owned(), c);
let order = import_graph(modules).unwrap();
let order = import_graph(&modules).unwrap();
assert_eq!(
vec![vec!["a.kcl".to_owned()], vec!["b.kcl".to_owned(), "c.kcl".to_owned()]],
order
@ -212,15 +263,15 @@ import \"a.kcl\"
import \"b.kcl\"
"
);
modules.insert("a.kcl".to_owned(), &a);
modules.insert("a.kcl".to_owned(), a);
let b = kcl!(
"
import \"a.kcl\"
"
);
modules.insert("b.kcl".to_owned(), &b);
modules.insert("b.kcl".to_owned(), b);
import_graph(modules).unwrap_err();
import_graph(&modules).unwrap_err();
}
}

View File

@ -8,3 +8,5 @@ mod import_graph;
pub use ast_node::Node;
pub use ast_visitor::Visitable;
pub use ast_walk::walk;
pub use import_graph::import_graph;
pub(crate) use import_graph::import_universe;

View File

@ -1,5 +1,4 @@
@no_std
@settings(defaultLengthUnit = mm)
/// Construct a 2-dimensional circle, of the specified radius, centered at
/// the provided (x, y) origin point.

View File

@ -42,24 +42,21 @@ description: Variables in memory after executing double_map_fn.kcl
"type": "Number",
"value": 2.0,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
{
"type": "Number",
"value": 3.0,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
{
"type": "Number",
"value": 4.0,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
}
]

View File

@ -307,13 +307,7 @@ description: Variables in memory after executing fillet-and-shell.kcl
"type": "Number",
"value": 73.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
},
"caseThickness": {
@ -333,13 +327,7 @@ description: Variables in memory after executing fillet-and-shell.kcl
"type": "Number",
"value": 38.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
},
"connectorPadding": {
@ -379,13 +367,7 @@ description: Variables in memory after executing fillet-and-shell.kcl
"type": "Number",
"value": 58.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
},
"m25Screw": {

View File

@ -51,8 +51,7 @@ description: Operations executed flush_batch_on_end.kcl
"type": "Number",
"value": 1.5,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
"sourceRange": []

View File

@ -128,16 +128,14 @@ description: Variables in memory after executing flush_batch_on_end.kcl
"type": "Number",
"value": 1.5,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
"outerDiameter": {
"type": "Number",
"value": 0.5469,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
"outerProfile": {

View File

@ -10,8 +10,7 @@ description: Operations executed ball-bearing.kcl
"type": "Number",
"value": -0.1565,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
"sourceRange": []
@ -667,8 +666,7 @@ description: Operations executed ball-bearing.kcl
"type": "Number",
"value": 36.0,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
"sourceRange": []
@ -902,8 +900,7 @@ description: Operations executed ball-bearing.kcl
"type": "Number",
"value": -0.1565,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
"sourceRange": []

View File

@ -3425,16 +3425,14 @@ description: Variables in memory after executing ball-bearing.kcl
"type": "Number",
"value": 0.0313,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
"chainWidth": {
"type": "Number",
"value": 0.125,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
"insideWall": {
@ -3633,8 +3631,7 @@ description: Variables in memory after executing ball-bearing.kcl
"type": "Number",
"value": 0.0625,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
"linkRevolve": {

View File

@ -58,8 +58,7 @@ description: Operations executed bench.kcl
"type": "Number",
"value": 2.0,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
"sourceRange": []
@ -118,8 +117,7 @@ description: Operations executed bench.kcl
"type": "Number",
"value": -2.0,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
"sourceRange": []
@ -236,8 +234,7 @@ description: Operations executed bench.kcl
"type": "Number",
"value": 28.0,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
"sourceRange": []
@ -309,8 +306,7 @@ description: Operations executed bench.kcl
"type": "Number",
"value": 2.0,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
"sourceRange": []
@ -369,8 +365,7 @@ description: Operations executed bench.kcl
"type": "Number",
"value": -2.0,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
"sourceRange": []
@ -487,8 +482,7 @@ description: Operations executed bench.kcl
"type": "Number",
"value": 28.0,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
"sourceRange": []
@ -560,8 +554,7 @@ description: Operations executed bench.kcl
"type": "Number",
"value": 2.0,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
"sourceRange": []
@ -620,8 +613,7 @@ description: Operations executed bench.kcl
"type": "Number",
"value": -2.0,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
"sourceRange": []
@ -738,8 +730,7 @@ description: Operations executed bench.kcl
"type": "Number",
"value": -28.0,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
"sourceRange": []
@ -911,8 +902,7 @@ description: Operations executed bench.kcl
"type": "Number",
"value": -30.0,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
"sourceRange": []
@ -1036,8 +1026,7 @@ description: Operations executed bench.kcl
"type": "Number",
"value": -30.0,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
"sourceRange": []
@ -1170,8 +1159,7 @@ description: Operations executed bench.kcl
"type": "Number",
"value": 28.0,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
"sourceRange": []
@ -1334,8 +1322,7 @@ description: Operations executed bench.kcl
"type": "Number",
"value": -28.0,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
"sourceRange": []

View File

@ -40,13 +40,7 @@ description: Variables in memory after executing bracket.kcl
"type": "Number",
"value": 3600.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
},
"mountingHoleDiameter": {

View File

@ -8440,7 +8440,7 @@ description: Artifact commands car-wheel-assembly.kcl
"type": "move_path_pen",
"path": "[uuid]",
"to": {
"x": 0.4724409448818898,
"x": 0.47244094488188976,
"y": 0.0,
"z": 0.0
}
@ -8512,7 +8512,7 @@ description: Artifact commands car-wheel-assembly.kcl
"path": "[uuid]",
"segment": {
"type": "tangential_arc",
"radius": 0.11811023622047245,
"radius": 0.11811023622047244,
"offset": {
"unit": "degrees",
"value": 90.0

View File

@ -79,85 +79,85 @@ flowchart LR
158[Solid2d]
end
subgraph path167 [Path]
167["Path<br>[1241, 1302, 5]"]
168["Segment<br>[1241, 1302, 5]"]
167["Path<br>[1241, 1301, 5]"]
168["Segment<br>[1241, 1301, 5]"]
169[Solid2d]
end
subgraph path179 [Path]
179["Path<br>[1660, 1706, 5]"]
180["Segment<br>[1712, 1764, 5]"]
181["Segment<br>[1770, 1875, 5]"]
182["Segment<br>[1881, 1903, 5]"]
183["Segment<br>[1909, 1965, 5]"]
184["Segment<br>[1971, 1978, 5]"]
179["Path<br>[1659, 1705, 5]"]
180["Segment<br>[1711, 1763, 5]"]
181["Segment<br>[1769, 1874, 5]"]
182["Segment<br>[1880, 1902, 5]"]
183["Segment<br>[1908, 1964, 5]"]
184["Segment<br>[1970, 1977, 5]"]
185[Solid2d]
end
subgraph path195 [Path]
195["Path<br>[2110, 2156, 5]"]
196["Segment<br>[2162, 2214, 5]"]
197["Segment<br>[2220, 2327, 5]"]
198["Segment<br>[2333, 2370, 5]"]
199["Segment<br>[2376, 2432, 5]"]
200["Segment<br>[2438, 2445, 5]"]
195["Path<br>[2109, 2155, 5]"]
196["Segment<br>[2161, 2213, 5]"]
197["Segment<br>[2219, 2326, 5]"]
198["Segment<br>[2332, 2369, 5]"]
199["Segment<br>[2375, 2431, 5]"]
200["Segment<br>[2437, 2444, 5]"]
201[Solid2d]
end
subgraph path212 [Path]
212["Path<br>[2954, 3001, 5]"]
213["Segment<br>[3009, 3349, 5]"]
214["Segment<br>[3357, 3389, 5]"]
215["Segment<br>[3397, 3741, 5]"]
216["Segment<br>[3749, 3805, 5]"]
217["Segment<br>[3813, 3820, 5]"]
212["Path<br>[2953, 3000, 5]"]
213["Segment<br>[3008, 3348, 5]"]
214["Segment<br>[3356, 3388, 5]"]
215["Segment<br>[3396, 3740, 5]"]
216["Segment<br>[3748, 3804, 5]"]
217["Segment<br>[3812, 3819, 5]"]
218[Solid2d]
end
subgraph path235 [Path]
235["Path<br>[2954, 3001, 5]"]
236["Segment<br>[3009, 3349, 5]"]
237["Segment<br>[3357, 3389, 5]"]
238["Segment<br>[3397, 3741, 5]"]
239["Segment<br>[3749, 3805, 5]"]
240["Segment<br>[3813, 3820, 5]"]
235["Path<br>[2953, 3000, 5]"]
236["Segment<br>[3008, 3348, 5]"]
237["Segment<br>[3356, 3388, 5]"]
238["Segment<br>[3396, 3740, 5]"]
239["Segment<br>[3748, 3804, 5]"]
240["Segment<br>[3812, 3819, 5]"]
241[Solid2d]
end
subgraph path258 [Path]
258["Path<br>[4348, 4443, 5]"]
259["Segment<br>[4449, 4482, 5]"]
260["Segment<br>[4488, 4539, 5]"]
261["Segment<br>[4545, 4578, 5]"]
262["Segment<br>[4584, 4634, 5]"]
263["Segment<br>[4640, 4681, 5]"]
264["Segment<br>[4687, 4736, 5]"]
265["Segment<br>[4742, 4775, 5]"]
266["Segment<br>[4781, 4815, 5]"]
267["Segment<br>[4821, 4855, 5]"]
268["Segment<br>[4861, 4913, 5]"]
269["Segment<br>[4919, 4953, 5]"]
270["Segment<br>[4959, 5035, 5]"]
271["Segment<br>[5041, 5074, 5]"]
272["Segment<br>[5080, 5156, 5]"]
273["Segment<br>[5162, 5196, 5]"]
274["Segment<br>[5202, 5276, 5]"]
275["Segment<br>[5282, 5316, 5]"]
276["Segment<br>[5322, 5373, 5]"]
277["Segment<br>[5379, 5441, 5]"]
278["Segment<br>[5447, 5498, 5]"]
279["Segment<br>[5504, 5538, 5]"]
280["Segment<br>[5544, 5577, 5]"]
281["Segment<br>[5583, 5616, 5]"]
282["Segment<br>[5622, 5629, 5]"]
258["Path<br>[4347, 4442, 5]"]
259["Segment<br>[4448, 4481, 5]"]
260["Segment<br>[4487, 4538, 5]"]
261["Segment<br>[4544, 4577, 5]"]
262["Segment<br>[4583, 4633, 5]"]
263["Segment<br>[4639, 4680, 5]"]
264["Segment<br>[4686, 4735, 5]"]
265["Segment<br>[4741, 4774, 5]"]
266["Segment<br>[4780, 4814, 5]"]
267["Segment<br>[4820, 4854, 5]"]
268["Segment<br>[4860, 4912, 5]"]
269["Segment<br>[4918, 4952, 5]"]
270["Segment<br>[4958, 5034, 5]"]
271["Segment<br>[5040, 5073, 5]"]
272["Segment<br>[5079, 5155, 5]"]
273["Segment<br>[5161, 5195, 5]"]
274["Segment<br>[5201, 5275, 5]"]
275["Segment<br>[5281, 5315, 5]"]
276["Segment<br>[5321, 5372, 5]"]
277["Segment<br>[5378, 5440, 5]"]
278["Segment<br>[5446, 5497, 5]"]
279["Segment<br>[5503, 5537, 5]"]
280["Segment<br>[5543, 5576, 5]"]
281["Segment<br>[5582, 5615, 5]"]
282["Segment<br>[5621, 5628, 5]"]
283[Solid2d]
end
subgraph path334 [Path]
334["Path<br>[745, 785, 8]"]
335["Segment<br>[793, 855, 8]"]
336["Segment<br>[863, 899, 8]"]
337["Segment<br>[907, 937, 8]"]
338["Segment<br>[945, 998, 8]"]
339["Segment<br>[1006, 1046, 8]"]
340["Segment<br>[1054, 1089, 8]"]
341["Segment<br>[1097, 1135, 8]"]
342["Segment<br>[1143, 1165, 8]"]
343["Segment<br>[1173, 1180, 8]"]
334["Path<br>[744, 784, 8]"]
335["Segment<br>[792, 854, 8]"]
336["Segment<br>[862, 898, 8]"]
337["Segment<br>[906, 936, 8]"]
338["Segment<br>[944, 996, 8]"]
339["Segment<br>[1004, 1044, 8]"]
340["Segment<br>[1052, 1087, 8]"]
341["Segment<br>[1095, 1133, 8]"]
342["Segment<br>[1141, 1163, 8]"]
343["Segment<br>[1171, 1178, 8]"]
344[Solid2d]
end
subgraph path365 [Path]
@ -315,16 +315,16 @@ flowchart LR
164["Sweep Extrusion<br>[1110, 1144, 5]"]
165["Sweep Extrusion<br>[1110, 1144, 5]"]
166["Sweep Extrusion<br>[1110, 1144, 5]"]
170["Sweep Extrusion<br>[1449, 1483, 5]"]
170["Sweep Extrusion<br>[1448, 1482, 5]"]
171[Wall]
172["SweepEdge Opposite"]
173["SweepEdge Adjacent"]
174["Sweep Extrusion<br>[1449, 1483, 5]"]
175["Sweep Extrusion<br>[1449, 1483, 5]"]
176["Sweep Extrusion<br>[1449, 1483, 5]"]
177["Sweep Extrusion<br>[1449, 1483, 5]"]
178["Plane<br>[1637, 1654, 5]"]
186["Sweep Revolve<br>[1984, 2001, 5]"]
174["Sweep Extrusion<br>[1448, 1482, 5]"]
175["Sweep Extrusion<br>[1448, 1482, 5]"]
176["Sweep Extrusion<br>[1448, 1482, 5]"]
177["Sweep Extrusion<br>[1448, 1482, 5]"]
178["Plane<br>[1636, 1653, 5]"]
186["Sweep Revolve<br>[1983, 2000, 5]"]
187[Wall]
188[Wall]
189[Wall]
@ -332,8 +332,8 @@ flowchart LR
191["SweepEdge Adjacent"]
192["SweepEdge Adjacent"]
193["SweepEdge Adjacent"]
194["Plane<br>[2087, 2104, 5]"]
202["Sweep Revolve<br>[2451, 2468, 5]"]
194["Plane<br>[2086, 2103, 5]"]
202["Sweep Revolve<br>[2450, 2467, 5]"]
203[Wall]
204[Wall]
205[Wall]
@ -342,8 +342,8 @@ flowchart LR
208["SweepEdge Adjacent"]
209["SweepEdge Adjacent"]
210["SweepEdge Adjacent"]
211["Plane<br>[2923, 2946, 5]"]
219["Sweep Extrusion<br>[3868, 3914, 5]"]
211["Plane<br>[2922, 2945, 5]"]
219["Sweep Extrusion<br>[3867, 3913, 5]"]
220[Wall]
221[Wall]
222[Wall]
@ -358,8 +358,8 @@ flowchart LR
231["SweepEdge Adjacent"]
232["SweepEdge Opposite"]
233["SweepEdge Adjacent"]
234["Plane<br>[2923, 2946, 5]"]
242["Sweep Extrusion<br>[3868, 3914, 5]"]
234["Plane<br>[2922, 2945, 5]"]
242["Sweep Extrusion<br>[3867, 3913, 5]"]
243[Wall]
244[Wall]
245[Wall]
@ -374,8 +374,8 @@ flowchart LR
254["SweepEdge Adjacent"]
255["SweepEdge Opposite"]
256["SweepEdge Adjacent"]
257["Plane<br>[4325, 4342, 5]"]
284["Sweep Revolve<br>[5635, 5652, 5]"]
257["Plane<br>[4324, 4341, 5]"]
284["Sweep Revolve<br>[5634, 5651, 5]"]
285[Wall]
286[Wall]
287[Wall]
@ -424,8 +424,8 @@ flowchart LR
330["SweepEdge Adjacent"]
331["SweepEdge Adjacent"]
332["SweepEdge Adjacent"]
333["Plane<br>[711, 737, 8]"]
345["Sweep Revolve<br>[1188, 1205, 8]"]
333["Plane<br>[710, 736, 8]"]
345["Sweep Revolve<br>[1186, 1203, 8]"]
346[Wall]
347[Wall]
348[Wall]

View File

@ -231,13 +231,7 @@ description: Operations executed car-wheel-assembly.kcl
"type": "Number",
"value": 0.5,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
},
"sourceRange": []
@ -428,13 +422,7 @@ description: Operations executed car-wheel-assembly.kcl
"type": "Number",
"value": 0.5,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
},
"sourceRange": []
@ -579,8 +567,7 @@ description: Operations executed car-wheel-assembly.kcl
"type": "Number",
"value": -0.125,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
"sourceRange": []
@ -659,8 +646,7 @@ description: Operations executed car-wheel-assembly.kcl
"type": "Number",
"value": -0.125,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
"sourceRange": []
@ -768,8 +754,7 @@ description: Operations executed car-wheel-assembly.kcl
"type": "Number",
"value": 0.475,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
"sourceRange": []
@ -845,8 +830,7 @@ description: Operations executed car-wheel-assembly.kcl
"type": "Number",
"value": 0.95,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
"sourceRange": []
@ -896,8 +880,7 @@ description: Operations executed car-wheel-assembly.kcl
"type": "Number",
"value": -0.95,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
"sourceRange": []
@ -976,8 +959,7 @@ description: Operations executed car-wheel-assembly.kcl
"type": "Number",
"value": -0.475,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
"sourceRange": []
@ -1233,8 +1215,8 @@ description: Operations executed car-wheel-assembly.kcl
"type": "FunctionCall",
"name": "spoke",
"functionSourceRange": [
2621,
4194,
2620,
4193,
5
],
"unlabeledArg": null,
@ -1284,8 +1266,7 @@ description: Operations executed car-wheel-assembly.kcl
"type": "Number",
"value": 0.1,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
}
]
@ -1624,8 +1605,8 @@ description: Operations executed car-wheel-assembly.kcl
"type": "FunctionCall",
"name": "spoke",
"functionSourceRange": [
2621,
4194,
2620,
4193,
5
],
"unlabeledArg": null,
@ -1675,8 +1656,7 @@ description: Operations executed car-wheel-assembly.kcl
"type": "Number",
"value": -0.1,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
}
]
@ -2128,8 +2108,8 @@ description: Operations executed car-wheel-assembly.kcl
"type": "FunctionCall",
"name": "lug",
"functionSourceRange": [
669,
1295,
668,
1293,
8
],
"unlabeledArg": null,

View File

@ -302,13 +302,7 @@ description: Variables in memory after executing car-wheel-assembly.kcl
"type": "Number",
"value": 0.5,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
},
"spacerPatternDiameter": {

View File

@ -10,8 +10,7 @@ description: Operations executed color-cube.kcl
"type": "Number",
"value": 50.0,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
"sourceRange": []
@ -35,8 +34,7 @@ description: Operations executed color-cube.kcl
"type": "Number",
"value": -50.0,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
"sourceRange": []
@ -60,8 +58,7 @@ description: Operations executed color-cube.kcl
"type": "Number",
"value": -50.0,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
"sourceRange": []
@ -85,8 +82,7 @@ description: Operations executed color-cube.kcl
"type": "Number",
"value": -50.0,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
"sourceRange": []
@ -110,8 +106,7 @@ description: Operations executed color-cube.kcl
"type": "Number",
"value": 49.0,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
"sourceRange": []
@ -135,8 +130,7 @@ description: Operations executed color-cube.kcl
"type": "Number",
"value": -50.0,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
"sourceRange": []

View File

@ -82,8 +82,7 @@ description: Variables in memory after executing color-cube.kcl
"type": "Number",
"value": 50.0,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
"metalConstant": {

View File

@ -201,8 +201,7 @@ description: Operations executed cycloidal-gear.kcl
"type": "Number",
"value": 0.75,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
"sourceRange": []

View File

@ -316,13 +316,7 @@ description: Operations executed dodecahedron.kcl
"type": "Number",
"value": 5.0,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
},
"sourceRange": []
@ -348,13 +342,7 @@ description: Operations executed dodecahedron.kcl
"type": "Number",
"value": 5.0,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
},
"sourceRange": []

View File

@ -1947,13 +1947,7 @@ description: Variables in memory after executing dodecahedron.kcl
"type": "Number",
"value": 5.0,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
}
}

View File

@ -1000,8 +1000,7 @@ description: Operations executed dual-basin-utility-sink.kcl
"type": "Number",
"value": 564.5,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
"sourceRange": []
@ -1011,13 +1010,7 @@ description: Operations executed dual-basin-utility-sink.kcl
"type": "Number",
"value": 6.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
},
"sourceRange": []

View File

@ -59,16 +59,14 @@ description: Variables in memory after executing dual-basin-utility-sink.kcl
"type": "Number",
"value": 564.5,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
"blockWidth": {
"type": "Number",
"value": 1129.0,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
"doorBody": {
@ -1117,13 +1115,7 @@ description: Variables in memory after executing dual-basin-utility-sink.kcl
"type": "Number",
"value": 6.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
},
"doorGap": {
@ -1213,8 +1205,7 @@ description: Variables in memory after executing dual-basin-utility-sink.kcl
"type": "Number",
"value": 547.5,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
"floorPlane": {
@ -1945,21 +1936,14 @@ description: Variables in memory after executing dual-basin-utility-sink.kcl
"type": "Number",
"value": 80.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
},
"handleOffset": {
"type": "Number",
"value": 228.75,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
"handlePlane": {
@ -5122,8 +5106,7 @@ description: Variables in memory after executing dual-basin-utility-sink.kcl
"type": "Number",
"value": 1116.0,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
"lowerBeltLengthY": {
@ -5557,13 +5540,7 @@ description: Variables in memory after executing dual-basin-utility-sink.kcl
"type": "Number",
"value": 7.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
},
"panelSpacing": {
@ -5583,13 +5560,7 @@ description: Variables in memory after executing dual-basin-utility-sink.kcl
"type": "Number",
"value": 370.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
},
"pillarBody": {
@ -8767,13 +8738,7 @@ description: Variables in memory after executing dual-basin-utility-sink.kcl
"type": "Number",
"value": 1700.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
},
"sinkWidth": {

View File

@ -57,13 +57,7 @@ description: Operations executed enclosure.kcl
"type": "Number",
"value": 12.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
},
"sourceRange": []
@ -1400,13 +1394,7 @@ description: Operations executed enclosure.kcl
"type": "Number",
"value": 12.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
},
"sourceRange": []
@ -1616,13 +1604,7 @@ description: Operations executed enclosure.kcl
"type": "Number",
"value": 9.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
},
"sourceRange": []

View File

@ -70,13 +70,7 @@ description: Operations executed exhaust-manifold.kcl
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
},
{
@ -377,13 +371,7 @@ description: Operations executed exhaust-manifold.kcl
"type": "Number",
"value": 2.0,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
},
{
@ -684,13 +672,7 @@ description: Operations executed exhaust-manifold.kcl
"type": "Number",
"value": 4.0,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
},
{
@ -991,13 +973,7 @@ description: Operations executed exhaust-manifold.kcl
"type": "Number",
"value": 6.0,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
},
{

View File

@ -47,8 +47,7 @@ description: Operations executed focusrite-scarlett-mounting-bracket.kcl
"type": "Number",
"value": 44.0,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
"z": {
@ -220,13 +219,7 @@ description: Operations executed focusrite-scarlett-mounting-bracket.kcl
"type": "Number",
"value": 88.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
},
"sourceRange": []
@ -563,8 +556,7 @@ description: Operations executed focusrite-scarlett-mounting-bracket.kcl
"type": "Number",
"value": 2.5,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
"sourceRange": []
@ -653,8 +645,7 @@ description: Operations executed focusrite-scarlett-mounting-bracket.kcl
"type": "Number",
"value": 54.666666666666664,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
"sourceRange": []
@ -951,8 +942,7 @@ description: Operations executed focusrite-scarlett-mounting-bracket.kcl
"type": "Number",
"value": 2.5,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
"sourceRange": []
@ -1041,8 +1031,7 @@ description: Operations executed focusrite-scarlett-mounting-bracket.kcl
"type": "Number",
"value": 54.666666666666664,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
"sourceRange": []
@ -1093,8 +1082,7 @@ description: Operations executed focusrite-scarlett-mounting-bracket.kcl
"type": "Number",
"value": -52.0,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
"y": {
@ -1317,8 +1305,7 @@ description: Operations executed focusrite-scarlett-mounting-bracket.kcl
"type": "Number",
"value": -52.0,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
"y": {

View File

@ -471,8 +471,7 @@ description: Variables in memory after executing focusrite-scarlett-mounting-bra
"type": "Number",
"value": 44.0,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
"z": {
@ -1402,8 +1401,7 @@ description: Variables in memory after executing focusrite-scarlett-mounting-bra
"type": "Number",
"value": -52.0,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
"y": {

View File

@ -345,8 +345,7 @@ description: Operations executed food-service-spatula.kcl
"type": "Number",
"value": -7.5,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
"sourceRange": []

View File

@ -1334,8 +1334,7 @@ description: Operations executed french-press.kcl
"type": "Number",
"value": 0.325,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
"sourceRange": []

File diff suppressed because it is too large Load Diff

View File

@ -73,13 +73,7 @@ description: Operations executed gridfinity-baseplate-magnets.kcl
"type": "Number",
"value": 34.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
},
"sourceRange": []
@ -171,16 +165,14 @@ description: Operations executed gridfinity-baseplate-magnets.kcl
"type": "Number",
"value": 21.0,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
{
"type": "Number",
"value": 21.0,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
{
@ -480,16 +472,14 @@ description: Operations executed gridfinity-baseplate-magnets.kcl
"type": "Number",
"value": 21.0,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
{
"type": "Number",
"value": 21.0,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
{

View File

@ -73,13 +73,7 @@ description: Operations executed gridfinity-baseplate.kcl
"type": "Number",
"value": 34.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
},
"sourceRange": []
@ -171,16 +165,14 @@ description: Operations executed gridfinity-baseplate.kcl
"type": "Number",
"value": 21.0,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
{
"type": "Number",
"value": 21.0,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
{
@ -480,16 +472,14 @@ description: Operations executed gridfinity-baseplate.kcl
"type": "Number",
"value": 21.0,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
{
"type": "Number",
"value": 21.0,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
{

View File

@ -73,13 +73,7 @@ description: Operations executed gridfinity-bins-stacking-lip.kcl
"type": "Number",
"value": 34.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
},
"sourceRange": []
@ -171,16 +165,14 @@ description: Operations executed gridfinity-bins-stacking-lip.kcl
"type": "Number",
"value": 21.0,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
{
"type": "Number",
"value": 21.0,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
{
@ -480,16 +472,14 @@ description: Operations executed gridfinity-bins-stacking-lip.kcl
"type": "Number",
"value": 21.0,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
{
"type": "Number",
"value": 21.0,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
{
@ -782,13 +772,7 @@ description: Operations executed gridfinity-bins-stacking-lip.kcl
"type": "Number",
"value": 42.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
},
"sourceRange": []
@ -900,13 +884,7 @@ description: Operations executed gridfinity-bins-stacking-lip.kcl
"type": "Number",
"value": 42.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
},
"sourceRange": []
@ -1042,13 +1020,7 @@ description: Operations executed gridfinity-bins-stacking-lip.kcl
"type": "Number",
"value": 42.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
},
"sourceRange": []
@ -1160,13 +1132,7 @@ description: Operations executed gridfinity-bins-stacking-lip.kcl
"type": "Number",
"value": 42.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
},
"sourceRange": []
@ -1302,13 +1268,7 @@ description: Operations executed gridfinity-bins-stacking-lip.kcl
"type": "Number",
"value": 42.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
},
"sourceRange": []
@ -1397,13 +1357,7 @@ description: Operations executed gridfinity-bins-stacking-lip.kcl
"type": "Number",
"value": 42.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
},
"sourceRange": []
@ -1501,13 +1455,7 @@ description: Operations executed gridfinity-bins-stacking-lip.kcl
"type": "Number",
"value": 7.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
},
"sourceRange": []
@ -1683,13 +1631,7 @@ description: Operations executed gridfinity-bins-stacking-lip.kcl
"type": "Number",
"value": 11.75,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
}
]
@ -1848,13 +1790,7 @@ description: Operations executed gridfinity-bins-stacking-lip.kcl
"type": "Number",
"value": 76.5,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
},
"sourceRange": []
@ -1930,13 +1866,7 @@ description: Operations executed gridfinity-bins-stacking-lip.kcl
"type": "Number",
"value": 11.75,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
}
]
@ -2095,13 +2025,7 @@ description: Operations executed gridfinity-bins-stacking-lip.kcl
"type": "Number",
"value": 118.5,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
},
"sourceRange": []
@ -2193,26 +2117,14 @@ description: Operations executed gridfinity-bins-stacking-lip.kcl
"type": "Number",
"value": 42.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
},
{
"type": "Number",
"value": 63.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
},
{
@ -2342,26 +2254,14 @@ description: Operations executed gridfinity-bins-stacking-lip.kcl
"type": "Number",
"value": 42.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
},
{
"type": "Number",
"value": 63.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
},
{
@ -2475,13 +2375,7 @@ description: Operations executed gridfinity-bins-stacking-lip.kcl
"type": "Number",
"value": 11.75,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
}
]
@ -2771,13 +2665,7 @@ description: Operations executed gridfinity-bins-stacking-lip.kcl
"type": "Number",
"value": 80.25,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
},
{
@ -2797,13 +2685,7 @@ description: Operations executed gridfinity-bins-stacking-lip.kcl
"type": "Number",
"value": 11.75,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
}
]
@ -3135,26 +3017,14 @@ description: Operations executed gridfinity-bins-stacking-lip.kcl
"type": "Number",
"value": 42.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
},
{
"type": "Number",
"value": 63.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
},
{
@ -3284,26 +3154,14 @@ description: Operations executed gridfinity-bins-stacking-lip.kcl
"type": "Number",
"value": 42.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
},
{
"type": "Number",
"value": 63.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
},
{

View File

@ -19603,13 +19603,7 @@ description: Variables in memory after executing gridfinity-bins-stacking-lip.kc
"type": "Number",
"value": 11.75,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
}
]
@ -19789,13 +19783,7 @@ description: Variables in memory after executing gridfinity-bins-stacking-lip.kc
"type": "Number",
"value": 11.75,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
}
]
@ -19949,13 +19937,7 @@ description: Variables in memory after executing gridfinity-bins-stacking-lip.kc
"type": "Number",
"value": 80.25,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
},
{
@ -19975,13 +19957,7 @@ description: Variables in memory after executing gridfinity-bins-stacking-lip.kc
"type": "Number",
"value": 11.75,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
}
]

View File

@ -73,13 +73,7 @@ description: Operations executed gridfinity-bins.kcl
"type": "Number",
"value": 34.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
},
"sourceRange": []
@ -171,16 +165,14 @@ description: Operations executed gridfinity-bins.kcl
"type": "Number",
"value": 21.0,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
{
"type": "Number",
"value": 21.0,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
{
@ -480,16 +472,14 @@ description: Operations executed gridfinity-bins.kcl
"type": "Number",
"value": 21.0,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
{
"type": "Number",
"value": 21.0,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
{
@ -782,13 +772,7 @@ description: Operations executed gridfinity-bins.kcl
"type": "Number",
"value": 42.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
},
"sourceRange": []
@ -900,13 +884,7 @@ description: Operations executed gridfinity-bins.kcl
"type": "Number",
"value": 42.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
},
"sourceRange": []
@ -1042,13 +1020,7 @@ description: Operations executed gridfinity-bins.kcl
"type": "Number",
"value": 42.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
},
"sourceRange": []
@ -1160,13 +1132,7 @@ description: Operations executed gridfinity-bins.kcl
"type": "Number",
"value": 42.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
},
"sourceRange": []
@ -1302,13 +1268,7 @@ description: Operations executed gridfinity-bins.kcl
"type": "Number",
"value": 42.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
},
"sourceRange": []
@ -1397,13 +1357,7 @@ description: Operations executed gridfinity-bins.kcl
"type": "Number",
"value": 42.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
},
"sourceRange": []
@ -1501,13 +1455,7 @@ description: Operations executed gridfinity-bins.kcl
"type": "Number",
"value": 14.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
},
"sourceRange": []

View File

@ -267,7 +267,7 @@ description: Artifact commands i-beam.kcl
"command": {
"type": "extrude",
"target": "[uuid]",
"distance": 72.0,
"distance": 72.00000000000001,
"faces": null
}
},

View File

@ -1,15 +1,15 @@
```mermaid
flowchart LR
subgraph path2 [Path]
2["Path<br>[463, 501, 0]"]
3["Segment<br>[507, 538, 0]"]
4["Segment<br>[544, 576, 0]"]
5["Segment<br>[582, 632, 0]"]
6["Segment<br>[638, 692, 0]"]
7["Segment<br>[698, 720, 0]"]
2["Path<br>[462, 500, 0]"]
3["Segment<br>[506, 537, 0]"]
4["Segment<br>[543, 575, 0]"]
5["Segment<br>[581, 631, 0]"]
6["Segment<br>[637, 691, 0]"]
7["Segment<br>[697, 719, 0]"]
end
1["Plane<br>[439, 457, 0]"]
8["Sweep Extrusion<br>[774, 802, 0]"]
1["Plane<br>[438, 456, 0]"]
8["Sweep Extrusion<br>[773, 801, 0]"]
1 --- 2
2 --- 3
2 --- 4

View File

@ -18,9 +18,10 @@ description: Result of parsing i-beam.kcl
"type": "Identifier"
},
"init": {
"arguments": [
{
"commentStart": 203,
"commentStart": 196,
"end": 0,
"left": {
"commentStart": 196,
"end": 0,
"raw": "6",
"start": 0,
@ -30,16 +31,18 @@ description: Result of parsing i-beam.kcl
"value": 6.0,
"suffix": "None"
}
}
],
},
"operator": "*",
"right": {
"arguments": [],
"callee": {
"abs_path": false,
"commentStart": 196,
"commentStart": 200,
"end": 0,
"name": {
"commentStart": 196,
"commentStart": 200,
"end": 0,
"name": "fromFt",
"name": "ft",
"start": 0,
"type": "Identifier"
},
@ -47,13 +50,17 @@ description: Result of parsing i-beam.kcl
"start": 0,
"type": "Name"
},
"commentStart": 196,
"commentStart": 200,
"end": 0,
"start": 0,
"type": "CallExpression",
"type": "CallExpression"
},
"start": 0,
"type": "BinaryExpression",
"type": "BinaryExpression"
},
"start": 0,
"type": "VariableDeclarator"
},
"end": 0,
@ -66,19 +73,19 @@ description: Result of parsing i-beam.kcl
"type": "VariableDeclaration"
},
{
"commentStart": 206,
"commentStart": 205,
"declaration": {
"commentStart": 206,
"commentStart": 205,
"end": 0,
"id": {
"commentStart": 206,
"commentStart": 205,
"end": 0,
"name": "beamHeight",
"start": 0,
"type": "Identifier"
},
"init": {
"commentStart": 219,
"commentStart": 218,
"end": 0,
"raw": "4",
"start": 0,
@ -99,19 +106,19 @@ description: Result of parsing i-beam.kcl
"type": "VariableDeclaration"
},
{
"commentStart": 221,
"commentStart": 220,
"declaration": {
"commentStart": 221,
"commentStart": 220,
"end": 0,
"id": {
"commentStart": 221,
"commentStart": 220,
"end": 0,
"name": "flangeWidth",
"start": 0,
"type": "Identifier"
},
"init": {
"commentStart": 235,
"commentStart": 234,
"end": 0,
"raw": "2.663",
"start": 0,
@ -132,19 +139,19 @@ description: Result of parsing i-beam.kcl
"type": "VariableDeclaration"
},
{
"commentStart": 241,
"commentStart": 240,
"declaration": {
"commentStart": 241,
"commentStart": 240,
"end": 0,
"id": {
"commentStart": 241,
"commentStart": 240,
"end": 0,
"name": "flangeThickness",
"start": 0,
"type": "Identifier"
},
"init": {
"commentStart": 259,
"commentStart": 258,
"end": 0,
"raw": "0.293",
"start": 0,
@ -165,19 +172,19 @@ description: Result of parsing i-beam.kcl
"type": "VariableDeclaration"
},
{
"commentStart": 265,
"commentStart": 264,
"declaration": {
"commentStart": 265,
"commentStart": 264,
"end": 0,
"id": {
"commentStart": 265,
"commentStart": 264,
"end": 0,
"name": "webThickness",
"start": 0,
"type": "Identifier"
},
"init": {
"commentStart": 280,
"commentStart": 279,
"end": 0,
"raw": "0.193",
"start": 0,
@ -198,19 +205,19 @@ description: Result of parsing i-beam.kcl
"type": "VariableDeclaration"
},
{
"commentStart": 286,
"commentStart": 285,
"declaration": {
"commentStart": 286,
"commentStart": 285,
"end": 0,
"id": {
"commentStart": 286,
"commentStart": 285,
"end": 0,
"name": "rootRadius",
"start": 0,
"type": "Identifier"
},
"init": {
"commentStart": 299,
"commentStart": 298,
"end": 0,
"raw": "0.457",
"start": 0,
@ -231,12 +238,12 @@ description: Result of parsing i-beam.kcl
"type": "VariableDeclaration"
},
{
"commentStart": 304,
"commentStart": 303,
"declaration": {
"commentStart": 431,
"commentStart": 430,
"end": 0,
"id": {
"commentStart": 431,
"commentStart": 430,
"end": 0,
"name": "iBeam",
"start": 0,
@ -249,10 +256,10 @@ description: Result of parsing i-beam.kcl
{
"argument": {
"abs_path": false,
"commentStart": 454,
"commentStart": 453,
"end": 0,
"name": {
"commentStart": 454,
"commentStart": 453,
"end": 0,
"name": "XZ",
"start": 0,
@ -263,7 +270,7 @@ description: Result of parsing i-beam.kcl
"type": "Name",
"type": "Name"
},
"commentStart": 453,
"commentStart": 452,
"end": 0,
"operator": "-",
"start": 0,
@ -273,10 +280,10 @@ description: Result of parsing i-beam.kcl
],
"callee": {
"abs_path": false,
"commentStart": 439,
"commentStart": 438,
"end": 0,
"name": {
"commentStart": 439,
"commentStart": 438,
"end": 0,
"name": "startSketchOn",
"start": 0,
@ -286,7 +293,7 @@ description: Result of parsing i-beam.kcl
"start": 0,
"type": "Name"
},
"commentStart": 439,
"commentStart": 438,
"end": 0,
"start": 0,
"type": "CallExpression",
@ -295,10 +302,10 @@ description: Result of parsing i-beam.kcl
{
"arguments": [
{
"commentStart": 478,
"commentStart": 477,
"elements": [
{
"commentStart": 479,
"commentStart": 478,
"end": 0,
"raw": "0",
"start": 0,
@ -310,14 +317,14 @@ description: Result of parsing i-beam.kcl
}
},
{
"commentStart": 482,
"commentStart": 481,
"end": 0,
"left": {
"abs_path": false,
"commentStart": 482,
"commentStart": 481,
"end": 0,
"name": {
"commentStart": 482,
"commentStart": 481,
"end": 0,
"name": "beamHeight",
"start": 0,
@ -330,7 +337,7 @@ description: Result of parsing i-beam.kcl
},
"operator": "/",
"right": {
"commentStart": 495,
"commentStart": 494,
"end": 0,
"raw": "2",
"start": 0,
@ -352,7 +359,7 @@ description: Result of parsing i-beam.kcl
"type": "ArrayExpression"
},
{
"commentStart": 499,
"commentStart": 498,
"end": 0,
"start": 0,
"type": "PipeSubstitution",
@ -361,10 +368,10 @@ description: Result of parsing i-beam.kcl
],
"callee": {
"abs_path": false,
"commentStart": 463,
"commentStart": 462,
"end": 0,
"name": {
"commentStart": 463,
"commentStart": 462,
"end": 0,
"name": "startProfileAt",
"start": 0,
@ -374,7 +381,7 @@ description: Result of parsing i-beam.kcl
"start": 0,
"type": "Name"
},
"commentStart": 463,
"commentStart": 462,
"end": 0,
"start": 0,
"type": "CallExpression",
@ -385,21 +392,21 @@ description: Result of parsing i-beam.kcl
{
"type": "LabeledArg",
"label": {
"commentStart": 513,
"commentStart": 512,
"end": 0,
"name": "length",
"start": 0,
"type": "Identifier"
},
"arg": {
"commentStart": 522,
"commentStart": 521,
"end": 0,
"left": {
"abs_path": false,
"commentStart": 522,
"commentStart": 521,
"end": 0,
"name": {
"commentStart": 522,
"commentStart": 521,
"end": 0,
"name": "flangeWidth",
"start": 0,
@ -412,7 +419,7 @@ description: Result of parsing i-beam.kcl
},
"operator": "/",
"right": {
"commentStart": 536,
"commentStart": 535,
"end": 0,
"raw": "2",
"start": 0,
@ -431,10 +438,10 @@ description: Result of parsing i-beam.kcl
],
"callee": {
"abs_path": false,
"commentStart": 507,
"commentStart": 506,
"end": 0,
"name": {
"commentStart": 507,
"commentStart": 506,
"end": 0,
"name": "xLine",
"start": 0,
@ -444,7 +451,7 @@ description: Result of parsing i-beam.kcl
"start": 0,
"type": "Name"
},
"commentStart": 507,
"commentStart": 506,
"end": 0,
"start": 0,
"type": "CallExpressionKw",
@ -456,7 +463,7 @@ description: Result of parsing i-beam.kcl
{
"type": "LabeledArg",
"label": {
"commentStart": 550,
"commentStart": 549,
"end": 0,
"name": "length",
"start": 0,
@ -465,10 +472,10 @@ description: Result of parsing i-beam.kcl
"arg": {
"argument": {
"abs_path": false,
"commentStart": 560,
"commentStart": 559,
"end": 0,
"name": {
"commentStart": 560,
"commentStart": 559,
"end": 0,
"name": "flangeThickness",
"start": 0,
@ -479,7 +486,7 @@ description: Result of parsing i-beam.kcl
"type": "Name",
"type": "Name"
},
"commentStart": 559,
"commentStart": 558,
"end": 0,
"operator": "-",
"start": 0,
@ -490,10 +497,10 @@ description: Result of parsing i-beam.kcl
],
"callee": {
"abs_path": false,
"commentStart": 544,
"commentStart": 543,
"end": 0,
"name": {
"commentStart": 544,
"commentStart": 543,
"end": 0,
"name": "yLine",
"start": 0,
@ -503,7 +510,7 @@ description: Result of parsing i-beam.kcl
"start": 0,
"type": "Name"
},
"commentStart": 544,
"commentStart": 543,
"end": 0,
"start": 0,
"type": "CallExpressionKw",
@ -515,24 +522,24 @@ description: Result of parsing i-beam.kcl
{
"type": "LabeledArg",
"label": {
"commentStart": 588,
"commentStart": 587,
"end": 0,
"name": "endAbsolute",
"start": 0,
"type": "Identifier"
},
"arg": {
"commentStart": 602,
"commentStart": 601,
"end": 0,
"left": {
"commentStart": 602,
"commentStart": 601,
"end": 0,
"left": {
"abs_path": false,
"commentStart": 602,
"commentStart": 601,
"end": 0,
"name": {
"commentStart": 602,
"commentStart": 601,
"end": 0,
"name": "webThickness",
"start": 0,
@ -545,7 +552,7 @@ description: Result of parsing i-beam.kcl
},
"operator": "/",
"right": {
"commentStart": 617,
"commentStart": 616,
"end": 0,
"raw": "2",
"start": 0,
@ -563,10 +570,10 @@ description: Result of parsing i-beam.kcl
"operator": "+",
"right": {
"abs_path": false,
"commentStart": 621,
"commentStart": 620,
"end": 0,
"name": {
"commentStart": 621,
"commentStart": 620,
"end": 0,
"name": "rootRadius",
"start": 0,
@ -585,10 +592,10 @@ description: Result of parsing i-beam.kcl
],
"callee": {
"abs_path": false,
"commentStart": 582,
"commentStart": 581,
"end": 0,
"name": {
"commentStart": 582,
"commentStart": 581,
"end": 0,
"name": "xLine",
"start": 0,
@ -598,7 +605,7 @@ description: Result of parsing i-beam.kcl
"start": 0,
"type": "Name"
},
"commentStart": 582,
"commentStart": 581,
"end": 0,
"start": 0,
"type": "CallExpressionKw",
@ -608,14 +615,14 @@ description: Result of parsing i-beam.kcl
{
"arguments": [
{
"commentStart": 652,
"commentStart": 651,
"end": 0,
"properties": [
{
"commentStart": 654,
"commentStart": 653,
"end": 0,
"key": {
"commentStart": 654,
"commentStart": 653,
"end": 0,
"name": "radius",
"start": 0,
@ -625,10 +632,10 @@ description: Result of parsing i-beam.kcl
"type": "ObjectProperty",
"value": {
"abs_path": false,
"commentStart": 663,
"commentStart": 662,
"end": 0,
"name": {
"commentStart": 663,
"commentStart": 662,
"end": 0,
"name": "rootRadius",
"start": 0,
@ -641,10 +648,10 @@ description: Result of parsing i-beam.kcl
}
},
{
"commentStart": 675,
"commentStart": 674,
"end": 0,
"key": {
"commentStart": 675,
"commentStart": 674,
"end": 0,
"name": "offset",
"start": 0,
@ -653,7 +660,7 @@ description: Result of parsing i-beam.kcl
"start": 0,
"type": "ObjectProperty",
"value": {
"commentStart": 684,
"commentStart": 683,
"end": 0,
"raw": "90",
"start": 0,
@ -671,7 +678,7 @@ description: Result of parsing i-beam.kcl
"type": "ObjectExpression"
},
{
"commentStart": 690,
"commentStart": 689,
"end": 0,
"start": 0,
"type": "PipeSubstitution",
@ -680,10 +687,10 @@ description: Result of parsing i-beam.kcl
],
"callee": {
"abs_path": false,
"commentStart": 638,
"commentStart": 637,
"end": 0,
"name": {
"commentStart": 638,
"commentStart": 637,
"end": 0,
"name": "tangentialArc",
"start": 0,
@ -693,7 +700,7 @@ description: Result of parsing i-beam.kcl
"start": 0,
"type": "Name"
},
"commentStart": 638,
"commentStart": 637,
"end": 0,
"start": 0,
"type": "CallExpression",
@ -704,14 +711,14 @@ description: Result of parsing i-beam.kcl
{
"type": "LabeledArg",
"label": {
"commentStart": 704,
"commentStart": 703,
"end": 0,
"name": "endAbsolute",
"start": 0,
"type": "Identifier"
},
"arg": {
"commentStart": 718,
"commentStart": 717,
"end": 0,
"raw": "0",
"start": 0,
@ -726,10 +733,10 @@ description: Result of parsing i-beam.kcl
],
"callee": {
"abs_path": false,
"commentStart": 698,
"commentStart": 697,
"end": 0,
"name": {
"commentStart": 698,
"commentStart": 697,
"end": 0,
"name": "yLine",
"start": 0,
@ -739,7 +746,7 @@ description: Result of parsing i-beam.kcl
"start": 0,
"type": "Name"
},
"commentStart": 698,
"commentStart": 697,
"end": 0,
"start": 0,
"type": "CallExpressionKw",
@ -751,7 +758,7 @@ description: Result of parsing i-beam.kcl
{
"type": "LabeledArg",
"label": {
"commentStart": 735,
"commentStart": 734,
"end": 0,
"name": "axis",
"start": 0,
@ -759,10 +766,10 @@ description: Result of parsing i-beam.kcl
},
"arg": {
"abs_path": false,
"commentStart": 742,
"commentStart": 741,
"end": 0,
"name": {
"commentStart": 742,
"commentStart": 741,
"end": 0,
"name": "X",
"start": 0,
@ -777,10 +784,10 @@ description: Result of parsing i-beam.kcl
],
"callee": {
"abs_path": false,
"commentStart": 726,
"commentStart": 725,
"end": 0,
"name": {
"commentStart": 726,
"commentStart": 725,
"end": 0,
"name": "mirror2d",
"start": 0,
@ -790,7 +797,7 @@ description: Result of parsing i-beam.kcl
"start": 0,
"type": "Name"
},
"commentStart": 726,
"commentStart": 725,
"end": 0,
"start": 0,
"type": "CallExpressionKw",
@ -802,7 +809,7 @@ description: Result of parsing i-beam.kcl
{
"type": "LabeledArg",
"label": {
"commentStart": 759,
"commentStart": 758,
"end": 0,
"name": "axis",
"start": 0,
@ -810,10 +817,10 @@ description: Result of parsing i-beam.kcl
},
"arg": {
"abs_path": false,
"commentStart": 766,
"commentStart": 765,
"end": 0,
"name": {
"commentStart": 766,
"commentStart": 765,
"end": 0,
"name": "Y",
"start": 0,
@ -828,10 +835,10 @@ description: Result of parsing i-beam.kcl
],
"callee": {
"abs_path": false,
"commentStart": 750,
"commentStart": 749,
"end": 0,
"name": {
"commentStart": 750,
"commentStart": 749,
"end": 0,
"name": "mirror2d",
"start": 0,
@ -841,7 +848,7 @@ description: Result of parsing i-beam.kcl
"start": 0,
"type": "Name"
},
"commentStart": 750,
"commentStart": 749,
"end": 0,
"start": 0,
"type": "CallExpressionKw",
@ -853,7 +860,7 @@ description: Result of parsing i-beam.kcl
{
"type": "LabeledArg",
"label": {
"commentStart": 782,
"commentStart": 781,
"end": 0,
"name": "length",
"start": 0,
@ -861,10 +868,10 @@ description: Result of parsing i-beam.kcl
},
"arg": {
"abs_path": false,
"commentStart": 791,
"commentStart": 790,
"end": 0,
"name": {
"commentStart": 791,
"commentStart": 790,
"end": 0,
"name": "beamLength",
"start": 0,
@ -879,10 +886,10 @@ description: Result of parsing i-beam.kcl
],
"callee": {
"abs_path": false,
"commentStart": 774,
"commentStart": 773,
"end": 0,
"name": {
"commentStart": 774,
"commentStart": 773,
"end": 0,
"name": "extrude",
"start": 0,
@ -892,7 +899,7 @@ description: Result of parsing i-beam.kcl
"start": 0,
"type": "Name"
},
"commentStart": 774,
"commentStart": 773,
"end": 0,
"start": 0,
"type": "CallExpressionKw",
@ -900,7 +907,7 @@ description: Result of parsing i-beam.kcl
"unlabeled": null
}
],
"commentStart": 439,
"commentStart": 438,
"end": 0,
"start": 0,
"type": "PipeExpression",

View File

@ -23,7 +23,7 @@ description: Operations executed i-beam.kcl
"length": {
"value": {
"type": "Number",
"value": 72.0,
"value": 72.00000000000001,
"ty": {
"type": "Unknown"
}

View File

@ -214,7 +214,7 @@ description: Variables in memory after executing i-beam.kcl
"type": "Inches"
}
},
"height": 72.0,
"height": 72.00000000000001,
"startCapId": "[uuid]",
"endCapId": "[uuid]",
"units": {

View File

@ -1897,78 +1897,42 @@ description: Variables in memory after executing keyboard.kcl
"type": "Number",
"value": 0.3,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
},
"row2": {
"type": "Number",
"value": 1.2,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
},
"row3": {
"type": "Number",
"value": 2.1,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
},
"row4": {
"type": "Number",
"value": 3.0,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
},
"row5": {
"type": "Number",
"value": 3.9,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
},
"row6": {
"type": "Number",
"value": 4.8,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
},
"seg01": {

View File

@ -3969,8 +3969,7 @@ description: Variables in memory after executing kitt.kcl
"type": "Number",
"value": 9.0,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
"kitBellyButtonWidth": {
@ -4029,13 +4028,7 @@ description: Variables in memory after executing kitt.kcl
"type": "Number",
"value": 24.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
},
"kitBody": {
@ -7167,13 +7160,7 @@ description: Variables in memory after executing kitt.kcl
"type": "Number",
"value": 20.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
},
"kitFloppy1": {
@ -9046,8 +9033,7 @@ description: Variables in memory after executing kitt.kcl
"type": "Number",
"value": 11.0,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
"kitFloppyWidth": {
@ -9539,13 +9525,7 @@ description: Variables in memory after executing kitt.kcl
"type": "Number",
"value": 24.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
},
"kitLeftEar": {

View File

@ -81,8 +81,7 @@ description: Operations executed lego.kcl
"type": "Number",
"value": -1.7000000000000002,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
"sourceRange": []

View File

@ -237,8 +237,7 @@ description: Variables in memory after executing lego.kcl
"type": "Number",
"value": 7.9333,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
"lbumps": {
@ -1932,8 +1931,7 @@ description: Variables in memory after executing lego.kcl
"type": "Number",
"value": 6.5,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
"shellExtrude": {
@ -2288,34 +2286,21 @@ description: Variables in memory after executing lego.kcl
"type": "Number",
"value": 1.5,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
"totalLength": {
"type": "Number",
"value": 23.8,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
},
"totalWidth": {
"type": "Number",
"value": 15.8,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
},
"tubePattern": {
@ -3219,8 +3204,7 @@ description: Variables in memory after executing lego.kcl
"type": "Number",
"value": 7.9,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
"wbumps": {

View File

@ -70,13 +70,7 @@ description: Operations executed makeup-mirror.kcl
"type": "Number",
"value": 24.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
},
"sourceRange": []
@ -120,13 +114,7 @@ description: Operations executed makeup-mirror.kcl
"type": "Number",
"value": 24.5,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
},
"sourceRange": []
@ -165,13 +153,7 @@ description: Operations executed makeup-mirror.kcl
"type": "Number",
"value": 24.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
},
"sourceRange": []
@ -215,13 +197,7 @@ description: Operations executed makeup-mirror.kcl
"type": "Number",
"value": 49.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
},
"sourceRange": []
@ -260,13 +236,7 @@ description: Operations executed makeup-mirror.kcl
"type": "Number",
"value": 24.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
},
"sourceRange": []
@ -310,13 +280,7 @@ description: Operations executed makeup-mirror.kcl
"type": "Number",
"value": 24.5,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
},
"sourceRange": []
@ -355,13 +319,7 @@ description: Operations executed makeup-mirror.kcl
"type": "Number",
"value": 24.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
},
"sourceRange": []
@ -405,13 +363,7 @@ description: Operations executed makeup-mirror.kcl
"type": "Number",
"value": 49.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
},
"sourceRange": []
@ -450,13 +402,7 @@ description: Operations executed makeup-mirror.kcl
"type": "Number",
"value": 24.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
},
"sourceRange": []
@ -500,13 +446,7 @@ description: Operations executed makeup-mirror.kcl
"type": "Number",
"value": 49.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
},
"sourceRange": []
@ -545,13 +485,7 @@ description: Operations executed makeup-mirror.kcl
"type": "Number",
"value": 24.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
},
"sourceRange": []
@ -595,13 +529,7 @@ description: Operations executed makeup-mirror.kcl
"type": "Number",
"value": 73.5,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
},
"sourceRange": []
@ -640,13 +568,7 @@ description: Operations executed makeup-mirror.kcl
"type": "Number",
"value": 24.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
},
"sourceRange": []
@ -820,8 +742,7 @@ description: Operations executed makeup-mirror.kcl
"type": "Number",
"value": 165.0,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
"sourceRange": []

View File

@ -7,8 +7,7 @@ description: Variables in memory after executing makeup-mirror.kcl
"type": "Number",
"value": 90.0,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
"archThickness": {
@ -298,13 +297,7 @@ description: Variables in memory after executing makeup-mirror.kcl
"type": "Number",
"value": 24.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
},
"hingePartA1": {
@ -1175,8 +1168,7 @@ description: Variables in memory after executing makeup-mirror.kcl
"type": "Number",
"value": 85.0,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
"mirrorThickness": {

View File

@ -1036,13 +1036,7 @@ description: Operations executed pipe-flange-assembly.kcl
"type": "Number",
"value": -1.563,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
},
"sourceRange": []
@ -1242,13 +1236,7 @@ description: Operations executed pipe-flange-assembly.kcl
"type": "Number",
"value": -0.46875,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
},
"sourceRange": []
@ -1512,8 +1500,7 @@ description: Operations executed pipe-flange-assembly.kcl
"type": "Number",
"value": 0.546875,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
"sourceRange": []
@ -1563,8 +1550,7 @@ description: Operations executed pipe-flange-assembly.kcl
"type": "Number",
"value": -0.546875,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
"sourceRange": []

View File

@ -49,16 +49,14 @@ description: Variables in memory after executing pipe-flange-assembly.kcl
"type": "Number",
"value": 0.5,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
"boltHexFlatLength": {
"type": "Number",
"value": 0.2887,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
"boltLength": {
@ -236,32 +234,28 @@ description: Variables in memory after executing pipe-flange-assembly.kcl
"type": "Number",
"value": 0.625,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
"hexNutFlatLength": {
"type": "Number",
"value": 0.5413,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
"hexNutFlatToFlat": {
"type": "Number",
"value": 0.9375,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
"hexNutThickness": {
"type": "Number",
"value": 0.5469,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
"mountingHoleDiameter": {

View File

@ -201,8 +201,7 @@ description: Operations executed poopy-shoe.kcl
"type": "Number",
"value": -1.4375,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
"z": {
@ -468,13 +467,7 @@ description: Operations executed poopy-shoe.kcl
"type": "Number",
"value": -3.875,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
},
"y": {
@ -769,13 +762,7 @@ description: Operations executed poopy-shoe.kcl
"type": "Number",
"value": 2.75,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
},
"sourceRange": []
@ -810,13 +797,7 @@ description: Operations executed poopy-shoe.kcl
"type": "Number",
"value": -3.875,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
},
"y": {

View File

@ -42,8 +42,7 @@ description: Variables in memory after executing poopy-shoe.kcl
"type": "Number",
"value": -1.4375,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
"z": {
@ -210,13 +209,7 @@ description: Variables in memory after executing poopy-shoe.kcl
"type": "Number",
"value": -3.875,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
},
"y": {
@ -396,13 +389,7 @@ description: Variables in memory after executing poopy-shoe.kcl
"type": "Number",
"value": -3.875,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
},
"y": {

View File

@ -1,59 +1,59 @@
```mermaid
flowchart LR
subgraph path2 [Path]
2["Path<br>[538, 581, 0]"]
3["Segment<br>[587, 640, 0]"]
4["Segment<br>[646, 748, 0]"]
5["Segment<br>[754, 807, 0]"]
6["Segment<br>[813, 860, 0]"]
7["Segment<br>[866, 961, 0]"]
8["Segment<br>[967, 1038, 0]"]
9["Segment<br>[1044, 1095, 0]"]
10["Segment<br>[1101, 1154, 0]"]
11["Segment<br>[1160, 1229, 0]"]
12["Segment<br>[1235, 1271, 0]"]
13["Segment<br>[1277, 1307, 0]"]
14["Segment<br>[1313, 1343, 0]"]
15["Segment<br>[1349, 1379, 0]"]
16["Segment<br>[1385, 1415, 0]"]
17["Segment<br>[1421, 1450, 0]"]
18["Segment<br>[1456, 1486, 0]"]
19["Segment<br>[1492, 1521, 0]"]
20["Segment<br>[1527, 1556, 0]"]
21["Segment<br>[1562, 1658, 0]"]
22["Segment<br>[1664, 1720, 0]"]
23["Segment<br>[1726, 1733, 0]"]
2["Path<br>[535, 578, 0]"]
3["Segment<br>[584, 637, 0]"]
4["Segment<br>[643, 745, 0]"]
5["Segment<br>[751, 804, 0]"]
6["Segment<br>[810, 857, 0]"]
7["Segment<br>[863, 958, 0]"]
8["Segment<br>[964, 1035, 0]"]
9["Segment<br>[1041, 1092, 0]"]
10["Segment<br>[1098, 1151, 0]"]
11["Segment<br>[1157, 1226, 0]"]
12["Segment<br>[1232, 1268, 0]"]
13["Segment<br>[1274, 1304, 0]"]
14["Segment<br>[1310, 1340, 0]"]
15["Segment<br>[1346, 1376, 0]"]
16["Segment<br>[1382, 1412, 0]"]
17["Segment<br>[1418, 1447, 0]"]
18["Segment<br>[1453, 1483, 0]"]
19["Segment<br>[1489, 1518, 0]"]
20["Segment<br>[1524, 1553, 0]"]
21["Segment<br>[1559, 1655, 0]"]
22["Segment<br>[1661, 1717, 0]"]
23["Segment<br>[1723, 1730, 0]"]
24[Solid2d]
end
subgraph path85 [Path]
85["Path<br>[1888, 1932, 0]"]
86["Segment<br>[1938, 2000, 0]"]
87["Segment<br>[2006, 2119, 0]"]
88["Segment<br>[2125, 2245, 0]"]
89["Segment<br>[2251, 2307, 0]"]
90["Segment<br>[2313, 2320, 0]"]
85["Path<br>[1885, 1929, 0]"]
86["Segment<br>[1935, 1997, 0]"]
87["Segment<br>[2003, 2116, 0]"]
88["Segment<br>[2122, 2242, 0]"]
89["Segment<br>[2248, 2304, 0]"]
90["Segment<br>[2310, 2317, 0]"]
91[Solid2d]
end
subgraph path107 [Path]
107["Path<br>[2476, 2521, 0]"]
108["Segment<br>[2527, 2587, 0]"]
109["Segment<br>[2593, 2706, 0]"]
110["Segment<br>[2712, 2832, 0]"]
111["Segment<br>[2838, 2894, 0]"]
112["Segment<br>[2900, 2907, 0]"]
107["Path<br>[2473, 2518, 0]"]
108["Segment<br>[2524, 2584, 0]"]
109["Segment<br>[2590, 2703, 0]"]
110["Segment<br>[2709, 2829, 0]"]
111["Segment<br>[2835, 2891, 0]"]
112["Segment<br>[2897, 2904, 0]"]
113[Solid2d]
end
subgraph path129 [Path]
129["Path<br>[3061, 3106, 0]"]
130["Segment<br>[3112, 3179, 0]"]
131["Segment<br>[3185, 3298, 0]"]
132["Segment<br>[3304, 3424, 0]"]
133["Segment<br>[3430, 3486, 0]"]
134["Segment<br>[3492, 3499, 0]"]
129["Path<br>[3058, 3103, 0]"]
130["Segment<br>[3109, 3176, 0]"]
131["Segment<br>[3182, 3295, 0]"]
132["Segment<br>[3301, 3421, 0]"]
133["Segment<br>[3427, 3483, 0]"]
134["Segment<br>[3489, 3496, 0]"]
135[Solid2d]
end
1["Plane<br>[515, 532, 0]"]
25["Sweep Extrusion<br>[1776, 1806, 0]"]
1["Plane<br>[512, 529, 0]"]
25["Sweep Extrusion<br>[1773, 1803, 0]"]
26[Wall]
27[Wall]
28[Wall]
@ -113,7 +113,7 @@ flowchart LR
82["SweepEdge Adjacent"]
83["SweepEdge Opposite"]
84["SweepEdge Adjacent"]
92["Sweep Extrusion<br>[2364, 2395, 0]"]
92["Sweep Extrusion<br>[2361, 2392, 0]"]
93[Wall]
94[Wall]
95[Wall]
@ -128,7 +128,7 @@ flowchart LR
104["SweepEdge Adjacent"]
105["SweepEdge Opposite"]
106["SweepEdge Adjacent"]
114["Sweep Extrusion<br>[2950, 2981, 0]"]
114["Sweep Extrusion<br>[2947, 2978, 0]"]
115[Wall]
116[Wall]
117[Wall]
@ -143,7 +143,7 @@ flowchart LR
126["SweepEdge Adjacent"]
127["SweepEdge Opposite"]
128["SweepEdge Adjacent"]
136["Sweep Extrusion<br>[3543, 3573, 0]"]
136["Sweep Extrusion<br>[3540, 3570, 0]"]
137[Wall]
138[Wall]
139[Wall]
@ -158,9 +158,9 @@ flowchart LR
148["SweepEdge Adjacent"]
149["SweepEdge Opposite"]
150["SweepEdge Adjacent"]
151["StartSketchOnFace<br>[1848, 1882, 0]"]
152["StartSketchOnFace<br>[2436, 2470, 0]"]
153["StartSketchOnFace<br>[3023, 3055, 0]"]
151["StartSketchOnFace<br>[1845, 1879, 0]"]
152["StartSketchOnFace<br>[2433, 2467, 0]"]
153["StartSketchOnFace<br>[3020, 3052, 0]"]
1 --- 2
2 --- 3
2 --- 4

View File

@ -1,42 +1,42 @@
```mermaid
flowchart LR
subgraph path2 [Path]
2["Path<br>[537, 580, 0]"]
3["Segment<br>[586, 625, 0]"]
4["Segment<br>[631, 729, 0]"]
5["Segment<br>[735, 811, 0]"]
6["Segment<br>[817, 886, 0]"]
7["Segment<br>[892, 932, 0]"]
8["Segment<br>[938, 974, 0]"]
9["Segment<br>[1014, 1044, 0]"]
10["Segment<br>[1050, 1079, 0]"]
11["Segment<br>[1085, 1114, 0]"]
12["Segment<br>[1120, 1149, 0]"]
13["Segment<br>[1155, 1255, 0]"]
14["Segment<br>[1261, 1317, 0]"]
15["Segment<br>[1323, 1330, 0]"]
2["Path<br>[534, 577, 0]"]
3["Segment<br>[583, 622, 0]"]
4["Segment<br>[628, 726, 0]"]
5["Segment<br>[732, 808, 0]"]
6["Segment<br>[814, 883, 0]"]
7["Segment<br>[889, 929, 0]"]
8["Segment<br>[935, 971, 0]"]
9["Segment<br>[1011, 1041, 0]"]
10["Segment<br>[1047, 1076, 0]"]
11["Segment<br>[1082, 1111, 0]"]
12["Segment<br>[1117, 1146, 0]"]
13["Segment<br>[1152, 1252, 0]"]
14["Segment<br>[1258, 1314, 0]"]
15["Segment<br>[1320, 1327, 0]"]
16[Solid2d]
end
subgraph path52 [Path]
52["Path<br>[1485, 1585, 0]"]
53["Segment<br>[1591, 1638, 0]"]
54["Segment<br>[1644, 1759, 0]"]
55["Segment<br>[1765, 1885, 0]"]
56["Segment<br>[1891, 1947, 0]"]
57["Segment<br>[1953, 1960, 0]"]
52["Path<br>[1482, 1582, 0]"]
53["Segment<br>[1588, 1635, 0]"]
54["Segment<br>[1641, 1756, 0]"]
55["Segment<br>[1762, 1882, 0]"]
56["Segment<br>[1888, 1944, 0]"]
57["Segment<br>[1950, 1957, 0]"]
58[Solid2d]
end
subgraph path74 [Path]
74["Path<br>[2117, 2216, 0]"]
75["Segment<br>[2222, 2268, 0]"]
76["Segment<br>[2274, 2366, 0]"]
77["Segment<br>[2372, 2469, 0]"]
78["Segment<br>[2475, 2531, 0]"]
79["Segment<br>[2537, 2544, 0]"]
74["Path<br>[2114, 2213, 0]"]
75["Segment<br>[2219, 2265, 0]"]
76["Segment<br>[2271, 2363, 0]"]
77["Segment<br>[2369, 2466, 0]"]
78["Segment<br>[2472, 2528, 0]"]
79["Segment<br>[2534, 2541, 0]"]
80[Solid2d]
end
1["Plane<br>[514, 531, 0]"]
17["Sweep Extrusion<br>[1373, 1403, 0]"]
1["Plane<br>[511, 528, 0]"]
17["Sweep Extrusion<br>[1370, 1400, 0]"]
18[Wall]
19[Wall]
20[Wall]
@ -71,7 +71,7 @@ flowchart LR
49["SweepEdge Opposite"]
50["SweepEdge Adjacent"]
51["SweepEdge Opposite"]
59["Sweep Extrusion<br>[2004, 2036, 0]"]
59["Sweep Extrusion<br>[2001, 2033, 0]"]
60[Wall]
61[Wall]
62[Wall]
@ -86,7 +86,7 @@ flowchart LR
71["SweepEdge Adjacent"]
72["SweepEdge Opposite"]
73["SweepEdge Adjacent"]
81["Sweep Extrusion<br>[2587, 2619, 0]"]
81["Sweep Extrusion<br>[2584, 2616, 0]"]
82[Wall]
83[Wall]
84[Wall]
@ -101,8 +101,8 @@ flowchart LR
93["SweepEdge Adjacent"]
94["SweepEdge Opposite"]
95["SweepEdge Adjacent"]
96["StartSketchOnFace<br>[1445, 1479, 0]"]
97["StartSketchOnFace<br>[2077, 2111, 0]"]
96["StartSketchOnFace<br>[1442, 1476, 0]"]
97["StartSketchOnFace<br>[2074, 2108, 0]"]
1 --- 2
2 --- 3
2 --- 4

File diff suppressed because it is too large Load Diff

View File

@ -28,9 +28,9 @@ description: Variables in memory after executing router-template-slate.kcl
"id": "[uuid]",
"sourceRange": [],
"tag": {
"commentStart": 618,
"end": 624,
"start": 618,
"commentStart": 615,
"end": 621,
"start": 615,
"type": "TagDeclarator",
"value": "seg01"
},
@ -48,9 +48,9 @@ description: Variables in memory after executing router-template-slate.kcl
"id": "[uuid]",
"sourceRange": [],
"tag": {
"commentStart": 804,
"end": 810,
"start": 804,
"commentStart": 801,
"end": 807,
"start": 801,
"type": "TagDeclarator",
"value": "seg05"
},
@ -61,9 +61,9 @@ description: Variables in memory after executing router-template-slate.kcl
"id": "[uuid]",
"sourceRange": [],
"tag": {
"commentStart": 879,
"end": 885,
"start": 879,
"commentStart": 876,
"end": 882,
"start": 876,
"type": "TagDeclarator",
"value": "seg04"
},
@ -74,9 +74,9 @@ description: Variables in memory after executing router-template-slate.kcl
"id": "[uuid]",
"sourceRange": [],
"tag": {
"commentStart": 925,
"end": 931,
"start": 925,
"commentStart": 922,
"end": 928,
"start": 922,
"type": "TagDeclarator",
"value": "seg03"
},
@ -139,9 +139,9 @@ description: Variables in memory after executing router-template-slate.kcl
28.1188
],
"tag": {
"commentStart": 618,
"end": 624,
"start": 618,
"commentStart": 615,
"end": 621,
"start": 615,
"type": "TagDeclarator",
"value": "seg01"
},
@ -189,9 +189,9 @@ description: Variables in memory after executing router-template-slate.kcl
20.0
],
"tag": {
"commentStart": 804,
"end": 810,
"start": 804,
"commentStart": 801,
"end": 807,
"start": 801,
"type": "TagDeclarator",
"value": "seg05"
},
@ -214,9 +214,9 @@ description: Variables in memory after executing router-template-slate.kcl
-12.4937
],
"tag": {
"commentStart": 879,
"end": 885,
"start": 879,
"commentStart": 876,
"end": 882,
"start": 876,
"type": "TagDeclarator",
"value": "seg04"
},
@ -239,9 +239,9 @@ description: Variables in memory after executing router-template-slate.kcl
-12.4937
],
"tag": {
"commentStart": 925,
"end": 931,
"start": 925,
"commentStart": 922,
"end": 928,
"start": 922,
"type": "TagDeclarator",
"value": "seg03"
},
@ -264,9 +264,9 @@ description: Variables in memory after executing router-template-slate.kcl
-122.4938
],
"tag": {
"commentStart": 967,
"end": 973,
"start": 967,
"commentStart": 964,
"end": 970,
"start": 964,
"type": "TagDeclarator",
"value": "seg02"
},
@ -514,9 +514,9 @@ description: Variables in memory after executing router-template-slate.kcl
"id": "[uuid]",
"sourceRange": [],
"tag": {
"commentStart": 1616,
"end": 1637,
"start": 1616,
"commentStart": 1613,
"end": 1634,
"start": 1613,
"type": "TagDeclarator",
"value": "rectangleSegmentA001"
},
@ -527,9 +527,9 @@ description: Variables in memory after executing router-template-slate.kcl
"id": "[uuid]",
"sourceRange": [],
"tag": {
"commentStart": 1737,
"end": 1758,
"start": 1737,
"commentStart": 1734,
"end": 1755,
"start": 1734,
"type": "TagDeclarator",
"value": "rectangleSegmentB001"
},
@ -540,9 +540,9 @@ description: Variables in memory after executing router-template-slate.kcl
"id": "[uuid]",
"sourceRange": [],
"tag": {
"commentStart": 1863,
"end": 1884,
"start": 1863,
"commentStart": 1860,
"end": 1881,
"start": 1860,
"type": "TagDeclarator",
"value": "rectangleSegmentC001"
},
@ -570,9 +570,9 @@ description: Variables in memory after executing router-template-slate.kcl
-12.4937
],
"tag": {
"commentStart": 1616,
"end": 1637,
"start": 1616,
"commentStart": 1613,
"end": 1634,
"start": 1613,
"type": "TagDeclarator",
"value": "rectangleSegmentA001"
},
@ -595,9 +595,9 @@ description: Variables in memory after executing router-template-slate.kcl
-12.4937
],
"tag": {
"commentStart": 1737,
"end": 1758,
"start": 1737,
"commentStart": 1734,
"end": 1755,
"start": 1734,
"type": "TagDeclarator",
"value": "rectangleSegmentB001"
},
@ -620,9 +620,9 @@ description: Variables in memory after executing router-template-slate.kcl
-92.4938
],
"tag": {
"commentStart": 1863,
"end": 1884,
"start": 1863,
"commentStart": 1860,
"end": 1881,
"start": 1860,
"type": "TagDeclarator",
"value": "rectangleSegmentC001"
},
@ -704,9 +704,9 @@ description: Variables in memory after executing router-template-slate.kcl
"id": "[uuid]",
"sourceRange": [],
"tag": {
"commentStart": 618,
"end": 624,
"start": 618,
"commentStart": 615,
"end": 621,
"start": 615,
"type": "TagDeclarator",
"value": "seg01"
},
@ -724,9 +724,9 @@ description: Variables in memory after executing router-template-slate.kcl
"id": "[uuid]",
"sourceRange": [],
"tag": {
"commentStart": 804,
"end": 810,
"start": 804,
"commentStart": 801,
"end": 807,
"start": 801,
"type": "TagDeclarator",
"value": "seg05"
},
@ -737,9 +737,9 @@ description: Variables in memory after executing router-template-slate.kcl
"id": "[uuid]",
"sourceRange": [],
"tag": {
"commentStart": 879,
"end": 885,
"start": 879,
"commentStart": 876,
"end": 882,
"start": 876,
"type": "TagDeclarator",
"value": "seg04"
},
@ -750,9 +750,9 @@ description: Variables in memory after executing router-template-slate.kcl
"id": "[uuid]",
"sourceRange": [],
"tag": {
"commentStart": 925,
"end": 931,
"start": 925,
"commentStart": 922,
"end": 928,
"start": 922,
"type": "TagDeclarator",
"value": "seg03"
},
@ -815,9 +815,9 @@ description: Variables in memory after executing router-template-slate.kcl
28.1188
],
"tag": {
"commentStart": 618,
"end": 624,
"start": 618,
"commentStart": 615,
"end": 621,
"start": 615,
"type": "TagDeclarator",
"value": "seg01"
},
@ -865,9 +865,9 @@ description: Variables in memory after executing router-template-slate.kcl
20.0
],
"tag": {
"commentStart": 804,
"end": 810,
"start": 804,
"commentStart": 801,
"end": 807,
"start": 801,
"type": "TagDeclarator",
"value": "seg05"
},
@ -890,9 +890,9 @@ description: Variables in memory after executing router-template-slate.kcl
-12.4937
],
"tag": {
"commentStart": 879,
"end": 885,
"start": 879,
"commentStart": 876,
"end": 882,
"start": 876,
"type": "TagDeclarator",
"value": "seg04"
},
@ -915,9 +915,9 @@ description: Variables in memory after executing router-template-slate.kcl
-12.4937
],
"tag": {
"commentStart": 925,
"end": 931,
"start": 925,
"commentStart": 922,
"end": 928,
"start": 922,
"type": "TagDeclarator",
"value": "seg03"
},
@ -940,9 +940,9 @@ description: Variables in memory after executing router-template-slate.kcl
-122.4938
],
"tag": {
"commentStart": 967,
"end": 973,
"start": 967,
"commentStart": 964,
"end": 970,
"start": 964,
"type": "TagDeclarator",
"value": "seg02"
},
@ -1239,9 +1239,9 @@ description: Variables in memory after executing router-template-slate.kcl
"id": "[uuid]",
"sourceRange": [],
"tag": {
"commentStart": 2246,
"end": 2267,
"start": 2246,
"commentStart": 2243,
"end": 2264,
"start": 2243,
"type": "TagDeclarator",
"value": "rectangleSegmentA002"
},
@ -1283,9 +1283,9 @@ description: Variables in memory after executing router-template-slate.kcl
-12.4937
],
"tag": {
"commentStart": 2246,
"end": 2267,
"start": 2246,
"commentStart": 2243,
"end": 2264,
"start": 2243,
"type": "TagDeclarator",
"value": "rectangleSegmentA002"
},
@ -1405,9 +1405,9 @@ description: Variables in memory after executing router-template-slate.kcl
"id": "[uuid]",
"sourceRange": [],
"tag": {
"commentStart": 618,
"end": 624,
"start": 618,
"commentStart": 615,
"end": 621,
"start": 615,
"type": "TagDeclarator",
"value": "seg01"
},
@ -1425,9 +1425,9 @@ description: Variables in memory after executing router-template-slate.kcl
"id": "[uuid]",
"sourceRange": [],
"tag": {
"commentStart": 804,
"end": 810,
"start": 804,
"commentStart": 801,
"end": 807,
"start": 801,
"type": "TagDeclarator",
"value": "seg05"
},
@ -1438,9 +1438,9 @@ description: Variables in memory after executing router-template-slate.kcl
"id": "[uuid]",
"sourceRange": [],
"tag": {
"commentStart": 879,
"end": 885,
"start": 879,
"commentStart": 876,
"end": 882,
"start": 876,
"type": "TagDeclarator",
"value": "seg04"
},
@ -1451,9 +1451,9 @@ description: Variables in memory after executing router-template-slate.kcl
"id": "[uuid]",
"sourceRange": [],
"tag": {
"commentStart": 925,
"end": 931,
"start": 925,
"commentStart": 922,
"end": 928,
"start": 922,
"type": "TagDeclarator",
"value": "seg03"
},
@ -1516,9 +1516,9 @@ description: Variables in memory after executing router-template-slate.kcl
28.1188
],
"tag": {
"commentStart": 618,
"end": 624,
"start": 618,
"commentStart": 615,
"end": 621,
"start": 615,
"type": "TagDeclarator",
"value": "seg01"
},
@ -1566,9 +1566,9 @@ description: Variables in memory after executing router-template-slate.kcl
20.0
],
"tag": {
"commentStart": 804,
"end": 810,
"start": 804,
"commentStart": 801,
"end": 807,
"start": 801,
"type": "TagDeclarator",
"value": "seg05"
},
@ -1591,9 +1591,9 @@ description: Variables in memory after executing router-template-slate.kcl
-12.4937
],
"tag": {
"commentStart": 879,
"end": 885,
"start": 879,
"commentStart": 876,
"end": 882,
"start": 876,
"type": "TagDeclarator",
"value": "seg04"
},
@ -1616,9 +1616,9 @@ description: Variables in memory after executing router-template-slate.kcl
-12.4937
],
"tag": {
"commentStart": 925,
"end": 931,
"start": 925,
"commentStart": 922,
"end": 928,
"start": 922,
"type": "TagDeclarator",
"value": "seg03"
},
@ -1641,9 +1641,9 @@ description: Variables in memory after executing router-template-slate.kcl
-122.4938
],
"tag": {
"commentStart": 967,
"end": 973,
"start": 967,
"commentStart": 964,
"end": 970,
"start": 964,
"type": "TagDeclarator",
"value": "seg02"
},
@ -1924,8 +1924,7 @@ description: Variables in memory after executing router-template-slate.kcl
"type": "Number",
"value": 10.75,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
"length002": {
@ -2041,9 +2040,9 @@ description: Variables in memory after executing router-template-slate.kcl
28.1188
],
"tag": {
"commentStart": 618,
"end": 624,
"start": 618,
"commentStart": 615,
"end": 621,
"start": 615,
"type": "TagDeclarator",
"value": "seg01"
},
@ -2091,9 +2090,9 @@ description: Variables in memory after executing router-template-slate.kcl
20.0
],
"tag": {
"commentStart": 804,
"end": 810,
"start": 804,
"commentStart": 801,
"end": 807,
"start": 801,
"type": "TagDeclarator",
"value": "seg05"
},
@ -2116,9 +2115,9 @@ description: Variables in memory after executing router-template-slate.kcl
-12.4937
],
"tag": {
"commentStart": 879,
"end": 885,
"start": 879,
"commentStart": 876,
"end": 882,
"start": 876,
"type": "TagDeclarator",
"value": "seg04"
},
@ -2141,9 +2140,9 @@ description: Variables in memory after executing router-template-slate.kcl
-12.4937
],
"tag": {
"commentStart": 925,
"end": 931,
"start": 925,
"commentStart": 922,
"end": 928,
"start": 922,
"type": "TagDeclarator",
"value": "seg03"
},
@ -2166,9 +2165,9 @@ description: Variables in memory after executing router-template-slate.kcl
-122.4938
],
"tag": {
"commentStart": 967,
"end": 973,
"start": 967,
"commentStart": 964,
"end": 970,
"start": 964,
"type": "TagDeclarator",
"value": "seg02"
},
@ -2413,9 +2412,9 @@ description: Variables in memory after executing router-template-slate.kcl
-12.4937
],
"tag": {
"commentStart": 1616,
"end": 1637,
"start": 1616,
"commentStart": 1613,
"end": 1634,
"start": 1613,
"type": "TagDeclarator",
"value": "rectangleSegmentA001"
},
@ -2438,9 +2437,9 @@ description: Variables in memory after executing router-template-slate.kcl
-12.4937
],
"tag": {
"commentStart": 1737,
"end": 1758,
"start": 1737,
"commentStart": 1734,
"end": 1755,
"start": 1734,
"type": "TagDeclarator",
"value": "rectangleSegmentB001"
},
@ -2463,9 +2462,9 @@ description: Variables in memory after executing router-template-slate.kcl
-92.4938
],
"tag": {
"commentStart": 1863,
"end": 1884,
"start": 1863,
"commentStart": 1860,
"end": 1881,
"start": 1860,
"type": "TagDeclarator",
"value": "rectangleSegmentC001"
},
@ -2547,9 +2546,9 @@ description: Variables in memory after executing router-template-slate.kcl
"id": "[uuid]",
"sourceRange": [],
"tag": {
"commentStart": 618,
"end": 624,
"start": 618,
"commentStart": 615,
"end": 621,
"start": 615,
"type": "TagDeclarator",
"value": "seg01"
},
@ -2567,9 +2566,9 @@ description: Variables in memory after executing router-template-slate.kcl
"id": "[uuid]",
"sourceRange": [],
"tag": {
"commentStart": 804,
"end": 810,
"start": 804,
"commentStart": 801,
"end": 807,
"start": 801,
"type": "TagDeclarator",
"value": "seg05"
},
@ -2580,9 +2579,9 @@ description: Variables in memory after executing router-template-slate.kcl
"id": "[uuid]",
"sourceRange": [],
"tag": {
"commentStart": 879,
"end": 885,
"start": 879,
"commentStart": 876,
"end": 882,
"start": 876,
"type": "TagDeclarator",
"value": "seg04"
},
@ -2593,9 +2592,9 @@ description: Variables in memory after executing router-template-slate.kcl
"id": "[uuid]",
"sourceRange": [],
"tag": {
"commentStart": 925,
"end": 931,
"start": 925,
"commentStart": 922,
"end": 928,
"start": 922,
"type": "TagDeclarator",
"value": "seg03"
},
@ -2658,9 +2657,9 @@ description: Variables in memory after executing router-template-slate.kcl
28.1188
],
"tag": {
"commentStart": 618,
"end": 624,
"start": 618,
"commentStart": 615,
"end": 621,
"start": 615,
"type": "TagDeclarator",
"value": "seg01"
},
@ -2708,9 +2707,9 @@ description: Variables in memory after executing router-template-slate.kcl
20.0
],
"tag": {
"commentStart": 804,
"end": 810,
"start": 804,
"commentStart": 801,
"end": 807,
"start": 801,
"type": "TagDeclarator",
"value": "seg05"
},
@ -2733,9 +2732,9 @@ description: Variables in memory after executing router-template-slate.kcl
-12.4937
],
"tag": {
"commentStart": 879,
"end": 885,
"start": 879,
"commentStart": 876,
"end": 882,
"start": 876,
"type": "TagDeclarator",
"value": "seg04"
},
@ -2758,9 +2757,9 @@ description: Variables in memory after executing router-template-slate.kcl
-12.4937
],
"tag": {
"commentStart": 925,
"end": 931,
"start": 925,
"commentStart": 922,
"end": 928,
"start": 922,
"type": "TagDeclarator",
"value": "seg03"
},
@ -2783,9 +2782,9 @@ description: Variables in memory after executing router-template-slate.kcl
-122.4938
],
"tag": {
"commentStart": 967,
"end": 973,
"start": 967,
"commentStart": 964,
"end": 970,
"start": 964,
"type": "TagDeclarator",
"value": "seg02"
},
@ -3079,9 +3078,9 @@ description: Variables in memory after executing router-template-slate.kcl
-12.4937
],
"tag": {
"commentStart": 2246,
"end": 2267,
"start": 2246,
"commentStart": 2243,
"end": 2264,
"start": 2243,
"type": "TagDeclarator",
"value": "rectangleSegmentA002"
},
@ -3201,9 +3200,9 @@ description: Variables in memory after executing router-template-slate.kcl
"id": "[uuid]",
"sourceRange": [],
"tag": {
"commentStart": 618,
"end": 624,
"start": 618,
"commentStart": 615,
"end": 621,
"start": 615,
"type": "TagDeclarator",
"value": "seg01"
},
@ -3221,9 +3220,9 @@ description: Variables in memory after executing router-template-slate.kcl
"id": "[uuid]",
"sourceRange": [],
"tag": {
"commentStart": 804,
"end": 810,
"start": 804,
"commentStart": 801,
"end": 807,
"start": 801,
"type": "TagDeclarator",
"value": "seg05"
},
@ -3234,9 +3233,9 @@ description: Variables in memory after executing router-template-slate.kcl
"id": "[uuid]",
"sourceRange": [],
"tag": {
"commentStart": 879,
"end": 885,
"start": 879,
"commentStart": 876,
"end": 882,
"start": 876,
"type": "TagDeclarator",
"value": "seg04"
},
@ -3247,9 +3246,9 @@ description: Variables in memory after executing router-template-slate.kcl
"id": "[uuid]",
"sourceRange": [],
"tag": {
"commentStart": 925,
"end": 931,
"start": 925,
"commentStart": 922,
"end": 928,
"start": 922,
"type": "TagDeclarator",
"value": "seg03"
},
@ -3312,9 +3311,9 @@ description: Variables in memory after executing router-template-slate.kcl
28.1188
],
"tag": {
"commentStart": 618,
"end": 624,
"start": 618,
"commentStart": 615,
"end": 621,
"start": 615,
"type": "TagDeclarator",
"value": "seg01"
},
@ -3362,9 +3361,9 @@ description: Variables in memory after executing router-template-slate.kcl
20.0
],
"tag": {
"commentStart": 804,
"end": 810,
"start": 804,
"commentStart": 801,
"end": 807,
"start": 801,
"type": "TagDeclarator",
"value": "seg05"
},
@ -3387,9 +3386,9 @@ description: Variables in memory after executing router-template-slate.kcl
-12.4937
],
"tag": {
"commentStart": 879,
"end": 885,
"start": 879,
"commentStart": 876,
"end": 882,
"start": 876,
"type": "TagDeclarator",
"value": "seg04"
},
@ -3412,9 +3411,9 @@ description: Variables in memory after executing router-template-slate.kcl
-12.4937
],
"tag": {
"commentStart": 925,
"end": 931,
"start": 925,
"commentStart": 922,
"end": 928,
"start": 922,
"type": "TagDeclarator",
"value": "seg03"
},
@ -3437,9 +3436,9 @@ description: Variables in memory after executing router-template-slate.kcl
-122.4938
],
"tag": {
"commentStart": 967,
"end": 973,
"start": 967,
"commentStart": 964,
"end": 970,
"start": 964,
"type": "TagDeclarator",
"value": "seg02"
},
@ -3713,8 +3712,7 @@ description: Variables in memory after executing router-template-slate.kcl
"type": "Number",
"value": 20.75,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
"templateDiameter": {

View File

@ -25,13 +25,7 @@ description: Operations executed sheet-metal-bracket.kcl
"type": "Number",
"value": 5.5,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
},
"sourceRange": []
@ -57,8 +51,7 @@ description: Operations executed sheet-metal-bracket.kcl
"type": "Number",
"value": 0.5,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
"sourceRange": []

View File

@ -1788,8 +1788,7 @@ description: Variables in memory after executing sheet-metal-bracket.kcl
"type": "Number",
"value": 0.1875,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
"componentBoltPatternX": {
@ -1835,21 +1834,14 @@ description: Variables in memory after executing sheet-metal-bracket.kcl
"type": "Number",
"value": 5.5,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
},
"flangeLength": {
"type": "Number",
"value": 1.5,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
"hatHeight": {
@ -3753,8 +3745,7 @@ description: Variables in memory after executing sheet-metal-bracket.kcl
"type": "Number",
"value": 0.25,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
"mountingBoltPatternX": {
@ -3787,8 +3778,7 @@ description: Variables in memory after executing sheet-metal-bracket.kcl
"type": "Number",
"value": 0.75,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
"rightFlangeBoltPattern": {

View File

@ -148,13 +148,7 @@ description: Operations executed socket-head-cap-screw.kcl
"type": "Number",
"value": -0.14250000000000002,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
"type": "Unknown"
}
},
"sourceRange": []

View File

@ -451,16 +451,14 @@ description: Variables in memory after executing socket-head-cap-screw.kcl
"type": "Number",
"value": 0.1563,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
"boltHexFlatLength": {
"type": "Number",
"value": 0.0902,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
"boltLength": {

View File

@ -83,8 +83,7 @@ description: Variables in memory after executing walkie-talkie.kcl
"type": "Number",
"value": 0.48,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
"buttonThickness": {
@ -255,8 +254,7 @@ description: Variables in memory after executing walkie-talkie.kcl
"type": "Number",
"value": 1.25,
"ty": {
"type": "Known",
"type": "Count"
"type": "Unknown"
}
},
"speakerBoxHeight": {

View File

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

View File

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

View File

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

View File

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

View File

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Some files were not shown because too many files have changed in this diff Show More