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
This commit is contained in:
		
							
								
								
									
										12454
									
								
								docs/kcl/std.json
									
									
									
									
									
								
							
							
						
						
									
										12454
									
								
								docs/kcl/std.json
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @ -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. | ||||
|  | ||||
|  | ||||
| @ -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 | | ||||
|  | ||||
|  | ||||
| @ -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 | | ||||
|  | ||||
|  | ||||
							
								
								
									
										23
									
								
								docs/kcl/types/SketchStart.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								docs/kcl/types/SketchStart.md
									
									
									
									
									
										Normal 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 | | ||||
|  | ||||
|  | ||||
| @ -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 | | ||||
|  | ||||
|  | ||||
| ---- | ||||
|  | ||||
|  | ||||
|  | ||||
| @ -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), | ||||
|  | ||||
| @ -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(), | ||||
|  | ||||
| @ -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(); | ||||
|  | ||||
|  | ||||
		Reference in New Issue
	
	Block a user