KCL: change twist to a case of extrude (#7481)
@franknoirot @jtran and I decided that the `extrudeTwist()` function (which I added in https://github.com/KittyCAD/modeling-app/pull/7480) would be better as an optional case of the normal `extrude` function. Doing it this way means less work for the frontend team.
This commit is contained in:
File diff suppressed because one or more lines are too long
@ -55,7 +55,6 @@ layout: manual
|
|||||||
* [`circleThreePoint`](/docs/kcl-std/functions/std-sketch-circleThreePoint)
|
* [`circleThreePoint`](/docs/kcl-std/functions/std-sketch-circleThreePoint)
|
||||||
* [`close`](/docs/kcl-std/functions/std-sketch-close)
|
* [`close`](/docs/kcl-std/functions/std-sketch-close)
|
||||||
* [`extrude`](/docs/kcl-std/functions/std-sketch-extrude)
|
* [`extrude`](/docs/kcl-std/functions/std-sketch-extrude)
|
||||||
* [`extrudeTwist`](/docs/kcl-std/functions/std-sketch-extrudeTwist)
|
|
||||||
* [`getCommonEdge`](/docs/kcl-std/functions/std-sketch-getCommonEdge)
|
* [`getCommonEdge`](/docs/kcl-std/functions/std-sketch-getCommonEdge)
|
||||||
* [`getNextAdjacentEdge`](/docs/kcl-std/functions/std-sketch-getNextAdjacentEdge)
|
* [`getNextAdjacentEdge`](/docs/kcl-std/functions/std-sketch-getNextAdjacentEdge)
|
||||||
* [`getOppositeEdge`](/docs/kcl-std/functions/std-sketch-getOppositeEdge)
|
* [`getOppositeEdge`](/docs/kcl-std/functions/std-sketch-getOppositeEdge)
|
||||||
|
@ -20,7 +20,6 @@ This module contains functions for creating and manipulating sketches, and makin
|
|||||||
* [`circleThreePoint`](/docs/kcl-std/functions/std-sketch-circleThreePoint)
|
* [`circleThreePoint`](/docs/kcl-std/functions/std-sketch-circleThreePoint)
|
||||||
* [`close`](/docs/kcl-std/functions/std-sketch-close)
|
* [`close`](/docs/kcl-std/functions/std-sketch-close)
|
||||||
* [`extrude`](/docs/kcl-std/functions/std-sketch-extrude)
|
* [`extrude`](/docs/kcl-std/functions/std-sketch-extrude)
|
||||||
* [`extrudeTwist`](/docs/kcl-std/functions/std-sketch-extrudeTwist)
|
|
||||||
* [`getCommonEdge`](/docs/kcl-std/functions/std-sketch-getCommonEdge)
|
* [`getCommonEdge`](/docs/kcl-std/functions/std-sketch-getCommonEdge)
|
||||||
* [`getNextAdjacentEdge`](/docs/kcl-std/functions/std-sketch-getNextAdjacentEdge)
|
* [`getNextAdjacentEdge`](/docs/kcl-std/functions/std-sketch-getNextAdjacentEdge)
|
||||||
* [`getOppositeEdge`](/docs/kcl-std/functions/std-sketch-getOppositeEdge)
|
* [`getOppositeEdge`](/docs/kcl-std/functions/std-sketch-getOppositeEdge)
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 52 KiB |
@ -117,11 +117,11 @@ pub const TEST_NAMES: &[&str] = &[
|
|||||||
"std-sketch-getOppositeEdge-0",
|
"std-sketch-getOppositeEdge-0",
|
||||||
"std-sketch-getPreviousAdjacentEdge-0",
|
"std-sketch-getPreviousAdjacentEdge-0",
|
||||||
"std-sketch-getNextAdjacentEdge-0",
|
"std-sketch-getNextAdjacentEdge-0",
|
||||||
"std-sketch-extrudeTwist-0",
|
|
||||||
"std-sketch-extrude-0",
|
"std-sketch-extrude-0",
|
||||||
"std-sketch-extrude-1",
|
"std-sketch-extrude-1",
|
||||||
"std-sketch-extrude-2",
|
"std-sketch-extrude-2",
|
||||||
"std-sketch-extrude-3",
|
"std-sketch-extrude-3",
|
||||||
|
"std-sketch-extrude-4",
|
||||||
"std-sketch-polygon-0",
|
"std-sketch-polygon-0",
|
||||||
"std-sketch-polygon-1",
|
"std-sketch-polygon-1",
|
||||||
"std-sketch-sweep-0",
|
"std-sketch-sweep-0",
|
||||||
|
@ -283,6 +283,9 @@ mod tests {
|
|||||||
bidirectionalLength?: number(Length),
|
bidirectionalLength?: number(Length),
|
||||||
tagStart?: TagDecl,
|
tagStart?: TagDecl,
|
||||||
tagEnd?: TagDecl,
|
tagEnd?: TagDecl,
|
||||||
|
twistAngle?: number(Angle),
|
||||||
|
twistAngleStep?: number(Angle),
|
||||||
|
twistCenter?: Point2d,
|
||||||
): [Solid; 1+]"#
|
): [Solid; 1+]"#
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -38,6 +38,10 @@ pub async fn extrude(exec_state: &mut ExecState, args: Args) -> Result<KclValue,
|
|||||||
args.get_kw_arg_opt("bidirectionalLength", &RuntimeType::length(), exec_state)?;
|
args.get_kw_arg_opt("bidirectionalLength", &RuntimeType::length(), exec_state)?;
|
||||||
let tag_start = args.get_kw_arg_opt("tagStart", &RuntimeType::tag_decl(), exec_state)?;
|
let tag_start = args.get_kw_arg_opt("tagStart", &RuntimeType::tag_decl(), exec_state)?;
|
||||||
let tag_end = args.get_kw_arg_opt("tagEnd", &RuntimeType::tag_decl(), exec_state)?;
|
let tag_end = args.get_kw_arg_opt("tagEnd", &RuntimeType::tag_decl(), exec_state)?;
|
||||||
|
let twist_angle: Option<TyF64> = args.get_kw_arg_opt("twistAngle", &RuntimeType::degrees(), exec_state)?;
|
||||||
|
let twist_angle_step: Option<TyF64> = args.get_kw_arg_opt("twistAngleStep", &RuntimeType::degrees(), exec_state)?;
|
||||||
|
let twist_center: Option<[TyF64; 2]> = args.get_kw_arg_opt("twistCenter", &RuntimeType::point2d(), exec_state)?;
|
||||||
|
let tolerance: Option<TyF64> = args.get_kw_arg_opt("tolerance", &RuntimeType::length(), exec_state)?;
|
||||||
|
|
||||||
let result = inner_extrude(
|
let result = inner_extrude(
|
||||||
sketches,
|
sketches,
|
||||||
@ -46,6 +50,10 @@ pub async fn extrude(exec_state: &mut ExecState, args: Args) -> Result<KclValue,
|
|||||||
bidirectional_length,
|
bidirectional_length,
|
||||||
tag_start,
|
tag_start,
|
||||||
tag_end,
|
tag_end,
|
||||||
|
twist_angle,
|
||||||
|
twist_angle_step,
|
||||||
|
twist_center,
|
||||||
|
tolerance,
|
||||||
exec_state,
|
exec_state,
|
||||||
args,
|
args,
|
||||||
)
|
)
|
||||||
@ -62,11 +70,16 @@ async fn inner_extrude(
|
|||||||
bidirectional_length: Option<TyF64>,
|
bidirectional_length: Option<TyF64>,
|
||||||
tag_start: Option<TagNode>,
|
tag_start: Option<TagNode>,
|
||||||
tag_end: Option<TagNode>,
|
tag_end: Option<TagNode>,
|
||||||
|
twist_angle: Option<TyF64>,
|
||||||
|
twist_angle_step: Option<TyF64>,
|
||||||
|
twist_center: Option<[TyF64; 2]>,
|
||||||
|
tolerance: Option<TyF64>,
|
||||||
exec_state: &mut ExecState,
|
exec_state: &mut ExecState,
|
||||||
args: Args,
|
args: Args,
|
||||||
) -> Result<Vec<Solid>, KclError> {
|
) -> Result<Vec<Solid>, KclError> {
|
||||||
// Extrude the element(s).
|
// Extrude the element(s).
|
||||||
let mut solids = Vec::new();
|
let mut solids = Vec::new();
|
||||||
|
let tolerance = LengthUnit(tolerance.as_ref().map(|t| t.to_mm()).unwrap_or(DEFAULT_TOLERANCE));
|
||||||
|
|
||||||
if symmetric.unwrap_or(false) && bidirectional_length.is_some() {
|
if symmetric.unwrap_or(false) && bidirectional_length.is_some() {
|
||||||
return Err(KclError::new_semantic(KclErrorDetails::new(
|
return Err(KclError::new_semantic(KclErrorDetails::new(
|
||||||
@ -88,97 +101,29 @@ async fn inner_extrude(
|
|||||||
|
|
||||||
for sketch in &sketches {
|
for sketch in &sketches {
|
||||||
let id = exec_state.next_uuid();
|
let id = exec_state.next_uuid();
|
||||||
let cmds = sketch.build_sketch_mode_cmds(
|
let cmd = match (&twist_angle, &twist_angle_step, &twist_center) {
|
||||||
exec_state,
|
(Some(angle), angle_step, center) => {
|
||||||
ModelingCmdReq {
|
let center = center.clone().map(point_to_mm).map(Point2d::from).unwrap_or_default();
|
||||||
cmd_id: id.into(),
|
let total_rotation_angle = Angle::from_degrees(angle.to_degrees());
|
||||||
cmd: ModelingCmd::from(mcmd::Extrude {
|
let angle_step_size = Angle::from_degrees(angle_step.clone().map(|a| a.to_degrees()).unwrap_or(15.0));
|
||||||
target: sketch.id.into(),
|
ModelingCmd::from(mcmd::TwistExtrude {
|
||||||
distance: LengthUnit(length.to_mm()),
|
|
||||||
faces: Default::default(),
|
|
||||||
opposite: opposite.clone(),
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
);
|
|
||||||
exec_state
|
|
||||||
.batch_modeling_cmds(ModelingCmdMeta::from_args_id(&args, id), &cmds)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
solids.push(
|
|
||||||
do_post_extrude(
|
|
||||||
sketch,
|
|
||||||
id.into(),
|
|
||||||
length.clone(),
|
|
||||||
false,
|
|
||||||
&NamedCapTags {
|
|
||||||
start: tag_start.as_ref(),
|
|
||||||
end: tag_end.as_ref(),
|
|
||||||
},
|
|
||||||
exec_state,
|
|
||||||
&args,
|
|
||||||
None,
|
|
||||||
)
|
|
||||||
.await?,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(solids)
|
|
||||||
}
|
|
||||||
/// Extrudes by a given amount, twisting the sketch as it goes.
|
|
||||||
pub async fn extrude_twist(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
|
||||||
let sketches = args.get_unlabeled_kw_arg("sketches", &RuntimeType::sketches(), exec_state)?;
|
|
||||||
let length: TyF64 = args.get_kw_arg("length", &RuntimeType::length(), exec_state)?;
|
|
||||||
let tolerance: Option<TyF64> = args.get_kw_arg_opt("tolerance", &RuntimeType::length(), exec_state)?;
|
|
||||||
let angle: TyF64 = args.get_kw_arg("angle", &RuntimeType::degrees(), exec_state)?;
|
|
||||||
let angle_step: Option<TyF64> = args.get_kw_arg_opt("angleStep", &RuntimeType::degrees(), exec_state)?;
|
|
||||||
let center: Option<[TyF64; 2]> = args.get_kw_arg_opt("center", &RuntimeType::point2d(), exec_state)?;
|
|
||||||
let tag_start = args.get_kw_arg_opt("tagStart", &RuntimeType::tag_decl(), exec_state)?;
|
|
||||||
let tag_end = args.get_kw_arg_opt("tagEnd", &RuntimeType::tag_decl(), exec_state)?;
|
|
||||||
|
|
||||||
let result = inner_extrude_twist(
|
|
||||||
sketches, length, tag_start, tag_end, center, angle, angle_step, tolerance, exec_state, args,
|
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
Ok(result.into())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(clippy::too_many_arguments)]
|
|
||||||
async fn inner_extrude_twist(
|
|
||||||
sketches: Vec<Sketch>,
|
|
||||||
length: TyF64,
|
|
||||||
tag_start: Option<TagNode>,
|
|
||||||
tag_end: Option<TagNode>,
|
|
||||||
center: Option<[TyF64; 2]>,
|
|
||||||
angle: TyF64,
|
|
||||||
angle_step: Option<TyF64>,
|
|
||||||
tolerance: Option<TyF64>,
|
|
||||||
exec_state: &mut ExecState,
|
|
||||||
args: Args,
|
|
||||||
) -> Result<Vec<Solid>, KclError> {
|
|
||||||
// Extrude the element(s).
|
|
||||||
let mut solids = Vec::new();
|
|
||||||
let tolerance = LengthUnit(tolerance.as_ref().map(|t| t.to_mm()).unwrap_or(DEFAULT_TOLERANCE));
|
|
||||||
let center = center.map(point_to_mm).map(Point2d::from).unwrap_or_default();
|
|
||||||
let angle_step_size = Angle::from_degrees(angle_step.map(|a| a.to_degrees()).unwrap_or(15.0));
|
|
||||||
|
|
||||||
for sketch in &sketches {
|
|
||||||
let id = exec_state.next_uuid();
|
|
||||||
let cmds = sketch.build_sketch_mode_cmds(
|
|
||||||
exec_state,
|
|
||||||
ModelingCmdReq {
|
|
||||||
cmd_id: id.into(),
|
|
||||||
cmd: ModelingCmd::from(mcmd::TwistExtrude {
|
|
||||||
target: sketch.id.into(),
|
target: sketch.id.into(),
|
||||||
distance: LengthUnit(length.to_mm()),
|
distance: LengthUnit(length.to_mm()),
|
||||||
faces: Default::default(),
|
faces: Default::default(),
|
||||||
center_2d: center,
|
center_2d: center,
|
||||||
total_rotation_angle: Angle::from_degrees(angle.to_degrees()),
|
total_rotation_angle,
|
||||||
angle_step_size,
|
angle_step_size,
|
||||||
tolerance,
|
tolerance,
|
||||||
}),
|
})
|
||||||
},
|
}
|
||||||
);
|
(None, _, _) => ModelingCmd::from(mcmd::Extrude {
|
||||||
|
target: sketch.id.into(),
|
||||||
|
distance: LengthUnit(length.to_mm()),
|
||||||
|
faces: Default::default(),
|
||||||
|
opposite: opposite.clone(),
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
let cmds = sketch.build_sketch_mode_cmds(exec_state, ModelingCmdReq { cmd_id: id.into(), cmd });
|
||||||
exec_state
|
exec_state
|
||||||
.batch_modeling_cmds(ModelingCmdMeta::from_args_id(&args, id), &cmds)
|
.batch_modeling_cmds(ModelingCmdMeta::from_args_id(&args, id), &cmds)
|
||||||
.await?;
|
.await?;
|
||||||
|
@ -260,10 +260,6 @@ pub(crate) fn std_fn(path: &str, fn_name: &str) -> (crate::std::StdFn, StdFnProp
|
|||||||
|e, a| Box::pin(crate::std::extrude::extrude(e, a)),
|
|e, a| Box::pin(crate::std::extrude::extrude(e, a)),
|
||||||
StdFnProps::default("std::sketch::extrude").include_in_feature_tree(),
|
StdFnProps::default("std::sketch::extrude").include_in_feature_tree(),
|
||||||
),
|
),
|
||||||
("sketch", "extrudeTwist") => (
|
|
||||||
|e, a| Box::pin(crate::std::extrude::extrude_twist(e, a)),
|
|
||||||
StdFnProps::default("std::sketch::extrudeTwist").include_in_feature_tree(),
|
|
||||||
),
|
|
||||||
("sketch", "patternTransform2d") => (
|
("sketch", "patternTransform2d") => (
|
||||||
|e, a| Box::pin(crate::std::patterns::pattern_transform_2d(e, a)),
|
|e, a| Box::pin(crate::std::patterns::pattern_transform_2d(e, a)),
|
||||||
StdFnProps::default("std::sketch::patternTransform2d"),
|
StdFnProps::default("std::sketch::patternTransform2d"),
|
||||||
|
@ -364,6 +364,11 @@ export fn circle(
|
|||||||
///
|
///
|
||||||
/// example = extrude(exampleSketch, length = 10, bidirectionalLength = 50)
|
/// example = extrude(exampleSketch, length = 10, bidirectionalLength = 50)
|
||||||
/// ```
|
/// ```
|
||||||
|
/// ```kcl
|
||||||
|
/// example = startSketchOn(XZ)
|
||||||
|
/// |> polygon(radius = 10, numSides = 3, center = [0, 0])
|
||||||
|
/// |> extrude(length = 10, twistAngle = 120deg)
|
||||||
|
/// ```
|
||||||
@(impl = std_rust)
|
@(impl = std_rust)
|
||||||
export fn extrude(
|
export fn extrude(
|
||||||
/// Which sketch or sketches should be extruded.
|
/// Which sketch or sketches should be extruded.
|
||||||
@ -378,39 +383,16 @@ export fn extrude(
|
|||||||
tagStart?: TagDecl,
|
tagStart?: TagDecl,
|
||||||
/// A named tag for the face at the end of the extrusion, i.e. the new face created by extruding the original sketch.
|
/// A named tag for the face at the end of the extrusion, i.e. the new face created by extruding the original sketch.
|
||||||
tagEnd?: TagDecl,
|
tagEnd?: TagDecl,
|
||||||
): [Solid; 1+] {}
|
/// If given, the sketch will be twisted around this angle while being extruded.
|
||||||
|
twistAngle?: number(Angle),
|
||||||
/// Works just like the `extrude` command, but also twists the sketch around
|
|
||||||
/// some center point while it's extruding.
|
|
||||||
///
|
|
||||||
/// You can provide more than one sketch to extrude, and they will all be
|
|
||||||
/// extruded in the same direction with the same twist.
|
|
||||||
///
|
|
||||||
/// ```kcl
|
|
||||||
/// example = startSketchOn(XZ)
|
|
||||||
/// |> polygon(radius = 10, numSides = 3, center = [0, 0])
|
|
||||||
/// |> extrudeTwist(length = 10, angle = 120deg)
|
|
||||||
/// ```
|
|
||||||
@(impl = std_rust)
|
|
||||||
export fn extrudeTwist(
|
|
||||||
/// Which sketch or sketches should be extruded.
|
|
||||||
@sketches: [Sketch; 1+],
|
|
||||||
/// The total angle that the sketch will be twisted around
|
|
||||||
angle: number(Angle),
|
|
||||||
/// How far to extrude the given sketches.
|
|
||||||
length: number(Length),
|
|
||||||
/// The size of each intermediate angle as the sketch twists around.
|
/// The size of each intermediate angle as the sketch twists around.
|
||||||
/// Must be between 4 and 90 degrees.
|
/// Must be between 4 and 90 degrees.
|
||||||
/// Defaults to 15 degrees.
|
/// Only used if `twistAngle` is given, defaults to 15 degrees.
|
||||||
angleStep?: number(Angle),
|
twistAngleStep?: number(Angle),
|
||||||
/// A named tag for the face at the start of the extrusion, i.e. the original sketch.
|
|
||||||
tagStart?: tag,
|
|
||||||
/// A named tag for the face at the end of the extrusion, i.e. the new face created by extruding the original sketch.
|
|
||||||
tagEnd?: tag,
|
|
||||||
/// The center around which the sketch will be twisted. Relative to the sketch's center.
|
/// The center around which the sketch will be twisted. Relative to the sketch's center.
|
||||||
/// If not given, defaults to 0,0 i.e. the sketch's center.
|
/// Only used if `twistAngle` is given, defaults to [0, 0] i.e. sketch's center.
|
||||||
@(snippetArray = ["0", "0"])
|
@(snippetArray = ["0", "0"])
|
||||||
center?: Point2d,
|
twistCenter?: Point2d,
|
||||||
): [Solid; 1+] {}
|
): [Solid; 1+] {}
|
||||||
|
|
||||||
/// Rotate a sketch around some provided axis, creating a solid from its extent.
|
/// Rotate a sketch around some provided axis, creating a solid from its extent.
|
||||||
|
Before Width: | Height: | Size: 82 KiB After Width: | Height: | Size: 82 KiB |
Reference in New Issue
Block a user