|
|
|
@ -21,17 +21,12 @@ use crate::{
|
|
|
|
|
/// Data to draw a line to a point.
|
|
|
|
|
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
|
|
|
|
|
#[ts(export)]
|
|
|
|
|
#[serde(rename_all = "camelCase", untagged)]
|
|
|
|
|
pub enum LineToData {
|
|
|
|
|
/// A point with a tag.
|
|
|
|
|
PointWithTag {
|
|
|
|
|
/// The to point.
|
|
|
|
|
to: [f64; 2],
|
|
|
|
|
/// The tag.
|
|
|
|
|
tag: String,
|
|
|
|
|
},
|
|
|
|
|
/// A point.
|
|
|
|
|
Point([f64; 2]),
|
|
|
|
|
#[serde(rename_all = "camelCase")]
|
|
|
|
|
pub struct LineToData {
|
|
|
|
|
/// The to point.
|
|
|
|
|
to: [f64; 2],
|
|
|
|
|
/// The tag.
|
|
|
|
|
tag: Option<String>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Draw a line to a point.
|
|
|
|
@ -52,10 +47,6 @@ async fn inner_line_to(
|
|
|
|
|
args: Args,
|
|
|
|
|
) -> Result<Box<SketchGroup>, KclError> {
|
|
|
|
|
let from = sketch_group.get_coords_from_paths()?;
|
|
|
|
|
let to = match data {
|
|
|
|
|
LineToData::PointWithTag { to, .. } => to,
|
|
|
|
|
LineToData::Point(to) => to,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
let id = uuid::Uuid::new_v4();
|
|
|
|
|
|
|
|
|
@ -64,11 +55,7 @@ async fn inner_line_to(
|
|
|
|
|
ModelingCmd::ExtendPath {
|
|
|
|
|
path: sketch_group.id,
|
|
|
|
|
segment: kittycad::types::PathSegment::Line {
|
|
|
|
|
end: Point3D {
|
|
|
|
|
x: to[0],
|
|
|
|
|
y: to[1],
|
|
|
|
|
z: 0.0,
|
|
|
|
|
},
|
|
|
|
|
end: into_3d(data.to, 0.0),
|
|
|
|
|
relative: false,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
@ -78,12 +65,8 @@ async fn inner_line_to(
|
|
|
|
|
let current_path = Path::ToPoint {
|
|
|
|
|
base: BasePath {
|
|
|
|
|
from: from.into(),
|
|
|
|
|
to,
|
|
|
|
|
name: if let LineToData::PointWithTag { tag, .. } = data {
|
|
|
|
|
tag.to_string()
|
|
|
|
|
} else {
|
|
|
|
|
"".to_string()
|
|
|
|
|
},
|
|
|
|
|
to: data.to,
|
|
|
|
|
name: data.tag.unwrap_or_default(),
|
|
|
|
|
geo_meta: GeoMeta {
|
|
|
|
|
id,
|
|
|
|
|
metadata: args.source_range.into(),
|
|
|
|
@ -100,17 +83,12 @@ async fn inner_line_to(
|
|
|
|
|
/// Data to draw a line to a point on an axis.
|
|
|
|
|
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
|
|
|
|
|
#[ts(export)]
|
|
|
|
|
#[serde(rename_all = "camelCase", untagged)]
|
|
|
|
|
pub enum AxisLineToData {
|
|
|
|
|
/// A point with a tag.
|
|
|
|
|
PointWithTag {
|
|
|
|
|
/// The to point.
|
|
|
|
|
to: f64,
|
|
|
|
|
/// The tag.
|
|
|
|
|
tag: String,
|
|
|
|
|
},
|
|
|
|
|
/// A point.
|
|
|
|
|
Point(f64),
|
|
|
|
|
#[serde(rename_all = "camelCase")]
|
|
|
|
|
pub struct AxisLineToData {
|
|
|
|
|
/// The to point.
|
|
|
|
|
to: f64,
|
|
|
|
|
/// The tag.
|
|
|
|
|
tag: Option<String>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Draw a line to a point on the x-axis.
|
|
|
|
@ -132,9 +110,9 @@ async fn inner_x_line_to(
|
|
|
|
|
) -> Result<Box<SketchGroup>, KclError> {
|
|
|
|
|
let from = sketch_group.get_coords_from_paths()?;
|
|
|
|
|
|
|
|
|
|
let line_to_data = match data {
|
|
|
|
|
AxisLineToData::PointWithTag { to, tag } => LineToData::PointWithTag { to: [to, from.y], tag },
|
|
|
|
|
AxisLineToData::Point(data) => LineToData::Point([data, from.y]),
|
|
|
|
|
let line_to_data = LineToData {
|
|
|
|
|
to: [data.to, from.y],
|
|
|
|
|
tag: data.tag,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
let new_sketch_group = inner_line_to(line_to_data, sketch_group, args).await?;
|
|
|
|
@ -161,9 +139,9 @@ async fn inner_y_line_to(
|
|
|
|
|
) -> Result<Box<SketchGroup>, KclError> {
|
|
|
|
|
let from = sketch_group.get_coords_from_paths()?;
|
|
|
|
|
|
|
|
|
|
let line_to_data = match data {
|
|
|
|
|
AxisLineToData::PointWithTag { to, tag } => LineToData::PointWithTag { to: [from.x, to], tag },
|
|
|
|
|
AxisLineToData::Point(data) => LineToData::Point([from.x, data]),
|
|
|
|
|
let line_to_data = LineToData {
|
|
|
|
|
to: [data.to, from.y],
|
|
|
|
|
tag: data.tag,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
let new_sketch_group = inner_line_to(line_to_data, sketch_group, args).await?;
|
|
|
|
@ -173,17 +151,12 @@ async fn inner_y_line_to(
|
|
|
|
|
/// Data to draw a line.
|
|
|
|
|
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
|
|
|
|
|
#[ts(export)]
|
|
|
|
|
#[serde(rename_all = "camelCase", untagged)]
|
|
|
|
|
pub enum LineData {
|
|
|
|
|
/// A point with a tag.
|
|
|
|
|
PointWithTag {
|
|
|
|
|
/// The to point.
|
|
|
|
|
to: [f64; 2],
|
|
|
|
|
/// The tag.
|
|
|
|
|
tag: String,
|
|
|
|
|
},
|
|
|
|
|
/// A point.
|
|
|
|
|
Point([f64; 2]),
|
|
|
|
|
#[serde(rename_all = "camelCase")]
|
|
|
|
|
pub struct LineData {
|
|
|
|
|
/// The to point.
|
|
|
|
|
to: [f64; 2],
|
|
|
|
|
/// The tag.
|
|
|
|
|
tag: Option<String>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Draw a line.
|
|
|
|
@ -200,10 +173,7 @@ pub async fn line(args: Args) -> Result<MemoryItem, KclError> {
|
|
|
|
|
}]
|
|
|
|
|
async fn inner_line(data: LineData, sketch_group: Box<SketchGroup>, 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 inner_args = data.to;
|
|
|
|
|
|
|
|
|
|
let delta = inner_args;
|
|
|
|
|
let to = [from.x + inner_args[0], from.y + inner_args[1]];
|
|
|
|
@ -230,11 +200,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: data.tag.unwrap_or_default(),
|
|
|
|
|
geo_meta: GeoMeta {
|
|
|
|
|
id,
|
|
|
|
|
metadata: args.source_range.into(),
|
|
|
|
@ -282,8 +248,14 @@ async fn inner_x_line(
|
|
|
|
|
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]),
|
|
|
|
|
AxisLineData::LengthWithTag { length, tag } => LineData {
|
|
|
|
|
to: [length, 0.0],
|
|
|
|
|
tag: Some(tag),
|
|
|
|
|
},
|
|
|
|
|
AxisLineData::Length(length) => LineData {
|
|
|
|
|
to: [length, 0.0],
|
|
|
|
|
tag: None,
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
let new_sketch_group = inner_line(line_data, sketch_group, args).await?;
|
|
|
|
@ -308,8 +280,14 @@ async fn inner_y_line(
|
|
|
|
|
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]),
|
|
|
|
|
AxisLineData::LengthWithTag { length, tag } => LineData {
|
|
|
|
|
to: [length, 0.0],
|
|
|
|
|
tag: Some(tag),
|
|
|
|
|
},
|
|
|
|
|
AxisLineData::Length(length) => LineData {
|
|
|
|
|
to: [length, 0.0],
|
|
|
|
|
tag: None,
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
let new_sketch_group = inner_line(line_data, sketch_group, args).await?;
|
|
|
|
@ -336,11 +314,12 @@ pub enum AngledLineData {
|
|
|
|
|
|
|
|
|
|
impl AngledLineData {
|
|
|
|
|
pub fn into_inner_line(self, to: [f64; 2]) -> LineData {
|
|
|
|
|
if let AngledLineData::AngleWithTag { tag, .. } = self {
|
|
|
|
|
LineData::PointWithTag { to, tag }
|
|
|
|
|
let tag = if let AngledLineData::AngleWithTag { tag, .. } = self {
|
|
|
|
|
Some(tag)
|
|
|
|
|
} else {
|
|
|
|
|
LineData::Point(to)
|
|
|
|
|
}
|
|
|
|
|
None
|
|
|
|
|
};
|
|
|
|
|
LineData { to, tag }
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -465,9 +444,15 @@ pub enum AngledLineToData {
|
|
|
|
|
impl AngledLineToData {
|
|
|
|
|
pub fn into_inner_line(self, x_to: f64, y_to: f64) -> LineToData {
|
|
|
|
|
if let AngledLineToData::AngleWithTag { tag, .. } = self {
|
|
|
|
|
LineToData::PointWithTag { to: [x_to, y_to], tag }
|
|
|
|
|
LineToData {
|
|
|
|
|
to: [x_to, y_to],
|
|
|
|
|
tag: Some(tag),
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
LineToData::Point([x_to, y_to])
|
|
|
|
|
LineToData {
|
|
|
|
|
to: [x_to, y_to],
|
|
|
|
|
tag: None,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -617,10 +602,9 @@ async fn inner_angled_line_that_intersects(
|
|
|
|
|
from,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
let line_to_data = if let Some(tag) = data.tag {
|
|
|
|
|
LineToData::PointWithTag { to: to.into(), tag }
|
|
|
|
|
} else {
|
|
|
|
|
LineToData::Point(to.into())
|
|
|
|
|
let line_to_data = LineToData {
|
|
|
|
|
to: to.into(),
|
|
|
|
|
tag: data.tag,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
let new_sketch_group = inner_line_to(line_to_data, sketch_group, args).await?;
|
|
|
|
@ -831,10 +815,7 @@ pub async fn start_profile_at(args: Args) -> Result<MemoryItem, KclError> {
|
|
|
|
|
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,
|
|
|
|
|
};
|
|
|
|
|
let to = data.to;
|
|
|
|
|
|
|
|
|
|
let id = uuid::Uuid::new_v4();
|
|
|
|
|
let path_id = uuid::Uuid::new_v4();
|
|
|
|
@ -844,11 +825,7 @@ async fn inner_start_profile_at(data: LineData, plane: Box<Plane>, args: Args) -
|
|
|
|
|
id,
|
|
|
|
|
ModelingCmd::MovePathPen {
|
|
|
|
|
path: path_id,
|
|
|
|
|
to: Point3D {
|
|
|
|
|
x: to[0],
|
|
|
|
|
y: to[1],
|
|
|
|
|
z: 0.0,
|
|
|
|
|
},
|
|
|
|
|
to: into_3d(to, 0.0),
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
|
.await?;
|
|
|
|
@ -856,11 +833,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: data.tag.unwrap_or_default(),
|
|
|
|
|
geo_meta: GeoMeta {
|
|
|
|
|
id,
|
|
|
|
|
metadata: args.source_range.into(),
|
|
|
|
@ -1246,28 +1219,16 @@ async fn inner_tangential_arc_to(
|
|
|
|
|
/// Data to draw a bezier curve.
|
|
|
|
|
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
|
|
|
|
|
#[ts(export)]
|
|
|
|
|
#[serde(rename_all = "camelCase", untagged)]
|
|
|
|
|
pub enum BezierData {
|
|
|
|
|
/// Points with a tag.
|
|
|
|
|
PointsWithTag {
|
|
|
|
|
/// The to point.
|
|
|
|
|
to: [f64; 2],
|
|
|
|
|
/// The first control point.
|
|
|
|
|
control1: [f64; 2],
|
|
|
|
|
/// The second control point.
|
|
|
|
|
control2: [f64; 2],
|
|
|
|
|
/// The tag.
|
|
|
|
|
tag: String,
|
|
|
|
|
},
|
|
|
|
|
/// Points.
|
|
|
|
|
Points {
|
|
|
|
|
/// The to point.
|
|
|
|
|
to: [f64; 2],
|
|
|
|
|
/// The first control point.
|
|
|
|
|
control1: [f64; 2],
|
|
|
|
|
/// The second control point.
|
|
|
|
|
control2: [f64; 2],
|
|
|
|
|
},
|
|
|
|
|
#[serde(rename_all = "camelCase")]
|
|
|
|
|
pub struct BezierData {
|
|
|
|
|
/// The to point.
|
|
|
|
|
to: [f64; 2],
|
|
|
|
|
/// The first control point.
|
|
|
|
|
control1: [f64; 2],
|
|
|
|
|
/// The second control point.
|
|
|
|
|
control2: [f64; 2],
|
|
|
|
|
/// The tag.
|
|
|
|
|
tag: Option<String>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Draw a bezier curve.
|
|
|
|
@ -1289,12 +1250,12 @@ async fn inner_bezier_curve(
|
|
|
|
|
) -> Result<Box<SketchGroup>, KclError> {
|
|
|
|
|
let from = sketch_group.get_coords_from_paths()?;
|
|
|
|
|
|
|
|
|
|
let (to, control1, control2) = match &data {
|
|
|
|
|
BezierData::PointsWithTag {
|
|
|
|
|
to, control1, control2, ..
|
|
|
|
|
} => (to, control1, control2),
|
|
|
|
|
BezierData::Points { to, control1, control2 } => (to, control1, control2),
|
|
|
|
|
};
|
|
|
|
|
let BezierData {
|
|
|
|
|
to,
|
|
|
|
|
control1,
|
|
|
|
|
control2,
|
|
|
|
|
tag,
|
|
|
|
|
} = data;
|
|
|
|
|
|
|
|
|
|
let relative = true;
|
|
|
|
|
let delta = to;
|
|
|
|
@ -1307,21 +1268,9 @@ async fn inner_bezier_curve(
|
|
|
|
|
ModelingCmd::ExtendPath {
|
|
|
|
|
path: sketch_group.id,
|
|
|
|
|
segment: kittycad::types::PathSegment::Bezier {
|
|
|
|
|
control1: Point3D {
|
|
|
|
|
x: control1[0],
|
|
|
|
|
y: control1[1],
|
|
|
|
|
z: 0.0,
|
|
|
|
|
},
|
|
|
|
|
control2: Point3D {
|
|
|
|
|
x: control2[0],
|
|
|
|
|
y: control2[1],
|
|
|
|
|
z: 0.0,
|
|
|
|
|
},
|
|
|
|
|
end: Point3D {
|
|
|
|
|
x: delta[0],
|
|
|
|
|
y: delta[1],
|
|
|
|
|
z: 0.0,
|
|
|
|
|
},
|
|
|
|
|
control1: into_3d(control1, 0.0),
|
|
|
|
|
control2: into_3d(control2, 0.0),
|
|
|
|
|
end: into_3d(delta, 0.0),
|
|
|
|
|
relative,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
@ -1332,11 +1281,7 @@ async fn inner_bezier_curve(
|
|
|
|
|
base: BasePath {
|
|
|
|
|
from: from.into(),
|
|
|
|
|
to,
|
|
|
|
|
name: if let BezierData::PointsWithTag { tag, .. } = data {
|
|
|
|
|
tag.to_string()
|
|
|
|
|
} else {
|
|
|
|
|
"".to_string()
|
|
|
|
|
},
|
|
|
|
|
name: tag.unwrap_or_default(),
|
|
|
|
|
geo_meta: GeoMeta {
|
|
|
|
|
id,
|
|
|
|
|
metadata: args.source_range.into(),
|
|
|
|
@ -1394,6 +1339,11 @@ async fn inner_hole(
|
|
|
|
|
Ok(sketch_group)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Make a 3D point from the given 2D (X,Y) point and a Z component.
|
|
|
|
|
fn into_3d([x, y]: [f64; 2], z: f64) -> Point3D {
|
|
|
|
|
Point3D { x, y, z }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
|
mod tests {
|
|
|
|
|
|
|
|
|
@ -1403,21 +1353,30 @@ mod tests {
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_deserialize_line_data() {
|
|
|
|
|
let data = LineData::Point([0.0, 1.0]);
|
|
|
|
|
let data = LineData {
|
|
|
|
|
to: [0.0, 1.0],
|
|
|
|
|
tag: None,
|
|
|
|
|
};
|
|
|
|
|
let mut str_json = serde_json::to_string(&data).unwrap();
|
|
|
|
|
assert_eq!(str_json, "[0.0,1.0]");
|
|
|
|
|
|
|
|
|
|
str_json = "[0, 1]".to_string();
|
|
|
|
|
let data: LineData = serde_json::from_str(&str_json).unwrap();
|
|
|
|
|
assert_eq!(data, LineData::Point([0.0, 1.0]));
|
|
|
|
|
assert_eq!(
|
|
|
|
|
data,
|
|
|
|
|
LineData {
|
|
|
|
|
to: [0.0, 1.0],
|
|
|
|
|
tag: None
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
str_json = "{ \"to\": [0.0, 1.0], \"tag\": \"thing\" }".to_string();
|
|
|
|
|
let data: LineData = serde_json::from_str(&str_json).unwrap();
|
|
|
|
|
assert_eq!(
|
|
|
|
|
data,
|
|
|
|
|
LineData::PointWithTag {
|
|
|
|
|
LineData {
|
|
|
|
|
to: [0.0, 1.0],
|
|
|
|
|
tag: "thing".to_string()
|
|
|
|
|
tag: Some("thing".to_string()),
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|