Compare commits

...

2 Commits

Author SHA1 Message Date
b3101d3fff Grackle: lineTo stdlib function 2024-03-02 00:26:04 -06:00
16575a8bf8 Bump execution plan 2024-03-01 11:40:56 -06:00
9 changed files with 137 additions and 23 deletions

1
.gitignore vendored
View File

@ -33,6 +33,7 @@ src/wasm-lib/bindings
src/wasm-lib/kcl/bindings src/wasm-lib/kcl/bindings
public/wasm_lib_bg.wasm public/wasm_lib_bg.wasm
src/wasm-lib/lcov.info src/wasm-lib/lcov.info
src/wasm-lib/grackle/*.test.json
e2e/playwright/playwright-secrets.env e2e/playwright/playwright-secrets.env
e2e/playwright/temp1.png e2e/playwright/temp1.png

View File

@ -1990,7 +1990,7 @@ dependencies = [
[[package]] [[package]]
name = "kittycad-execution-plan" name = "kittycad-execution-plan"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/KittyCAD/modeling-api?branch=main#29086e1079adb82b6427639a779dc58eabcd7f78" source = "git+https://github.com/KittyCAD/modeling-api?branch=main#9c96767289139f03036c2ba40f889f974ca3e976"
dependencies = [ dependencies = [
"bytes", "bytes",
"insta", "insta",
@ -2009,7 +2009,7 @@ dependencies = [
[[package]] [[package]]
name = "kittycad-execution-plan-macros" name = "kittycad-execution-plan-macros"
version = "0.1.6" version = "0.1.6"
source = "git+https://github.com/KittyCAD/modeling-api?branch=main#29086e1079adb82b6427639a779dc58eabcd7f78" source = "git+https://github.com/KittyCAD/modeling-api?branch=main#9c96767289139f03036c2ba40f889f974ca3e976"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -2019,7 +2019,7 @@ dependencies = [
[[package]] [[package]]
name = "kittycad-execution-plan-traits" name = "kittycad-execution-plan-traits"
version = "0.1.11" version = "0.1.11"
source = "git+https://github.com/KittyCAD/modeling-api?branch=main#29086e1079adb82b6427639a779dc58eabcd7f78" source = "git+https://github.com/KittyCAD/modeling-api?branch=main#9c96767289139f03036c2ba40f889f974ca3e976"
dependencies = [ dependencies = [
"serde", "serde",
"thiserror", "thiserror",
@ -2028,8 +2028,8 @@ dependencies = [
[[package]] [[package]]
name = "kittycad-modeling-cmds" name = "kittycad-modeling-cmds"
version = "0.1.26" version = "0.1.27"
source = "git+https://github.com/KittyCAD/modeling-api?branch=main#29086e1079adb82b6427639a779dc58eabcd7f78" source = "git+https://github.com/KittyCAD/modeling-api?branch=main#9c96767289139f03036c2ba40f889f974ca3e976"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"chrono", "chrono",
@ -2056,8 +2056,8 @@ dependencies = [
[[package]] [[package]]
name = "kittycad-modeling-cmds-macros" name = "kittycad-modeling-cmds-macros"
version = "0.1.1" version = "0.1.2"
source = "git+https://github.com/KittyCAD/modeling-api?branch=main#29086e1079adb82b6427639a779dc58eabcd7f78" source = "git+https://github.com/KittyCAD/modeling-api?branch=main#9c96767289139f03036c2ba40f889f974ca3e976"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -2067,7 +2067,7 @@ dependencies = [
[[package]] [[package]]
name = "kittycad-modeling-session" name = "kittycad-modeling-session"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/KittyCAD/modeling-api?branch=main#29086e1079adb82b6427639a779dc58eabcd7f78" source = "git+https://github.com/KittyCAD/modeling-api?branch=main#9c96767289139f03036c2ba40f889f974ca3e976"
dependencies = [ dependencies = [
"futures", "futures",
"kittycad", "kittycad",

View File

@ -105,6 +105,10 @@ impl BindingScope {
"startSketchAt".into(), "startSketchAt".into(),
EpBinding::from(KclFunction::StartSketchAt(native_functions::sketch::StartSketchAt)), EpBinding::from(KclFunction::StartSketchAt(native_functions::sketch::StartSketchAt)),
), ),
(
"lineTo".into(),
EpBinding::from(KclFunction::LineTo(native_functions::sketch::LineTo)),
),
]), ]),
parent: None, parent: None,
} }

View File

@ -252,6 +252,7 @@ impl Planner {
} = match callee { } = match callee {
KclFunction::Id(f) => f.call(&mut self.next_addr, args)?, KclFunction::Id(f) => f.call(&mut self.next_addr, args)?,
KclFunction::StartSketchAt(f) => f.call(&mut self.next_addr, args)?, KclFunction::StartSketchAt(f) => f.call(&mut self.next_addr, args)?,
KclFunction::LineTo(f) => f.call(&mut self.next_addr, args)?,
KclFunction::Add(f) => f.call(&mut self.next_addr, args)?, KclFunction::Add(f) => f.call(&mut self.next_addr, args)?,
KclFunction::UserDefined(f) => { KclFunction::UserDefined(f) => {
let UserDefinedFunction { let UserDefinedFunction {
@ -619,6 +620,7 @@ impl Eq for UserDefinedFunction {}
enum KclFunction { enum KclFunction {
Id(native_functions::Id), Id(native_functions::Id),
StartSketchAt(native_functions::sketch::StartSketchAt), StartSketchAt(native_functions::sketch::StartSketchAt),
LineTo(native_functions::sketch::LineTo),
Add(native_functions::Add), Add(native_functions::Add),
UserDefined(UserDefinedFunction), UserDefined(UserDefinedFunction),
} }

View File

@ -4,4 +4,4 @@ pub mod helpers;
pub mod stdlib_functions; pub mod stdlib_functions;
pub mod types; pub mod types;
pub use stdlib_functions::StartSketchAt; pub use stdlib_functions::{LineTo, StartSketchAt};

View File

@ -1,4 +1,4 @@
use kittycad_execution_plan::{api_request::ApiRequest, Instruction}; use kittycad_execution_plan::{api_request::ApiRequest, Destination, Instruction};
use kittycad_execution_plan_traits::{Address, InMemory}; use kittycad_execution_plan_traits::{Address, InMemory};
use kittycad_modeling_cmds::{id::ModelingCmdId, ModelingCmdEndpoint}; use kittycad_modeling_cmds::{id::ModelingCmdId, ModelingCmdEndpoint};
@ -120,11 +120,13 @@ pub fn arg_point2d(
instructions.extend([ instructions.extend([
Instruction::Copy { Instruction::Copy {
source: single_binding(elements[0].clone(), "startSketchAt", "number", arg_number)?, source: single_binding(elements[0].clone(), "startSketchAt", "number", arg_number)?,
destination: start_x, destination: Destination::Address(start_x),
length: 1,
}, },
Instruction::Copy { Instruction::Copy {
source: single_binding(elements[1].clone(), "startSketchAt", "number", arg_number)?, source: single_binding(elements[1].clone(), "startSketchAt", "number", arg_number)?,
destination: start_y, destination: Destination::Address(start_y),
length: 1,
}, },
Instruction::SetPrimitive { Instruction::SetPrimitive {
address: start_z, address: start_z,

View File

@ -1,4 +1,4 @@
use kittycad_execution_plan::{api_request::ApiRequest, Instruction}; use kittycad_execution_plan::{api_request::ApiRequest, Destination, Instruction};
use kittycad_execution_plan_traits::{Address, InMemory, Value}; use kittycad_execution_plan_traits::{Address, InMemory, Value};
use kittycad_modeling_cmds::{ use kittycad_modeling_cmds::{
shared::{Point3d, Point4d}, shared::{Point3d, Point4d},
@ -12,6 +12,82 @@ use super::{
}; };
use crate::{binding_scope::EpBinding, error::CompileError, native_functions::Callable, EvalPlan}; use crate::{binding_scope::EpBinding, error::CompileError, native_functions::Callable, EvalPlan};
#[derive(Debug, Clone)]
#[cfg_attr(test, derive(Eq, PartialEq))]
pub struct LineTo;
impl Callable for LineTo {
fn call(&self, next_addr: &mut Address, args: Vec<EpBinding>) -> Result<EvalPlan, CompileError> {
let mut instructions = Vec::new();
let fn_name = "lineTo";
// Get both required params.
let mut args_iter = args.into_iter();
let Some(to) = args_iter.next() else {
return Err(CompileError::NotEnoughArgs {
fn_name: fn_name.into(),
required: 2,
actual: 0,
});
};
let Some(sketch_group) = args_iter.next() else {
return Err(CompileError::NotEnoughArgs {
fn_name: fn_name.into(),
required: 2,
actual: 1,
});
};
// Check the type of both required params.
let to = arg_point2d(to, fn_name, &mut instructions, next_addr, 0)?;
let sg = single_binding(sketch_group, fn_name, "sketch group", 1)?;
let id = Uuid::new_v4();
let start_of_line = next_addr.offset(1);
let length_of_3d_point = Point3d::<f64>::default().into_parts().len();
instructions.extend([
// Push the `to` 2D point onto the stack.
Instruction::Copy {
source: to,
length: 2,
destination: Destination::StackPush,
},
// Make it a 3D point.
Instruction::StackExtend { data: vec![0.0.into()] },
// Append the new path segment to memory.
// First comes its tag.
Instruction::SetPrimitive {
address: start_of_line,
value: "Line".to_owned().into(),
},
// Then its end
Instruction::StackPop {
destination: Some(start_of_line + 1),
},
// Then its `relative` field.
Instruction::SetPrimitive {
address: start_of_line + 1 + length_of_3d_point,
value: false.into(),
},
// Send the ExtendPath request
Instruction::ApiRequest(ApiRequest {
endpoint: ModelingCmdEndpoint::ExtendPath,
store_response: None,
arguments: vec![
// Path ID
InMemory::Address(sg + SketchGroup::path_id_offset()),
// Segment
InMemory::Address(start_of_line),
],
cmd_id: id.into(),
}),
]);
// TODO: Create a new SketchGroup from the old one + add the new path, then store it.
Ok(EvalPlan {
instructions,
binding: EpBinding::Single(Address::ZERO + 9999),
})
}
}
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
#[cfg_attr(test, derive(Eq, PartialEq))] #[cfg_attr(test, derive(Eq, PartialEq))]
pub struct StartSketchAt; pub struct StartSketchAt;

View File

@ -1,4 +1,4 @@
use kittycad_execution_plan::Instruction; use kittycad_execution_plan::{Destination, Instruction};
use kittycad_execution_plan_macros::ExecutionPlanValue; use kittycad_execution_plan_macros::ExecutionPlanValue;
use kittycad_execution_plan_traits::{Address, Value}; use kittycad_execution_plan_traits::{Address, Value};
use kittycad_modeling_cmds::shared::{Point2d, Point3d, Point4d}; use kittycad_modeling_cmds::shared::{Point2d, Point3d, Point4d};
@ -7,6 +7,8 @@ use uuid::Uuid;
/// A sketch group is a collection of paths. /// A sketch group is a collection of paths.
#[derive(Clone, ExecutionPlanValue)] #[derive(Clone, ExecutionPlanValue)]
pub struct SketchGroup { pub struct SketchGroup {
// NOTE to developers
// Do NOT reorder these fields without updating the _offset() methods below.
/// The id of the sketch group. /// The id of the sketch group.
pub id: Uuid, pub id: Uuid,
/// What the sketch is on (can be a plane or a face). /// What the sketch is on (can be a plane or a face).
@ -26,6 +28,10 @@ pub struct SketchGroup {
} }
impl SketchGroup { impl SketchGroup {
/// Get the offset for the `id` field.
pub fn path_id_offset() -> usize {
0
}
pub fn set_base_path(&self, sketch_group: Address, start_point: Address, tag: Option<Address>) -> Vec<Instruction> { pub fn set_base_path(&self, sketch_group: Address, start_point: Address, tag: Option<Address>) -> Vec<Instruction> {
let base_path_addr = sketch_group let base_path_addr = sketch_group
+ self.id.into_parts().len() + self.id.into_parts().len()
@ -39,21 +45,24 @@ impl SketchGroup {
// Copy over the `from` field. // Copy over the `from` field.
Instruction::Copy { Instruction::Copy {
source: start_point, source: start_point,
destination: base_path_addr, destination: Destination::Address(base_path_addr),
length: 1,
}, },
// Copy over the `to` field. // Copy over the `to` field.
Instruction::Copy { Instruction::Copy {
source: start_point, source: start_point,
destination: base_path_addr + self.path_first.from.into_parts().len(), destination: Destination::Address(base_path_addr + self.path_first.from.into_parts().len()),
length: 1,
}, },
]; ];
if let Some(tag) = tag { if let Some(tag) = tag {
// Copy over the `name` field. // Copy over the `name` field.
out.push(Instruction::Copy { out.push(Instruction::Copy {
source: tag, source: tag,
destination: base_path_addr destination: Destination::Address(
+ self.path_first.from.into_parts().len() base_path_addr + self.path_first.from.into_parts().len() + self.path_first.to.into_parts().len(),
+ self.path_first.to.into_parts().len(), ),
length: 1,
}); });
} }
out out

View File

@ -1048,15 +1048,35 @@ fn store_object_with_array_property() {
#[tokio::test] #[tokio::test]
async fn stdlib_cube_partial() { async fn stdlib_cube_partial() {
let program = r#" let program = r#"
let cube = startSketchAt([22.0, 33.0]) let cube = startSketchAt([0.0, 0.0])
|> lineTo([4.0, 0.0], %)
"#; "#;
let (plan, _scope) = must_plan(program); let (plan, _scope) = must_plan(program);
std::fs::write("stdlib_cube_partial.json", serde_json::to_string_pretty(&plan).unwrap()).unwrap(); std::fs::write(
"stdlib_cube_partial.test.json",
serde_json::to_string_pretty(&plan).unwrap(),
)
.unwrap();
let ast = kcl_lib::parser::Parser::new(kcl_lib::token::lexer(program)) let ast = kcl_lib::parser::Parser::new(kcl_lib::token::lexer(program))
.ast() .ast()
.unwrap(); .unwrap();
let mem = crate::execute(ast, Some(test_client().await)).await.unwrap(); let client = test_client().await;
dbg!(mem); let _mem = crate::execute(ast, Some(client)).await.unwrap();
// use kittycad_modeling_cmds::{each_cmd, ok_response::OkModelingCmdResponse, ImageFormat, ModelingCmd};
// let out = client
// .run_command(
// uuid::Uuid::new_v4().into(),
// each_cmd::TakeSnapshot {
// format: ImageFormat::Png,
// },
// )
// .await
// .unwrap();
// let out = match out {
// OkModelingCmdResponse::TakeSnapshot(b) => b,
// other => panic!("wrong output: {other:?}"),
// };
// let out: Vec<u8> = out.contents.into();
} }
async fn test_client() -> Session { async fn test_client() -> Session {