Revolve changed to kw args (#5873)

* initial port

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

* updates

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

* more fixes

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

* fix e2e

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

* more fixes

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

* updates

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

* update js side

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

* updates

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

* fixes

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

* fix;

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

* cleanup

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

* updates

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-18 20:34:44 -07:00
committed by GitHub
parent 859bfc7b28
commit 26fba71abf
124 changed files with 27930 additions and 23476 deletions

View File

@ -98,7 +98,7 @@ pub async fn appearance(exec_state: &mut ExecState, args: Args) -> Result<KclVal
/// // Add color to a revolved solid.
/// sketch001 = startSketchOn('XY')
/// |> circle( center = [15, 0], radius = 5 )
/// |> revolve({ angle = 360, axis = 'y' }, %)
/// |> revolve( angle = 360, axis = 'y')
/// |> appearance(
/// color = '#ff0000',
/// metalness = 90,

View File

@ -1239,16 +1239,6 @@ impl<'a> FromKclValue<'a> for super::sketch::ArcToData {
}
}
impl<'a> FromKclValue<'a> for super::revolve::RevolveData {
fn from_kcl_val(arg: &'a KclValue) -> Option<Self> {
let obj = arg.as_object()?;
let angle = obj.get("angle").and_then(|x| x.as_f64());
let tolerance = obj.get("tolerance").and_then(|x| x.as_f64());
let_field_of!(obj, axis);
Some(Self { angle, axis, tolerance })
}
}
impl<'a> FromKclValue<'a> for super::sketch::TangentialArcData {
fn from_kcl_val(arg: &'a KclValue) -> Option<Self> {
let obj = arg.as_object()?;

View File

@ -4,35 +4,28 @@ use anyhow::Result;
use kcl_derive_docs::stdlib;
use kcmc::{each_cmd as mcmd, length_unit::LengthUnit, shared::Angle, ModelingCmd};
use kittycad_modeling_cmds::{self as kcmc};
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use crate::{
errors::{KclError, KclErrorDetails},
execution::{ExecState, KclValue, Sketch, Solid},
execution::{
kcl_value::{ArrayLen, RuntimeType},
ExecState, KclValue, PrimitiveType, Sketch, Solid,
},
std::{axis_or_reference::Axis2dOrEdgeReference, extrude::do_post_extrude, fillet::default_tolerance, Args},
};
/// Data for revolution surfaces.
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
#[ts(export)]
pub struct RevolveData {
/// Angle to revolve (in degrees). Default is 360.
#[serde(default)]
#[schemars(range(min = -360.0, max = 360.0))]
pub angle: Option<f64>,
/// Axis of revolution.
pub axis: Axis2dOrEdgeReference,
/// Tolerance for the revolve operation.
#[serde(default)]
pub tolerance: Option<f64>,
}
/// Revolve a sketch or set of sketches around an axis.
pub async fn revolve(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let (data, sketches): (RevolveData, _) = args.get_data_and_sketches(exec_state)?;
let sketches = args.get_unlabeled_kw_arg_typed(
"sketches",
&RuntimeType::Array(PrimitiveType::Sketch, ArrayLen::NonEmpty),
exec_state,
)?;
let axis: Axis2dOrEdgeReference = args.get_kw_arg("axis")?;
let angle = args.get_kw_arg_opt("angle")?;
let tolerance = args.get_kw_arg_opt("tolerance")?;
let value = inner_revolve(data, sketches, exec_state, args).await?;
let value = inner_revolve(sketches, axis, angle, tolerance, exec_state, args).await?;
Ok(value.into())
}
@ -60,17 +53,17 @@ pub async fn revolve(exec_state: &mut ExecState, args: Args) -> Result<KclValue,
/// |> line(end = [0, -5.5])
/// |> line(end = [-2, 0])
/// |> close()
/// |> revolve({axis = 'y'}, %) // default angle is 360
/// |> revolve(axis = 'y') // default angle is 360
/// ```
///
/// ```no_run
/// // A donut shape.
/// sketch001 = startSketchOn('XY')
/// |> circle( center = [15, 0], radius = 5 )
/// |> revolve({
/// |> revolve(
/// angle = 360,
/// axis = 'y'
/// }, %)
/// )
/// ```
///
/// ```no_run
@ -84,7 +77,7 @@ pub async fn revolve(exec_state: &mut ExecState, args: Args) -> Result<KclValue,
/// |> line(end = [0, -5.5])
/// |> line(end = [-2, 0])
/// |> close()
/// |> revolve({axis = 'y', angle = 180}, %)
/// |> revolve(axis = 'y', angle = 180)
/// ```
///
/// ```no_run
@ -98,7 +91,8 @@ pub async fn revolve(exec_state: &mut ExecState, args: Args) -> Result<KclValue,
/// |> line(end = [0, -5.5])
/// |> line(end = [-2, 0])
/// |> close()
/// |> revolve({axis = 'y', angle = 180}, %)
/// |> revolve(axis = 'y', angle = 180)
///
/// part002 = startSketchOn(part001, 'end')
/// |> startProfileAt([4.5, -5], %)
/// |> line(end = [0, 5])
@ -119,10 +113,10 @@ pub async fn revolve(exec_state: &mut ExecState, args: Args) -> Result<KclValue,
///
/// sketch001 = startSketchOn(box, "END")
/// |> circle( center = [10,10], radius = 4 )
/// |> revolve({
/// |> revolve(
/// angle = -90,
/// axis = 'y'
/// }, %)
/// )
/// ```
///
/// ```no_run
@ -136,10 +130,10 @@ pub async fn revolve(exec_state: &mut ExecState, args: Args) -> Result<KclValue,
///
/// sketch001 = startSketchOn(box, "END")
/// |> circle( center = [10,10], radius = 4 )
/// |> revolve({
/// |> revolve(
/// angle = 90,
/// axis = getOppositeEdge(revolveAxis)
/// }, %)
/// )
/// ```
///
/// ```no_run
@ -153,11 +147,11 @@ pub async fn revolve(exec_state: &mut ExecState, args: Args) -> Result<KclValue,
///
/// sketch001 = startSketchOn(box, "END")
/// |> circle( center = [10,10], radius = 4 )
/// |> revolve({
/// |> revolve(
/// angle = 90,
/// axis = getOppositeEdge(revolveAxis),
/// tolerance: 0.0001
/// }, %)
/// tolerance = 0.0001
/// )
/// ```
///
/// ```no_run
@ -168,14 +162,15 @@ pub async fn revolve(exec_state: &mut ExecState, args: Args) -> Result<KclValue,
/// |> line(endAbsolute = [profileStartX(%), profileStartY(%)])
/// |> close()
///
/// part001 = revolve({
/// part001 = revolve(
/// sketch001,
/// axis = {
/// custom: {
/// axis = [0.0, 1.0],
/// origin: [0.0, 0.0]
/// }
/// }
/// }, sketch001)
/// )
/// ```
///
/// ```no_run
@ -196,9 +191,10 @@ pub async fn revolve(exec_state: &mut ExecState, args: Args) -> Result<KclValue,
/// |> line(endAbsolute = [profileStartX(%), profileStartY(%)])
/// |> close()
///
/// revolve({
/// revolve(
/// [profile001, profile002],
/// axis = "X",
/// }, [profile001, profile002])
/// )
/// ```
///
/// ```no_run
@ -213,7 +209,7 @@ pub async fn revolve(exec_state: &mut ExecState, args: Args) -> Result<KclValue,
///
/// sketch001 = startSketchOn('XY')
/// |> circle(center = [-10, 10], radius = 4)
/// |> revolve({ angle: 90, axis: revolveAxis }, %)
/// |> revolve(angle = 90, axis = revolveAxis)
/// ```
///
/// ```no_run
@ -226,19 +222,29 @@ pub async fn revolve(exec_state: &mut ExecState, args: Args) -> Result<KclValue,
///
/// sketch001 = startSketchOn('XY')
/// |> circle(center = [-10, 10], radius = 4)
/// |> revolve({ angle: 90, axis: revolveAxis }, %)
/// |> revolve(angle = 90, axis = revolveAxis)
/// ```
#[stdlib {
name = "revolve",
feature_tree_operation = true,
keywords = true,
unlabeled_first = true,
args = {
sketches = { docs = "The sketch or set of sketches that should be revolved" },
axis = { docs = "Axis of revolution." },
angle = { docs = "Angle to revolve (in degrees). Default is 360." },
tolerance = { docs = "Tolerance for the revolve operation." },
}
}]
async fn inner_revolve(
data: RevolveData,
sketches: Vec<Sketch>,
axis: Axis2dOrEdgeReference,
angle: Option<f64>,
tolerance: Option<f64>,
exec_state: &mut ExecState,
args: Args,
) -> Result<Vec<Solid>, KclError> {
if let Some(angle) = data.angle {
if let Some(angle) = angle {
// Return an error if the angle is zero.
// We don't use validate() here because we want to return a specific error message that is
// nice and we use the other data in the docs, so we still need use the derive above for the json schema.
@ -250,13 +256,13 @@ async fn inner_revolve(
}
}
let angle = Angle::from_degrees(data.angle.unwrap_or(360.0));
let angle = Angle::from_degrees(angle.unwrap_or(360.0));
let mut solids = Vec::new();
for sketch in &sketches {
let id = exec_state.next_uuid();
match &data.axis {
match &axis {
Axis2dOrEdgeReference::Axis(axis) => {
let (axis, origin) = axis.axis_and_origin()?;
args.batch_modeling_cmd(
@ -266,7 +272,7 @@ async fn inner_revolve(
target: sketch.id.into(),
axis,
origin,
tolerance: LengthUnit(data.tolerance.unwrap_or(default_tolerance(&args.ctx.settings.units))),
tolerance: LengthUnit(tolerance.unwrap_or(default_tolerance(&args.ctx.settings.units))),
axis_is_2d: true,
}),
)
@ -280,7 +286,7 @@ async fn inner_revolve(
angle,
target: sketch.id.into(),
edge_id,
tolerance: LengthUnit(data.tolerance.unwrap_or(default_tolerance(&args.ctx.settings.units))),
tolerance: LengthUnit(tolerance.unwrap_or(default_tolerance(&args.ctx.settings.units))),
}),
)
.await?;

View File

@ -991,7 +991,7 @@ pub async fn start_sketch_on(exec_state: &mut ExecState, args: Args) -> Result<K
/// |> line(end = [-2, 0])
/// |> close()
///
/// example = revolve({ axis: 'y', angle: 180 }, exampleSketch)
/// example = revolve(exampleSketch, axis = 'y', angle = 180)
///
/// exampleSketch002 = startSketchOn(example, 'end')
/// |> startProfileAt([4.5, -5], %)