Compare commits

...

1 Commits

Author SHA1 Message Date
2fafe547c8 Path enum no longer includes BasePath
BasePath is a pair of points and geometry metadata.

Previously BasePath was used for:

 - The start of a sketch
 - The data which all path types have in common

It wasn't a good fit for the start of a sketch, because there was a lot
of duplicated information, and a sketch starts at a point, not a line
(two points).

This adds a separate SketchStart struct which replaces the first use
of BasePath. This means BasePath no longer needs to be a variant of
Path, simplifying it.

Solves problem 4 of
 https://github.com/KittyCAD/modeling-app/issues/4297
2024-10-28 11:30:47 -05:00
9 changed files with 3374 additions and 9216 deletions

File diff suppressed because it is too large Load Diff

View File

@ -141,26 +141,6 @@ An angled line to.
| `__geoMeta` |[`GeoMeta`](/docs/kcl/types/GeoMeta)| Metadata. | No |
----
A base path.
**Type:** `object`
## Properties
| Property | Type | Description | Required |
|----------|------|-------------|----------|
| `type` |enum: `Base`| | No |
| `from` |`[number, number]`| The from point. | No |
| `to` |`[number, number]`| The to point. | No |
| `tag` |[`TagDeclarator`](/docs/kcl/types#tag-declaration)| The tag of the path. | No |
| `__geoMeta` |[`GeoMeta`](/docs/kcl/types/GeoMeta)| Metadata. | No |
----
A circular arc, not necessarily tangential to the current point.

View File

@ -19,7 +19,7 @@ A sketch is a collection of paths.
| `id` |`string`| The id of the sketch (this will change when the engine's reference to it changes). | No |
| `paths` |`[` [`Path`](/docs/kcl/types/Path) `]`| The paths in the sketch. | No |
| `on` |[`SketchSurface`](/docs/kcl/types/SketchSurface)| What the sketch is on (can be a plane or a face). | No |
| `start` |[`BasePath`](/docs/kcl/types/BasePath)| The starting path. | No |
| `start` |[`SketchStart`](/docs/kcl/types/SketchStart)| The starting path. | No |
| `tags` |`object`| Tag identifiers that have been declared in this sketch. | No |
| `__meta` |`[` [`Metadata`](/docs/kcl/types/Metadata) `]`| Metadata. | No |

View File

@ -28,7 +28,7 @@ A sketch is a collection of paths.
| `id` |`string`| The id of the sketch (this will change when the engine's reference to it changes). | No |
| `paths` |`[` [`Path`](/docs/kcl/types/Path) `]`| The paths in the sketch. | No |
| `on` |[`SketchSurface`](/docs/kcl/types/SketchSurface)| What the sketch is on (can be a plane or a face). | No |
| `start` |[`BasePath`](/docs/kcl/types/BasePath)| The starting path. | No |
| `start` |[`SketchStart`](/docs/kcl/types/SketchStart)| The starting path. | No |
| `tags` |`object`| Tag identifiers that have been declared in this sketch. | No |
| `__meta` |`[` [`Metadata`](/docs/kcl/types/Metadata) `]`| Metadata. | No |

View File

@ -0,0 +1,23 @@
---
title: "SketchStart"
excerpt: "Where the sketch starts."
layout: manual
---
Where the sketch starts.
**Type:** `object`
## Properties
| Property | Type | Description | Required |
|----------|------|-------------|----------|
| `at` |`[number, number]`| Start point. | No |
| `tag` |[`TagDeclarator`](/docs/kcl/types#tag-declaration)| Tag of the start point. | No |
| `__geoMeta` |[`GeoMeta`](/docs/kcl/types/GeoMeta)| Metadata. | No |

View File

@ -43,6 +43,22 @@ The surface information for the tag.
| `surface` |[`ExtrudeSurface`](/docs/kcl/types/ExtrudeSurface)| Engine information for a tag. | No |
----
The point being tagged.
**Type:** `object`
## Properties
| Property | Type | Description | Required |
|----------|------|-------------|----------|
| `point` |`[number, number]`| | No |
----

View File

@ -1141,6 +1141,11 @@ impl TagEngineInfo {
pub fn surface(&self) -> Option<&ExtrudeSurface> {
self.tagged.surface()
}
/// If this is tagging a point, get it.
pub fn point(&self) -> Option<&[f64; 2]> {
self.tagged.point()
}
}
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
@ -1151,6 +1156,8 @@ pub enum Tagged {
Path(Path),
/// The surface information for the tag.
Surface(ExtrudeSurface),
/// The point being tagged.
Point([f64; 2]),
}
impl Tagged {
@ -1169,6 +1176,13 @@ impl Tagged {
};
Some(x)
}
/// If this is a path, get it.
fn point(&self) -> Option<&[f64; 2]> {
let Self::Point(x) = &self else {
return None;
};
Some(x)
}
}
/// A sketch is a collection of paths.
@ -1183,7 +1197,7 @@ pub struct Sketch {
/// What the sketch is on (can be a plane or a face).
pub on: SketchSurface,
/// The starting path.
pub start: BasePath,
pub start: SketchStart,
/// Tag identifiers that have been declared in this sketch.
#[serde(default, skip_serializing_if = "HashMap::is_empty")]
pub tags: HashMap<String, TagIdentifier>,
@ -1261,7 +1275,7 @@ impl Sketch {
/// where the last path segment ends, and the next path segment will begin.
pub(crate) fn current_pen_position(&self) -> Result<Point2d, KclError> {
let Some(path) = self.latest_path() else {
return Ok(self.start.to.into());
return Ok(self.start.at.into());
};
let base = path.get_base();
@ -1271,7 +1285,7 @@ impl Sketch {
pub(crate) fn get_tangential_info_from_paths(&self) -> GetTangentialInfoFromPathsResult {
let Some(path) = self.latest_path() else {
return GetTangentialInfoFromPathsResult {
center_or_tangent_point: self.start.to,
center_or_tangent_point: self.start.at,
is_center: false,
ccw: false,
};
@ -1617,6 +1631,21 @@ pub struct BasePath {
pub geo_meta: GeoMeta,
}
/// Where the sketch starts.
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
#[ts(export)]
#[serde(rename_all = "camelCase")]
pub struct SketchStart {
/// Start point.
#[ts(type = "[number, number]")]
pub at: [f64; 2],
/// Tag of the start point.
pub tag: Option<TagDeclarator>,
/// Metadata.
#[serde(rename = "__geoMeta")]
pub geo_meta: GeoMeta,
}
/// Geometry metadata.
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
#[ts(export)]
@ -1689,11 +1718,6 @@ pub enum Path {
/// The y coordinate.
y: Option<f64>,
},
/// A base path.
Base {
#[serde(flatten)]
base: BasePath,
},
/// A circular arc, not necessarily tangential to the current point.
Arc {
#[serde(flatten)]
@ -1709,7 +1733,6 @@ pub enum Path {
#[derive(Display)]
enum PathType {
ToPoint,
Base,
TangentialArc,
TangentialArcTo,
Circle,
@ -1727,7 +1750,6 @@ impl From<&Path> for PathType {
Path::Circle { .. } => Self::Circle,
Path::Horizontal { .. } => Self::Horizontal,
Path::AngledLineTo { .. } => Self::AngledLineTo,
Path::Base { .. } => Self::Base,
Path::Arc { .. } => Self::Arc,
}
}
@ -1739,7 +1761,6 @@ impl Path {
Path::ToPoint { base } => base.geo_meta.id,
Path::Horizontal { base, .. } => base.geo_meta.id,
Path::AngledLineTo { base, .. } => base.geo_meta.id,
Path::Base { base } => base.geo_meta.id,
Path::TangentialArcTo { base, .. } => base.geo_meta.id,
Path::TangentialArc { base, .. } => base.geo_meta.id,
Path::Circle { base, .. } => base.geo_meta.id,
@ -1752,7 +1773,6 @@ impl Path {
Path::ToPoint { base } => base.tag.clone(),
Path::Horizontal { base, .. } => base.tag.clone(),
Path::AngledLineTo { base, .. } => base.tag.clone(),
Path::Base { base } => base.tag.clone(),
Path::TangentialArcTo { base, .. } => base.tag.clone(),
Path::TangentialArc { base, .. } => base.tag.clone(),
Path::Circle { base, .. } => base.tag.clone(),
@ -1765,7 +1785,6 @@ impl Path {
Path::ToPoint { base } => base,
Path::Horizontal { base, .. } => base,
Path::AngledLineTo { base, .. } => base,
Path::Base { base } => base,
Path::TangentialArcTo { base, .. } => base,
Path::TangentialArc { base, .. } => base,
Path::Circle { base, .. } => base,
@ -1785,7 +1804,7 @@ impl Path {
/// Length of this path segment, in cartesian plane.
pub fn length(&self) -> f64 {
match self {
Self::ToPoint { .. } | Self::Base { .. } | Self::Horizontal { .. } | Self::AngledLineTo { .. } => {
Self::ToPoint { .. } | Self::Horizontal { .. } | Self::AngledLineTo { .. } => {
linear_distance(self.get_from(), self.get_to())
}
Self::TangentialArc {
@ -1818,7 +1837,6 @@ impl Path {
Path::ToPoint { base } => Some(base),
Path::Horizontal { base, .. } => Some(base),
Path::AngledLineTo { base, .. } => Some(base),
Path::Base { base } => Some(base),
Path::TangentialArcTo { base, .. } => Some(base),
Path::TangentialArc { base, .. } => Some(base),
Path::Circle { base, .. } => Some(base),

View File

@ -238,7 +238,7 @@ pub(crate) async fn do_post_extrude(
});
Some(extrude_surface)
}
Path::Base { .. } | Path::ToPoint { .. } | Path::Horizontal { .. } | Path::AngledLineTo { .. } => {
Path::ToPoint { .. } | Path::Horizontal { .. } | Path::AngledLineTo { .. } => {
let extrude_surface = ExtrudeSurface::ExtrudePlane(crate::executor::ExtrudePlane {
face_id: *actual_face_id,
tag: path.get_base().tag.clone(),

View File

@ -12,7 +12,7 @@ use parse_display::{Display, FromStr};
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use crate::executor::Tagged;
use crate::executor::{SketchStart, Tagged};
use crate::{
ast::types::TagDeclarator,
errors::{KclError, KclErrorDetails},
@ -1224,9 +1224,8 @@ pub(crate) async fn inner_start_profile_at(
)
.await?;
let current_path = BasePath {
from: to,
to,
let start = SketchStart {
at: to,
tag: tag.clone(),
geo_meta: GeoMeta {
id,
@ -1243,17 +1242,15 @@ pub(crate) async fn inner_start_profile_at(
tags: if let Some(tag) = &tag {
let mut tag_identifier: TagIdentifier = tag.into();
tag_identifier.info = Some(TagEngineInfo {
id: current_path.geo_meta.id,
id,
sketch: path_id,
tagged: Tagged::Path(Path::Base {
base: current_path.clone(),
}),
tagged: Tagged::Point(to),
});
HashMap::from([(tag.name.to_string(), tag_identifier)])
} else {
Default::default()
},
start: current_path,
start,
};
Ok(sketch)
}
@ -1279,7 +1276,7 @@ pub async fn profile_start_x(_exec_state: &mut ExecState, args: Args) -> Result<
name = "profileStartX"
}]
pub(crate) fn inner_profile_start_x(sketch: Sketch) -> Result<f64, KclError> {
Ok(sketch.start.to[0])
Ok(sketch.start.at[0])
}
/// Returns the Y component of the sketch profile start point.
@ -1302,7 +1299,7 @@ pub async fn profile_start_y(_exec_state: &mut ExecState, args: Args) -> Result<
name = "profileStartY"
}]
pub(crate) fn inner_profile_start_y(sketch: Sketch) -> Result<f64, KclError> {
Ok(sketch.start.to[1])
Ok(sketch.start.at[1])
}
/// Returns the sketch profile start point.
@ -1336,7 +1333,7 @@ pub async fn profile_start(_exec_state: &mut ExecState, args: Args) -> Result<Kc
name = "profileStart"
}]
pub(crate) fn inner_profile_start(sketch: Sketch) -> Result<[f64; 2], KclError> {
Ok(sketch.start.to)
Ok(sketch.start.at)
}
/// Close the current sketch.
@ -1379,7 +1376,7 @@ pub(crate) async fn inner_close(
args: Args,
) -> Result<Sketch, KclError> {
let from = sketch.current_pen_position()?;
let to: Point2d = sketch.start.from.into();
let to: Point2d = sketch.start.at.into();
let id = exec_state.id_generator.next_uuid();