change helix to kw args (#5274)

* update

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

* updates

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

* remove old file

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-02-05 15:58:32 -08:00
committed by GitHub
parent c30b161e95
commit eb4048cd16
14 changed files with 1147 additions and 225 deletions

View File

@ -9,7 +9,7 @@ Create a helix.
```js
helix(data: HelixData) -> HelixValue
helix(revolutions: number, angle_start: number, ccw?: bool, radius: number, axis: Axis3dOrEdgeReference, length?: number) -> HelixValue
```
@ -17,7 +17,12 @@ helix(data: HelixData) -> HelixValue
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `data` | [`HelixData`](/docs/kcl/types/HelixData) | Data for a helix. | Yes |
| `revolutions` | `number` | Number of revolutions. | Yes |
| `angle_start` | `number` | Start angle (in degrees). | Yes |
| `ccw` | `bool` | Is the helix rotation counter clockwise? The default is `false`. | No |
| `radius` | `number` | Radius of the helix. | Yes |
| `axis` | [`Axis3dOrEdgeReference`](/docs/kcl/types/Axis3dOrEdgeReference) | Axis to use for the helix. | Yes |
| `length` | `number` | Length of the helix. This is not necessary if the helix is created around an edge. If not given the length of the edge is used. | No |
### Returns
@ -28,14 +33,7 @@ helix(data: HelixData) -> HelixValue
```js
// Create a helix around the Z axis.
helixPath = helix({
angleStart = 0,
ccw = true,
revolutions = 5,
length = 10,
radius = 5,
axis = 'Z'
})
helixPath = helix(angleStart = 0, ccw = true, revolutions = 5, length = 10, radius = 5, axis = 'Z')
// Create a spring by sweeping around the helix path.
springSketch = startSketchOn('YZ')
@ -51,14 +49,7 @@ helper001 = startSketchOn('XZ')
|> startProfileAt([0, 0], %)
|> line(end = [0, 10], tag = $edge001)
helixPath = helix({
angleStart = 0,
ccw = true,
revolutions = 5,
length = 10,
radius = 5,
axis = edge001
})
helixPath = helix(angleStart = 0, ccw = true, revolutions = 5, length = 10, radius = 5, axis = edge001)
// Create a spring by sweeping around the helix path.
springSketch = startSketchOn('XY')
@ -70,17 +61,10 @@ springSketch = startSketchOn('XY')
```js
// Create a helix around a custom axis.
helixPath = helix({
angleStart = 0,
ccw = true,
revolutions = 5,
length = 10,
radius = 5,
axis = {
custom = {
axis = [0, 0, 1.0],
origin = [0, 0.25, 0]
}
helixPath = helix(angleStart = 0, ccw = true, revolutions = 5, length = 10, radius = 5, axis = {
custom = {
axis = [0, 0, 1.0],
origin = [0, 0.25, 0]
}
})

File diff suppressed because it is too large Load Diff

View File

@ -57,14 +57,7 @@ sweepSketch = startSketchOn('XY')
// Create a helix around the Z axis.
helixPath = helix({
angleStart = 0,
ccw = true,
revolutions = 4,
length = 10,
radius = 5,
axis = 'Z'
})
helixPath = helix(angleStart = 0, ccw = true, revolutions = 4, length = 10, radius = 5, axis = 'Z')
// Create a spring by sweeping around the helix path.
springSketch = startSketchOn('YZ')

View File

@ -1,26 +0,0 @@
---
title: "HelixData"
excerpt: "Data for a helix."
layout: manual
---
Data for a helix.
**Type:** `object`
## Properties
| Property | Type | Description | Required |
|----------|------|-------------|----------|
| `revolutions` |`number`| Number of revolutions. | No |
| `angleStart` |`number`| Start angle (in degrees). | No |
| `ccw` |`boolean`| Is the helix rotation counter clockwise? The default is `false`. | No |
| `length` |`number`| Length of the helix. This is not necessary if the helix is created around an edge. If not given the length of the edge is used. | No |
| `radius` |`number`| Radius of the helix. | No |
| `axis` |[`Axis3dOrEdgeReference`](/docs/kcl/types/Axis3dOrEdgeReference)| Axis to use as mirror. | No |

View File

@ -1059,13 +1059,7 @@ mod tests {
let snippet = helix_fn.to_autocomplete_snippet().unwrap();
assert_eq!(
snippet,
r#"helix({
revolutions = ${0:3.14},
angleStart = ${1:3.14},
ccw = ${2:false},
radius = ${3:3.14},
axis = ${4:"X"},
})${}"#
r#"helix(revolutions = ${0:3.14}, angle_start = ${1:3.14}, radius = ${2:3.14}, axis = ${3:"X"}, length = ${4:3.14})${}"#
);
}

View File

@ -1640,9 +1640,8 @@ impl JsonSchema for FunctionParam<'_> {
#[cfg(test)]
mod test {
use crate::parsing::ast::types::{DefaultParamVal, Identifier, Parameter};
use super::*;
use crate::parsing::ast::types::{DefaultParamVal, Identifier, Parameter};
#[test]
fn test_assign_args_to_params() {

View File

@ -3,8 +3,15 @@
use std::{path::PathBuf, sync::Arc};
use anyhow::Result;
pub use artifact::{Artifact, ArtifactCommand, ArtifactGraph, ArtifactId};
pub use cache::bust_cache;
use cache::OldAstState;
pub use cad_op::Operation;
pub use exec_ast::FunctionParam;
pub use geometry::*;
pub(crate) use import::{import_foreign, send_to_engine as send_import_to_engine, ZOO_COORD_SYSTEM};
use indexmap::IndexMap;
pub use kcl_value::{KclObjectFields, KclValue, UnitAngle, UnitLen};
use kcmc::{
each_cmd as mcmd,
ok_response::{output::TakeSnapshot, OkModelingCmdResponse},
@ -12,8 +19,10 @@ use kcmc::{
ImageFormat, ModelingCmd,
};
use kittycad_modeling_cmds as kcmc;
pub use memory::ProgramMemory;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
pub use state::{ExecState, IdGenerator, MetaSettings};
use crate::{
engine::EngineManager,
@ -30,16 +39,6 @@ use crate::{
ExecError, KclErrorWithOutputs,
};
pub use artifact::{Artifact, ArtifactCommand, ArtifactGraph, ArtifactId};
pub use cache::bust_cache;
pub use cad_op::Operation;
pub use exec_ast::FunctionParam;
pub use geometry::*;
pub(crate) use import::{import_foreign, send_to_engine as send_import_to_engine, ZOO_COORD_SYSTEM};
pub use kcl_value::{KclObjectFields, KclValue, UnitAngle, UnitLen};
pub use memory::ProgramMemory;
pub use state::{ExecState, IdGenerator, MetaSettings};
pub(crate) mod annotations;
mod artifact;
pub(crate) mod cache;

View File

@ -6,6 +6,7 @@ use kcmc::{
};
use kittycad_modeling_cmds as kcmc;
use super::types::{CallExpressionKw, Identifier, LabeledArg, LiteralValue};
use crate::{
engine::EngineManager,
errors::{KclError, KclErrorDetails},
@ -18,8 +19,6 @@ use crate::{
Program,
};
use super::types::{CallExpressionKw, Identifier, LabeledArg, LiteralValue};
type Point3d = kcmc::shared::Point3d<f64>;
#[derive(Debug)]

View File

@ -26,8 +26,7 @@ use crate::{
docs::StdLibFn,
errors::KclError,
execution::{annotations, KclValue, Metadata, TagIdentifier},
parsing::ast::digest::Digest,
parsing::PIPE_OPERATOR,
parsing::{ast::digest::Digest, PIPE_OPERATOR},
source_range::{ModuleId, SourceRange},
};

View File

@ -561,12 +561,11 @@ mod tests {
use pretty_assertions::assert_eq;
use validator::Validate;
use crate::settings::types::CameraOrbitType;
use super::{
AppColor, AppSettings, AppTheme, AppearanceSettings, CameraProjectionType, CommandBarSettings, Configuration,
ModelingSettings, OnboardingStatus, ProjectSettings, Settings, TextEditorSettings, UnitLength,
};
use crate::settings::types::CameraOrbitType;
#[test]
// Test that we can deserialize a project file from the old format.

View File

@ -1071,27 +1071,6 @@ impl<'a> FromKclValue<'a> for super::appearance::AppearanceData {
}
}
impl<'a> FromKclValue<'a> for super::helix::HelixData {
fn from_kcl_val(arg: &'a KclValue) -> Option<Self> {
let obj = arg.as_object()?;
let_field_of!(obj, revolutions);
let_field_of!(obj, length?);
let_field_of!(obj, ccw?);
let_field_of!(obj, radius);
let_field_of!(obj, axis);
let ccw = ccw.unwrap_or_default();
let angle_start = obj.get("angleStart")?.as_f64()?;
Some(Self {
revolutions,
angle_start,
ccw,
length,
radius,
axis,
})
}
}
impl<'a> FromKclValue<'a> for super::helix::HelixRevolutionsData {
fn from_kcl_val(arg: &'a KclValue) -> Option<Self> {
let obj = arg.as_object()?;

View File

@ -13,33 +13,16 @@ use crate::{
std::{axis_or_reference::Axis3dOrEdgeReference, Args},
};
/// Data for a helix.
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
#[ts(export)]
pub struct HelixData {
/// Number of revolutions.
pub revolutions: f64,
/// Start angle (in degrees).
#[serde(rename = "angleStart")]
pub angle_start: f64,
/// Is the helix rotation counter clockwise?
/// The default is `false`.
#[serde(default)]
pub ccw: bool,
/// Length of the helix. This is not necessary if the helix is created around an edge. If not
/// given the length of the edge is used.
pub length: Option<f64>,
/// Radius of the helix.
pub radius: f64,
/// Axis to use as mirror.
pub axis: Axis3dOrEdgeReference,
}
/// Create a helix.
pub async fn helix(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let data: HelixData = args.get_data()?;
let angle_start = args.get_kw_arg("angleStart")?;
let revolutions = args.get_kw_arg("revolutions")?;
let ccw = args.get_kw_arg_opt("ccw")?;
let radius = args.get_kw_arg("radius")?;
let axis = args.get_kw_arg("axis")?;
let length = args.get_kw_arg_opt("length")?;
let value = inner_helix(data, exec_state, args).await?;
let value = inner_helix(revolutions, angle_start, ccw, radius, axis, length, exec_state, args).await?;
Ok(KclValue::Helix { value })
}
@ -47,14 +30,14 @@ pub async fn helix(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K
///
/// ```no_run
/// // Create a helix around the Z axis.
/// helixPath = helix({
/// helixPath = helix(
/// angleStart = 0,
/// ccw = true,
/// revolutions = 5,
/// length = 10,
/// radius = 5,
/// axis = 'Z',
/// })
/// )
///
///
/// // Create a spring by sweeping around the helix path.
@ -69,14 +52,14 @@ pub async fn helix(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K
/// |> startProfileAt([0, 0], %)
/// |> line(end = [0, 10], tag = $edge001)
///
/// helixPath = helix({
/// helixPath = helix(
/// angleStart = 0,
/// ccw = true,
/// revolutions = 5,
/// length = 10,
/// radius = 5,
/// axis = edge001,
/// })
/// )
///
/// // Create a spring by sweeping around the helix path.
/// springSketch = startSketchOn('XY')
@ -86,7 +69,7 @@ pub async fn helix(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K
///
/// ```no_run
/// // Create a helix around a custom axis.
/// helixPath = helix({
/// helixPath = helix(
/// angleStart = 0,
/// ccw = true,
/// revolutions = 5,
@ -98,7 +81,7 @@ pub async fn helix(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K
/// origin = [0, 0.25, 0]
/// }
/// }
/// })
/// )
///
/// // Create a spring by sweeping around the helix path.
/// springSketch = startSketchOn('XY')
@ -107,16 +90,36 @@ pub async fn helix(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K
/// ```
#[stdlib {
name = "helix",
keywords = true,
unlabeled_first = false,
args = {
revolutions = { docs = "Number of revolutions."},
angle_start = { docs = "Start angle (in degrees)."},
ccw = { docs = "Is the helix rotation counter clockwise? The default is `false`.", include_in_snippet = false},
radius = { docs = "Radius of the helix."},
axis = { docs = "Axis to use for the helix."},
length = { docs = "Length of the helix. This is not necessary if the helix is created around an edge. If not given the length of the edge is used.", include_in_snippet = true},
},
feature_tree_operation = true,
}]
async fn inner_helix(data: HelixData, exec_state: &mut ExecState, args: Args) -> Result<Box<HelixValue>, KclError> {
#[allow(clippy::too_many_arguments)]
async fn inner_helix(
revolutions: f64,
angle_start: f64,
ccw: Option<bool>,
radius: f64,
axis: Axis3dOrEdgeReference,
length: Option<f64>,
exec_state: &mut ExecState,
args: Args,
) -> Result<Box<HelixValue>, KclError> {
let id = exec_state.next_uuid();
let helix_result = Box::new(HelixValue {
value: id,
revolutions: data.revolutions,
angle_start: data.angle_start,
ccw: data.ccw,
revolutions,
angle_start,
ccw: ccw.unwrap_or(false),
units: exec_state.length_unit(),
meta: vec![args.source_range.into()],
});
@ -125,12 +128,12 @@ async fn inner_helix(data: HelixData, exec_state: &mut ExecState, args: Args) ->
return Ok(helix_result);
}
match data.axis {
match axis {
Axis3dOrEdgeReference::Axis(axis) => {
let (axis, origin) = axis.axis_and_origin()?;
// Make sure they gave us a length.
let Some(length) = data.length else {
let Some(length) = length else {
return Err(KclError::Semantic(crate::errors::KclErrorDetails {
message: "Length is required when creating a helix around an axis.".to_string(),
source_ranges: vec![args.source_range],
@ -140,11 +143,11 @@ async fn inner_helix(data: HelixData, exec_state: &mut ExecState, args: Args) ->
args.batch_modeling_cmd(
id,
ModelingCmd::from(mcmd::EntityMakeHelixFromParams {
radius: LengthUnit(data.radius),
is_clockwise: !data.ccw,
radius: LengthUnit(radius),
is_clockwise: !helix_result.ccw,
length: LengthUnit(length),
revolutions: data.revolutions,
start_angle: Angle::from_degrees(data.angle_start),
revolutions,
start_angle: Angle::from_degrees(angle_start),
axis,
center: origin,
}),
@ -157,11 +160,11 @@ async fn inner_helix(data: HelixData, exec_state: &mut ExecState, args: Args) ->
args.batch_modeling_cmd(
id,
ModelingCmd::from(mcmd::EntityMakeHelixFromEdge {
radius: LengthUnit(data.radius),
is_clockwise: !data.ccw,
length: data.length.map(LengthUnit),
revolutions: data.revolutions,
start_angle: Angle::from_degrees(data.angle_start),
radius: LengthUnit(radius),
is_clockwise: !helix_result.ccw,
length: length.map(LengthUnit),
revolutions,
start_angle: Angle::from_degrees(angle_start),
edge_id,
}),
)

View File

@ -130,7 +130,6 @@ pub async fn line(exec_state: &mut ExecState, args: Args) -> Result<KclValue, Kc
/// |> line(end = [-10, 0], tag = $thirdLineOfBox)
/// |> close()
/// |> extrude(length = 5)
///
/// ```
#[stdlib {
name = "line",

View File

@ -91,14 +91,14 @@ pub async fn sweep(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K
/// // Create a spring by sweeping around a helix path.
///
/// // Create a helix around the Z axis.
/// helixPath = helix({
/// helixPath = helix(
/// angleStart = 0,
/// ccw = true,
/// revolutions = 4,
/// length = 10,
/// radius = 5,
/// axis = 'Z',
/// })
/// )
///
///
/// // Create a spring by sweeping around the helix path.