Compare commits
2 Commits
nested_dir
...
achalmers/
Author | SHA1 | Date | |
---|---|---|---|
98dae3aa9a | |||
52dc8842f7 |
4
src/wasm-lib/Cargo.lock
generated
4
src/wasm-lib/Cargo.lock
generated
@ -1819,9 +1819,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "kittycad-modeling-cmds"
|
name = "kittycad-modeling-cmds"
|
||||||
version = "0.2.79"
|
version = "0.2.82"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "10a9cab4476455be70ea57643c31444068b056d091bd348cab6044c0d8ad7fcc"
|
checksum = "e209a26f2ef14afbb25de6a4641bc899e8468a62ae30c6c40d3a2840c7a6ce76"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"chrono",
|
"chrono",
|
||||||
|
@ -76,7 +76,7 @@ members = [
|
|||||||
[workspace.dependencies]
|
[workspace.dependencies]
|
||||||
http = "1"
|
http = "1"
|
||||||
kittycad = { version = "0.3.28", default-features = false, features = ["js", "requests"] }
|
kittycad = { version = "0.3.28", default-features = false, features = ["js", "requests"] }
|
||||||
kittycad-modeling-cmds = { version = "0.2.79", features = ["websocket"] }
|
kittycad-modeling-cmds = { version = "0.2.82", features = ["websocket"] }
|
||||||
|
|
||||||
[workspace.lints.clippy]
|
[workspace.lints.clippy]
|
||||||
assertions_on_result_states = "warn"
|
assertions_on_result_states = "warn"
|
||||||
|
@ -31,3 +31,5 @@ new-sim-test test_name render_to_png="true":
|
|||||||
{{cita}} -p kcl-lib -- simulation_tests::{{test_name}}::unparse
|
{{cita}} -p kcl-lib -- simulation_tests::{{test_name}}::unparse
|
||||||
TWENTY_TWENTY=overwrite {{cita}} -p kcl-lib -- tests::{{test_name}}::kcl_test_execute
|
TWENTY_TWENTY=overwrite {{cita}} -p kcl-lib -- tests::{{test_name}}::kcl_test_execute
|
||||||
|
|
||||||
|
bench-lego:
|
||||||
|
cargo criterion -p kcl-lib --bench executor_benchmark_criterion -- lego
|
||||||
|
@ -265,6 +265,7 @@ pub trait EngineManager: std::fmt::Debug + Send + Sync + 'static {
|
|||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
|
dbg!(&requests);
|
||||||
let batched_requests = WebSocketRequest::ModelingCmdBatchReq(ModelingBatch {
|
let batched_requests = WebSocketRequest::ModelingCmdBatchReq(ModelingBatch {
|
||||||
requests,
|
requests,
|
||||||
batch_id: uuid::Uuid::new_v4().into(),
|
batch_id: uuid::Uuid::new_v4().into(),
|
||||||
|
@ -8,7 +8,10 @@ use kcmc::{
|
|||||||
each_cmd as mcmd, length_unit::LengthUnit, ok_response::OkModelingCmdResponse, output::ExtrusionFaceInfo,
|
each_cmd as mcmd, length_unit::LengthUnit, ok_response::OkModelingCmdResponse, output::ExtrusionFaceInfo,
|
||||||
shared::ExtrusionFaceCapType, websocket::OkWebSocketResponseData, ModelingCmd,
|
shared::ExtrusionFaceCapType, websocket::OkWebSocketResponseData, ModelingCmd,
|
||||||
};
|
};
|
||||||
use kittycad_modeling_cmds as kcmc;
|
use kittycad_modeling_cmds::{
|
||||||
|
self as kcmc,
|
||||||
|
shared::{ExtrudedFaceInfo, SideFace},
|
||||||
|
};
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
@ -108,12 +111,27 @@ async fn inner_extrude(
|
|||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
// Choose IDs for the new faces that will be created when extruding.
|
||||||
|
let _sketch_is_on_face = matches!(sketch.on, SketchSurface::Face(_));
|
||||||
|
let new_faces = ExtrudedFaceInfo {
|
||||||
|
bottom: Some(exec_state.id_generator.next_uuid()),
|
||||||
|
top: exec_state.id_generator.next_uuid(),
|
||||||
|
sides: sketch
|
||||||
|
.paths
|
||||||
|
.iter()
|
||||||
|
.map(|path| SideFace {
|
||||||
|
path_id: path.get_id(),
|
||||||
|
face_id: exec_state.id_generator.next_uuid(),
|
||||||
|
})
|
||||||
|
.collect(),
|
||||||
|
};
|
||||||
|
|
||||||
args.batch_modeling_cmd(
|
args.batch_modeling_cmd(
|
||||||
id,
|
id,
|
||||||
ModelingCmd::from(mcmd::Extrude {
|
ModelingCmd::from(mcmd::Extrude {
|
||||||
target: sketch.id.into(),
|
target: sketch.id.into(),
|
||||||
distance: LengthUnit(length),
|
distance: LengthUnit(length),
|
||||||
faces: Default::default(),
|
faces: Some(new_faces.clone()),
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
@ -124,7 +142,7 @@ async fn inner_extrude(
|
|||||||
ModelingCmd::SketchModeDisable(mcmd::SketchModeDisable {}),
|
ModelingCmd::SketchModeDisable(mcmd::SketchModeDisable {}),
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
solids.push(do_post_extrude(sketch.clone(), length, exec_state, args.clone()).await?);
|
solids.push(do_post_extrude(sketch.clone(), length, Some(new_faces), exec_state, args.clone()).await?);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(solids.into())
|
Ok(solids.into())
|
||||||
@ -133,6 +151,7 @@ async fn inner_extrude(
|
|||||||
pub(crate) async fn do_post_extrude(
|
pub(crate) async fn do_post_extrude(
|
||||||
sketch: Sketch,
|
sketch: Sketch,
|
||||||
length: f64,
|
length: f64,
|
||||||
|
new_faces: Option<ExtrudedFaceInfo>,
|
||||||
exec_state: &mut ExecState,
|
exec_state: &mut ExecState,
|
||||||
args: Args,
|
args: Args,
|
||||||
) -> Result<Box<Solid>, KclError> {
|
) -> Result<Box<Solid>, KclError> {
|
||||||
@ -160,60 +179,65 @@ pub(crate) async fn do_post_extrude(
|
|||||||
sketch.id = face.solid.sketch.id;
|
sketch.id = face.solid.sketch.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
let solid3d_info = args
|
let face_infos = match new_faces {
|
||||||
.send_modeling_cmd(
|
Some(new_faces) => new_faces.list_faces(),
|
||||||
exec_state.id_generator.next_uuid(),
|
None => {
|
||||||
ModelingCmd::from(mcmd::Solid3dGetExtrusionFaceInfo {
|
let solid3d_info = args
|
||||||
edge_id: any_edge_id,
|
.send_modeling_cmd(
|
||||||
object_id: sketch.id,
|
exec_state.id_generator.next_uuid(),
|
||||||
}),
|
ModelingCmd::from(mcmd::Solid3dGetExtrusionFaceInfo {
|
||||||
)
|
edge_id: any_edge_id,
|
||||||
.await?;
|
object_id: sketch.id,
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
let face_infos = if let OkWebSocketResponseData::Modeling {
|
let face_infos: Vec<ExtrusionFaceInfo> = if let OkWebSocketResponseData::Modeling {
|
||||||
modeling_response: OkModelingCmdResponse::Solid3dGetExtrusionFaceInfo(data),
|
modeling_response: OkModelingCmdResponse::Solid3dGetExtrusionFaceInfo(data),
|
||||||
} = solid3d_info
|
} = solid3d_info
|
||||||
{
|
{
|
||||||
data.faces
|
data.faces
|
||||||
} else {
|
|
||||||
vec![]
|
|
||||||
};
|
|
||||||
|
|
||||||
for (curve_id, face_id) in face_infos
|
|
||||||
.iter()
|
|
||||||
.filter(|face_info| face_info.cap == ExtrusionFaceCapType::None)
|
|
||||||
.filter_map(|face_info| {
|
|
||||||
if let (Some(curve_id), Some(face_id)) = (face_info.curve_id, face_info.face_id) {
|
|
||||||
Some((curve_id, face_id))
|
|
||||||
} else {
|
} else {
|
||||||
None
|
vec![]
|
||||||
}
|
};
|
||||||
})
|
for (curve_id, face_id) in face_infos
|
||||||
{
|
.iter()
|
||||||
// Batch these commands, because the Rust code doesn't actually care about the outcome.
|
.filter(|face_info| face_info.cap == ExtrusionFaceCapType::None)
|
||||||
// So, there's no need to await them.
|
.filter_map(|face_info| {
|
||||||
// Instead, the Typescript codebases (which handles WebSocket sends when compiled via Wasm)
|
if let (Some(curve_id), Some(face_id)) = (face_info.curve_id, face_info.face_id) {
|
||||||
// uses this to build the artifact graph, which the UI needs.
|
Some((curve_id, face_id))
|
||||||
args.batch_modeling_cmd(
|
} else {
|
||||||
exec_state.id_generator.next_uuid(),
|
None
|
||||||
ModelingCmd::from(mcmd::Solid3dGetOppositeEdge {
|
}
|
||||||
edge_id: curve_id,
|
})
|
||||||
object_id: sketch.id,
|
{
|
||||||
face_id,
|
// Batch these commands, because the Rust code doesn't actually care about the outcome.
|
||||||
}),
|
// So, there's no need to await them.
|
||||||
)
|
// Instead, the Typescript codebases (which handles WebSocket sends when compiled via Wasm)
|
||||||
.await?;
|
// uses this to build the artifact graph, which the UI needs.
|
||||||
|
args.batch_modeling_cmd(
|
||||||
|
exec_state.id_generator.next_uuid(),
|
||||||
|
ModelingCmd::from(mcmd::Solid3dGetOppositeEdge {
|
||||||
|
edge_id: curve_id,
|
||||||
|
object_id: sketch.id,
|
||||||
|
face_id,
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
args.batch_modeling_cmd(
|
args.batch_modeling_cmd(
|
||||||
exec_state.id_generator.next_uuid(),
|
exec_state.id_generator.next_uuid(),
|
||||||
ModelingCmd::from(mcmd::Solid3dGetNextAdjacentEdge {
|
ModelingCmd::from(mcmd::Solid3dGetNextAdjacentEdge {
|
||||||
edge_id: curve_id,
|
edge_id: curve_id,
|
||||||
object_id: sketch.id,
|
object_id: sketch.id,
|
||||||
face_id,
|
face_id,
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
}
|
}
|
||||||
|
face_infos
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
let Faces {
|
let Faces {
|
||||||
sides: face_id_map,
|
sides: face_id_map,
|
||||||
|
@ -155,5 +155,5 @@ async fn inner_loft(
|
|||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
// Using the first sketch as the base curve, idk we might want to change this later.
|
// Using the first sketch as the base curve, idk we might want to change this later.
|
||||||
do_post_extrude(sketches[0].clone(), 0.0, exec_state, args).await
|
do_post_extrude(sketches[0].clone(), 0.0, None, exec_state, args).await
|
||||||
}
|
}
|
||||||
|
@ -295,7 +295,7 @@ async fn inner_revolve(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
do_post_extrude(sketch, 0.0, exec_state, args).await
|
do_post_extrude(sketch, 0.0, None, exec_state, args).await
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -98,5 +98,5 @@ async fn inner_sweep(
|
|||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
do_post_extrude(sketch, 0.0, exec_state, args).await
|
do_post_extrude(sketch, 0.0, None, exec_state, args).await
|
||||||
}
|
}
|
||||||
|
@ -1,36 +1,36 @@
|
|||||||
// 2x8 Lego Brick
|
// 2x8 Lego Brick
|
||||||
// A standard Lego brick with 2 bumps wide and 8 bumps long.
|
// A standard Lego brick with 2 bumps wide and 8 bumps long.
|
||||||
// Define constants
|
// Define constants
|
||||||
const lbumps = 10 // number of bumps long
|
lbumps = 10 // number of bumps long
|
||||||
const wbumps = {{N}} // number of bumps wide
|
wbumps = {{N}} // number of bumps wide
|
||||||
const pitch = 8.0
|
pitch = 8.0
|
||||||
const clearance = 0.1
|
clearance = 0.1
|
||||||
const bumpDiam = 4.8
|
bumpDiam = 4.8
|
||||||
const bumpHeight = 1.8
|
bumpHeight = 1.8
|
||||||
const height = 9.6
|
height = 9.6
|
||||||
const t = (pitch - (2 * clearance) - bumpDiam) / 2.0
|
t = (pitch - (2 * clearance) - bumpDiam) / 2.0
|
||||||
const totalLength = lbumps * pitch - (2.0 * clearance)
|
totalLength = lbumps * pitch - (2.0 * clearance)
|
||||||
const totalWidth = wbumps * pitch - (2.0 * clearance)
|
totalWidth = wbumps * pitch - (2.0 * clearance)
|
||||||
// Create the plane for the pegs. This is a hack so that the pegs can be patterned along the face of the lego base.
|
// Create the plane for the pegs. This is a hack so that the pegs can be patterned along the face of the lego base.
|
||||||
const pegFace = {
|
pegFace = {
|
||||||
plane: {
|
plane = {
|
||||||
origin: { x: 0, y: 0, z: height },
|
origin = { x = 0, y = 0, z = height },
|
||||||
xAxis: { x: 1, y: 0, z: 0 },
|
xAxis = { x = 1, y = 0, z = 0 },
|
||||||
yAxis: { x: 0, y: 1, z: 0 },
|
yAxis = { x = 0, y = 1, z = 0 },
|
||||||
zAxis: { x: 0, y: 0, z: 1 }
|
zAxis = { x = 0, y = 0, z = 1 }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Create the plane for the tubes underneath the lego. This is a hack so that the tubes can be patterned underneath the lego.
|
// Create the plane for the tubes underneath the lego. This is a hack so that the tubes can be patterned underneath the lego.
|
||||||
const tubeFace = {
|
tubeFace = {
|
||||||
plane: {
|
plane = {
|
||||||
origin: { x: 0, y: 0, z: height - t },
|
origin = { x = 0, y = 0, z = height - t },
|
||||||
xAxis: { x: 1, y: 0, z: 0 },
|
xAxis = { x = 1, y = 0, z = 0 },
|
||||||
yAxis: { x: 0, y: 1, z: 0 },
|
yAxis = { x = 0, y = 1, z = 0 },
|
||||||
zAxis: { x: 0, y: 0, z: 1 }
|
zAxis = { x = 0, y = 0, z = 1 }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Make the base
|
// Make the base
|
||||||
const s = startSketchOn('XY')
|
s = startSketchOn('XY')
|
||||||
|> startProfileAt([-totalWidth / 2, -totalLength / 2], %)
|
|> startProfileAt([-totalWidth / 2, -totalLength / 2], %)
|
||||||
|> line([totalWidth, 0], %)
|
|> line([totalWidth, 0], %)
|
||||||
|> line([0, totalLength], %)
|
|> line([0, totalLength], %)
|
||||||
@ -39,7 +39,7 @@ const s = startSketchOn('XY')
|
|||||||
|> extrude(height, %)
|
|> extrude(height, %)
|
||||||
|
|
||||||
// Sketch and extrude a rectangular shape to create the shell underneath the lego. This is a hack until we have a shell function.
|
// Sketch and extrude a rectangular shape to create the shell underneath the lego. This is a hack until we have a shell function.
|
||||||
const shellExtrude = startSketchOn(s, "start")
|
shellExtrude = startSketchOn(s, "start")
|
||||||
|> startProfileAt([
|
|> startProfileAt([
|
||||||
-(totalWidth / 2 - t),
|
-(totalWidth / 2 - t),
|
||||||
-(totalLength / 2 - t)
|
-(totalLength / 2 - t)
|
||||||
@ -50,32 +50,33 @@ const shellExtrude = startSketchOn(s, "start")
|
|||||||
|> close(%)
|
|> close(%)
|
||||||
|> extrude(-(height - t), %)
|
|> extrude(-(height - t), %)
|
||||||
|
|
||||||
fn tr = (i) => {
|
fn tr(i) {
|
||||||
let j = i + 1
|
j = i + 1
|
||||||
let x = (j/wbumps) * pitch
|
x = j / wbumps * pitch
|
||||||
let y = (j % wbumps) * pitch
|
y = j % wbumps * pitch
|
||||||
return {
|
return { translate = [x, y, 0] }
|
||||||
translate: [x, y, 0],
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the pegs on the top of the base
|
// Create the pegs on the top of the base
|
||||||
const totalBumps = (wbumps * lbumps)-1
|
totalBumps = wbumps * lbumps - 1
|
||||||
const peg = startSketchOn(s, 'end')
|
peg = startSketchOn(s, 'end')
|
||||||
|> circle({ center: [
|
|> circle({
|
||||||
-(pitch*(wbumps-1)/2),
|
center = [
|
||||||
-(pitch*(lbumps-1)/2)
|
-(pitch * (wbumps - 1) / 2),
|
||||||
], radius: bumpDiam / 2 }, %)
|
-(pitch * (lbumps - 1) / 2)
|
||||||
|> patternLinear2d({
|
],
|
||||||
axis: [1, 0],
|
radius = bumpDiam / 2
|
||||||
instances: wbumps,
|
|
||||||
distance: pitch
|
|
||||||
}, %)
|
}, %)
|
||||||
|> patternLinear2d({
|
|> patternLinear2d({
|
||||||
axis: [0, 1],
|
axis = [1, 0],
|
||||||
instances: lbumps,
|
instances = wbumps,
|
||||||
distance: pitch
|
distance = pitch
|
||||||
|
}, %)
|
||||||
|
|> patternLinear2d({
|
||||||
|
axis = [0, 1],
|
||||||
|
instances = lbumps,
|
||||||
|
distance = pitch
|
||||||
}, %)
|
}, %)
|
||||||
|> extrude(bumpHeight, %)
|
|> extrude(bumpHeight, %)
|
||||||
// |> patternTransform(int(totalBumps-1), tr, %)
|
// |> patternTransform(int(totalBumps-1), tr, %)
|
||||||
|
|
||||||
|
@ -62,6 +62,16 @@ async fn kcl_test_execute_i_shape() {
|
|||||||
assert_out("i_shape", &result);
|
assert_out("i_shape", &result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tokio::test(flavor = "multi_thread")]
|
||||||
|
async fn kcl_test_execute_slow_lego() {
|
||||||
|
// This is some code from lee that starts a pipe expression with a variable.
|
||||||
|
let code = include_str!("inputs/slow_lego.kcl.tmpl");
|
||||||
|
let code = code.replace("{{N}}", "1");
|
||||||
|
|
||||||
|
let result = execute_and_snapshot(&code, UnitLength::Mm, None).await.unwrap();
|
||||||
|
assert_out("i_shape", &result);
|
||||||
|
}
|
||||||
|
|
||||||
#[tokio::test(flavor = "multi_thread")]
|
#[tokio::test(flavor = "multi_thread")]
|
||||||
#[ignore] // No longer a stack overflow problem, instead it causes an engine internal error.
|
#[ignore] // No longer a stack overflow problem, instead it causes an engine internal error.
|
||||||
async fn kcl_test_execute_pipes_on_pipes() {
|
async fn kcl_test_execute_pipes_on_pipes() {
|
||||||
|
Reference in New Issue
Block a user