Compare commits

..

1 Commits

Author SHA1 Message Date
310693c1aa updates
Signed-off-by: Jess Frazelle <github@jessfraz.com>
2025-04-04 12:24:29 -07:00
222 changed files with 27229 additions and 24026 deletions

View File

@ -281,7 +281,7 @@ jobs:
os:
- "runs-on=${{ github.run_id }}/family=i7ie.2xlarge/image=ubuntu22-full-x64"
- namespace-profile-macos-8-cores
- windows-latest-8-cores
- windows-latest
shardIndex: [1, 2, 3, 4]
shardTotal: [4]
# Disable macos and windows tests on hourly e2e tests since we only care
@ -292,7 +292,7 @@ jobs:
exclude:
- os: namespace-profile-macos-8-cores
isScheduled: true
- os: windows-latest-8-cores
- os: windows-latest
isScheduled: true
# TODO: add ref here for main and latest release tag
runs-on: ${{ matrix.os }}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -32,44 +32,53 @@ test(
})
await page.setBodyDimensions({ width: 1200, height: 500 })
await test.step('on open of project', async () => {
// Open the project
const projectName = page.getByText(`bracket`)
await expect(projectName).toBeVisible()
await projectName.click()
await scene.waitForExecutionDone()
await page.waitForTimeout(1_000) // wait for panel buttons to be available
page.on('console', console.log)
// Expect zero errors in gutter
await test.step('on open of project', async () => {
await expect(page.getByText(`bracket`)).toBeVisible()
// open the project
await page.getByText(`bracket`).click()
// expect zero errors in guter
await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible()
// Click the export button
// export the model
const exportButton = page.getByTestId('export-pane-button')
await expect(exportButton).toBeVisible()
await exportButton.click()
await page.waitForTimeout(1_000) // wait for export options to be available
// Select the first format option
await scene.waitForExecutionDone()
const gltfOption = page.getByText('glTF')
const exportFileName = `main.gltf` // source file is named `main.kcl`
const submitButton = page.getByText('Confirm Export')
const exportingToastMessage = page.getByText(`Exporting...`)
const errorToastMessage = page.getByText(`Error while exporting`)
const engineErrorToastMessage = page.getByText(`Nothing to export`)
const alreadyExportingToastMessage = page.getByText(`Already exporting`)
// The open file's name is `main.kcl`, so the export file name should be `main.gltf`
const exportFileName = `main.gltf`
// Click the export button
await exportButton.click()
await expect(gltfOption).toBeVisible()
await expect(page.getByText('STL')).toBeVisible()
await page.keyboard.press('Enter')
// Click the checkbox
const submitButton = page.getByText('Confirm Export')
await expect(submitButton).toBeVisible()
await page.waitForTimeout(500)
await page.keyboard.press('Enter')
// Find the toast.
// Look out for the toast message
const exportingToastMessage = page.getByText(`Exporting...`)
const alreadyExportingToastMessage = page.getByText(`Already exporting`)
await expect(exportingToastMessage).toBeVisible()
await expect(alreadyExportingToastMessage).not.toBeVisible()
// Expect it to succeed
const errorToastMessage = page.getByText(`Error while exporting`)
const engineErrorToastMessage = page.getByText(`Nothing to export`)
// Expect it to succeed.
await expect(errorToastMessage).not.toBeVisible()
await expect(engineErrorToastMessage).not.toBeVisible()
@ -77,7 +86,6 @@ test(
await expect(successToastMessage).toBeVisible()
await expect(exportingToastMessage).not.toBeVisible()
// Check for the exported file
const firstFileFullPath = path.resolve(
getPlaywrightDownloadDir(tronApp.projectDirName),
exportFileName
@ -104,53 +112,60 @@ test(
const u = await getUtils(page)
await u.openFilePanel()
// Click on the other file
const otherKclButton = page.getByRole('button', { name: 'other.kcl' })
// Click the file
await otherKclButton.click()
// Close the file pane
await u.closeFilePanel()
await scene.waitForExecutionDone()
await page.waitForTimeout(1_000) // wait for panel buttons to be available
// Expect zero errors in gutter
// FIXME: await scene.waitForExecutionDone() does not work. The modeling indicator stays in -receive-reliable and not execution done
await page.waitForTimeout(10000)
// expect zero errors in guter
await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible()
// Click the export button
// export the model
const exportButton = page.getByTestId('export-pane-button')
await expect(exportButton).toBeVisible()
await exportButton.click()
await page.waitForTimeout(1_000) // wait for export options to be available
// Select the first format option
const gltfOption = page.getByText('glTF')
const exportFileName = `other.gltf` // source file is named `other.kcl`
const submitButton = page.getByText('Confirm Export')
const exportingToastMessage = page.getByText(`Exporting...`)
const errorToastMessage = page.getByText(`Error while exporting`)
const engineErrorToastMessage = page.getByText(`Nothing to export`)
const alreadyExportingToastMessage = page.getByText(`Already exporting`)
// The open file's name is `other.kcl`, so the export file name should be `other.gltf`
const exportFileName = `other.gltf`
// Click the export button
await exportButton.click()
await expect(gltfOption).toBeVisible()
await expect(page.getByText('STL')).toBeVisible()
await page.keyboard.press('Enter')
// Click the checkbox
const submitButton = page.getByText('Confirm Export')
await expect(submitButton).toBeVisible()
await page.waitForTimeout(500)
await page.keyboard.press('Enter')
// Find the toast.
// Look out for the toast message
const exportingToastMessage = page.getByText(`Exporting...`)
const alreadyExportingToastMessage = page.getByText(`Already exporting`)
await expect(exportingToastMessage).toBeVisible()
await expect(alreadyExportingToastMessage).not.toBeVisible()
// Expect it to succeed
const errorToastMessage = page.getByText(`Error while exporting`)
const engineErrorToastMessage = page.getByText(`Nothing to export`)
await expect(errorToastMessage).not.toBeVisible()
await expect(engineErrorToastMessage).not.toBeVisible()
const successToastMessage = page.getByText(`Exported successfully`)
await expect(successToastMessage).toBeVisible()
await expect(exportingToastMessage).not.toBeVisible()
await test.step('Check the success toast message shows and nothing else', async () =>
Promise.all([
expect(alreadyExportingToastMessage).not.toBeVisible(),
expect(errorToastMessage).not.toBeVisible(),
expect(engineErrorToastMessage).not.toBeVisible(),
expect(successToastMessage).toBeVisible(),
expect(exportingToastMessage).not.toBeVisible(),
]))
// Check for the exported file=
const secondFileFullPath = path.resolve(
getPlaywrightDownloadDir(tronApp.projectDirName),
exportFileName

View File

@ -1315,38 +1315,4 @@ sketch001 = startSketchOn(XZ)
const element = page.locator('[data-overlay-index="1"]')
await expect(element).toHaveAttribute('data-overlay-visible', 'true')
})
test(`Only show axis planes when there are no errors`, async ({
page,
homePage,
scene,
cmdBar,
}) => {
await page.addInitScript(async () => {
localStorage.setItem(
'persistCode',
`sketch001 = startSketchOn(XZ)
profile001 = circle(sketch001, center = [-100.0, -100.0], radius = 50.0)
sketch002 = startSketchOn(XZ)
profile002 = circle(sketch002, center = [-100.0, 100.0], radius = 50.0)
extrude001 = extrude(profile002, length = 0)` // length = 0 is causing the error
)
})
const viewportSize = { width: 1200, height: 800 }
await page.setBodyDimensions(viewportSize)
await homePage.goToModelingScene()
await scene.connectionEstablished()
await scene.settled(cmdBar)
await scene.expectPixelColor(
TEST_COLORS.DARK_MODE_BKGD,
// This is a position where the blue part of the axis plane is visible if its rendered
{ x: viewportSize.width * 0.75, y: viewportSize.height * 0.2 },
15
)
})
})

View File

@ -8,8 +8,8 @@ import { expect, test } from '@e2e/playwright/zoo-test'
test.describe('Testing in-app sample loading', () => {
/**
* Note this test implicitly depends on the KCL sample "parametric-bearing-pillow-block",
* its title, and its units settings. https://github.com/KittyCAD/kcl-samples/blob/main/parametric-bearing-pillow-block/main.kcl
* Note this test implicitly depends on the KCL sample "a-parametric-bearing-pillow-block",
* its title, and its units settings. https://github.com/KittyCAD/kcl-samples/blob/main/a-parametric-bearing-pillow-block/main.kcl
*/
test('Web: should overwrite current code, cannot create new file', async ({
editor,
@ -29,8 +29,8 @@ test.describe('Testing in-app sample loading', () => {
// Locators and constants
const newSample = {
file: 'parametric-bearing-pillow-block' + FILE_EXT,
title: 'Parametric Bearing Pillow Block',
file: 'a-parametric-bearing-pillow-block' + FILE_EXT,
title: 'A Parametric Bearing Pillow Block',
}
const commandBarButton = page.getByRole('button', { name: 'Commands' })
const samplesCommandOption = page.getByRole('option', {
@ -72,7 +72,7 @@ test.describe('Testing in-app sample loading', () => {
/**
* Note this test implicitly depends on the KCL samples:
* "parametric-bearing-pillow-block": https://github.com/KittyCAD/kcl-samples/blob/main/parametric-bearing-pillow-block/main.kcl
* "a-parametric-bearing-pillow-block": https://github.com/KittyCAD/kcl-samples/blob/main/a-parametric-bearing-pillow-block/main.kcl
* "gear-rack": https://github.com/KittyCAD/kcl-samples/blob/main/gear-rack/main.kcl
*/
test(
@ -90,8 +90,8 @@ test.describe('Testing in-app sample loading', () => {
// Locators and constants
const sampleOne = {
file: 'parametric-bearing-pillow-block' + FILE_EXT,
title: 'Parametric Bearing Pillow Block',
file: 'a-parametric-bearing-pillow-block' + FILE_EXT,
title: 'A Parametric Bearing Pillow Block',
}
const sampleTwo = {
file: 'gear-rack' + FILE_EXT,

View File

@ -4,7 +4,6 @@ directories:
buildResources: assets
files:
- .vite/**
- "!node_modules/win-ca/pem/**"
mac:
category: public.app-category.developer-tools
artifactName: "${productName}-${version}-${arch}-${os}.${ext}"

View File

@ -66,7 +66,6 @@
"vscode-languageserver-protocol": "^3.17.5",
"vscode-uri": "^3.1.0",
"web-vitals": "^3.5.2",
"win-ca": "^3.5.1",
"xstate": "^5.19.2",
"yargs": "^17.7.2"
},

View File

@ -94,4 +94,4 @@ outsideWallSketch = startSketchOn(offsetPlane(XY, offset = -overallThickness / 2
|> circle(center = [0, 0], radius = outsideDiameter / 2)
|> hole(circle(center = [0, 0], radius = shaftDia / 2 + wallThickness + sphereDia), %)
outsideWall = extrude(outsideWallSketch, length = overallThickness)
outsideWall = extrude(outsideWallSketch, length = overallThickness)

View File

@ -21,7 +21,7 @@ archThickness = 1
archRadius = mirrorRadius + archToMirrorGap
// Geometry
// Add a function to create the hinge
// Add a function to create the hinge
fn hingeFn(x, y, z) {
hingeBody = startSketchOn(offsetPlane(XY, offset = z))
|> circle(center = [x, y], radius = hingeRadius)

View File

@ -9,6 +9,7 @@ import pipeInnerDiameter, pipeOuterDiameter, pipeLength from "parameters.kcl"
// Create a function to make the pipe. Export
export fn pipe() {
// Create the pipe base
pipeBase = startSketchOn(XZ)
|> circle(%, center = [0, 0], radius = pipeOuterDiameter / 2)

View File

@ -9,6 +9,7 @@ import pipeDiameter, mountingHoleDiameter, mountingHolePlacementDiameter, flange
// Create a function to create the flange. We must create a function since we are using multiple flanges.
export fn flange() {
// Sketch the mounting hole pattern
mountingHoles = startSketchOn(XY)
|> circle(%, center = [0, mountingHolePlacementDiameter / 2], radius = mountingHoleDiameter / 2)
@ -41,4 +42,4 @@ export fn flange() {
|> appearance(%, color = "#bab0b0")
return pipeCut
}
}

View File

@ -9,6 +9,7 @@ import hexNutDiameter, hexNutFlatToFlat, hexNutThickness, hexNutFlatLength from
// Create a function to make the hex nut. Must be a function since multiple hex nuts are used
export fn hexNut() {
// Create the base of the hex nut
hexNutBase = startSketchOn(XY)
|> startProfileAt([

View File

@ -7,7 +7,7 @@
// Import parameters
import washerInnerDia, washerOuterDia, washerThickness from "parameters.kcl"
// Create a function to make the washer. Must be a function since multiple washers are used.
// Create a function to make the washer. Must be a function since multiple washers are used.
export fn washer() {
// Create the base of the washer
washerBase = startSketchOn(XY)

View File

@ -8,7 +8,7 @@
import * from "parameters.kcl"
// Import parts
import "9472k188-gasket.kcl" as gasket
import '9472k188-gasket.kcl' as gasket
import flange from "68095k348-flange.kcl"
import washer from "98017a257-washer.kcl"
import bolt from "91251a404-bolt.kcl"

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

20
rust/Cargo.lock generated
View File

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

View File

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

View File

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

View File

@ -31,7 +31,19 @@ async fn cache_test(
// set the new settings.
ctx.settings = variation.settings.clone();
let outcome = ctx.run_with_caching(program).await.unwrap();
let outcome = match ctx.run_with_caching(program).await {
Ok(outcome) => outcome,
Err(err) => {
miette::set_hook(Box::new(|_| {
Box::new(miette::MietteHandlerOpts::new().show_related_errors_as_nested().build())
}))
.unwrap();
let report = err.clone().into_miette_report_with_outputs(variation.code).unwrap();
let report = miette::Report::new(report);
let report = format!("{:?}", report);
panic!("Error: {}", report);
}
};
let snapshot_png_bytes = ctx.prepare_snapshot().await.unwrap().contents.0;
// Decode the snapshot, return it.
@ -282,3 +294,33 @@ async fn kcl_test_cache_empty_file_pop_cache_empty_file_planes_work() {
ctx.close().await;
}
#[tokio::test(flavor = "multi_thread")]
async fn kcl_test_cache_fillet_error_opening_closing_specific_files() {
let main_code = include_str!("../../tests/fillet_error_switch_files/main.kcl");
let switch_code = include_str!("../../tests/fillet_error_switch_files/switch_protector.kcl");
let result = cache_test(
"fillet_error_opening_closing_specific_files",
vec![
Variation {
code: main_code,
settings: &Default::default(),
},
Variation {
code: switch_code,
settings: &Default::default(),
},
Variation {
code: main_code,
settings: &Default::default(),
},
],
)
.await;
// Make sure nothing failed.
result.first().unwrap();
result.get(1).unwrap();
result.last().unwrap();
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

View File

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

View File

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

View File

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

View File

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

View File

@ -5,6 +5,7 @@ use indexmap::IndexMap;
use super::{cad_op::Group, kcl_value::TypeDef, types::PrimitiveType};
use crate::{
engine::ExecutionKind,
errors::{KclError, KclErrorDetails},
execution::{
annotations,
@ -61,13 +62,15 @@ impl ExecutorContext {
exec_state.mod_local.explicit_length_units = true;
}
let new_units = exec_state.length_unit();
self.engine
.set_units(
new_units.into(),
annotation.as_source_range(),
exec_state.id_generator(),
)
.await?;
if !self.engine.execution_kind().await.is_isolated() {
self.engine
.set_units(
new_units.into(),
annotation.as_source_range(),
exec_state.id_generator(),
)
.await?;
}
} else {
exec_state.err(CompilationError::err(
annotation.as_source_range(),
@ -97,13 +100,15 @@ impl ExecutorContext {
&self,
program: &Node<Program>,
exec_state: &mut ExecState,
exec_kind: ExecutionKind,
preserve_mem: bool,
module_id: ModuleId,
path: &ModulePath,
) -> Result<(Option<KclValue>, EnvironmentRef, Vec<String>), KclError> {
crate::log::log(format!("enter module {path} {}", exec_state.stack()));
crate::log::log(format!("enter module {path} {} {exec_kind:?}", exec_state.stack()));
let old_units = exec_state.length_unit();
let original_execution = self.engine.replace_execution_kind(exec_kind).await;
let mut local_state = ModuleState::new(path.std_path(), exec_state.stack().memory.clone(), Some(module_id));
if !preserve_mem {
@ -136,11 +141,12 @@ impl ExecutorContext {
// If we reset at the end of the main path, then we just add on an extra
// command and we'd need to flush the batch again.
// This avoids that.
if new_units != old_units && *path != ModulePath::Main {
if !exec_kind.is_isolated() && new_units != old_units && *path != ModulePath::Main {
self.engine
.set_units(old_units.into(), Default::default(), exec_state.id_generator())
.await?;
}
self.engine.replace_execution_kind(original_execution).await;
crate::log::log(format!("leave {path}"));
@ -151,7 +157,7 @@ impl ExecutorContext {
#[async_recursion]
pub(super) async fn exec_block<'a>(
&'a self,
program: NodeRef<'a, Program>,
program: NodeRef<'a, crate::parsing::ast::types::Program>,
exec_state: &mut ExecState,
body_type: BodyType,
) -> Result<Option<KclValue>, KclError> {
@ -175,8 +181,9 @@ impl ExecutorContext {
match &import_stmt.selector {
ImportSelector::List { items } => {
let (env_ref, module_exports) =
self.exec_module_for_items(module_id, exec_state, source_range).await?;
let (env_ref, module_exports) = self
.exec_module_for_items(module_id, exec_state, ExecutionKind::Isolated, source_range)
.await?;
for import_item in items {
// Extract the item from the module.
let item = exec_state
@ -217,8 +224,9 @@ impl ExecutorContext {
}
}
ImportSelector::Glob(_) => {
let (env_ref, module_exports) =
self.exec_module_for_items(module_id, exec_state, source_range).await?;
let (env_ref, module_exports) = self
.exec_module_for_items(module_id, exec_state, ExecutionKind::Isolated, source_range)
.await?;
for name in module_exports.iter() {
let item = exec_state
.stack()
@ -409,7 +417,7 @@ impl ExecutorContext {
Ok(last_expr)
}
pub async fn open_module(
pub(super) async fn open_module(
&self,
path: &ImportPath,
attrs: &[Node<Annotation>],
@ -417,7 +425,6 @@ impl ExecutorContext {
source_range: SourceRange,
) -> Result<ModuleId, KclError> {
let resolved_path = ModulePath::from_import_path(path, &self.settings.project_directory);
match path {
ImportPath::Kcl { .. } => {
exec_state.global.mod_loader.cycle_check(&resolved_path, source_range)?;
@ -474,6 +481,7 @@ impl ExecutorContext {
&self,
module_id: ModuleId,
exec_state: &mut ExecState,
exec_kind: ExecutionKind,
source_range: SourceRange,
) -> Result<(EnvironmentRef, Vec<String>), KclError> {
let path = exec_state.global.module_infos[&module_id].path.clone();
@ -482,12 +490,12 @@ impl ExecutorContext {
let result = match &mut repr {
ModuleRepr::Root => Err(exec_state.circular_import_error(&path, source_range)),
ModuleRepr::Kcl(_, Some((_, env_ref, items))) => Ok((*env_ref, items.clone())),
ModuleRepr::Kcl(_, Some((env_ref, items))) => Ok((*env_ref, items.clone())),
ModuleRepr::Kcl(program, cache) => self
.exec_module_from_ast(program, module_id, &path, exec_state, source_range)
.exec_module_from_ast(program, module_id, &path, exec_state, exec_kind, source_range)
.await
.map(|(val, er, items)| {
*cache = Some((val, er, items.clone()));
.map(|(_, er, items)| {
*cache = Some((er, items.clone()));
(er, items)
}),
ModuleRepr::Foreign(geom) => Err(KclError::Semantic(KclErrorDetails {
@ -506,6 +514,7 @@ impl ExecutorContext {
module_id: ModuleId,
module_name: &BoxNode<Name>,
exec_state: &mut ExecState,
exec_kind: ExecutionKind,
source_range: SourceRange,
) -> Result<Option<KclValue>, KclError> {
exec_state.global.operations.push(Operation::GroupBegin {
@ -522,14 +531,13 @@ impl ExecutorContext {
let result = match &mut repr {
ModuleRepr::Root => Err(exec_state.circular_import_error(&path, source_range)),
ModuleRepr::Kcl(_, Some((val, _, _))) => Ok(val.clone()),
ModuleRepr::Kcl(program, cached_items) => {
let result = self
.exec_module_from_ast(program, module_id, &path, exec_state, source_range)
.exec_module_from_ast(program, module_id, &path, exec_state, exec_kind, source_range)
.await;
match result {
Ok((val, env, items)) => {
*cached_items = Some((val.clone(), env, items));
*cached_items = Some((env, items));
Ok(val)
}
Err(e) => Err(e),
@ -548,16 +556,19 @@ impl ExecutorContext {
result
}
pub async fn exec_module_from_ast(
async fn exec_module_from_ast(
&self,
program: &Node<Program>,
module_id: ModuleId,
path: &ModulePath,
exec_state: &mut ExecState,
exec_kind: ExecutionKind,
source_range: SourceRange,
) -> Result<(Option<KclValue>, EnvironmentRef, Vec<String>), KclError> {
exec_state.global.mod_loader.enter_module(path);
let result = self.exec_module_body(program, exec_state, false, module_id, path).await;
let result = self
.exec_module_body(program, exec_state, exec_kind, false, module_id, path)
.await;
exec_state.global.mod_loader.leave_module(path);
result.map_err(|err| {
@ -593,7 +604,7 @@ impl ExecutorContext {
Expr::Name(name) => {
let value = name.get_result(exec_state, self).await?.clone();
if let KclValue::Module { value: module_id, meta } = value {
self.exec_module_for_result(module_id, name, exec_state, metadata.source_range)
self.exec_module_for_result(module_id, name, exec_state, ExecutionKind::Normal, metadata.source_range)
.await?
.unwrap_or_else(|| {
exec_state.warn(CompilationError::err(
@ -781,7 +792,7 @@ impl Node<Name> {
};
mem_spec = Some(
ctx.exec_module_for_items(*module_id, exec_state, p.as_source_range())
ctx.exec_module_for_items(*module_id, exec_state, ExecutionKind::Normal, p.as_source_range())
.await?,
);
}
@ -1262,7 +1273,7 @@ impl Node<CallExpressionKw> {
));
}
let op = if func.feature_tree_operation() {
let op = if func.feature_tree_operation() && !ctx.is_isolated_execution().await {
let op_labeled_args = args
.kw_args
.labeled
@ -1348,7 +1359,7 @@ impl Node<CallExpressionKw> {
e.add_source_ranges(vec![callsite])
})?;
if matches!(fn_src, FunctionSource::User { .. }) {
if matches!(fn_src, FunctionSource::User { .. }) && !ctx.is_isolated_execution().await {
// Track return operation.
exec_state.global.operations.push(Operation::GroupEnd);
}
@ -1400,7 +1411,7 @@ impl Node<CallExpression> {
));
}
let op = if func.feature_tree_operation() {
let op = if func.feature_tree_operation() && !ctx.is_isolated_execution().await {
let op_labeled_args = func
.args(false)
.iter()
@ -1458,17 +1469,19 @@ impl Node<CallExpression> {
// exec_state.
let func = fn_name.get_result(exec_state, ctx).await?.clone();
// Track call operation.
exec_state.global.operations.push(Operation::GroupBegin {
group: Group::FunctionCall {
name: Some(fn_name.to_string()),
function_source_range: func.function_def_source_range().unwrap_or_default(),
unlabeled_arg: None,
// TODO: Add the arguments for legacy positional parameters.
labeled_args: Default::default(),
},
source_range: callsite,
});
if !ctx.is_isolated_execution().await {
// Track call operation.
exec_state.global.operations.push(Operation::GroupBegin {
group: Group::FunctionCall {
name: Some(fn_name.to_string()),
function_source_range: func.function_def_source_range().unwrap_or_default(),
unlabeled_arg: None,
// TODO: Add the arguments for legacy positional parameters.
labeled_args: Default::default(),
},
source_range: callsite,
});
}
let Some(fn_src) = func.as_fn() else {
return Err(KclError::Semantic(KclErrorDetails {
@ -1497,8 +1510,10 @@ impl Node<CallExpression> {
})
})?;
// Track return operation.
exec_state.global.operations.push(Operation::GroupEnd);
if !ctx.is_isolated_execution().await {
// Track return operation.
exec_state.global.operations.push(Operation::GroupEnd);
}
Ok(result)
}
@ -2226,7 +2241,7 @@ impl FunctionSource {
}
}
let op = if props.include_in_feature_tree {
let op = if props.include_in_feature_tree && !ctx.is_isolated_execution().await {
let op_labeled_args = args
.kw_args
.labeled
@ -2270,26 +2285,28 @@ impl FunctionSource {
Ok(Some(result))
}
FunctionSource::User { ast, memory, .. } => {
// Track call operation.
let op_labeled_args = args
.kw_args
.labeled
.iter()
.map(|(k, arg)| (k.clone(), OpArg::new(OpKclValue::from(&arg.value), arg.source_range)))
.collect();
exec_state.global.operations.push(Operation::GroupBegin {
group: Group::FunctionCall {
name: fn_name,
function_source_range: ast.as_source_range(),
unlabeled_arg: args
.kw_args
.unlabeled
.as_ref()
.map(|arg| OpArg::new(OpKclValue::from(&arg.value), arg.source_range)),
labeled_args: op_labeled_args,
},
source_range: callsite,
});
if !ctx.is_isolated_execution().await {
// Track call operation.
let op_labeled_args = args
.kw_args
.labeled
.iter()
.map(|(k, arg)| (k.clone(), OpArg::new(OpKclValue::from(&arg.value), arg.source_range)))
.collect();
exec_state.global.operations.push(Operation::GroupBegin {
group: Group::FunctionCall {
name: fn_name,
function_source_range: ast.as_source_range(),
unlabeled_arg: args
.kw_args
.unlabeled
.as_ref()
.map(|arg| OpArg::new(OpKclValue::from(&arg.value), arg.source_range)),
labeled_args: op_labeled_args,
},
source_range: callsite,
});
}
call_user_defined_function_kw(args.kw_args, *memory, ast, exec_state, ctx).await
}
@ -2302,13 +2319,10 @@ impl FunctionSource {
mod test {
use std::sync::Arc;
use tokio::io::AsyncWriteExt;
use super::*;
use crate::{
execution::{memory::Stack, parse_execute, ContextType},
parsing::ast::types::{DefaultParamVal, Identifier, Parameter},
ExecutorSettings,
};
#[tokio::test(flavor = "multi_thread")]
@ -2418,7 +2432,7 @@ mod test {
// Run each test.
let func_expr = &Node::no_src(FunctionExpression {
params,
body: Program::empty(),
body: crate::parsing::ast::types::Program::empty(),
return_type: None,
digest: None,
});
@ -2520,100 +2534,4 @@ a = foo()
let result = parse_execute(program).await;
assert!(result.unwrap_err().to_string().contains("return"));
}
#[tokio::test(flavor = "multi_thread")]
async fn load_all_modules() {
// program a.kcl
let programa_kcl = r#"
export a = 1
"#;
// program b.kcl
let programb_kcl = r#"
import a from 'a.kcl'
export b = a + 1
"#;
// program c.kcl
let programc_kcl = r#"
import a from 'a.kcl'
export c = a + 2
"#;
// program main.kcl
let main_kcl = r#"
import b from 'b.kcl'
import c from 'c.kcl'
d = b + c
"#;
let main = crate::parsing::parse_str(main_kcl, ModuleId::default())
.parse_errs_as_err()
.unwrap();
let tmpdir = tempdir::TempDir::new("zma_kcl_load_all_modules").unwrap();
tokio::fs::File::create(tmpdir.path().join("main.kcl"))
.await
.unwrap()
.write_all(main_kcl.as_bytes())
.await
.unwrap();
tokio::fs::File::create(tmpdir.path().join("a.kcl"))
.await
.unwrap()
.write_all(programa_kcl.as_bytes())
.await
.unwrap();
tokio::fs::File::create(tmpdir.path().join("b.kcl"))
.await
.unwrap()
.write_all(programb_kcl.as_bytes())
.await
.unwrap();
tokio::fs::File::create(tmpdir.path().join("c.kcl"))
.await
.unwrap()
.write_all(programc_kcl.as_bytes())
.await
.unwrap();
let exec_ctxt = ExecutorContext {
engine: Arc::new(Box::new(
crate::engine::conn_mock::EngineConnection::new()
.await
.map_err(|err| {
KclError::Internal(crate::errors::KclErrorDetails {
message: format!("Failed to create mock engine connection: {}", err),
source_ranges: vec![SourceRange::default()],
})
})
.unwrap(),
)),
fs: Arc::new(crate::fs::FileManager::new()),
settings: ExecutorSettings {
project_directory: Some(tmpdir.path().into()),
..Default::default()
},
stdlib: Arc::new(crate::std::StdLib::new()),
context_type: ContextType::Mock,
};
let mut exec_state = ExecState::new(&exec_ctxt);
exec_ctxt
.run_concurrent(
&crate::Program {
ast: main.clone(),
original_file_contents: "".to_owned(),
},
&mut exec_state,
false,
)
.await
.unwrap();
}
}

View File

@ -418,9 +418,6 @@ pub struct Sketch {
pub artifact_id: ArtifactId,
#[ts(skip)]
pub original_id: uuid::Uuid,
/// If the sketch includes a mirror.
#[serde(skip)]
pub mirror: Option<uuid::Uuid>,
pub units: UnitLen,
/// Metadata.
#[serde(skip)]

View File

@ -4,13 +4,13 @@ use anyhow::Result;
use schemars::JsonSchema;
use serde::Serialize;
use super::{types::UnitLen, EnvironmentRef, ExecState, MetaSettings};
use crate::{
errors::KclErrorDetails,
execution::{
annotations::{SETTINGS, SETTINGS_UNIT_LENGTH},
types::{NumericType, PrimitiveType, RuntimeType, UnitLen},
EnvironmentRef, ExecState, Face, Helix, ImportedGeometry, MetaSettings, Metadata, Plane, Sketch, Solid,
TagIdentifier,
types::{NumericType, PrimitiveType, RuntimeType},
Face, Helix, ImportedGeometry, Metadata, Plane, Sketch, Solid, TagIdentifier,
},
parsing::ast::types::{
DefaultParamVal, FunctionExpression, KclNone, Literal, LiteralValue, Node, TagDeclarator, TagNode,

View File

@ -30,18 +30,18 @@ pub use state::{ExecState, MetaSettings};
use crate::{
engine::EngineManager,
errors::{KclError, KclErrorDetails},
errors::KclError,
execution::{
artifact::build_artifact_graph,
cache::{CacheInformation, CacheResult},
types::{UnitAngle, UnitLen},
},
fs::FileManager,
modules::{ModuleId, ModulePath, ModuleRepr},
modules::{ModuleId, ModulePath},
parsing::ast::types::{Expr, ImportPath, NodeRef},
source_range::SourceRange,
std::StdLib,
CompilationError, ExecError, KclErrorWithOutputs,
CompilationError, ExecError, ExecutionKind, KclErrorWithOutputs,
};
pub(crate) mod annotations;
@ -497,9 +497,13 @@ impl ExecutorContext {
self.context_type == ContextType::Mock || self.context_type == ContextType::MockCustomForwarded
}
pub async fn is_isolated_execution(&self) -> bool {
self.engine.execution_kind().await.is_isolated()
}
/// Returns true if we should not send engine commands for any reason.
pub async fn no_engine_commands(&self) -> bool {
self.is_mock()
self.is_mock() || self.is_isolated_execution().await
}
pub async fn send_clear_scene(
@ -670,7 +674,7 @@ impl ExecutorContext {
(program, exec_state, false)
};
let result = self.run_concurrent(&program, &mut exec_state, preserve_mem).await;
let result = self.inner_run(&program, &mut exec_state, preserve_mem).await;
if result.is_err() {
cache::bust_cache().await;
@ -689,6 +693,10 @@ impl ExecutorContext {
.await;
let outcome = exec_state.to_wasm_outcome(result.0).await;
println!("batch_end: {:#?}", self.engine.batch_end().read().await);
println!("responses: {:#?}", self.engine.responses().read().await);
println!("batch: {:#?}", self.engine.batch().read().await);
Ok(outcome)
}
@ -703,138 +711,7 @@ impl ExecutorContext {
program: &crate::Program,
exec_state: &mut ExecState,
) -> Result<(EnvironmentRef, Option<ModelingSessionData>), KclErrorWithOutputs> {
self.run_concurrent(program, exec_state, false).await
}
/// Perform the execution of a program using an (experimental!) concurrent
/// execution model. This has the same signature as [Self::run].
///
/// For now -- do not use this unless you're willing to accept some
/// breakage.
///
/// You can optionally pass in some initialization memory for partial
/// execution.
///
/// To access non-fatal errors and warnings, extract them from the `ExecState`.
pub async fn run_concurrent(
&self,
program: &crate::Program,
exec_state: &mut ExecState,
preserve_mem: bool,
) -> Result<(EnvironmentRef, Option<ModelingSessionData>), KclErrorWithOutputs> {
self.prepare_mem(exec_state).await.unwrap();
let mut universe = std::collections::HashMap::new();
crate::walk::import_universe(self, &program.ast, &mut universe, exec_state)
.await
.map_err(KclErrorWithOutputs::no_outputs)?;
for modules in crate::walk::import_graph(&universe, self)
.map_err(KclErrorWithOutputs::no_outputs)?
.into_iter()
{
#[cfg(not(target_arch = "wasm32"))]
let mut set = tokio::task::JoinSet::new();
#[allow(clippy::type_complexity)]
let (results_tx, mut results_rx): (
tokio::sync::mpsc::Sender<(
ModuleId,
ModulePath,
Result<(Option<KclValue>, EnvironmentRef, Vec<String>), KclError>,
)>,
tokio::sync::mpsc::Receiver<_>,
) = tokio::sync::mpsc::channel(1);
for module in modules {
let Some((import_stmt, module_id, module_path, program)) = universe.get(&module) else {
return Err(KclErrorWithOutputs::no_outputs(KclError::Internal(KclErrorDetails {
message: format!("Module {module} not found in universe"),
source_ranges: Default::default(),
})));
};
let module_id = *module_id;
let module_path = module_path.clone();
let program = program.clone();
let exec_state = exec_state.clone();
let exec_ctxt = self.clone();
let results_tx = results_tx.clone();
let source_range = SourceRange::from(import_stmt);
#[cfg(target_arch = "wasm32")]
{
wasm_bindgen_futures::spawn_local(async move {
//set.spawn(async move {
let mut exec_state = exec_state;
let exec_ctxt = exec_ctxt;
let result = exec_ctxt
.exec_module_from_ast(&program, module_id, &module_path, &mut exec_state, source_range)
.await;
results_tx
.send((module_id, module_path, result))
.await
.unwrap_or_default();
});
}
#[cfg(not(target_arch = "wasm32"))]
{
set.spawn(async move {
let mut exec_state = exec_state;
let exec_ctxt = exec_ctxt;
let result = exec_ctxt
.exec_module_from_ast(&program, module_id, &module_path, &mut exec_state, source_range)
.await;
results_tx
.send((module_id, module_path, result))
.await
.unwrap_or_default();
});
}
}
drop(results_tx);
while let Some((module_id, _, result)) = results_rx.recv().await {
match result {
Ok((val, session_data, variables)) => {
let mut repr = exec_state.global.module_infos[&module_id].take_repr();
let ModuleRepr::Kcl(_, cache) = &mut repr else {
continue;
};
*cache = Some((val, session_data, variables.clone()));
exec_state.global.module_infos[&module_id].restore_repr(repr);
}
Err(e) => {
let module_id_to_module_path: IndexMap<ModuleId, ModulePath> = exec_state
.global
.path_to_source_id
.iter()
.map(|(k, v)| ((*v), k.clone()))
.collect();
let default_planes = self.engine.get_default_planes().read().await.clone();
return Err(KclErrorWithOutputs::new(
e,
exec_state.global.operations.clone(),
exec_state.global.artifact_commands.clone(),
exec_state.global.artifact_graph.clone(),
module_id_to_module_path,
exec_state.global.id_to_source.clone(),
default_planes,
));
}
}
}
}
self.inner_run(program, exec_state, preserve_mem).await
self.inner_run(program, exec_state, false).await
}
/// Perform the execution of a program. Accept all possible parameters and
@ -885,12 +762,11 @@ impl ExecutorContext {
)
})?;
// TODO: fix this
/* if !self.is_mock() {
if !self.is_mock() {
let mut mem = exec_state.stack().deep_clone();
mem.restore_env(env_ref);
cache::write_old_memory((mem, exec_state.global.module_infos.clone())).await;
}*/
}
let session_data = self.engine.get_session_data().await;
Ok((env_ref, session_data))
}
@ -913,6 +789,7 @@ impl ExecutorContext {
.exec_module_body(
program,
exec_state,
ExecutionKind::Normal,
preserve_mem,
ModuleId::default(),
&ModulePath::Main,
@ -966,7 +843,9 @@ impl ExecutorContext {
source_range,
)
.await?;
let (module_memory, _) = self.exec_module_for_items(id, exec_state, source_range).await?;
let (module_memory, _) = self
.exec_module_for_items(id, exec_state, ExecutionKind::Isolated, source_range)
.await?;
exec_state.mut_stack().memory.set_std(module_memory);
}

View File

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

View File

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

View File

@ -6,7 +6,6 @@ use serde::{Deserialize, Serialize};
use crate::{
errors::{KclError, KclErrorDetails},
exec::KclValue,
execution::{EnvironmentRef, PreImportedGeometry},
fs::{FileManager, FileSystem},
parsing::ast::types::{ImportPath, Node, Program},
@ -95,7 +94,7 @@ pub(crate) fn read_std(mod_name: &str) -> Option<&'static str> {
}
/// Info about a module.
#[derive(Debug, Clone, PartialEq, Serialize)]
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
pub struct ModuleInfo {
/// The ID of the module.
pub(crate) id: ModuleId,
@ -118,11 +117,11 @@ impl ModuleInfo {
}
#[allow(clippy::large_enum_variant)]
#[derive(Debug, Clone, PartialEq, Serialize)]
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
pub enum ModuleRepr {
Root,
// AST, memory, exported names
Kcl(Node<Program>, Option<(Option<KclValue>, EnvironmentRef, Vec<String>)>),
Kcl(Node<Program>, Option<(EnvironmentRef, Vec<String>)>),
Foreign(PreImportedGeometry),
Dummy,
}

View File

@ -13,7 +13,7 @@ use kcmc::{
websocket::{ModelingCmdReq, OkWebSocketResponseData},
ModelingCmd,
};
use kittycad_modeling_cmds::{self as kcmc};
use kittycad_modeling_cmds as kcmc;
use uuid::Uuid;
use crate::{
@ -168,18 +168,13 @@ pub(crate) async fn do_post_extrude<'a>(
)
.await?;
let any_edge_id = if let Some(edge_id) = sketch.mirror {
edge_id
} else {
// The "get extrusion face info" API call requires *any* edge on the sketch being extruded.
// So, let's just use the first one.
let Some(any_edge_id) = sketch.paths.first().map(|edge| edge.get_base().geo_meta.id) else {
return Err(KclError::Type(KclErrorDetails {
message: "Expected a non-empty sketch".to_string(),
source_ranges: vec![args.source_range],
}));
};
any_edge_id
// The "get extrusion face info" API call requires *any* edge on the sketch being extruded.
// So, let's just use the first one.
let Some(any_edge_id) = sketch.paths.first().map(|edge| edge.get_base().geo_meta.id) else {
return Err(KclError::Type(KclErrorDetails {
message: "Expected a non-empty sketch".to_string(),
source_ranges: vec![args.source_range],
}));
};
let mut sketch = sketch.clone();

View File

@ -2,13 +2,10 @@
use anyhow::Result;
use kcmc::{each_cmd as mcmd, ModelingCmd};
use kittycad_modeling_cmds::{
self as kcmc, length_unit::LengthUnit, ok_response::OkModelingCmdResponse, output::EntityGetAllChildUuids,
shared::Point3d, websocket::OkWebSocketResponseData,
};
use kittycad_modeling_cmds::{self as kcmc, length_unit::LengthUnit, shared::Point3d};
use crate::{
errors::{KclError, KclErrorDetails},
errors::KclError,
execution::{
types::{PrimitiveType, RuntimeType},
ExecState, KclValue, Sketch,
@ -34,21 +31,13 @@ pub async fn mirror_2d(exec_state: &mut ExecState, args: Args) -> Result<KclValu
Ok(sketches.into())
}
/// Mirror a sketch.
///
/// Only works on unclosed sketches for now.
async fn inner_mirror_2d(
sketches: Vec<Sketch>,
axis: Axis2dOrEdgeReference,
exec_state: &mut ExecState,
args: Args,
) -> Result<Vec<Sketch>, KclError> {
let mut starting_sketches = sketches.clone();
// Update all to have a mirror.
starting_sketches.iter_mut().for_each(|sketch| {
sketch.mirror = Some(exec_state.next_uuid());
});
let starting_sketches = sketches;
if args.ctx.no_engine_commands().await {
return Ok(starting_sketches);
@ -88,40 +77,5 @@ async fn inner_mirror_2d(
}
};
// After the mirror, get the first child uuid for the path.
// The "get extrusion face info" API call requires *any* edge on the sketch being extruded.
// But if you mirror2d a sketch these IDs might change so we need to get the children versus
// using the IDs we already have.
// We only do this with mirrors because otherwise it is a waste of a websocket call.
for sketch in &mut starting_sketches {
let response = args
.send_modeling_cmd(
exec_state.next_uuid(),
ModelingCmd::from(mcmd::EntityGetAllChildUuids { entity_id: sketch.id }),
)
.await?;
let OkWebSocketResponseData::Modeling {
modeling_response:
OkModelingCmdResponse::EntityGetAllChildUuids(EntityGetAllChildUuids { entity_ids: child_ids }),
} = response
else {
return Err(KclError::Internal(KclErrorDetails {
message: "Expected a successful response from EntityGetAllChildUuids".to_string(),
source_ranges: vec![args.source_range],
}));
};
if child_ids.len() >= 2 {
// The first child is the original sketch, the second is the mirrored sketch.
let child_id = child_ids[1];
sketch.mirror = Some(child_id);
} else {
return Err(KclError::Type(KclErrorDetails {
message: "Expected child uuids to be >= 2".to_string(),
source_ranges: vec![args.source_range],
}));
}
}
Ok(starting_sketches)
}

View File

@ -1343,7 +1343,6 @@ pub(crate) async fn inner_start_profile_at(
on: sketch_surface.clone(),
paths: vec![],
units: sketch_surface.units(),
mirror: Default::default(),
meta: vec![args.source_range.into()],
tags: if let Some(tag) = &tag {
let mut tag_identifier: TagIdentifier = tag.into();

View File

@ -6,37 +6,31 @@ use std::{
use anyhow::Result;
use crate::{
errors::KclErrorDetails,
modules::{ModulePath, ModuleRepr},
parsing::ast::types::{ImportPath, ImportStatement, Node as AstNode, NodeRef, Program},
parsing::ast::types::{ImportPath, NodeRef, Program},
walk::{Node, Visitable},
ExecState, ExecutorContext, KclError, ModuleId,
};
/// Specific dependency between two modules. The 0th element of this info
/// Specific dependency between two modules. The 0th element of this tuple
/// is the "importing" module, the 1st is the "imported" module. The 0th
/// module *depends on* the 1st module.
type Dependency = (String, String);
type Graph = Vec<Dependency>;
type DependencyInfo = (AstNode<ImportStatement>, ModuleId, ModulePath, AstNode<Program>);
type Universe = HashMap<String, DependencyInfo>;
/// Process a number of programs, returning the graph of dependencies.
///
/// This will (currently) return a list of lists of IDs that can be safely
/// run concurrently. Each "stage" is blocking in this model, which will
/// change in the future. Don't use this function widely, yet.
#[allow(clippy::iter_over_hash_type)]
pub fn import_graph(progs: &Universe, ctx: &ExecutorContext) -> Result<Vec<Vec<String>>, KclError> {
pub fn import_graph(progs: HashMap<String, NodeRef<'_, Program>>) -> Result<Vec<Vec<String>>> {
let mut graph = Graph::new();
for (name, (_, _, _, program)) in progs.iter() {
for (name, program) in progs.iter() {
graph.extend(
import_dependencies(program, ctx)?
import_dependencies(program)?
.into_iter()
.map(|(dependency, _, _)| (name.clone(), dependency))
.map(|dependency| (name.clone(), dependency))
.collect::<Vec<_>>(),
);
}
@ -46,10 +40,7 @@ pub fn import_graph(progs: &Universe, ctx: &ExecutorContext) -> Result<Vec<Vec<S
}
#[allow(clippy::iter_over_hash_type)]
fn topsort(all_modules: &[&str], graph: Graph) -> Result<Vec<Vec<String>>, KclError> {
if all_modules.is_empty() {
return Ok(vec![]);
}
fn topsort(all_modules: &[&str], graph: Graph) -> Result<Vec<Vec<String>>> {
let mut dep_map = HashMap::<String, Vec<String>>::new();
for (dependent, dependency) in graph.iter() {
@ -92,10 +83,7 @@ fn topsort(all_modules: &[&str], graph: Graph) -> Result<Vec<Vec<String>>, KclEr
}
if stage_modules.is_empty() {
return Err(KclError::Internal(KclErrorDetails {
message: "Circular import detected".to_string(),
source_ranges: Default::default(),
}));
anyhow::bail!("imports are acyclic");
}
// not strictly needed here, but perhaps helpful to avoid thinking
@ -113,98 +101,33 @@ fn topsort(all_modules: &[&str], graph: Graph) -> Result<Vec<Vec<String>>, KclEr
Ok(order)
}
type ImportDependencies = Vec<(String, AstNode<ImportStatement>, ModulePath)>;
pub(crate) fn import_dependencies(
prog: NodeRef<Program>,
ctx: &ExecutorContext,
) -> Result<ImportDependencies, KclError> {
pub(crate) fn import_dependencies(prog: NodeRef<'_, Program>) -> Result<Vec<String>> {
let ret = Arc::new(Mutex::new(vec![]));
fn walk(ret: Arc<Mutex<ImportDependencies>>, node: Node<'_>, ctx: &ExecutorContext) -> Result<(), KclError> {
fn walk(ret: Arc<Mutex<Vec<String>>>, node: Node<'_>) {
if let Node::ImportStatement(is) = node {
// We only care about Kcl imports for now.
if let ImportPath::Kcl { filename } = &is.path {
let resolved_path = ModulePath::from_import_path(&is.path, &ctx.settings.project_directory);
let dependency = match &is.path {
ImportPath::Kcl { filename } => filename.to_string(),
ImportPath::Foreign { path } => path.to_string(),
ImportPath::Std { path } => path.join("::"),
};
// We need to lock the mutex to push the dependency.
// This is a bit of a hack, but it works for now.
ret.lock()
.map_err(|err| {
KclError::Internal(KclErrorDetails {
message: format!("Failed to lock mutex: {}", err),
source_ranges: Default::default(),
})
})?
.push((filename.to_string(), is.clone(), resolved_path));
}
ret.lock().unwrap().push(dependency);
}
for child in node.children().iter() {
walk(ret.clone(), *child, ctx)?;
walk(ret.clone(), *child)
}
Ok(())
}
walk(ret.clone(), prog.into(), ctx)?;
walk(ret.clone(), prog.into());
let ret = ret.lock().map_err(|err| {
KclError::Internal(KclErrorDetails {
message: format!("Failed to lock mutex: {}", err),
source_ranges: Default::default(),
})
})?;
Ok(ret.clone())
}
pub(crate) async fn import_universe(
ctx: &ExecutorContext,
prog: NodeRef<'_, Program>,
out: &mut Universe,
exec_state: &mut ExecState,
) -> Result<(), KclError> {
let modules = import_dependencies(prog, ctx)?;
for (filename, import_stmt, module_path) in modules {
if out.contains_key(&filename) {
continue;
}
let module_id = ctx
.open_module(&import_stmt.path, &[], exec_state, Default::default())
.await?;
let program = {
let Some(module_info) = exec_state.get_module(module_id) else {
return Err(KclError::Internal(KclErrorDetails {
message: format!("Module {} not found", module_id),
source_ranges: Default::default(),
}));
};
let ModuleRepr::Kcl(program, _) = &module_info.repr else {
return Err(KclError::Internal(KclErrorDetails {
message: format!("Module {} is not a KCL module", module_id),
source_ranges: Default::default(),
}));
};
program.clone()
};
out.insert(
filename.clone(),
(import_stmt.clone(), module_id, module_path.clone(), program.clone()),
);
Box::pin(import_universe(ctx, &program, out, exec_state)).await?;
}
Ok(())
let ret = ret.lock().unwrap().clone();
Ok(ret)
}
#[cfg(test)]
mod tests {
use super::*;
use crate::parsing::ast::types::ImportSelector;
macro_rules! kcl {
( $kcl:expr ) => {{
@ -212,41 +135,26 @@ mod tests {
}};
}
fn into_module_info(program: AstNode<Program>) -> DependencyInfo {
(
AstNode::no_src(ImportStatement {
selector: ImportSelector::None { alias: None },
path: ImportPath::Kcl { filename: "".into() },
visibility: Default::default(),
digest: None,
}),
ModuleId::default(),
ModulePath::Local { value: "".into() },
program,
)
}
#[tokio::test]
async fn order_imports() {
#[test]
fn order_imports() {
let mut modules = HashMap::new();
let a = kcl!("");
modules.insert("a.kcl".to_owned(), into_module_info(a));
modules.insert("a.kcl".to_owned(), &a);
let b = kcl!(
"
import \"a.kcl\"
"
);
modules.insert("b.kcl".to_owned(), into_module_info(b));
modules.insert("b.kcl".to_owned(), &b);
let ctx = ExecutorContext::new_mock().await;
let order = import_graph(&modules, &ctx).unwrap();
let order = import_graph(modules).unwrap();
assert_eq!(vec![vec!["a.kcl".to_owned()], vec!["b.kcl".to_owned()]], order);
}
#[tokio::test]
async fn order_imports_none() {
#[test]
fn order_imports_none() {
let mut modules = HashMap::new();
let a = kcl!(
@ -254,51 +162,49 @@ import \"a.kcl\"
y = 2
"
);
modules.insert("a.kcl".to_owned(), into_module_info(a));
modules.insert("a.kcl".to_owned(), &a);
let b = kcl!(
"
x = 1
"
);
modules.insert("b.kcl".to_owned(), into_module_info(b));
modules.insert("b.kcl".to_owned(), &b);
let ctx = ExecutorContext::new_mock().await;
let order = import_graph(&modules, &ctx).unwrap();
let order = import_graph(modules).unwrap();
assert_eq!(vec![vec!["a.kcl".to_owned(), "b.kcl".to_owned()]], order);
}
#[tokio::test]
async fn order_imports_2() {
#[test]
fn order_imports_2() {
let mut modules = HashMap::new();
let a = kcl!("");
modules.insert("a.kcl".to_owned(), into_module_info(a));
modules.insert("a.kcl".to_owned(), &a);
let b = kcl!(
"
import \"a.kcl\"
"
);
modules.insert("b.kcl".to_owned(), into_module_info(b));
modules.insert("b.kcl".to_owned(), &b);
let c = kcl!(
"
import \"a.kcl\"
"
);
modules.insert("c.kcl".to_owned(), into_module_info(c));
modules.insert("c.kcl".to_owned(), &c);
let ctx = ExecutorContext::new_mock().await;
let order = import_graph(&modules, &ctx).unwrap();
let order = import_graph(modules).unwrap();
assert_eq!(
vec![vec!["a.kcl".to_owned()], vec!["b.kcl".to_owned(), "c.kcl".to_owned()]],
order
);
}
#[tokio::test]
async fn order_imports_cycle() {
#[test]
fn order_imports_cycle() {
let mut modules = HashMap::new();
let a = kcl!(
@ -306,16 +212,15 @@ import \"a.kcl\"
import \"b.kcl\"
"
);
modules.insert("a.kcl".to_owned(), into_module_info(a));
modules.insert("a.kcl".to_owned(), &a);
let b = kcl!(
"
import \"a.kcl\"
"
);
modules.insert("b.kcl".to_owned(), into_module_info(b));
modules.insert("b.kcl".to_owned(), &b);
let ctx = ExecutorContext::new_mock().await;
import_graph(&modules, &ctx).unwrap_err();
import_graph(modules).unwrap_err();
}
}

View File

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

View File

@ -96,25 +96,6 @@ export fn circle(
///
/// example = extrude(sketch001, length = 10)
/// ```
///
/// ```
/// // Sketch on the face of a mirrored sketch, that has been extruded.
/// sketch0011 = startSketchOn(XY)
/// |> startProfileAt([6.77, 0], %)
/// |> yLine(length = 1.27)
/// |> tangentialArcTo([5.96, 2.37], %)
/// |> tangentialArcTo([-6.2, 2.44], %)
/// |> tangentialArcTo([-6.6, 1.82], %)
/// |> yLine(length = -1.82)
/// |> mirror2d( axis = X )
/// |> extrude(length = 10)
///
/// sketch002 = startSketchOn(sketch0011, 'END')
/// |> circle( center = [-0.01, 1.58], radius = 1.2 )
/// |> extrude(length = 1.2)
///
/// shell([sketch002], faces = ['end'], thickness = .1 )
/// ```
@(impl = std_rust)
export fn mirror2d(
/// The sketch or sketches to be reflected.

View File

@ -3,22 +3,6 @@ source: kcl-lib/src/simulation_tests.rs
description: Artifact commands angled_line.kcl
---
[
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],

View File

@ -3,22 +3,6 @@ source: kcl-lib/src/simulation_tests.rs
description: Artifact commands argument_error.kcl
---
[
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],

View File

@ -3,22 +3,6 @@ source: kcl-lib/src/simulation_tests.rs
description: Artifact commands array_elem_pop.kcl
---
[
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],

View File

@ -3,22 +3,6 @@ source: kcl-lib/src/simulation_tests.rs
description: Artifact commands array_elem_pop_empty_fail.kcl
---
[
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],

View File

@ -3,22 +3,6 @@ source: kcl-lib/src/simulation_tests.rs
description: Artifact commands array_elem_pop_fail.kcl
---
[
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],

View File

@ -3,22 +3,6 @@ source: kcl-lib/src/simulation_tests.rs
description: Artifact commands array_elem_push.kcl
---
[
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],

View File

@ -3,22 +3,6 @@ source: kcl-lib/src/simulation_tests.rs
description: Artifact commands array_elem_push_fail.kcl
---
[
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],

View File

@ -3,22 +3,6 @@ source: kcl-lib/src/simulation_tests.rs
description: Artifact commands array_index_oob.kcl
---
[
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],

View File

@ -3,22 +3,6 @@ source: kcl-lib/src/simulation_tests.rs
description: Artifact commands array_range_expr.kcl
---
[
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],

View File

@ -3,22 +3,6 @@ source: kcl-lib/src/simulation_tests.rs
description: Artifact commands array_range_negative_expr.kcl
---
[
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],

View File

@ -3,22 +3,6 @@ source: kcl-lib/src/simulation_tests.rs
description: Artifact commands artifact_graph_example_code1.kcl
---
[
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],

View File

@ -3,22 +3,6 @@ source: kcl-lib/src/simulation_tests.rs
description: Artifact commands artifact_graph_example_code_no_3d.kcl
---
[
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],

View File

@ -3,22 +3,6 @@ source: kcl-lib/src/simulation_tests.rs
description: Artifact commands artifact_graph_example_code_offset_planes.kcl
---
[
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],

View File

@ -3,22 +3,6 @@ source: kcl-lib/src/simulation_tests.rs
description: Artifact commands artifact_graph_sketch_on_face_etc.kcl
---
[
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],

View File

@ -7,16 +7,26 @@ description: Artifact commands assembly_mixed_units_cubes.kcl
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
"type": "edge_lines_visible",
"hidden": false
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
"type": "object_visible",
"object_id": "[uuid]",
"hidden": true
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "object_visible",
"object_id": "[uuid]",
"hidden": true
}
},
{
@ -32,7 +42,7 @@ description: Artifact commands assembly_mixed_units_cubes.kcl
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
"unit": "in"
}
},
{
@ -60,6 +70,263 @@ description: Artifact commands assembly_mixed_units_cubes.kcl
"hide": true
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "enable_sketch_mode",
"entity_id": "[uuid]",
"ortho": false,
"animated": false,
"adjust_camera": false,
"planar_normal": {
"x": 0.0,
"y": 0.0,
"z": 1.0
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "start_path"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "move_path_pen",
"path": "[uuid]",
"to": {
"x": -10.0,
"y": -10.0,
"z": 0.0
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "sketch_mode_disable"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "extend_path",
"path": "[uuid]",
"segment": {
"type": "line",
"end": {
"x": 5.0,
"y": 0.0,
"z": 0.0
},
"relative": true
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "extend_path",
"path": "[uuid]",
"segment": {
"type": "line",
"end": {
"x": 0.0,
"y": -5.0,
"z": 0.0
},
"relative": true
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "extend_path",
"path": "[uuid]",
"segment": {
"type": "line",
"end": {
"x": -5.0,
"y": 0.0,
"z": 0.0
},
"relative": true
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "extend_path",
"path": "[uuid]",
"segment": {
"type": "line",
"end": {
"x": -10.0,
"y": -10.0,
"z": 0.0
},
"relative": false
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "close_path",
"path_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "enable_sketch_mode",
"entity_id": "[uuid]",
"ortho": false,
"animated": false,
"adjust_camera": false,
"planar_normal": {
"x": 0.0,
"y": 0.0,
"z": 1.0
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "extrude",
"target": "[uuid]",
"distance": 5.0,
"faces": null
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "sketch_mode_disable"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "object_bring_to_front",
"object_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_extrusion_face_info",
"object_id": "[uuid]",
"edge_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_opposite_edge",
"object_id": "[uuid]",
"edge_id": "[uuid]",
"face_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_next_adjacent_edge",
"object_id": "[uuid]",
"edge_id": "[uuid]",
"face_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_opposite_edge",
"object_id": "[uuid]",
"edge_id": "[uuid]",
"face_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_next_adjacent_edge",
"object_id": "[uuid]",
"edge_id": "[uuid]",
"face_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_opposite_edge",
"object_id": "[uuid]",
"edge_id": "[uuid]",
"face_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_next_adjacent_edge",
"object_id": "[uuid]",
"edge_id": "[uuid]",
"face_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_opposite_edge",
"object_id": "[uuid]",
"edge_id": "[uuid]",
"face_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_next_adjacent_edge",
"object_id": "[uuid]",
"edge_id": "[uuid]",
"face_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],
@ -128,66 +395,6 @@ description: Artifact commands assembly_mixed_units_cubes.kcl
"type": "sketch_mode_disable"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "enable_sketch_mode",
"entity_id": "[uuid]",
"ortho": false,
"animated": false,
"adjust_camera": false,
"planar_normal": {
"x": 0.0,
"y": 0.0,
"z": 1.0
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "start_path"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "move_path_pen",
"path": "[uuid]",
"to": {
"x": -10.0,
"y": -10.0,
"z": 0.0
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "sketch_mode_disable"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "extend_path",
"path": "[uuid]",
"segment": {
"type": "line",
"end": {
"x": 5.0,
"y": 0.0,
"z": 0.0
},
"relative": true
}
}
},
{
"cmdId": "[uuid]",
"range": [],
@ -222,40 +429,6 @@ description: Artifact commands assembly_mixed_units_cubes.kcl
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "extend_path",
"path": "[uuid]",
"segment": {
"type": "line",
"end": {
"x": 0.0,
"y": -5.0,
"z": 0.0
},
"relative": true
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "extend_path",
"path": "[uuid]",
"segment": {
"type": "line",
"end": {
"x": -5.0,
"y": 0.0,
"z": 0.0
},
"relative": true
}
}
},
{
"cmdId": "[uuid]",
"range": [],
@ -290,31 +463,6 @@ description: Artifact commands assembly_mixed_units_cubes.kcl
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "extend_path",
"path": "[uuid]",
"segment": {
"type": "line",
"end": {
"x": -10.0,
"y": -10.0,
"z": 0.0
},
"relative": false
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "close_path",
"path_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
@ -373,56 +521,6 @@ description: Artifact commands assembly_mixed_units_cubes.kcl
"edge_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "enable_sketch_mode",
"entity_id": "[uuid]",
"ortho": false,
"animated": false,
"adjust_camera": false,
"planar_normal": {
"x": 0.0,
"y": 0.0,
"z": 1.0
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "extrude",
"target": "[uuid]",
"distance": 5.0,
"faces": null
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "sketch_mode_disable"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "object_bring_to_front",
"object_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_extrusion_face_info",
"object_id": "[uuid]",
"edge_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
@ -503,120 +601,6 @@ description: Artifact commands assembly_mixed_units_cubes.kcl
"face_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_opposite_edge",
"object_id": "[uuid]",
"edge_id": "[uuid]",
"face_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_next_adjacent_edge",
"object_id": "[uuid]",
"edge_id": "[uuid]",
"face_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_opposite_edge",
"object_id": "[uuid]",
"edge_id": "[uuid]",
"face_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_next_adjacent_edge",
"object_id": "[uuid]",
"edge_id": "[uuid]",
"face_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_opposite_edge",
"object_id": "[uuid]",
"edge_id": "[uuid]",
"face_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_next_adjacent_edge",
"object_id": "[uuid]",
"edge_id": "[uuid]",
"face_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_opposite_edge",
"object_id": "[uuid]",
"edge_id": "[uuid]",
"face_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_next_adjacent_edge",
"object_id": "[uuid]",
"edge_id": "[uuid]",
"face_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "edge_lines_visible",
"hidden": false
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "object_visible",
"object_id": "[uuid]",
"hidden": true
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "object_visible",
"object_id": "[uuid]",
"hidden": true
}
},
{
"cmdId": "[uuid]",
"range": [],

View File

@ -1,47 +1,47 @@
```mermaid
flowchart LR
subgraph path3 [Path]
3["Path<br>[76, 111, 6]"]
5["Segment<br>[117, 134, 6]"]
7["Segment<br>[140, 158, 6]"]
9["Segment<br>[164, 182, 6]"]
11["Segment<br>[188, 244, 6]"]
13["Segment<br>[250, 257, 6]"]
14[Solid2d]
subgraph path2 [Path]
2["Path<br>[76, 113, 5]"]
3["Segment<br>[119, 136, 5]"]
4["Segment<br>[142, 160, 5]"]
5["Segment<br>[166, 184, 5]"]
6["Segment<br>[190, 246, 5]"]
7["Segment<br>[252, 259, 5]"]
8[Solid2d]
end
subgraph path4 [Path]
4["Path<br>[76, 113, 5]"]
6["Segment<br>[119, 136, 5]"]
8["Segment<br>[142, 160, 5]"]
10["Segment<br>[166, 184, 5]"]
12["Segment<br>[190, 246, 5]"]
15["Segment<br>[252, 259, 5]"]
16[Solid2d]
subgraph path25 [Path]
25["Path<br>[76, 111, 6]"]
26["Segment<br>[117, 134, 6]"]
27["Segment<br>[140, 158, 6]"]
28["Segment<br>[164, 182, 6]"]
29["Segment<br>[188, 244, 6]"]
30["Segment<br>[250, 257, 6]"]
31[Solid2d]
end
1["Plane<br>[47, 66, 6]"]
2["Plane<br>[47, 66, 5]"]
17["Sweep Extrusion<br>[263, 285, 6]"]
18[Wall]
19[Wall]
20[Wall]
21[Wall]
22["Cap Start"]
23["Cap End"]
24["Sweep Extrusion<br>[265, 287, 5]"]
25[Wall]
26[Wall]
27[Wall]
28[Wall]
29["Cap Start"]
30["Cap End"]
31["SweepEdge Opposite"]
32["SweepEdge Adjacent"]
33["SweepEdge Opposite"]
34["SweepEdge Adjacent"]
35["SweepEdge Opposite"]
36["SweepEdge Adjacent"]
37["SweepEdge Opposite"]
38["SweepEdge Adjacent"]
1["Plane<br>[47, 66, 5]"]
9["Sweep Extrusion<br>[265, 287, 5]"]
10[Wall]
11[Wall]
12[Wall]
13[Wall]
14["Cap Start"]
15["Cap End"]
16["SweepEdge Opposite"]
17["SweepEdge Adjacent"]
18["SweepEdge Opposite"]
19["SweepEdge Adjacent"]
20["SweepEdge Opposite"]
21["SweepEdge Adjacent"]
22["SweepEdge Opposite"]
23["SweepEdge Adjacent"]
24["Plane<br>[47, 66, 6]"]
32["Sweep Extrusion<br>[263, 285, 6]"]
33[Wall]
34[Wall]
35[Wall]
36[Wall]
37["Cap Start"]
38["Cap End"]
39["SweepEdge Opposite"]
40["SweepEdge Adjacent"]
41["SweepEdge Opposite"]
@ -50,72 +50,72 @@ flowchart LR
44["SweepEdge Adjacent"]
45["SweepEdge Opposite"]
46["SweepEdge Adjacent"]
1 --- 3
1 --- 2
2 --- 3
2 --- 4
3 --- 5
3 --- 7
3 --- 9
3 --- 11
2 --- 5
2 --- 6
2 --- 7
2 ---- 9
2 --- 8
3 --- 13
3 ---- 17
3 --- 14
4 --- 6
4 --- 8
4 --- 10
3 --- 22
3 --- 23
4 --- 12
4 --- 15
4 ---- 24
4 --- 16
5 --- 21
5 --- 37
5 --- 38
6 --- 28
6 --- 45
6 --- 46
7 --- 20
7 --- 35
7 --- 36
8 --- 27
8 --- 43
8 --- 44
4 --- 20
4 --- 21
5 --- 11
5 --- 18
5 --- 19
6 --- 10
6 --- 16
6 --- 17
9 --- 10
9 --- 11
9 --- 12
9 --- 13
9 --- 14
9 --- 15
9 --- 16
9 --- 17
9 --- 18
9 --- 19
9 --- 33
9 --- 34
10 --- 26
10 --- 41
10 --- 42
11 --- 18
11 --- 31
11 --- 32
12 --- 25
12 --- 39
12 --- 40
17 --- 18
17 --- 19
17 --- 20
17 --- 21
17 --- 22
17 --- 23
17 --- 31
17 --- 32
17 --- 33
17 --- 34
17 --- 35
17 --- 36
17 --- 37
17 --- 38
9 --- 20
9 --- 21
9 --- 22
9 --- 23
24 --- 25
24 --- 26
24 --- 27
24 --- 28
24 --- 29
24 --- 30
24 --- 39
24 --- 40
24 --- 41
24 --- 42
24 --- 43
24 --- 44
24 --- 45
24 --- 46
25 --- 26
25 --- 27
25 --- 28
25 --- 29
25 --- 30
25 ---- 32
25 --- 31
26 --- 36
26 --- 45
26 --- 46
27 --- 35
27 --- 43
27 --- 44
28 --- 34
28 --- 41
28 --- 42
29 --- 33
29 --- 39
29 --- 40
32 --- 33
32 --- 34
32 --- 35
32 --- 36
32 --- 37
32 --- 38
32 --- 39
32 --- 40
32 --- 41
32 --- 42
32 --- 43
32 --- 44
32 --- 45
32 --- 46
```

View File

@ -12,6 +12,53 @@ description: Operations executed assembly_mixed_units_cubes.kcl
},
"sourceRange": []
},
{
"labeledArgs": {
"data": {
"value": {
"type": "String",
"value": "XY"
},
"sourceRange": []
}
},
"name": "startSketchOn",
"sourceRange": [],
"type": "StdLibCall",
"unlabeledArg": null
},
{
"labeledArgs": {
"length": {
"value": {
"type": "Number",
"value": 5.0,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
},
"sourceRange": []
}
},
"name": "extrude",
"sourceRange": [],
"type": "StdLibCall",
"unlabeledArg": {
"value": {
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
"sourceRange": []
}
},
{
"type": "GroupEnd"
},
@ -24,6 +71,53 @@ description: Operations executed assembly_mixed_units_cubes.kcl
},
"sourceRange": []
},
{
"labeledArgs": {
"data": {
"value": {
"type": "String",
"value": "XY"
},
"sourceRange": []
}
},
"name": "startSketchOn",
"sourceRange": [],
"type": "StdLibCall",
"unlabeledArg": null
},
{
"labeledArgs": {
"length": {
"value": {
"type": "Number",
"value": 5.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
},
"sourceRange": []
}
},
"name": "extrude",
"sourceRange": [],
"type": "StdLibCall",
"unlabeledArg": {
"value": {
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
"sourceRange": []
}
},
{
"type": "GroupEnd"
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 35 KiB

View File

@ -7,16 +7,26 @@ description: Artifact commands assembly_non_default_units.kcl
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
"type": "edge_lines_visible",
"hidden": false
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
"type": "object_visible",
"object_id": "[uuid]",
"hidden": true
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "object_visible",
"object_id": "[uuid]",
"hidden": true
}
},
{
@ -83,131 +93,6 @@ description: Artifact commands assembly_non_default_units.kcl
"type": "start_path"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "move_path_pen",
"path": "[uuid]",
"to": {
"x": 1.0,
"y": 2.0,
"z": 0.0
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "sketch_mode_disable"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "extend_path",
"path": "[uuid]",
"segment": {
"type": "arc",
"center": {
"x": 0.0,
"y": 2.0
},
"radius": 1.0,
"start": {
"unit": "degrees",
"value": 0.0
},
"end": {
"unit": "degrees",
"value": 360.0
},
"relative": false
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "close_path",
"path_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "in"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "make_plane",
"origin": {
"x": 0.0,
"y": 0.0,
"z": 0.0
},
"x_axis": {
"x": 1.0,
"y": 0.0,
"z": 0.0
},
"y_axis": {
"x": 0.0,
"y": 0.0,
"z": 1.0
},
"size": 60.0,
"clobber": false,
"hide": true
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "enable_sketch_mode",
"entity_id": "[uuid]",
"ortho": false,
"animated": false,
"adjust_camera": false,
"planar_normal": {
"x": 0.0,
"y": -1.0,
"z": 0.0
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "start_path"
}
},
{
"cmdId": "[uuid]",
"range": [],
@ -261,40 +146,6 @@ description: Artifact commands assembly_non_default_units.kcl
"path_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "edge_lines_visible",
"hidden": false
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "object_visible",
"object_id": "[uuid]",
"hidden": true
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "object_visible",
"object_id": "[uuid]",
"hidden": true
}
},
{
"cmdId": "[uuid]",
"range": [],
@ -302,5 +153,106 @@ description: Artifact commands assembly_non_default_units.kcl
"type": "set_scene_units",
"unit": "in"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "make_plane",
"origin": {
"x": 0.0,
"y": 0.0,
"z": 0.0
},
"x_axis": {
"x": 1.0,
"y": 0.0,
"z": 0.0
},
"y_axis": {
"x": 0.0,
"y": 0.0,
"z": 1.0
},
"size": 60.0,
"clobber": false,
"hide": true
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "enable_sketch_mode",
"entity_id": "[uuid]",
"ortho": false,
"animated": false,
"adjust_camera": false,
"planar_normal": {
"x": 0.0,
"y": -1.0,
"z": 0.0
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "start_path"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "move_path_pen",
"path": "[uuid]",
"to": {
"x": 1.0,
"y": 2.0,
"z": 0.0
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "sketch_mode_disable"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "extend_path",
"path": "[uuid]",
"segment": {
"type": "arc",
"center": {
"x": 0.0,
"y": 2.0
},
"radius": 1.0,
"start": {
"unit": "degrees",
"value": 0.0
},
"end": {
"unit": "degrees",
"value": 360.0
},
"relative": false
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "close_path",
"path_id": "[uuid]"
}
}
]

View File

@ -1,17 +1,17 @@
```mermaid
flowchart LR
subgraph path2 [Path]
2["Path<br>[113, 148, 7]"]
3["Segment<br>[113, 148, 7]"]
2["Path<br>[197, 232, 5]"]
3["Segment<br>[197, 232, 5]"]
4[Solid2d]
end
subgraph path6 [Path]
6["Path<br>[197, 232, 5]"]
7["Segment<br>[197, 232, 5]"]
6["Path<br>[113, 148, 6]"]
7["Segment<br>[113, 148, 6]"]
8[Solid2d]
end
1["Plane<br>[88, 107, 7]"]
5["Plane<br>[172, 191, 5]"]
1["Plane<br>[172, 191, 5]"]
5["Plane<br>[88, 107, 6]"]
1 --- 2
2 --- 3
2 --- 4

View File

@ -12,6 +12,21 @@ description: Operations executed assembly_non_default_units.kcl
},
"sourceRange": []
},
{
"labeledArgs": {
"data": {
"value": {
"type": "String",
"value": "XZ"
},
"sourceRange": []
}
},
"name": "startSketchOn",
"sourceRange": [],
"type": "StdLibCall",
"unlabeledArg": null
},
{
"type": "GroupEnd"
},
@ -20,10 +35,25 @@ description: Operations executed assembly_non_default_units.kcl
"group": {
"type": "ModuleInstance",
"name": "other2",
"moduleId": 7
"moduleId": 6
},
"sourceRange": []
},
{
"labeledArgs": {
"data": {
"value": {
"type": "String",
"value": "XZ"
},
"sourceRange": []
}
},
"name": "startSketchOn",
"sourceRange": [],
"type": "StdLibCall",
"unlabeledArg": null
},
{
"type": "GroupEnd"
}

View File

@ -9,6 +9,6 @@ description: Variables in memory after executing assembly_non_default_units.kcl
},
"other2": {
"type": "Module",
"value": 7
"value": 6
}
}

View File

@ -3,22 +3,6 @@ source: kcl-lib/src/simulation_tests.rs
description: Artifact commands bad_units_in_annotation.kcl
---
[
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],

View File

@ -3,22 +3,6 @@ source: kcl-lib/src/simulation_tests.rs
description: Artifact commands basic_fillet_cube_close_opposite.kcl
---
[
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],

View File

@ -3,22 +3,6 @@ source: kcl-lib/src/simulation_tests.rs
description: Artifact commands basic_fillet_cube_end.kcl
---
[
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],

View File

@ -3,22 +3,6 @@ source: kcl-lib/src/simulation_tests.rs
description: Artifact commands basic_fillet_cube_next_adjacent.kcl
---
[
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],

View File

@ -3,22 +3,6 @@ source: kcl-lib/src/simulation_tests.rs
description: Artifact commands basic_fillet_cube_previous_adjacent.kcl
---
[
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],

View File

@ -3,22 +3,6 @@ source: kcl-lib/src/simulation_tests.rs
description: Artifact commands basic_fillet_cube_start.kcl
---
[
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],

View File

@ -3,22 +3,6 @@ source: kcl-lib/src/simulation_tests.rs
description: Artifact commands big_number_angle_to_match_length_x.kcl
---
[
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],

View File

@ -3,22 +3,6 @@ source: kcl-lib/src/simulation_tests.rs
description: Artifact commands big_number_angle_to_match_length_y.kcl
---
[
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],

View File

@ -3,22 +3,6 @@ source: kcl-lib/src/simulation_tests.rs
description: Artifact commands boolean_logical_and.kcl
---
[
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],

View File

@ -3,22 +3,6 @@ source: kcl-lib/src/simulation_tests.rs
description: Artifact commands boolean_logical_multiple.kcl
---
[
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],

View File

@ -3,22 +3,6 @@ source: kcl-lib/src/simulation_tests.rs
description: Artifact commands boolean_logical_or.kcl
---
[
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],

View File

@ -3,22 +3,6 @@ source: kcl-lib/src/simulation_tests.rs
description: Artifact commands circle_three_point.kcl
---
[
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],

View File

@ -3,22 +3,6 @@ source: kcl-lib/src/simulation_tests.rs
description: Artifact commands circular_pattern3d_a_pattern.kcl
---
[
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],

View File

@ -3,22 +3,6 @@ source: kcl-lib/src/simulation_tests.rs
description: Artifact commands comparisons.kcl
---
[
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],

View File

@ -3,22 +3,6 @@ source: kcl-lib/src/simulation_tests.rs
description: Artifact commands comparisons_multiple.kcl
---
[
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],

View File

@ -3,22 +3,6 @@ source: kcl-lib/src/simulation_tests.rs
description: Artifact commands computed_var.kcl
---
[
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],

View File

@ -3,22 +3,6 @@ source: kcl-lib/src/simulation_tests.rs
description: Artifact commands crazy_multi_profile.kcl
---
[
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],

View File

@ -3,22 +3,6 @@ source: kcl-lib/src/simulation_tests.rs
description: Artifact commands cube.kcl
---
[
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],

View File

@ -3,22 +3,6 @@ source: kcl-lib/src/simulation_tests.rs
description: Artifact commands cube_with_error.kcl
---
[
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],

View File

@ -3,22 +3,6 @@ source: kcl-lib/src/simulation_tests.rs
description: Artifact commands double_map_fn.kcl
---
[
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],

View File

@ -3,22 +3,6 @@ source: kcl-lib/src/simulation_tests.rs
description: Artifact commands fillet-and-shell.kcl
---
[
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],

View File

@ -0,0 +1,71 @@
holeFudge = 0.4
frontBarD = 5.0
yBarD = 6.7
slideGap = 0.7
lowerBlockTransHole = {
r = (frontBarD + slideGap + holeFudge) / 2
}
upperBlockLongHole = { r = (yBarD + holeFudge) / 2 }
upperBlockTransHole = { r = (yBarD + holeFudge) / 2 }
tubeClr = 1.5
lowerBlock = {
h = 2 * lowerBlockTransHole.r + 2 * tubeClr,
l = 70
}
upperBlock = {
h = 2 * upperBlockLongHole.r + 2 * tubeClr,
l = 25
}
elevate = { h = 5 }
blockSz = max(upperBlock.h, lowerBlock.h)
slot = { l = 10, h = 1 }
sketch001 = startSketchOn(XZ)
|> startProfileAt([0, 0], %)
|> yLine(length = blockSz, tag = $edgeA)
|> xLine(length = blockSz, tag = $edgeB)
|> yLine(length = -blockSz, tag = $edgeC)
|> xLine(length = upperBlock.l - blockSz, tag = $edge1)
|> yLine(length = -(elevate.h + blockSz), tag = $edge2)
|> xLine(length = lowerBlock.l - blockSz, tag = $edge3)
|> yLine(length = -blockSz, tag = $edge4)
|> xLine(length = -lowerBlock.l, tag = $edge5)
|> yLine(length = blockSz + elevate.h, tag = $edge6)
|> xLine(length = -(upperBlock.l - blockSz), tag = $edge7)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)], tag = $seg01)
|> close(%)
|> hole(circle(center = [blockSz / 2, blockSz / 2], radius = upperBlockTransHole.r), %)
|> hole(circle(
center = [
upperBlock.l + lowerBlock.l - blockSz - lowerBlockTransHole.r - tubeClr,
-(blockSz + elevate.h + blockSz / 2)
],
radius = lowerBlockTransHole.r,
), %)
rad = 3
extrude001 = extrude(sketch001, length = blockSz)
|> fillet(
radius = rad,
tags = [
getNextAdjacentEdge(edgeA),
getNextAdjacentEdge(edgeB),
getNextAdjacentEdge(edgeC),
getNextAdjacentEdge(edge1),
getNextAdjacentEdge(edge2),
getNextAdjacentEdge(edge3),
getNextAdjacentEdge(edge4),
getNextAdjacentEdge(edge5),
getNextAdjacentEdge(edge6),
getNextAdjacentEdge(edge7)
],
)
sketch002 = startSketchOn(extrude001, seg01)
|> startProfileAt([0, 0], %)
|> circle(center = [blockSz / 2, -blockSz / 2], radius = upperBlockLongHole.r)
|> extrude(length = -upperBlock.l)

View File

@ -0,0 +1,24 @@
holeFudgeD = 0.4
holeFudgeR = holeFudgeD / 2
totalH = 12.5
switchNutD = 9.5
switchNutR = switchNutD / 2
bottomInnerR = switchNutR + holeFudgeR
bottomOuterR = 13.5
topInnerR = switchNutR + 1.5 + holeFudgeR
topFlatL = 1
topOuterR = topInnerR + topFlatL
baseH = 1
coneH = totalH - baseH
sketch001 = startSketchOn(XZ)
|> startProfileAt([bottomInnerR, 0], %)
|> xLine(endAbsolute = bottomOuterR)
|> yLine(length = baseH)
|> line(end = [-(bottomOuterR - topOuterR), coneH])
|> line(end = [-(topOuterR - topInnerR), 0])
|> close(%)
|> revolve(axis = Y)

View File

@ -3,22 +3,6 @@ source: kcl-lib/src/simulation_tests.rs
description: Artifact commands flush_batch_on_end.kcl
---
[
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],

View File

@ -3,22 +3,6 @@ source: kcl-lib/src/simulation_tests.rs
description: Artifact commands function_sketch.kcl
---
[
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],

View File

@ -3,22 +3,6 @@ source: kcl-lib/src/simulation_tests.rs
description: Artifact commands function_sketch_with_position.kcl
---
[
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],

View File

@ -3,22 +3,6 @@ source: kcl-lib/src/simulation_tests.rs
description: Artifact commands helix_ccw.kcl
---
[
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],

View File

@ -3,22 +3,6 @@ source: kcl-lib/src/simulation_tests.rs
description: Artifact commands helix_simple.kcl
---
[
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],

View File

@ -3,22 +3,6 @@ source: kcl-lib/src/simulation_tests.rs
description: Artifact commands i_shape.kcl
---
[
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],

View File

@ -3,22 +3,6 @@ source: kcl-lib/src/simulation_tests.rs
description: Artifact commands if_else.kcl
---
[
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],

View File

@ -3,22 +3,6 @@ source: kcl-lib/src/simulation_tests.rs
description: Artifact commands import_constant.kcl
---
[
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],

View File

@ -3,22 +3,6 @@ source: kcl-lib/src/simulation_tests.rs
description: Artifact commands import_export.kcl
---
[
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],

View File

@ -2,4 +2,31 @@
source: kcl-lib/src/simulation_tests.rs
description: Artifact commands import_file_not_exist_error.kcl
---
[]
[
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "edge_lines_visible",
"hidden": false
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "object_visible",
"object_id": "[uuid]",
"hidden": true
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "object_visible",
"object_id": "[uuid]",
"hidden": true
}
}
]

View File

@ -1,5 +1,5 @@
---
source: kcl-lib/src/simulation_tests.rs
source: kcl/src/simulation_tests.rs
description: Error from executing import_file_not_exist_error.kcl
---
KCL I/O error
@ -8,6 +8,6 @@ KCL I/O error
│ exist.kcl`: No such file or directory (os error 2)
╭────
1 │ import hotdog from "not-exist.kcl"
·
· ╰── main
· ─────────────────┬────────────────
· ╰── tests/import_file_not_exist_error/input.kcl
╰────

View File

@ -2,4 +2,31 @@
source: kcl-lib/src/simulation_tests.rs
description: Artifact commands import_file_parse_error.kcl
---
[]
[
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "edge_lines_visible",
"hidden": false
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "object_visible",
"object_id": "[uuid]",
"hidden": true
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "object_visible",
"object_id": "[uuid]",
"hidden": true
}
}
]

View File

@ -1,12 +1,13 @@
---
source: kcl-lib/src/simulation_tests.rs
source: kcl/src/simulation_tests.rs
description: Error from executing import_file_parse_error.kcl
---
KCL Syntax error
× syntax: Unexpected token: }
╭────
1import hotdog from "parse-failure.kcl"
· ┬
· ╰── main
╭─[3:1]
2 return
3 │ }
·
· ╰── tests/import_file_parse_error/parse-failure.kcl
╰────

View File

@ -3,22 +3,6 @@ source: kcl-lib/src/simulation_tests.rs
description: Artifact commands import_foreign.kcl
---
[
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],

View File

@ -3,426 +3,6 @@ source: kcl-lib/src/simulation_tests.rs
description: Artifact commands import_function_not_sketch.kcl
---
[
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "make_plane",
"origin": {
"x": 0.0,
"y": 0.0,
"z": 0.0
},
"x_axis": {
"x": 1.0,
"y": 0.0,
"z": 0.0
},
"y_axis": {
"x": 0.0,
"y": 1.0,
"z": 0.0
},
"size": 60.0,
"clobber": false,
"hide": true
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "enable_sketch_mode",
"entity_id": "[uuid]",
"ortho": false,
"animated": false,
"adjust_camera": false,
"planar_normal": {
"x": 0.0,
"y": 0.0,
"z": 1.0
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "start_path"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "move_path_pen",
"path": "[uuid]",
"to": {
"x": 4.0,
"y": 12.0,
"z": 0.0
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "sketch_mode_disable"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "extend_path",
"path": "[uuid]",
"segment": {
"type": "line",
"end": {
"x": 2.0,
"y": 0.0,
"z": 0.0
},
"relative": true
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "extend_path",
"path": "[uuid]",
"segment": {
"type": "line",
"end": {
"x": 0.0,
"y": -6.0,
"z": 0.0
},
"relative": true
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "extend_path",
"path": "[uuid]",
"segment": {
"type": "line",
"end": {
"x": 4.0,
"y": -6.0,
"z": 0.0
},
"relative": true
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "extend_path",
"path": "[uuid]",
"segment": {
"type": "line",
"end": {
"x": 0.0,
"y": -6.0,
"z": 0.0
},
"relative": true
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "extend_path",
"path": "[uuid]",
"segment": {
"type": "line",
"end": {
"x": -3.75,
"y": -4.5,
"z": 0.0
},
"relative": true
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "extend_path",
"path": "[uuid]",
"segment": {
"type": "line",
"end": {
"x": 0.0,
"y": -5.5,
"z": 0.0
},
"relative": true
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "extend_path",
"path": "[uuid]",
"segment": {
"type": "line",
"end": {
"x": -2.0,
"y": 0.0,
"z": 0.0
},
"relative": true
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "close_path",
"path_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "revolve",
"target": "[uuid]",
"origin": {
"x": 0.0,
"y": 0.0,
"z": 0.0
},
"axis": {
"x": 0.0,
"y": 1.0,
"z": 0.0
},
"axis_is_2d": true,
"angle": {
"unit": "degrees",
"value": 360.0
},
"tolerance": 0.0000001
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "object_bring_to_front",
"object_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_extrusion_face_info",
"object_id": "[uuid]",
"edge_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_opposite_edge",
"object_id": "[uuid]",
"edge_id": "[uuid]",
"face_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_next_adjacent_edge",
"object_id": "[uuid]",
"edge_id": "[uuid]",
"face_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_opposite_edge",
"object_id": "[uuid]",
"edge_id": "[uuid]",
"face_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_next_adjacent_edge",
"object_id": "[uuid]",
"edge_id": "[uuid]",
"face_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_opposite_edge",
"object_id": "[uuid]",
"edge_id": "[uuid]",
"face_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_next_adjacent_edge",
"object_id": "[uuid]",
"edge_id": "[uuid]",
"face_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_opposite_edge",
"object_id": "[uuid]",
"edge_id": "[uuid]",
"face_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_next_adjacent_edge",
"object_id": "[uuid]",
"edge_id": "[uuid]",
"face_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_opposite_edge",
"object_id": "[uuid]",
"edge_id": "[uuid]",
"face_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_next_adjacent_edge",
"object_id": "[uuid]",
"edge_id": "[uuid]",
"face_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_opposite_edge",
"object_id": "[uuid]",
"edge_id": "[uuid]",
"face_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_next_adjacent_edge",
"object_id": "[uuid]",
"edge_id": "[uuid]",
"face_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_opposite_edge",
"object_id": "[uuid]",
"edge_id": "[uuid]",
"face_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_next_adjacent_edge",
"object_id": "[uuid]",
"edge_id": "[uuid]",
"face_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_opposite_edge",
"object_id": "[uuid]",
"edge_id": "[uuid]",
"face_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_next_adjacent_edge",
"object_id": "[uuid]",
"edge_id": "[uuid]",
"face_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],

View File

@ -1,5 +1,6 @@
---
source: kcl-lib/src/simulation_tests.rs
source: kcl/src/simulation_tests.rs
assertion_line: 189
description: Artifact graph flowchart import_function_not_sketch.kcl
extension: md
snapshot_kind: binary

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