Generalise and simplify offsetPlane (#5429)
* Generalise and simplify offsetPlane Signed-off-by: Nick Cameron <nrc@ncameron.org> * A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores) * A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores) --------- Signed-off-by: Nick Cameron <nrc@ncameron.org> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
This commit is contained in:
@ -9,7 +9,7 @@ Offset a plane by a distance along its normal.
|
||||
For example, if you offset the 'XZ' plane by 10, the new plane will be parallel to the 'XZ' plane and 10 units away from it.
|
||||
|
||||
```js
|
||||
offsetPlane(std_plane: StandardPlane, offset: number) -> Plane
|
||||
offsetPlane(plane: PlaneData, offset: number) -> Plane
|
||||
```
|
||||
|
||||
|
||||
@ -17,7 +17,7 @@ offsetPlane(std_plane: StandardPlane, offset: number) -> Plane
|
||||
|
||||
| Name | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `std_plane` | [`StandardPlane`](/docs/kcl/types/StandardPlane) | Which standard plane (e.g. XY) should this new plane be created from? | Yes |
|
||||
| `plane` | [`PlaneData`](/docs/kcl/types/PlaneData) | The plane (e.g. 'XY') which this new plane is created from. | Yes |
|
||||
| `offset` | `number` | Distance from the standard plane this new plane will be created at. | Yes |
|
||||
|
||||
### Returns
|
||||
|
||||
@ -147531,12 +147531,12 @@
|
||||
"keywordArguments": true,
|
||||
"args": [
|
||||
{
|
||||
"name": "std_plane",
|
||||
"type": "StandardPlane",
|
||||
"name": "plane",
|
||||
"type": "PlaneData",
|
||||
"schema": {
|
||||
"$schema": "https://spec.openapis.org/oas/3.0/schema/2019-04-02#/definitions/Schema",
|
||||
"title": "StandardPlane",
|
||||
"description": "One of the standard planes.",
|
||||
"title": "PlaneData",
|
||||
"description": "Orientation data that can be used to construct a plane, not a plane in itself.",
|
||||
"oneOf": [
|
||||
{
|
||||
"description": "The XY plane.",
|
||||
@ -147579,12 +147579,89 @@
|
||||
"enum": [
|
||||
"-YZ"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "A defined plane.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"plane"
|
||||
],
|
||||
"properties": {
|
||||
"plane": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"origin",
|
||||
"xAxis",
|
||||
"yAxis",
|
||||
"zAxis"
|
||||
],
|
||||
"properties": {
|
||||
"origin": {
|
||||
"description": "Origin of the plane.",
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/Point3d"
|
||||
}
|
||||
]
|
||||
},
|
||||
"xAxis": {
|
||||
"description": "What should the plane’s X axis be?",
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/Point3d"
|
||||
}
|
||||
]
|
||||
},
|
||||
"yAxis": {
|
||||
"description": "What should the plane’s Y axis be?",
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/Point3d"
|
||||
}
|
||||
]
|
||||
},
|
||||
"zAxis": {
|
||||
"description": "The z-axis (normal).",
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/Point3d"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
]
|
||||
],
|
||||
"definitions": {
|
||||
"Point3d": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"x",
|
||||
"y",
|
||||
"z"
|
||||
],
|
||||
"properties": {
|
||||
"x": {
|
||||
"type": "number",
|
||||
"format": "double"
|
||||
},
|
||||
"y": {
|
||||
"type": "number",
|
||||
"format": "double"
|
||||
},
|
||||
"z": {
|
||||
"type": "number",
|
||||
"format": "double"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": true,
|
||||
"includeInSnippet": true,
|
||||
"description": "Which standard plane (e.g. XY) should this new plane be created from?",
|
||||
"description": "The plane (e.g. 'XY') which this new plane is created from.",
|
||||
"labelRequired": false
|
||||
},
|
||||
{
|
||||
@ -147594,7 +147671,31 @@
|
||||
"$schema": "https://spec.openapis.org/oas/3.0/schema/2019-04-02#/definitions/Schema",
|
||||
"title": "double",
|
||||
"type": "number",
|
||||
"format": "double"
|
||||
"format": "double",
|
||||
"definitions": {
|
||||
"Point3d": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"x",
|
||||
"y",
|
||||
"z"
|
||||
],
|
||||
"properties": {
|
||||
"x": {
|
||||
"type": "number",
|
||||
"format": "double"
|
||||
},
|
||||
"y": {
|
||||
"type": "number",
|
||||
"format": "double"
|
||||
},
|
||||
"z": {
|
||||
"type": "number",
|
||||
"format": "double"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": true,
|
||||
"includeInSnippet": true,
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
use std::ops::{Add, AddAssign, Mul};
|
||||
|
||||
use anyhow::Result;
|
||||
use indexmap::IndexMap;
|
||||
use kittycad_modeling_cmds as kcmc;
|
||||
@ -353,11 +355,6 @@ impl Plane {
|
||||
}
|
||||
}
|
||||
|
||||
/// The standard planes are XY, YZ and XZ (in both positive and negative)
|
||||
pub fn is_standard(&self) -> bool {
|
||||
!self.is_custom()
|
||||
}
|
||||
|
||||
/// The standard planes are XY, YZ and XZ (in both positive and negative)
|
||||
/// Custom planes are any other plane that the user might specify.
|
||||
pub fn is_custom(&self) -> bool {
|
||||
@ -696,6 +693,36 @@ impl From<Point3d> for kittycad_modeling_cmds::shared::Point3d<LengthUnit> {
|
||||
}
|
||||
}
|
||||
|
||||
impl Add for Point3d {
|
||||
type Output = Point3d;
|
||||
|
||||
fn add(self, rhs: Self) -> Self::Output {
|
||||
Point3d {
|
||||
x: self.x + rhs.x,
|
||||
y: self.y + rhs.y,
|
||||
z: self.z + rhs.z,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl AddAssign for Point3d {
|
||||
fn add_assign(&mut self, rhs: Self) {
|
||||
*self = *self + rhs
|
||||
}
|
||||
}
|
||||
|
||||
impl Mul<f64> for Point3d {
|
||||
type Output = Point3d;
|
||||
|
||||
fn mul(self, rhs: f64) -> Self::Output {
|
||||
Point3d {
|
||||
x: self.x * rhs,
|
||||
y: self.y * rhs,
|
||||
z: self.z * rhs,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A base path.
|
||||
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
|
||||
#[ts(export)]
|
||||
|
||||
@ -874,21 +874,6 @@ impl<'a> FromKclValue<'a> for crate::std::polar::PolarCoordsData {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> FromKclValue<'a> for crate::std::planes::StandardPlane {
|
||||
fn from_kcl_val(arg: &'a KclValue) -> Option<Self> {
|
||||
let s = arg.as_str()?;
|
||||
match s {
|
||||
"XY" | "xy" => Some(Self::XY),
|
||||
"-XY" | "-xy" => Some(Self::NegXY),
|
||||
"XZ" | "xz" => Some(Self::XZ),
|
||||
"-XZ" | "-xz" => Some(Self::NegXZ),
|
||||
"YZ" | "yz" => Some(Self::YZ),
|
||||
"-YZ" | "-yz" => Some(Self::NegYZ),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> FromKclValue<'a> for crate::execution::Plane {
|
||||
fn from_kcl_val(arg: &'a KclValue) -> Option<Self> {
|
||||
arg.as_plane().cloned()
|
||||
|
||||
@ -3,57 +3,19 @@
|
||||
use derive_docs::stdlib;
|
||||
use kcmc::{each_cmd as mcmd, length_unit::LengthUnit, shared::Color, ModelingCmd};
|
||||
use kittycad_modeling_cmds as kcmc;
|
||||
use schemars::JsonSchema;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{
|
||||
errors::KclError,
|
||||
execution::{ExecState, KclValue, Plane, PlaneType},
|
||||
std::{sketch::PlaneData, Args},
|
||||
std::Args,
|
||||
};
|
||||
|
||||
/// One of the standard planes.
|
||||
#[derive(Debug, Clone, Copy, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
|
||||
#[ts(export)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub enum StandardPlane {
|
||||
/// The XY plane.
|
||||
#[serde(rename = "XY", alias = "xy")]
|
||||
XY,
|
||||
/// The opposite side of the XY plane.
|
||||
#[serde(rename = "-XY", alias = "-xy")]
|
||||
NegXY,
|
||||
/// The XZ plane.
|
||||
#[serde(rename = "XZ", alias = "xz")]
|
||||
XZ,
|
||||
/// The opposite side of the XZ plane.
|
||||
#[serde(rename = "-XZ", alias = "-xz")]
|
||||
NegXZ,
|
||||
/// The YZ plane.
|
||||
#[serde(rename = "YZ", alias = "yz")]
|
||||
YZ,
|
||||
/// The opposite side of the YZ plane.
|
||||
#[serde(rename = "-YZ", alias = "-yz")]
|
||||
NegYZ,
|
||||
}
|
||||
|
||||
impl From<StandardPlane> for PlaneData {
|
||||
fn from(value: StandardPlane) -> Self {
|
||||
match value {
|
||||
StandardPlane::XY => PlaneData::XY,
|
||||
StandardPlane::NegXY => PlaneData::NegXY,
|
||||
StandardPlane::XZ => PlaneData::XZ,
|
||||
StandardPlane::NegXZ => PlaneData::NegXZ,
|
||||
StandardPlane::YZ => PlaneData::YZ,
|
||||
StandardPlane::NegYZ => PlaneData::NegYZ,
|
||||
}
|
||||
}
|
||||
}
|
||||
use super::sketch::PlaneData;
|
||||
|
||||
/// Offset a plane by a distance along its normal.
|
||||
pub async fn offset_plane(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
||||
// let (std_plane, offset): (StandardPlane, f64) = args.get_data_and_float()?;
|
||||
let std_plane = args.get_unlabeled_kw_arg("stdPlane")?;
|
||||
let std_plane = args.get_unlabeled_kw_arg("plane")?;
|
||||
let offset = args.get_kw_arg("offset")?;
|
||||
let plane = inner_offset_plane(std_plane, offset, exec_state).await?;
|
||||
make_offset_plane_in_engine(&plane, exec_state, &args).await?;
|
||||
@ -148,43 +110,17 @@ pub async fn offset_plane(exec_state: &mut ExecState, args: Args) -> Result<KclV
|
||||
keywords = true,
|
||||
unlabeled_first = true,
|
||||
args = {
|
||||
std_plane = { docs = "Which standard plane (e.g. XY) should this new plane be created from?" },
|
||||
plane = { docs = "The plane (e.g. 'XY') which this new plane is created from." },
|
||||
offset = { docs = "Distance from the standard plane this new plane will be created at." },
|
||||
}
|
||||
}]
|
||||
async fn inner_offset_plane(
|
||||
std_plane: StandardPlane,
|
||||
offset: f64,
|
||||
exec_state: &mut ExecState,
|
||||
) -> Result<Plane, KclError> {
|
||||
// Convert to the plane type.
|
||||
let plane_data: PlaneData = std_plane.into();
|
||||
// Convert to a plane.
|
||||
let mut plane = Plane::from_plane_data(plane_data, exec_state);
|
||||
// Though offset planes are derived from standard planes, they are not
|
||||
async fn inner_offset_plane(plane: PlaneData, offset: f64, exec_state: &mut ExecState) -> Result<Plane, KclError> {
|
||||
let mut plane = Plane::from_plane_data(plane, exec_state);
|
||||
// Though offset planes might be derived from standard planes, they are not
|
||||
// standard planes themselves.
|
||||
plane.value = PlaneType::Custom;
|
||||
|
||||
match std_plane {
|
||||
StandardPlane::XY => {
|
||||
plane.origin.z += offset;
|
||||
}
|
||||
StandardPlane::XZ => {
|
||||
plane.origin.y -= offset;
|
||||
}
|
||||
StandardPlane::YZ => {
|
||||
plane.origin.x += offset;
|
||||
}
|
||||
StandardPlane::NegXY => {
|
||||
plane.origin.z -= offset;
|
||||
}
|
||||
StandardPlane::NegXZ => {
|
||||
plane.origin.y += offset;
|
||||
}
|
||||
StandardPlane::NegYZ => {
|
||||
plane.origin.x -= offset;
|
||||
}
|
||||
}
|
||||
plane.origin += plane.z_axis * offset;
|
||||
|
||||
Ok(plane)
|
||||
}
|
||||
|
||||
@ -1296,7 +1296,7 @@ pub(crate) async fn inner_start_profile_at(
|
||||
args.flush_batch_for_solid_set(exec_state, face.solid.clone().into())
|
||||
.await?;
|
||||
}
|
||||
SketchSurface::Plane(plane) if !plane.is_standard() => {
|
||||
SketchSurface::Plane(plane) if plane.is_custom() => {
|
||||
// Hide whatever plane we are sketching on.
|
||||
// This is especially helpful for offset planes, which would be visible otherwise.
|
||||
args.batch_end_cmd(
|
||||
|
||||
Reference in New Issue
Block a user