Fix circle (#1715)
* start of circle Signed-off-by: Jess Frazelle <github@jessfraz.com> * fixews Signed-off-by: Jess Frazelle <github@jessfraz.com> * fix all samples Signed-off-by: Jess Frazelle <github@jessfraz.com> * docs Signed-off-by: Jess Frazelle <github@jessfraz.com> * updates Signed-off-by: Jess Frazelle <github@jessfraz.com> * fix tests Signed-off-by: Jess Frazelle <github@jessfraz.com> * bump version; Signed-off-by: Jess Frazelle <github@jessfraz.com> * fixes Signed-off-by: Jess Frazelle <github@jessfraz.com> * fixes Signed-off-by: Jess Frazelle <github@jessfraz.com> --------- Signed-off-by: Jess Frazelle <github@jessfraz.com>
This commit is contained in:
@ -1,22 +1,43 @@
|
|||||||
---
|
---
|
||||||
title: "circle"
|
title: "circle"
|
||||||
excerpt: "Sketch a circle on the given plane"
|
excerpt: "Sketch a circle."
|
||||||
layout: manual
|
layout: manual
|
||||||
---
|
---
|
||||||
|
|
||||||
Sketch a circle on the given plane
|
Sketch a circle.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
```js
|
```js
|
||||||
circle(center: [number, number], radius: number, surface: SketchSurface, tag?: String) -> SketchGroup
|
circle(center: [number], radius: number, tag?: String, sketch_surface_or_group: SketchSurfaceOrGroup) -> SketchGroup
|
||||||
|
```
|
||||||
|
|
||||||
|
### Examples
|
||||||
|
|
||||||
|
```js
|
||||||
|
const circles = startSketchOn('XY')
|
||||||
|
|> circle([5, 5], 1, %)
|
||||||
|
|> patternLinear2d({
|
||||||
|
axis: [1, 1],
|
||||||
|
repetitions: 12,
|
||||||
|
distance: 3
|
||||||
|
}, %)
|
||||||
|
|
||||||
|
const rectangle = startSketchOn('XY')
|
||||||
|
|> startProfileAt([0, 0], %)
|
||||||
|
|> line([0, 50], %)
|
||||||
|
|> line([50, 0], %)
|
||||||
|
|> line([0, -50], %)
|
||||||
|
|> close(%)
|
||||||
|
|> hole(circles, %)
|
||||||
```
|
```
|
||||||
|
|
||||||
### Arguments
|
### Arguments
|
||||||
|
|
||||||
* `center`: `[number, number]` (REQUIRED)
|
* `center`: `[number]` (REQUIRED)
|
||||||
* `radius`: `number` (REQUIRED)
|
* `radius`: `number` (REQUIRED)
|
||||||
* `surface`: `SketchSurface` - A sketch group type. (REQUIRED)
|
* `tag`: `String` (OPTIONAL)
|
||||||
|
* `sketch_surface_or_group`: `SketchSurfaceOrGroup` - A sketch surface or a sketch group. (REQUIRED)
|
||||||
```js
|
```js
|
||||||
{
|
{
|
||||||
// The id of the plane.
|
// The id of the plane.
|
||||||
@ -75,9 +96,169 @@ circle(center: [number, number], radius: number, surface: SketchSurface, tag?: S
|
|||||||
y: number,
|
y: number,
|
||||||
z: number,
|
z: number,
|
||||||
},
|
},
|
||||||
|
} |
|
||||||
|
{
|
||||||
|
// The plane id or face id of the sketch group.
|
||||||
|
entityId: uuid,
|
||||||
|
// The id of the sketch group.
|
||||||
|
id: uuid,
|
||||||
|
// What the sketch is on (can be a plane or a face).
|
||||||
|
on: {
|
||||||
|
// The id of the plane.
|
||||||
|
id: uuid,
|
||||||
|
// Origin of the plane.
|
||||||
|
origin: {
|
||||||
|
x: number,
|
||||||
|
y: number,
|
||||||
|
z: number,
|
||||||
|
},
|
||||||
|
type: "plane",
|
||||||
|
// Type for a plane.
|
||||||
|
value: "XY" | "XZ" | "YZ" | "Custom",
|
||||||
|
// What should the plane’s X axis be?
|
||||||
|
xAxis: {
|
||||||
|
x: number,
|
||||||
|
y: number,
|
||||||
|
z: number,
|
||||||
|
},
|
||||||
|
// What should the plane’s Y axis be?
|
||||||
|
yAxis: {
|
||||||
|
x: number,
|
||||||
|
y: number,
|
||||||
|
z: number,
|
||||||
|
},
|
||||||
|
// The z-axis (normal).
|
||||||
|
zAxis: {
|
||||||
|
x: number,
|
||||||
|
y: number,
|
||||||
|
z: number,
|
||||||
|
},
|
||||||
|
} |
|
||||||
|
{
|
||||||
|
// The id of the face.
|
||||||
|
id: uuid,
|
||||||
|
// The original sketch group id of the object we are sketching on.
|
||||||
|
sketchGroupId: uuid,
|
||||||
|
type: "face",
|
||||||
|
// The tag of the face.
|
||||||
|
value: string,
|
||||||
|
// What should the face’s X axis be?
|
||||||
|
xAxis: {
|
||||||
|
x: number,
|
||||||
|
y: number,
|
||||||
|
z: number,
|
||||||
|
},
|
||||||
|
// What should the face’s Y axis be?
|
||||||
|
yAxis: {
|
||||||
|
x: number,
|
||||||
|
y: number,
|
||||||
|
z: number,
|
||||||
|
},
|
||||||
|
// The z-axis (normal).
|
||||||
|
zAxis: {
|
||||||
|
x: number,
|
||||||
|
y: number,
|
||||||
|
z: number,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// The position of the sketch group.
|
||||||
|
position: [number, number, number],
|
||||||
|
// The rotation of the sketch group base plane.
|
||||||
|
rotation: [number, number, number, number],
|
||||||
|
// The starting path.
|
||||||
|
start: {
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// The name of the path.
|
||||||
|
name: string,
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
},
|
||||||
|
// The paths in the sketch group.
|
||||||
|
value: [{
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// The name of the path.
|
||||||
|
name: string,
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "ToPoint",
|
||||||
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: string,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// The name of the path.
|
||||||
|
name: string,
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "TangentialArcTo",
|
||||||
|
} |
|
||||||
|
{
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// The name of the path.
|
||||||
|
name: string,
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "TangentialArc",
|
||||||
|
} |
|
||||||
|
{
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// The name of the path.
|
||||||
|
name: string,
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Horizontal",
|
||||||
|
// The x coordinate.
|
||||||
|
x: number,
|
||||||
|
} |
|
||||||
|
{
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// The name of the path.
|
||||||
|
name: string,
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "AngledLineTo",
|
||||||
|
// The x coordinate.
|
||||||
|
x: number,
|
||||||
|
// The y coordinate.
|
||||||
|
y: number,
|
||||||
|
} |
|
||||||
|
{
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// The name of the path.
|
||||||
|
name: string,
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Base",
|
||||||
|
}],
|
||||||
|
// The x-axis of the sketch group base plane in the 3D space
|
||||||
|
xAxis: {
|
||||||
|
x: number,
|
||||||
|
y: number,
|
||||||
|
z: number,
|
||||||
|
},
|
||||||
|
// The y-axis of the sketch group base plane in the 3D space
|
||||||
|
yAxis: {
|
||||||
|
x: number,
|
||||||
|
y: number,
|
||||||
|
z: number,
|
||||||
|
},
|
||||||
|
// The z-axis of the sketch group base plane in the 3D space
|
||||||
|
zAxis: {
|
||||||
|
x: number,
|
||||||
|
y: number,
|
||||||
|
z: number,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
* `tag`: `String` (OPTIONAL)
|
|
||||||
|
|
||||||
### Returns
|
### Returns
|
||||||
|
|
||||||
|
@ -21,8 +21,8 @@ const square = startSketchOn('XY')
|
|||||||
|> line([10, 0], %)
|
|> line([10, 0], %)
|
||||||
|> line([0, -10], %)
|
|> line([0, -10], %)
|
||||||
|> close(%)
|
|> close(%)
|
||||||
|> hole(circle([2, 2], .5, startSketchOn('XY')), %)
|
|> hole(circle([2, 2], .5, %), %)
|
||||||
|> hole(circle([2, 8], .5, startSketchOn('XY')), %)
|
|> hole(circle([2, 8], .5, %), %)
|
||||||
|> extrude(2, %)
|
|> extrude(2, %)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
2
src/wasm-lib/Cargo.lock
generated
2
src/wasm-lib/Cargo.lock
generated
@ -1909,7 +1909,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "kcl-lib"
|
name = "kcl-lib"
|
||||||
version = "0.1.45"
|
version = "0.1.46"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"approx 0.5.1",
|
"approx 0.5.1",
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "kcl-lib"
|
name = "kcl-lib"
|
||||||
description = "KittyCAD Language implementation and tools"
|
description = "KittyCAD Language implementation and tools"
|
||||||
version = "0.1.45"
|
version = "0.1.46"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
repository = "https://github.com/KittyCAD/modeling-app"
|
repository = "https://github.com/KittyCAD/modeling-app"
|
||||||
|
@ -49,6 +49,7 @@ lazy_static! {
|
|||||||
Box::new(crate::std::segment::SegAng),
|
Box::new(crate::std::segment::SegAng),
|
||||||
Box::new(crate::std::segment::AngleToMatchLengthX),
|
Box::new(crate::std::segment::AngleToMatchLengthX),
|
||||||
Box::new(crate::std::segment::AngleToMatchLengthY),
|
Box::new(crate::std::segment::AngleToMatchLengthY),
|
||||||
|
Box::new(crate::std::shapes::Circle),
|
||||||
Box::new(crate::std::sketch::LineTo),
|
Box::new(crate::std::sketch::LineTo),
|
||||||
Box::new(crate::std::sketch::Line),
|
Box::new(crate::std::sketch::Line),
|
||||||
Box::new(crate::std::sketch::XLineTo),
|
Box::new(crate::std::sketch::XLineTo),
|
||||||
@ -130,7 +131,7 @@ impl StdLib {
|
|||||||
.map(|internal_fn| (internal_fn.name(), internal_fn))
|
.map(|internal_fn| (internal_fn.name(), internal_fn))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let kcl_internal_fns: [Box<dyn KclStdLibFn>; 1] = [Box::<shapes::Circle>::default()];
|
let kcl_internal_fns: [Box<dyn KclStdLibFn>; 0] = [];
|
||||||
let kcl_fns = kcl_internal_fns
|
let kcl_fns = kcl_internal_fns
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|internal_fn| (internal_fn.name(), internal_fn))
|
.map(|internal_fn| (internal_fn.name(), internal_fn))
|
||||||
@ -265,6 +266,103 @@ impl Args {
|
|||||||
Ok((numbers[0], numbers[1]))
|
Ok((numbers[0], numbers[1]))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_circle_args(
|
||||||
|
&self,
|
||||||
|
) -> Result<([f64; 2], f64, crate::std::shapes::SketchSurfaceOrGroup, Option<String>), KclError> {
|
||||||
|
let first_value = self
|
||||||
|
.args
|
||||||
|
.first()
|
||||||
|
.ok_or_else(|| {
|
||||||
|
KclError::Type(KclErrorDetails {
|
||||||
|
message: format!(
|
||||||
|
"Expected a [number, number] as the first argument, found `{:?}`",
|
||||||
|
self.args
|
||||||
|
),
|
||||||
|
source_ranges: vec![self.source_range],
|
||||||
|
})
|
||||||
|
})?
|
||||||
|
.get_json_value()?;
|
||||||
|
|
||||||
|
let center: [f64; 2] = if let serde_json::Value::Array(arr) = first_value {
|
||||||
|
if arr.len() != 2 {
|
||||||
|
return Err(KclError::Type(KclErrorDetails {
|
||||||
|
message: format!(
|
||||||
|
"Expected a [number, number] as the first argument, found `{:?}`",
|
||||||
|
self.args
|
||||||
|
),
|
||||||
|
source_ranges: vec![self.source_range],
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
let x = parse_json_number_as_f64(&arr[0], self.source_range)?;
|
||||||
|
let y = parse_json_number_as_f64(&arr[1], self.source_range)?;
|
||||||
|
[x, y]
|
||||||
|
} else {
|
||||||
|
return Err(KclError::Type(KclErrorDetails {
|
||||||
|
message: format!(
|
||||||
|
"Expected a [number, number] as the first argument, found `{:?}`",
|
||||||
|
self.args
|
||||||
|
),
|
||||||
|
source_ranges: vec![self.source_range],
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
|
let second_value = self
|
||||||
|
.args
|
||||||
|
.get(1)
|
||||||
|
.ok_or_else(|| {
|
||||||
|
KclError::Type(KclErrorDetails {
|
||||||
|
message: format!("Expected a number as the second argument, found `{:?}`", self.args),
|
||||||
|
source_ranges: vec![self.source_range],
|
||||||
|
})
|
||||||
|
})?
|
||||||
|
.get_json_value()?;
|
||||||
|
|
||||||
|
let radius: f64 = serde_json::from_value(second_value).map_err(|e| {
|
||||||
|
KclError::Type(KclErrorDetails {
|
||||||
|
message: format!("Failed to deserialize number from JSON: {}", e),
|
||||||
|
source_ranges: vec![self.source_range],
|
||||||
|
})
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let third_value = self.args.get(2).ok_or_else(|| {
|
||||||
|
KclError::Type(KclErrorDetails {
|
||||||
|
message: format!(
|
||||||
|
"Expected a SketchGroup or SketchSurface as the third argument, found `{:?}`",
|
||||||
|
self.args
|
||||||
|
),
|
||||||
|
source_ranges: vec![self.source_range],
|
||||||
|
})
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let sketch_group_or_surface = if let MemoryItem::SketchGroup(sg) = third_value {
|
||||||
|
crate::std::shapes::SketchSurfaceOrGroup::SketchGroup(sg.clone())
|
||||||
|
} else if let MemoryItem::Plane(sg) = third_value {
|
||||||
|
crate::std::shapes::SketchSurfaceOrGroup::SketchSurface(SketchSurface::Plane(sg.clone()))
|
||||||
|
} else if let MemoryItem::Face(sg) = third_value {
|
||||||
|
crate::std::shapes::SketchSurfaceOrGroup::SketchSurface(SketchSurface::Face(sg.clone()))
|
||||||
|
} else {
|
||||||
|
return Err(KclError::Type(KclErrorDetails {
|
||||||
|
message: format!(
|
||||||
|
"Expected a SketchGroup or SketchSurface as the third argument, found `{:?}`",
|
||||||
|
self.args
|
||||||
|
),
|
||||||
|
source_ranges: vec![self.source_range],
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(fourth_value) = self.args.get(3) {
|
||||||
|
let tag: String = serde_json::from_value(fourth_value.get_json_value()?).map_err(|e| {
|
||||||
|
KclError::Type(KclErrorDetails {
|
||||||
|
message: format!("Failed to deserialize String from JSON: {}", e),
|
||||||
|
source_ranges: vec![self.source_range],
|
||||||
|
})
|
||||||
|
})?;
|
||||||
|
Ok((center, radius, sketch_group_or_surface, Some(tag)))
|
||||||
|
} else {
|
||||||
|
Ok((center, radius, sketch_group_or_surface, None))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn get_segment_name_sketch_group(&self) -> Result<(String, Box<SketchGroup>), KclError> {
|
fn get_segment_name_sketch_group(&self) -> Result<(String, Box<SketchGroup>), KclError> {
|
||||||
// Iterate over our args, the first argument should be a UserVal with a string value.
|
// Iterate over our args, the first argument should be a UserVal with a string value.
|
||||||
// The second argument should be a SketchGroup.
|
// The second argument should be a SketchGroup.
|
||||||
|
@ -1,155 +1,83 @@
|
|||||||
|
//! Standard library shapes.
|
||||||
|
|
||||||
|
use anyhow::Result;
|
||||||
|
use derive_docs::stdlib;
|
||||||
use schemars::JsonSchema;
|
use schemars::JsonSchema;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use super::kcl_stdlib::KclStdLibFn;
|
|
||||||
use crate::{
|
use crate::{
|
||||||
ast::types::{FunctionExpression, Program},
|
errors::KclError,
|
||||||
docs::StdLibFn,
|
executor::MemoryItem,
|
||||||
|
std::{Args, SketchGroup, SketchSurface},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const CIRCLE_FN: &str = r#"
|
/// A sketch surface or a sketch group.
|
||||||
(center, radius, surface, tag?) => {
|
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
|
||||||
const sg = startProfileAt([center[0] + radius, center[1]], surface)
|
#[ts(export)]
|
||||||
|> arc({
|
#[serde(untagged)]
|
||||||
angle_end: 360,
|
pub enum SketchSurfaceOrGroup {
|
||||||
angle_start: 0,
|
SketchSurface(SketchSurface),
|
||||||
radius: radius,
|
SketchGroup(Box<SketchGroup>),
|
||||||
tag: tag
|
|
||||||
}, %)
|
|
||||||
|> close(%)
|
|
||||||
return sg
|
|
||||||
}
|
|
||||||
"#;
|
|
||||||
|
|
||||||
#[derive(Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
|
|
||||||
pub struct Circle {
|
|
||||||
function: FunctionExpression,
|
|
||||||
program: Program,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Circle {
|
/// Sketch a circle.
|
||||||
fn default() -> Self {
|
pub async fn circle(args: Args) -> Result<MemoryItem, KclError> {
|
||||||
// TODO in https://github.com/KittyCAD/modeling-app/issues/1018
|
let (center, radius, sketch_surface_or_group, tag): ([f64; 2], f64, SketchSurfaceOrGroup, Option<String>) =
|
||||||
// Don't unwrap here, parse it at compile-time.
|
args.get_circle_args()?;
|
||||||
let (src, function) = super::kcl_stdlib::extract_function(CIRCLE_FN).unwrap();
|
|
||||||
Self {
|
let sketch_group = inner_circle(center, radius, tag, sketch_surface_or_group, args).await?;
|
||||||
function: *function,
|
Ok(MemoryItem::SketchGroup(sketch_group))
|
||||||
program: src,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::fmt::Debug for Circle {
|
/// Sketch a circle.
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
///
|
||||||
"circle".fmt(f)
|
/// ```no_run
|
||||||
}
|
/// const circles = startSketchOn('XY')
|
||||||
}
|
/// |> circle([5, 5], 1, %)
|
||||||
|
/// |> patternLinear2d({axis: [1,1], repetitions: 12, distance: 3}, %)
|
||||||
/// TODO: Parse the KCL in a macro and generate these
|
///
|
||||||
impl StdLibFn for Circle {
|
/// const rectangle = startSketchOn('XY')
|
||||||
fn name(&self) -> String {
|
/// |> startProfileAt([0, 0], %)
|
||||||
"circle".to_owned()
|
/// |> line([0, 50], %)
|
||||||
}
|
/// |> line([50, 0], %)
|
||||||
|
/// |> line([0, -50], %)
|
||||||
fn summary(&self) -> String {
|
/// |> close(%)
|
||||||
"Sketch a circle on the given plane".to_owned()
|
/// |> hole(circles, %)
|
||||||
}
|
/// ```
|
||||||
|
#[stdlib {
|
||||||
fn description(&self) -> String {
|
name = "circle",
|
||||||
String::new()
|
}]
|
||||||
}
|
async fn inner_circle(
|
||||||
|
center: [f64; 2],
|
||||||
fn tags(&self) -> Vec<String> {
|
radius: f64,
|
||||||
Vec::new()
|
tag: Option<String>,
|
||||||
}
|
sketch_surface_or_group: SketchSurfaceOrGroup,
|
||||||
|
args: Args,
|
||||||
fn args(&self) -> Vec<crate::docs::StdLibFnArg> {
|
) -> Result<Box<SketchGroup>, KclError> {
|
||||||
let mut settings = schemars::gen::SchemaSettings::openapi3();
|
let sketch_surface = match sketch_surface_or_group {
|
||||||
settings.inline_subschemas = true;
|
SketchSurfaceOrGroup::SketchSurface(surface) => surface,
|
||||||
let mut generator = schemars::gen::SchemaGenerator::new(settings);
|
SketchSurfaceOrGroup::SketchGroup(group) => group.on,
|
||||||
let mut args = Vec::new();
|
};
|
||||||
for parameter in &self.function.params {
|
let mut sketch_group = crate::std::sketch::inner_start_profile_at(
|
||||||
match parameter.identifier.name.as_str() {
|
crate::std::sketch::LineData::Point([center[0] + radius, center[1]]),
|
||||||
"center" => {
|
sketch_surface,
|
||||||
args.push(crate::docs::StdLibFnArg {
|
args.clone(),
|
||||||
name: parameter.identifier.name.to_owned(),
|
)
|
||||||
type_: "[number, number]".to_string(),
|
.await?;
|
||||||
schema: <[f64; 2]>::json_schema(&mut generator),
|
|
||||||
required: true,
|
// Call arc.
|
||||||
});
|
sketch_group = crate::std::sketch::inner_arc(
|
||||||
}
|
crate::std::sketch::ArcData::AnglesAndRadius {
|
||||||
"radius" => {
|
angle_start: 0.0,
|
||||||
args.push(crate::docs::StdLibFnArg {
|
angle_end: 360.0,
|
||||||
name: parameter.identifier.name.to_owned(),
|
radius,
|
||||||
type_: "number".to_string(),
|
tag,
|
||||||
schema: <f64>::json_schema(&mut generator),
|
},
|
||||||
required: true,
|
sketch_group,
|
||||||
});
|
args.clone(),
|
||||||
}
|
)
|
||||||
"surface" => {
|
.await?;
|
||||||
args.push(crate::docs::StdLibFnArg {
|
|
||||||
name: parameter.identifier.name.to_owned(),
|
// Call close.
|
||||||
type_: "SketchSurface".to_string(),
|
crate::std::sketch::inner_close(sketch_group, None, args).await
|
||||||
schema: <crate::executor::SketchSurface>::json_schema(&mut generator),
|
|
||||||
required: true,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
"tag" => {
|
|
||||||
args.push(crate::docs::StdLibFnArg {
|
|
||||||
name: parameter.identifier.name.to_owned(),
|
|
||||||
type_: "String".to_string(),
|
|
||||||
schema: <String>::json_schema(&mut generator),
|
|
||||||
required: false,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
_ => panic!("Unknown parameter: {:?}", parameter.identifier.name),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
args
|
|
||||||
}
|
|
||||||
|
|
||||||
fn return_value(&self) -> Option<crate::docs::StdLibFnArg> {
|
|
||||||
let mut settings = schemars::gen::SchemaSettings::openapi3();
|
|
||||||
settings.inline_subschemas = true;
|
|
||||||
let mut generator = schemars::gen::SchemaGenerator::new(settings);
|
|
||||||
Some(crate::docs::StdLibFnArg {
|
|
||||||
name: "SketchGroup".to_owned(),
|
|
||||||
type_: "SketchGroup".to_string(),
|
|
||||||
schema: <crate::executor::SketchGroup>::json_schema(&mut generator),
|
|
||||||
required: true,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn unpublished(&self) -> bool {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
fn deprecated(&self) -> bool {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
fn examples(&self) -> Vec<String> {
|
|
||||||
vec![]
|
|
||||||
}
|
|
||||||
|
|
||||||
fn std_lib_fn(&self) -> crate::std::StdFn {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn clone_box(&self) -> Box<dyn StdLibFn> {
|
|
||||||
Box::new(self.to_owned())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl KclStdLibFn for Circle {
|
|
||||||
fn function(&self) -> &FunctionExpression {
|
|
||||||
&self.function
|
|
||||||
}
|
|
||||||
fn program(&self) -> &Program {
|
|
||||||
&self.program
|
|
||||||
}
|
|
||||||
|
|
||||||
fn kcl_clone_box(&self) -> Box<dyn KclStdLibFn> {
|
|
||||||
Box::new(self.clone())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1220,7 +1220,7 @@ pub async fn start_profile_at(args: Args) -> Result<MemoryItem, KclError> {
|
|||||||
#[stdlib {
|
#[stdlib {
|
||||||
name = "startProfileAt",
|
name = "startProfileAt",
|
||||||
}]
|
}]
|
||||||
async fn inner_start_profile_at(
|
pub(crate) async fn inner_start_profile_at(
|
||||||
data: LineData,
|
data: LineData,
|
||||||
sketch_surface: SketchSurface,
|
sketch_surface: SketchSurface,
|
||||||
args: Args,
|
args: Args,
|
||||||
@ -1306,7 +1306,7 @@ pub async fn close(args: Args) -> Result<MemoryItem, KclError> {
|
|||||||
#[stdlib {
|
#[stdlib {
|
||||||
name = "close",
|
name = "close",
|
||||||
}]
|
}]
|
||||||
async fn inner_close(
|
pub(crate) async fn inner_close(
|
||||||
sketch_group: Box<SketchGroup>,
|
sketch_group: Box<SketchGroup>,
|
||||||
tag: Option<String>,
|
tag: Option<String>,
|
||||||
args: Args,
|
args: Args,
|
||||||
@ -1402,7 +1402,11 @@ pub async fn arc(args: Args) -> Result<MemoryItem, KclError> {
|
|||||||
#[stdlib {
|
#[stdlib {
|
||||||
name = "arc",
|
name = "arc",
|
||||||
}]
|
}]
|
||||||
async fn inner_arc(data: ArcData, sketch_group: Box<SketchGroup>, args: Args) -> Result<Box<SketchGroup>, KclError> {
|
pub(crate) async fn inner_arc(
|
||||||
|
data: ArcData,
|
||||||
|
sketch_group: Box<SketchGroup>,
|
||||||
|
args: Args,
|
||||||
|
) -> Result<Box<SketchGroup>, KclError> {
|
||||||
let from: Point2d = sketch_group.get_coords_from_paths()?;
|
let from: Point2d = sketch_group.get_coords_from_paths()?;
|
||||||
|
|
||||||
let (center, angle_start, angle_end, radius, end) = match &data {
|
let (center, angle_start, angle_end, radius, end) = match &data {
|
||||||
@ -1790,8 +1794,8 @@ pub async fn hole(args: Args) -> Result<MemoryItem, KclError> {
|
|||||||
/// |> line([10, 0], %)
|
/// |> line([10, 0], %)
|
||||||
/// |> line([0, -10], %)
|
/// |> line([0, -10], %)
|
||||||
/// |> close(%)
|
/// |> close(%)
|
||||||
/// |> hole(circle([2, 2], .5, startSketchOn('XY')), %)
|
/// |> hole(circle([2, 2], .5, %), %)
|
||||||
/// |> hole(circle([2, 8], .5, startSketchOn('XY')), %)
|
/// |> hole(circle([2, 8], .5, %), %)
|
||||||
/// |> extrude(2, %)
|
/// |> extrude(2, %)
|
||||||
/// ```
|
/// ```
|
||||||
#[stdlib {
|
#[stdlib {
|
||||||
|
@ -731,8 +731,8 @@ async fn serial_test_holes() {
|
|||||||
|> line([10, 0], %)
|
|> line([10, 0], %)
|
||||||
|> line([0, -10], %)
|
|> line([0, -10], %)
|
||||||
|> close(%)
|
|> close(%)
|
||||||
|> hole(circle([2, 2], .5, startSketchOn('XY')), %)
|
|> hole(circle([2, 2], .5, %), %)
|
||||||
|> hole(circle([2, 8], .5, startSketchOn('XY')), %)
|
|> hole(circle([2, 8], .5, %), %)
|
||||||
|> extrude(2, %)
|
|> extrude(2, %)
|
||||||
"#;
|
"#;
|
||||||
|
|
||||||
@ -787,10 +787,10 @@ const holeRadius = 1
|
|||||||
const holeIndex = 6
|
const holeIndex = 6
|
||||||
|
|
||||||
const part = roundedRectangle([0, 0], 20, 20, 4)
|
const part = roundedRectangle([0, 0], 20, 20, 4)
|
||||||
|> hole(circle([-holeIndex, holeIndex], holeRadius, startSketchOn('XY')), %)
|
|> hole(circle([-holeIndex, holeIndex], holeRadius, %), %)
|
||||||
|> hole(circle([holeIndex, holeIndex], holeRadius, startSketchOn('XY')), %)
|
|> hole(circle([holeIndex, holeIndex], holeRadius, %), %)
|
||||||
|> hole(circle([-holeIndex, -holeIndex], holeRadius, startSketchOn('XY')), %)
|
|> hole(circle([-holeIndex, -holeIndex], holeRadius, %), %)
|
||||||
|> hole(circle([holeIndex, -holeIndex], holeRadius, startSketchOn('XY')), %)
|
|> hole(circle([holeIndex, -holeIndex], holeRadius, %), %)
|
||||||
|> extrude(2, %)
|
|> extrude(2, %)
|
||||||
"#;
|
"#;
|
||||||
|
|
||||||
@ -802,7 +802,7 @@ const part = roundedRectangle([0, 0], 20, 20, 4)
|
|||||||
|
|
||||||
#[tokio::test(flavor = "multi_thread")]
|
#[tokio::test(flavor = "multi_thread")]
|
||||||
async fn serial_test_top_level_expression() {
|
async fn serial_test_top_level_expression() {
|
||||||
let code = r#"circle([0,0], 22, startSketchOn('XY')) |> extrude(14, %)"#;
|
let code = r#"startSketchOn('XY') |> circle([0,0], 22, %) |> extrude(14, %)"#;
|
||||||
|
|
||||||
let result = execute_and_snapshot(code, kittycad::types::UnitLength::Mm)
|
let result = execute_and_snapshot(code, kittycad::types::UnitLength::Mm)
|
||||||
.await
|
.await
|
||||||
@ -1252,7 +1252,7 @@ async fn serial_test_stdlib_kcl_error_right_code_path() {
|
|||||||
|> line([0, -10], %)
|
|> line([0, -10], %)
|
||||||
|> close(%)
|
|> close(%)
|
||||||
|> hole(circle([2, 2], .5), %)
|
|> hole(circle([2, 2], .5), %)
|
||||||
|> hole(circle([2, 8], .5, startSketchOn('XY')), %)
|
|> hole(circle([2, 8], .5, %), %)
|
||||||
|> extrude(2, %)
|
|> extrude(2, %)
|
||||||
"#;
|
"#;
|
||||||
|
|
||||||
@ -1260,7 +1260,7 @@ async fn serial_test_stdlib_kcl_error_right_code_path() {
|
|||||||
assert!(result.is_err());
|
assert!(result.is_err());
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
result.err().unwrap().to_string(),
|
result.err().unwrap().to_string(),
|
||||||
r#"semantic: KclErrorDetails { source_ranges: [SourceRange([157, 175])], message: "this function expected 3 arguments, got 2" }"#
|
r#"type: KclErrorDetails { source_ranges: [SourceRange([157, 175])], message: "Expected a SketchGroup or SketchSurface as the third argument, found `[UserVal(UserVal { value: Array [Number(2), Number(2)], meta: [Metadata { source_range: SourceRange([164, 170]) }] }), UserVal(UserVal { value: Number(0.5), meta: [Metadata { source_range: SourceRange([172, 174]) }] })]`" }"#
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1367,6 +1367,6 @@ const part = rectShape([0, 0], 20, 20)
|
|||||||
assert!(result.is_err());
|
assert!(result.is_err());
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
result.err().unwrap().to_string(),
|
result.err().unwrap().to_string(),
|
||||||
r#"semantic: KclErrorDetails { source_ranges: [SourceRange([987, 1036])], message: "MemberExpression array is not an array: UserVal(UserVal { value: String(\"XY\"), meta: [Metadata { source_range: SourceRange([994, 998]) }] })" }"#
|
r#"type: KclErrorDetails { source_ranges: [SourceRange([987, 1036])], message: "Expected a [number, number] as the first argument, found `[UserVal(UserVal { value: String(\"XY\"), meta: [Metadata { source_range: SourceRange([994, 998]) }] }), UserVal(UserVal { value: Array [Number(-6.0), Number(6)], meta: [Metadata { source_range: SourceRange([1000, 1023]) }] }), UserVal(UserVal { value: Number(1), meta: [Metadata { source_range: SourceRange([856, 857]) }] })]`" }"#
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user