Compare commits

...

3 Commits

11 changed files with 100 additions and 45 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 72 KiB

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 72 KiB

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 72 KiB

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

After

Width:  |  Height:  |  Size: 57 KiB

View File

@ -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> {

View File

@ -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(),