Skip to content

Commit

Permalink
Merge branch 'main' into nadro/gh-5157/center-rectangle-kcl-fix
Browse files Browse the repository at this point in the history
  • Loading branch information
nadr0 committed Jan 31, 2025
2 parents 519041c + 1e56537 commit f5ec62a
Show file tree
Hide file tree
Showing 85 changed files with 6,769 additions and 831 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ e2e/playwright/temp3.png
e2e/playwright/export-snapshots/*
!e2e/playwright/export-snapshots/*.png


/kcl-samples
/test-results/
/playwright-report/
/blob-report/
Expand Down
6 changes: 4 additions & 2 deletions docs/kcl/import.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,16 @@ excerpt: "Import a CAD file."
layout: manual
---

**WARNING:** This function is deprecated.

Import a CAD file.

**DEPRECATED** Prefer to use import statements.

For formats lacking unit data (such as STL, OBJ, or PLY files), the default unit of measurement is millimeters. Alternatively you may specify the unit by passing your desired measurement unit in the options parameter. When importing a GLTF file, the bin file will be imported as well. Import paths are relative to the current project directory.

Note: The import command currently only works when using the native Modeling App.

For importing KCL functions using the `import` statement, see the docs on [KCL modules](/docs/kcl/modules).

```js
import(file_path: String, options?: ImportFormat) -> ImportedGeometry
```
Expand Down
1 change: 0 additions & 1 deletion docs/kcl/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ layout: manual
* [`helixRevolutions`](kcl/helixRevolutions)
* [`hole`](kcl/hole)
* [`hollow`](kcl/hollow)
* [`import`](kcl/import)
* [`inch`](kcl/inch)
* [`lastSegX`](kcl/lastSegX)
* [`lastSegY`](kcl/lastSegY)
Expand Down
4 changes: 2 additions & 2 deletions docs/kcl/std.json
Original file line number Diff line number Diff line change
Expand Up @@ -92765,7 +92765,7 @@
{
"name": "import",
"summary": "Import a CAD file.",
"description": "For formats lacking unit data (such as STL, OBJ, or PLY files), the default unit of measurement is millimeters. Alternatively you may specify the unit by passing your desired measurement unit in the options parameter. When importing a GLTF file, the bin file will be imported as well. Import paths are relative to the current project directory.\n\nNote: The import command currently only works when using the native Modeling App.\n\nFor importing KCL functions using the `import` statement, see the docs on [KCL modules](/docs/kcl/modules).",
"description": "**DEPRECATED** Prefer to use import statements.\n\nFor formats lacking unit data (such as STL, OBJ, or PLY files), the default unit of measurement is millimeters. Alternatively you may specify the unit by passing your desired measurement unit in the options parameter. When importing a GLTF file, the bin file will be imported as well. Import paths are relative to the current project directory.\n\nNote: The import command currently only works when using the native Modeling App.",
"tags": [],
"keywordArguments": false,
"args": [
Expand Down Expand Up @@ -93168,7 +93168,7 @@
"labelRequired": true
},
"unpublished": false,
"deprecated": false,
"deprecated": true,
"examples": [
"model = import(\"tests/inputs/cube.obj\")",
"model = import(\"tests/inputs/cube.obj\", { format = \"obj\", units = \"m\" })",
Expand Down
1 change: 1 addition & 0 deletions src/lang/KclSingleton.ts
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,7 @@ export class KclManager {
await this.ensureWasmInit()
const { logs, errors, execState, isInterrupted } = await executeAst({
ast,
path: codeManager.currentFilePath || undefined,
engineCommandManager: this.engineCommandManager,
})

Expand Down
4 changes: 4 additions & 0 deletions src/lang/codeManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,10 @@ export default class CodeManager {
}))
}

get currentFilePath(): string | null {
return this._currentFilePath
}

updateCurrentFilePath(path: string) {
this._currentFilePath = path
}
Expand Down
29 changes: 12 additions & 17 deletions src/lang/kclSamples.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,27 +52,22 @@ afterAll(async () => {
} catch (e) {}
})

afterEach(() => {
process.chdir('..')
})

// The tests have to be sequential because we need to change directories
// to support `import` working properly.
// @ts-expect-error
describe.sequential('Test KCL Samples from public Github repository', () => {
// @ts-expect-error
describe.sequential('when performing enginelessExecutor', () => {
describe('Test KCL Samples from public Github repository', () => {
describe('when performing enginelessExecutor', () => {
manifest.forEach((file: KclSampleFile) => {
// @ts-expect-error
it.sequential(
it(
`should execute ${file.title} (${file.file}) successfully`,
async () => {
const [dirProject, fileKcl] =
file.pathFromProjectDirectoryToFirstFile.split('/')
process.chdir(dirProject)
const code = await fs.readFile(fileKcl, 'utf-8')
const code = await fs.readFile(
file.pathFromProjectDirectoryToFirstFile,
'utf-8'
)
const ast = assertParse(code)
await enginelessExecutor(ast, programMemoryInit())
await enginelessExecutor(
ast,
programMemoryInit(),
file.pathFromProjectDirectoryToFirstFile
)
},
files.length * 1000
)
Expand Down
6 changes: 4 additions & 2 deletions src/lang/langHelpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,14 @@ export const toolTips: Array<ToolTip> = [

export async function executeAst({
ast,
path,
engineCommandManager,
// If you set programMemoryOverride we assume you mean mock mode. Since that
// is the only way to go about it.
programMemoryOverride,
}: {
ast: Node<Program>
path?: string
engineCommandManager: EngineCommandManager
programMemoryOverride?: ProgramMemory
isInterrupted?: boolean
Expand All @@ -63,8 +65,8 @@ export async function executeAst({
}> {
try {
const execState = await (programMemoryOverride
? enginelessExecutor(ast, programMemoryOverride)
: executor(ast, engineCommandManager))
? enginelessExecutor(ast, programMemoryOverride, path)
: executor(ast, engineCommandManager, path))

await engineCommandManager.waitForAllCommands()

Expand Down
3 changes: 3 additions & 0 deletions src/lang/std/fileSystemManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ class FileSystemManager {
}

async join(dir: string, path: string): Promise<string> {
if (path.startsWith(dir)) {
path = path.slice(dir.length)
}
return Promise.resolve(window.electron.path.join(dir, path))
}

Expand Down
11 changes: 11 additions & 0 deletions src/lang/wasm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -567,9 +567,19 @@ export function sketchFromKclValue(
return result
}

/**
* Execute a KCL program.
* @param node The AST of the program to execute.
* @param path The full path of the file being executed. Use `null` for
* expressions that don't have a file, like expressions in the command bar.
* @param programMemoryOverride If this is not `null`, this will be used as the
* initial program memory, and the execution will be engineless (AKA mock
* execution).
*/
export const executor = async (
node: Node<Program>,
engineCommandManager: EngineCommandManager,
path?: string,
programMemoryOverride: ProgramMemory | Error | null = null
): Promise<ExecState> => {
if (programMemoryOverride !== null && err(programMemoryOverride))
Expand All @@ -591,6 +601,7 @@ export const executor = async (
}
const execOutcome: RustExecOutcome = await execute(
JSON.stringify(node),
path,
JSON.stringify(programMemoryOverride?.toRaw() || null),
JSON.stringify({ settings: jsAppSettings }),
engineCommandManager,
Expand Down
5 changes: 3 additions & 2 deletions src/lib/testHelpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,8 @@ class MockEngineCommandManager {

export async function enginelessExecutor(
ast: Node<Program>,
pmo: ProgramMemory | Error = ProgramMemory.empty()
pmo: ProgramMemory | Error = ProgramMemory.empty(),
path?: string
): Promise<ExecState> {
if (pmo !== null && err(pmo)) return Promise.reject(pmo)

Expand All @@ -90,7 +91,7 @@ export async function enginelessExecutor(
}) as any as EngineCommandManager
// eslint-disable-next-line @typescript-eslint/no-floating-promises
mockEngineCommandManager.startNewSession()
const execState = await executor(ast, mockEngineCommandManager, pmo)
const execState = await executor(ast, mockEngineCommandManager, path, pmo)
await mockEngineCommandManager.waitForAllCommands()
return execState
}
6 changes: 3 additions & 3 deletions src/wasm-lib/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src/wasm-lib/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ members = [
[workspace.dependencies]
http = "1"
kittycad = { version = "0.3.28", default-features = false, features = ["js", "requests"] }
kittycad-modeling-cmds = { version = "0.2.92", features = [
kittycad-modeling-cmds = { version = "0.2.93", features = [
"ts-rs",
"websocket",
] }
Expand Down
2 changes: 1 addition & 1 deletion src/wasm-lib/kcl/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "kcl-lib"
description = "KittyCAD Language implementation and tools"
version = "0.2.30"
version = "0.2.32"
edition = "2021"
license = "MIT"
repository = "https://github.com/KittyCAD/modeling-app"
Expand Down
4 changes: 0 additions & 4 deletions src/wasm-lib/kcl/src/engine/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -197,10 +197,6 @@ pub trait EngineManager: std::fmt::Debug + Send + Sync + 'static {
source_range: SourceRange,
cmd: &ModelingCmd,
) -> Result<(), crate::errors::KclError> {
let execution_kind = self.execution_kind();
if execution_kind.is_isolated() {
return Err(KclError::Semantic(KclErrorDetails { message: "Cannot send modeling commands while importing. Wrap your code in a function if you want to import the file.".to_owned(), source_ranges: vec![source_range] }));
}
let req = WebSocketRequest::ModelingCmdReq(ModelingCmdReq {
cmd: cmd.clone(),
cmd_id: id.into(),
Expand Down
21 changes: 18 additions & 3 deletions src/wasm-lib/kcl/src/execution/artifact/mermaid_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -462,22 +462,31 @@ impl ArtifactGraph {
output.push_str("mindmap\n");
output.push_str(" root\n");

let mut ids_seen: fnv::FnvHashSet<ArtifactId> = Default::default();

for (_, artifact) in &self.map {
// Only the planes are roots.
let Artifact::Plane(_) = artifact else {
continue;
};
self.mind_map_artifact(&mut output, artifact, " ")?;
self.mind_map_artifact(&mut output, &mut ids_seen, artifact, " ")?;
}

output.push_str("```\n");

Ok(output)
}

fn mind_map_artifact<W: Write>(&self, output: &mut W, artifact: &Artifact, prefix: &str) -> std::fmt::Result {
fn mind_map_artifact<W: Write>(
&self,
output: &mut W,
ids_seen: &mut fnv::FnvHashSet<ArtifactId>,
artifact: &Artifact,
prefix: &str,
) -> std::fmt::Result {
match artifact {
Artifact::Plane(_plane) => {
ids_seen.clear();
writeln!(output, "{prefix}Plane")?;
}
Artifact::Path(_path) => {
Expand Down Expand Up @@ -515,11 +524,17 @@ impl ArtifactGraph {
}
}

if ids_seen.contains(&artifact.id()) {
return Ok(());
}

ids_seen.insert(artifact.id());

for child_id in artifact.child_ids() {
let Some(child_artifact) = self.map.get(&child_id) else {
continue;
};
self.mind_map_artifact(output, child_artifact, &format!("{} ", prefix))?;
self.mind_map_artifact(output, ids_seen, child_artifact, &format!("{} ", prefix))?;
}

Ok(())
Expand Down
Loading

0 comments on commit f5ec62a

Please sign in to comment.