set scene units based on a module's default units (#5127)
Signed-off-by: Nick Cameron <nrc@ncameron.org>
This commit is contained in:
@ -11,6 +11,11 @@ pub(super) const SETTINGS: &str = "settings";
|
||||
pub(super) const SETTINGS_UNIT_LENGTH: &str = "defaultLengthUnit";
|
||||
pub(super) const SETTINGS_UNIT_ANGLE: &str = "defaultAngleUnit";
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||
pub(super) enum AnnotationScope {
|
||||
Module,
|
||||
}
|
||||
|
||||
pub(super) fn expect_properties<'a>(
|
||||
for_key: &'static str,
|
||||
annotation: &'a NonCodeValue,
|
||||
|
||||
@ -622,6 +622,19 @@ impl From<crate::UnitLength> for UnitLen {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<UnitLen> for crate::UnitLength {
|
||||
fn from(unit: UnitLen) -> Self {
|
||||
match unit {
|
||||
UnitLen::Cm => crate::UnitLength::Cm,
|
||||
UnitLen::Feet => crate::UnitLength::Ft,
|
||||
UnitLen::Inches => crate::UnitLength::In,
|
||||
UnitLen::M => crate::UnitLength::M,
|
||||
UnitLen::Mm => crate::UnitLength::Mm,
|
||||
UnitLen::Yards => crate::UnitLength::Yd,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Clone, Copy, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema, Eq)]
|
||||
#[ts(export)]
|
||||
#[serde(tag = "type")]
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
|
||||
use std::{path::PathBuf, sync::Arc};
|
||||
|
||||
use annotations::AnnotationScope;
|
||||
use anyhow::Result;
|
||||
use artifact::build_artifact_graph;
|
||||
use async_recursion::async_recursion;
|
||||
@ -2316,6 +2317,36 @@ impl ExecutorContext {
|
||||
}
|
||||
}
|
||||
|
||||
async fn handle_annotations(
|
||||
&self,
|
||||
annotations: impl Iterator<Item = (&NonCodeValue, SourceRange)>,
|
||||
scope: AnnotationScope,
|
||||
exec_state: &mut ExecState,
|
||||
) -> Result<(), KclError> {
|
||||
for (annotation, source_range) in annotations {
|
||||
if annotation.annotation_name() == Some(annotations::SETTINGS) {
|
||||
if scope == AnnotationScope::Module {
|
||||
let old_units = exec_state.length_unit();
|
||||
exec_state
|
||||
.mod_local
|
||||
.settings
|
||||
.update_from_annotation(annotation, source_range)?;
|
||||
let new_units = exec_state.length_unit();
|
||||
if old_units != new_units {
|
||||
self.engine.set_units(new_units.into(), source_range).await?;
|
||||
}
|
||||
} else {
|
||||
return Err(KclError::Semantic(KclErrorDetails {
|
||||
message: "Settings can only be modified at the top level scope of a file".to_owned(),
|
||||
source_ranges: vec![source_range],
|
||||
}));
|
||||
}
|
||||
}
|
||||
// TODO warn on unknown annotations
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Execute an AST's program.
|
||||
#[async_recursion]
|
||||
pub(crate) async fn inner_execute<'a>(
|
||||
@ -2324,21 +2355,16 @@ impl ExecutorContext {
|
||||
exec_state: &mut ExecState,
|
||||
body_type: BodyType,
|
||||
) -> Result<Option<KclValue>, KclError> {
|
||||
if let Some((annotation, source_range)) = program
|
||||
.non_code_meta
|
||||
.start_nodes
|
||||
.iter()
|
||||
.filter_map(|n| {
|
||||
n.annotation(annotations::SETTINGS)
|
||||
.map(|result| (result, n.as_source_range()))
|
||||
})
|
||||
.next()
|
||||
{
|
||||
exec_state
|
||||
.mod_local
|
||||
.settings
|
||||
.update_from_annotation(annotation, source_range)?;
|
||||
}
|
||||
self.handle_annotations(
|
||||
program
|
||||
.non_code_meta
|
||||
.start_nodes
|
||||
.iter()
|
||||
.filter_map(|n| n.annotation().map(|result| (result, n.as_source_range()))),
|
||||
AnnotationScope::Module,
|
||||
exec_state,
|
||||
)
|
||||
.await?;
|
||||
|
||||
let mut last_expr = None;
|
||||
// Iterate over the body of the program.
|
||||
@ -2521,6 +2547,7 @@ impl ExecutorContext {
|
||||
exec_kind: ExecutionKind,
|
||||
source_range: SourceRange,
|
||||
) -> Result<(Option<KclValue>, ProgramMemory, Vec<String>), KclError> {
|
||||
let old_units = exec_state.length_unit();
|
||||
// TODO It sucks that we have to clone the whole module AST here
|
||||
let info = exec_state.global.module_infos[&module_id].clone();
|
||||
|
||||
@ -2537,7 +2564,11 @@ impl ExecutorContext {
|
||||
.inner_execute(&info.parsed.unwrap(), exec_state, crate::execution::BodyType::Root)
|
||||
.await;
|
||||
|
||||
let new_units = exec_state.length_unit();
|
||||
std::mem::swap(&mut exec_state.mod_local, &mut local_state);
|
||||
if new_units != old_units {
|
||||
self.engine.set_units(old_units.into(), Default::default()).await?;
|
||||
}
|
||||
self.engine.replace_execution_kind(original_execution);
|
||||
|
||||
let result = result.map_err(|err| {
|
||||
|
||||
@ -1011,9 +1011,9 @@ impl NonCodeNode {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn annotation(&self, expected_name: &str) -> Option<&NonCodeValue> {
|
||||
pub fn annotation(&self) -> Option<&NonCodeValue> {
|
||||
match &self.value {
|
||||
a @ NonCodeValue::Annotation { name, .. } if name.name == expected_name => Some(a),
|
||||
a @ NonCodeValue::Annotation { .. } => Some(a),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
@ -1071,6 +1071,15 @@ pub enum NonCodeValue {
|
||||
},
|
||||
}
|
||||
|
||||
impl NonCodeValue {
|
||||
pub fn annotation_name(&self) -> Option<&str> {
|
||||
match self {
|
||||
NonCodeValue::Annotation { name, .. } => Some(&name.name),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Clone, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
|
||||
#[ts(export)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
|
||||
@ -119,7 +119,7 @@ async fn execute(test_name: &str, render_to_png: bool) {
|
||||
.global
|
||||
.artifact_graph
|
||||
.to_mermaid_flowchart()
|
||||
.unwrap_or_else(|e| format!("Failed to convert artifact graph to mind map: {e}"));
|
||||
.unwrap_or_else(|e| format!("Failed to convert artifact graph to flowchart: {e}"));
|
||||
// Change the snapshot suffix so that it is rendered as a
|
||||
// Markdown file in GitHub.
|
||||
insta::assert_binary_snapshot!("artifact_graph_flowchart.md", flowchart.as_bytes().to_owned());
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
---
|
||||
source: kcl/src/simulation_tests.rs
|
||||
description: Artifact commands import_whole.kcl
|
||||
snapshot_kind: text
|
||||
---
|
||||
[
|
||||
{
|
||||
@ -286,7 +285,19 @@ snapshot_kind: text
|
||||
"cmdId": "[uuid]",
|
||||
"range": [
|
||||
0,
|
||||
19,
|
||||
35,
|
||||
1
|
||||
],
|
||||
"command": {
|
||||
"type": "set_scene_units",
|
||||
"unit": "in"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cmdId": "[uuid]",
|
||||
"range": [
|
||||
36,
|
||||
55,
|
||||
1
|
||||
],
|
||||
"command": {
|
||||
@ -314,8 +325,8 @@ snapshot_kind: text
|
||||
{
|
||||
"cmdId": "[uuid]",
|
||||
"range": [
|
||||
25,
|
||||
68,
|
||||
61,
|
||||
104,
|
||||
1
|
||||
],
|
||||
"command": {
|
||||
@ -334,8 +345,8 @@ snapshot_kind: text
|
||||
{
|
||||
"cmdId": "[uuid]",
|
||||
"range": [
|
||||
25,
|
||||
68,
|
||||
61,
|
||||
104,
|
||||
1
|
||||
],
|
||||
"command": {
|
||||
@ -345,8 +356,8 @@ snapshot_kind: text
|
||||
{
|
||||
"cmdId": "[uuid]",
|
||||
"range": [
|
||||
25,
|
||||
68,
|
||||
61,
|
||||
104,
|
||||
1
|
||||
],
|
||||
"command": {
|
||||
@ -362,8 +373,8 @@ snapshot_kind: text
|
||||
{
|
||||
"cmdId": "[uuid]",
|
||||
"range": [
|
||||
25,
|
||||
68,
|
||||
61,
|
||||
104,
|
||||
1
|
||||
],
|
||||
"command": {
|
||||
@ -391,8 +402,8 @@ snapshot_kind: text
|
||||
{
|
||||
"cmdId": "[uuid]",
|
||||
"range": [
|
||||
25,
|
||||
68,
|
||||
61,
|
||||
104,
|
||||
1
|
||||
],
|
||||
"command": {
|
||||
@ -403,8 +414,8 @@ snapshot_kind: text
|
||||
{
|
||||
"cmdId": "[uuid]",
|
||||
"range": [
|
||||
74,
|
||||
88,
|
||||
110,
|
||||
124,
|
||||
1
|
||||
],
|
||||
"command": {
|
||||
@ -423,8 +434,8 @@ snapshot_kind: text
|
||||
{
|
||||
"cmdId": "[uuid]",
|
||||
"range": [
|
||||
74,
|
||||
88,
|
||||
110,
|
||||
124,
|
||||
1
|
||||
],
|
||||
"command": {
|
||||
@ -437,8 +448,8 @@ snapshot_kind: text
|
||||
{
|
||||
"cmdId": "[uuid]",
|
||||
"range": [
|
||||
74,
|
||||
88,
|
||||
110,
|
||||
124,
|
||||
1
|
||||
],
|
||||
"command": {
|
||||
@ -448,8 +459,8 @@ snapshot_kind: text
|
||||
{
|
||||
"cmdId": "[uuid]",
|
||||
"range": [
|
||||
74,
|
||||
88,
|
||||
110,
|
||||
124,
|
||||
1
|
||||
],
|
||||
"command": {
|
||||
@ -460,8 +471,8 @@ snapshot_kind: text
|
||||
{
|
||||
"cmdId": "[uuid]",
|
||||
"range": [
|
||||
74,
|
||||
88,
|
||||
110,
|
||||
124,
|
||||
1
|
||||
],
|
||||
"command": {
|
||||
@ -473,8 +484,8 @@ snapshot_kind: text
|
||||
{
|
||||
"cmdId": "[uuid]",
|
||||
"range": [
|
||||
74,
|
||||
88,
|
||||
110,
|
||||
124,
|
||||
1
|
||||
],
|
||||
"command": {
|
||||
@ -487,8 +498,8 @@ snapshot_kind: text
|
||||
{
|
||||
"cmdId": "[uuid]",
|
||||
"range": [
|
||||
74,
|
||||
88,
|
||||
110,
|
||||
124,
|
||||
1
|
||||
],
|
||||
"command": {
|
||||
@ -501,8 +512,20 @@ snapshot_kind: text
|
||||
{
|
||||
"cmdId": "[uuid]",
|
||||
"range": [
|
||||
49,
|
||||
96,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
],
|
||||
"command": {
|
||||
"type": "set_scene_units",
|
||||
"unit": "mm"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cmdId": "[uuid]",
|
||||
"range": [
|
||||
83,
|
||||
130,
|
||||
0
|
||||
],
|
||||
"command": {
|
||||
|
||||
@ -1,12 +1,12 @@
|
||||
```mermaid
|
||||
flowchart LR
|
||||
subgraph path2 [Path]
|
||||
2["Path<br>[25, 68, 1]"]
|
||||
3["Segment<br>[25, 68, 1]"]
|
||||
2["Path<br>[61, 104, 1]"]
|
||||
3["Segment<br>[61, 104, 1]"]
|
||||
4[Solid2d]
|
||||
end
|
||||
1["Plane<br>[0, 19, 1]"]
|
||||
5["Sweep Extrusion<br>[74, 88, 1]"]
|
||||
1["Plane<br>[36, 55, 1]"]
|
||||
5["Sweep Extrusion<br>[110, 124, 1]"]
|
||||
6[Wall]
|
||||
7["Cap Start"]
|
||||
8["Cap End"]
|
||||
|
||||
@ -6,85 +6,85 @@ description: Result of parsing import_whole.kcl
|
||||
"Ok": {
|
||||
"body": [
|
||||
{
|
||||
"end": 32,
|
||||
"end": 66,
|
||||
"path": "exported_mod.kcl",
|
||||
"selector": {
|
||||
"type": "None",
|
||||
"alias": {
|
||||
"end": 32,
|
||||
"end": 66,
|
||||
"name": "foo",
|
||||
"start": 29,
|
||||
"start": 63,
|
||||
"type": "Identifier"
|
||||
}
|
||||
},
|
||||
"start": 0,
|
||||
"start": 34,
|
||||
"type": "ImportStatement",
|
||||
"type": "ImportStatement"
|
||||
},
|
||||
{
|
||||
"declaration": {
|
||||
"end": 96,
|
||||
"end": 130,
|
||||
"id": {
|
||||
"end": 37,
|
||||
"end": 71,
|
||||
"name": "bar",
|
||||
"start": 34,
|
||||
"start": 68,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"init": {
|
||||
"body": [
|
||||
{
|
||||
"end": 43,
|
||||
"end": 77,
|
||||
"name": "foo",
|
||||
"start": 40,
|
||||
"start": 74,
|
||||
"type": "Identifier",
|
||||
"type": "Identifier"
|
||||
},
|
||||
{
|
||||
"arguments": [
|
||||
{
|
||||
"end": 92,
|
||||
"end": 126,
|
||||
"properties": [
|
||||
{
|
||||
"end": 72,
|
||||
"end": 106,
|
||||
"key": {
|
||||
"end": 62,
|
||||
"end": 96,
|
||||
"name": "faces",
|
||||
"start": 57,
|
||||
"start": 91,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"start": 57,
|
||||
"start": 91,
|
||||
"type": "ObjectProperty",
|
||||
"value": {
|
||||
"elements": [
|
||||
{
|
||||
"end": 71,
|
||||
"end": 105,
|
||||
"raw": "'end'",
|
||||
"start": 66,
|
||||
"start": 100,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": "end"
|
||||
}
|
||||
],
|
||||
"end": 72,
|
||||
"start": 65,
|
||||
"end": 106,
|
||||
"start": 99,
|
||||
"type": "ArrayExpression",
|
||||
"type": "ArrayExpression"
|
||||
}
|
||||
},
|
||||
{
|
||||
"end": 90,
|
||||
"end": 124,
|
||||
"key": {
|
||||
"end": 83,
|
||||
"end": 117,
|
||||
"name": "thickness",
|
||||
"start": 74,
|
||||
"start": 108,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"start": 74,
|
||||
"start": 108,
|
||||
"type": "ObjectProperty",
|
||||
"value": {
|
||||
"end": 90,
|
||||
"end": 124,
|
||||
"raw": "0.25",
|
||||
"start": 86,
|
||||
"start": 120,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
@ -94,51 +94,51 @@ description: Result of parsing import_whole.kcl
|
||||
}
|
||||
}
|
||||
],
|
||||
"start": 55,
|
||||
"start": 89,
|
||||
"type": "ObjectExpression",
|
||||
"type": "ObjectExpression"
|
||||
},
|
||||
{
|
||||
"end": 95,
|
||||
"start": 94,
|
||||
"end": 129,
|
||||
"start": 128,
|
||||
"type": "PipeSubstitution",
|
||||
"type": "PipeSubstitution"
|
||||
}
|
||||
],
|
||||
"callee": {
|
||||
"end": 54,
|
||||
"end": 88,
|
||||
"name": "shell",
|
||||
"start": 49,
|
||||
"start": 83,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"end": 96,
|
||||
"start": 49,
|
||||
"end": 130,
|
||||
"start": 83,
|
||||
"type": "CallExpression",
|
||||
"type": "CallExpression"
|
||||
}
|
||||
],
|
||||
"end": 96,
|
||||
"start": 40,
|
||||
"end": 130,
|
||||
"start": 74,
|
||||
"type": "PipeExpression",
|
||||
"type": "PipeExpression"
|
||||
},
|
||||
"start": 34,
|
||||
"start": 68,
|
||||
"type": "VariableDeclarator"
|
||||
},
|
||||
"end": 96,
|
||||
"end": 130,
|
||||
"kind": "const",
|
||||
"start": 34,
|
||||
"start": 68,
|
||||
"type": "VariableDeclaration",
|
||||
"type": "VariableDeclaration"
|
||||
}
|
||||
],
|
||||
"end": 97,
|
||||
"end": 131,
|
||||
"nonCodeMeta": {
|
||||
"nonCodeNodes": {
|
||||
"0": [
|
||||
{
|
||||
"end": 34,
|
||||
"start": 32,
|
||||
"end": 68,
|
||||
"start": 66,
|
||||
"type": "NonCodeNode",
|
||||
"value": {
|
||||
"type": "newLine"
|
||||
@ -146,7 +146,42 @@ description: Result of parsing import_whole.kcl
|
||||
}
|
||||
]
|
||||
},
|
||||
"startNodes": []
|
||||
"startNodes": [
|
||||
{
|
||||
"end": 33,
|
||||
"start": 0,
|
||||
"type": "NonCodeNode",
|
||||
"value": {
|
||||
"type": "annotation",
|
||||
"name": {
|
||||
"end": 9,
|
||||
"name": "settings",
|
||||
"start": 1,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"properties": [
|
||||
{
|
||||
"end": 32,
|
||||
"key": {
|
||||
"end": 27,
|
||||
"name": "defaultLengthUnit",
|
||||
"start": 10,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"start": 10,
|
||||
"type": "ObjectProperty",
|
||||
"value": {
|
||||
"end": 32,
|
||||
"name": "mm",
|
||||
"start": 30,
|
||||
"type": "Identifier",
|
||||
"type": "Identifier"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"start": 0
|
||||
}
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
@settings(defaultLengthUnit = inch)
|
||||
startSketchOn('XY')
|
||||
|> circle({ center = [5, 5], radius = 10 }, %)
|
||||
|> extrude(10, %)
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
@settings(defaultLengthUnit = mm)
|
||||
import "exported_mod.kcl" as foo
|
||||
|
||||
bar = foo
|
||||
|
||||
@ -1,30 +1,29 @@
|
||||
---
|
||||
source: kcl/src/simulation_tests.rs
|
||||
description: Operations executed import_whole.kcl
|
||||
snapshot_kind: text
|
||||
---
|
||||
[
|
||||
{
|
||||
"labeledArgs": {
|
||||
"data": {
|
||||
"sourceRange": [
|
||||
55,
|
||||
92,
|
||||
89,
|
||||
126,
|
||||
0
|
||||
]
|
||||
},
|
||||
"solid_set": {
|
||||
"sourceRange": [
|
||||
94,
|
||||
95,
|
||||
128,
|
||||
129,
|
||||
0
|
||||
]
|
||||
}
|
||||
},
|
||||
"name": "shell",
|
||||
"sourceRange": [
|
||||
49,
|
||||
96,
|
||||
83,
|
||||
130,
|
||||
0
|
||||
],
|
||||
"type": "StdLibCall",
|
||||
|
||||
@ -36,8 +36,8 @@ description: Program memory after executing import_whole.kcl
|
||||
"faceId": "[uuid]",
|
||||
"id": "[uuid]",
|
||||
"sourceRange": [
|
||||
25,
|
||||
68,
|
||||
61,
|
||||
104,
|
||||
1
|
||||
],
|
||||
"tag": null,
|
||||
@ -52,8 +52,8 @@ description: Program memory after executing import_whole.kcl
|
||||
"__geoMeta": {
|
||||
"id": "[uuid]",
|
||||
"sourceRange": [
|
||||
25,
|
||||
68,
|
||||
61,
|
||||
104,
|
||||
1
|
||||
]
|
||||
},
|
||||
@ -100,7 +100,7 @@ description: Program memory after executing import_whole.kcl
|
||||
"z": 1.0
|
||||
},
|
||||
"units": {
|
||||
"type": "Mm"
|
||||
"type": "Inches"
|
||||
},
|
||||
"__meta": []
|
||||
},
|
||||
@ -117,20 +117,20 @@ description: Program memory after executing import_whole.kcl
|
||||
"__geoMeta": {
|
||||
"id": "[uuid]",
|
||||
"sourceRange": [
|
||||
25,
|
||||
68,
|
||||
61,
|
||||
104,
|
||||
1
|
||||
]
|
||||
}
|
||||
},
|
||||
"units": {
|
||||
"type": "Mm"
|
||||
"type": "Inches"
|
||||
},
|
||||
"__meta": [
|
||||
{
|
||||
"sourceRange": [
|
||||
25,
|
||||
68,
|
||||
61,
|
||||
104,
|
||||
1
|
||||
]
|
||||
}
|
||||
@ -140,13 +140,13 @@ description: Program memory after executing import_whole.kcl
|
||||
"startCapId": "[uuid]",
|
||||
"endCapId": "[uuid]",
|
||||
"units": {
|
||||
"type": "Mm"
|
||||
"type": "Inches"
|
||||
},
|
||||
"__meta": [
|
||||
{
|
||||
"sourceRange": [
|
||||
25,
|
||||
68,
|
||||
61,
|
||||
104,
|
||||
1
|
||||
]
|
||||
}
|
||||
@ -159,8 +159,8 @@ description: Program memory after executing import_whole.kcl
|
||||
"__meta": [
|
||||
{
|
||||
"sourceRange": [
|
||||
0,
|
||||
32,
|
||||
34,
|
||||
66,
|
||||
0
|
||||
]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user