Revolve/Sweep multiple sketches at once (#5779)

* revolve multiple sketches at once

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* do the same for swweep

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* do the same for swweep

Signed-off-by: Jess Frazelle <github@jessfraz.com>

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
This commit is contained in:
Jess Frazelle
2025-03-13 09:38:22 -07:00
committed by GitHub
parent c441a3ab1c
commit 80f78e1c61
28 changed files with 1153 additions and 899 deletions

View File

@ -9,7 +9,7 @@ use serde::{Deserialize, Serialize};
use crate::{
errors::KclError,
execution::{ExecState, Helix, KclValue, Sketch, Solid},
execution::{ExecState, Helix, KclValue, Sketch, SketchSet, SolidSet},
std::{extrude::do_post_extrude, fillet::default_tolerance, Args},
};
@ -30,7 +30,7 @@ pub async fn sweep(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K
let tolerance = args.get_kw_arg_opt("tolerance")?;
let value = inner_sweep(sketch, path, sectional, tolerance, exec_state, args).await?;
Ok(KclValue::Solid { value })
Ok(value.into())
}
/// Extrude a sketch along a path.
@ -41,6 +41,9 @@ pub async fn sweep(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K
/// creating more complex shapes that can't be created with a simple
/// extrusion.
///
/// You can provide more than one sketch to sweep, and they will all be
/// swept along the same path.
///
/// ```no_run
/// // Create a pipe using a sweep.
///
@ -94,40 +97,79 @@ pub async fn sweep(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K
/// |> circle( center = [0, 0], radius = 1)
/// |> sweep(path = helixPath)
/// ```
///
/// ```
/// // Sweep two sketches along the same path.
///
/// sketch001 = startSketchOn('XY')
/// rectangleSketch = startProfileAt([-200, 23.86], sketch001)
/// |> angledLine([0, 73.47], %, $rectangleSegmentA001)
/// |> angledLine([
/// segAng(rectangleSegmentA001) - 90,
/// 50.61
/// ], %)
/// |> angledLine([
/// segAng(rectangleSegmentA001),
/// -segLen(rectangleSegmentA001)
/// ], %)
/// |> line(endAbsolute = [profileStartX(%), profileStartY(%)])
/// |> close()
///
/// circleSketch = circle(sketch001, center = [200, -30.29], radius = 32.63)
///
/// sketch002 = startSketchOn('YZ')
/// sweepPath = startProfileAt([0, 0], sketch002)
/// |> yLine(length = 231.81)
/// |> tangentialArc({
/// radius = 80,
/// offset = -90,
/// }, %)
/// |> xLine(length = 384.93)
///
/// sweep([rectangleSketch, circleSketch], path = sweepPath)
/// ```
#[stdlib {
name = "sweep",
feature_tree_operation = true,
keywords = true,
unlabeled_first = true,
args = {
sketch = { docs = "The sketch that should be swept in space" },
sketch_set = { docs = "The sketch or set of sketches that should be swept in space" },
path = { docs = "The path to sweep the sketch along" },
sectional = { docs = "If true, the sweep will be broken up into sub-sweeps (extrusions, revolves, sweeps) based on the trajectory path components." },
tolerance = { docs = "Tolerance for this operation" },
}
}]
async fn inner_sweep(
sketch: Sketch,
sketch_set: SketchSet,
path: SweepPath,
sectional: Option<bool>,
tolerance: Option<f64>,
exec_state: &mut ExecState,
args: Args,
) -> Result<Box<Solid>, KclError> {
let id = exec_state.next_uuid();
args.batch_modeling_cmd(
id,
ModelingCmd::from(mcmd::Sweep {
target: sketch.id.into(),
trajectory: match path {
SweepPath::Sketch(sketch) => sketch.id.into(),
SweepPath::Helix(helix) => helix.value.into(),
},
sectional: sectional.unwrap_or(false),
tolerance: LengthUnit(tolerance.unwrap_or(default_tolerance(&args.ctx.settings.units))),
}),
)
.await?;
) -> Result<SolidSet, KclError> {
let trajectory = match path {
SweepPath::Sketch(sketch) => sketch.id.into(),
SweepPath::Helix(helix) => helix.value.into(),
};
do_post_extrude(sketch, id.into(), 0.0, exec_state, args).await
let sketches: Vec<Sketch> = sketch_set.into();
let mut solids = Vec::new();
for sketch in &sketches {
let id = exec_state.next_uuid();
args.batch_modeling_cmd(
id,
ModelingCmd::from(mcmd::Sweep {
target: sketch.id.into(),
trajectory,
sectional: sectional.unwrap_or(false),
tolerance: LengthUnit(tolerance.unwrap_or(default_tolerance(&args.ctx.settings.units))),
}),
)
.await?;
solids.push(do_post_extrude(sketch.clone(), id.into(), 0.0, exec_state, args.clone()).await?);
}
Ok(solids.into())
}