KCL: New extrudeTwist endpoint (#7480)
This does not include feature tree editing support.
This commit is contained in:
53
docs/kcl-std/functions/std-sketch-extrudeTwist.md
Normal file
53
docs/kcl-std/functions/std-sketch-extrudeTwist.md
Normal file
File diff suppressed because one or more lines are too long
@ -55,6 +55,7 @@ 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,6 +20,7 @@ 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)
|
||||||
|
4
rust/Cargo.lock
generated
4
rust/Cargo.lock
generated
@ -2049,9 +2049,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "kittycad-modeling-cmds"
|
name = "kittycad-modeling-cmds"
|
||||||
version = "0.2.121"
|
version = "0.2.123"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "94ba95c22493d79ec8a1faab963d8903f6de0e373efedf2bc3bb76a0ddbab036"
|
checksum = "b8f3c1b4b4ddb9aa336a09933f2550f9882552e321187b7bcff47f006379c3aa"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"chrono",
|
"chrono",
|
||||||
|
@ -36,7 +36,7 @@ dashmap = { version = "6.1.0" }
|
|||||||
http = "1"
|
http = "1"
|
||||||
indexmap = "2.9.0"
|
indexmap = "2.9.0"
|
||||||
kittycad = { version = "0.3.37", default-features = false, features = ["js", "requests"] }
|
kittycad = { version = "0.3.37", default-features = false, features = ["js", "requests"] }
|
||||||
kittycad-modeling-cmds = { version = "0.2.120", features = ["ts-rs", "websocket"] }
|
kittycad-modeling-cmds = { version = "0.2.123", features = ["ts-rs", "websocket"] }
|
||||||
lazy_static = "1.5.0"
|
lazy_static = "1.5.0"
|
||||||
miette = "7.5.0"
|
miette = "7.5.0"
|
||||||
pyo3 = { version = "0.24.1" }
|
pyo3 = { version = "0.24.1" }
|
||||||
|
@ -117,6 +117,7 @@ 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",
|
||||||
|
@ -170,6 +170,7 @@ pub struct Sweep {
|
|||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub enum SweepSubType {
|
pub enum SweepSubType {
|
||||||
Extrusion,
|
Extrusion,
|
||||||
|
ExtrusionTwist,
|
||||||
Revolve,
|
Revolve,
|
||||||
RevolveAboutEdge,
|
RevolveAboutEdge,
|
||||||
Loft,
|
Loft,
|
||||||
@ -1082,11 +1083,13 @@ fn artifacts_to_update(
|
|||||||
return Ok(return_arr);
|
return Ok(return_arr);
|
||||||
}
|
}
|
||||||
ModelingCmd::Extrude(kcmc::Extrude { target, .. })
|
ModelingCmd::Extrude(kcmc::Extrude { target, .. })
|
||||||
|
| ModelingCmd::TwistExtrude(kcmc::TwistExtrude { target, .. })
|
||||||
| ModelingCmd::Revolve(kcmc::Revolve { target, .. })
|
| ModelingCmd::Revolve(kcmc::Revolve { target, .. })
|
||||||
| ModelingCmd::RevolveAboutEdge(kcmc::RevolveAboutEdge { target, .. })
|
| ModelingCmd::RevolveAboutEdge(kcmc::RevolveAboutEdge { target, .. })
|
||||||
| ModelingCmd::Sweep(kcmc::Sweep { target, .. }) => {
|
| ModelingCmd::Sweep(kcmc::Sweep { target, .. }) => {
|
||||||
let sub_type = match cmd {
|
let sub_type = match cmd {
|
||||||
ModelingCmd::Extrude(_) => SweepSubType::Extrusion,
|
ModelingCmd::Extrude(_) => SweepSubType::Extrusion,
|
||||||
|
ModelingCmd::TwistExtrude(_) => SweepSubType::ExtrusionTwist,
|
||||||
ModelingCmd::Revolve(_) => SweepSubType::Revolve,
|
ModelingCmd::Revolve(_) => SweepSubType::Revolve,
|
||||||
ModelingCmd::RevolveAboutEdge(_) => SweepSubType::RevolveAboutEdge,
|
ModelingCmd::RevolveAboutEdge(_) => SweepSubType::RevolveAboutEdge,
|
||||||
ModelingCmd::Sweep(_) => SweepSubType::Sweep,
|
ModelingCmd::Sweep(_) => SweepSubType::Sweep,
|
||||||
|
@ -12,10 +12,13 @@ use kcmc::{
|
|||||||
websocket::{ModelingCmdReq, OkWebSocketResponseData},
|
websocket::{ModelingCmdReq, OkWebSocketResponseData},
|
||||||
ModelingCmd,
|
ModelingCmd,
|
||||||
};
|
};
|
||||||
use kittycad_modeling_cmds::{self as kcmc};
|
use kittycad_modeling_cmds::{
|
||||||
|
self as kcmc,
|
||||||
|
shared::{Angle, Point2d},
|
||||||
|
};
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
use super::args::TyF64;
|
use super::{args::TyF64, utils::point_to_mm, DEFAULT_TOLERANCE};
|
||||||
use crate::{
|
use crate::{
|
||||||
errors::{KclError, KclErrorDetails},
|
errors::{KclError, KclErrorDetails},
|
||||||
execution::{
|
execution::{
|
||||||
@ -121,6 +124,85 @@ async fn inner_extrude(
|
|||||||
|
|
||||||
Ok(solids)
|
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(),
|
||||||
|
distance: LengthUnit(length.to_mm()),
|
||||||
|
faces: Default::default(),
|
||||||
|
center_2d: center,
|
||||||
|
total_rotation_angle: Angle::from_degrees(angle.to_degrees()),
|
||||||
|
angle_step_size,
|
||||||
|
tolerance,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub(crate) struct NamedCapTags<'a> {
|
pub(crate) struct NamedCapTags<'a> {
|
||||||
|
@ -260,6 +260,10 @@ 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"),
|
||||||
|
@ -380,6 +380,39 @@ export fn extrude(
|
|||||||
tagEnd?: tag,
|
tagEnd?: tag,
|
||||||
): [Solid; 1+] {}
|
): [Solid; 1+] {}
|
||||||
|
|
||||||
|
/// 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.
|
||||||
|
/// Must be between 4 and 90 degrees.
|
||||||
|
/// Defaults to 15 degrees.
|
||||||
|
angleStep?: 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.
|
||||||
|
/// If not given, defaults to 0,0 i.e. the sketch's center.
|
||||||
|
@(snippetArray = ["0", "0"])
|
||||||
|
center?: Point2d,
|
||||||
|
): [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.
|
||||||
///
|
///
|
||||||
/// This, like extrude, is able to create a 3-dimensional solid from a
|
/// This, like extrude, is able to create a 3-dimensional solid from a
|
||||||
|
Binary file not shown.
After Width: | Height: | Size: 82 KiB |
@ -256,7 +256,6 @@ impl EngineConnection {
|
|||||||
let entity_ids = generate_repl_uuids(*num_repetitions as usize);
|
let entity_ids = generate_repl_uuids(*num_repetitions as usize);
|
||||||
|
|
||||||
this_response = OkModelingCmdResponse::EntityCircularPattern(kcmc::output::EntityCircularPattern {
|
this_response = OkModelingCmdResponse::EntityCircularPattern(kcmc::output::EntityCircularPattern {
|
||||||
entity_ids: entity_ids.clone(),
|
|
||||||
entity_face_edge_ids: vec![],
|
entity_face_edge_ids: vec![],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@ import type {
|
|||||||
Plane,
|
Plane,
|
||||||
StartSketchOnFace,
|
StartSketchOnFace,
|
||||||
StartSketchOnPlane,
|
StartSketchOnPlane,
|
||||||
|
SweepSubType,
|
||||||
Wall,
|
Wall,
|
||||||
} from '@rust/kcl-lib/bindings/Artifact'
|
} from '@rust/kcl-lib/bindings/Artifact'
|
||||||
|
|
||||||
@ -92,7 +93,7 @@ interface SegmentArtifactRich extends BaseArtifact {
|
|||||||
|
|
||||||
interface SweepArtifactRich extends BaseArtifact {
|
interface SweepArtifactRich extends BaseArtifact {
|
||||||
type: 'sweep'
|
type: 'sweep'
|
||||||
subType: 'extrusion' | 'revolve' | 'revolveAboutEdge' | 'loft' | 'sweep'
|
subType: SweepSubType
|
||||||
path: PathArtifact
|
path: PathArtifact
|
||||||
surfaces: Array<WallArtifact | CapArtifact>
|
surfaces: Array<WallArtifact | CapArtifact>
|
||||||
edges: Array<SweepEdge>
|
edges: Array<SweepEdge>
|
||||||
|
Reference in New Issue
Block a user