BREAKING: Change polygon to keyword args (#6385)
* Change polygon to keyword args * Update docs * Update generated output * Update docs to mention the default for inscribed * Appease clippy * Remove tag parameter * Update docs since removing tag * Remove inscribed from autocomplete snippet since the default is true
This commit is contained in:
@ -13,6 +13,7 @@ use kittycad_modeling_cmds::shared::PathSegment;
|
||||
use schemars::JsonSchema;
|
||||
use serde::Serialize;
|
||||
|
||||
use super::{args::TyF64, utils::untype_point};
|
||||
use crate::{
|
||||
errors::{KclError, KclErrorDetails},
|
||||
execution::{types::RuntimeType, BasePath, ExecState, GeoMeta, KclValue, Path, Sketch, SketchSurface},
|
||||
@ -24,8 +25,6 @@ use crate::{
|
||||
},
|
||||
};
|
||||
|
||||
use super::{args::TyF64, utils::untype_point};
|
||||
|
||||
/// A sketch surface or a sketch.
|
||||
#[derive(Debug, Clone, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
|
||||
#[ts(export)]
|
||||
@ -259,35 +258,24 @@ pub enum PolygonType {
|
||||
Circumscribed,
|
||||
}
|
||||
|
||||
/// Data for drawing a polygon
|
||||
#[derive(Debug, Clone, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
|
||||
#[ts(export)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct PolygonData {
|
||||
/// The radius of the polygon
|
||||
pub radius: TyF64,
|
||||
/// The number of sides in the polygon
|
||||
pub num_sides: u64,
|
||||
/// The center point of the polygon
|
||||
pub center: [TyF64; 2],
|
||||
/// The type of the polygon (inscribed or circumscribed)
|
||||
#[serde(skip)]
|
||||
pub polygon_type: PolygonType,
|
||||
/// Whether the polygon is inscribed (true) or circumscribed (false) about a circle with the specified radius
|
||||
#[serde(default = "default_inscribed")]
|
||||
pub inscribed: bool,
|
||||
}
|
||||
|
||||
fn default_inscribed() -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
/// Create a regular polygon with the specified number of sides and radius.
|
||||
pub async fn polygon(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
||||
let (data, sketch_surface_or_group, tag): (PolygonData, SketchOrSurface, Option<TagNode>) =
|
||||
args.get_polygon_args()?;
|
||||
let sketch_surface_or_group = args.get_unlabeled_kw_arg("sketchOrSurface")?;
|
||||
let radius: TyF64 = args.get_kw_arg_typed("radius", &RuntimeType::length(), exec_state)?;
|
||||
let num_sides: TyF64 = args.get_kw_arg_typed("numSides", &RuntimeType::count(), exec_state)?;
|
||||
let center = args.get_kw_arg_typed("center", &RuntimeType::point2d(), exec_state)?;
|
||||
let inscribed = args.get_kw_arg_opt_typed("inscribed", &RuntimeType::bool(), exec_state)?;
|
||||
|
||||
let sketch = inner_polygon(data, sketch_surface_or_group, tag, exec_state, args).await?;
|
||||
let sketch = inner_polygon(
|
||||
sketch_surface_or_group,
|
||||
radius,
|
||||
num_sides.n as u64,
|
||||
untype_point(center).0,
|
||||
inscribed,
|
||||
exec_state,
|
||||
args,
|
||||
)
|
||||
.await?;
|
||||
Ok(KclValue::Sketch {
|
||||
value: Box::new(sketch),
|
||||
})
|
||||
@ -298,12 +286,12 @@ pub async fn polygon(exec_state: &mut ExecState, args: Args) -> Result<KclValue,
|
||||
/// ```no_run
|
||||
/// // Create a regular hexagon inscribed in a circle of radius 10
|
||||
/// hex = startSketchOn('XY')
|
||||
/// |> polygon({
|
||||
/// |> polygon(
|
||||
/// radius = 10,
|
||||
/// numSides = 6,
|
||||
/// center = [0, 0],
|
||||
/// inscribed = true,
|
||||
/// }, %)
|
||||
/// )
|
||||
///
|
||||
/// example = extrude(hex, length = 5)
|
||||
/// ```
|
||||
@ -311,32 +299,44 @@ pub async fn polygon(exec_state: &mut ExecState, args: Args) -> Result<KclValue,
|
||||
/// ```no_run
|
||||
/// // Create a square circumscribed around a circle of radius 5
|
||||
/// square = startSketchOn('XY')
|
||||
/// |> polygon({
|
||||
/// |> polygon(
|
||||
/// radius = 5.0,
|
||||
/// numSides = 4,
|
||||
/// center = [10, 10],
|
||||
/// inscribed = false,
|
||||
/// }, %)
|
||||
/// )
|
||||
/// example = extrude(square, length = 5)
|
||||
/// ```
|
||||
#[stdlib {
|
||||
name = "polygon",
|
||||
keywords = true,
|
||||
unlabeled_first = true,
|
||||
args = {
|
||||
sketch_surface_or_group = { docs = "Plane or surface to sketch on" },
|
||||
radius = { docs = "The radius of the polygon", include_in_snippet = true },
|
||||
num_sides = { docs = "The number of sides in the polygon", include_in_snippet = true },
|
||||
center = { docs = "The center point of the polygon", include_in_snippet = true },
|
||||
inscribed = { docs = "Whether the polygon is inscribed (true, the default) or circumscribed (false) about a circle with the specified radius" },
|
||||
}
|
||||
}]
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
async fn inner_polygon(
|
||||
data: PolygonData,
|
||||
sketch_surface_or_group: SketchOrSurface,
|
||||
tag: Option<TagNode>,
|
||||
radius: TyF64,
|
||||
num_sides: u64,
|
||||
center: [f64; 2],
|
||||
inscribed: Option<bool>,
|
||||
exec_state: &mut ExecState,
|
||||
args: Args,
|
||||
) -> Result<Sketch, KclError> {
|
||||
if data.num_sides < 3 {
|
||||
if num_sides < 3 {
|
||||
return Err(KclError::Type(KclErrorDetails {
|
||||
message: "Polygon must have at least 3 sides".to_string(),
|
||||
source_ranges: vec![args.source_range],
|
||||
}));
|
||||
}
|
||||
|
||||
if data.radius.n <= 0.0 {
|
||||
if radius.n <= 0.0 {
|
||||
return Err(KclError::Type(KclErrorDetails {
|
||||
message: "Radius must be greater than 0".to_string(),
|
||||
source_ranges: vec![args.source_range],
|
||||
@ -348,21 +348,24 @@ async fn inner_polygon(
|
||||
SketchOrSurface::Sketch(group) => group.on,
|
||||
};
|
||||
|
||||
let half_angle = std::f64::consts::PI / data.num_sides as f64;
|
||||
let half_angle = std::f64::consts::PI / num_sides as f64;
|
||||
|
||||
let radius_to_vertices = match data.polygon_type {
|
||||
PolygonType::Inscribed => data.radius.n,
|
||||
PolygonType::Circumscribed => data.radius.n / half_angle.cos(),
|
||||
let radius_to_vertices = if inscribed.unwrap_or(true) {
|
||||
// inscribed
|
||||
radius.n
|
||||
} else {
|
||||
// circumscribed
|
||||
radius.n / half_angle.cos()
|
||||
};
|
||||
|
||||
let angle_step = 2.0 * std::f64::consts::PI / data.num_sides as f64;
|
||||
let angle_step = std::f64::consts::TAU / num_sides as f64;
|
||||
|
||||
let vertices: Vec<[f64; 2]> = (0..data.num_sides)
|
||||
let vertices: Vec<[f64; 2]> = (0..num_sides)
|
||||
.map(|i| {
|
||||
let angle = angle_step * i as f64;
|
||||
[
|
||||
data.center[0].n + radius_to_vertices * angle.cos(),
|
||||
data.center[1].n + radius_to_vertices * angle.sin(),
|
||||
center[0] + radius_to_vertices * angle.cos(),
|
||||
center[1] + radius_to_vertices * angle.sin(),
|
||||
]
|
||||
})
|
||||
.collect();
|
||||
@ -391,7 +394,7 @@ async fn inner_polygon(
|
||||
base: BasePath {
|
||||
from: from.into(),
|
||||
to: *vertex,
|
||||
tag: tag.clone(),
|
||||
tag: None,
|
||||
units: sketch.units,
|
||||
geo_meta: GeoMeta {
|
||||
id,
|
||||
@ -400,10 +403,6 @@ async fn inner_polygon(
|
||||
},
|
||||
};
|
||||
|
||||
if let Some(tag) = &tag {
|
||||
sketch.add_tag(tag, ¤t_path, exec_state);
|
||||
}
|
||||
|
||||
sketch.paths.push(current_path);
|
||||
}
|
||||
|
||||
@ -427,7 +426,7 @@ async fn inner_polygon(
|
||||
base: BasePath {
|
||||
from: from.into(),
|
||||
to: vertices[0],
|
||||
tag: tag.clone(),
|
||||
tag: None,
|
||||
units: sketch.units,
|
||||
geo_meta: GeoMeta {
|
||||
id: close_id,
|
||||
@ -436,10 +435,6 @@ async fn inner_polygon(
|
||||
},
|
||||
};
|
||||
|
||||
if let Some(tag) = &tag {
|
||||
sketch.add_tag(tag, ¤t_path, exec_state);
|
||||
}
|
||||
|
||||
sketch.paths.push(current_path);
|
||||
|
||||
args.batch_modeling_cmd(
|
||||
|
Reference in New Issue
Block a user