Compare commits

...

6 Commits

Author SHA1 Message Date
df8ef799cb dont need to flush fillets on transform
Signed-off-by: Jess Frazelle <github@jessfraz.com>
2025-05-23 18:23:21 -07:00
678433d2b3 Bubble up the actual error message in the Text-to-CAD toast message (#7201)
So that users can see if they're blocked, for example.
2025-05-24 00:00:42 +00:00
30bd307931 [Fix]: Corrected camera's projection when engine idle reconnects (#7173)
* fix: implemented a fix to read from settings before restoring camera view and log if it desyncs

* fix: reverting testing code

* fix: always enable ortho scale enabled mode

* fix: fixed the ortho_scale_enabled boolean, do not touch it. Set it to true and never touch it again
2025-05-23 17:30:05 -04:00
08dfaba7f7 Updating the rail to modern practice (#7180)
* Updating the rail to modern practice

* rename 8020 to generic T-slot
2025-05-23 20:59:44 +00:00
eb2327827b Release KCL 77 (#7188) 2025-05-23 18:54:04 +00:00
1f53dd1357 KCL: [number; 3] to RGB hex string color function (#7184)
Closes https://github.com/KittyCAD/modeling-app/issues/6805. Enables users to programatically construct colors, which will be helpful for 

- Applying color to visualize program execution and help debugging
- Doing weird cool shit
2025-05-23 13:53:58 -05:00
59 changed files with 6103 additions and 13467 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -16,6 +16,8 @@ layout: manual
* [`helix`](/docs/kcl-std/functions/std-helix) * [`helix`](/docs/kcl-std/functions/std-helix)
* [`offsetPlane`](/docs/kcl-std/functions/std-offsetPlane) * [`offsetPlane`](/docs/kcl-std/functions/std-offsetPlane)
* [`patternLinear2d`](/docs/kcl-std/patternLinear2d) * [`patternLinear2d`](/docs/kcl-std/patternLinear2d)
* [**std::appearance**](/docs/kcl-std/modules/std-appearance)
* [`appearance::hexString`](/docs/kcl-std/functions/std-appearance-hexString)
* [**std::array**](/docs/kcl-std/modules/std-array) * [**std::array**](/docs/kcl-std/modules/std-array)
* [`map`](/docs/kcl-std/functions/std-array-map) * [`map`](/docs/kcl-std/functions/std-array-map)
* [`pop`](/docs/kcl-std/functions/std-array-pop) * [`pop`](/docs/kcl-std/functions/std-array-pop)

View File

@ -0,0 +1,16 @@
---
title: "appearance"
subtitle: "Module in std"
excerpt: ""
layout: manual
---
## Functions and constants
* [`appearance::hexString`](/docs/kcl-std/functions/std-appearance-hexString)

View File

@ -15,6 +15,7 @@ You might also want the [KCL language reference](/docs/kcl-lang) or the [KCL gui
## Modules ## Modules
* [`appearance::appearance`](/docs/kcl-std/modules/std-appearance)
* [`array`](/docs/kcl-std/modules/std-array) * [`array`](/docs/kcl-std/modules/std-array)
* [`math`](/docs/kcl-std/modules/std-math) * [`math`](/docs/kcl-std/modules/std-math)
* [`sketch`](/docs/kcl-std/modules/std-sketch) * [`sketch`](/docs/kcl-std/modules/std-sketch)

View File

@ -1,142 +0,0 @@
// 80/20 Rail
// An 80/20 extruded aluminum linear rail. T-slot profile adjustable by profile height, rail length, and origin position
// Set units
@settings(defaultLengthUnit = in, kclVersion = 1.0)
// Create a function to make the 80-20 rail
fn rail8020(originStart, railHeight, railLength) {
// Sketch side 1 of profile
sketch001 = startSketchOn(-XZ)
|> startProfile(at = [
originStart[0],
0.1 * railHeight + originStart[1]
])
|> arc(angleStart = 180, angleEnd = 270, radius = 0.1 * railHeight)
|> arc(angleStart = 180, angleEnd = 0, radius = 0.072 / 4 * railHeight)
|> xLine(length = 0.1 * railHeight)
|> arc(angleStart = 180, angleEnd = 0, radius = 0.072 / 4 * railHeight)
|> xLine(length = 0.06 * railHeight, tag = $edge1)
|> yLine(length = 0.087 * railHeight, tag = $edge2)
|> xLine(length = -0.183 * railHeight, tag = $edge3)
|> angledLine(angle = 45, endAbsoluteY = (1 - 0.356) / 2 * railHeight + originStart[1], tag = $edge4)
|> xLine(length = 0.232 * railHeight, tag = $edge5)
|> angledLine(angle = -45, endAbsoluteY = 0.087 * railHeight + originStart[1], tag = $edge6)
|> xLine(length = -0.183 * railHeight, tag = $edge7)
|> yLine(length = -0.087 * railHeight, tag = $edge8)
|> xLine(length = 0.06 * railHeight)
|> arc(angleStart = 180, angleEnd = 0, radius = 0.072 / 4 * railHeight)
|> xLine(length = 0.1 * railHeight)
|> arc(angleStart = 180, angleEnd = 0, radius = 0.072 / 4 * railHeight)
|> arc(angleStart = -90, angleEnd = 0, radius = 0.1 * railHeight)
// Sketch side 2 of profile
|> arc(angleStart = 270, angleEnd = 90, radius = 0.072 / 4 * railHeight)
|> yLine(length = 0.1 * railHeight)
|> arc(angleStart = 270, angleEnd = 90, radius = 0.072 / 4 * railHeight)
|> yLine(length = 0.06 * railHeight, tag = $edge9)
|> xLine(length = -0.087 * railHeight, tag = $edge10)
|> yLine(length = -0.183 * railHeight, tag = $edge11) // edge11
|> angledLine(angle = 135, endAbsoluteX = ((1 - 0.356) / 2 + 0.356) * railHeight + originStart[0], tag = $edge12) // edge12
|> yLine(length = 0.232 * railHeight, tag = $edge13) // 13
|> angledLine(angle = 45, endAbsoluteX = (1 - 0.087) * railHeight + originStart[0], tag = $edge14) // 14
|> yLine(length = -0.183 * railHeight, tag = $edge15) // 15
|> xLine(length = 0.087 * railHeight, tag = $edge16)
|> yLine(length = 0.06 * railHeight)
|> arc(angleStart = 270, angleEnd = 90, radius = 0.072 / 4 * railHeight)
|> yLine(length = 0.1 * railHeight)
|> arc(angleStart = 270, angleEnd = 90, radius = 0.072 / 4 * railHeight)
// Sketch side 3 of profile
|> arc(angleStart = 0, angleEnd = 90, radius = 0.1 * railHeight)
|> arc(angleStart = 0, angleEnd = -180, radius = 0.072 / 4 * railHeight)
|> xLine(length = -0.1 * railHeight)
|> arc(angleStart = 0, angleEnd = -180, radius = 0.072 / 4 * railHeight)
|> xLine(length = -0.06 * railHeight, tag = $edge17)
|> yLine(length = -0.087 * railHeight, tag = $edge18)
|> xLine(length = 0.183 * railHeight, tag = $edge19)
|> angledLine(angle = 45, endAbsoluteY = ((1 - 0.356) / 2 + 0.356) * railHeight + originStart[1], tag = $edge20)
|> xLine(length = -0.232 * railHeight, tag = $edge21)
|> angledLine(angle = 135, endAbsoluteY = (1 - 0.087) * railHeight + originStart[1], tag = $edge22)
|> xLine(length = 0.183 * railHeight, tag = $edge23)
|> yLine(length = 0.087 * railHeight, tag = $edge24)
|> xLine(length = -0.06 * railHeight)
|> arc(angleStart = 0, angleEnd = -180, radius = 0.072 / 4 * railHeight)
|> xLine(length = -0.1 * railHeight)
|> arc(angleStart = 0, angleEnd = -180, radius = 0.072 / 4 * railHeight)
|> arc(angleStart = 90, angleEnd = 180, radius = 0.1 * railHeight)
// Sketch side 4 of profile
|> arc(angleStart = 90, angleEnd = -90, radius = 0.072 / 4 * railHeight)
|> yLine(length = -0.1 * railHeight)
|> arc(angleStart = 90, angleEnd = -90, radius = 0.072 / 4 * railHeight)
|> yLine(length = -0.06 * railHeight, tag = $edge25)
|> xLine(length = 0.087 * railHeight, tag = $edge26)
|> yLine(length = 0.183 * railHeight, tag = $edge27)
|> angledLine(angle = 135, endAbsoluteX = (1 - 0.356) / 2 * railHeight + originStart[0], tag = $edge28)
|> yLine(length = -0.232 * railHeight, tag = $edge29)
|> angledLine(angle = 45, endAbsoluteX = 0.087 * railHeight + originStart[0], tag = $edge30)
|> yLine(length = 0.183 * railHeight, tag = $edge31)
|> xLine(length = -0.087 * railHeight, tag = $edge32)
|> yLine(length = -0.06 * railHeight)
|> arc(angleStart = 90, angleEnd = -90, radius = 0.072 / 4 * railHeight)
|> yLine(length = -0.1 * railHeight)
|> arc(angleStart = 90, angleEnd = -90, radius = 0.072 / 4 * railHeight)
|> close()
// Sketch center hole of profile
|> subtract2d(tool = circle(
center = [
.5 * railHeight + originStart[0],
.5 * railHeight + originStart[1]
],
radius = .205 * railHeight / 2,
))
|> extrude(length = railLength)
|> fillet(
radius = 0.06,
tags = [
getNextAdjacentEdge(edge3),
getNextAdjacentEdge(edge4),
getNextAdjacentEdge(edge5),
getNextAdjacentEdge(edge6),
getNextAdjacentEdge(edge11),
getNextAdjacentEdge(edge12),
getNextAdjacentEdge(edge13),
getNextAdjacentEdge(edge14),
getNextAdjacentEdge(edge19),
getNextAdjacentEdge(edge20),
getNextAdjacentEdge(edge21),
getNextAdjacentEdge(edge22),
getNextAdjacentEdge(edge27),
getNextAdjacentEdge(edge28),
getNextAdjacentEdge(edge29),
getNextAdjacentEdge(edge30)
],
)
|> fillet(
radius = 0.03,
tags = [
getNextAdjacentEdge(edge1),
getNextAdjacentEdge(edge2),
getNextAdjacentEdge(edge7),
getNextAdjacentEdge(edge8),
getNextAdjacentEdge(edge9),
getNextAdjacentEdge(edge10),
getNextAdjacentEdge(edge15),
getNextAdjacentEdge(edge16),
getNextAdjacentEdge(edge17),
getNextAdjacentEdge(edge18),
getNextAdjacentEdge(edge23),
getNextAdjacentEdge(edge24),
getNextAdjacentEdge(edge25),
getNextAdjacentEdge(edge26),
getNextAdjacentEdge(edge31),
getNextAdjacentEdge(edge32)
],
)
return sketch001
}
// Generate one adjustable rail of 80/20
rail8020(originStart = [0, 0], railHeight = 1.5, railLength = 48)

View File

@ -23,8 +23,6 @@ KCL samples conform to a set of style guidelines to ensure consistency and reada
When you submit a PR to add or modify KCL samples, images will be generated and added to the repository automatically. When you submit a PR to add or modify KCL samples, images will be generated and added to the repository automatically.
--- ---
#### [80-20-rail](80-20-rail/main.kcl) ([screenshot](screenshots/80-20-rail.png))
[![80-20-rail](screenshots/80-20-rail.png)](80-20-rail/main.kcl)
#### [axial-fan](axial-fan/main.kcl) ([screenshot](screenshots/axial-fan.png)) #### [axial-fan](axial-fan/main.kcl) ([screenshot](screenshots/axial-fan.png))
[![axial-fan](screenshots/axial-fan.png)](axial-fan/main.kcl) [![axial-fan](screenshots/axial-fan.png)](axial-fan/main.kcl)
#### [ball-bearing](ball-bearing/main.kcl) ([screenshot](screenshots/ball-bearing.png)) #### [ball-bearing](ball-bearing/main.kcl) ([screenshot](screenshots/ball-bearing.png))
@ -143,6 +141,8 @@ When you submit a PR to add or modify KCL samples, images will be generated and
[![spur-reduction-gearset](screenshots/spur-reduction-gearset.png)](spur-reduction-gearset/main.kcl) [![spur-reduction-gearset](screenshots/spur-reduction-gearset.png)](spur-reduction-gearset/main.kcl)
#### [surgical-drill-guide](surgical-drill-guide/main.kcl) ([screenshot](screenshots/surgical-drill-guide.png)) #### [surgical-drill-guide](surgical-drill-guide/main.kcl) ([screenshot](screenshots/surgical-drill-guide.png))
[![surgical-drill-guide](screenshots/surgical-drill-guide.png)](surgical-drill-guide/main.kcl) [![surgical-drill-guide](screenshots/surgical-drill-guide.png)](surgical-drill-guide/main.kcl)
#### [t-slot-rail](t-slot-rail/main.kcl) ([screenshot](screenshots/t-slot-rail.png))
[![t-slot-rail](screenshots/t-slot-rail.png)](t-slot-rail/main.kcl)
#### [telemetry-antenna](telemetry-antenna/main.kcl) ([screenshot](screenshots/telemetry-antenna.png)) #### [telemetry-antenna](telemetry-antenna/main.kcl) ([screenshot](screenshots/telemetry-antenna.png))
[![telemetry-antenna](screenshots/telemetry-antenna.png)](telemetry-antenna/main.kcl) [![telemetry-antenna](screenshots/telemetry-antenna.png)](telemetry-antenna/main.kcl)
#### [thermal-block-insert](thermal-block-insert/main.kcl) ([screenshot](screenshots/thermal-block-insert.png)) #### [thermal-block-insert](thermal-block-insert/main.kcl) ([screenshot](screenshots/thermal-block-insert.png))

View File

@ -1,14 +1,4 @@
[ [
{
"file": "main.kcl",
"pathFromProjectDirectoryToFirstFile": "80-20-rail/main.kcl",
"multipleFiles": false,
"title": "80/20 Rail",
"description": "An 80/20 extruded aluminum linear rail. T-slot profile adjustable by profile height, rail length, and origin position",
"files": [
"main.kcl"
]
},
{ {
"file": "main.kcl", "file": "main.kcl",
"pathFromProjectDirectoryToFirstFile": "axial-fan/main.kcl", "pathFromProjectDirectoryToFirstFile": "axial-fan/main.kcl",
@ -632,6 +622,16 @@
"main.kcl" "main.kcl"
] ]
}, },
{
"file": "main.kcl",
"pathFromProjectDirectoryToFirstFile": "t-slot-rail/main.kcl",
"multipleFiles": false,
"title": "T-Slotted Framing Rail",
"description": "A T-slotted framing rail, or T-slot extrusion, is a rectangular or square aluminum profile with a \"T\" shaped slot along one or more sides. These slots allow for easy attachment of various hardware components like brackets, connectors, and fasteners, making it a versatile and customizable framing system.",
"files": [
"main.kcl"
]
},
{ {
"file": "main.kcl", "file": "main.kcl",
"pathFromProjectDirectoryToFirstFile": "telemetry-antenna/main.kcl", "pathFromProjectDirectoryToFirstFile": "telemetry-antenna/main.kcl",

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

View File

@ -0,0 +1,58 @@
// T-Slotted Framing Rail
// A T-slotted framing rail, or T-slot extrusion, is a rectangular or square aluminum profile with a "T" shaped slot along one or more sides. These slots allow for easy attachment of various hardware components like brackets, connectors, and fasteners, making it a versatile and customizable framing system.
// Set units
@settings(defaultLengthUnit = in, kclVersion = 1.0)
// Define parameters
interiorRadius = 0.01
scoreDepth = 0.018
arcEnd = 0.0275
holeDiameter = 0.262
fn railTslot(railHeight, railLength) {
// Sketch one inner leg of the extruded rail
railProfile = startSketchOn(XZ)
|> startProfile(at = [0.5, (1 - 0.356) / 2])
|> xLine(length = -0.08)
|> tangentialArc(angle = 45, radius = .09)
|> angledLine(angle = 45, endAbsoluteY = 0.113)
|> tangentialArc(angle = 135, radius = interiorRadius)
|> xLine(endAbsolute = .5 - (.320 / 2) - interiorRadius)
|> tangentialArc(angle = -90, radius = interiorRadius)
|> yLine(endAbsolute = interiorRadius)
|> tangentialArc(angle = -90, radius = interiorRadius)
|> xLine(length = -0.03)
|> arc(angleStart = 0, angleEnd = 180, radius = scoreDepth)
|> xLine(length = -0.1)
|> arc(angleStart = 0, angleEnd = 180, radius = scoreDepth)
|> xLine(length = -0.03)
|> tangentialArc(endAbsolute = [arcEnd, arcEnd])
// Mirror the sketch about the diagonal to complete the leg. Then mirror across the center of the profile in the horizontal and vertical directions. Then close the sketch
|> mirror2d(axis = {
direction = [1.0, 1.0],
origin = [0.0, 0.0]
})
|> mirror2d(axis = {
direction = [1.0, 0.0],
origin = [0.0, 0.5]
})
|> mirror2d(axis = {
direction = [0.0, 1.0],
origin = [0.5, 0.0]
})
|> close()
// Sketch a dimensioned hole in the center of the profile
|> subtract2d(tool = circle(center = [railHeight / 2, railHeight / 2], radius = holeDiameter / 2))
// Scale the entire sketch by a factor of the rail height, then extrude
|> scale(x = railHeight, z = railHeight)
|> extrude(length = -railLength)
return railProfile
}
// Generate one rail using the rail function
railTslot(railHeight = 1.5, railLength = 2ft)

20
rust/Cargo.lock generated
View File

@ -1815,7 +1815,7 @@ dependencies = [
[[package]] [[package]]
name = "kcl-bumper" name = "kcl-bumper"
version = "0.1.76" version = "0.1.77"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"clap", "clap",
@ -1826,7 +1826,7 @@ dependencies = [
[[package]] [[package]]
name = "kcl-derive-docs" name = "kcl-derive-docs"
version = "0.1.76" version = "0.1.77"
dependencies = [ dependencies = [
"Inflector", "Inflector",
"anyhow", "anyhow",
@ -1845,7 +1845,7 @@ dependencies = [
[[package]] [[package]]
name = "kcl-directory-test-macro" name = "kcl-directory-test-macro"
version = "0.1.76" version = "0.1.77"
dependencies = [ dependencies = [
"convert_case", "convert_case",
"proc-macro2", "proc-macro2",
@ -1855,7 +1855,7 @@ dependencies = [
[[package]] [[package]]
name = "kcl-language-server" name = "kcl-language-server"
version = "0.2.76" version = "0.2.77"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"clap", "clap",
@ -1876,7 +1876,7 @@ dependencies = [
[[package]] [[package]]
name = "kcl-language-server-release" name = "kcl-language-server-release"
version = "0.1.76" version = "0.1.77"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"clap", "clap",
@ -1896,7 +1896,7 @@ dependencies = [
[[package]] [[package]]
name = "kcl-lib" name = "kcl-lib"
version = "0.2.76" version = "0.2.77"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"approx 0.5.1", "approx 0.5.1",
@ -1973,7 +1973,7 @@ dependencies = [
[[package]] [[package]]
name = "kcl-python-bindings" name = "kcl-python-bindings"
version = "0.3.76" version = "0.3.77"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"kcl-lib", "kcl-lib",
@ -1988,7 +1988,7 @@ dependencies = [
[[package]] [[package]]
name = "kcl-test-server" name = "kcl-test-server"
version = "0.1.76" version = "0.1.77"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"hyper 0.14.32", "hyper 0.14.32",
@ -2001,7 +2001,7 @@ dependencies = [
[[package]] [[package]]
name = "kcl-to-core" name = "kcl-to-core"
version = "0.1.76" version = "0.1.77"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"async-trait", "async-trait",
@ -2015,7 +2015,7 @@ dependencies = [
[[package]] [[package]]
name = "kcl-wasm-lib" name = "kcl-wasm-lib"
version = "0.1.76" version = "0.1.77"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"bson", "bson",

View File

@ -1,7 +1,7 @@
[package] [package]
name = "kcl-bumper" name = "kcl-bumper"
version = "0.1.76" version = "0.1.77"
edition = "2021" edition = "2021"
repository = "https://github.com/KittyCAD/modeling-api" repository = "https://github.com/KittyCAD/modeling-api"
rust-version = "1.76" rust-version = "1.76"

View File

@ -1,7 +1,7 @@
[package] [package]
name = "kcl-derive-docs" name = "kcl-derive-docs"
description = "A tool for generating documentation from Rust derive macros" description = "A tool for generating documentation from Rust derive macros"
version = "0.1.76" version = "0.1.77"
edition = "2021" edition = "2021"
license = "MIT" license = "MIT"
repository = "https://github.com/KittyCAD/modeling-app" repository = "https://github.com/KittyCAD/modeling-app"

View File

@ -42,7 +42,10 @@ pub fn do_for_all_example_test(item: proc_macro2::TokenStream) -> proc_macro2::T
item.into_token_stream() item.into_token_stream()
} }
pub const TEST_NAMES: [&str; 93] = [ pub const TEST_NAMES: &[&str] = &[
"std-appearance-hexString-0",
"std-appearance-hexString-1",
"std-appearance-hexString-2",
"std-array-map-0", "std-array-map-0",
"std-array-map-1", "std-array-map-1",
"std-array-pop-0", "std-array-pop-0",

View File

@ -1,7 +1,7 @@
[package] [package]
name = "kcl-directory-test-macro" name = "kcl-directory-test-macro"
description = "A tool for generating tests from a directory of kcl files" description = "A tool for generating tests from a directory of kcl files"
version = "0.1.76" version = "0.1.77"
edition = "2021" edition = "2021"
license = "MIT" license = "MIT"
repository = "https://github.com/KittyCAD/modeling-app" repository = "https://github.com/KittyCAD/modeling-app"

View File

@ -1,6 +1,6 @@
[package] [package]
name = "kcl-language-server-release" name = "kcl-language-server-release"
version = "0.1.76" version = "0.1.77"
edition = "2021" edition = "2021"
authors = ["KittyCAD Inc <kcl@kittycad.io>"] authors = ["KittyCAD Inc <kcl@kittycad.io>"]
publish = false publish = false

View File

@ -2,7 +2,7 @@
name = "kcl-language-server" name = "kcl-language-server"
description = "A language server for KCL." description = "A language server for KCL."
authors = ["KittyCAD Inc <kcl@kittycad.io>"] authors = ["KittyCAD Inc <kcl@kittycad.io>"]
version = "0.2.76" version = "0.2.77"
edition = "2021" edition = "2021"
license = "MIT" license = "MIT"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

View File

@ -1,7 +1,7 @@
[package] [package]
name = "kcl-lib" name = "kcl-lib"
description = "KittyCAD Language implementation and tools" description = "KittyCAD Language implementation and tools"
version = "0.2.76" version = "0.2.77"
edition = "2021" edition = "2021"
license = "MIT" license = "MIT"
repository = "https://github.com/KittyCAD/modeling-app" repository = "https://github.com/KittyCAD/modeling-app"

View File

@ -97,6 +97,7 @@ pub(crate) fn read_std(mod_name: &str) -> Option<&'static str> {
"units" => Some(include_str!("../std/units.kcl")), "units" => Some(include_str!("../std/units.kcl")),
"array" => Some(include_str!("../std/array.kcl")), "array" => Some(include_str!("../std/array.kcl")),
"sweep" => Some(include_str!("../std/sweep.kcl")), "sweep" => Some(include_str!("../std/sweep.kcl")),
"appearance" => Some(include_str!("../std/appearance.kcl")),
"transform" => Some(include_str!("../std/transform.kcl")), "transform" => Some(include_str!("../std/transform.kcl")),
_ => None, _ => None,
} }

View File

@ -10,7 +10,10 @@ use rgba_simple::Hex;
use super::args::TyF64; use super::args::TyF64;
use crate::{ use crate::{
errors::{KclError, KclErrorDetails}, errors::{KclError, KclErrorDetails},
execution::{types::RuntimeType, ExecState, KclValue, SolidOrImportedGeometry}, execution::{
types::{ArrayLen, RuntimeType},
ExecState, KclValue, SolidOrImportedGeometry,
},
std::Args, std::Args,
}; };
@ -18,6 +21,34 @@ lazy_static::lazy_static! {
static ref HEX_REGEX: Regex = Regex::new(r"^#[0-9a-fA-F]{6}$").unwrap(); static ref HEX_REGEX: Regex = Regex::new(r"^#[0-9a-fA-F]{6}$").unwrap();
} }
/// Construct a color from its red, blue and green components.
pub async fn hex_string(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let rgb: [TyF64; 3] = args.get_unlabeled_kw_arg_typed(
"rgb",
&RuntimeType::Array(Box::new(RuntimeType::count()), ArrayLen::Known(3)),
exec_state,
)?;
// Make sure the color if set is valid.
if let Some(component) = rgb.iter().find(|component| component.n < 0.0 || component.n > 255.0) {
return Err(KclError::Semantic(KclErrorDetails::new(
format!("Colors are given between 0 and 255, so {} is invalid", component.n),
vec![args.source_range],
)));
}
inner_hex_string(rgb, exec_state, args).await
}
async fn inner_hex_string(rgb: [TyF64; 3], _: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let [r, g, b] = rgb.map(|n| n.n.floor() as u32);
let s = format!("#{r:02x}{g:02x}{b:02x}");
Ok(KclValue::String {
value: s,
meta: args.into(),
})
}
/// Set the appearance of a solid. This only works on solids, not sketches or individual paths. /// Set the appearance of a solid. This only works on solids, not sketches or individual paths.
pub async fn appearance(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> { pub async fn appearance(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let solids = args.get_unlabeled_kw_arg_typed( let solids = args.get_unlabeled_kw_arg_typed(

View File

@ -286,7 +286,13 @@ pub(crate) fn std_fn(path: &str, fn_name: &str) -> (crate::std::StdFn, StdFnProp
|e, a| Box::pin(crate::std::patterns::pattern_transform_2d(e, a)), |e, a| Box::pin(crate::std::patterns::pattern_transform_2d(e, a)),
StdFnProps::default("std::sketch::patternTransform2d"), StdFnProps::default("std::sketch::patternTransform2d"),
), ),
_ => unreachable!(), ("appearance", "hexString") => (
|e, a| Box::pin(crate::std::appearance::hex_string(e, a)),
StdFnProps::default("std::appearance::hexString"),
),
(module, fn_name) => {
panic!("No implementation found for {module}::{fn_name}, please add it to this big match statement")
}
} }
} }

View File

@ -166,12 +166,6 @@ async fn inner_scale(
exec_state: &mut ExecState, exec_state: &mut ExecState,
args: Args, args: Args,
) -> Result<SolidOrSketchOrImportedGeometry, KclError> { ) -> Result<SolidOrSketchOrImportedGeometry, KclError> {
// If we have a solid, flush the fillets and chamfers.
// Only transforms needs this, it is very odd, see: https://github.com/KittyCAD/modeling-app/issues/5880
if let SolidOrSketchOrImportedGeometry::SolidSet(solids) = &objects {
args.flush_batch_for_solids(exec_state, solids).await?;
}
let mut objects = objects.clone(); let mut objects = objects.clone();
for object_id in objects.ids(&args.ctx).await? { for object_id in objects.ids(&args.ctx).await? {
let id = exec_state.next_uuid(); let id = exec_state.next_uuid();
@ -396,12 +390,6 @@ async fn inner_translate(
exec_state: &mut ExecState, exec_state: &mut ExecState,
args: Args, args: Args,
) -> Result<SolidOrSketchOrImportedGeometry, KclError> { ) -> Result<SolidOrSketchOrImportedGeometry, KclError> {
// If we have a solid, flush the fillets and chamfers.
// Only transforms needs this, it is very odd, see: https://github.com/KittyCAD/modeling-app/issues/5880
if let SolidOrSketchOrImportedGeometry::SolidSet(solids) = &objects {
args.flush_batch_for_solids(exec_state, solids).await?;
}
let mut objects = objects.clone(); let mut objects = objects.clone();
for object_id in objects.ids(&args.ctx).await? { for object_id in objects.ids(&args.ctx).await? {
let id = exec_state.next_uuid(); let id = exec_state.next_uuid();
@ -804,12 +792,6 @@ async fn inner_rotate(
exec_state: &mut ExecState, exec_state: &mut ExecState,
args: Args, args: Args,
) -> Result<SolidOrSketchOrImportedGeometry, KclError> { ) -> Result<SolidOrSketchOrImportedGeometry, KclError> {
// If we have a solid, flush the fillets and chamfers.
// Only transforms needs this, it is very odd, see: https://github.com/KittyCAD/modeling-app/issues/5880
if let SolidOrSketchOrImportedGeometry::SolidSet(solids) = &objects {
args.flush_batch_for_solids(exec_state, solids).await?;
}
let mut objects = objects.clone(); let mut objects = objects.clone();
for object_id in objects.ids(&args.ctx).await? { for object_id in objects.ids(&args.ctx).await? {
let id = exec_state.next_uuid(); let id = exec_state.next_uuid();

View File

@ -0,0 +1,64 @@
/// Build a color from its red, green and blue components.
/// These must be between 0 and 255.
///
/// ```
/// startSketchOn(-XZ)
/// |> circle(center = [0, 0], radius = 10)
/// |> extrude(length = 4)
/// |> appearance(color = appearance::hexString([50, 160, 160]))
/// ```
/// ```
/// sideLen = 30
/// n = 10
///
/// // The cubes become more green and less blue with each instance.
/// fn cube(i, center) {
/// g = 255 / n * i
/// b = 255 / n * (n - i)
/// return startSketchOn(XY)
/// |> polygon(radius = sideLen / 2, numSides = 4, center = [center, 0])
/// |> extrude(length = sideLen)
/// |> appearance(color = appearance::hexString([0, g, b]), metalness = 80, roughness = 20)
/// }
///
/// // Create n cubes, shifting each one over in a line.
/// map(
/// [0..n],
/// f = fn(@i) {
/// return cube(i, center = sideLen * i * 1.5)
/// },
/// )
/// ```
/// ```
/// sideLen = 30
/// n = 6
///
/// fn cube(offset, i, red) {
/// x = floor(i / n)
/// y = rem(i, divisor = n)
/// g = 255 / n * x
/// b = 255 / n * y
/// return startSketchOn(offsetPlane(XZ, offset))
/// |> circle(diameter = sideLen, center = [sideLen * x * 1.5, sideLen * y * 1.5])
/// |> extrude(length = sideLen)
/// |> appearance(color = appearance::hexString([red, g, b]), metalness = 80, roughness = 40)
/// }
///
/// fn grid(offset, red) {
/// return map(
/// [0 ..< n * n],
/// f = fn(@i) {
/// return cube(offset, i, red)
/// },
/// )
/// }
///
/// grid(offset = 0, red = 0)
/// ```
///
@(impl = std_rust)
export fn hexString(
/// The red, blue and green components of the color.
/// Must be between 0 and 255.
@rgb: [number(_); 3],
): string {}

View File

@ -22,6 +22,7 @@ export import * from "std::solid"
export import * from "std::transform" export import * from "std::transform"
export import "std::turns" export import "std::turns"
export import "std::sweep" export import "std::sweep"
export import "std::appearance"
/// An abstract 3d plane aligned with the X and Y axes. Its normal is the positive Z axis. /// An abstract 3d plane aligned with the X and Y axes. Its normal is the positive Z axis.
export XY = { export XY = {

File diff suppressed because it is too large Load Diff

View File

@ -1,365 +0,0 @@
---
source: kcl-lib/src/simulation_tests.rs
description: Operations executed 80-20-rail.kcl
---
[
{
"type": "StdLibCall",
"name": "startSketchOn",
"unlabeledArg": {
"value": {
"type": "Plane",
"artifact_id": "[uuid]"
},
"sourceRange": []
},
"labeledArgs": {},
"sourceRange": []
},
{
"type": "StdLibCall",
"name": "subtract2d",
"unlabeledArg": {
"value": {
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
"sourceRange": []
},
"labeledArgs": {
"tool": {
"value": {
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
"sourceRange": []
}
},
"sourceRange": []
},
{
"type": "StdLibCall",
"name": "extrude",
"unlabeledArg": {
"value": {
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
"sourceRange": []
},
"labeledArgs": {
"length": {
"value": {
"type": "Number",
"value": 48.0,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
},
"sourceRange": []
}
},
"sourceRange": []
},
{
"type": "StdLibCall",
"name": "fillet",
"unlabeledArg": {
"value": {
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
"sourceRange": []
},
"labeledArgs": {
"radius": {
"value": {
"type": "Number",
"value": 0.06,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
},
"sourceRange": []
},
"tags": {
"value": {
"type": "Array",
"value": [
{
"type": "Uuid",
"value": "[uuid]"
},
{
"type": "Uuid",
"value": "[uuid]"
},
{
"type": "Uuid",
"value": "[uuid]"
},
{
"type": "Uuid",
"value": "[uuid]"
},
{
"type": "Uuid",
"value": "[uuid]"
},
{
"type": "Uuid",
"value": "[uuid]"
},
{
"type": "Uuid",
"value": "[uuid]"
},
{
"type": "Uuid",
"value": "[uuid]"
},
{
"type": "Uuid",
"value": "[uuid]"
},
{
"type": "Uuid",
"value": "[uuid]"
},
{
"type": "Uuid",
"value": "[uuid]"
},
{
"type": "Uuid",
"value": "[uuid]"
},
{
"type": "Uuid",
"value": "[uuid]"
},
{
"type": "Uuid",
"value": "[uuid]"
},
{
"type": "Uuid",
"value": "[uuid]"
},
{
"type": "Uuid",
"value": "[uuid]"
}
]
},
"sourceRange": []
}
},
"sourceRange": []
},
{
"type": "StdLibCall",
"name": "fillet",
"unlabeledArg": {
"value": {
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
"sourceRange": []
},
"labeledArgs": {
"radius": {
"value": {
"type": "Number",
"value": 0.03,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
},
"sourceRange": []
},
"tags": {
"value": {
"type": "Array",
"value": [
{
"type": "Uuid",
"value": "[uuid]"
},
{
"type": "Uuid",
"value": "[uuid]"
},
{
"type": "Uuid",
"value": "[uuid]"
},
{
"type": "Uuid",
"value": "[uuid]"
},
{
"type": "Uuid",
"value": "[uuid]"
},
{
"type": "Uuid",
"value": "[uuid]"
},
{
"type": "Uuid",
"value": "[uuid]"
},
{
"type": "Uuid",
"value": "[uuid]"
},
{
"type": "Uuid",
"value": "[uuid]"
},
{
"type": "Uuid",
"value": "[uuid]"
},
{
"type": "Uuid",
"value": "[uuid]"
},
{
"type": "Uuid",
"value": "[uuid]"
},
{
"type": "Uuid",
"value": "[uuid]"
},
{
"type": "Uuid",
"value": "[uuid]"
},
{
"type": "Uuid",
"value": "[uuid]"
},
{
"type": "Uuid",
"value": "[uuid]"
}
]
},
"sourceRange": []
}
},
"sourceRange": []
},
{
"type": "GroupBegin",
"group": {
"type": "FunctionCall",
"name": "rail8020",
"functionSourceRange": [],
"unlabeledArg": null,
"labeledArgs": {
"originStart": {
"value": {
"type": "Array",
"value": [
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
},
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
}
]
},
"sourceRange": []
},
"railHeight": {
"value": {
"type": "Number",
"value": 1.5,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
},
"sourceRange": []
},
"railLength": {
"value": {
"type": "Number",
"value": 48.0,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
},
"sourceRange": []
}
}
},
"sourceRange": []
},
{
"type": "GroupEnd"
}
]

View File

@ -1,10 +0,0 @@
---
source: kcl-lib/src/simulation_tests.rs
description: Variables in memory after executing 80-20-rail.kcl
---
{
"rail8020": {
"type": "Function",
"value": null
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

View File

@ -366,114 +366,114 @@ flowchart LR
11 ---- 74 11 ---- 74
26 --- 75 26 --- 75
26 x--> 108 26 x--> 108
26 --- 138 26 --- 131
26 --- 170 26 --- 163
27 --- 76 27 --- 76
27 x--> 108 27 x--> 108
27 --- 124 27 --- 132
27 --- 156 27 --- 164
28 --- 77 28 --- 77
28 x--> 108 28 x--> 108
28 --- 137 28 --- 116
28 --- 169 28 --- 148
29 --- 78 29 --- 78
29 x--> 108 29 x--> 108
29 --- 133 29 --- 134
29 --- 165 29 --- 166
30 --- 79 30 --- 79
30 x--> 108 30 x--> 108
30 --- 116 30 --- 120
30 --- 148 30 --- 152
31 --- 80 31 --- 80
31 x--> 108 31 x--> 108
31 --- 115 31 --- 136
31 --- 147 31 --- 168
32 --- 81 32 --- 81
32 x--> 108 32 x--> 108
32 --- 118 32 --- 123
32 --- 150 32 --- 155
33 --- 82 33 --- 82
33 x--> 108 33 x--> 108
33 --- 134 33 --- 129
33 --- 166 33 --- 161
34 --- 83 34 --- 83
34 x--> 108 34 x--> 108
34 --- 129 34 --- 114
34 --- 161 34 --- 146
35 --- 84 35 --- 84
35 x--> 108 35 x--> 108
35 --- 127 35 --- 117
35 --- 159 35 --- 149
36 --- 85 36 --- 85
36 x--> 108 36 x--> 108
36 --- 132 36 --- 115
36 --- 164 36 --- 147
37 --- 86 37 --- 86
37 x--> 108 37 x--> 108
37 --- 122 37 --- 126
37 --- 154 37 --- 158
38 --- 87 38 --- 87
38 x--> 108 38 x--> 108
38 --- 123 38 --- 130
38 --- 155 38 --- 162
39 --- 88 39 --- 88
39 x--> 108 39 x--> 108
39 --- 131 39 --- 122
39 --- 163 39 --- 154
40 --- 89 40 --- 89
40 x--> 108 40 x--> 108
40 --- 119 40 --- 127
40 --- 151 40 --- 159
41 --- 90 41 --- 90
41 x--> 108 41 x--> 108
41 --- 130 41 --- 125
41 --- 162 41 --- 157
42 --- 91 42 --- 91
42 x--> 108 42 x--> 108
42 --- 114 42 --- 135
42 --- 146 42 --- 167
43 --- 92 43 --- 92
43 x--> 108 43 x--> 108
43 --- 125 43 --- 119
43 --- 157 43 --- 151
44 --- 93 44 --- 93
44 x--> 108 44 x--> 108
44 --- 121 44 --- 118
44 --- 153 44 --- 150
45 --- 94 45 --- 94
45 x--> 108 45 x--> 108
45 --- 135 45 --- 121
45 --- 167 45 --- 153
46 --- 95 46 --- 95
46 x--> 108 46 x--> 108
46 --- 120 46 --- 138
46 --- 152 46 --- 170
47 --- 96 47 --- 96
47 x--> 108 47 x--> 108
47 --- 126 47 --- 128
47 --- 158 47 --- 160
48 --- 97 48 --- 97
48 x--> 108 48 x--> 108
48 --- 117 48 --- 133
48 --- 149 48 --- 165
49 --- 98 49 --- 98
49 x--> 108 49 x--> 108
49 --- 113 49 --- 137
49 --- 145 49 --- 169
50 --- 99 50 --- 99
50 x--> 108 50 x--> 108
50 --- 136 50 --- 139
50 --- 168 50 --- 171
51 --- 100 51 --- 100
51 x--> 108 51 x--> 108
51 --- 128 51 --- 124
51 --- 160 51 --- 156
52 --- 101 52 --- 101
52 x--> 108 52 x--> 108
52 --- 139 52 --- 113
52 --- 171 52 --- 145
61 --- 102 61 --- 102
61 x--> 109 61 x--> 110
61 --- 140 61 --- 140
61 --- 172 61 --- 172
63 --- 103 63 --- 103
@ -594,87 +594,87 @@ flowchart LR
74 --- 174 74 --- 174
74 --- 175 74 --- 175
74 --- 176 74 --- 176
75 --- 138 75 --- 131
75 --- 170 75 --- 163
171 <--x 75 164 <--x 75
76 --- 124 76 --- 132
76 --- 156 76 --- 164
157 <--x 76 165 <--x 76
77 --- 137 77 --- 116
77 --- 169 77 --- 148
170 <--x 77 149 <--x 77
78 --- 133 78 --- 134
78 --- 165 78 --- 166
166 <--x 78 167 <--x 78
79 --- 116 79 --- 120
79 --- 148 79 --- 152
149 <--x 79 153 <--x 79
80 --- 115 80 --- 136
80 --- 147 80 --- 168
148 <--x 80 169 <--x 80
81 --- 118 81 --- 123
81 --- 150 81 --- 155
151 <--x 81 156 <--x 81
82 --- 134 82 --- 129
82 --- 166 82 --- 161
167 <--x 82 162 <--x 82
83 --- 129 83 --- 114
83 --- 161 83 --- 146
162 <--x 83 147 <--x 83
84 --- 127 84 --- 117
84 --- 159 84 --- 149
160 <--x 84 150 <--x 84
85 --- 132 85 --- 115
85 --- 164 85 --- 147
165 <--x 85 148 <--x 85
86 --- 122 86 --- 126
86 --- 154 86 --- 158
155 <--x 86 159 <--x 86
87 --- 123 87 --- 130
87 --- 155 87 --- 162
156 <--x 87 163 <--x 87
88 --- 131 88 --- 122
88 --- 163 88 --- 154
164 <--x 88 155 <--x 88
89 --- 119 89 --- 127
89 --- 151 89 --- 159
152 <--x 89 160 <--x 89
90 --- 130 90 --- 125
90 --- 162 90 --- 157
163 <--x 90 158 <--x 90
91 --- 114 91 --- 135
91 --- 146 91 --- 167
147 <--x 91 168 <--x 91
92 --- 125 92 --- 119
92 --- 157 92 --- 151
158 <--x 92 152 <--x 92
93 --- 121 93 --- 118
93 --- 153 93 --- 150
154 <--x 93 151 <--x 93
94 --- 135 94 --- 121
94 --- 167 94 --- 153
168 <--x 94 154 <--x 94
95 --- 120 95 --- 138
95 --- 152 95 --- 170
153 <--x 95 171 <--x 95
96 --- 126 96 --- 128
96 --- 158 96 --- 160
159 <--x 96 161 <--x 96
97 --- 117 97 --- 133
97 --- 149 97 --- 165
150 <--x 97 166 <--x 97
98 --- 113 98 --- 137
98 --- 145 98 --- 169
146 <--x 98 170 <--x 98
99 --- 136 99 --- 139
99 --- 168 145 <--x 99
169 <--x 99 99 --- 171
100 --- 128 100 --- 124
100 --- 160 100 --- 156
161 <--x 100 157 <--x 100
101 --- 139 101 --- 113
145 <--x 101 101 --- 145
101 --- 171 146 <--x 101
102 --- 140 102 --- 140
102 --- 172 102 --- 172
103 --- 144 103 --- 144
@ -689,7 +689,7 @@ flowchart LR
106 --- 141 106 --- 141
106 --- 173 106 --- 173
174 <--x 106 174 <--x 106
140 <--x 110 140 <--x 109
141 <--x 111 141 <--x 111
142 <--x 111 142 <--x 111
143 <--x 111 143 <--x 111

View File

@ -111,9 +111,9 @@ flowchart LR
8 --- 19 8 --- 19
8 --- 20 8 --- 20
8 ---- 25 8 ---- 25
12 --- 32 12 <--x 32
12 <--x 33 12 <--x 33
12 <--x 34 12 --- 34
13 --- 31 13 --- 31
13 x--> 35 13 x--> 35
13 --- 39 13 --- 39

View File

@ -0,0 +1,620 @@
---
source: kcl-lib/src/simulation_tests.rs
description: Artifact commands t-slot-rail.kcl
---
[
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "edge_lines_visible",
"hidden": false
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "object_visible",
"object_id": "[uuid]",
"hidden": true
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "object_visible",
"object_id": "[uuid]",
"hidden": true
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "make_plane",
"origin": {
"x": 0.0,
"y": 0.0,
"z": 0.0
},
"x_axis": {
"x": 1.0,
"y": 0.0,
"z": 0.0
},
"y_axis": {
"x": 0.0,
"y": 0.0,
"z": 1.0
},
"size": 60.0,
"clobber": false,
"hide": true
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "enable_sketch_mode",
"entity_id": "[uuid]",
"ortho": false,
"animated": false,
"adjust_camera": false,
"planar_normal": {
"x": 0.0,
"y": -1.0,
"z": 0.0
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "move_path_pen",
"path": "[uuid]",
"to": {
"x": 12.7,
"y": 8.1788,
"z": 0.0
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "sketch_mode_disable"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "start_path"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "extend_path",
"path": "[uuid]",
"segment": {
"type": "line",
"end": {
"x": -2.032,
"y": 0.0,
"z": 0.0
},
"relative": true
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "extend_path",
"path": "[uuid]",
"segment": {
"type": "tangential_arc",
"radius": 2.2859999999999996,
"offset": {
"unit": "degrees",
"value": 45.0
}
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "extend_path",
"path": "[uuid]",
"segment": {
"type": "line",
"end": {
"x": 4.4125,
"y": 2.8702,
"z": 0.0
},
"relative": false
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "extend_path",
"path": "[uuid]",
"segment": {
"type": "tangential_arc",
"radius": 0.254,
"offset": {
"unit": "degrees",
"value": 135.0
}
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "extend_path",
"path": "[uuid]",
"segment": {
"type": "line",
"end": {
"x": 8.382,
"y": 2.4366,
"z": 0.0
},
"relative": false
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "extend_path",
"path": "[uuid]",
"segment": {
"type": "tangential_arc",
"radius": 0.254,
"offset": {
"unit": "degrees",
"value": -90.0
}
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "extend_path",
"path": "[uuid]",
"segment": {
"type": "line",
"end": {
"x": 8.636,
"y": 0.254,
"z": 0.0
},
"relative": false
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "extend_path",
"path": "[uuid]",
"segment": {
"type": "tangential_arc",
"radius": 0.254,
"offset": {
"unit": "degrees",
"value": -90.0
}
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "extend_path",
"path": "[uuid]",
"segment": {
"type": "line",
"end": {
"x": -0.762,
"y": 0.0,
"z": 0.0
},
"relative": true
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "extend_path",
"path": "[uuid]",
"segment": {
"type": "arc",
"center": {
"x": 7.1628,
"y": -0.0
},
"radius": 0.45719999999999994,
"start": {
"unit": "degrees",
"value": 0.0
},
"end": {
"unit": "degrees",
"value": 180.0
},
"relative": false
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "extend_path",
"path": "[uuid]",
"segment": {
"type": "line",
"end": {
"x": -2.54,
"y": 0.0,
"z": 0.0
},
"relative": true
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "extend_path",
"path": "[uuid]",
"segment": {
"type": "arc",
"center": {
"x": 3.7084,
"y": 0.0
},
"radius": 0.45719999999999994,
"start": {
"unit": "degrees",
"value": 0.0
},
"end": {
"unit": "degrees",
"value": 180.0
},
"relative": false
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "extend_path",
"path": "[uuid]",
"segment": {
"type": "line",
"end": {
"x": -0.762,
"y": 0.0,
"z": 0.0
},
"relative": true
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "extend_path",
"path": "[uuid]",
"segment": {
"type": "tangential_arc_to",
"to": {
"x": -1.7907,
"y": 0.6985,
"z": 0.0
},
"angle_snap_increment": null
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "entity_get_all_child_uuids",
"entity_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "entity_mirror",
"ids": [
"[uuid]"
],
"axis": {
"x": 25.4,
"y": 25.4,
"z": 0.0
},
"point": {
"x": 0.0,
"y": 0.0,
"z": 0.0
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "entity_get_all_child_uuids",
"entity_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "entity_mirror",
"ids": [
"[uuid]"
],
"axis": {
"x": 25.4,
"y": 0.0,
"z": 0.0
},
"point": {
"x": 0.0,
"y": 12.7,
"z": 0.0
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "entity_get_all_child_uuids",
"entity_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "entity_mirror",
"ids": [
"[uuid]"
],
"axis": {
"x": 0.0,
"y": 25.4,
"z": 0.0
},
"point": {
"x": 12.7,
"y": 0.0,
"z": 0.0
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "close_path",
"path_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "object_visible",
"object_id": "[uuid]",
"hidden": true
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid2d_add_hole",
"object_id": "[uuid]",
"hole_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "close_path",
"path_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "enable_sketch_mode",
"entity_id": "[uuid]",
"ortho": false,
"animated": false,
"adjust_camera": false,
"planar_normal": {
"x": 0.0,
"y": -1.0,
"z": 0.0
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "extend_path",
"path": "[uuid]",
"segment": {
"type": "arc",
"center": {
"x": 19.05,
"y": 19.05
},
"radius": 3.3274,
"start": {
"unit": "degrees",
"value": 0.0
},
"end": {
"unit": "degrees",
"value": 360.0
},
"relative": false
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "move_path_pen",
"path": "[uuid]",
"to": {
"x": 22.3774,
"y": 19.05,
"z": 0.0
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "sketch_mode_disable"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "start_path"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_object_transform",
"object_id": "[uuid]",
"transforms": [
{
"translate": null,
"rotate_rpy": null,
"rotate_angle_axis": null,
"scale": {
"property": {
"x": 1.5,
"y": 1.0,
"z": 1.5
},
"set": false,
"is_local": true
}
}
]
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "enable_sketch_mode",
"entity_id": "[uuid]",
"ortho": false,
"animated": false,
"adjust_camera": false,
"planar_normal": {
"x": 0.0,
"y": -1.0,
"z": 0.0
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "extrude",
"target": "[uuid]",
"distance": -609.5999999999999,
"faces": null,
"opposite": "None"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "object_bring_to_front",
"object_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "sketch_mode_disable"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_adjacency_info",
"object_id": "[uuid]",
"edge_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_extrusion_face_info",
"object_id": "[uuid]",
"edge_id": "[uuid]"
}
}
]

View File

@ -1,6 +1,6 @@
--- ---
source: kcl-lib/src/simulation_tests.rs source: kcl-lib/src/simulation_tests.rs
description: Artifact graph flowchart 80-20-rail.kcl description: Artifact graph flowchart t-slot-rail.kcl
extension: md extension: md
snapshot_kind: binary snapshot_kind: binary
--- ---

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,115 @@
---
source: kcl-lib/src/simulation_tests.rs
description: Operations executed t-slot-rail.kcl
---
[
{
"type": "StdLibCall",
"name": "startSketchOn",
"unlabeledArg": {
"value": {
"type": "Plane",
"artifact_id": "[uuid]"
},
"sourceRange": []
},
"labeledArgs": {},
"sourceRange": []
},
{
"type": "StdLibCall",
"name": "subtract2d",
"unlabeledArg": {
"value": {
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
"sourceRange": []
},
"labeledArgs": {
"tool": {
"value": {
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
"sourceRange": []
}
},
"sourceRange": []
},
{
"type": "StdLibCall",
"name": "extrude",
"unlabeledArg": {
"value": {
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
"sourceRange": []
},
"labeledArgs": {
"length": {
"value": {
"type": "Number",
"value": -2.0,
"ty": {
"type": "Known",
"type": "Length",
"type": "Feet"
}
},
"sourceRange": []
}
},
"sourceRange": []
},
{
"type": "GroupBegin",
"group": {
"type": "FunctionCall",
"name": "railTslot",
"functionSourceRange": [],
"unlabeledArg": null,
"labeledArgs": {
"railHeight": {
"value": {
"type": "Number",
"value": 1.5,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
},
"sourceRange": []
},
"railLength": {
"value": {
"type": "Number",
"value": 2.0,
"ty": {
"type": "Known",
"type": "Length",
"type": "Feet"
}
},
"sourceRange": []
}
}
},
"sourceRange": []
},
{
"type": "GroupEnd"
}
]

View File

@ -0,0 +1,62 @@
---
source: kcl-lib/src/simulation_tests.rs
description: Variables in memory after executing t-slot-rail.kcl
---
{
"arcEnd": {
"type": "Number",
"value": 0.0275,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
},
"holeDiameter": {
"type": "Number",
"value": 0.262,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
},
"interiorRadius": {
"type": "Number",
"value": 0.01,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
},
"railTslot": {
"type": "Function",
"value": null
},
"scoreDepth": {
"type": "Number",
"value": 0.018,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 190 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 190 KiB

View File

@ -139,7 +139,7 @@ flowchart LR
15 --- 42 15 --- 42
15 --- 49 15 --- 49
18 --- 32 18 --- 32
18 x--> 35 18 x--> 36
18 --- 43 18 --- 43
18 --- 50 18 --- 50
23 --- 26 23 --- 26
@ -194,5 +194,5 @@ flowchart LR
40 <--x 34 40 <--x 34
41 <--x 34 41 <--x 34
42 <--x 34 42 <--x 34
43 <--x 36 43 <--x 35
``` ```

View File

@ -87,11 +87,11 @@ flowchart LR
8 ---- 20 8 ---- 20
8 --- 21 8 --- 21
12 <--x 22 12 <--x 22
12 --- 23 12 <--x 23
12 <--x 24 12 --- 24
16 <--x 25 16 <--x 25
16 --- 26 16 <--x 26
16 <--x 27 16 --- 27
19 --- 22 19 --- 22
19 --- 23 19 --- 23
19 --- 24 19 --- 24

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

After

Width:  |  Height:  |  Size: 60 KiB

View File

@ -1,6 +1,6 @@
[package] [package]
name = "kcl-python-bindings" name = "kcl-python-bindings"
version = "0.3.76" version = "0.3.77"
edition = "2021" edition = "2021"
repository = "https://github.com/kittycad/modeling-app" repository = "https://github.com/kittycad/modeling-app"
exclude = ["tests/*", "files/*", "venv/*"] exclude = ["tests/*", "files/*", "venv/*"]

View File

@ -1,7 +1,7 @@
[package] [package]
name = "kcl-test-server" name = "kcl-test-server"
description = "A test server for KCL" description = "A test server for KCL"
version = "0.1.76" version = "0.1.77"
edition = "2021" edition = "2021"
license = "MIT" license = "MIT"

View File

@ -1,7 +1,7 @@
[package] [package]
name = "kcl-to-core" name = "kcl-to-core"
description = "Utility methods to convert kcl to engine core executable tests" description = "Utility methods to convert kcl to engine core executable tests"
version = "0.1.76" version = "0.1.77"
edition = "2021" edition = "2021"
license = "MIT" license = "MIT"
repository = "https://github.com/KittyCAD/modeling-app" repository = "https://github.com/KittyCAD/modeling-app"

View File

@ -1,6 +1,6 @@
[package] [package]
name = "kcl-wasm-lib" name = "kcl-wasm-lib"
version = "0.1.76" version = "0.1.77"
edition = "2021" edition = "2021"
repository = "https://github.com/KittyCAD/modeling-app" repository = "https://github.com/KittyCAD/modeling-app"
rust-version = "1.83" rust-version = "1.83"

View File

@ -43,6 +43,7 @@ import {
uuidv4, uuidv4,
} from '@src/lib/utils' } from '@src/lib/utils'
import { deg2Rad } from '@src/lib/utils2d' import { deg2Rad } from '@src/lib/utils2d'
import type { SettingsType } from '@src/lib/settings/initialSettings'
const ORTHOGRAPHIC_CAMERA_SIZE = 20 const ORTHOGRAPHIC_CAMERA_SIZE = 20
const FRAMES_TO_ANIMATE_IN = 30 const FRAMES_TO_ANIMATE_IN = 30
@ -124,6 +125,8 @@ export class CameraControls {
interactionGuards: MouseGuard = cameraMouseDragGuards.Zoo interactionGuards: MouseGuard = cameraMouseDragGuards.Zoo
isFovAnimationInProgress = false isFovAnimationInProgress = false
perspectiveFovBeforeOrtho = 45 perspectiveFovBeforeOrtho = 45
// TODO: proper dependency injection
getSettings: (() => SettingsType) | null = null
// NOTE: Duplicated state across Provider and singleton. Mapped from settingsMachine // NOTE: Duplicated state across Provider and singleton. Mapped from settingsMachine
_setting_allowOrbitInSketchMode = false _setting_allowOrbitInSketchMode = false
@ -964,8 +967,50 @@ export class CameraControls {
}) })
} }
/**
* A helper function that will override this.oldCameraState
* with the current setting's camera projection. If these are desynced
* that is okay but when the camera restores we want the user to be in the correct
* camera projection which is the settings value. Not this old state.
*
* Gotcha: This is not to be confused with Named Views, those have correct state.
*/
overrideOldCameraStateToPreventDesync() {
if (!this.getSettings) {
return
}
// Engine idle disconnection happened, we saved off the camera state
// If the settings camera projection is different from the saved camera state we need to override it.
const settings = this.getSettings()
const cameraProjection = settings.modeling.cameraProjection.current
const isOrtho = cameraProjection === 'orthographic' ? true : false
if (this.oldCameraState) {
// Leave a log to know when this desyncs
console.log(`restoring camera projection setting:${cameraProjection}`)
console.log(
`oldCameraState projection:${isOrtho ? 'orthographic' : 'perspective'}, ortho_scaled_enabled:${this.oldCameraState.ortho_scale_enabled}`
)
if (this.oldCameraState.is_ortho !== isOrtho) {
console.log(
'oldCameraState is_ortho desynced',
this.oldCameraState.is_ortho,
isOrtho
)
}
this.oldCameraState.is_ortho = isOrtho
// Always keep this enabled!
this.oldCameraState.ortho_scale_enabled = true
}
}
async restoreRemoteCameraStateAndTriggerSync() { async restoreRemoteCameraStateAndTriggerSync() {
if (this.oldCameraState) { if (this.oldCameraState) {
// Always write settings.modeling.cameraProjection to the restored camera view
this.overrideOldCameraStateToPreventDesync()
await this.engineCommandManager.sendSceneCommand({ await this.engineCommandManager.sendSceneCommand({
type: 'modeling_cmd_req', type: 'modeling_cmd_req',
cmd_id: uuidv4(), cmd_id: uuidv4(),

View File

@ -1,5 +1,5 @@
[ [
"80-20-rail", "t-slot-rail",
"parametric-bearing-pillow-block", "parametric-bearing-pillow-block",
"ball-bearing", "ball-bearing",
"bracket", "bracket",

View File

@ -206,6 +206,11 @@ export const getSettings = () => {
const { currentProject: _, ...settings } = settingsActor.getSnapshot().context const { currentProject: _, ...settings } = settingsActor.getSnapshot().context
return settings return settings
} }
// These are all late binding because of their circular dependency.
// TODO: proper dependency injection.
sceneInfra.camControls.getSettings = getSettings
export const useSettings = () => export const useSettings = () =>
useSelector(settingsActor, (state) => { useSelector(settingsActor, (state) => {
// We have to peel everything that isn't settings off // We have to peel everything that isn't settings off

View File

@ -15,7 +15,7 @@ import {
SystemIOMachineEvents, SystemIOMachineEvents,
waitForIdleState, waitForIdleState,
} from '@src/machines/systemIO/utils' } from '@src/machines/systemIO/utils'
import { reportRejection } from '@src/lib/trap' import { err, reportRejection } from '@src/lib/trap'
import { toSync } from '@src/lib/utils' import { toSync } from '@src/lib/utils'
import { getAllSubDirectoriesAtProjectRoot } from '@src/machines/systemIO/snapshotContext' import { getAllSubDirectoriesAtProjectRoot } from '@src/machines/systemIO/snapshotContext'
import { joinOSPaths } from '@src/lib/paths' import { joinOSPaths } from '@src/lib/paths'
@ -120,12 +120,15 @@ export async function submitAndAwaitTextToKclSystemIO({
return value return value
}) })
.catch((error) => { .catch((error) => {
showFailureToast('Failed to submit to Text-to-CAD API') const message = err(error)
? error.message
: 'Failed to submit to Text-to-CAD API'
showFailureToast(message)
return error return error
}) })
if (textToCadQueued instanceof Error) { if (err(textToCadQueued)) {
showFailureToast('Failed to submit to Text-to-CAD API') showFailureToast(textToCadQueued.message)
return return
} }

View File

@ -29,7 +29,7 @@ export function isErr<T>(value: ExcludeErr<T> | Error): value is Error {
return value instanceof Error return value instanceof Error
} }
// Used to bubble errors up /** Used to bubble errors up */
export function err<T>(value: ExcludeErr<T> | Error): value is Error { export function err<T>(value: ExcludeErr<T> | Error): value is Error {
if (!isErr(value)) { if (!isErr(value)) {
return false return false

View File

@ -648,7 +648,8 @@ export async function engineViewIsometricWithoutGeometryPresent({
fov_y: 45, fov_y: 45,
ortho_scale_factor: 1.4063792, ortho_scale_factor: 1.4063792,
is_ortho: cameraProjection !== 'perspective', is_ortho: cameraProjection !== 'perspective',
ortho_scale_enabled: cameraProjection !== 'perspective', // always keep this enabled
ortho_scale_enabled: true,
world_coord_system: 'right_handed_up_z', world_coord_system: 'right_handed_up_z',
} }
await engineCommandManager.sendSceneCommand({ await engineCommandManager.sendSceneCommand({