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"
|
||||
excerpt: "Sketch a circle on the given plane"
|
||||
excerpt: "Sketch a circle."
|
||||
layout: manual
|
||||
---
|
||||
|
||||
Sketch a circle on the given plane
|
||||
Sketch a circle.
|
||||
|
||||
|
||||
|
||||
```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
|
||||
|
||||
* `center`: `[number, number]` (REQUIRED)
|
||||
* `center`: `[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
|
||||
{
|
||||
// The id of the plane.
|
||||
@ -75,9 +96,169 @@ circle(center: [number, number], radius: number, surface: SketchSurface, tag?: S
|
||||
y: 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
|
||||
|
||||
|
@ -21,8 +21,8 @@ const square = startSketchOn('XY')
|
||||
|> line([10, 0], %)
|
||||
|> line([0, -10], %)
|
||||
|> close(%)
|
||||
|> hole(circle([2, 2], .5, startSketchOn('XY')), %)
|
||||
|> hole(circle([2, 8], .5, startSketchOn('XY')), %)
|
||||
|> hole(circle([2, 2], .5, %), %)
|
||||
|> hole(circle([2, 8], .5, %), %)
|
||||
|> 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]]
|
||||
name = "kcl-lib"
|
||||
version = "0.1.45"
|
||||
version = "0.1.46"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"approx 0.5.1",
|
||||
|
@ -1,7 +1,7 @@
|
||||
[package]
|
||||
name = "kcl-lib"
|
||||
description = "KittyCAD Language implementation and tools"
|
||||
version = "0.1.45"
|
||||
version = "0.1.46"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
repository = "https://github.com/KittyCAD/modeling-app"
|
||||
|
@ -49,6 +49,7 @@ lazy_static! {
|
||||
Box::new(crate::std::segment::SegAng),
|
||||
Box::new(crate::std::segment::AngleToMatchLengthX),
|
||||
Box::new(crate::std::segment::AngleToMatchLengthY),
|
||||
Box::new(crate::std::shapes::Circle),
|
||||
Box::new(crate::std::sketch::LineTo),
|
||||
Box::new(crate::std::sketch::Line),
|
||||
Box::new(crate::std::sketch::XLineTo),
|
||||
@ -130,7 +131,7 @@ impl StdLib {
|
||||
.map(|internal_fn| (internal_fn.name(), internal_fn))
|
||||
.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
|
||||
.into_iter()
|
||||
.map(|internal_fn| (internal_fn.name(), internal_fn))
|
||||
@ -265,6 +266,103 @@ impl Args {
|
||||
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> {
|
||||
// Iterate over our args, the first argument should be a UserVal with a string value.
|
||||
// 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 serde::{Deserialize, Serialize};
|
||||
|
||||
use super::kcl_stdlib::KclStdLibFn;
|
||||
use crate::{
|
||||
ast::types::{FunctionExpression, Program},
|
||||
docs::StdLibFn,
|
||||
errors::KclError,
|
||||
executor::MemoryItem,
|
||||
std::{Args, SketchGroup, SketchSurface},
|
||||
};
|
||||
|
||||
pub const CIRCLE_FN: &str = r#"
|
||||
(center, radius, surface, tag?) => {
|
||||
const sg = startProfileAt([center[0] + radius, center[1]], surface)
|
||||
|> arc({
|
||||
angle_end: 360,
|
||||
angle_start: 0,
|
||||
radius: radius,
|
||||
tag: tag
|
||||
}, %)
|
||||
|> close(%)
|
||||
return sg
|
||||
}
|
||||
"#;
|
||||
|
||||
#[derive(Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
|
||||
pub struct Circle {
|
||||
function: FunctionExpression,
|
||||
program: Program,
|
||||
/// A sketch surface or a sketch group.
|
||||
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
|
||||
#[ts(export)]
|
||||
#[serde(untagged)]
|
||||
pub enum SketchSurfaceOrGroup {
|
||||
SketchSurface(SketchSurface),
|
||||
SketchGroup(Box<SketchGroup>),
|
||||
}
|
||||
|
||||
impl Default for Circle {
|
||||
fn default() -> Self {
|
||||
// TODO in https://github.com/KittyCAD/modeling-app/issues/1018
|
||||
// Don't unwrap here, parse it at compile-time.
|
||||
let (src, function) = super::kcl_stdlib::extract_function(CIRCLE_FN).unwrap();
|
||||
Self {
|
||||
function: *function,
|
||||
program: src,
|
||||
}
|
||||
}
|
||||
/// Sketch a circle.
|
||||
pub async fn circle(args: Args) -> Result<MemoryItem, KclError> {
|
||||
let (center, radius, sketch_surface_or_group, tag): ([f64; 2], f64, SketchSurfaceOrGroup, Option<String>) =
|
||||
args.get_circle_args()?;
|
||||
|
||||
let sketch_group = inner_circle(center, radius, tag, sketch_surface_or_group, args).await?;
|
||||
Ok(MemoryItem::SketchGroup(sketch_group))
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for Circle {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
"circle".fmt(f)
|
||||
}
|
||||
}
|
||||
/// Sketch a circle.
|
||||
///
|
||||
/// ```no_run
|
||||
/// 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, %)
|
||||
/// ```
|
||||
#[stdlib {
|
||||
name = "circle",
|
||||
}]
|
||||
async fn inner_circle(
|
||||
center: [f64; 2],
|
||||
radius: f64,
|
||||
tag: Option<String>,
|
||||
sketch_surface_or_group: SketchSurfaceOrGroup,
|
||||
args: Args,
|
||||
) -> Result<Box<SketchGroup>, KclError> {
|
||||
let sketch_surface = match sketch_surface_or_group {
|
||||
SketchSurfaceOrGroup::SketchSurface(surface) => surface,
|
||||
SketchSurfaceOrGroup::SketchGroup(group) => group.on,
|
||||
};
|
||||
let mut sketch_group = crate::std::sketch::inner_start_profile_at(
|
||||
crate::std::sketch::LineData::Point([center[0] + radius, center[1]]),
|
||||
sketch_surface,
|
||||
args.clone(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
/// TODO: Parse the KCL in a macro and generate these
|
||||
impl StdLibFn for Circle {
|
||||
fn name(&self) -> String {
|
||||
"circle".to_owned()
|
||||
}
|
||||
// Call arc.
|
||||
sketch_group = crate::std::sketch::inner_arc(
|
||||
crate::std::sketch::ArcData::AnglesAndRadius {
|
||||
angle_start: 0.0,
|
||||
angle_end: 360.0,
|
||||
radius,
|
||||
tag,
|
||||
},
|
||||
sketch_group,
|
||||
args.clone(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
fn summary(&self) -> String {
|
||||
"Sketch a circle on the given plane".to_owned()
|
||||
}
|
||||
|
||||
fn description(&self) -> String {
|
||||
String::new()
|
||||
}
|
||||
|
||||
fn tags(&self) -> Vec<String> {
|
||||
Vec::new()
|
||||
}
|
||||
|
||||
fn args(&self) -> Vec<crate::docs::StdLibFnArg> {
|
||||
let mut settings = schemars::gen::SchemaSettings::openapi3();
|
||||
settings.inline_subschemas = true;
|
||||
let mut generator = schemars::gen::SchemaGenerator::new(settings);
|
||||
let mut args = Vec::new();
|
||||
for parameter in &self.function.params {
|
||||
match parameter.identifier.name.as_str() {
|
||||
"center" => {
|
||||
args.push(crate::docs::StdLibFnArg {
|
||||
name: parameter.identifier.name.to_owned(),
|
||||
type_: "[number, number]".to_string(),
|
||||
schema: <[f64; 2]>::json_schema(&mut generator),
|
||||
required: true,
|
||||
});
|
||||
}
|
||||
"radius" => {
|
||||
args.push(crate::docs::StdLibFnArg {
|
||||
name: parameter.identifier.name.to_owned(),
|
||||
type_: "number".to_string(),
|
||||
schema: <f64>::json_schema(&mut generator),
|
||||
required: true,
|
||||
});
|
||||
}
|
||||
"surface" => {
|
||||
args.push(crate::docs::StdLibFnArg {
|
||||
name: parameter.identifier.name.to_owned(),
|
||||
type_: "SketchSurface".to_string(),
|
||||
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())
|
||||
}
|
||||
// Call close.
|
||||
crate::std::sketch::inner_close(sketch_group, None, args).await
|
||||
}
|
||||
|
@ -1220,7 +1220,7 @@ pub async fn start_profile_at(args: Args) -> Result<MemoryItem, KclError> {
|
||||
#[stdlib {
|
||||
name = "startProfileAt",
|
||||
}]
|
||||
async fn inner_start_profile_at(
|
||||
pub(crate) async fn inner_start_profile_at(
|
||||
data: LineData,
|
||||
sketch_surface: SketchSurface,
|
||||
args: Args,
|
||||
@ -1306,7 +1306,7 @@ pub async fn close(args: Args) -> Result<MemoryItem, KclError> {
|
||||
#[stdlib {
|
||||
name = "close",
|
||||
}]
|
||||
async fn inner_close(
|
||||
pub(crate) async fn inner_close(
|
||||
sketch_group: Box<SketchGroup>,
|
||||
tag: Option<String>,
|
||||
args: Args,
|
||||
@ -1402,7 +1402,11 @@ pub async fn arc(args: Args) -> Result<MemoryItem, KclError> {
|
||||
#[stdlib {
|
||||
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 (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([0, -10], %)
|
||||
/// |> close(%)
|
||||
/// |> hole(circle([2, 2], .5, startSketchOn('XY')), %)
|
||||
/// |> hole(circle([2, 8], .5, startSketchOn('XY')), %)
|
||||
/// |> hole(circle([2, 2], .5, %), %)
|
||||
/// |> hole(circle([2, 8], .5, %), %)
|
||||
/// |> extrude(2, %)
|
||||
/// ```
|
||||
#[stdlib {
|
||||
|
@ -731,8 +731,8 @@ async fn serial_test_holes() {
|
||||
|> line([10, 0], %)
|
||||
|> line([0, -10], %)
|
||||
|> close(%)
|
||||
|> hole(circle([2, 2], .5, startSketchOn('XY')), %)
|
||||
|> hole(circle([2, 8], .5, startSketchOn('XY')), %)
|
||||
|> hole(circle([2, 2], .5, %), %)
|
||||
|> hole(circle([2, 8], .5, %), %)
|
||||
|> extrude(2, %)
|
||||
"#;
|
||||
|
||||
@ -787,10 +787,10 @@ const holeRadius = 1
|
||||
const holeIndex = 6
|
||||
|
||||
const part = roundedRectangle([0, 0], 20, 20, 4)
|
||||
|> hole(circle([-holeIndex, holeIndex], holeRadius, startSketchOn('XY')), %)
|
||||
|> hole(circle([holeIndex, holeIndex], holeRadius, startSketchOn('XY')), %)
|
||||
|> hole(circle([-holeIndex, -holeIndex], holeRadius, startSketchOn('XY')), %)
|
||||
|> hole(circle([holeIndex, -holeIndex], holeRadius, startSketchOn('XY')), %)
|
||||
|> hole(circle([-holeIndex, holeIndex], holeRadius, %), %)
|
||||
|> hole(circle([holeIndex, holeIndex], holeRadius, %), %)
|
||||
|> hole(circle([-holeIndex, -holeIndex], holeRadius, %), %)
|
||||
|> hole(circle([holeIndex, -holeIndex], holeRadius, %), %)
|
||||
|> extrude(2, %)
|
||||
"#;
|
||||
|
||||
@ -802,7 +802,7 @@ const part = roundedRectangle([0, 0], 20, 20, 4)
|
||||
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
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)
|
||||
.await
|
||||
@ -1252,7 +1252,7 @@ async fn serial_test_stdlib_kcl_error_right_code_path() {
|
||||
|> line([0, -10], %)
|
||||
|> close(%)
|
||||
|> hole(circle([2, 2], .5), %)
|
||||
|> hole(circle([2, 8], .5, startSketchOn('XY')), %)
|
||||
|> hole(circle([2, 8], .5, %), %)
|
||||
|> extrude(2, %)
|
||||
"#;
|
||||
|
||||
@ -1260,7 +1260,7 @@ async fn serial_test_stdlib_kcl_error_right_code_path() {
|
||||
assert!(result.is_err());
|
||||
assert_eq!(
|
||||
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_eq!(
|
||||
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