2024-03-25 17:07:53 -07:00
|
|
|
//! Standard library helices.
|
|
|
|
|
|
|
|
use anyhow::Result;
|
|
|
|
use derive_docs::stdlib;
|
2024-09-19 14:06:29 -07:00
|
|
|
use kcmc::{each_cmd as mcmd, length_unit::LengthUnit, shared::Angle, ModelingCmd};
|
2024-09-18 17:04:04 -05:00
|
|
|
use kittycad_modeling_cmds as kcmc;
|
2024-03-25 17:07:53 -07:00
|
|
|
use schemars::JsonSchema;
|
|
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
|
|
|
|
use crate::{
|
|
|
|
errors::KclError,
|
2024-12-07 07:16:04 +13:00
|
|
|
execution::{ExecState, KclValue, Solid},
|
2024-03-25 17:07:53 -07:00
|
|
|
std::Args,
|
|
|
|
};
|
|
|
|
|
|
|
|
/// Data for helices.
|
|
|
|
#[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).
|
2024-07-29 13:18:55 -07:00
|
|
|
#[serde(rename = "angleStart", alias = "angle_start")]
|
2024-03-25 17:07:53 -07:00
|
|
|
pub angle_start: f64,
|
|
|
|
/// Is the helix rotation counter clockwise?
|
|
|
|
/// The default is `false`.
|
|
|
|
#[serde(default)]
|
|
|
|
pub ccw: bool,
|
|
|
|
/// Length of the helix. If this argument is not provided, the height of
|
2024-09-27 15:44:44 -07:00
|
|
|
/// the solid is used.
|
2024-03-25 17:07:53 -07:00
|
|
|
pub length: Option<f64>,
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Create a helix on a cylinder.
|
2024-10-09 19:38:40 -04:00
|
|
|
pub async fn helix(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
2024-09-27 15:44:44 -07:00
|
|
|
let (data, solid): (HelixData, Box<Solid>) = args.get_data_and_solid()?;
|
2024-03-25 17:07:53 -07:00
|
|
|
|
2024-10-09 19:38:40 -04:00
|
|
|
let solid = inner_helix(data, solid, exec_state, args).await?;
|
2024-09-27 15:44:44 -07:00
|
|
|
Ok(KclValue::Solid(solid))
|
2024-03-25 17:07:53 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Create a helix on a cylinder.
|
|
|
|
///
|
|
|
|
/// ```no_run
|
2024-12-12 11:33:37 -05:00
|
|
|
/// part001 = startSketchOn('XY')
|
2024-09-23 22:42:51 +10:00
|
|
|
/// |> circle({ center: [5, 5], radius: 10 }, %)
|
2024-05-14 17:10:47 -07:00
|
|
|
/// |> extrude(10, %)
|
|
|
|
/// |> helix({
|
2024-11-25 09:21:55 +13:00
|
|
|
/// angleStart = 0,
|
|
|
|
/// ccw = true,
|
|
|
|
/// revolutions = 16,
|
2024-05-14 17:10:47 -07:00
|
|
|
/// }, %)
|
2024-03-25 17:07:53 -07:00
|
|
|
/// ```
|
|
|
|
#[stdlib {
|
|
|
|
name = "helix",
|
2024-12-16 13:10:31 -05:00
|
|
|
feature_tree_operation = true,
|
2024-03-25 17:07:53 -07:00
|
|
|
}]
|
2024-10-09 19:38:40 -04:00
|
|
|
async fn inner_helix(
|
|
|
|
data: HelixData,
|
|
|
|
solid: Box<Solid>,
|
|
|
|
exec_state: &mut ExecState,
|
|
|
|
args: Args,
|
|
|
|
) -> Result<Box<Solid>, KclError> {
|
2024-12-17 09:38:32 +13:00
|
|
|
let id = exec_state.next_uuid();
|
2024-06-19 13:57:50 -07:00
|
|
|
args.batch_modeling_cmd(
|
2024-03-25 17:07:53 -07:00
|
|
|
id,
|
2024-09-18 17:04:04 -05:00
|
|
|
ModelingCmd::from(mcmd::EntityMakeHelix {
|
2024-09-27 15:44:44 -07:00
|
|
|
cylinder_id: solid.id,
|
2024-03-25 17:07:53 -07:00
|
|
|
is_clockwise: !data.ccw,
|
2024-09-27 15:44:44 -07:00
|
|
|
length: LengthUnit(data.length.unwrap_or(solid.height)),
|
2024-03-25 17:07:53 -07:00
|
|
|
revolutions: data.revolutions,
|
2024-09-18 17:04:04 -05:00
|
|
|
start_angle: Angle::from_degrees(data.angle_start),
|
|
|
|
}),
|
2024-03-25 17:07:53 -07:00
|
|
|
)
|
|
|
|
.await?;
|
|
|
|
|
2024-09-27 15:44:44 -07:00
|
|
|
Ok(solid)
|
2024-03-25 17:07:53 -07:00
|
|
|
}
|