Compare commits
	
		
			3 Commits
		
	
	
		
			grackle-la
			...
			achalmers/
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 92cd142100 | |||
| b6b6edf539 | |||
| 32d7fe9744 | 
| Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 80 KiB | 
| Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 80 KiB | 
| Before Width: | Height: | Size: 60 KiB After Width: | Height: | Size: 56 KiB | 
| Before Width: | Height: | Size: 60 KiB After Width: | Height: | Size: 56 KiB | 
| Before Width: | Height: | Size: 60 KiB After Width: | Height: | Size: 56 KiB | 
| Before Width: | Height: | Size: 60 KiB After Width: | Height: | Size: 56 KiB | 
| Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 80 KiB | 
| Before Width: | Height: | Size: 60 KiB After Width: | Height: | Size: 57 KiB | 
| Before Width: | Height: | Size: 60 KiB After Width: | Height: | Size: 57 KiB | 
| @ -24,7 +24,7 @@ use crate::{ | ||||
|     docs::StdLibFn, | ||||
|     engine::EngineManager, | ||||
|     errors::{KclError, KclErrorDetails}, | ||||
|     executor::{ExecutorContext, ExtrudeGroup, MemoryItem, Metadata, Plane, SketchGroup, SourceRange}, | ||||
|     executor::{ExecutorContext, ExtrudeGroup, MemoryItem, Metadata, Plane, SketchGroup, SourceRange, UserVal}, | ||||
| }; | ||||
|  | ||||
| pub type StdFn = fn(Args) -> std::pin::Pin<Box<dyn std::future::Future<Output = Result<MemoryItem, KclError>>>>; | ||||
| @ -362,6 +362,41 @@ impl Args { | ||||
|         Ok(data) | ||||
|     } | ||||
|  | ||||
|     fn get_data_and_tag<T: serde::de::DeserializeOwned>(&self) -> Result<(T, Option<String>), KclError> { | ||||
|         let first_value = self | ||||
|             .args | ||||
|             .first() | ||||
|             .ok_or_else(|| { | ||||
|                 KclError::Type(KclErrorDetails { | ||||
|                     message: format!("Expected a struct as the first argument, found `{:?}`", self.args), | ||||
|                     source_ranges: vec![self.source_range], | ||||
|                 }) | ||||
|             })? | ||||
|             .get_json_value()?; | ||||
|  | ||||
|         let data: T = serde_json::from_value(first_value).map_err(|e| { | ||||
|             KclError::Type(KclErrorDetails { | ||||
|                 message: format!("Failed to deserialize struct from JSON: {}", e), | ||||
|                 source_ranges: vec![self.source_range], | ||||
|             }) | ||||
|         })?; | ||||
|  | ||||
|         let tag = match self.args.get(1) { | ||||
|             Some(MemoryItem::UserVal(UserVal { | ||||
|                 value: serde_json::Value::String(s), | ||||
|                 .. | ||||
|             })) => Some(s.to_owned()), | ||||
|             Some(_other) => { | ||||
|                 return Err(KclError::Type(KclErrorDetails { | ||||
|                     source_ranges: vec![self.source_range], | ||||
|                     message: format!("Expected a tag or nothing as the third value, found `{:?}`", self.args), | ||||
|                 })) | ||||
|             } | ||||
|             None => None, | ||||
|         }; | ||||
|         Ok((data, tag)) | ||||
|     } | ||||
|  | ||||
|     fn get_data_and_sketch_group<T: serde::de::DeserializeOwned>(&self) -> Result<(T, Box<SketchGroup>), KclError> { | ||||
|         let first_value = self | ||||
|             .args | ||||
| @ -400,7 +435,9 @@ impl Args { | ||||
|         Ok((data, sketch_group)) | ||||
|     } | ||||
|  | ||||
|     fn get_data_and_plane<T: serde::de::DeserializeOwned>(&self) -> Result<(T, Box<Plane>), KclError> { | ||||
|     fn get_data_and_plane_then_tag<T: serde::de::DeserializeOwned>( | ||||
|         &self, | ||||
|     ) -> Result<(T, Box<Plane>, Option<String>), KclError> { | ||||
|         let first_value = self | ||||
|             .args | ||||
|             .first() | ||||
| @ -435,7 +472,21 @@ impl Args { | ||||
|             })); | ||||
|         }; | ||||
|  | ||||
|         Ok((data, plane)) | ||||
|         let tag = match self.args.get(2) { | ||||
|             Some(MemoryItem::UserVal(UserVal { | ||||
|                 value: serde_json::Value::String(s), | ||||
|                 .. | ||||
|             })) => Some(s.to_owned()), | ||||
|             Some(_other) => { | ||||
|                 return Err(KclError::Type(KclErrorDetails { | ||||
|                     source_ranges: vec![self.source_range], | ||||
|                     message: format!("Expected a tag or nothing as the third value, found `{:?}`", self.args), | ||||
|                 })) | ||||
|             } | ||||
|             None => None, | ||||
|         }; | ||||
|  | ||||
|         Ok((data, plane, tag)) | ||||
|     } | ||||
|  | ||||
|     fn get_segment_name_to_number_sketch_group(&self) -> Result<(String, f64, Box<SketchGroup>), KclError> { | ||||
|  | ||||
| @ -186,11 +186,20 @@ pub enum LineData { | ||||
|     Point([f64; 2]), | ||||
| } | ||||
|  | ||||
| impl LineData { | ||||
|     fn to_and_tag(self) -> ([f64; 2], Option<String>) { | ||||
|         match self { | ||||
|             LineData::PointWithTag { to, tag } => (to, Some(tag)), | ||||
|             LineData::Point(to) => (to, None), | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| /// Draw a line. | ||||
| pub async fn line(args: Args) -> Result<MemoryItem, KclError> { | ||||
|     let (data, sketch_group): (LineData, Box<SketchGroup>) = args.get_data_and_sketch_group()?; | ||||
|  | ||||
|     let new_sketch_group = inner_line(data, sketch_group, args).await?; | ||||
|     let (to, tag) = data.to_and_tag(); | ||||
|     let new_sketch_group = inner_line(to, sketch_group, tag, args).await?; | ||||
|     Ok(MemoryItem::SketchGroup(new_sketch_group)) | ||||
| } | ||||
|  | ||||
| @ -198,15 +207,16 @@ pub async fn line(args: Args) -> Result<MemoryItem, KclError> { | ||||
| #[stdlib { | ||||
|     name = "line", | ||||
| }] | ||||
| async fn inner_line(data: LineData, sketch_group: Box<SketchGroup>, args: Args) -> Result<Box<SketchGroup>, KclError> { | ||||
| async fn inner_line( | ||||
|     to: [f64; 2], | ||||
|     sketch_group: Box<SketchGroup>, | ||||
|     tag: Option<String>, | ||||
|     args: Args, | ||||
| ) -> Result<Box<SketchGroup>, KclError> { | ||||
|     let from = sketch_group.get_coords_from_paths()?; | ||||
|     let inner_args = match &data { | ||||
|         LineData::PointWithTag { to, .. } => *to, | ||||
|         LineData::Point(to) => *to, | ||||
|     }; | ||||
|  | ||||
|     let delta = inner_args; | ||||
|     let to = [from.x + inner_args[0], from.y + inner_args[1]]; | ||||
|     let delta = to; | ||||
|     let to = [from.x + to[0], from.y + to[1]]; | ||||
|  | ||||
|     let id = uuid::Uuid::new_v4(); | ||||
|  | ||||
| @ -230,11 +240,7 @@ async fn inner_line(data: LineData, sketch_group: Box<SketchGroup>, args: Args) | ||||
|         base: BasePath { | ||||
|             from: from.into(), | ||||
|             to, | ||||
|             name: if let LineData::PointWithTag { tag, .. } = data { | ||||
|                 tag.to_string() | ||||
|             } else { | ||||
|                 "".to_string() | ||||
|             }, | ||||
|             name: tag.unwrap_or_default(), | ||||
|             geo_meta: GeoMeta { | ||||
|                 id, | ||||
|                 metadata: args.source_range.into(), | ||||
| @ -281,12 +287,12 @@ async fn inner_x_line( | ||||
|     sketch_group: Box<SketchGroup>, | ||||
|     args: Args, | ||||
| ) -> Result<Box<SketchGroup>, KclError> { | ||||
|     let line_data = match data { | ||||
|         AxisLineData::LengthWithTag { length, tag } => LineData::PointWithTag { to: [length, 0.0], tag }, | ||||
|         AxisLineData::Length(length) => LineData::Point([length, 0.0]), | ||||
|     let (to, tag) = match data { | ||||
|         AxisLineData::LengthWithTag { length, tag } => ([length, 0.0], Some(tag)), | ||||
|         AxisLineData::Length(length) => ([length, 0.0], None), | ||||
|     }; | ||||
|  | ||||
|     let new_sketch_group = inner_line(line_data, sketch_group, args).await?; | ||||
|     let new_sketch_group = inner_line(to, sketch_group, tag, args).await?; | ||||
|     Ok(new_sketch_group) | ||||
| } | ||||
|  | ||||
| @ -307,12 +313,12 @@ async fn inner_y_line( | ||||
|     sketch_group: Box<SketchGroup>, | ||||
|     args: Args, | ||||
| ) -> Result<Box<SketchGroup>, KclError> { | ||||
|     let line_data = match data { | ||||
|         AxisLineData::LengthWithTag { length, tag } => LineData::PointWithTag { to: [0.0, length], tag }, | ||||
|         AxisLineData::Length(length) => LineData::Point([0.0, length]), | ||||
|     let (to, tag) = match data { | ||||
|         AxisLineData::LengthWithTag { length, tag } => ([0.0, length], Some(tag)), | ||||
|         AxisLineData::Length(length) => ([0.0, length], None), | ||||
|     }; | ||||
|  | ||||
|     let new_sketch_group = inner_line(line_data, sketch_group, args).await?; | ||||
|     let new_sketch_group = inner_line(to, sketch_group, tag, args).await?; | ||||
|     Ok(new_sketch_group) | ||||
| } | ||||
|  | ||||
| @ -438,8 +444,8 @@ async fn inner_angled_line_of_x_length( | ||||
|     }; | ||||
|  | ||||
|     let to = get_y_component(Angle::from_degrees(angle), length); | ||||
|  | ||||
|     let new_sketch_group = inner_line(data.into_inner_line(to.into()), sketch_group, args).await?; | ||||
|     let (to, tag) = data.into_inner_line(to.into()).to_and_tag(); | ||||
|     let new_sketch_group = inner_line(to, sketch_group, tag, args).await?; | ||||
|  | ||||
|     Ok(new_sketch_group) | ||||
| } | ||||
| @ -527,8 +533,8 @@ async fn inner_angled_line_of_y_length( | ||||
|     }; | ||||
|  | ||||
|     let to = get_x_component(Angle::from_degrees(angle), length); | ||||
|  | ||||
|     let new_sketch_group = inner_line(data.into_inner_line(to.into()), sketch_group, args).await?; | ||||
|     let (to, tag) = data.into_inner_line(to.into()).to_and_tag(); | ||||
|     let new_sketch_group = inner_line(to, sketch_group, tag, args).await?; | ||||
|  | ||||
|     Ok(new_sketch_group) | ||||
| } | ||||
| @ -629,9 +635,9 @@ async fn inner_angled_line_that_intersects( | ||||
|  | ||||
| /// Start a sketch at a given point. | ||||
| pub async fn start_sketch_at(args: Args) -> Result<MemoryItem, KclError> { | ||||
|     let data: LineData = args.get_data()?; | ||||
|     let (to, tag) = args.get_data_and_tag()?; | ||||
|  | ||||
|     let sketch_group = inner_start_sketch_at(data, args).await?; | ||||
|     let sketch_group = inner_start_sketch_at(to, tag, args).await?; | ||||
|     Ok(MemoryItem::SketchGroup(sketch_group)) | ||||
| } | ||||
|  | ||||
| @ -639,11 +645,11 @@ pub async fn start_sketch_at(args: Args) -> Result<MemoryItem, KclError> { | ||||
| #[stdlib { | ||||
|     name = "startSketchAt", | ||||
| }] | ||||
| async fn inner_start_sketch_at(data: LineData, args: Args) -> Result<Box<SketchGroup>, KclError> { | ||||
| async fn inner_start_sketch_at(at: [f64; 2], tag: Option<String>, args: Args) -> Result<Box<SketchGroup>, KclError> { | ||||
|     // Let's assume it's the XY plane for now, this is just for backwards compatibility. | ||||
|     let xy_plane = PlaneData::XY; | ||||
|     let plane = inner_start_sketch_on(xy_plane, args.clone()).await?; | ||||
|     let sketch_group = inner_start_profile_at(data, plane, args).await?; | ||||
|     let sketch_group = inner_start_profile_at(at, plane, tag, args).await?; | ||||
|     Ok(sketch_group) | ||||
| } | ||||
|  | ||||
| @ -820,9 +826,9 @@ async fn inner_start_sketch_on(data: PlaneData, args: Args) -> Result<Box<Plane> | ||||
|  | ||||
| /// Start a profile at a given point. | ||||
| pub async fn start_profile_at(args: Args) -> Result<MemoryItem, KclError> { | ||||
|     let (data, plane): (LineData, Box<Plane>) = args.get_data_and_plane()?; | ||||
|     let (data, plane, tag): ([f64; 2], Box<Plane>, _) = args.get_data_and_plane_then_tag()?; | ||||
|  | ||||
|     let sketch_group = inner_start_profile_at(data, plane, args).await?; | ||||
|     let sketch_group = inner_start_profile_at(data, plane, tag, args).await?; | ||||
|     Ok(MemoryItem::SketchGroup(sketch_group)) | ||||
| } | ||||
|  | ||||
| @ -830,11 +836,13 @@ pub async fn start_profile_at(args: Args) -> Result<MemoryItem, KclError> { | ||||
| #[stdlib { | ||||
|     name = "startProfileAt", | ||||
| }] | ||||
| async fn inner_start_profile_at(data: LineData, plane: Box<Plane>, args: Args) -> Result<Box<SketchGroup>, KclError> { | ||||
|     let to = match &data { | ||||
|         LineData::PointWithTag { to, .. } => *to, | ||||
|         LineData::Point(to) => *to, | ||||
|     }; | ||||
| async fn inner_start_profile_at( | ||||
|     point: [f64; 2], | ||||
|     plane: Box<Plane>, | ||||
|     tag: Option<String>, | ||||
|     args: Args, | ||||
| ) -> Result<Box<SketchGroup>, KclError> { | ||||
|     let to = point; | ||||
|  | ||||
|     let id = uuid::Uuid::new_v4(); | ||||
|     let path_id = uuid::Uuid::new_v4(); | ||||
| @ -856,11 +864,7 @@ async fn inner_start_profile_at(data: LineData, plane: Box<Plane>, args: Args) - | ||||
|     let current_path = BasePath { | ||||
|         from: to, | ||||
|         to, | ||||
|         name: if let LineData::PointWithTag { tag, .. } = data { | ||||
|             tag.to_string() | ||||
|         } else { | ||||
|             "".to_string() | ||||
|         }, | ||||
|         name: tag.unwrap_or_default(), | ||||
|         geo_meta: GeoMeta { | ||||
|             id, | ||||
|             metadata: args.source_range.into(), | ||||
|  | ||||
![github-actions[bot]](/assets/img/avatar_default.png)