KCL: Add diameter arg to circle (#7116)

Paul's been requesting this for a long time. Now that we're fully using keyword args, this is easy to do.

We should probably add a similar `diameter` arg to `arc`, `tangentialArc`, `polygon` etc. And _maybe_ to `fillet`, but that might not be as helpful.
This commit is contained in:
Adam Chalmers
2025-05-20 14:44:35 -05:00
committed by GitHub
parent 5dc77ceed5
commit 36c8ad439d
5 changed files with 37 additions and 10 deletions

View File

@ -11,7 +11,8 @@ layout: manual
circle(
@sketch_or_surface: Sketch | Plane | Face,
center: Point2d,
radius: number(Length),
radius?: number(Length),
diameter?: number(Length),
tag?: tag,
): Sketch
```
@ -25,7 +26,8 @@ the provided (x, y) origin point.
|----------|------|-------------|----------|
| `sketch_or_surface` | [`Sketch`](/docs/kcl-std/types/std-types-Sketch) or [`Plane`](/docs/kcl-std/types/std-types-Plane) or [`Face`](/docs/kcl-std/types/std-types-Face) | Sketch to extend, or plane or surface to sketch on. | Yes |
| `center` | [`Point2d`](/docs/kcl-std/types/std-types-Point2d) | The center of the circle. | Yes |
| `radius` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | The radius of the circle. | Yes |
| `radius` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | The radius of the circle. Incompatible with `diameter`. | No |
| `diameter` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | The diameter of the circle. Incompatible with `radius`. | No |
| [`tag`](/docs/kcl-std/types/std-types-tag) | [`tag`](/docs/kcl-std/types/std-types-tag) | Create a new tag which refers to this circle. | No |
### Returns
@ -51,7 +53,7 @@ exampleSketch = startSketchOn(XZ)
|> line(end = [0, 30])
|> line(end = [-30, 0])
|> close()
|> subtract2d(tool = circle(center = [0, 15], radius = 5))
|> subtract2d(tool = circle(center = [0, 15], diameter = 10))
example = extrude(exampleSketch, length = 5)
```

View File

@ -631,6 +631,8 @@ impl FnData {
return "clone(${0:part001})".to_owned();
} else if self.name == "hole" {
return "hole(${0:holeSketch}, ${1:%})".to_owned();
} else if self.name == "circle" {
return "circle(center = [${0:3.14}, ${1:3.14}], diameter = ${2:3.14})".to_owned();
}
let mut args = Vec::new();
let mut index = 0;

View File

@ -1018,7 +1018,7 @@ mod tests {
let snippet = circle_fn.to_autocomplete_snippet();
assert_eq!(
snippet,
r#"circle(center = [${0:3.14}, ${1:3.14}], radius = ${2:3.14})"#
r#"circle(center = [${0:3.14}, ${1:3.14}], diameter = ${2:3.14})"#
);
}

View File

@ -44,10 +44,11 @@ pub enum SketchOrSurface {
pub async fn circle(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let sketch_or_surface = args.get_unlabeled_kw_arg("sketchOrSurface")?;
let center = args.get_kw_arg_typed("center", &RuntimeType::point2d(), exec_state)?;
let radius: TyF64 = args.get_kw_arg_typed("radius", &RuntimeType::length(), exec_state)?;
let radius: Option<TyF64> = args.get_kw_arg_opt_typed("radius", &RuntimeType::length(), exec_state)?;
let diameter: Option<TyF64> = args.get_kw_arg_opt_typed("diameter", &RuntimeType::length(), exec_state)?;
let tag = args.get_kw_arg_opt(NEW_TAG_KW)?;
let sketch = inner_circle(sketch_or_surface, center, radius, tag, exec_state, args).await?;
let sketch = inner_circle(sketch_or_surface, center, radius, diameter, tag, exec_state, args).await?;
Ok(KclValue::Sketch {
value: Box::new(sketch),
})
@ -56,7 +57,8 @@ pub async fn circle(exec_state: &mut ExecState, args: Args) -> Result<KclValue,
async fn inner_circle(
sketch_or_surface: SketchOrSurface,
center: [TyF64; 2],
radius: TyF64,
radius: Option<TyF64>,
diameter: Option<TyF64>,
tag: Option<TagNode>,
exec_state: &mut ExecState,
args: Args,
@ -68,6 +70,25 @@ async fn inner_circle(
let (center_u, ty) = untype_point(center.clone());
let units = ty.expect_length();
let radius = match (radius, diameter) {
(Some(radius), None) => radius,
(None, Some(mut diameter)) => {
diameter.n /= 2.0;
diameter
}
(None, None) => {
return Err(KclError::Type(KclErrorDetails::new(
"This function needs either `diameter` or `radius`".to_string(),
vec![args.source_range],
)))
}
(Some(_), Some(_)) => {
return Err(KclError::Type(KclErrorDetails::new(
"You cannot specify both `diameter` and `radius`, please remove one".to_string(),
vec![args.source_range],
)))
}
};
let from = [center_u[0] + radius.to_length_units(units), center_u[1]];
let from_t = [TyF64::new(from[0], ty.clone()), TyF64::new(from[1], ty)];

View File

@ -24,7 +24,7 @@
/// |> line(end = [0, 30])
/// |> line(end = [-30, 0])
/// |> close()
/// |> subtract2d(tool = circle(center = [0, 15], radius = 5))
/// |> subtract2d(tool = circle(center = [0, 15], diameter = 10))
///
/// example = extrude(exampleSketch, length = 5)
/// ```
@ -34,8 +34,10 @@ export fn circle(
@sketch_or_surface: Sketch | Plane | Face,
/// The center of the circle.
center: Point2d,
/// The radius of the circle.
radius: number(Length),
/// The radius of the circle. Incompatible with `diameter`.
radius?: number(Length),
/// The diameter of the circle. Incompatible with `radius`.
diameter?: number(Length),
/// Create a new tag which refers to this circle.
tag?: tag,
): Sketch {}