Compare commits
5 Commits
pierremtb/
...
kcl-59
Author | SHA1 | Date | |
---|---|---|---|
6d50278d34 | |||
35844842de | |||
843e772094 | |||
9d0518dfeb | |||
d33d399c31 |
2
.github/workflows/build-apps.yml
vendored
@ -378,7 +378,7 @@ jobs:
|
||||
NOTES: ${{ needs.prepare-files.outputs.notes }}
|
||||
PUB_DATE: ${{ github.event.repository.updated_at }}
|
||||
WEBSITE_DIR: ${{ env.IS_NIGHTLY == 'true' && 'dl.zoo.dev/releases/modeling-app/nightly' || 'dl.zoo.dev/releases/modeling-app' }}
|
||||
URL_CODED_NAME: ${{ env.IS_NIGHTLY == 'true' && 'Zoo%20Modeling%20App%20%28Nightly%29' || 'Zoo%20Modeling%20App' }}
|
||||
URL_CODED_NAME: ${{ env.IS_NIGHTLY == 'true' && 'Zoo%20Design%20Studio%20%28Nightly%29' || 'Zoo%20Design%20Studio' }}
|
||||
run: |
|
||||
RELEASE_DIR=https://${WEBSITE_DIR}
|
||||
jq --null-input \
|
||||
|
1
.gitignore
vendored
@ -26,6 +26,7 @@ yarn-error.log*
|
||||
.idea
|
||||
.vscode
|
||||
.helix
|
||||
result
|
||||
|
||||
# rust
|
||||
rust/target
|
||||
|
@ -77,6 +77,7 @@ layout: manual
|
||||
* [`helix`](kcl/std-helix)
|
||||
* [`hole`](kcl/hole)
|
||||
* [`hollow`](kcl/hollow)
|
||||
* [`intersect`](kcl/intersect)
|
||||
* [`lastSegX`](kcl/lastSegX)
|
||||
* [`lastSegY`](kcl/lastSegY)
|
||||
* [`legAngX`](kcl/legAngX)
|
||||
@ -123,6 +124,7 @@ layout: manual
|
||||
* [`sqrt`](kcl/sqrt)
|
||||
* [`startProfileAt`](kcl/startProfileAt)
|
||||
* [`startSketchOn`](kcl/startSketchOn)
|
||||
* [`subtract`](kcl/subtract)
|
||||
* [`sweep`](kcl/sweep)
|
||||
* [`tangentToEnd`](kcl/tangentToEnd)
|
||||
* [`tangentialArc`](kcl/tangentialArc)
|
||||
@ -131,6 +133,7 @@ layout: manual
|
||||
* [`toDegrees`](kcl/toDegrees)
|
||||
* [`toRadians`](kcl/toRadians)
|
||||
* [`translate`](kcl/translate)
|
||||
* [`union`](kcl/union)
|
||||
* [`xLine`](kcl/xLine)
|
||||
* [`yLine`](kcl/yLine)
|
||||
* **std::math**
|
||||
|
4811
docs/kcl/std.json
@ -99,7 +99,6 @@ export class HomePageFixture {
|
||||
createAndGoToProject = async (projectTitle = 'untitled') => {
|
||||
await this.projectsLoaded()
|
||||
await this.projectButtonNew.click()
|
||||
await this.projectTextName.click()
|
||||
await this.projectTextName.fill(projectTitle)
|
||||
await this.projectButtonContinue.click()
|
||||
}
|
||||
|
@ -233,7 +233,7 @@ export class SceneFixture {
|
||||
settled = async (cmdBar: CmdBarFixture) => {
|
||||
const u = await getUtils(this.page)
|
||||
|
||||
await expect(this.startEditSketchBtn).not.toBeDisabled()
|
||||
await expect(this.startEditSketchBtn).not.toBeDisabled({ timeout: 15_000 })
|
||||
await expect(this.startEditSketchBtn).toBeVisible()
|
||||
|
||||
await cmdBar.openCmdBar()
|
||||
|
@ -68,12 +68,10 @@ test.describe('edit with AI example snapshots', () => {
|
||||
body1CapCoords.x,
|
||||
body1CapCoords.y
|
||||
)
|
||||
const yellow: [number, number, number] = [179, 179, 131]
|
||||
const submittingToast = page.getByText('Submitting to Text-to-CAD API...')
|
||||
|
||||
await test.step('wait for scene to load select body and check selection came through', async () => {
|
||||
await clickBody1Cap()
|
||||
await scene.expectPixelColor(yellow, body1CapCoords, 20)
|
||||
await editor.expectState({
|
||||
highlightedCode: '',
|
||||
activeLines: ['|>startProfileAt([-73.64,-42.89],%)'],
|
||||
|
@ -588,6 +588,7 @@ test(
|
||||
'Draft circle should look right',
|
||||
{ tag: '@snapshot' },
|
||||
async ({ page, context, cmdBar, scene }) => {
|
||||
test.fixme(orRunWhenFullSuiteEnabled())
|
||||
const u = await getUtils(page)
|
||||
await page.setViewportSize({ width: 1200, height: 500 })
|
||||
const PUR = 400 / 37.5 //pixeltoUnitRatio
|
||||
|
15
e2e/playwright/stress-test.spec.ts
Normal file
@ -0,0 +1,15 @@
|
||||
import { createProject } from '@e2e/playwright/test-utils'
|
||||
import { test } from '@e2e/playwright/zoo-test'
|
||||
|
||||
test.describe('Stress test', () => {
|
||||
test('Create project and load stress test', async ({
|
||||
cmdBar,
|
||||
scene,
|
||||
page,
|
||||
}, testInfo) => {
|
||||
const projectName = 'stress-test-project'
|
||||
// Create and load project
|
||||
await createProject({ name: projectName, page })
|
||||
await scene.settled(cmdBar)
|
||||
})
|
||||
})
|
41
flake.lock
generated
@ -1,6 +1,40 @@
|
||||
{
|
||||
"nodes": {
|
||||
"naersk": {
|
||||
"inputs": {
|
||||
"nixpkgs": "nixpkgs"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1743800763,
|
||||
"narHash": "sha256-YFKV+fxEpMgP5VsUcM6Il28lI0NlpM7+oB1XxbBAYCw=",
|
||||
"owner": "nix-community",
|
||||
"repo": "naersk",
|
||||
"rev": "ed0232117731a4c19d3ee93aa0c382a8fe754b01",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-community",
|
||||
"repo": "naersk",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1744096231,
|
||||
"narHash": "sha256-kUfx3FKU1Etnua3EaKvpeuXs7zoFiAcli1gBwkPvGSs=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "b2b0718004cc9a5bca610326de0a82e6ea75920b",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixpkgs-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs_2": {
|
||||
"locked": {
|
||||
"lastModified": 1736320768,
|
||||
"narHash": "sha256-nIYdTAiKIGnFNugbomgBJR+Xv5F1ZQU+HfaBqJKroC0=",
|
||||
@ -16,7 +50,7 @@
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs_2": {
|
||||
"nixpkgs_3": {
|
||||
"locked": {
|
||||
"lastModified": 1728538411,
|
||||
"narHash": "sha256-f0SBJz1eZ2yOuKUr5CA9BHULGXVSn6miBuUWdTyhUhU=",
|
||||
@ -34,13 +68,14 @@
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"nixpkgs": "nixpkgs",
|
||||
"naersk": "naersk",
|
||||
"nixpkgs": "nixpkgs_2",
|
||||
"rust-overlay": "rust-overlay"
|
||||
}
|
||||
},
|
||||
"rust-overlay": {
|
||||
"inputs": {
|
||||
"nixpkgs": "nixpkgs_2"
|
||||
"nixpkgs": "nixpkgs_3"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1736476219,
|
||||
|
142
flake.nix
@ -1,84 +1,104 @@
|
||||
{
|
||||
description = "modeling-app development environment";
|
||||
description = "zoo.dev modeling-app";
|
||||
|
||||
# Flake inputs
|
||||
inputs = {
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
|
||||
rust-overlay.url = "github:oxalica/rust-overlay"; # A helper for Rust + Nix
|
||||
rust-overlay.url = "github:oxalica/rust-overlay";
|
||||
naersk.url = "github:nix-community/naersk";
|
||||
};
|
||||
|
||||
# Flake outputs
|
||||
outputs = { self, nixpkgs, rust-overlay }:
|
||||
let
|
||||
# Overlays enable you to customize the Nixpkgs attribute set
|
||||
overlays = [
|
||||
# Makes a `rust-bin` attribute available in Nixpkgs
|
||||
(import rust-overlay)
|
||||
# Provides a `rustToolchain` attribute for Nixpkgs that we can use to
|
||||
# create a Rust environment
|
||||
(self: super: {
|
||||
rustToolchain = super. rust-bin.stable.latest.default.override {
|
||||
targets = [ "wasm32-unknown-unknown" ];
|
||||
extensions = [ "rustfmt" "llvm-tools-preview" "rust-src" ];
|
||||
outputs = {
|
||||
self,
|
||||
nixpkgs,
|
||||
rust-overlay,
|
||||
naersk,
|
||||
}: let
|
||||
overlays = [
|
||||
(import rust-overlay)
|
||||
(self: super: {
|
||||
rustToolchain = super.rust-bin.stable.latest.default.override {
|
||||
targets = ["wasm32-unknown-unknown"];
|
||||
extensions = ["rustfmt" "llvm-tools-preview" "rust-src"];
|
||||
};
|
||||
})
|
||||
(self: super: {
|
||||
cargo-llvm-cov = super.cargo-llvm-cov.overrideAttrs (oa: {
|
||||
doCheck = false;
|
||||
doInstallCheck = false;
|
||||
});
|
||||
})
|
||||
];
|
||||
|
||||
allSystems = [
|
||||
"x86_64-linux"
|
||||
"aarch64-linux"
|
||||
"x86_64-darwin"
|
||||
"aarch64-darwin"
|
||||
];
|
||||
|
||||
forAllSystems = f:
|
||||
nixpkgs.lib.genAttrs allSystems (system:
|
||||
f {
|
||||
pkgs = import nixpkgs {
|
||||
inherit overlays system;
|
||||
config.allowBroken = true;
|
||||
};
|
||||
})
|
||||
(self: super: {
|
||||
cargo-llvm-cov = super.cargo-llvm-cov.overrideAttrs(oa: {
|
||||
doCheck = false; doInstallCheck = false;
|
||||
});
|
||||
})
|
||||
];
|
||||
|
||||
# Systems supported
|
||||
allSystems = [
|
||||
"x86_64-linux" # 64-bit Intel/AMD Linux
|
||||
"aarch64-linux" # 64-bit ARM Linux
|
||||
"x86_64-darwin" # 64-bit Intel macOS
|
||||
"aarch64-darwin" # 64-bit ARM macOS
|
||||
];
|
||||
|
||||
# Helper to provide system-specific attributes
|
||||
forAllSystems = f: nixpkgs.lib.genAttrs allSystems (system: f {
|
||||
pkgs = import nixpkgs { inherit overlays system; config.allowBroken = true; };
|
||||
});
|
||||
|
||||
in
|
||||
{
|
||||
# Development environment output
|
||||
devShells = forAllSystems ({ pkgs }: {
|
||||
default = pkgs.mkShell {
|
||||
# The Nix packages provided in the environment
|
||||
packages = (with pkgs; [
|
||||
# The package provided by our custom overlay. Includes cargo, Clippy, cargo-fmt,
|
||||
# rustdoc, rustfmt, and other tools.
|
||||
system = system;
|
||||
});
|
||||
in {
|
||||
devShells = forAllSystems ({pkgs, ...}: {
|
||||
default = pkgs.mkShell {
|
||||
packages =
|
||||
(with pkgs; [
|
||||
rustToolchain
|
||||
|
||||
cargo-llvm-cov
|
||||
cargo-nextest
|
||||
|
||||
just
|
||||
postgresql.lib
|
||||
openssl
|
||||
pkg-config
|
||||
|
||||
nodejs_22
|
||||
yarn
|
||||
|
||||
electron
|
||||
playwright-driver.browsers
|
||||
]) ++ pkgs.lib.optionals pkgs.stdenv.isDarwin (with pkgs; [
|
||||
wasm-pack
|
||||
python3Full
|
||||
])
|
||||
++ pkgs.lib.optionals pkgs.stdenv.isDarwin (with pkgs; [
|
||||
libiconv
|
||||
darwin.apple_sdk.frameworks.Security
|
||||
]);
|
||||
|
||||
TARGET_CC = "${pkgs.stdenv.cc}/bin/${pkgs.stdenv.cc.targetPrefix}cc";
|
||||
LIBCLANG_PATH = "${pkgs.libclang.lib}/lib";
|
||||
ELECTRON_OVERRIDE_DIST_PATH = "${pkgs.electron}/bin/";
|
||||
PLAYWRIGHT_SKIP_VALIDATE_HOST_REQUIREMENTS = true;
|
||||
PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH = "${pkgs.playwright-driver.browsers}/chromium-1091/chrome-linux/chrome";
|
||||
PLAYWRIGHT_BROWSERS_PATH = "${pkgs.playwright-driver.browsers}";
|
||||
NODE_ENV = "development";
|
||||
};
|
||||
});
|
||||
};
|
||||
TARGET_CC = "${pkgs.stdenv.cc}/bin/${pkgs.stdenv.cc.targetPrefix}cc";
|
||||
LIBCLANG_PATH = "${pkgs.libclang.lib}/lib";
|
||||
ELECTRON_OVERRIDE_DIST_PATH = "${pkgs.electron}/bin/";
|
||||
PLAYWRIGHT_SKIP_VALIDATE_HOST_REQUIREMENTS = true;
|
||||
PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH = "${pkgs.playwright-driver.browsers}/chromium-1091/chrome-linux/chrome";
|
||||
PLAYWRIGHT_BROWSERS_PATH = "${pkgs.playwright-driver.browsers}";
|
||||
NODE_ENV = "development";
|
||||
};
|
||||
});
|
||||
|
||||
packages = forAllSystems ({
|
||||
pkgs,
|
||||
system,
|
||||
}: let
|
||||
naersk-lib = pkgs.callPackage naersk {
|
||||
cargo = pkgs.rustToolchain;
|
||||
rustc = pkgs.rustToolchain;
|
||||
};
|
||||
in {
|
||||
kcl-language-server = naersk-lib.buildPackage {
|
||||
pname = "kcl-language-server";
|
||||
version = "0.1.0";
|
||||
release = true;
|
||||
|
||||
src = ./rust;
|
||||
|
||||
cargoBuildOptions = opt: opt ++ ["-p" "kcl-language-server"];
|
||||
buildInputs = [pkgs.openssl pkgs.pkg-config];
|
||||
};
|
||||
default = self.packages.${system}.kcl-language-server;
|
||||
});
|
||||
};
|
||||
}
|
||||
|
24
rust/Cargo.lock
generated
@ -1780,7 +1780,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "kcl-bumper"
|
||||
version = "0.1.58"
|
||||
version = "0.1.59"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"clap",
|
||||
@ -1791,7 +1791,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "kcl-derive-docs"
|
||||
version = "0.1.58"
|
||||
version = "0.1.59"
|
||||
dependencies = [
|
||||
"Inflector",
|
||||
"anyhow",
|
||||
@ -1810,7 +1810,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "kcl-directory-test-macro"
|
||||
version = "0.1.58"
|
||||
version = "0.1.59"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -1819,7 +1819,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "kcl-language-server"
|
||||
version = "0.2.58"
|
||||
version = "0.2.59"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"clap",
|
||||
@ -1840,7 +1840,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "kcl-language-server-release"
|
||||
version = "0.1.58"
|
||||
version = "0.1.59"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"clap",
|
||||
@ -1860,7 +1860,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "kcl-lib"
|
||||
version = "0.2.58"
|
||||
version = "0.2.59"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"approx 0.5.1",
|
||||
@ -1928,7 +1928,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "kcl-python-bindings"
|
||||
version = "0.3.58"
|
||||
version = "0.3.59"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"kcl-lib",
|
||||
@ -1943,7 +1943,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "kcl-test-server"
|
||||
version = "0.1.58"
|
||||
version = "0.1.59"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"hyper 0.14.32",
|
||||
@ -1956,7 +1956,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "kcl-to-core"
|
||||
version = "0.1.58"
|
||||
version = "0.1.59"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
@ -1970,7 +1970,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "kcl-wasm-lib"
|
||||
version = "0.1.58"
|
||||
version = "0.1.59"
|
||||
dependencies = [
|
||||
"bson",
|
||||
"console_error_panic_hook",
|
||||
@ -2033,9 +2033,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "kittycad-modeling-cmds"
|
||||
version = "0.2.110"
|
||||
version = "0.2.112"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bdfd16800a12a2eaefff53958bd871875c246e669274269f7caefc25d19641ad"
|
||||
checksum = "08f06b4eb4e98ded7cda21586347baeb8055c4898f609f55f7c544cfed2b229c"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"chrono",
|
||||
|
@ -36,7 +36,7 @@ dashmap = { version = "6.1.0" }
|
||||
http = "1"
|
||||
indexmap = "2.7.0"
|
||||
kittycad = { version = "0.3.36", default-features = false, features = ["js", "requests"] }
|
||||
kittycad-modeling-cmds = { version = "0.2.110", features = ["ts-rs", "websocket"] }
|
||||
kittycad-modeling-cmds = { version = "0.2.112", features = ["ts-rs", "websocket"] }
|
||||
lazy_static = "1.5.0"
|
||||
miette = "7.5.0"
|
||||
pyo3 = { version = "0.24.0" }
|
||||
|
@ -1,7 +1,7 @@
|
||||
|
||||
[package]
|
||||
name = "kcl-bumper"
|
||||
version = "0.1.58"
|
||||
version = "0.1.59"
|
||||
edition = "2021"
|
||||
repository = "https://github.com/KittyCAD/modeling-api"
|
||||
rust-version = "1.76"
|
||||
|
@ -1,7 +1,7 @@
|
||||
[package]
|
||||
name = "kcl-derive-docs"
|
||||
description = "A tool for generating documentation from Rust derive macros"
|
||||
version = "0.1.58"
|
||||
version = "0.1.59"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
repository = "https://github.com/KittyCAD/modeling-app"
|
||||
|
@ -1,7 +1,7 @@
|
||||
[package]
|
||||
name = "kcl-directory-test-macro"
|
||||
description = "A tool for generating tests from a directory of kcl files"
|
||||
version = "0.1.58"
|
||||
version = "0.1.59"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
repository = "https://github.com/KittyCAD/modeling-app"
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "kcl-language-server-release"
|
||||
version = "0.1.58"
|
||||
version = "0.1.59"
|
||||
edition = "2021"
|
||||
authors = ["KittyCAD Inc <kcl@kittycad.io>"]
|
||||
publish = false
|
||||
|
@ -2,7 +2,7 @@
|
||||
name = "kcl-language-server"
|
||||
description = "A language server for KCL."
|
||||
authors = ["KittyCAD Inc <kcl@kittycad.io>"]
|
||||
version = "0.2.58"
|
||||
version = "0.2.59"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
@ -1,7 +1,7 @@
|
||||
[package]
|
||||
name = "kcl-lib"
|
||||
description = "KittyCAD Language implementation and tools"
|
||||
version = "0.2.58"
|
||||
version = "0.2.59"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
repository = "https://github.com/KittyCAD/modeling-app"
|
||||
@ -103,7 +103,7 @@ tokio-tungstenite = { version = "0.24.0", features = [
|
||||
tower-lsp = { workspace = true, features = ["proposed", "default"] }
|
||||
|
||||
[features]
|
||||
default = ["engine"]
|
||||
default = ["cli", "engine"]
|
||||
cli = ["dep:clap", "kittycad/clap"]
|
||||
dhat-heap = ["dep:dhat"]
|
||||
# For the lsp server, when run with stdout for rpc we want to disable println.
|
||||
|
@ -20,7 +20,6 @@ pub(crate) const SETTINGS_UNIT_ANGLE: &str = "defaultAngleUnit";
|
||||
pub(super) const NO_PRELUDE: &str = "no_std";
|
||||
|
||||
pub(super) const IMPORT_FORMAT: &str = "format";
|
||||
pub(super) const IMPORT_FORMAT_VALUES: [&str; 9] = ["fbx", "gltf", "glb", "obj", "ply", "sldprt", "stp", "step", "stl"];
|
||||
pub(super) const IMPORT_COORDS: &str = "coords";
|
||||
pub(super) const IMPORT_COORDS_VALUES: [(&str, &System); 3] =
|
||||
[("zoo", KITTYCAD), ("opengl", OPENGL), ("vulkan", VULKAN)];
|
||||
|
@ -939,25 +939,40 @@ impl Node<BinaryExpression> {
|
||||
if self.operator == BinaryOperator::Add || self.operator == BinaryOperator::Or {
|
||||
if let (KclValue::Solid { value: left }, KclValue::Solid { value: right }) = (&left_value, &right_value) {
|
||||
let args = crate::std::Args::new(Default::default(), self.into(), ctx.clone(), None);
|
||||
let result =
|
||||
crate::std::csg::inner_union(vec![*left.clone(), *right.clone()], exec_state, args).await?;
|
||||
let result = crate::std::csg::inner_union(
|
||||
vec![*left.clone(), *right.clone()],
|
||||
Default::default(),
|
||||
exec_state,
|
||||
args,
|
||||
)
|
||||
.await?;
|
||||
return Ok(result.into());
|
||||
}
|
||||
} else if self.operator == BinaryOperator::Sub {
|
||||
// Check if we have solids.
|
||||
if let (KclValue::Solid { value: left }, KclValue::Solid { value: right }) = (&left_value, &right_value) {
|
||||
let args = crate::std::Args::new(Default::default(), self.into(), ctx.clone(), None);
|
||||
let result =
|
||||
crate::std::csg::inner_subtract(vec![*left.clone()], vec![*right.clone()], exec_state, args)
|
||||
.await?;
|
||||
let result = crate::std::csg::inner_subtract(
|
||||
vec![*left.clone()],
|
||||
vec![*right.clone()],
|
||||
Default::default(),
|
||||
exec_state,
|
||||
args,
|
||||
)
|
||||
.await?;
|
||||
return Ok(result.into());
|
||||
}
|
||||
} else if self.operator == BinaryOperator::And {
|
||||
// Check if we have solids.
|
||||
if let (KclValue::Solid { value: left }, KclValue::Solid { value: right }) = (&left_value, &right_value) {
|
||||
let args = crate::std::Args::new(Default::default(), self.into(), ctx.clone(), None);
|
||||
let result =
|
||||
crate::std::csg::inner_intersect(vec![*left.clone(), *right.clone()], exec_state, args).await?;
|
||||
let result = crate::std::csg::inner_intersect(
|
||||
vec![*left.clone(), *right.clone()],
|
||||
Default::default(),
|
||||
exec_state,
|
||||
args,
|
||||
)
|
||||
.await?;
|
||||
return Ok(result.into());
|
||||
}
|
||||
}
|
||||
|
@ -173,7 +173,7 @@ pub(super) fn format_from_annotations(
|
||||
KclError::Semantic(KclErrorDetails {
|
||||
message: format!(
|
||||
"Unknown format for import, expected one of: {}",
|
||||
annotations::IMPORT_FORMAT_VALUES.join(", ")
|
||||
crate::IMPORT_FILE_EXTENSIONS.join(", ")
|
||||
),
|
||||
source_ranges: vec![p.as_source_range()],
|
||||
})
|
||||
|
@ -131,11 +131,36 @@ pub mod pretty {
|
||||
pub use crate::{parsing::token::NumericSuffix, unparser::format_number};
|
||||
}
|
||||
|
||||
#[cfg(feature = "cli")]
|
||||
use clap::ValueEnum;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[allow(unused_imports)]
|
||||
use crate::log::{log, logln};
|
||||
|
||||
lazy_static::lazy_static! {
|
||||
|
||||
pub static ref IMPORT_FILE_EXTENSIONS: Vec<String> = {
|
||||
let mut import_file_extensions = vec!["stp".to_string(), "glb".to_string(), "fbxb".to_string()];
|
||||
#[cfg(feature = "cli")]
|
||||
let named_extensions = kittycad::types::FileImportFormat::value_variants()
|
||||
.iter()
|
||||
.map(|x| format!("{}", x))
|
||||
.collect::<Vec<String>>();
|
||||
#[cfg(not(feature = "cli"))]
|
||||
let named_extensions = vec![]; // We don't really need this outside of the CLI.
|
||||
// Add all the default import formats.
|
||||
import_file_extensions.extend_from_slice(&named_extensions);
|
||||
import_file_extensions
|
||||
};
|
||||
|
||||
pub static ref RELEVANT_FILE_EXTENSIONS: Vec<String> = {
|
||||
let mut relevant_extensions = IMPORT_FILE_EXTENSIONS.clone();
|
||||
relevant_extensions.push("kcl".to_string());
|
||||
relevant_extensions
|
||||
};
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
pub struct Program {
|
||||
#[serde(flatten)]
|
||||
|
@ -35,7 +35,7 @@ use crate::{
|
||||
token::{Token, TokenSlice, TokenType},
|
||||
PIPE_OPERATOR, PIPE_SUBSTITUTION_OPERATOR,
|
||||
},
|
||||
SourceRange,
|
||||
SourceRange, IMPORT_FILE_EXTENSIONS,
|
||||
};
|
||||
|
||||
thread_local! {
|
||||
@ -1843,8 +1843,6 @@ fn import_stmt(i: &mut TokenSlice) -> PResult<BoxNode<ImportStatement>> {
|
||||
))
|
||||
}
|
||||
|
||||
const FOREIGN_IMPORT_EXTENSIONS: [&str; 8] = ["fbx", "gltf", "glb", "obj", "ply", "sldprt", "step", "stl"];
|
||||
|
||||
/// Validates the path string in an `import` statement.
|
||||
///
|
||||
/// `var_name` is `true` if the path will be used as a variable name.
|
||||
@ -1909,12 +1907,11 @@ fn validate_path_string(path_string: String, var_name: bool, path_range: SourceR
|
||||
|
||||
ImportPath::Std { path: segments }
|
||||
} else if path_string.contains('.') {
|
||||
// TODO should allow other extensions if there is a format attribute.
|
||||
let extn = &path_string[path_string.rfind('.').unwrap() + 1..];
|
||||
if !FOREIGN_IMPORT_EXTENSIONS.contains(&extn) {
|
||||
let extn = std::path::Path::new(&path_string).extension().unwrap_or_default();
|
||||
if !IMPORT_FILE_EXTENSIONS.contains(&extn.to_string_lossy().to_string()) {
|
||||
ParseContext::warn(CompilationError::err(
|
||||
path_range,
|
||||
format!("unsupported import path format. KCL files can be imported from the current project, CAD files with the following formats are supported: {}", FOREIGN_IMPORT_EXTENSIONS.join(", ")),
|
||||
format!("unsupported import path format. KCL files can be imported from the current project, CAD files with the following formats are supported: {}", IMPORT_FILE_EXTENSIONS.join(", ")),
|
||||
))
|
||||
}
|
||||
ImportPath::Foreign { path: path_string }
|
||||
@ -1922,7 +1919,7 @@ fn validate_path_string(path_string: String, var_name: bool, path_range: SourceR
|
||||
return Err(ErrMode::Cut(
|
||||
CompilationError::fatal(
|
||||
path_range,
|
||||
format!("unsupported import path format. KCL files can be imported from the current project, CAD files with the following formats are supported: {}", FOREIGN_IMPORT_EXTENSIONS.join(", ")),
|
||||
format!("unsupported import path format. KCL files can be imported from the current project, CAD files with the following formats are supported: {}", IMPORT_FILE_EXTENSIONS.join(", ")),
|
||||
)
|
||||
.into(),
|
||||
));
|
||||
|
@ -2,6 +2,13 @@
|
||||
|
||||
use anyhow::Result;
|
||||
use kcl_derive_docs::stdlib;
|
||||
use kcmc::{each_cmd as mcmd, length_unit::LengthUnit, ModelingCmd};
|
||||
use kittycad_modeling_cmds::{
|
||||
self as kcmc,
|
||||
ok_response::OkModelingCmdResponse,
|
||||
output::{BooleanIntersection, BooleanSubtract, BooleanUnion},
|
||||
websocket::OkWebSocketResponseData,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
errors::{KclError, KclErrorDetails},
|
||||
@ -9,10 +16,13 @@ use crate::{
|
||||
std::Args,
|
||||
};
|
||||
|
||||
use super::DEFAULT_TOLERANCE;
|
||||
|
||||
/// Union two or more solids into a single solid.
|
||||
pub async fn union(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
||||
let solids: Vec<Solid> =
|
||||
args.get_unlabeled_kw_arg_typed("solids", &RuntimeType::Union(vec![RuntimeType::solids()]), exec_state)?;
|
||||
let tolerance = args.get_kw_arg_opt("tolerance")?;
|
||||
|
||||
if solids.len() < 2 {
|
||||
return Err(KclError::UndefinedValue(KclErrorDetails {
|
||||
@ -21,7 +31,7 @@ pub async fn union(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K
|
||||
}));
|
||||
}
|
||||
|
||||
let solids = inner_union(solids, exec_state, args).await?;
|
||||
let solids = inner_union(solids, tolerance, exec_state, args).await?;
|
||||
Ok(solids.into())
|
||||
}
|
||||
|
||||
@ -30,18 +40,19 @@ pub async fn union(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K
|
||||
/// ```no_run
|
||||
/// // Union two cubes using the stdlib functions.
|
||||
///
|
||||
/// fn cube(center) {
|
||||
/// fn cube(center, size) {
|
||||
/// return startSketchOn('XY')
|
||||
/// |> startProfileAt([center[0] - 10, center[1] - 10], %)
|
||||
/// |> line(endAbsolute = [center[0] + 10, center[1] - 10])
|
||||
/// |> line(endAbsolute = [center[0] + 10, center[1] + 10])
|
||||
/// |> line(endAbsolute = [center[0] - 10, center[1] + 10])
|
||||
/// |> startProfileAt([center[0] - size, center[1] - size], %)
|
||||
/// |> line(endAbsolute = [center[0] + size, center[1] - size])
|
||||
/// |> line(endAbsolute = [center[0] + size, center[1] + size])
|
||||
/// |> line(endAbsolute = [center[0] - size, center[1] + size])
|
||||
/// |> close()
|
||||
/// |> extrude(length = 10)
|
||||
/// }
|
||||
///
|
||||
/// part001 = cube([0, 0])
|
||||
/// part002 = cube([20, 10])
|
||||
/// part001 = cube([0, 0], 10)
|
||||
/// part002 = cube([7, 3], 5)
|
||||
/// |> translate(z = 1)
|
||||
///
|
||||
/// unionedPart = union([part001, part002])
|
||||
/// ```
|
||||
@ -51,18 +62,19 @@ pub async fn union(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K
|
||||
/// // NOTE: This will not work when using codemods through the UI.
|
||||
/// // Codemods will generate the stdlib function call instead.
|
||||
///
|
||||
/// fn cube(center) {
|
||||
/// fn cube(center, size) {
|
||||
/// return startSketchOn('XY')
|
||||
/// |> startProfileAt([center[0] - 10, center[1] - 10], %)
|
||||
/// |> line(endAbsolute = [center[0] + 10, center[1] - 10])
|
||||
/// |> line(endAbsolute = [center[0] + 10, center[1] + 10])
|
||||
/// |> line(endAbsolute = [center[0] - 10, center[1] + 10])
|
||||
/// |> startProfileAt([center[0] - size, center[1] - size], %)
|
||||
/// |> line(endAbsolute = [center[0] + size, center[1] - size])
|
||||
/// |> line(endAbsolute = [center[0] + size, center[1] + size])
|
||||
/// |> line(endAbsolute = [center[0] - size, center[1] + size])
|
||||
/// |> close()
|
||||
/// |> extrude(length = 10)
|
||||
/// }
|
||||
///
|
||||
/// part001 = cube([0, 0])
|
||||
/// part002 = cube([20, 10])
|
||||
/// part001 = cube([0, 0], 10)
|
||||
/// part002 = cube([7, 3], 5)
|
||||
/// |> translate(z = 1)
|
||||
///
|
||||
/// // This is the equivalent of: union([part001, part002])
|
||||
/// unionedPart = part001 + part002
|
||||
@ -73,18 +85,19 @@ pub async fn union(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K
|
||||
/// // NOTE: This will not work when using codemods through the UI.
|
||||
/// // Codemods will generate the stdlib function call instead.
|
||||
///
|
||||
/// fn cube(center) {
|
||||
/// fn cube(center, size) {
|
||||
/// return startSketchOn('XY')
|
||||
/// |> startProfileAt([center[0] - 10, center[1] - 10], %)
|
||||
/// |> line(endAbsolute = [center[0] + 10, center[1] - 10])
|
||||
/// |> line(endAbsolute = [center[0] + 10, center[1] + 10])
|
||||
/// |> line(endAbsolute = [center[0] - 10, center[1] + 10])
|
||||
/// |> startProfileAt([center[0] - size, center[1] - size], %)
|
||||
/// |> line(endAbsolute = [center[0] + size, center[1] - size])
|
||||
/// |> line(endAbsolute = [center[0] + size, center[1] + size])
|
||||
/// |> line(endAbsolute = [center[0] - size, center[1] + size])
|
||||
/// |> close()
|
||||
/// |> extrude(length = 10)
|
||||
/// }
|
||||
///
|
||||
/// part001 = cube([0, 0])
|
||||
/// part002 = cube([20, 10])
|
||||
/// part001 = cube([0, 0], 10)
|
||||
/// part002 = cube([7, 3], 5)
|
||||
/// |> translate(z = 1)
|
||||
///
|
||||
/// // This is the equivalent of: union([part001, part002])
|
||||
/// // Programmers will understand `|` as a union operation, but mechanical engineers
|
||||
@ -96,31 +109,64 @@ pub async fn union(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K
|
||||
feature_tree_operation = true,
|
||||
keywords = true,
|
||||
unlabeled_first = true,
|
||||
deprecated = true,
|
||||
args = {
|
||||
solids = {docs = "The solids to union."},
|
||||
tolerance = {docs = "The tolerance to use for the union operation."},
|
||||
}
|
||||
}]
|
||||
pub(crate) async fn inner_union(
|
||||
solids: Vec<Solid>,
|
||||
tolerance: Option<f64>,
|
||||
exec_state: &mut ExecState,
|
||||
args: Args,
|
||||
) -> Result<Vec<Solid>, KclError> {
|
||||
let solid_out_id = exec_state.next_uuid();
|
||||
|
||||
let mut solid = solids[0].clone();
|
||||
solid.id = solid_out_id;
|
||||
let mut new_solids = vec![solid.clone()];
|
||||
|
||||
if args.ctx.no_engine_commands().await {
|
||||
return Ok(new_solids);
|
||||
}
|
||||
|
||||
// Flush the fillets for the solids.
|
||||
args.flush_batch_for_solids(exec_state, &solids).await?;
|
||||
|
||||
// TODO: call the engine union operation.
|
||||
// TODO: figure out all the shit after for the faces etc.
|
||||
let result = args
|
||||
.send_modeling_cmd(
|
||||
solid_out_id,
|
||||
ModelingCmd::from(mcmd::BooleanUnion {
|
||||
solid_ids: solids.iter().map(|s| s.id).collect(),
|
||||
tolerance: LengthUnit(tolerance.unwrap_or(DEFAULT_TOLERANCE)),
|
||||
}),
|
||||
)
|
||||
.await?;
|
||||
|
||||
// For now just return the first solid.
|
||||
// Til we have a proper implementation.
|
||||
Ok(vec![solids[0].clone()])
|
||||
let OkWebSocketResponseData::Modeling {
|
||||
modeling_response: OkModelingCmdResponse::BooleanUnion(BooleanUnion { extra_solid_ids }),
|
||||
} = result
|
||||
else {
|
||||
return Err(KclError::Internal(KclErrorDetails {
|
||||
message: "Failed to get the result of the union operation.".to_string(),
|
||||
source_ranges: vec![args.source_range],
|
||||
}));
|
||||
};
|
||||
|
||||
// If we have more solids, set those as well.
|
||||
if !extra_solid_ids.is_empty() {
|
||||
solid.id = extra_solid_ids[0];
|
||||
new_solids.push(solid.clone());
|
||||
}
|
||||
|
||||
Ok(new_solids)
|
||||
}
|
||||
|
||||
/// Intersect returns the shared volume between multiple solids, preserving only
|
||||
/// overlapping regions.
|
||||
pub async fn intersect(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
||||
let solids: Vec<Solid> = args.get_unlabeled_kw_arg_typed("solids", &RuntimeType::solids(), exec_state)?;
|
||||
let tolerance = args.get_kw_arg_opt("tolerance")?;
|
||||
|
||||
if solids.len() < 2 {
|
||||
return Err(KclError::UndefinedValue(KclErrorDetails {
|
||||
@ -129,7 +175,7 @@ pub async fn intersect(exec_state: &mut ExecState, args: Args) -> Result<KclValu
|
||||
}));
|
||||
}
|
||||
|
||||
let solids = inner_intersect(solids, exec_state, args).await?;
|
||||
let solids = inner_intersect(solids, tolerance, exec_state, args).await?;
|
||||
Ok(solids.into())
|
||||
}
|
||||
|
||||
@ -144,18 +190,19 @@ pub async fn intersect(exec_state: &mut ExecState, args: Args) -> Result<KclValu
|
||||
/// ```no_run
|
||||
/// // Intersect two cubes using the stdlib functions.
|
||||
///
|
||||
/// fn cube(center) {
|
||||
/// fn cube(center, size) {
|
||||
/// return startSketchOn('XY')
|
||||
/// |> startProfileAt([center[0] - 10, center[1] - 10], %)
|
||||
/// |> line(endAbsolute = [center[0] + 10, center[1] - 10])
|
||||
/// |> line(endAbsolute = [center[0] + 10, center[1] + 10])
|
||||
/// |> line(endAbsolute = [center[0] - 10, center[1] + 10])
|
||||
/// |> startProfileAt([center[0] - size, center[1] - size], %)
|
||||
/// |> line(endAbsolute = [center[0] + size, center[1] - size])
|
||||
/// |> line(endAbsolute = [center[0] + size, center[1] + size])
|
||||
/// |> line(endAbsolute = [center[0] - size, center[1] + size])
|
||||
/// |> close()
|
||||
/// |> extrude(length = 10)
|
||||
/// }
|
||||
///
|
||||
/// part001 = cube([0, 0])
|
||||
/// part002 = cube([8, 8])
|
||||
/// part001 = cube([0, 0], 10)
|
||||
/// part002 = cube([7, 3], 5)
|
||||
/// |> translate(z = 1)
|
||||
///
|
||||
/// intersectedPart = intersect([part001, part002])
|
||||
/// ```
|
||||
@ -165,18 +212,19 @@ pub async fn intersect(exec_state: &mut ExecState, args: Args) -> Result<KclValu
|
||||
/// // NOTE: This will not work when using codemods through the UI.
|
||||
/// // Codemods will generate the stdlib function call instead.
|
||||
///
|
||||
/// fn cube(center) {
|
||||
/// fn cube(center, size) {
|
||||
/// return startSketchOn('XY')
|
||||
/// |> startProfileAt([center[0] - 10, center[1] - 10], %)
|
||||
/// |> line(endAbsolute = [center[0] + 10, center[1] - 10])
|
||||
/// |> line(endAbsolute = [center[0] + 10, center[1] + 10])
|
||||
/// |> line(endAbsolute = [center[0] - 10, center[1] + 10])
|
||||
/// |> startProfileAt([center[0] - size, center[1] - size], %)
|
||||
/// |> line(endAbsolute = [center[0] + size, center[1] - size])
|
||||
/// |> line(endAbsolute = [center[0] + size, center[1] + size])
|
||||
/// |> line(endAbsolute = [center[0] - size, center[1] + size])
|
||||
/// |> close()
|
||||
/// |> extrude(length = 10)
|
||||
/// }
|
||||
///
|
||||
/// part001 = cube([0, 0])
|
||||
/// part002 = cube([8, 8])
|
||||
/// part001 = cube([0, 0], 10)
|
||||
/// part002 = cube([7, 3], 5)
|
||||
/// |> translate(z = 1)
|
||||
///
|
||||
/// // This is the equivalent of: intersect([part001, part002])
|
||||
/// intersectedPart = part001 & part002
|
||||
@ -186,25 +234,57 @@ pub async fn intersect(exec_state: &mut ExecState, args: Args) -> Result<KclValu
|
||||
feature_tree_operation = true,
|
||||
keywords = true,
|
||||
unlabeled_first = true,
|
||||
deprecated = true,
|
||||
args = {
|
||||
solids = {docs = "The solids to intersect."},
|
||||
tolerance = {docs = "The tolerance to use for the intersection operation."},
|
||||
}
|
||||
}]
|
||||
pub(crate) async fn inner_intersect(
|
||||
solids: Vec<Solid>,
|
||||
tolerance: Option<f64>,
|
||||
exec_state: &mut ExecState,
|
||||
args: Args,
|
||||
) -> Result<Vec<Solid>, KclError> {
|
||||
let solid_out_id = exec_state.next_uuid();
|
||||
|
||||
let mut solid = solids[0].clone();
|
||||
solid.id = solid_out_id;
|
||||
let mut new_solids = vec![solid.clone()];
|
||||
|
||||
if args.ctx.no_engine_commands().await {
|
||||
return Ok(new_solids);
|
||||
}
|
||||
|
||||
// Flush the fillets for the solids.
|
||||
args.flush_batch_for_solids(exec_state, &solids).await?;
|
||||
|
||||
// TODO: call the engine union operation.
|
||||
// TODO: figure out all the shit after for the faces etc.
|
||||
let result = args
|
||||
.send_modeling_cmd(
|
||||
solid_out_id,
|
||||
ModelingCmd::from(mcmd::BooleanIntersection {
|
||||
solid_ids: solids.iter().map(|s| s.id).collect(),
|
||||
tolerance: LengthUnit(tolerance.unwrap_or(DEFAULT_TOLERANCE)),
|
||||
}),
|
||||
)
|
||||
.await?;
|
||||
|
||||
// For now just return the first solid.
|
||||
// Til we have a proper implementation.
|
||||
Ok(vec![solids[0].clone()])
|
||||
let OkWebSocketResponseData::Modeling {
|
||||
modeling_response: OkModelingCmdResponse::BooleanIntersection(BooleanIntersection { extra_solid_ids }),
|
||||
} = result
|
||||
else {
|
||||
return Err(KclError::Internal(KclErrorDetails {
|
||||
message: "Failed to get the result of the intersection operation.".to_string(),
|
||||
source_ranges: vec![args.source_range],
|
||||
}));
|
||||
};
|
||||
|
||||
// If we have more solids, set those as well.
|
||||
if !extra_solid_ids.is_empty() {
|
||||
solid.id = extra_solid_ids[0];
|
||||
new_solids.push(solid.clone());
|
||||
}
|
||||
|
||||
Ok(new_solids)
|
||||
}
|
||||
|
||||
/// Subtract removes tool solids from base solids, leaving the remaining material.
|
||||
@ -212,7 +292,23 @@ pub async fn subtract(exec_state: &mut ExecState, args: Args) -> Result<KclValue
|
||||
let solids: Vec<Solid> = args.get_unlabeled_kw_arg_typed("solids", &RuntimeType::solids(), exec_state)?;
|
||||
let tools: Vec<Solid> = args.get_kw_arg_typed("tools", &RuntimeType::solids(), exec_state)?;
|
||||
|
||||
let solids = inner_subtract(solids, tools, exec_state, args).await?;
|
||||
if solids.len() > 1 {
|
||||
return Err(KclError::UndefinedValue(KclErrorDetails {
|
||||
message: "Only one solid is allowed for a subtract operation, currently.".to_string(),
|
||||
source_ranges: vec![args.source_range],
|
||||
}));
|
||||
}
|
||||
|
||||
if tools.len() > 1 {
|
||||
return Err(KclError::UndefinedValue(KclErrorDetails {
|
||||
message: "Only one tool is allowed for a subtract operation, currently.".to_string(),
|
||||
source_ranges: vec![args.source_range],
|
||||
}));
|
||||
}
|
||||
|
||||
let tolerance = args.get_kw_arg_opt("tolerance")?;
|
||||
|
||||
let solids = inner_subtract(solids, tools, tolerance, exec_state, args).await?;
|
||||
Ok(solids.into())
|
||||
}
|
||||
|
||||
@ -227,20 +323,19 @@ pub async fn subtract(exec_state: &mut ExecState, args: Args) -> Result<KclValue
|
||||
/// ```no_run
|
||||
/// // Subtract a cylinder from a cube using the stdlib functions.
|
||||
///
|
||||
/// fn cube(center) {
|
||||
/// fn cube(center, size) {
|
||||
/// return startSketchOn('XY')
|
||||
/// |> startProfileAt([center[0] - 10, center[1] - 10], %)
|
||||
/// |> line(endAbsolute = [center[0] + 10, center[1] - 10])
|
||||
/// |> line(endAbsolute = [center[0] + 10, center[1] + 10])
|
||||
/// |> line(endAbsolute = [center[0] - 10, center[1] + 10])
|
||||
/// |> startProfileAt([center[0] - size, center[1] - size], %)
|
||||
/// |> line(endAbsolute = [center[0] + size, center[1] - size])
|
||||
/// |> line(endAbsolute = [center[0] + size, center[1] + size])
|
||||
/// |> line(endAbsolute = [center[0] - size, center[1] + size])
|
||||
/// |> close()
|
||||
/// |> extrude(length = 10)
|
||||
/// }
|
||||
///
|
||||
/// part001 = cube([0, 0])
|
||||
/// part002 = startSketchOn('XY')
|
||||
/// |> circle(center = [0, 0], radius = 2)
|
||||
/// |> extrude(length = 10)
|
||||
/// part001 = cube([0, 0], 10)
|
||||
/// part002 = cube([7, 3], 5)
|
||||
/// |> translate(z = 1)
|
||||
///
|
||||
/// subtractedPart = subtract([part001], tools=[part002])
|
||||
/// ```
|
||||
@ -250,20 +345,19 @@ pub async fn subtract(exec_state: &mut ExecState, args: Args) -> Result<KclValue
|
||||
/// // NOTE: This will not work when using codemods through the UI.
|
||||
/// // Codemods will generate the stdlib function call instead.
|
||||
///
|
||||
/// fn cube(center) {
|
||||
/// fn cube(center, size) {
|
||||
/// return startSketchOn('XY')
|
||||
/// |> startProfileAt([center[0] - 10, center[1] - 10], %)
|
||||
/// |> line(endAbsolute = [center[0] + 10, center[1] - 10])
|
||||
/// |> line(endAbsolute = [center[0] + 10, center[1] + 10])
|
||||
/// |> line(endAbsolute = [center[0] - 10, center[1] + 10])
|
||||
/// |> startProfileAt([center[0] - size, center[1] - size], %)
|
||||
/// |> line(endAbsolute = [center[0] + size, center[1] - size])
|
||||
/// |> line(endAbsolute = [center[0] + size, center[1] + size])
|
||||
/// |> line(endAbsolute = [center[0] - size, center[1] + size])
|
||||
/// |> close()
|
||||
/// |> extrude(length = 10)
|
||||
/// }
|
||||
///
|
||||
/// part001 = cube([0, 0])
|
||||
/// part002 = startSketchOn('XY')
|
||||
/// |> circle(center = [0, 0], radius = 2)
|
||||
/// |> extrude(length = 10)
|
||||
/// part001 = cube([0, 0], 10)
|
||||
/// part002 = cube([7, 3], 5)
|
||||
/// |> translate(z = 1)
|
||||
///
|
||||
/// // This is the equivalent of: subtract([part001], tools=[part002])
|
||||
/// subtractedPart = part001 - part002
|
||||
@ -273,26 +367,59 @@ pub async fn subtract(exec_state: &mut ExecState, args: Args) -> Result<KclValue
|
||||
feature_tree_operation = true,
|
||||
keywords = true,
|
||||
unlabeled_first = true,
|
||||
deprecated = true,
|
||||
args = {
|
||||
solids = {docs = "The solids to use as the base to subtract from."},
|
||||
tools = {docs = "The solids to subtract."},
|
||||
tolerance = {docs = "The tolerance to use for the subtraction operation."},
|
||||
}
|
||||
}]
|
||||
pub(crate) async fn inner_subtract(
|
||||
solids: Vec<Solid>,
|
||||
tools: Vec<Solid>,
|
||||
tolerance: Option<f64>,
|
||||
exec_state: &mut ExecState,
|
||||
args: Args,
|
||||
) -> Result<Vec<Solid>, KclError> {
|
||||
let solid_out_id = exec_state.next_uuid();
|
||||
|
||||
let mut solid = solids[0].clone();
|
||||
solid.id = solid_out_id;
|
||||
let mut new_solids = vec![solid.clone()];
|
||||
|
||||
if args.ctx.no_engine_commands().await {
|
||||
return Ok(new_solids);
|
||||
}
|
||||
|
||||
// Flush the fillets for the solids and the tools.
|
||||
let combined_solids = solids.iter().chain(tools.iter()).cloned().collect::<Vec<Solid>>();
|
||||
args.flush_batch_for_solids(exec_state, &combined_solids).await?;
|
||||
|
||||
// TODO: call the engine union operation.
|
||||
// TODO: figure out all the shit after for the faces etc.
|
||||
let result = args
|
||||
.send_modeling_cmd(
|
||||
solid_out_id,
|
||||
ModelingCmd::from(mcmd::BooleanSubtract {
|
||||
target_ids: solids.iter().map(|s| s.id).collect(),
|
||||
tool_ids: tools.iter().map(|s| s.id).collect(),
|
||||
tolerance: LengthUnit(tolerance.unwrap_or(DEFAULT_TOLERANCE)),
|
||||
}),
|
||||
)
|
||||
.await?;
|
||||
|
||||
// For now just return the first solid.
|
||||
// Til we have a proper implementation.
|
||||
Ok(vec![solids[0].clone()])
|
||||
let OkWebSocketResponseData::Modeling {
|
||||
modeling_response: OkModelingCmdResponse::BooleanSubtract(BooleanSubtract { extra_solid_ids }),
|
||||
} = result
|
||||
else {
|
||||
return Err(KclError::Internal(KclErrorDetails {
|
||||
message: "Failed to get the result of the subtract operation.".to_string(),
|
||||
source_ranges: vec![args.source_range],
|
||||
}));
|
||||
};
|
||||
|
||||
// If we have more solids, set those as well.
|
||||
if !extra_solid_ids.is_empty() {
|
||||
solid.id = extra_solid_ids[0];
|
||||
new_solids.push(solid.clone());
|
||||
}
|
||||
|
||||
Ok(new_solids)
|
||||
}
|
||||
|
@ -1,8 +1,5 @@
|
||||
use std::fmt::Write;
|
||||
|
||||
#[cfg(feature = "cli")]
|
||||
use clap::ValueEnum;
|
||||
|
||||
use crate::parsing::{
|
||||
ast::types::{
|
||||
Annotation, ArrayExpression, ArrayRangeExpression, BinaryExpression, BinaryOperator, BinaryPart, BodyItem,
|
||||
@ -867,29 +864,6 @@ impl Parameter {
|
||||
}
|
||||
}
|
||||
|
||||
lazy_static::lazy_static! {
|
||||
|
||||
pub static ref IMPORT_FILE_EXTENSIONS: Vec<String> = {
|
||||
let mut import_file_extensions = vec!["stp".to_string(), "glb".to_string(), "fbxb".to_string()];
|
||||
#[cfg(feature = "cli")]
|
||||
let named_extensions = kittycad::types::FileImportFormat::value_variants()
|
||||
.iter()
|
||||
.map(|x| format!("{}", x))
|
||||
.collect::<Vec<String>>();
|
||||
#[cfg(not(feature = "cli"))]
|
||||
let named_extensions = vec![]; // We don't really need this outside of the CLI.
|
||||
// Add all the default import formats.
|
||||
import_file_extensions.extend_from_slice(&named_extensions);
|
||||
import_file_extensions
|
||||
};
|
||||
|
||||
pub static ref RELEVANT_EXTENSIONS: Vec<String> = {
|
||||
let mut relevant_extensions = IMPORT_FILE_EXTENSIONS.clone();
|
||||
relevant_extensions.push("kcl".to_string());
|
||||
relevant_extensions
|
||||
};
|
||||
}
|
||||
|
||||
/// Collect all the kcl (and other relevant) files in a directory, recursively.
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
#[async_recursion::async_recursion]
|
||||
@ -909,7 +883,7 @@ pub async fn walk_dir(dir: &std::path::PathBuf) -> Result<Vec<std::path::PathBuf
|
||||
files.extend(walk_dir(&path).await?);
|
||||
} else if path
|
||||
.extension()
|
||||
.is_some_and(|ext| RELEVANT_EXTENSIONS.contains(&ext.to_string_lossy().to_string()))
|
||||
.is_some_and(|ext| crate::RELEVANT_FILE_EXTENSIONS.contains(&ext.to_string_lossy().to_string()))
|
||||
{
|
||||
files.push(path);
|
||||
}
|
||||
|
@ -178,7 +178,7 @@ description: Artifact commands intersect_cubes.kcl
|
||||
"command": {
|
||||
"type": "extrude",
|
||||
"target": "[uuid]",
|
||||
"distance": 10.0,
|
||||
"distance": 20.0,
|
||||
"faces": null,
|
||||
"opposite": "None"
|
||||
}
|
||||
@ -342,7 +342,7 @@ description: Artifact commands intersect_cubes.kcl
|
||||
"type": "move_path_pen",
|
||||
"path": "[uuid]",
|
||||
"to": {
|
||||
"x": -2.0,
|
||||
"x": 2.0,
|
||||
"y": -2.0,
|
||||
"z": 0.0
|
||||
}
|
||||
@ -364,7 +364,7 @@ description: Artifact commands intersect_cubes.kcl
|
||||
"segment": {
|
||||
"type": "line",
|
||||
"end": {
|
||||
"x": 18.0,
|
||||
"x": 12.0,
|
||||
"y": -2.0,
|
||||
"z": 0.0
|
||||
},
|
||||
@ -381,8 +381,8 @@ description: Artifact commands intersect_cubes.kcl
|
||||
"segment": {
|
||||
"type": "line",
|
||||
"end": {
|
||||
"x": 18.0,
|
||||
"y": 18.0,
|
||||
"x": 12.0,
|
||||
"y": 8.0,
|
||||
"z": 0.0
|
||||
},
|
||||
"relative": false
|
||||
@ -398,8 +398,8 @@ description: Artifact commands intersect_cubes.kcl
|
||||
"segment": {
|
||||
"type": "line",
|
||||
"end": {
|
||||
"x": -2.0,
|
||||
"y": 18.0,
|
||||
"x": 2.0,
|
||||
"y": 8.0,
|
||||
"z": 0.0
|
||||
},
|
||||
"relative": false
|
||||
@ -544,5 +544,41 @@ description: Artifact commands intersect_cubes.kcl
|
||||
"edge_id": "[uuid]",
|
||||
"face_id": "[uuid]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cmdId": "[uuid]",
|
||||
"range": [],
|
||||
"command": {
|
||||
"type": "set_object_transform",
|
||||
"object_id": "[uuid]",
|
||||
"transforms": [
|
||||
{
|
||||
"translate": {
|
||||
"property": {
|
||||
"x": 0.0,
|
||||
"y": 0.0,
|
||||
"z": 1.0
|
||||
},
|
||||
"set": false,
|
||||
"is_local": true
|
||||
},
|
||||
"rotate_rpy": null,
|
||||
"rotate_angle_axis": null,
|
||||
"scale": null
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"cmdId": "[uuid]",
|
||||
"range": [],
|
||||
"command": {
|
||||
"type": "boolean_intersection",
|
||||
"solid_ids": [
|
||||
"[uuid]",
|
||||
"[uuid]"
|
||||
],
|
||||
"tolerance": 0.0000001
|
||||
}
|
||||
}
|
||||
]
|
||||
|
@ -1,23 +1,23 @@
|
||||
```mermaid
|
||||
flowchart LR
|
||||
subgraph path2 [Path]
|
||||
2["Path<br>[52, 103, 0]"]
|
||||
3["Segment<br>[111, 163, 0]"]
|
||||
4["Segment<br>[171, 223, 0]"]
|
||||
5["Segment<br>[231, 283, 0]"]
|
||||
6["Segment<br>[291, 298, 0]"]
|
||||
2["Path<br>[58, 113, 0]"]
|
||||
3["Segment<br>[121, 177, 0]"]
|
||||
4["Segment<br>[185, 241, 0]"]
|
||||
5["Segment<br>[249, 305, 0]"]
|
||||
6["Segment<br>[313, 320, 0]"]
|
||||
7[Solid2d]
|
||||
end
|
||||
subgraph path24 [Path]
|
||||
24["Path<br>[52, 103, 0]"]
|
||||
25["Segment<br>[111, 163, 0]"]
|
||||
26["Segment<br>[171, 223, 0]"]
|
||||
27["Segment<br>[231, 283, 0]"]
|
||||
28["Segment<br>[291, 298, 0]"]
|
||||
24["Path<br>[58, 113, 0]"]
|
||||
25["Segment<br>[121, 177, 0]"]
|
||||
26["Segment<br>[185, 241, 0]"]
|
||||
27["Segment<br>[249, 305, 0]"]
|
||||
28["Segment<br>[313, 320, 0]"]
|
||||
29[Solid2d]
|
||||
end
|
||||
1["Plane<br>[27, 44, 0]"]
|
||||
8["Sweep Extrusion<br>[306, 326, 0]"]
|
||||
1["Plane<br>[33, 50, 0]"]
|
||||
8["Sweep Extrusion<br>[328, 354, 0]"]
|
||||
9[Wall]
|
||||
10[Wall]
|
||||
11[Wall]
|
||||
@ -32,8 +32,8 @@ flowchart LR
|
||||
20["SweepEdge Adjacent"]
|
||||
21["SweepEdge Opposite"]
|
||||
22["SweepEdge Adjacent"]
|
||||
23["Plane<br>[27, 44, 0]"]
|
||||
30["Sweep Extrusion<br>[306, 326, 0]"]
|
||||
23["Plane<br>[33, 50, 0]"]
|
||||
30["Sweep Extrusion<br>[328, 354, 0]"]
|
||||
31[Wall]
|
||||
32[Wall]
|
||||
33[Wall]
|
||||
|
@ -101,16 +101,20 @@ description: Result of parsing intersect_cubes.kcl
|
||||
},
|
||||
"operator": "-",
|
||||
"right": {
|
||||
"abs_path": false,
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"raw": "10",
|
||||
"name": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "size",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"path": [],
|
||||
"start": 0,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 10.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
"type": "Name",
|
||||
"type": "Name"
|
||||
},
|
||||
"start": 0,
|
||||
"type": "BinaryExpression",
|
||||
@ -149,16 +153,20 @@ description: Result of parsing intersect_cubes.kcl
|
||||
},
|
||||
"operator": "-",
|
||||
"right": {
|
||||
"abs_path": false,
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"raw": "10",
|
||||
"name": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "size",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"path": [],
|
||||
"start": 0,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 10.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
"type": "Name",
|
||||
"type": "Name"
|
||||
},
|
||||
"start": 0,
|
||||
"type": "BinaryExpression",
|
||||
@ -246,16 +254,20 @@ description: Result of parsing intersect_cubes.kcl
|
||||
},
|
||||
"operator": "+",
|
||||
"right": {
|
||||
"abs_path": false,
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"raw": "10",
|
||||
"name": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "size",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"path": [],
|
||||
"start": 0,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 10.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
"type": "Name",
|
||||
"type": "Name"
|
||||
},
|
||||
"start": 0,
|
||||
"type": "BinaryExpression",
|
||||
@ -294,16 +306,20 @@ description: Result of parsing intersect_cubes.kcl
|
||||
},
|
||||
"operator": "-",
|
||||
"right": {
|
||||
"abs_path": false,
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"raw": "10",
|
||||
"name": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "size",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"path": [],
|
||||
"start": 0,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 10.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
"type": "Name",
|
||||
"type": "Name"
|
||||
},
|
||||
"start": 0,
|
||||
"type": "BinaryExpression",
|
||||
@ -386,16 +402,20 @@ description: Result of parsing intersect_cubes.kcl
|
||||
},
|
||||
"operator": "+",
|
||||
"right": {
|
||||
"abs_path": false,
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"raw": "10",
|
||||
"name": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "size",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"path": [],
|
||||
"start": 0,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 10.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
"type": "Name",
|
||||
"type": "Name"
|
||||
},
|
||||
"start": 0,
|
||||
"type": "BinaryExpression",
|
||||
@ -434,16 +454,20 @@ description: Result of parsing intersect_cubes.kcl
|
||||
},
|
||||
"operator": "+",
|
||||
"right": {
|
||||
"abs_path": false,
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"raw": "10",
|
||||
"name": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "size",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"path": [],
|
||||
"start": 0,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 10.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
"type": "Name",
|
||||
"type": "Name"
|
||||
},
|
||||
"start": 0,
|
||||
"type": "BinaryExpression",
|
||||
@ -526,16 +550,20 @@ description: Result of parsing intersect_cubes.kcl
|
||||
},
|
||||
"operator": "-",
|
||||
"right": {
|
||||
"abs_path": false,
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"raw": "10",
|
||||
"name": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "size",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"path": [],
|
||||
"start": 0,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 10.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
"type": "Name",
|
||||
"type": "Name"
|
||||
},
|
||||
"start": 0,
|
||||
"type": "BinaryExpression",
|
||||
@ -574,16 +602,20 @@ description: Result of parsing intersect_cubes.kcl
|
||||
},
|
||||
"operator": "+",
|
||||
"right": {
|
||||
"abs_path": false,
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"raw": "10",
|
||||
"name": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "size",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"path": [],
|
||||
"start": 0,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 10.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
"type": "Name",
|
||||
"type": "Name"
|
||||
},
|
||||
"start": 0,
|
||||
"type": "BinaryExpression",
|
||||
@ -656,14 +688,38 @@ description: Result of parsing intersect_cubes.kcl
|
||||
"arg": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"raw": "10",
|
||||
"left": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"raw": "2",
|
||||
"start": 0,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 2.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
},
|
||||
"operator": "*",
|
||||
"right": {
|
||||
"abs_path": false,
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "size",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"path": [],
|
||||
"start": 0,
|
||||
"type": "Name",
|
||||
"type": "Name"
|
||||
},
|
||||
"start": 0,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 10.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
"type": "BinaryExpression",
|
||||
"type": "BinaryExpression"
|
||||
}
|
||||
}
|
||||
],
|
||||
@ -719,6 +775,16 @@ description: Result of parsing intersect_cubes.kcl
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Parameter",
|
||||
"identifier": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "size",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
}
|
||||
}
|
||||
],
|
||||
"start": 0,
|
||||
@ -780,6 +846,18 @@ description: Result of parsing intersect_cubes.kcl
|
||||
"start": 0,
|
||||
"type": "ArrayExpression",
|
||||
"type": "ArrayExpression"
|
||||
},
|
||||
{
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"raw": "10",
|
||||
"start": 0,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 10.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
}
|
||||
],
|
||||
"callee": {
|
||||
@ -825,61 +903,129 @@ description: Result of parsing intersect_cubes.kcl
|
||||
"type": "Identifier"
|
||||
},
|
||||
"init": {
|
||||
"arguments": [
|
||||
"body": [
|
||||
{
|
||||
"commentStart": 0,
|
||||
"elements": [
|
||||
"arguments": [
|
||||
{
|
||||
"commentStart": 0,
|
||||
"elements": [
|
||||
{
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"raw": "7",
|
||||
"start": 0,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 7.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
},
|
||||
{
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"raw": "3",
|
||||
"start": 0,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 3.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
}
|
||||
],
|
||||
"end": 0,
|
||||
"raw": "8",
|
||||
"start": 0,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 8.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
"type": "ArrayExpression",
|
||||
"type": "ArrayExpression"
|
||||
},
|
||||
{
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"raw": "8",
|
||||
"raw": "5",
|
||||
"start": 0,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 8.0,
|
||||
"value": 5.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
}
|
||||
],
|
||||
"end": 0,
|
||||
"start": 0,
|
||||
"type": "ArrayExpression",
|
||||
"type": "ArrayExpression"
|
||||
}
|
||||
],
|
||||
"callee": {
|
||||
"abs_path": false,
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": {
|
||||
"callee": {
|
||||
"abs_path": false,
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "cube",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"path": [],
|
||||
"start": 0,
|
||||
"type": "Name"
|
||||
},
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "cube",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
"type": "CallExpression",
|
||||
"type": "CallExpression"
|
||||
},
|
||||
"path": [],
|
||||
"start": 0,
|
||||
"type": "Name"
|
||||
},
|
||||
{
|
||||
"arguments": [
|
||||
{
|
||||
"type": "LabeledArg",
|
||||
"label": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "z",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"arg": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"raw": "1",
|
||||
"start": 0,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 1.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"callee": {
|
||||
"abs_path": false,
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "translate",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"path": [],
|
||||
"start": 0,
|
||||
"type": "Name"
|
||||
},
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"start": 0,
|
||||
"type": "CallExpressionKw",
|
||||
"type": "CallExpressionKw",
|
||||
"unlabeled": null
|
||||
}
|
||||
],
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"start": 0,
|
||||
"type": "CallExpression",
|
||||
"type": "CallExpression"
|
||||
"type": "PipeExpression",
|
||||
"type": "PipeExpression"
|
||||
},
|
||||
"start": 0,
|
||||
"type": "VariableDeclarator"
|
||||
|
@ -1,14 +1,15 @@
|
||||
fn cube(center) {
|
||||
fn cube(center, size) {
|
||||
return startSketchOn(XY)
|
||||
|> startProfileAt([center[0] - 10, center[1] - 10], %)
|
||||
|> line(endAbsolute = [center[0] + 10, center[1] - 10])
|
||||
|> line(endAbsolute = [center[0] + 10, center[1] + 10])
|
||||
|> line(endAbsolute = [center[0] - 10, center[1] + 10])
|
||||
|> startProfileAt([center[0] - size, center[1] - size], %)
|
||||
|> line(endAbsolute = [center[0] + size, center[1] - size])
|
||||
|> line(endAbsolute = [center[0] + size, center[1] + size])
|
||||
|> line(endAbsolute = [center[0] - size, center[1] + size])
|
||||
|> close()
|
||||
|> extrude(length = 10)
|
||||
|> extrude(length = 2 * size)
|
||||
}
|
||||
|
||||
part001 = cube([0, 0])
|
||||
part002 = cube([8, 8])
|
||||
part001 = cube([0, 0], 10)
|
||||
part002 = cube([7, 3], 5)
|
||||
|> translate(z = 1)
|
||||
|
||||
fullPart = intersect([part001, part002])
|
||||
|
@ -10,7 +10,7 @@ description: Operations executed intersect_cubes.kcl
|
||||
"name": "cube",
|
||||
"functionSourceRange": [
|
||||
7,
|
||||
328,
|
||||
356,
|
||||
0
|
||||
],
|
||||
"unlabeledArg": null,
|
||||
@ -38,7 +38,7 @@ description: Operations executed intersect_cubes.kcl
|
||||
"length": {
|
||||
"value": {
|
||||
"type": "Number",
|
||||
"value": 10.0,
|
||||
"value": 20.0,
|
||||
"ty": {
|
||||
"type": "Default",
|
||||
"len": {
|
||||
@ -75,7 +75,7 @@ description: Operations executed intersect_cubes.kcl
|
||||
"name": "cube",
|
||||
"functionSourceRange": [
|
||||
7,
|
||||
328,
|
||||
356,
|
||||
0
|
||||
],
|
||||
"unlabeledArg": null,
|
||||
|
@ -7,182 +7,365 @@ description: Variables in memory after executing intersect_cubes.kcl
|
||||
"type": "Function"
|
||||
},
|
||||
"fullPart": {
|
||||
"type": "Solid",
|
||||
"value": {
|
||||
"type": "Solid",
|
||||
"id": "[uuid]",
|
||||
"artifactId": "[uuid]",
|
||||
"value": [
|
||||
{
|
||||
"faceId": "[uuid]",
|
||||
"id": "[uuid]",
|
||||
"sourceRange": [],
|
||||
"tag": null,
|
||||
"type": "extrudePlane"
|
||||
},
|
||||
{
|
||||
"faceId": "[uuid]",
|
||||
"id": "[uuid]",
|
||||
"sourceRange": [],
|
||||
"tag": null,
|
||||
"type": "extrudePlane"
|
||||
},
|
||||
{
|
||||
"faceId": "[uuid]",
|
||||
"id": "[uuid]",
|
||||
"sourceRange": [],
|
||||
"tag": null,
|
||||
"type": "extrudePlane"
|
||||
},
|
||||
{
|
||||
"faceId": "[uuid]",
|
||||
"id": "[uuid]",
|
||||
"sourceRange": [],
|
||||
"tag": null,
|
||||
"type": "extrudePlane"
|
||||
}
|
||||
],
|
||||
"sketch": {
|
||||
"type": "Sketch",
|
||||
"id": "[uuid]",
|
||||
"paths": [
|
||||
{
|
||||
"__geoMeta": {
|
||||
"id": "[uuid]",
|
||||
"sourceRange": []
|
||||
},
|
||||
"from": [
|
||||
-10.0,
|
||||
-10.0
|
||||
],
|
||||
"tag": null,
|
||||
"to": [
|
||||
10.0,
|
||||
-10.0
|
||||
],
|
||||
"type": "ToPoint",
|
||||
"units": {
|
||||
"type": "Mm"
|
||||
}
|
||||
},
|
||||
{
|
||||
"__geoMeta": {
|
||||
"id": "[uuid]",
|
||||
"sourceRange": []
|
||||
},
|
||||
"from": [
|
||||
10.0,
|
||||
-10.0
|
||||
],
|
||||
"tag": null,
|
||||
"to": [
|
||||
10.0,
|
||||
10.0
|
||||
],
|
||||
"type": "ToPoint",
|
||||
"units": {
|
||||
"type": "Mm"
|
||||
}
|
||||
},
|
||||
{
|
||||
"__geoMeta": {
|
||||
"id": "[uuid]",
|
||||
"sourceRange": []
|
||||
},
|
||||
"from": [
|
||||
10.0,
|
||||
10.0
|
||||
],
|
||||
"tag": null,
|
||||
"to": [
|
||||
-10.0,
|
||||
10.0
|
||||
],
|
||||
"type": "ToPoint",
|
||||
"units": {
|
||||
"type": "Mm"
|
||||
}
|
||||
},
|
||||
{
|
||||
"__geoMeta": {
|
||||
"id": "[uuid]",
|
||||
"sourceRange": []
|
||||
},
|
||||
"from": [
|
||||
-10.0,
|
||||
10.0
|
||||
],
|
||||
"tag": null,
|
||||
"to": [
|
||||
-10.0,
|
||||
-10.0
|
||||
],
|
||||
"type": "ToPoint",
|
||||
"units": {
|
||||
"type": "Mm"
|
||||
}
|
||||
}
|
||||
],
|
||||
"on": {
|
||||
"type": "plane",
|
||||
"type": "HomArray",
|
||||
"value": [
|
||||
{
|
||||
"type": "Solid",
|
||||
"value": {
|
||||
"type": "Solid",
|
||||
"id": "[uuid]",
|
||||
"artifactId": "[uuid]",
|
||||
"value": "XY",
|
||||
"origin": {
|
||||
"x": 0.0,
|
||||
"y": 0.0,
|
||||
"z": 0.0
|
||||
},
|
||||
"xAxis": {
|
||||
"x": 1.0,
|
||||
"y": 0.0,
|
||||
"z": 0.0
|
||||
},
|
||||
"yAxis": {
|
||||
"x": 0.0,
|
||||
"y": 1.0,
|
||||
"z": 0.0
|
||||
},
|
||||
"zAxis": {
|
||||
"x": 0.0,
|
||||
"y": 0.0,
|
||||
"z": 1.0
|
||||
},
|
||||
"units": {
|
||||
"type": "Mm"
|
||||
}
|
||||
},
|
||||
"start": {
|
||||
"from": [
|
||||
-10.0,
|
||||
-10.0
|
||||
"value": [
|
||||
{
|
||||
"faceId": "[uuid]",
|
||||
"id": "[uuid]",
|
||||
"sourceRange": [],
|
||||
"tag": null,
|
||||
"type": "extrudePlane"
|
||||
},
|
||||
{
|
||||
"faceId": "[uuid]",
|
||||
"id": "[uuid]",
|
||||
"sourceRange": [],
|
||||
"tag": null,
|
||||
"type": "extrudePlane"
|
||||
},
|
||||
{
|
||||
"faceId": "[uuid]",
|
||||
"id": "[uuid]",
|
||||
"sourceRange": [],
|
||||
"tag": null,
|
||||
"type": "extrudePlane"
|
||||
},
|
||||
{
|
||||
"faceId": "[uuid]",
|
||||
"id": "[uuid]",
|
||||
"sourceRange": [],
|
||||
"tag": null,
|
||||
"type": "extrudePlane"
|
||||
}
|
||||
],
|
||||
"to": [
|
||||
-10.0,
|
||||
-10.0
|
||||
],
|
||||
"units": {
|
||||
"type": "Mm"
|
||||
},
|
||||
"tag": null,
|
||||
"__geoMeta": {
|
||||
"sketch": {
|
||||
"type": "Sketch",
|
||||
"id": "[uuid]",
|
||||
"sourceRange": []
|
||||
"paths": [
|
||||
{
|
||||
"__geoMeta": {
|
||||
"id": "[uuid]",
|
||||
"sourceRange": []
|
||||
},
|
||||
"from": [
|
||||
-10.0,
|
||||
-10.0
|
||||
],
|
||||
"tag": null,
|
||||
"to": [
|
||||
10.0,
|
||||
-10.0
|
||||
],
|
||||
"type": "ToPoint",
|
||||
"units": {
|
||||
"type": "Mm"
|
||||
}
|
||||
},
|
||||
{
|
||||
"__geoMeta": {
|
||||
"id": "[uuid]",
|
||||
"sourceRange": []
|
||||
},
|
||||
"from": [
|
||||
10.0,
|
||||
-10.0
|
||||
],
|
||||
"tag": null,
|
||||
"to": [
|
||||
10.0,
|
||||
10.0
|
||||
],
|
||||
"type": "ToPoint",
|
||||
"units": {
|
||||
"type": "Mm"
|
||||
}
|
||||
},
|
||||
{
|
||||
"__geoMeta": {
|
||||
"id": "[uuid]",
|
||||
"sourceRange": []
|
||||
},
|
||||
"from": [
|
||||
10.0,
|
||||
10.0
|
||||
],
|
||||
"tag": null,
|
||||
"to": [
|
||||
-10.0,
|
||||
10.0
|
||||
],
|
||||
"type": "ToPoint",
|
||||
"units": {
|
||||
"type": "Mm"
|
||||
}
|
||||
},
|
||||
{
|
||||
"__geoMeta": {
|
||||
"id": "[uuid]",
|
||||
"sourceRange": []
|
||||
},
|
||||
"from": [
|
||||
-10.0,
|
||||
10.0
|
||||
],
|
||||
"tag": null,
|
||||
"to": [
|
||||
-10.0,
|
||||
-10.0
|
||||
],
|
||||
"type": "ToPoint",
|
||||
"units": {
|
||||
"type": "Mm"
|
||||
}
|
||||
}
|
||||
],
|
||||
"on": {
|
||||
"type": "plane",
|
||||
"id": "[uuid]",
|
||||
"artifactId": "[uuid]",
|
||||
"value": "XY",
|
||||
"origin": {
|
||||
"x": 0.0,
|
||||
"y": 0.0,
|
||||
"z": 0.0
|
||||
},
|
||||
"xAxis": {
|
||||
"x": 1.0,
|
||||
"y": 0.0,
|
||||
"z": 0.0
|
||||
},
|
||||
"yAxis": {
|
||||
"x": 0.0,
|
||||
"y": 1.0,
|
||||
"z": 0.0
|
||||
},
|
||||
"zAxis": {
|
||||
"x": 0.0,
|
||||
"y": 0.0,
|
||||
"z": 1.0
|
||||
},
|
||||
"units": {
|
||||
"type": "Mm"
|
||||
}
|
||||
},
|
||||
"start": {
|
||||
"from": [
|
||||
-10.0,
|
||||
-10.0
|
||||
],
|
||||
"to": [
|
||||
-10.0,
|
||||
-10.0
|
||||
],
|
||||
"units": {
|
||||
"type": "Mm"
|
||||
},
|
||||
"tag": null,
|
||||
"__geoMeta": {
|
||||
"id": "[uuid]",
|
||||
"sourceRange": []
|
||||
}
|
||||
},
|
||||
"artifactId": "[uuid]",
|
||||
"originalId": "[uuid]",
|
||||
"units": {
|
||||
"type": "Mm"
|
||||
}
|
||||
},
|
||||
"height": 20.0,
|
||||
"startCapId": "[uuid]",
|
||||
"endCapId": "[uuid]",
|
||||
"units": {
|
||||
"type": "Mm"
|
||||
}
|
||||
},
|
||||
"artifactId": "[uuid]",
|
||||
"originalId": "[uuid]",
|
||||
"units": {
|
||||
"type": "Mm"
|
||||
}
|
||||
},
|
||||
"height": 10.0,
|
||||
"startCapId": "[uuid]",
|
||||
"endCapId": "[uuid]",
|
||||
"units": {
|
||||
"type": "Mm"
|
||||
{
|
||||
"type": "Solid",
|
||||
"value": {
|
||||
"type": "Solid",
|
||||
"id": "[uuid]",
|
||||
"artifactId": "[uuid]",
|
||||
"value": [
|
||||
{
|
||||
"faceId": "[uuid]",
|
||||
"id": "[uuid]",
|
||||
"sourceRange": [],
|
||||
"tag": null,
|
||||
"type": "extrudePlane"
|
||||
},
|
||||
{
|
||||
"faceId": "[uuid]",
|
||||
"id": "[uuid]",
|
||||
"sourceRange": [],
|
||||
"tag": null,
|
||||
"type": "extrudePlane"
|
||||
},
|
||||
{
|
||||
"faceId": "[uuid]",
|
||||
"id": "[uuid]",
|
||||
"sourceRange": [],
|
||||
"tag": null,
|
||||
"type": "extrudePlane"
|
||||
},
|
||||
{
|
||||
"faceId": "[uuid]",
|
||||
"id": "[uuid]",
|
||||
"sourceRange": [],
|
||||
"tag": null,
|
||||
"type": "extrudePlane"
|
||||
}
|
||||
],
|
||||
"sketch": {
|
||||
"type": "Sketch",
|
||||
"id": "[uuid]",
|
||||
"paths": [
|
||||
{
|
||||
"__geoMeta": {
|
||||
"id": "[uuid]",
|
||||
"sourceRange": []
|
||||
},
|
||||
"from": [
|
||||
-10.0,
|
||||
-10.0
|
||||
],
|
||||
"tag": null,
|
||||
"to": [
|
||||
10.0,
|
||||
-10.0
|
||||
],
|
||||
"type": "ToPoint",
|
||||
"units": {
|
||||
"type": "Mm"
|
||||
}
|
||||
},
|
||||
{
|
||||
"__geoMeta": {
|
||||
"id": "[uuid]",
|
||||
"sourceRange": []
|
||||
},
|
||||
"from": [
|
||||
10.0,
|
||||
-10.0
|
||||
],
|
||||
"tag": null,
|
||||
"to": [
|
||||
10.0,
|
||||
10.0
|
||||
],
|
||||
"type": "ToPoint",
|
||||
"units": {
|
||||
"type": "Mm"
|
||||
}
|
||||
},
|
||||
{
|
||||
"__geoMeta": {
|
||||
"id": "[uuid]",
|
||||
"sourceRange": []
|
||||
},
|
||||
"from": [
|
||||
10.0,
|
||||
10.0
|
||||
],
|
||||
"tag": null,
|
||||
"to": [
|
||||
-10.0,
|
||||
10.0
|
||||
],
|
||||
"type": "ToPoint",
|
||||
"units": {
|
||||
"type": "Mm"
|
||||
}
|
||||
},
|
||||
{
|
||||
"__geoMeta": {
|
||||
"id": "[uuid]",
|
||||
"sourceRange": []
|
||||
},
|
||||
"from": [
|
||||
-10.0,
|
||||
10.0
|
||||
],
|
||||
"tag": null,
|
||||
"to": [
|
||||
-10.0,
|
||||
-10.0
|
||||
],
|
||||
"type": "ToPoint",
|
||||
"units": {
|
||||
"type": "Mm"
|
||||
}
|
||||
}
|
||||
],
|
||||
"on": {
|
||||
"type": "plane",
|
||||
"id": "[uuid]",
|
||||
"artifactId": "[uuid]",
|
||||
"value": "XY",
|
||||
"origin": {
|
||||
"x": 0.0,
|
||||
"y": 0.0,
|
||||
"z": 0.0
|
||||
},
|
||||
"xAxis": {
|
||||
"x": 1.0,
|
||||
"y": 0.0,
|
||||
"z": 0.0
|
||||
},
|
||||
"yAxis": {
|
||||
"x": 0.0,
|
||||
"y": 1.0,
|
||||
"z": 0.0
|
||||
},
|
||||
"zAxis": {
|
||||
"x": 0.0,
|
||||
"y": 0.0,
|
||||
"z": 1.0
|
||||
},
|
||||
"units": {
|
||||
"type": "Mm"
|
||||
}
|
||||
},
|
||||
"start": {
|
||||
"from": [
|
||||
-10.0,
|
||||
-10.0
|
||||
],
|
||||
"to": [
|
||||
-10.0,
|
||||
-10.0
|
||||
],
|
||||
"units": {
|
||||
"type": "Mm"
|
||||
},
|
||||
"tag": null,
|
||||
"__geoMeta": {
|
||||
"id": "[uuid]",
|
||||
"sourceRange": []
|
||||
}
|
||||
},
|
||||
"artifactId": "[uuid]",
|
||||
"originalId": "[uuid]",
|
||||
"units": {
|
||||
"type": "Mm"
|
||||
}
|
||||
},
|
||||
"height": 20.0,
|
||||
"startCapId": "[uuid]",
|
||||
"endCapId": "[uuid]",
|
||||
"units": {
|
||||
"type": "Mm"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"part001": {
|
||||
"type": "Solid",
|
||||
@ -354,7 +537,7 @@ description: Variables in memory after executing intersect_cubes.kcl
|
||||
"type": "Mm"
|
||||
}
|
||||
},
|
||||
"height": 10.0,
|
||||
"height": 20.0,
|
||||
"startCapId": "[uuid]",
|
||||
"endCapId": "[uuid]",
|
||||
"units": {
|
||||
@ -408,12 +591,12 @@ description: Variables in memory after executing intersect_cubes.kcl
|
||||
"sourceRange": []
|
||||
},
|
||||
"from": [
|
||||
-2.0,
|
||||
2.0,
|
||||
-2.0
|
||||
],
|
||||
"tag": null,
|
||||
"to": [
|
||||
18.0,
|
||||
12.0,
|
||||
-2.0
|
||||
],
|
||||
"type": "ToPoint",
|
||||
@ -427,13 +610,13 @@ description: Variables in memory after executing intersect_cubes.kcl
|
||||
"sourceRange": []
|
||||
},
|
||||
"from": [
|
||||
18.0,
|
||||
12.0,
|
||||
-2.0
|
||||
],
|
||||
"tag": null,
|
||||
"to": [
|
||||
18.0,
|
||||
18.0
|
||||
12.0,
|
||||
8.0
|
||||
],
|
||||
"type": "ToPoint",
|
||||
"units": {
|
||||
@ -446,13 +629,13 @@ description: Variables in memory after executing intersect_cubes.kcl
|
||||
"sourceRange": []
|
||||
},
|
||||
"from": [
|
||||
18.0,
|
||||
18.0
|
||||
12.0,
|
||||
8.0
|
||||
],
|
||||
"tag": null,
|
||||
"to": [
|
||||
-2.0,
|
||||
18.0
|
||||
2.0,
|
||||
8.0
|
||||
],
|
||||
"type": "ToPoint",
|
||||
"units": {
|
||||
@ -465,12 +648,12 @@ description: Variables in memory after executing intersect_cubes.kcl
|
||||
"sourceRange": []
|
||||
},
|
||||
"from": [
|
||||
-2.0,
|
||||
18.0
|
||||
2.0,
|
||||
8.0
|
||||
],
|
||||
"tag": null,
|
||||
"to": [
|
||||
-2.0,
|
||||
2.0,
|
||||
-2.0
|
||||
],
|
||||
"type": "ToPoint",
|
||||
@ -510,11 +693,11 @@ description: Variables in memory after executing intersect_cubes.kcl
|
||||
},
|
||||
"start": {
|
||||
"from": [
|
||||
-2.0,
|
||||
2.0,
|
||||
-2.0
|
||||
],
|
||||
"to": [
|
||||
-2.0,
|
||||
2.0,
|
||||
-2.0
|
||||
],
|
||||
"units": {
|
||||
|
Before Width: | Height: | Size: 67 KiB After Width: | Height: | Size: 61 KiB |
@ -2,17 +2,18 @@
|
||||
source: kcl-lib/src/simulation_tests.rs
|
||||
description: Result of unparsing intersect_cubes.kcl
|
||||
---
|
||||
fn cube(center) {
|
||||
fn cube(center, size) {
|
||||
return startSketchOn(XY)
|
||||
|> startProfileAt([center[0] - 10, center[1] - 10], %)
|
||||
|> line(endAbsolute = [center[0] + 10, center[1] - 10])
|
||||
|> line(endAbsolute = [center[0] + 10, center[1] + 10])
|
||||
|> line(endAbsolute = [center[0] - 10, center[1] + 10])
|
||||
|> startProfileAt([center[0] - size, center[1] - size], %)
|
||||
|> line(endAbsolute = [center[0] + size, center[1] - size])
|
||||
|> line(endAbsolute = [center[0] + size, center[1] + size])
|
||||
|> line(endAbsolute = [center[0] - size, center[1] + size])
|
||||
|> close()
|
||||
|> extrude(length = 10)
|
||||
|> extrude(length = 2 * size)
|
||||
}
|
||||
|
||||
part001 = cube([0, 0])
|
||||
part002 = cube([8, 8])
|
||||
part001 = cube([0, 0], 10)
|
||||
part002 = cube([7, 3], 5)
|
||||
|> translate(z = 1)
|
||||
|
||||
fullPart = intersect([part001, part002])
|
||||
|
Before Width: | Height: | Size: 67 KiB After Width: | Height: | Size: 58 KiB |
Before Width: | Height: | Size: 67 KiB After Width: | Height: | Size: 58 KiB |
Before Width: | Height: | Size: 70 KiB After Width: | Height: | Size: 59 KiB |
Before Width: | Height: | Size: 70 KiB After Width: | Height: | Size: 59 KiB |
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 61 KiB |
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 61 KiB |
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 61 KiB |
@ -342,8 +342,8 @@ description: Artifact commands subtract_cylinder_from_cube.kcl
|
||||
"type": "move_path_pen",
|
||||
"path": "[uuid]",
|
||||
"to": {
|
||||
"x": 2.0,
|
||||
"y": 0.0,
|
||||
"x": 4.0,
|
||||
"y": 2.0,
|
||||
"z": 0.0
|
||||
}
|
||||
}
|
||||
@ -364,8 +364,8 @@ description: Artifact commands subtract_cylinder_from_cube.kcl
|
||||
"segment": {
|
||||
"type": "arc",
|
||||
"center": {
|
||||
"x": 0.0,
|
||||
"y": 0.0
|
||||
"x": 2.0,
|
||||
"y": 2.0
|
||||
},
|
||||
"radius": 2.0,
|
||||
"start": {
|
||||
@ -410,7 +410,7 @@ description: Artifact commands subtract_cylinder_from_cube.kcl
|
||||
"command": {
|
||||
"type": "extrude",
|
||||
"target": "[uuid]",
|
||||
"distance": 10.0,
|
||||
"distance": 5.0,
|
||||
"faces": null,
|
||||
"opposite": "None"
|
||||
}
|
||||
@ -458,5 +458,19 @@ description: Artifact commands subtract_cylinder_from_cube.kcl
|
||||
"edge_id": "[uuid]",
|
||||
"face_id": "[uuid]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cmdId": "[uuid]",
|
||||
"range": [],
|
||||
"command": {
|
||||
"type": "boolean_subtract",
|
||||
"target_ids": [
|
||||
"[uuid]"
|
||||
],
|
||||
"tool_ids": [
|
||||
"[uuid]"
|
||||
],
|
||||
"tolerance": 0.0000001
|
||||
}
|
||||
}
|
||||
]
|
||||
|
@ -30,7 +30,7 @@ flowchart LR
|
||||
21["SweepEdge Opposite"]
|
||||
22["SweepEdge Adjacent"]
|
||||
23["Plane<br>[363, 382, 0]"]
|
||||
27["Sweep Extrusion<br>[429, 449, 0]"]
|
||||
27["Sweep Extrusion<br>[429, 448, 0]"]
|
||||
28[Wall]
|
||||
29["Cap Start"]
|
||||
30["Cap End"]
|
||||
|
@ -876,24 +876,24 @@ description: Result of parsing subtract_cylinder_from_cube.kcl
|
||||
{
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"raw": "0",
|
||||
"raw": "2",
|
||||
"start": 0,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 0.0,
|
||||
"value": 2.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
},
|
||||
{
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"raw": "0",
|
||||
"raw": "2",
|
||||
"start": 0,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 0.0,
|
||||
"value": 2.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
}
|
||||
@ -963,12 +963,12 @@ description: Result of parsing subtract_cylinder_from_cube.kcl
|
||||
"arg": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"raw": "10",
|
||||
"raw": "5",
|
||||
"start": 0,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 10.0,
|
||||
"value": 5.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ fn cube(center) {
|
||||
|
||||
part001 = cube([0, 0])
|
||||
part002 = startSketchOn('XY')
|
||||
|> circle(center = [0, 0], radius = 2)
|
||||
|> extrude(length = 10)
|
||||
|> circle(center = [2, 2], radius = 2)
|
||||
|> extrude(length = 5)
|
||||
|
||||
fullPart = subtract([part001], tools=[part002])
|
||||
|
@ -88,7 +88,7 @@ description: Operations executed subtract_cylinder_from_cube.kcl
|
||||
"length": {
|
||||
"value": {
|
||||
"type": "Number",
|
||||
"value": 10.0,
|
||||
"value": 5.0,
|
||||
"ty": {
|
||||
"type": "Default",
|
||||
"len": {
|
||||
|
@ -7,182 +7,365 @@ description: Variables in memory after executing subtract_cylinder_from_cube.kcl
|
||||
"type": "Function"
|
||||
},
|
||||
"fullPart": {
|
||||
"type": "Solid",
|
||||
"value": {
|
||||
"type": "Solid",
|
||||
"id": "[uuid]",
|
||||
"artifactId": "[uuid]",
|
||||
"value": [
|
||||
{
|
||||
"faceId": "[uuid]",
|
||||
"id": "[uuid]",
|
||||
"sourceRange": [],
|
||||
"tag": null,
|
||||
"type": "extrudePlane"
|
||||
},
|
||||
{
|
||||
"faceId": "[uuid]",
|
||||
"id": "[uuid]",
|
||||
"sourceRange": [],
|
||||
"tag": null,
|
||||
"type": "extrudePlane"
|
||||
},
|
||||
{
|
||||
"faceId": "[uuid]",
|
||||
"id": "[uuid]",
|
||||
"sourceRange": [],
|
||||
"tag": null,
|
||||
"type": "extrudePlane"
|
||||
},
|
||||
{
|
||||
"faceId": "[uuid]",
|
||||
"id": "[uuid]",
|
||||
"sourceRange": [],
|
||||
"tag": null,
|
||||
"type": "extrudePlane"
|
||||
}
|
||||
],
|
||||
"sketch": {
|
||||
"type": "Sketch",
|
||||
"id": "[uuid]",
|
||||
"paths": [
|
||||
{
|
||||
"__geoMeta": {
|
||||
"id": "[uuid]",
|
||||
"sourceRange": []
|
||||
},
|
||||
"from": [
|
||||
-10.0,
|
||||
-10.0
|
||||
],
|
||||
"tag": null,
|
||||
"to": [
|
||||
10.0,
|
||||
-10.0
|
||||
],
|
||||
"type": "ToPoint",
|
||||
"units": {
|
||||
"type": "Mm"
|
||||
}
|
||||
},
|
||||
{
|
||||
"__geoMeta": {
|
||||
"id": "[uuid]",
|
||||
"sourceRange": []
|
||||
},
|
||||
"from": [
|
||||
10.0,
|
||||
-10.0
|
||||
],
|
||||
"tag": null,
|
||||
"to": [
|
||||
10.0,
|
||||
10.0
|
||||
],
|
||||
"type": "ToPoint",
|
||||
"units": {
|
||||
"type": "Mm"
|
||||
}
|
||||
},
|
||||
{
|
||||
"__geoMeta": {
|
||||
"id": "[uuid]",
|
||||
"sourceRange": []
|
||||
},
|
||||
"from": [
|
||||
10.0,
|
||||
10.0
|
||||
],
|
||||
"tag": null,
|
||||
"to": [
|
||||
-10.0,
|
||||
10.0
|
||||
],
|
||||
"type": "ToPoint",
|
||||
"units": {
|
||||
"type": "Mm"
|
||||
}
|
||||
},
|
||||
{
|
||||
"__geoMeta": {
|
||||
"id": "[uuid]",
|
||||
"sourceRange": []
|
||||
},
|
||||
"from": [
|
||||
-10.0,
|
||||
10.0
|
||||
],
|
||||
"tag": null,
|
||||
"to": [
|
||||
-10.0,
|
||||
-10.0
|
||||
],
|
||||
"type": "ToPoint",
|
||||
"units": {
|
||||
"type": "Mm"
|
||||
}
|
||||
}
|
||||
],
|
||||
"on": {
|
||||
"type": "plane",
|
||||
"type": "HomArray",
|
||||
"value": [
|
||||
{
|
||||
"type": "Solid",
|
||||
"value": {
|
||||
"type": "Solid",
|
||||
"id": "[uuid]",
|
||||
"artifactId": "[uuid]",
|
||||
"value": "XY",
|
||||
"origin": {
|
||||
"x": 0.0,
|
||||
"y": 0.0,
|
||||
"z": 0.0
|
||||
},
|
||||
"xAxis": {
|
||||
"x": 1.0,
|
||||
"y": 0.0,
|
||||
"z": 0.0
|
||||
},
|
||||
"yAxis": {
|
||||
"x": 0.0,
|
||||
"y": 1.0,
|
||||
"z": 0.0
|
||||
},
|
||||
"zAxis": {
|
||||
"x": 0.0,
|
||||
"y": 0.0,
|
||||
"z": 1.0
|
||||
},
|
||||
"units": {
|
||||
"type": "Mm"
|
||||
}
|
||||
},
|
||||
"start": {
|
||||
"from": [
|
||||
-10.0,
|
||||
-10.0
|
||||
"value": [
|
||||
{
|
||||
"faceId": "[uuid]",
|
||||
"id": "[uuid]",
|
||||
"sourceRange": [],
|
||||
"tag": null,
|
||||
"type": "extrudePlane"
|
||||
},
|
||||
{
|
||||
"faceId": "[uuid]",
|
||||
"id": "[uuid]",
|
||||
"sourceRange": [],
|
||||
"tag": null,
|
||||
"type": "extrudePlane"
|
||||
},
|
||||
{
|
||||
"faceId": "[uuid]",
|
||||
"id": "[uuid]",
|
||||
"sourceRange": [],
|
||||
"tag": null,
|
||||
"type": "extrudePlane"
|
||||
},
|
||||
{
|
||||
"faceId": "[uuid]",
|
||||
"id": "[uuid]",
|
||||
"sourceRange": [],
|
||||
"tag": null,
|
||||
"type": "extrudePlane"
|
||||
}
|
||||
],
|
||||
"to": [
|
||||
-10.0,
|
||||
-10.0
|
||||
],
|
||||
"units": {
|
||||
"type": "Mm"
|
||||
},
|
||||
"tag": null,
|
||||
"__geoMeta": {
|
||||
"sketch": {
|
||||
"type": "Sketch",
|
||||
"id": "[uuid]",
|
||||
"sourceRange": []
|
||||
"paths": [
|
||||
{
|
||||
"__geoMeta": {
|
||||
"id": "[uuid]",
|
||||
"sourceRange": []
|
||||
},
|
||||
"from": [
|
||||
-10.0,
|
||||
-10.0
|
||||
],
|
||||
"tag": null,
|
||||
"to": [
|
||||
10.0,
|
||||
-10.0
|
||||
],
|
||||
"type": "ToPoint",
|
||||
"units": {
|
||||
"type": "Mm"
|
||||
}
|
||||
},
|
||||
{
|
||||
"__geoMeta": {
|
||||
"id": "[uuid]",
|
||||
"sourceRange": []
|
||||
},
|
||||
"from": [
|
||||
10.0,
|
||||
-10.0
|
||||
],
|
||||
"tag": null,
|
||||
"to": [
|
||||
10.0,
|
||||
10.0
|
||||
],
|
||||
"type": "ToPoint",
|
||||
"units": {
|
||||
"type": "Mm"
|
||||
}
|
||||
},
|
||||
{
|
||||
"__geoMeta": {
|
||||
"id": "[uuid]",
|
||||
"sourceRange": []
|
||||
},
|
||||
"from": [
|
||||
10.0,
|
||||
10.0
|
||||
],
|
||||
"tag": null,
|
||||
"to": [
|
||||
-10.0,
|
||||
10.0
|
||||
],
|
||||
"type": "ToPoint",
|
||||
"units": {
|
||||
"type": "Mm"
|
||||
}
|
||||
},
|
||||
{
|
||||
"__geoMeta": {
|
||||
"id": "[uuid]",
|
||||
"sourceRange": []
|
||||
},
|
||||
"from": [
|
||||
-10.0,
|
||||
10.0
|
||||
],
|
||||
"tag": null,
|
||||
"to": [
|
||||
-10.0,
|
||||
-10.0
|
||||
],
|
||||
"type": "ToPoint",
|
||||
"units": {
|
||||
"type": "Mm"
|
||||
}
|
||||
}
|
||||
],
|
||||
"on": {
|
||||
"type": "plane",
|
||||
"id": "[uuid]",
|
||||
"artifactId": "[uuid]",
|
||||
"value": "XY",
|
||||
"origin": {
|
||||
"x": 0.0,
|
||||
"y": 0.0,
|
||||
"z": 0.0
|
||||
},
|
||||
"xAxis": {
|
||||
"x": 1.0,
|
||||
"y": 0.0,
|
||||
"z": 0.0
|
||||
},
|
||||
"yAxis": {
|
||||
"x": 0.0,
|
||||
"y": 1.0,
|
||||
"z": 0.0
|
||||
},
|
||||
"zAxis": {
|
||||
"x": 0.0,
|
||||
"y": 0.0,
|
||||
"z": 1.0
|
||||
},
|
||||
"units": {
|
||||
"type": "Mm"
|
||||
}
|
||||
},
|
||||
"start": {
|
||||
"from": [
|
||||
-10.0,
|
||||
-10.0
|
||||
],
|
||||
"to": [
|
||||
-10.0,
|
||||
-10.0
|
||||
],
|
||||
"units": {
|
||||
"type": "Mm"
|
||||
},
|
||||
"tag": null,
|
||||
"__geoMeta": {
|
||||
"id": "[uuid]",
|
||||
"sourceRange": []
|
||||
}
|
||||
},
|
||||
"artifactId": "[uuid]",
|
||||
"originalId": "[uuid]",
|
||||
"units": {
|
||||
"type": "Mm"
|
||||
}
|
||||
},
|
||||
"height": 10.0,
|
||||
"startCapId": "[uuid]",
|
||||
"endCapId": "[uuid]",
|
||||
"units": {
|
||||
"type": "Mm"
|
||||
}
|
||||
},
|
||||
"artifactId": "[uuid]",
|
||||
"originalId": "[uuid]",
|
||||
"units": {
|
||||
"type": "Mm"
|
||||
}
|
||||
},
|
||||
"height": 10.0,
|
||||
"startCapId": "[uuid]",
|
||||
"endCapId": "[uuid]",
|
||||
"units": {
|
||||
"type": "Mm"
|
||||
{
|
||||
"type": "Solid",
|
||||
"value": {
|
||||
"type": "Solid",
|
||||
"id": "[uuid]",
|
||||
"artifactId": "[uuid]",
|
||||
"value": [
|
||||
{
|
||||
"faceId": "[uuid]",
|
||||
"id": "[uuid]",
|
||||
"sourceRange": [],
|
||||
"tag": null,
|
||||
"type": "extrudePlane"
|
||||
},
|
||||
{
|
||||
"faceId": "[uuid]",
|
||||
"id": "[uuid]",
|
||||
"sourceRange": [],
|
||||
"tag": null,
|
||||
"type": "extrudePlane"
|
||||
},
|
||||
{
|
||||
"faceId": "[uuid]",
|
||||
"id": "[uuid]",
|
||||
"sourceRange": [],
|
||||
"tag": null,
|
||||
"type": "extrudePlane"
|
||||
},
|
||||
{
|
||||
"faceId": "[uuid]",
|
||||
"id": "[uuid]",
|
||||
"sourceRange": [],
|
||||
"tag": null,
|
||||
"type": "extrudePlane"
|
||||
}
|
||||
],
|
||||
"sketch": {
|
||||
"type": "Sketch",
|
||||
"id": "[uuid]",
|
||||
"paths": [
|
||||
{
|
||||
"__geoMeta": {
|
||||
"id": "[uuid]",
|
||||
"sourceRange": []
|
||||
},
|
||||
"from": [
|
||||
-10.0,
|
||||
-10.0
|
||||
],
|
||||
"tag": null,
|
||||
"to": [
|
||||
10.0,
|
||||
-10.0
|
||||
],
|
||||
"type": "ToPoint",
|
||||
"units": {
|
||||
"type": "Mm"
|
||||
}
|
||||
},
|
||||
{
|
||||
"__geoMeta": {
|
||||
"id": "[uuid]",
|
||||
"sourceRange": []
|
||||
},
|
||||
"from": [
|
||||
10.0,
|
||||
-10.0
|
||||
],
|
||||
"tag": null,
|
||||
"to": [
|
||||
10.0,
|
||||
10.0
|
||||
],
|
||||
"type": "ToPoint",
|
||||
"units": {
|
||||
"type": "Mm"
|
||||
}
|
||||
},
|
||||
{
|
||||
"__geoMeta": {
|
||||
"id": "[uuid]",
|
||||
"sourceRange": []
|
||||
},
|
||||
"from": [
|
||||
10.0,
|
||||
10.0
|
||||
],
|
||||
"tag": null,
|
||||
"to": [
|
||||
-10.0,
|
||||
10.0
|
||||
],
|
||||
"type": "ToPoint",
|
||||
"units": {
|
||||
"type": "Mm"
|
||||
}
|
||||
},
|
||||
{
|
||||
"__geoMeta": {
|
||||
"id": "[uuid]",
|
||||
"sourceRange": []
|
||||
},
|
||||
"from": [
|
||||
-10.0,
|
||||
10.0
|
||||
],
|
||||
"tag": null,
|
||||
"to": [
|
||||
-10.0,
|
||||
-10.0
|
||||
],
|
||||
"type": "ToPoint",
|
||||
"units": {
|
||||
"type": "Mm"
|
||||
}
|
||||
}
|
||||
],
|
||||
"on": {
|
||||
"type": "plane",
|
||||
"id": "[uuid]",
|
||||
"artifactId": "[uuid]",
|
||||
"value": "XY",
|
||||
"origin": {
|
||||
"x": 0.0,
|
||||
"y": 0.0,
|
||||
"z": 0.0
|
||||
},
|
||||
"xAxis": {
|
||||
"x": 1.0,
|
||||
"y": 0.0,
|
||||
"z": 0.0
|
||||
},
|
||||
"yAxis": {
|
||||
"x": 0.0,
|
||||
"y": 1.0,
|
||||
"z": 0.0
|
||||
},
|
||||
"zAxis": {
|
||||
"x": 0.0,
|
||||
"y": 0.0,
|
||||
"z": 1.0
|
||||
},
|
||||
"units": {
|
||||
"type": "Mm"
|
||||
}
|
||||
},
|
||||
"start": {
|
||||
"from": [
|
||||
-10.0,
|
||||
-10.0
|
||||
],
|
||||
"to": [
|
||||
-10.0,
|
||||
-10.0
|
||||
],
|
||||
"units": {
|
||||
"type": "Mm"
|
||||
},
|
||||
"tag": null,
|
||||
"__geoMeta": {
|
||||
"id": "[uuid]",
|
||||
"sourceRange": []
|
||||
}
|
||||
},
|
||||
"artifactId": "[uuid]",
|
||||
"originalId": "[uuid]",
|
||||
"units": {
|
||||
"type": "Mm"
|
||||
}
|
||||
},
|
||||
"height": 10.0,
|
||||
"startCapId": "[uuid]",
|
||||
"endCapId": "[uuid]",
|
||||
"units": {
|
||||
"type": "Mm"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"part001": {
|
||||
"type": "Solid",
|
||||
@ -388,18 +571,18 @@ description: Variables in memory after executing subtract_cylinder_from_cube.kcl
|
||||
},
|
||||
"ccw": true,
|
||||
"center": [
|
||||
0.0,
|
||||
0.0
|
||||
2.0,
|
||||
2.0
|
||||
],
|
||||
"from": [
|
||||
2.0,
|
||||
0.0
|
||||
4.0,
|
||||
2.0
|
||||
],
|
||||
"radius": 2.0,
|
||||
"tag": null,
|
||||
"to": [
|
||||
2.0,
|
||||
0.0
|
||||
4.0,
|
||||
2.0
|
||||
],
|
||||
"type": "Circle",
|
||||
"units": {
|
||||
@ -438,12 +621,12 @@ description: Variables in memory after executing subtract_cylinder_from_cube.kcl
|
||||
},
|
||||
"start": {
|
||||
"from": [
|
||||
2.0,
|
||||
0.0
|
||||
4.0,
|
||||
2.0
|
||||
],
|
||||
"to": [
|
||||
2.0,
|
||||
0.0
|
||||
4.0,
|
||||
2.0
|
||||
],
|
||||
"units": {
|
||||
"type": "Mm"
|
||||
@ -460,7 +643,7 @@ description: Variables in memory after executing subtract_cylinder_from_cube.kcl
|
||||
"type": "Mm"
|
||||
}
|
||||
},
|
||||
"height": 10.0,
|
||||
"height": 5.0,
|
||||
"startCapId": "[uuid]",
|
||||
"endCapId": "[uuid]",
|
||||
"units": {
|
||||
|
Before Width: | Height: | Size: 70 KiB After Width: | Height: | Size: 70 KiB |
@ -14,7 +14,7 @@ fn cube(center) {
|
||||
|
||||
part001 = cube([0, 0])
|
||||
part002 = startSketchOn(XY)
|
||||
|> circle(center = [0, 0], radius = 2)
|
||||
|> extrude(length = 10)
|
||||
|> circle(center = [2, 2], radius = 2)
|
||||
|> extrude(length = 5)
|
||||
|
||||
fullPart = subtract([part001], tools = [part002])
|
||||
|
@ -178,7 +178,7 @@ description: Artifact commands union_cubes.kcl
|
||||
"command": {
|
||||
"type": "extrude",
|
||||
"target": "[uuid]",
|
||||
"distance": 10.0,
|
||||
"distance": 20.0,
|
||||
"faces": null,
|
||||
"opposite": "None"
|
||||
}
|
||||
@ -342,8 +342,8 @@ description: Artifact commands union_cubes.kcl
|
||||
"type": "move_path_pen",
|
||||
"path": "[uuid]",
|
||||
"to": {
|
||||
"x": 10.0,
|
||||
"y": 0.0,
|
||||
"x": 2.0,
|
||||
"y": -2.0,
|
||||
"z": 0.0
|
||||
}
|
||||
}
|
||||
@ -364,8 +364,8 @@ description: Artifact commands union_cubes.kcl
|
||||
"segment": {
|
||||
"type": "line",
|
||||
"end": {
|
||||
"x": 30.0,
|
||||
"y": 0.0,
|
||||
"x": 12.0,
|
||||
"y": -2.0,
|
||||
"z": 0.0
|
||||
},
|
||||
"relative": false
|
||||
@ -381,8 +381,8 @@ description: Artifact commands union_cubes.kcl
|
||||
"segment": {
|
||||
"type": "line",
|
||||
"end": {
|
||||
"x": 30.0,
|
||||
"y": 20.0,
|
||||
"x": 12.0,
|
||||
"y": 8.0,
|
||||
"z": 0.0
|
||||
},
|
||||
"relative": false
|
||||
@ -398,8 +398,8 @@ description: Artifact commands union_cubes.kcl
|
||||
"segment": {
|
||||
"type": "line",
|
||||
"end": {
|
||||
"x": 10.0,
|
||||
"y": 20.0,
|
||||
"x": 2.0,
|
||||
"y": 8.0,
|
||||
"z": 0.0
|
||||
},
|
||||
"relative": false
|
||||
@ -544,5 +544,41 @@ description: Artifact commands union_cubes.kcl
|
||||
"edge_id": "[uuid]",
|
||||
"face_id": "[uuid]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cmdId": "[uuid]",
|
||||
"range": [],
|
||||
"command": {
|
||||
"type": "set_object_transform",
|
||||
"object_id": "[uuid]",
|
||||
"transforms": [
|
||||
{
|
||||
"translate": {
|
||||
"property": {
|
||||
"x": 0.0,
|
||||
"y": 0.0,
|
||||
"z": 1.0
|
||||
},
|
||||
"set": false,
|
||||
"is_local": true
|
||||
},
|
||||
"rotate_rpy": null,
|
||||
"rotate_angle_axis": null,
|
||||
"scale": null
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"cmdId": "[uuid]",
|
||||
"range": [],
|
||||
"command": {
|
||||
"type": "boolean_union",
|
||||
"solid_ids": [
|
||||
"[uuid]",
|
||||
"[uuid]"
|
||||
],
|
||||
"tolerance": 0.0000001
|
||||
}
|
||||
}
|
||||
]
|
||||
|
@ -1,23 +1,23 @@
|
||||
```mermaid
|
||||
flowchart LR
|
||||
subgraph path2 [Path]
|
||||
2["Path<br>[52, 103, 0]"]
|
||||
3["Segment<br>[111, 163, 0]"]
|
||||
4["Segment<br>[171, 223, 0]"]
|
||||
5["Segment<br>[231, 283, 0]"]
|
||||
6["Segment<br>[291, 298, 0]"]
|
||||
2["Path<br>[58, 113, 0]"]
|
||||
3["Segment<br>[121, 177, 0]"]
|
||||
4["Segment<br>[185, 241, 0]"]
|
||||
5["Segment<br>[249, 305, 0]"]
|
||||
6["Segment<br>[313, 320, 0]"]
|
||||
7[Solid2d]
|
||||
end
|
||||
subgraph path24 [Path]
|
||||
24["Path<br>[52, 103, 0]"]
|
||||
25["Segment<br>[111, 163, 0]"]
|
||||
26["Segment<br>[171, 223, 0]"]
|
||||
27["Segment<br>[231, 283, 0]"]
|
||||
28["Segment<br>[291, 298, 0]"]
|
||||
24["Path<br>[58, 113, 0]"]
|
||||
25["Segment<br>[121, 177, 0]"]
|
||||
26["Segment<br>[185, 241, 0]"]
|
||||
27["Segment<br>[249, 305, 0]"]
|
||||
28["Segment<br>[313, 320, 0]"]
|
||||
29[Solid2d]
|
||||
end
|
||||
1["Plane<br>[27, 44, 0]"]
|
||||
8["Sweep Extrusion<br>[306, 326, 0]"]
|
||||
1["Plane<br>[33, 50, 0]"]
|
||||
8["Sweep Extrusion<br>[328, 354, 0]"]
|
||||
9[Wall]
|
||||
10[Wall]
|
||||
11[Wall]
|
||||
@ -32,8 +32,8 @@ flowchart LR
|
||||
20["SweepEdge Adjacent"]
|
||||
21["SweepEdge Opposite"]
|
||||
22["SweepEdge Adjacent"]
|
||||
23["Plane<br>[27, 44, 0]"]
|
||||
30["Sweep Extrusion<br>[306, 326, 0]"]
|
||||
23["Plane<br>[33, 50, 0]"]
|
||||
30["Sweep Extrusion<br>[328, 354, 0]"]
|
||||
31[Wall]
|
||||
32[Wall]
|
||||
33[Wall]
|
||||
|
@ -101,16 +101,20 @@ description: Result of parsing union_cubes.kcl
|
||||
},
|
||||
"operator": "-",
|
||||
"right": {
|
||||
"abs_path": false,
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"raw": "10",
|
||||
"name": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "size",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"path": [],
|
||||
"start": 0,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 10.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
"type": "Name",
|
||||
"type": "Name"
|
||||
},
|
||||
"start": 0,
|
||||
"type": "BinaryExpression",
|
||||
@ -149,16 +153,20 @@ description: Result of parsing union_cubes.kcl
|
||||
},
|
||||
"operator": "-",
|
||||
"right": {
|
||||
"abs_path": false,
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"raw": "10",
|
||||
"name": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "size",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"path": [],
|
||||
"start": 0,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 10.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
"type": "Name",
|
||||
"type": "Name"
|
||||
},
|
||||
"start": 0,
|
||||
"type": "BinaryExpression",
|
||||
@ -246,16 +254,20 @@ description: Result of parsing union_cubes.kcl
|
||||
},
|
||||
"operator": "+",
|
||||
"right": {
|
||||
"abs_path": false,
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"raw": "10",
|
||||
"name": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "size",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"path": [],
|
||||
"start": 0,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 10.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
"type": "Name",
|
||||
"type": "Name"
|
||||
},
|
||||
"start": 0,
|
||||
"type": "BinaryExpression",
|
||||
@ -294,16 +306,20 @@ description: Result of parsing union_cubes.kcl
|
||||
},
|
||||
"operator": "-",
|
||||
"right": {
|
||||
"abs_path": false,
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"raw": "10",
|
||||
"name": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "size",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"path": [],
|
||||
"start": 0,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 10.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
"type": "Name",
|
||||
"type": "Name"
|
||||
},
|
||||
"start": 0,
|
||||
"type": "BinaryExpression",
|
||||
@ -386,16 +402,20 @@ description: Result of parsing union_cubes.kcl
|
||||
},
|
||||
"operator": "+",
|
||||
"right": {
|
||||
"abs_path": false,
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"raw": "10",
|
||||
"name": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "size",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"path": [],
|
||||
"start": 0,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 10.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
"type": "Name",
|
||||
"type": "Name"
|
||||
},
|
||||
"start": 0,
|
||||
"type": "BinaryExpression",
|
||||
@ -434,16 +454,20 @@ description: Result of parsing union_cubes.kcl
|
||||
},
|
||||
"operator": "+",
|
||||
"right": {
|
||||
"abs_path": false,
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"raw": "10",
|
||||
"name": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "size",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"path": [],
|
||||
"start": 0,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 10.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
"type": "Name",
|
||||
"type": "Name"
|
||||
},
|
||||
"start": 0,
|
||||
"type": "BinaryExpression",
|
||||
@ -526,16 +550,20 @@ description: Result of parsing union_cubes.kcl
|
||||
},
|
||||
"operator": "-",
|
||||
"right": {
|
||||
"abs_path": false,
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"raw": "10",
|
||||
"name": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "size",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"path": [],
|
||||
"start": 0,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 10.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
"type": "Name",
|
||||
"type": "Name"
|
||||
},
|
||||
"start": 0,
|
||||
"type": "BinaryExpression",
|
||||
@ -574,16 +602,20 @@ description: Result of parsing union_cubes.kcl
|
||||
},
|
||||
"operator": "+",
|
||||
"right": {
|
||||
"abs_path": false,
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"raw": "10",
|
||||
"name": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "size",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"path": [],
|
||||
"start": 0,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 10.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
"type": "Name",
|
||||
"type": "Name"
|
||||
},
|
||||
"start": 0,
|
||||
"type": "BinaryExpression",
|
||||
@ -656,14 +688,38 @@ description: Result of parsing union_cubes.kcl
|
||||
"arg": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"raw": "10",
|
||||
"left": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"raw": "2",
|
||||
"start": 0,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 2.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
},
|
||||
"operator": "*",
|
||||
"right": {
|
||||
"abs_path": false,
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "size",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"path": [],
|
||||
"start": 0,
|
||||
"type": "Name",
|
||||
"type": "Name"
|
||||
},
|
||||
"start": 0,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 10.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
"type": "BinaryExpression",
|
||||
"type": "BinaryExpression"
|
||||
}
|
||||
}
|
||||
],
|
||||
@ -719,6 +775,16 @@ description: Result of parsing union_cubes.kcl
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Parameter",
|
||||
"identifier": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "size",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
}
|
||||
}
|
||||
],
|
||||
"start": 0,
|
||||
@ -780,6 +846,18 @@ description: Result of parsing union_cubes.kcl
|
||||
"start": 0,
|
||||
"type": "ArrayExpression",
|
||||
"type": "ArrayExpression"
|
||||
},
|
||||
{
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"raw": "10",
|
||||
"start": 0,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 10.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
}
|
||||
],
|
||||
"callee": {
|
||||
@ -825,61 +903,129 @@ description: Result of parsing union_cubes.kcl
|
||||
"type": "Identifier"
|
||||
},
|
||||
"init": {
|
||||
"arguments": [
|
||||
"body": [
|
||||
{
|
||||
"commentStart": 0,
|
||||
"elements": [
|
||||
"arguments": [
|
||||
{
|
||||
"commentStart": 0,
|
||||
"elements": [
|
||||
{
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"raw": "7",
|
||||
"start": 0,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 7.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
},
|
||||
{
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"raw": "3",
|
||||
"start": 0,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 3.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
}
|
||||
],
|
||||
"end": 0,
|
||||
"raw": "20",
|
||||
"start": 0,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 20.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
"type": "ArrayExpression",
|
||||
"type": "ArrayExpression"
|
||||
},
|
||||
{
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"raw": "10",
|
||||
"raw": "5",
|
||||
"start": 0,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 10.0,
|
||||
"value": 5.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
}
|
||||
],
|
||||
"end": 0,
|
||||
"start": 0,
|
||||
"type": "ArrayExpression",
|
||||
"type": "ArrayExpression"
|
||||
}
|
||||
],
|
||||
"callee": {
|
||||
"abs_path": false,
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": {
|
||||
"callee": {
|
||||
"abs_path": false,
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "cube",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"path": [],
|
||||
"start": 0,
|
||||
"type": "Name"
|
||||
},
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "cube",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
"type": "CallExpression",
|
||||
"type": "CallExpression"
|
||||
},
|
||||
"path": [],
|
||||
"start": 0,
|
||||
"type": "Name"
|
||||
},
|
||||
{
|
||||
"arguments": [
|
||||
{
|
||||
"type": "LabeledArg",
|
||||
"label": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "z",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"arg": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"raw": "1",
|
||||
"start": 0,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 1.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"callee": {
|
||||
"abs_path": false,
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "translate",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"path": [],
|
||||
"start": 0,
|
||||
"type": "Name"
|
||||
},
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"start": 0,
|
||||
"type": "CallExpressionKw",
|
||||
"type": "CallExpressionKw",
|
||||
"unlabeled": null
|
||||
}
|
||||
],
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"start": 0,
|
||||
"type": "CallExpression",
|
||||
"type": "CallExpression"
|
||||
"type": "PipeExpression",
|
||||
"type": "PipeExpression"
|
||||
},
|
||||
"start": 0,
|
||||
"type": "VariableDeclarator"
|
||||
|
@ -1,14 +1,15 @@
|
||||
fn cube(center) {
|
||||
fn cube(center, size) {
|
||||
return startSketchOn(XY)
|
||||
|> startProfileAt([center[0] - 10, center[1] - 10], %)
|
||||
|> line(endAbsolute = [center[0] + 10, center[1] - 10])
|
||||
|> line(endAbsolute = [center[0] + 10, center[1] + 10])
|
||||
|> line(endAbsolute = [center[0] - 10, center[1] + 10])
|
||||
|> startProfileAt([center[0] - size, center[1] - size], %)
|
||||
|> line(endAbsolute = [center[0] + size, center[1] - size])
|
||||
|> line(endAbsolute = [center[0] + size, center[1] + size])
|
||||
|> line(endAbsolute = [center[0] - size, center[1] + size])
|
||||
|> close()
|
||||
|> extrude(length = 10)
|
||||
|> extrude(length = 2 * size)
|
||||
}
|
||||
|
||||
part001 = cube([0, 0])
|
||||
part002 = cube([20, 10])
|
||||
part001 = cube([0, 0], 10)
|
||||
part002 = cube([7, 3], 5)
|
||||
|> translate(z = 1)
|
||||
|
||||
fullPart = union([part001, part002])
|
||||
|
@ -10,7 +10,7 @@ description: Operations executed union_cubes.kcl
|
||||
"name": "cube",
|
||||
"functionSourceRange": [
|
||||
7,
|
||||
328,
|
||||
356,
|
||||
0
|
||||
],
|
||||
"unlabeledArg": null,
|
||||
@ -38,7 +38,7 @@ description: Operations executed union_cubes.kcl
|
||||
"length": {
|
||||
"value": {
|
||||
"type": "Number",
|
||||
"value": 10.0,
|
||||
"value": 20.0,
|
||||
"ty": {
|
||||
"type": "Default",
|
||||
"len": {
|
||||
@ -75,7 +75,7 @@ description: Operations executed union_cubes.kcl
|
||||
"name": "cube",
|
||||
"functionSourceRange": [
|
||||
7,
|
||||
328,
|
||||
356,
|
||||
0
|
||||
],
|
||||
"unlabeledArg": null,
|
||||
|
@ -7,182 +7,365 @@ description: Variables in memory after executing union_cubes.kcl
|
||||
"type": "Function"
|
||||
},
|
||||
"fullPart": {
|
||||
"type": "Solid",
|
||||
"value": {
|
||||
"type": "Solid",
|
||||
"id": "[uuid]",
|
||||
"artifactId": "[uuid]",
|
||||
"value": [
|
||||
{
|
||||
"faceId": "[uuid]",
|
||||
"id": "[uuid]",
|
||||
"sourceRange": [],
|
||||
"tag": null,
|
||||
"type": "extrudePlane"
|
||||
},
|
||||
{
|
||||
"faceId": "[uuid]",
|
||||
"id": "[uuid]",
|
||||
"sourceRange": [],
|
||||
"tag": null,
|
||||
"type": "extrudePlane"
|
||||
},
|
||||
{
|
||||
"faceId": "[uuid]",
|
||||
"id": "[uuid]",
|
||||
"sourceRange": [],
|
||||
"tag": null,
|
||||
"type": "extrudePlane"
|
||||
},
|
||||
{
|
||||
"faceId": "[uuid]",
|
||||
"id": "[uuid]",
|
||||
"sourceRange": [],
|
||||
"tag": null,
|
||||
"type": "extrudePlane"
|
||||
}
|
||||
],
|
||||
"sketch": {
|
||||
"type": "Sketch",
|
||||
"id": "[uuid]",
|
||||
"paths": [
|
||||
{
|
||||
"__geoMeta": {
|
||||
"id": "[uuid]",
|
||||
"sourceRange": []
|
||||
},
|
||||
"from": [
|
||||
-10.0,
|
||||
-10.0
|
||||
],
|
||||
"tag": null,
|
||||
"to": [
|
||||
10.0,
|
||||
-10.0
|
||||
],
|
||||
"type": "ToPoint",
|
||||
"units": {
|
||||
"type": "Mm"
|
||||
}
|
||||
},
|
||||
{
|
||||
"__geoMeta": {
|
||||
"id": "[uuid]",
|
||||
"sourceRange": []
|
||||
},
|
||||
"from": [
|
||||
10.0,
|
||||
-10.0
|
||||
],
|
||||
"tag": null,
|
||||
"to": [
|
||||
10.0,
|
||||
10.0
|
||||
],
|
||||
"type": "ToPoint",
|
||||
"units": {
|
||||
"type": "Mm"
|
||||
}
|
||||
},
|
||||
{
|
||||
"__geoMeta": {
|
||||
"id": "[uuid]",
|
||||
"sourceRange": []
|
||||
},
|
||||
"from": [
|
||||
10.0,
|
||||
10.0
|
||||
],
|
||||
"tag": null,
|
||||
"to": [
|
||||
-10.0,
|
||||
10.0
|
||||
],
|
||||
"type": "ToPoint",
|
||||
"units": {
|
||||
"type": "Mm"
|
||||
}
|
||||
},
|
||||
{
|
||||
"__geoMeta": {
|
||||
"id": "[uuid]",
|
||||
"sourceRange": []
|
||||
},
|
||||
"from": [
|
||||
-10.0,
|
||||
10.0
|
||||
],
|
||||
"tag": null,
|
||||
"to": [
|
||||
-10.0,
|
||||
-10.0
|
||||
],
|
||||
"type": "ToPoint",
|
||||
"units": {
|
||||
"type": "Mm"
|
||||
}
|
||||
}
|
||||
],
|
||||
"on": {
|
||||
"type": "plane",
|
||||
"type": "HomArray",
|
||||
"value": [
|
||||
{
|
||||
"type": "Solid",
|
||||
"value": {
|
||||
"type": "Solid",
|
||||
"id": "[uuid]",
|
||||
"artifactId": "[uuid]",
|
||||
"value": "XY",
|
||||
"origin": {
|
||||
"x": 0.0,
|
||||
"y": 0.0,
|
||||
"z": 0.0
|
||||
},
|
||||
"xAxis": {
|
||||
"x": 1.0,
|
||||
"y": 0.0,
|
||||
"z": 0.0
|
||||
},
|
||||
"yAxis": {
|
||||
"x": 0.0,
|
||||
"y": 1.0,
|
||||
"z": 0.0
|
||||
},
|
||||
"zAxis": {
|
||||
"x": 0.0,
|
||||
"y": 0.0,
|
||||
"z": 1.0
|
||||
},
|
||||
"units": {
|
||||
"type": "Mm"
|
||||
}
|
||||
},
|
||||
"start": {
|
||||
"from": [
|
||||
-10.0,
|
||||
-10.0
|
||||
"value": [
|
||||
{
|
||||
"faceId": "[uuid]",
|
||||
"id": "[uuid]",
|
||||
"sourceRange": [],
|
||||
"tag": null,
|
||||
"type": "extrudePlane"
|
||||
},
|
||||
{
|
||||
"faceId": "[uuid]",
|
||||
"id": "[uuid]",
|
||||
"sourceRange": [],
|
||||
"tag": null,
|
||||
"type": "extrudePlane"
|
||||
},
|
||||
{
|
||||
"faceId": "[uuid]",
|
||||
"id": "[uuid]",
|
||||
"sourceRange": [],
|
||||
"tag": null,
|
||||
"type": "extrudePlane"
|
||||
},
|
||||
{
|
||||
"faceId": "[uuid]",
|
||||
"id": "[uuid]",
|
||||
"sourceRange": [],
|
||||
"tag": null,
|
||||
"type": "extrudePlane"
|
||||
}
|
||||
],
|
||||
"to": [
|
||||
-10.0,
|
||||
-10.0
|
||||
],
|
||||
"units": {
|
||||
"type": "Mm"
|
||||
},
|
||||
"tag": null,
|
||||
"__geoMeta": {
|
||||
"sketch": {
|
||||
"type": "Sketch",
|
||||
"id": "[uuid]",
|
||||
"sourceRange": []
|
||||
"paths": [
|
||||
{
|
||||
"__geoMeta": {
|
||||
"id": "[uuid]",
|
||||
"sourceRange": []
|
||||
},
|
||||
"from": [
|
||||
-10.0,
|
||||
-10.0
|
||||
],
|
||||
"tag": null,
|
||||
"to": [
|
||||
10.0,
|
||||
-10.0
|
||||
],
|
||||
"type": "ToPoint",
|
||||
"units": {
|
||||
"type": "Mm"
|
||||
}
|
||||
},
|
||||
{
|
||||
"__geoMeta": {
|
||||
"id": "[uuid]",
|
||||
"sourceRange": []
|
||||
},
|
||||
"from": [
|
||||
10.0,
|
||||
-10.0
|
||||
],
|
||||
"tag": null,
|
||||
"to": [
|
||||
10.0,
|
||||
10.0
|
||||
],
|
||||
"type": "ToPoint",
|
||||
"units": {
|
||||
"type": "Mm"
|
||||
}
|
||||
},
|
||||
{
|
||||
"__geoMeta": {
|
||||
"id": "[uuid]",
|
||||
"sourceRange": []
|
||||
},
|
||||
"from": [
|
||||
10.0,
|
||||
10.0
|
||||
],
|
||||
"tag": null,
|
||||
"to": [
|
||||
-10.0,
|
||||
10.0
|
||||
],
|
||||
"type": "ToPoint",
|
||||
"units": {
|
||||
"type": "Mm"
|
||||
}
|
||||
},
|
||||
{
|
||||
"__geoMeta": {
|
||||
"id": "[uuid]",
|
||||
"sourceRange": []
|
||||
},
|
||||
"from": [
|
||||
-10.0,
|
||||
10.0
|
||||
],
|
||||
"tag": null,
|
||||
"to": [
|
||||
-10.0,
|
||||
-10.0
|
||||
],
|
||||
"type": "ToPoint",
|
||||
"units": {
|
||||
"type": "Mm"
|
||||
}
|
||||
}
|
||||
],
|
||||
"on": {
|
||||
"type": "plane",
|
||||
"id": "[uuid]",
|
||||
"artifactId": "[uuid]",
|
||||
"value": "XY",
|
||||
"origin": {
|
||||
"x": 0.0,
|
||||
"y": 0.0,
|
||||
"z": 0.0
|
||||
},
|
||||
"xAxis": {
|
||||
"x": 1.0,
|
||||
"y": 0.0,
|
||||
"z": 0.0
|
||||
},
|
||||
"yAxis": {
|
||||
"x": 0.0,
|
||||
"y": 1.0,
|
||||
"z": 0.0
|
||||
},
|
||||
"zAxis": {
|
||||
"x": 0.0,
|
||||
"y": 0.0,
|
||||
"z": 1.0
|
||||
},
|
||||
"units": {
|
||||
"type": "Mm"
|
||||
}
|
||||
},
|
||||
"start": {
|
||||
"from": [
|
||||
-10.0,
|
||||
-10.0
|
||||
],
|
||||
"to": [
|
||||
-10.0,
|
||||
-10.0
|
||||
],
|
||||
"units": {
|
||||
"type": "Mm"
|
||||
},
|
||||
"tag": null,
|
||||
"__geoMeta": {
|
||||
"id": "[uuid]",
|
||||
"sourceRange": []
|
||||
}
|
||||
},
|
||||
"artifactId": "[uuid]",
|
||||
"originalId": "[uuid]",
|
||||
"units": {
|
||||
"type": "Mm"
|
||||
}
|
||||
},
|
||||
"height": 20.0,
|
||||
"startCapId": "[uuid]",
|
||||
"endCapId": "[uuid]",
|
||||
"units": {
|
||||
"type": "Mm"
|
||||
}
|
||||
},
|
||||
"artifactId": "[uuid]",
|
||||
"originalId": "[uuid]",
|
||||
"units": {
|
||||
"type": "Mm"
|
||||
}
|
||||
},
|
||||
"height": 10.0,
|
||||
"startCapId": "[uuid]",
|
||||
"endCapId": "[uuid]",
|
||||
"units": {
|
||||
"type": "Mm"
|
||||
{
|
||||
"type": "Solid",
|
||||
"value": {
|
||||
"type": "Solid",
|
||||
"id": "[uuid]",
|
||||
"artifactId": "[uuid]",
|
||||
"value": [
|
||||
{
|
||||
"faceId": "[uuid]",
|
||||
"id": "[uuid]",
|
||||
"sourceRange": [],
|
||||
"tag": null,
|
||||
"type": "extrudePlane"
|
||||
},
|
||||
{
|
||||
"faceId": "[uuid]",
|
||||
"id": "[uuid]",
|
||||
"sourceRange": [],
|
||||
"tag": null,
|
||||
"type": "extrudePlane"
|
||||
},
|
||||
{
|
||||
"faceId": "[uuid]",
|
||||
"id": "[uuid]",
|
||||
"sourceRange": [],
|
||||
"tag": null,
|
||||
"type": "extrudePlane"
|
||||
},
|
||||
{
|
||||
"faceId": "[uuid]",
|
||||
"id": "[uuid]",
|
||||
"sourceRange": [],
|
||||
"tag": null,
|
||||
"type": "extrudePlane"
|
||||
}
|
||||
],
|
||||
"sketch": {
|
||||
"type": "Sketch",
|
||||
"id": "[uuid]",
|
||||
"paths": [
|
||||
{
|
||||
"__geoMeta": {
|
||||
"id": "[uuid]",
|
||||
"sourceRange": []
|
||||
},
|
||||
"from": [
|
||||
-10.0,
|
||||
-10.0
|
||||
],
|
||||
"tag": null,
|
||||
"to": [
|
||||
10.0,
|
||||
-10.0
|
||||
],
|
||||
"type": "ToPoint",
|
||||
"units": {
|
||||
"type": "Mm"
|
||||
}
|
||||
},
|
||||
{
|
||||
"__geoMeta": {
|
||||
"id": "[uuid]",
|
||||
"sourceRange": []
|
||||
},
|
||||
"from": [
|
||||
10.0,
|
||||
-10.0
|
||||
],
|
||||
"tag": null,
|
||||
"to": [
|
||||
10.0,
|
||||
10.0
|
||||
],
|
||||
"type": "ToPoint",
|
||||
"units": {
|
||||
"type": "Mm"
|
||||
}
|
||||
},
|
||||
{
|
||||
"__geoMeta": {
|
||||
"id": "[uuid]",
|
||||
"sourceRange": []
|
||||
},
|
||||
"from": [
|
||||
10.0,
|
||||
10.0
|
||||
],
|
||||
"tag": null,
|
||||
"to": [
|
||||
-10.0,
|
||||
10.0
|
||||
],
|
||||
"type": "ToPoint",
|
||||
"units": {
|
||||
"type": "Mm"
|
||||
}
|
||||
},
|
||||
{
|
||||
"__geoMeta": {
|
||||
"id": "[uuid]",
|
||||
"sourceRange": []
|
||||
},
|
||||
"from": [
|
||||
-10.0,
|
||||
10.0
|
||||
],
|
||||
"tag": null,
|
||||
"to": [
|
||||
-10.0,
|
||||
-10.0
|
||||
],
|
||||
"type": "ToPoint",
|
||||
"units": {
|
||||
"type": "Mm"
|
||||
}
|
||||
}
|
||||
],
|
||||
"on": {
|
||||
"type": "plane",
|
||||
"id": "[uuid]",
|
||||
"artifactId": "[uuid]",
|
||||
"value": "XY",
|
||||
"origin": {
|
||||
"x": 0.0,
|
||||
"y": 0.0,
|
||||
"z": 0.0
|
||||
},
|
||||
"xAxis": {
|
||||
"x": 1.0,
|
||||
"y": 0.0,
|
||||
"z": 0.0
|
||||
},
|
||||
"yAxis": {
|
||||
"x": 0.0,
|
||||
"y": 1.0,
|
||||
"z": 0.0
|
||||
},
|
||||
"zAxis": {
|
||||
"x": 0.0,
|
||||
"y": 0.0,
|
||||
"z": 1.0
|
||||
},
|
||||
"units": {
|
||||
"type": "Mm"
|
||||
}
|
||||
},
|
||||
"start": {
|
||||
"from": [
|
||||
-10.0,
|
||||
-10.0
|
||||
],
|
||||
"to": [
|
||||
-10.0,
|
||||
-10.0
|
||||
],
|
||||
"units": {
|
||||
"type": "Mm"
|
||||
},
|
||||
"tag": null,
|
||||
"__geoMeta": {
|
||||
"id": "[uuid]",
|
||||
"sourceRange": []
|
||||
}
|
||||
},
|
||||
"artifactId": "[uuid]",
|
||||
"originalId": "[uuid]",
|
||||
"units": {
|
||||
"type": "Mm"
|
||||
}
|
||||
},
|
||||
"height": 20.0,
|
||||
"startCapId": "[uuid]",
|
||||
"endCapId": "[uuid]",
|
||||
"units": {
|
||||
"type": "Mm"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"part001": {
|
||||
"type": "Solid",
|
||||
@ -354,7 +537,7 @@ description: Variables in memory after executing union_cubes.kcl
|
||||
"type": "Mm"
|
||||
}
|
||||
},
|
||||
"height": 10.0,
|
||||
"height": 20.0,
|
||||
"startCapId": "[uuid]",
|
||||
"endCapId": "[uuid]",
|
||||
"units": {
|
||||
@ -408,13 +591,13 @@ description: Variables in memory after executing union_cubes.kcl
|
||||
"sourceRange": []
|
||||
},
|
||||
"from": [
|
||||
10.0,
|
||||
0.0
|
||||
2.0,
|
||||
-2.0
|
||||
],
|
||||
"tag": null,
|
||||
"to": [
|
||||
30.0,
|
||||
0.0
|
||||
12.0,
|
||||
-2.0
|
||||
],
|
||||
"type": "ToPoint",
|
||||
"units": {
|
||||
@ -427,13 +610,13 @@ description: Variables in memory after executing union_cubes.kcl
|
||||
"sourceRange": []
|
||||
},
|
||||
"from": [
|
||||
30.0,
|
||||
0.0
|
||||
12.0,
|
||||
-2.0
|
||||
],
|
||||
"tag": null,
|
||||
"to": [
|
||||
30.0,
|
||||
20.0
|
||||
12.0,
|
||||
8.0
|
||||
],
|
||||
"type": "ToPoint",
|
||||
"units": {
|
||||
@ -446,13 +629,13 @@ description: Variables in memory after executing union_cubes.kcl
|
||||
"sourceRange": []
|
||||
},
|
||||
"from": [
|
||||
30.0,
|
||||
20.0
|
||||
12.0,
|
||||
8.0
|
||||
],
|
||||
"tag": null,
|
||||
"to": [
|
||||
10.0,
|
||||
20.0
|
||||
2.0,
|
||||
8.0
|
||||
],
|
||||
"type": "ToPoint",
|
||||
"units": {
|
||||
@ -465,13 +648,13 @@ description: Variables in memory after executing union_cubes.kcl
|
||||
"sourceRange": []
|
||||
},
|
||||
"from": [
|
||||
10.0,
|
||||
20.0
|
||||
2.0,
|
||||
8.0
|
||||
],
|
||||
"tag": null,
|
||||
"to": [
|
||||
10.0,
|
||||
0.0
|
||||
2.0,
|
||||
-2.0
|
||||
],
|
||||
"type": "ToPoint",
|
||||
"units": {
|
||||
@ -510,12 +693,12 @@ description: Variables in memory after executing union_cubes.kcl
|
||||
},
|
||||
"start": {
|
||||
"from": [
|
||||
10.0,
|
||||
0.0
|
||||
2.0,
|
||||
-2.0
|
||||
],
|
||||
"to": [
|
||||
10.0,
|
||||
0.0
|
||||
2.0,
|
||||
-2.0
|
||||
],
|
||||
"units": {
|
||||
"type": "Mm"
|
||||
|
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 71 KiB |
@ -2,17 +2,18 @@
|
||||
source: kcl-lib/src/simulation_tests.rs
|
||||
description: Result of unparsing union_cubes.kcl
|
||||
---
|
||||
fn cube(center) {
|
||||
fn cube(center, size) {
|
||||
return startSketchOn(XY)
|
||||
|> startProfileAt([center[0] - 10, center[1] - 10], %)
|
||||
|> line(endAbsolute = [center[0] + 10, center[1] - 10])
|
||||
|> line(endAbsolute = [center[0] + 10, center[1] + 10])
|
||||
|> line(endAbsolute = [center[0] - 10, center[1] + 10])
|
||||
|> startProfileAt([center[0] - size, center[1] - size], %)
|
||||
|> line(endAbsolute = [center[0] + size, center[1] - size])
|
||||
|> line(endAbsolute = [center[0] + size, center[1] + size])
|
||||
|> line(endAbsolute = [center[0] - size, center[1] + size])
|
||||
|> close()
|
||||
|> extrude(length = 10)
|
||||
|> extrude(length = 2 * size)
|
||||
}
|
||||
|
||||
part001 = cube([0, 0])
|
||||
part002 = cube([20, 10])
|
||||
part001 = cube([0, 0], 10)
|
||||
part002 = cube([7, 3], 5)
|
||||
|> translate(z = 1)
|
||||
|
||||
fullPart = union([part001, part002])
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "kcl-python-bindings"
|
||||
version = "0.3.58"
|
||||
version = "0.3.59"
|
||||
edition = "2021"
|
||||
repository = "https://github.com/kittycad/modeling-app"
|
||||
exclude = ["tests/*", "files/*", "venv/*"]
|
||||
|
@ -1,7 +1,7 @@
|
||||
[package]
|
||||
name = "kcl-test-server"
|
||||
description = "A test server for KCL"
|
||||
version = "0.1.58"
|
||||
version = "0.1.59"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
[package]
|
||||
name = "kcl-to-core"
|
||||
description = "Utility methods to convert kcl to engine core executable tests"
|
||||
version = "0.1.58"
|
||||
version = "0.1.59"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
repository = "https://github.com/KittyCAD/modeling-app"
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "kcl-wasm-lib"
|
||||
version = "0.1.58"
|
||||
version = "0.1.59"
|
||||
edition = "2021"
|
||||
repository = "https://github.com/KittyCAD/modeling-app"
|
||||
rust-version = "1.83"
|
||||
|
@ -292,3 +292,22 @@ pub fn get_kcl_version() -> String {
|
||||
|
||||
kcl_lib::version().to_string()
|
||||
}
|
||||
|
||||
/// Get the allowed import file extensions.
|
||||
#[wasm_bindgen]
|
||||
pub fn import_file_extensions() -> Result<Vec<String>, String> {
|
||||
console_error_panic_hook::set_once();
|
||||
|
||||
Ok(kcl_lib::IMPORT_FILE_EXTENSIONS.iter().map(|s| s.to_string()).collect())
|
||||
}
|
||||
|
||||
/// Get the allowed relevant file extensions (imports + kcl).
|
||||
#[wasm_bindgen]
|
||||
pub fn relevant_file_extensions() -> Result<Vec<String>, String> {
|
||||
console_error_panic_hook::set_once();
|
||||
|
||||
Ok(kcl_lib::RELEVANT_FILE_EXTENSIONS
|
||||
.iter()
|
||||
.map(|s| s.to_string())
|
||||
.collect::<Vec<String>>())
|
||||
}
|
||||
|
@ -14,6 +14,7 @@ import {
|
||||
commandBarActor,
|
||||
useCommandBarState,
|
||||
} from '@src/machines/commandBarMachine'
|
||||
import toast from 'react-hot-toast'
|
||||
|
||||
export const COMMAND_PALETTE_HOTKEY = 'mod+k'
|
||||
|
||||
@ -35,13 +36,23 @@ export const CommandBar = () => {
|
||||
commandBarActor.send({ type: 'Close' })
|
||||
}, [pathname])
|
||||
|
||||
/**
|
||||
* if the engine connection is about to end, we don't want users
|
||||
* to be able to perform commands that might require that connection,
|
||||
* so we just close the command palette.
|
||||
* TODO: instead, let each command control whether it is disabled, and
|
||||
* don't just bail out
|
||||
*/
|
||||
useEffect(() => {
|
||||
if (
|
||||
immediateState.type !== EngineConnectionStateType.ConnectionEstablished
|
||||
!commandBarActor.getSnapshot().matches('Closed') &&
|
||||
(immediateState.type === EngineConnectionStateType.Disconnecting ||
|
||||
immediateState.type === EngineConnectionStateType.Disconnected)
|
||||
) {
|
||||
commandBarActor.send({ type: 'Close' })
|
||||
toast.error('Exiting command flow because engine disconnected')
|
||||
}
|
||||
}, [immediateState])
|
||||
}, [immediateState, commandBarActor])
|
||||
|
||||
// Hook up keyboard shortcuts
|
||||
useHotkeyWrapper([COMMAND_PALETTE_HOTKEY], () => {
|
||||
|
@ -4,6 +4,7 @@ import type { MouseEventHandler } from 'react'
|
||||
import { useCallback, useContext, useEffect, useMemo } from 'react'
|
||||
import { useHotkeys } from 'react-hotkeys-hook'
|
||||
|
||||
import { useAppState } from '@src/AppState'
|
||||
import { ActionIcon } from '@src/components/ActionIcon'
|
||||
import type { CustomIconName } from '@src/components/CustomIcon'
|
||||
import { MachineManagerContext } from '@src/components/MachineManagerProvider'
|
||||
@ -16,7 +17,10 @@ import { sidebarPanes } from '@src/components/ModelingSidebar/ModelingPanes'
|
||||
import Tooltip from '@src/components/Tooltip'
|
||||
import { DEV } from '@src/env'
|
||||
import { useModelingContext } from '@src/hooks/useModelingContext'
|
||||
import { useNetworkContext } from '@src/hooks/useNetworkContext'
|
||||
import { NetworkHealthState } from '@src/hooks/useNetworkStatus'
|
||||
import { useKclContext } from '@src/lang/KclProvider'
|
||||
import { EngineConnectionStateType } from '@src/lang/std/engineConnection'
|
||||
import { SIDEBAR_BUTTON_SUFFIX } from '@src/lib/constants'
|
||||
import { isDesktop } from '@src/lib/isDesktop'
|
||||
import { useSettings } from '@src/machines/appMachine'
|
||||
@ -52,6 +56,16 @@ export function ModelingSidebar({ paneOpacity }: ModelingSidebarProps) {
|
||||
: 'pointer-events-auto '
|
||||
const showDebugPanel = settings.app.showDebugPanel
|
||||
|
||||
const { overallState, immediateState } = useNetworkContext()
|
||||
const { isExecuting } = useKclContext()
|
||||
const { isStreamReady } = useAppState()
|
||||
const reliesOnEngine =
|
||||
(overallState !== NetworkHealthState.Ok &&
|
||||
overallState !== NetworkHealthState.Weak) ||
|
||||
isExecuting ||
|
||||
immediateState.type !== EngineConnectionStateType.ConnectionEstablished ||
|
||||
!isStreamReady
|
||||
|
||||
const paneCallbackProps = useMemo(
|
||||
() => ({
|
||||
kclContext,
|
||||
@ -93,6 +107,8 @@ export function ModelingSidebar({ paneOpacity }: ModelingSidebarProps) {
|
||||
sidebarName: 'Export part',
|
||||
icon: 'floppyDiskArrow',
|
||||
keybinding: 'Ctrl + Shift + E',
|
||||
disable: () =>
|
||||
reliesOnEngine ? 'Need engine connection to export' : undefined,
|
||||
action: () =>
|
||||
commandBarActor.send({
|
||||
type: 'Find and select command',
|
||||
|
12
src/lang/wasmUtils.ts
Normal file
@ -0,0 +1,12 @@
|
||||
import {
|
||||
import_file_extensions,
|
||||
relevant_file_extensions,
|
||||
} from '@rust/kcl-wasm-lib/pkg/kcl_wasm_lib'
|
||||
|
||||
export function importFileExtensions(): string[] {
|
||||
return import_file_extensions()
|
||||
}
|
||||
|
||||
export function relevantFileExtensions(): string[] {
|
||||
return relevant_file_extensions()
|
||||
}
|
@ -1,5 +1,4 @@
|
||||
import type { Models } from '@kittycad/lib/dist/types/src'
|
||||
import type { FileImportFormat_type } from '@kittycad/lib/dist/types/src/models'
|
||||
|
||||
import type { UnitAngle, UnitLength } from '@rust/kcl-lib/bindings/ModelingCmd'
|
||||
|
||||
@ -36,29 +35,6 @@ export const PROJECT_IMAGE_NAME = `thumbnail.png`
|
||||
export const FILE_PERSIST_KEY = `${PROJECT_FOLDER}-last-opened` as const
|
||||
/** The default name given to new kcl files in a project */
|
||||
export const DEFAULT_FILE_NAME = 'Untitled'
|
||||
/** The file endings that will appear in
|
||||
* the file explorer if found in a project directory */
|
||||
// TODO: make stp part of this enum as an alias to step
|
||||
// TODO: make glb part of this enum as it is in fact supported
|
||||
export type NativeFileType = 'kcl'
|
||||
export type RelevantFileType =
|
||||
| FileImportFormat_type
|
||||
| NativeFileType
|
||||
| 'stp'
|
||||
| 'glb'
|
||||
export const NATIVE_FILE_TYPE: NativeFileType = 'kcl'
|
||||
export const RELEVANT_FILE_TYPES: RelevantFileType[] = [
|
||||
'kcl',
|
||||
'fbx',
|
||||
'gltf',
|
||||
'glb',
|
||||
'obj',
|
||||
'ply',
|
||||
'sldprt',
|
||||
'stp',
|
||||
'step',
|
||||
'stl',
|
||||
] as const
|
||||
/** The default name for a tutorial project */
|
||||
export const ONBOARDING_PROJECT_NAME = 'Tutorial Project $nn'
|
||||
/**
|
||||
|
@ -2,9 +2,14 @@ import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
|
||||
import type { Configuration } from '@rust/kcl-lib/bindings/Configuration'
|
||||
|
||||
import { isRelevantFile, listProjects } from '@src/lib/desktop'
|
||||
import { initPromise } from '@src/lang/wasm'
|
||||
import { listProjects } from '@src/lib/desktop'
|
||||
import type { DeepPartial } from '@src/lib/types'
|
||||
|
||||
beforeAll(async () => {
|
||||
await initPromise
|
||||
})
|
||||
|
||||
// Mock the electron window global
|
||||
const mockElectron = {
|
||||
readdir: vi.fn(),
|
||||
@ -112,41 +117,6 @@ describe('desktop utilities', () => {
|
||||
mockElectron.kittycad.mockResolvedValue({})
|
||||
})
|
||||
|
||||
describe('isRelevantFile', () => {
|
||||
it('finds supported extension files relevant', () => {
|
||||
expect(isRelevantFile('part.kcl')).toEqual(true)
|
||||
expect(isRelevantFile('part.fbx')).toEqual(true)
|
||||
expect(isRelevantFile('part.gltf')).toEqual(true)
|
||||
expect(isRelevantFile('part.glb')).toEqual(true)
|
||||
expect(isRelevantFile('part.obj')).toEqual(true)
|
||||
expect(isRelevantFile('part.ply')).toEqual(true)
|
||||
expect(isRelevantFile('part.sldprt')).toEqual(true)
|
||||
expect(isRelevantFile('part.stp')).toEqual(true)
|
||||
expect(isRelevantFile('part.step')).toEqual(true)
|
||||
expect(isRelevantFile('part.stl')).toEqual(true)
|
||||
})
|
||||
|
||||
// TODO: we should be lowercasing the extension here to check. .sldprt or .SLDPRT should be supported
|
||||
// But the api doesn't allow it today, so revisit this and the tests once this is done
|
||||
it('finds (now) supported uppercase extension files *not* relevant', () => {
|
||||
expect(isRelevantFile('part.KCL')).toEqual(false)
|
||||
expect(isRelevantFile('part.FBX')).toEqual(false)
|
||||
expect(isRelevantFile('part.GLTF')).toEqual(false)
|
||||
expect(isRelevantFile('part.GLB')).toEqual(false)
|
||||
expect(isRelevantFile('part.OBJ')).toEqual(false)
|
||||
expect(isRelevantFile('part.PLY')).toEqual(false)
|
||||
expect(isRelevantFile('part.SLDPRT')).toEqual(false)
|
||||
expect(isRelevantFile('part.STP')).toEqual(false)
|
||||
expect(isRelevantFile('part.STEP')).toEqual(false)
|
||||
expect(isRelevantFile('part.STL')).toEqual(false)
|
||||
})
|
||||
|
||||
it("doesn't find .docx or .SLDASM relevant", () => {
|
||||
expect(isRelevantFile('paper.docx')).toEqual(false)
|
||||
expect(isRelevantFile('assembly.SLDASM')).toEqual(false)
|
||||
})
|
||||
})
|
||||
|
||||
describe('listProjects', () => {
|
||||
it('does not list .git directories', async () => {
|
||||
const projects = await listProjects(mockConfig)
|
||||
|
@ -10,13 +10,13 @@ import {
|
||||
parseAppSettings,
|
||||
parseProjectSettings,
|
||||
} from '@src/lang/wasm'
|
||||
import { relevantFileExtensions } from '@src/lang/wasmUtils'
|
||||
import {
|
||||
DEFAULT_DEFAULT_LENGTH_UNIT,
|
||||
PROJECT_ENTRYPOINT,
|
||||
PROJECT_FOLDER,
|
||||
PROJECT_IMAGE_NAME,
|
||||
PROJECT_SETTINGS_FILE_NAME,
|
||||
RELEVANT_FILE_TYPES,
|
||||
SETTINGS_FILE_NAME,
|
||||
TELEMETRY_FILE_NAME,
|
||||
TELEMETRY_RAW_FILE_NAME,
|
||||
@ -201,15 +201,13 @@ export async function listProjects(
|
||||
return projects
|
||||
}
|
||||
|
||||
// TODO: we should be lowercasing the extension here to check. .sldprt or .SLDPRT should be supported
|
||||
// But the api doesn't allow it today, so revisit this and the tests once this is done
|
||||
export const isRelevantFile = (filename: string): boolean =>
|
||||
RELEVANT_FILE_TYPES.some((ext) => filename.endsWith('.' + ext))
|
||||
|
||||
const collectAllFilesRecursiveFrom = async (
|
||||
path: string,
|
||||
canReadWritePath: boolean
|
||||
) => {
|
||||
const RELEVANT_FILE_EXTENSIONS = relevantFileExtensions()
|
||||
const isRelevantFile = (filename: string): boolean =>
|
||||
RELEVANT_FILE_EXTENSIONS.some((ext) => filename.endsWith('.' + ext))
|
||||
// Make sure the filesystem object exists.
|
||||
try {
|
||||
await window.electron.stat(path)
|
||||
|
@ -3,8 +3,13 @@ import os from 'os'
|
||||
import path from 'path'
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
|
||||
import { initPromise } from '@src/lang/wasm'
|
||||
import getCurrentProjectFile from '@src/lib/getCurrentProjectFile'
|
||||
|
||||
beforeAll(async () => {
|
||||
await initPromise
|
||||
})
|
||||
|
||||
describe('getCurrentProjectFile', () => {
|
||||
test('with explicit open file with space (URL encoded)', async () => {
|
||||
const name = `kittycad-modeling-projects-${uuidv4()}`
|
||||
|
@ -1,17 +1,12 @@
|
||||
import {
|
||||
importFileExtensions,
|
||||
relevantFileExtensions,
|
||||
} from '@src/lang/wasmUtils'
|
||||
import type { Stats } from 'fs'
|
||||
import * as fs from 'fs/promises'
|
||||
import * as path from 'path'
|
||||
|
||||
import {
|
||||
NATIVE_FILE_TYPE,
|
||||
PROJECT_ENTRYPOINT,
|
||||
RELEVANT_FILE_TYPES,
|
||||
type RelevantFileType,
|
||||
} from '@src/lib/constants'
|
||||
|
||||
const shouldWrapExtension = (extension: string) =>
|
||||
RELEVANT_FILE_TYPES.includes(extension as RelevantFileType) &&
|
||||
extension !== NATIVE_FILE_TYPE
|
||||
import { PROJECT_ENTRYPOINT } from '@src/lib/constants'
|
||||
|
||||
/// Get the current project file from the path.
|
||||
/// This is used for double-clicking on a file in the file explorer,
|
||||
@ -19,6 +14,12 @@ const shouldWrapExtension = (extension: string) =>
|
||||
export default async function getCurrentProjectFile(
|
||||
pathString: string
|
||||
): Promise<string | Error> {
|
||||
// Extract the values into an array
|
||||
const allFileImportFormats: string[] = importFileExtensions()
|
||||
const relevantExtensions: string[] = relevantFileExtensions()
|
||||
const shouldWrapExtension = (extension: string) =>
|
||||
allFileImportFormats.includes(extension)
|
||||
|
||||
// Fix for "." path, which is the current directory.
|
||||
let sourcePath = pathString === '.' ? process.cwd() : pathString
|
||||
|
||||
@ -71,12 +72,9 @@ export default async function getCurrentProjectFile(
|
||||
// Check if the extension on what we are trying to open is a relevant file type.
|
||||
const extension = path.extname(sourcePath).slice(1).toLowerCase()
|
||||
|
||||
if (
|
||||
!RELEVANT_FILE_TYPES.includes(extension as RelevantFileType) &&
|
||||
extension !== 'toml'
|
||||
) {
|
||||
if (!relevantExtensions.includes(extension) && extension !== 'toml') {
|
||||
return new Error(
|
||||
`File type (${extension}) cannot be opened with this app: '${sourcePath}', try opening one of the following file types: ${RELEVANT_FILE_TYPES.join(
|
||||
`File type (${extension}) cannot be opened with this app: '${sourcePath}', try opening one of the following file types: ${relevantExtensions.join(
|
||||
', '
|
||||
)}`
|
||||
)
|
||||
|
@ -15,6 +15,7 @@ import type {
|
||||
format_number as FormatNumber,
|
||||
get_kcl_version as GetKclVersion,
|
||||
get_tangential_arc_to_info as GetTangentialArcToInfo,
|
||||
import_file_extensions as ImportFileExtensions,
|
||||
is_kcl_empty_or_only_settings as IsKclEmptyOrOnlySettings,
|
||||
is_points_ccw as IsPointsCcw,
|
||||
kcl_lint as KclLint,
|
||||
@ -23,6 +24,7 @@ import type {
|
||||
parse_project_settings as ParseProjectSettings,
|
||||
parse_wasm as ParseWasm,
|
||||
recast_wasm as RecastWasm,
|
||||
relevant_file_extensions as RelevantFileExtensions,
|
||||
serialize_configuration as SerializeConfiguration,
|
||||
serialize_project_configuration as SerializeProjectConfiguration,
|
||||
} from '@rust/kcl-wasm-lib/pkg/kcl_wasm_lib'
|
||||
@ -111,3 +113,9 @@ export const serialize_project_configuration: typeof SerializeProjectConfigurati
|
||||
(...args) => {
|
||||
return getModule().serialize_project_configuration(...args)
|
||||
}
|
||||
export const import_file_extensions: typeof ImportFileExtensions = () => {
|
||||
return getModule().import_file_extensions()
|
||||
}
|
||||
export const relevant_file_extensions: typeof RelevantFileExtensions = () => {
|
||||
return getModule().relevant_file_extensions()
|
||||
}
|
||||
|
@ -45,7 +45,8 @@ export function useDemoCode() {
|
||||
}
|
||||
// Don't run if the network isn't healthy or the connection isn't established
|
||||
if (
|
||||
overallState !== NetworkHealthState.Ok ||
|
||||
overallState === NetworkHealthState.Disconnected ||
|
||||
overallState === NetworkHealthState.Issue ||
|
||||
immediateState.type !== EngineConnectionStateType.ConnectionEstablished
|
||||
) {
|
||||
return
|
||||
|