Batch extrudes (#3764)
Adds a new KCL executor benchmark which builds a `10` wide by `n` tall lego, with varying `n`. The benchmark runs a n = 1, 2, 3 etc build, so we can get an idea of how the speed changes with size. This change improves execution speed by 25-36% depending on how many bumps there are. Tested by: * Rust unit tests * Open up modeling app, sketch a square, use the command palette to extrude it * Open up the Bambu printer "poop chute" model, it all extrudes and works fine Also fixes a bug: extrude, loft, revolve all trigger a GetExtrusionFaceInfo command. Due to a bug, the GetExtrusionFaceInfo command reused the Command ID from the previous extrude/loft/revolve. Fixed that.
This commit is contained in:
@ -1,5 +1,5 @@
|
||||
use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion};
|
||||
use kcl_lib::test_server;
|
||||
use kcl_lib::{settings::types::UnitLength::Mm, test_server};
|
||||
use tokio::runtime::Runtime;
|
||||
|
||||
pub fn bench_execute(c: &mut Criterion) {
|
||||
@ -13,26 +13,42 @@ pub fn bench_execute(c: &mut Criterion) {
|
||||
// Configure Criterion.rs to detect smaller differences and increase sample size to improve
|
||||
// precision and counteract the resulting noise.
|
||||
group.sample_size(10);
|
||||
group.bench_with_input(BenchmarkId::new("execute_", name), &code, |b, &s| {
|
||||
group.bench_with_input(BenchmarkId::new("execute", name), &code, |b, &s| {
|
||||
let rt = Runtime::new().unwrap();
|
||||
|
||||
// Spawn a future onto the runtime
|
||||
b.iter(|| {
|
||||
rt.block_on(test_server::execute_and_snapshot(
|
||||
s,
|
||||
kcl_lib::settings::types::UnitLength::Mm,
|
||||
))
|
||||
.unwrap();
|
||||
rt.block_on(test_server::execute_and_snapshot(s, Mm)).unwrap();
|
||||
});
|
||||
});
|
||||
group.finish();
|
||||
}
|
||||
}
|
||||
|
||||
criterion_group!(benches, bench_execute);
|
||||
pub fn bench_lego(c: &mut Criterion) {
|
||||
let mut group = c.benchmark_group("executor_lego_pattern");
|
||||
// Configure Criterion.rs to detect smaller differences and increase sample size to improve
|
||||
// precision and counteract the resulting noise.
|
||||
group.sample_size(10);
|
||||
// Create lego bricks with N x 10 bumps, where N is each element of `sizes`.
|
||||
let sizes = vec![1, 2, 4];
|
||||
for size in sizes {
|
||||
group.bench_with_input(BenchmarkId::from_parameter(size), &size, |b, &size| {
|
||||
let rt = Runtime::new().unwrap();
|
||||
let code = LEGO_PROGRAM.replace("{{N}}", &size.to_string());
|
||||
// Spawn a future onto the runtime
|
||||
b.iter(|| {
|
||||
rt.block_on(test_server::execute_and_snapshot(&code, Mm)).unwrap();
|
||||
});
|
||||
});
|
||||
}
|
||||
group.finish();
|
||||
}
|
||||
|
||||
criterion_group!(benches, bench_lego, bench_execute);
|
||||
criterion_main!(benches);
|
||||
|
||||
const KITT_PROGRAM: &str = include_str!("../../tests/executor/inputs/kittycad_svg.kcl");
|
||||
const CUBE_PROGRAM: &str = include_str!("../../tests/executor/inputs/cube.kcl");
|
||||
const SERVER_RACK_HEAVY_PROGRAM: &str = include_str!("../../tests/executor/inputs/server-rack-heavy.kcl");
|
||||
const SERVER_RACK_LITE_PROGRAM: &str = include_str!("../../tests/executor/inputs/server-rack-lite.kcl");
|
||||
const LEGO_PROGRAM: &str = include_str!("../../tests/executor/inputs/slow_lego.kcl.tmpl");
|
||||
|
@ -99,7 +99,7 @@ async fn inner_extrude(length: f64, sketch_group_set: SketchGroupSet, args: Args
|
||||
)
|
||||
.await?;
|
||||
|
||||
args.send_modeling_cmd(
|
||||
args.batch_modeling_cmd(
|
||||
id,
|
||||
kittycad::types::ModelingCmd::Extrude {
|
||||
target: sketch_group.id,
|
||||
@ -112,7 +112,7 @@ async fn inner_extrude(length: f64, sketch_group_set: SketchGroupSet, args: Args
|
||||
// Disable the sketch mode.
|
||||
args.batch_modeling_cmd(uuid::Uuid::new_v4(), kittycad::types::ModelingCmd::SketchModeDisable {})
|
||||
.await?;
|
||||
extrude_groups.push(do_post_extrude(sketch_group.clone(), length, id, args.clone()).await?);
|
||||
extrude_groups.push(do_post_extrude(sketch_group.clone(), length, args.clone()).await?);
|
||||
}
|
||||
|
||||
Ok(extrude_groups.into())
|
||||
@ -121,7 +121,6 @@ async fn inner_extrude(length: f64, sketch_group_set: SketchGroupSet, args: Args
|
||||
pub(crate) async fn do_post_extrude(
|
||||
sketch_group: SketchGroup,
|
||||
length: f64,
|
||||
id: Uuid,
|
||||
args: Args,
|
||||
) -> Result<Box<ExtrudeGroup>, KclError> {
|
||||
// Bring the object to the front of the scene.
|
||||
@ -165,7 +164,7 @@ pub(crate) async fn do_post_extrude(
|
||||
|
||||
let solid3d_info = args
|
||||
.send_modeling_cmd(
|
||||
id,
|
||||
uuid::Uuid::new_v4(),
|
||||
kittycad::types::ModelingCmd::Solid3DGetExtrusionFaceInfo {
|
||||
edge_id,
|
||||
object_id: sketch_group.id,
|
||||
|
@ -170,5 +170,5 @@ async fn inner_loft(
|
||||
.await?;
|
||||
|
||||
// Using the first sketch as the base curve, idk we might want to change this later.
|
||||
do_post_extrude(sketch_groups[0].clone(), 0.0, id, args).await
|
||||
do_post_extrude(sketch_groups[0].clone(), 0.0, args).await
|
||||
}
|
||||
|
@ -299,7 +299,7 @@ async fn inner_revolve(
|
||||
}
|
||||
}
|
||||
|
||||
do_post_extrude(sketch_group, 0.0, id, args).await
|
||||
do_post_extrude(sketch_group, 0.0, args).await
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
81
src/wasm-lib/tests/executor/inputs/slow_lego.kcl.tmpl
Normal file
81
src/wasm-lib/tests/executor/inputs/slow_lego.kcl.tmpl
Normal file
@ -0,0 +1,81 @@
|
||||
// 2x8 Lego Brick
|
||||
// A standard Lego brick with 2 bumps wide and 8 bumps long.
|
||||
// Define constants
|
||||
const lbumps = 10 // number of bumps long
|
||||
const wbumps = {{N}} // number of bumps wide
|
||||
const pitch = 8.0
|
||||
const clearance = 0.1
|
||||
const bumpDiam = 4.8
|
||||
const bumpHeight = 1.8
|
||||
const height = 9.6
|
||||
const t = (pitch - (2 * clearance) - bumpDiam) / 2.0
|
||||
const totalLength = lbumps * pitch - (2.0 * clearance)
|
||||
const 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.
|
||||
const pegFace = {
|
||||
plane: {
|
||||
origin: { x: 0, y: 0, z: height },
|
||||
xAxis: { x: 1, y: 0, z: 0 },
|
||||
yAxis: { x: 0, y: 1, z: 0 },
|
||||
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.
|
||||
const tubeFace = {
|
||||
plane: {
|
||||
origin: { x: 0, y: 0, z: height - t },
|
||||
xAxis: { x: 1, y: 0, z: 0 },
|
||||
yAxis: { x: 0, y: 1, z: 0 },
|
||||
zAxis: { x: 0, y: 0, z: 1 }
|
||||
}
|
||||
}
|
||||
// Make the base
|
||||
const s = startSketchOn('XY')
|
||||
|> startProfileAt([-totalWidth / 2, -totalLength / 2], %)
|
||||
|> line([totalWidth, 0], %)
|
||||
|> line([0, totalLength], %)
|
||||
|> line([-totalWidth, 0], %)
|
||||
|> close(%)
|
||||
|> 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.
|
||||
const shellExtrude = startSketchOn(s, "start")
|
||||
|> startProfileAt([
|
||||
-(totalWidth / 2 - t),
|
||||
-(totalLength / 2 - t)
|
||||
], %)
|
||||
|> line([totalWidth - (2 * t), 0], %)
|
||||
|> line([0, totalLength - (2 * t)], %)
|
||||
|> line([-(totalWidth - (2 * t)), 0], %)
|
||||
|> close(%)
|
||||
|> extrude(-(height - t), %)
|
||||
|
||||
fn tr = (i) => {
|
||||
let j = i + 1
|
||||
let x = (j/wbumps) * pitch
|
||||
let y = (j % wbumps) * pitch
|
||||
return {
|
||||
translate: [x, y, 0],
|
||||
}
|
||||
}
|
||||
|
||||
// Create the pegs on the top of the base
|
||||
const totalBumps = (wbumps * lbumps)-1
|
||||
const peg = startSketchOn(s, 'end')
|
||||
|> circle([
|
||||
-(pitch*(wbumps-1)/2),
|
||||
-(pitch*(lbumps-1)/2)
|
||||
], bumpDiam / 2, %)
|
||||
|> patternLinear2d({
|
||||
axis: [1, 0],
|
||||
repetitions: wbumps-1,
|
||||
distance: pitch
|
||||
}, %)
|
||||
|> patternLinear2d({
|
||||
axis: [0, 1],
|
||||
repetitions: lbumps-1,
|
||||
distance: pitch
|
||||
}, %)
|
||||
|> extrude(bumpHeight, %)
|
||||
// |> patternTransform(int(totalBumps-1), tr, %)
|
||||
|
Reference in New Issue
Block a user