* add helix

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)

* updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* u[pdates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* fixes for camera and batch

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* fix;

Signed-off-by: Jess Frazelle <github@jessfraz.com>

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
This commit is contained in:
Jess Frazelle
2024-03-25 17:07:53 -07:00
committed by GitHub
parent d8cc57b843
commit 0025349e9a
23 changed files with 4675 additions and 2 deletions

306
docs/kcl/helix.md Normal file
View File

@ -0,0 +1,306 @@
---
title: "helix"
excerpt: "Create a helix on a cylinder."
layout: manual
---
Create a helix on a cylinder.
```js
helix(data: HelixData, extrude_group: ExtrudeGroup) -> ExtrudeGroup
```
### Examples
```js
const part001 = startSketchOn('XY')
|> circle([5, 5], 10, %)
|> extrude(10, %)
|> helix({ revolutions: 16, angle_start: 0 }, %)
```
### Arguments
* `data`: `HelixData` - Data for helices. (REQUIRED)
```js
{
// Start angle (in degrees).
angle_start: number,
// Is the helix rotation counter clockwise? The default is `false`.
ccw: string,
// Length of the helix. If this argument is not provided, the height of the extrude group is used.
length: number,
// Number of revolutions.
revolutions: number,
}
```
* `extrude_group`: `ExtrudeGroup` - An extrude group is a collection of extrude surfaces. (REQUIRED)
```js
{
// The id of the extrusion end cap
endCapId: uuid,
// The height of the extrude group.
height: number,
// The id of the extrude group.
id: uuid,
// The position of the extrude group.
position: [number, number, number],
// The rotation of the extrude group.
rotation: [number, number, number, number],
// The sketch group paths.
sketchGroupValues: [{
// 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 id of the extrusion start cap
startCapId: uuid,
// The extrude surfaces.
value: [{
// The face id for the extrude plane.
faceId: uuid,
// The id of the geometry.
id: uuid,
// The name.
name: string,
// The position.
position: [number, number, number],
// The rotation.
rotation: [number, number, number, number],
// The source range.
sourceRange: [number, number],
type: "extrudePlane",
} |
{
// The face id for the extrude plane.
faceId: uuid,
// The id of the geometry.
id: uuid,
// The name.
name: string,
// The position.
position: [number, number, number],
// The rotation.
rotation: [number, number, number, number],
// The source range.
sourceRange: [number, number],
type: "extrudeArc",
}],
// The x-axis of the extrude group base plane in the 3D space
xAxis: {
x: number,
y: number,
z: number,
},
// The y-axis of the extrude group base plane in the 3D space
yAxis: {
x: number,
y: number,
z: number,
},
// The z-axis of the extrude group base plane in the 3D space
zAxis: {
x: number,
y: number,
z: number,
},
}
```
### Returns
`ExtrudeGroup` - An extrude group is a collection of extrude surfaces.
```js
{
// The id of the extrusion end cap
endCapId: uuid,
// The height of the extrude group.
height: number,
// The id of the extrude group.
id: uuid,
// The position of the extrude group.
position: [number, number, number],
// The rotation of the extrude group.
rotation: [number, number, number, number],
// The sketch group paths.
sketchGroupValues: [{
// 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 id of the extrusion start cap
startCapId: uuid,
// The extrude surfaces.
value: [{
// The face id for the extrude plane.
faceId: uuid,
// The id of the geometry.
id: uuid,
// The name.
name: string,
// The position.
position: [number, number, number],
// The rotation.
rotation: [number, number, number, number],
// The source range.
sourceRange: [number, number],
type: "extrudePlane",
} |
{
// The face id for the extrude plane.
faceId: uuid,
// The id of the geometry.
id: uuid,
// The name.
name: string,
// The position.
position: [number, number, number],
// The rotation.
rotation: [number, number, number, number],
// The source range.
sourceRange: [number, number],
type: "extrudeArc",
}],
// The x-axis of the extrude group base plane in the 3D space
xAxis: {
x: number,
y: number,
z: number,
},
// The y-axis of the extrude group base plane in the 3D space
yAxis: {
x: number,
y: number,
z: number,
},
// The z-axis of the extrude group base plane in the 3D space
zAxis: {
x: number,
y: number,
z: number,
},
}
```

View File

@ -34,6 +34,7 @@ layout: manual
* [`getNextAdjacentEdge`](kcl/getNextAdjacentEdge)
* [`getOppositeEdge`](kcl/getOppositeEdge)
* [`getPreviousAdjacentEdge`](kcl/getPreviousAdjacentEdge)
* [`helix`](kcl/helix)
* [`hole`](kcl/hole)
* [`import`](kcl/import)
* [`lastSegX`](kcl/lastSegX)

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 221 KiB

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 221 KiB

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 221 KiB

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 163 KiB

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 163 KiB

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 163 KiB

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 163 KiB

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 221 KiB

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 163 KiB

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 163 KiB

After

Width:  |  Height:  |  Size: 70 KiB

View File

@ -134,6 +134,11 @@ pub trait EngineManager: std::fmt::Debug + Send + Sync + 'static {
pub fn is_cmd_with_return_values(cmd: &kittycad::types::ModelingCmd) -> bool {
let (kittycad::types::ModelingCmd::Export { .. }
| kittycad::types::ModelingCmd::Extrude { .. }
| kittycad::types::ModelingCmd::DefaultCameraLookAt { .. }
| kittycad::types::ModelingCmd::DefaultCameraFocusOn { .. }
| kittycad::types::ModelingCmd::DefaultCameraGetSettings { .. }
| kittycad::types::ModelingCmd::DefaultCameraPerspectiveSettings { .. }
| kittycad::types::ModelingCmd::DefaultCameraZoom { .. }
| kittycad::types::ModelingCmd::SketchModeDisable { .. }
| kittycad::types::ModelingCmd::ObjectBringToFront { .. }
| kittycad::types::ModelingCmd::SelectWithPoint { .. }
@ -144,8 +149,6 @@ pub fn is_cmd_with_return_values(cmd: &kittycad::types::ModelingCmd) -> bool {
| kittycad::types::ModelingCmd::EntityGetAllChildUuids { .. }
| kittycad::types::ModelingCmd::CameraDragMove { .. }
| kittycad::types::ModelingCmd::CameraDragEnd { .. }
| kittycad::types::ModelingCmd::DefaultCameraGetSettings { .. }
| kittycad::types::ModelingCmd::DefaultCameraZoom { .. }
| kittycad::types::ModelingCmd::SelectGet { .. }
| kittycad::types::ModelingCmd::Solid3DGetAllEdgeFaces { .. }
| kittycad::types::ModelingCmd::Solid3DGetAllOppositeEdges { .. }

View File

@ -0,0 +1,70 @@
//! Standard library helices.
use anyhow::Result;
use derive_docs::stdlib;
use kittycad::types::ModelingCmd;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use crate::{
errors::KclError,
executor::{ExtrudeGroup, MemoryItem},
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).
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
/// the extrude group is used.
pub length: Option<f64>,
}
/// Create a helix on a cylinder.
pub async fn helix(args: Args) -> Result<MemoryItem, KclError> {
let (data, extrude_group): (HelixData, Box<ExtrudeGroup>) = args.get_data_and_extrude_group()?;
let extrude_group = inner_helix(data, extrude_group, args).await?;
Ok(MemoryItem::ExtrudeGroup(extrude_group))
}
/// Create a helix on a cylinder.
///
/// ```no_run
/// const part001 = startSketchOn('XY')
/// |> circle([5, 5], 10, %)
/// |> extrude(10, %)
/// |> helix({revolutions: 16, angle_start: 0}, %)
/// ```
#[stdlib {
name = "helix",
}]
async fn inner_helix(
data: HelixData,
extrude_group: Box<ExtrudeGroup>,
args: Args,
) -> Result<Box<ExtrudeGroup>, KclError> {
let id = uuid::Uuid::new_v4();
args.send_modeling_cmd(
id,
ModelingCmd::EntityMakeHelix {
cylinder_id: extrude_group.id,
is_clockwise: !data.ccw,
length: data.length.unwrap_or(extrude_group.height),
revolutions: data.revolutions,
start_angle: kittycad::types::Angle::from_degrees(data.angle_start),
},
)
.await?;
Ok(extrude_group)
}

View File

@ -2,6 +2,7 @@
pub mod extrude;
pub mod fillet;
pub mod helix;
pub mod import;
pub mod kcl_stdlib;
pub mod math;
@ -79,6 +80,7 @@ lazy_static! {
Box::new(crate::std::fillet::GetOppositeEdge),
Box::new(crate::std::fillet::GetNextAdjacentEdge),
Box::new(crate::std::fillet::GetPreviousAdjacentEdge),
Box::new(crate::std::helix::Helix),
Box::new(crate::std::import::Import),
Box::new(crate::std::math::Cos),
Box::new(crate::std::math::Sin),

File diff suppressed because it is too large Load Diff

View File

@ -542,6 +542,82 @@ const pt2 = b2.value[0]
);
}
#[tokio::test(flavor = "multi_thread")]
async fn serial_test_helix_defaults() {
let code = r#"const part001 = startSketchOn('XY')
|> circle([5, 5], 10, %)
|> extrude(10, %)
|> helix({revolutions: 16, angle_start: 0}, %)
"#;
let result = execute_and_snapshot(code, kittycad::types::UnitLength::Mm)
.await
.unwrap();
twenty_twenty::assert_image("tests/executor/outputs/helix_defaults.png", &result, 1.0);
}
#[tokio::test(flavor = "multi_thread")]
async fn serial_test_helix_defaults_negative_extrude() {
let code = r#"const part001 = startSketchOn('XY')
|> circle([5, 5], 10, %)
|> extrude(-10, %)
|> helix({revolutions: 16, angle_start: 0}, %)
"#;
let result = execute_and_snapshot(code, kittycad::types::UnitLength::Mm)
.await
.unwrap();
twenty_twenty::assert_image(
"tests/executor/outputs/helix_defaults_negative_extrude.png",
&result,
1.0,
);
}
#[tokio::test(flavor = "multi_thread")]
async fn serial_test_helix_ccw() {
let code = r#"const part001 = startSketchOn('XY')
|> circle([5, 5], 10, %)
|> extrude(10, %)
|> helix({revolutions: 16, angle_start: 0, ccw: true}, %)
"#;
let result = execute_and_snapshot(code, kittycad::types::UnitLength::Mm)
.await
.unwrap();
twenty_twenty::assert_image("tests/executor/outputs/helix_ccw.png", &result, 1.0);
}
#[tokio::test(flavor = "multi_thread")]
async fn serial_test_helix_with_length() {
let code = r#"const part001 = startSketchOn('XY')
|> circle([5, 5], 10, %)
|> extrude(10, %)
|> helix({revolutions: 16, angle_start: 0, length: 3}, %)
"#;
let result = execute_and_snapshot(code, kittycad::types::UnitLength::Mm)
.await
.unwrap();
twenty_twenty::assert_image("tests/executor/outputs/helix_with_length.png", &result, 1.0);
}
#[tokio::test(flavor = "multi_thread")]
async fn serial_test_dimensions_match() {
let code = r#"const part001 = startSketchOn('XY')
|> startProfileAt([-10, -10], %)
|> line([20, 0], %)
|> line([0, 20], %)
|> line([-20, 0], %)
|> close(%)
"#;
let result = execute_and_snapshot(code, kittycad::types::UnitLength::Mm)
.await
.unwrap();
twenty_twenty::assert_image("tests/executor/outputs/dimensions_match.png", &result, 1.0);
}
#[tokio::test(flavor = "multi_thread")]
async fn serial_test_close_arc() {
let code = r#"const center = [0,0]

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 127 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 127 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 125 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB