Turn on units of measure (BREAKING CHANGE) (#6343)
* Turn on uom checks Signed-off-by: Nick Cameron <nrc@ncameron.org> * Convert all lengths to mm for engine calls Signed-off-by: Nick Cameron <nrc@ncameron.org> --------- Signed-off-by: Nick Cameron <nrc@ncameron.org>
This commit is contained in:
@ -12,11 +12,11 @@ use parse_display::{Display, FromStr};
|
||||
use schemars::JsonSchema;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use super::utils::untype_point;
|
||||
use super::utils::{point_to_len_unit, point_to_mm, untype_point, untyped_point_to_mm};
|
||||
use crate::{
|
||||
errors::{KclError, KclErrorDetails},
|
||||
execution::{
|
||||
types::{PrimitiveType, RuntimeType, UnitLen},
|
||||
types::{NumericType, PrimitiveType, RuntimeType, UnitLen},
|
||||
Artifact, ArtifactId, BasePath, CodeRef, ExecState, Face, GeoMeta, KclValue, Path, Plane, Point2d, Point3d,
|
||||
Sketch, SketchSurface, Solid, StartSketchOnFace, StartSketchOnPlane, TagEngineInfo, TagIdentifier,
|
||||
},
|
||||
@ -200,7 +200,7 @@ async fn inner_involute_circular(
|
||||
|
||||
let current_path = Path::ToPoint {
|
||||
base: BasePath {
|
||||
from: from.into(),
|
||||
from: from.ignore_units(),
|
||||
to: [end.x, end.y],
|
||||
tag: tag.clone(),
|
||||
units: sketch.units,
|
||||
@ -226,15 +226,7 @@ pub async fn line(exec_state: &mut ExecState, args: Args) -> Result<KclValue, Kc
|
||||
let end_absolute = args.get_kw_arg_opt_typed("endAbsolute", &RuntimeType::point2d(), exec_state)?;
|
||||
let tag = args.get_kw_arg_opt(NEW_TAG_KW)?;
|
||||
|
||||
let new_sketch = inner_line(
|
||||
sketch,
|
||||
end_absolute.map(|p| untype_point(p).0),
|
||||
end.map(|p| untype_point(p).0),
|
||||
tag,
|
||||
exec_state,
|
||||
args,
|
||||
)
|
||||
.await?;
|
||||
let new_sketch = inner_line(sketch, end_absolute, end, tag, exec_state, args).await?;
|
||||
Ok(KclValue::Sketch {
|
||||
value: Box::new(new_sketch),
|
||||
})
|
||||
@ -277,8 +269,8 @@ pub async fn line(exec_state: &mut ExecState, args: Args) -> Result<KclValue, Kc
|
||||
}]
|
||||
async fn inner_line(
|
||||
sketch: Sketch,
|
||||
end_absolute: Option<[f64; 2]>,
|
||||
end: Option<[f64; 2]>,
|
||||
end_absolute: Option<[TyF64; 2]>,
|
||||
end: Option<[TyF64; 2]>,
|
||||
tag: Option<TagNode>,
|
||||
exec_state: &mut ExecState,
|
||||
args: Args,
|
||||
@ -298,13 +290,13 @@ async fn inner_line(
|
||||
|
||||
struct StraightLineParams {
|
||||
sketch: Sketch,
|
||||
end_absolute: Option<[f64; 2]>,
|
||||
end: Option<[f64; 2]>,
|
||||
end_absolute: Option<[TyF64; 2]>,
|
||||
end: Option<[TyF64; 2]>,
|
||||
tag: Option<TagNode>,
|
||||
}
|
||||
|
||||
impl StraightLineParams {
|
||||
fn relative(p: [f64; 2], sketch: Sketch, tag: Option<TagNode>) -> Self {
|
||||
fn relative(p: [TyF64; 2], sketch: Sketch, tag: Option<TagNode>) -> Self {
|
||||
Self {
|
||||
sketch,
|
||||
tag,
|
||||
@ -312,7 +304,7 @@ impl StraightLineParams {
|
||||
end_absolute: None,
|
||||
}
|
||||
}
|
||||
fn absolute(p: [f64; 2], sketch: Sketch, tag: Option<TagNode>) -> Self {
|
||||
fn absolute(p: [TyF64; 2], sketch: Sketch, tag: Option<TagNode>) -> Self {
|
||||
Self {
|
||||
sketch,
|
||||
tag,
|
||||
@ -357,7 +349,7 @@ async fn straight_line(
|
||||
ModelingCmd::from(mcmd::ExtendPath {
|
||||
path: sketch.id.into(),
|
||||
segment: PathSegment::Line {
|
||||
end: KPoint2d::from(point).with_z(0.0).map(LengthUnit),
|
||||
end: KPoint2d::from(point_to_mm(point.clone())).with_z(0.0).map(LengthUnit),
|
||||
relative: !is_absolute,
|
||||
},
|
||||
}),
|
||||
@ -365,15 +357,16 @@ async fn straight_line(
|
||||
.await?;
|
||||
|
||||
let end = if is_absolute {
|
||||
point
|
||||
point_to_len_unit(point, from.units)
|
||||
} else {
|
||||
let from = sketch.current_pen_position()?;
|
||||
let point = point_to_len_unit(point, from.units);
|
||||
[from.x + point[0], from.y + point[1]]
|
||||
};
|
||||
|
||||
let current_path = Path::ToPoint {
|
||||
base: BasePath {
|
||||
from: from.into(),
|
||||
from: from.ignore_units(),
|
||||
to: end,
|
||||
tag: tag.clone(),
|
||||
units: sketch.units,
|
||||
@ -402,15 +395,7 @@ pub async fn x_line(exec_state: &mut ExecState, args: Args) -> Result<KclValue,
|
||||
let end_absolute: Option<TyF64> = args.get_kw_arg_opt_typed("endAbsolute", &RuntimeType::length(), exec_state)?;
|
||||
let tag = args.get_kw_arg_opt(NEW_TAG_KW)?;
|
||||
|
||||
let new_sketch = inner_x_line(
|
||||
sketch,
|
||||
length.map(|t| t.n),
|
||||
end_absolute.map(|t| t.n),
|
||||
tag,
|
||||
exec_state,
|
||||
args,
|
||||
)
|
||||
.await?;
|
||||
let new_sketch = inner_x_line(sketch, length, end_absolute, tag, exec_state, args).await?;
|
||||
Ok(KclValue::Sketch {
|
||||
value: Box::new(new_sketch),
|
||||
})
|
||||
@ -451,8 +436,8 @@ pub async fn x_line(exec_state: &mut ExecState, args: Args) -> Result<KclValue,
|
||||
}]
|
||||
async fn inner_x_line(
|
||||
sketch: Sketch,
|
||||
length: Option<f64>,
|
||||
end_absolute: Option<f64>,
|
||||
length: Option<TyF64>,
|
||||
end_absolute: Option<TyF64>,
|
||||
tag: Option<TagNode>,
|
||||
exec_state: &mut ExecState,
|
||||
args: Args,
|
||||
@ -461,8 +446,8 @@ async fn inner_x_line(
|
||||
straight_line(
|
||||
StraightLineParams {
|
||||
sketch,
|
||||
end_absolute: end_absolute.map(|x| [x, from.y]),
|
||||
end: length.map(|x| [x, 0.0]),
|
||||
end_absolute: end_absolute.map(|x| [x, from.into_y()]),
|
||||
end: length.map(|x| [x, TyF64::new(0.0, NumericType::mm())]),
|
||||
tag,
|
||||
},
|
||||
exec_state,
|
||||
@ -479,15 +464,7 @@ pub async fn y_line(exec_state: &mut ExecState, args: Args) -> Result<KclValue,
|
||||
let end_absolute: Option<TyF64> = args.get_kw_arg_opt_typed("endAbsolute", &RuntimeType::length(), exec_state)?;
|
||||
let tag = args.get_kw_arg_opt(NEW_TAG_KW)?;
|
||||
|
||||
let new_sketch = inner_y_line(
|
||||
sketch,
|
||||
length.map(|t| t.n),
|
||||
end_absolute.map(|t| t.n),
|
||||
tag,
|
||||
exec_state,
|
||||
args,
|
||||
)
|
||||
.await?;
|
||||
let new_sketch = inner_y_line(sketch, length, end_absolute, tag, exec_state, args).await?;
|
||||
Ok(KclValue::Sketch {
|
||||
value: Box::new(new_sketch),
|
||||
})
|
||||
@ -523,8 +500,8 @@ pub async fn y_line(exec_state: &mut ExecState, args: Args) -> Result<KclValue,
|
||||
}]
|
||||
async fn inner_y_line(
|
||||
sketch: Sketch,
|
||||
length: Option<f64>,
|
||||
end_absolute: Option<f64>,
|
||||
length: Option<TyF64>,
|
||||
end_absolute: Option<TyF64>,
|
||||
tag: Option<TagNode>,
|
||||
exec_state: &mut ExecState,
|
||||
args: Args,
|
||||
@ -533,8 +510,8 @@ async fn inner_y_line(
|
||||
straight_line(
|
||||
StraightLineParams {
|
||||
sketch,
|
||||
end_absolute: end_absolute.map(|y| [from.x, y]),
|
||||
end: length.map(|y| [0.0, y]),
|
||||
end_absolute: end_absolute.map(|y| [from.into_x(), y]),
|
||||
end: length.map(|y| [TyF64::new(0.0, NumericType::mm()), y]),
|
||||
tag,
|
||||
},
|
||||
exec_state,
|
||||
@ -559,11 +536,11 @@ pub async fn angled_line(exec_state: &mut ExecState, args: Args) -> Result<KclVa
|
||||
let new_sketch = inner_angled_line(
|
||||
sketch,
|
||||
angle.n,
|
||||
length.map(|t| t.n),
|
||||
length_x.map(|t| t.n),
|
||||
length_y.map(|t| t.n),
|
||||
end_absolute_x.map(|t| t.n),
|
||||
end_absolute_y.map(|t| t.n),
|
||||
length,
|
||||
length_x,
|
||||
length_y,
|
||||
end_absolute_x,
|
||||
end_absolute_y,
|
||||
tag,
|
||||
exec_state,
|
||||
args,
|
||||
@ -610,16 +587,16 @@ pub async fn angled_line(exec_state: &mut ExecState, args: Args) -> Result<KclVa
|
||||
async fn inner_angled_line(
|
||||
sketch: Sketch,
|
||||
angle: f64,
|
||||
length: Option<f64>,
|
||||
length_x: Option<f64>,
|
||||
length_y: Option<f64>,
|
||||
end_absolute_x: Option<f64>,
|
||||
end_absolute_y: Option<f64>,
|
||||
length: Option<TyF64>,
|
||||
length_x: Option<TyF64>,
|
||||
length_y: Option<TyF64>,
|
||||
end_absolute_x: Option<TyF64>,
|
||||
end_absolute_y: Option<TyF64>,
|
||||
tag: Option<TagNode>,
|
||||
exec_state: &mut ExecState,
|
||||
args: Args,
|
||||
) -> Result<Sketch, KclError> {
|
||||
let options_given = [length, length_x, length_y, end_absolute_x, end_absolute_y]
|
||||
let options_given = [&length, &length_x, &length_y, &end_absolute_x, &end_absolute_y]
|
||||
.iter()
|
||||
.filter(|x| x.is_some())
|
||||
.count();
|
||||
@ -667,12 +644,13 @@ async fn inner_angled_line(
|
||||
async fn inner_angled_line_length(
|
||||
sketch: Sketch,
|
||||
angle_degrees: f64,
|
||||
length: f64,
|
||||
length: TyF64,
|
||||
tag: Option<TagNode>,
|
||||
exec_state: &mut ExecState,
|
||||
args: Args,
|
||||
) -> Result<Sketch, KclError> {
|
||||
let from = sketch.current_pen_position()?;
|
||||
let length = length.to_length_units(from.units);
|
||||
|
||||
//double check me on this one - mike
|
||||
let delta: [f64; 2] = [
|
||||
@ -690,7 +668,9 @@ async fn inner_angled_line_length(
|
||||
ModelingCmd::from(mcmd::ExtendPath {
|
||||
path: sketch.id.into(),
|
||||
segment: PathSegment::Line {
|
||||
end: KPoint2d::from(delta).with_z(0.0).map(LengthUnit),
|
||||
end: KPoint2d::from(untyped_point_to_mm(delta, from.units))
|
||||
.with_z(0.0)
|
||||
.map(LengthUnit),
|
||||
relative,
|
||||
},
|
||||
}),
|
||||
@ -699,7 +679,7 @@ async fn inner_angled_line_length(
|
||||
|
||||
let current_path = Path::ToPoint {
|
||||
base: BasePath {
|
||||
from: from.into(),
|
||||
from: from.ignore_units(),
|
||||
to,
|
||||
tag: tag.clone(),
|
||||
units: sketch.units,
|
||||
@ -721,7 +701,7 @@ async fn inner_angled_line_length(
|
||||
|
||||
async fn inner_angled_line_of_x_length(
|
||||
angle_degrees: f64,
|
||||
length: f64,
|
||||
length: TyF64,
|
||||
sketch: Sketch,
|
||||
tag: Option<TagNode>,
|
||||
exec_state: &mut ExecState,
|
||||
@ -741,7 +721,8 @@ async fn inner_angled_line_of_x_length(
|
||||
}));
|
||||
}
|
||||
|
||||
let to = get_y_component(Angle::from_degrees(angle_degrees), length);
|
||||
let to = get_y_component(Angle::from_degrees(angle_degrees), length.n);
|
||||
let to = [TyF64::new(to[0], length.ty.clone()), TyF64::new(to[1], length.ty)];
|
||||
|
||||
let new_sketch = straight_line(StraightLineParams::relative(to, sketch, tag), exec_state, args).await?;
|
||||
|
||||
@ -750,7 +731,7 @@ async fn inner_angled_line_of_x_length(
|
||||
|
||||
async fn inner_angled_line_to_x(
|
||||
angle_degrees: f64,
|
||||
x_to: f64,
|
||||
x_to: TyF64,
|
||||
sketch: Sketch,
|
||||
tag: Option<TagNode>,
|
||||
exec_state: &mut ExecState,
|
||||
@ -772,12 +753,12 @@ async fn inner_angled_line_to_x(
|
||||
}));
|
||||
}
|
||||
|
||||
let x_component = x_to - from.x;
|
||||
let x_component = x_to.to_length_units(from.units) - from.x;
|
||||
let y_component = x_component * f64::tan(angle_degrees.to_radians());
|
||||
let y_to = from.y + y_component;
|
||||
|
||||
let new_sketch = straight_line(
|
||||
StraightLineParams::absolute([x_to, y_to], sketch, tag),
|
||||
StraightLineParams::absolute([x_to, TyF64::new(y_to, from.units.into())], sketch, tag),
|
||||
exec_state,
|
||||
args,
|
||||
)
|
||||
@ -787,7 +768,7 @@ async fn inner_angled_line_to_x(
|
||||
|
||||
async fn inner_angled_line_of_y_length(
|
||||
angle_degrees: f64,
|
||||
length: f64,
|
||||
length: TyF64,
|
||||
sketch: Sketch,
|
||||
tag: Option<TagNode>,
|
||||
exec_state: &mut ExecState,
|
||||
@ -807,7 +788,8 @@ async fn inner_angled_line_of_y_length(
|
||||
}));
|
||||
}
|
||||
|
||||
let to = get_x_component(Angle::from_degrees(angle_degrees), length);
|
||||
let to = get_x_component(Angle::from_degrees(angle_degrees), length.n);
|
||||
let to = [TyF64::new(to[0], length.ty.clone()), TyF64::new(to[1], length.ty)];
|
||||
|
||||
let new_sketch = straight_line(StraightLineParams::relative(to, sketch, tag), exec_state, args).await?;
|
||||
|
||||
@ -816,7 +798,7 @@ async fn inner_angled_line_of_y_length(
|
||||
|
||||
async fn inner_angled_line_to_y(
|
||||
angle_degrees: f64,
|
||||
y_to: f64,
|
||||
y_to: TyF64,
|
||||
sketch: Sketch,
|
||||
tag: Option<TagNode>,
|
||||
exec_state: &mut ExecState,
|
||||
@ -838,12 +820,12 @@ async fn inner_angled_line_to_y(
|
||||
}));
|
||||
}
|
||||
|
||||
let y_component = y_to - from.y;
|
||||
let y_component = y_to.to_length_units(from.units) - from.y;
|
||||
let x_component = y_component / f64::tan(angle_degrees.to_radians());
|
||||
let x_to = from.x + x_component;
|
||||
|
||||
let new_sketch = straight_line(
|
||||
StraightLineParams::absolute([x_to, y_to], sketch, tag),
|
||||
StraightLineParams::absolute([TyF64::new(x_to, from.units.into()), y_to], sketch, tag),
|
||||
exec_state,
|
||||
args,
|
||||
)
|
||||
@ -916,11 +898,18 @@ pub async fn inner_angled_line_that_intersects(
|
||||
|
||||
let from = sketch.current_pen_position()?;
|
||||
let to = intersection_with_parallel_line(
|
||||
&[untype_point(path.get_from()).0, untype_point(path.get_to()).0],
|
||||
offset.map(|t| t.n).unwrap_or_default(),
|
||||
angle.n,
|
||||
from.into(),
|
||||
&[
|
||||
point_to_len_unit(path.get_from(), from.units),
|
||||
point_to_len_unit(path.get_to(), from.units),
|
||||
],
|
||||
offset.map(|t| t.to_length_units(from.units)).unwrap_or_default(),
|
||||
angle.to_degrees(),
|
||||
from.ignore_units(),
|
||||
);
|
||||
let to = [
|
||||
TyF64::new(to[0], from.units.into()),
|
||||
TyF64::new(to[1], from.units.into()),
|
||||
];
|
||||
|
||||
straight_line(StraightLineParams::absolute(to, sketch, tag), exec_state, args).await
|
||||
}
|
||||
@ -1309,7 +1298,7 @@ async fn make_sketch_plane_from_orientation(
|
||||
pub async fn start_profile_at(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
||||
let (start, sketch_surface, tag) = args.get_data_and_sketch_surface()?;
|
||||
|
||||
let sketch = inner_start_profile_at([start[0].n, start[1].n], sketch_surface, tag, exec_state, args).await?;
|
||||
let sketch = inner_start_profile_at(start, sketch_surface, tag, exec_state, args).await?;
|
||||
Ok(KclValue::Sketch {
|
||||
value: Box::new(sketch),
|
||||
})
|
||||
@ -1353,7 +1342,7 @@ pub async fn start_profile_at(exec_state: &mut ExecState, args: Args) -> Result<
|
||||
name = "startProfileAt",
|
||||
}]
|
||||
pub(crate) async fn inner_start_profile_at(
|
||||
to: [f64; 2],
|
||||
to: [TyF64; 2],
|
||||
sketch_surface: SketchSurface,
|
||||
tag: Option<TagNode>,
|
||||
exec_state: &mut ExecState,
|
||||
@ -1409,7 +1398,7 @@ pub(crate) async fn inner_start_profile_at(
|
||||
ModelingCmdReq {
|
||||
cmd: ModelingCmd::from(mcmd::MovePathPen {
|
||||
path: path_id.into(),
|
||||
to: KPoint2d::from(to).with_z(0.0).map(LengthUnit),
|
||||
to: KPoint2d::from(point_to_mm(to.clone())).with_z(0.0).map(LengthUnit),
|
||||
}),
|
||||
cmd_id: move_pen_id.into(),
|
||||
},
|
||||
@ -1420,11 +1409,12 @@ pub(crate) async fn inner_start_profile_at(
|
||||
])
|
||||
.await?;
|
||||
|
||||
let (to, ty) = untype_point(to);
|
||||
let current_path = BasePath {
|
||||
from: to,
|
||||
to,
|
||||
tag: tag.clone(),
|
||||
units: sketch_surface.units(),
|
||||
units: ty.expect_length(),
|
||||
geo_meta: GeoMeta {
|
||||
id: move_pen_id,
|
||||
metadata: args.source_range.into(),
|
||||
@ -1437,7 +1427,7 @@ pub(crate) async fn inner_start_profile_at(
|
||||
artifact_id: path_id.into(),
|
||||
on: sketch_surface.clone(),
|
||||
paths: vec![],
|
||||
units: sketch_surface.units(),
|
||||
units: ty.expect_length(),
|
||||
mirror: Default::default(),
|
||||
meta: vec![args.source_range.into()],
|
||||
tags: if let Some(tag) = &tag {
|
||||
@ -1586,7 +1576,7 @@ pub(crate) async fn inner_close(
|
||||
args: Args,
|
||||
) -> Result<Sketch, KclError> {
|
||||
let from = sketch.current_pen_position()?;
|
||||
let to: Point2d = sketch.start.get_from().into();
|
||||
let to = point_to_len_unit(sketch.start.get_from(), from.units);
|
||||
|
||||
let id = exec_state.next_uuid();
|
||||
|
||||
@ -1595,8 +1585,8 @@ pub(crate) async fn inner_close(
|
||||
|
||||
let current_path = Path::ToPoint {
|
||||
base: BasePath {
|
||||
from: from.into(),
|
||||
to: to.into(),
|
||||
from: from.ignore_units(),
|
||||
to,
|
||||
tag: tag.clone(),
|
||||
units: sketch.units,
|
||||
geo_meta: GeoMeta {
|
||||
@ -1708,7 +1698,6 @@ pub(crate) async fn inner_arc(
|
||||
let from: Point2d = sketch.current_pen_position()?;
|
||||
let id = exec_state.next_uuid();
|
||||
|
||||
// Relative case
|
||||
match (angle_start, angle_end, radius, interior_absolute, end_absolute) {
|
||||
(Some(angle_start), Some(angle_end), Some(radius), None, None) => {
|
||||
relative_arc(&args, id, exec_state, sketch, from, angle_start, angle_end, radius, tag).await
|
||||
@ -1745,13 +1734,13 @@ pub async fn absolute_arc(
|
||||
path: sketch.id.into(),
|
||||
segment: PathSegment::ArcTo {
|
||||
end: kcmc::shared::Point3d {
|
||||
x: LengthUnit(end_absolute[0].n),
|
||||
y: LengthUnit(end_absolute[1].n),
|
||||
x: LengthUnit(end_absolute[0].to_mm()),
|
||||
y: LengthUnit(end_absolute[1].to_mm()),
|
||||
z: LengthUnit(0.0),
|
||||
},
|
||||
interior: kcmc::shared::Point3d {
|
||||
x: LengthUnit(interior_absolute[0].n),
|
||||
y: LengthUnit(interior_absolute[1].n),
|
||||
x: LengthUnit(interior_absolute[0].to_mm()),
|
||||
y: LengthUnit(interior_absolute[1].to_mm()),
|
||||
z: LengthUnit(0.0),
|
||||
},
|
||||
relative: false,
|
||||
@ -1761,13 +1750,12 @@ pub async fn absolute_arc(
|
||||
.await?;
|
||||
|
||||
let start = [from.x, from.y];
|
||||
let end = end_absolute.clone();
|
||||
let untyped_end = untype_point(end);
|
||||
let end = point_to_len_unit(end_absolute, from.units);
|
||||
|
||||
let current_path = Path::ArcThreePoint {
|
||||
base: BasePath {
|
||||
from: from.into(),
|
||||
to: untyped_end.0,
|
||||
from: from.ignore_units(),
|
||||
to: end,
|
||||
tag: tag.clone(),
|
||||
units: sketch.units,
|
||||
geo_meta: GeoMeta {
|
||||
@ -1776,8 +1764,8 @@ pub async fn absolute_arc(
|
||||
},
|
||||
},
|
||||
p1: start,
|
||||
p2: untype_point(interior_absolute).0,
|
||||
p3: untyped_end.0,
|
||||
p2: point_to_len_unit(interior_absolute, from.units),
|
||||
p3: end,
|
||||
};
|
||||
|
||||
let mut new_sketch = sketch.clone();
|
||||
@ -1802,16 +1790,17 @@ pub async fn relative_arc(
|
||||
radius: TyF64,
|
||||
tag: Option<TagNode>,
|
||||
) -> Result<Sketch, KclError> {
|
||||
let a_start = Angle::from_degrees(angle_start.n);
|
||||
let a_end = Angle::from_degrees(angle_end.n);
|
||||
let (center, end) = arc_center_and_end(from.into(), a_start, a_end, radius.n);
|
||||
if angle_start == angle_end {
|
||||
let a_start = Angle::from_degrees(angle_start.to_degrees());
|
||||
let a_end = Angle::from_degrees(angle_end.to_degrees());
|
||||
let radius = radius.to_length_units(from.units);
|
||||
let (center, end) = arc_center_and_end(from.ignore_units(), a_start, a_end, radius);
|
||||
if a_start == a_end {
|
||||
return Err(KclError::Type(KclErrorDetails {
|
||||
message: "Arc start and end angles must be different".to_string(),
|
||||
source_ranges: vec![args.source_range],
|
||||
}));
|
||||
}
|
||||
let ccw = angle_start.n < angle_end.n;
|
||||
let ccw = a_start < a_end;
|
||||
|
||||
args.batch_modeling_cmd(
|
||||
id,
|
||||
@ -1820,8 +1809,8 @@ pub async fn relative_arc(
|
||||
segment: PathSegment::Arc {
|
||||
start: a_start,
|
||||
end: a_end,
|
||||
center: KPoint2d::from(center).map(LengthUnit),
|
||||
radius: LengthUnit(radius.n),
|
||||
center: KPoint2d::from(untyped_point_to_mm(center, from.units)).map(LengthUnit),
|
||||
radius: LengthUnit(from.units.adjust_to(radius, UnitLen::Mm).0),
|
||||
relative: false,
|
||||
},
|
||||
}),
|
||||
@ -1830,17 +1819,17 @@ pub async fn relative_arc(
|
||||
|
||||
let current_path = Path::Arc {
|
||||
base: BasePath {
|
||||
from: from.into(),
|
||||
from: from.ignore_units(),
|
||||
to: end,
|
||||
tag: tag.clone(),
|
||||
units: sketch.units,
|
||||
units: from.units,
|
||||
geo_meta: GeoMeta {
|
||||
id,
|
||||
metadata: args.source_range.into(),
|
||||
},
|
||||
},
|
||||
center,
|
||||
radius: radius.n,
|
||||
radius,
|
||||
ccw,
|
||||
};
|
||||
|
||||
@ -1853,6 +1842,7 @@ pub async fn relative_arc(
|
||||
|
||||
Ok(new_sketch)
|
||||
}
|
||||
|
||||
/// Draw a tangential arc to a specific point.
|
||||
pub async fn tangential_arc(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
||||
let sketch =
|
||||
@ -1863,17 +1853,7 @@ pub async fn tangential_arc(exec_state: &mut ExecState, args: Args) -> Result<Kc
|
||||
let angle = args.get_kw_arg_opt_typed("angle", &RuntimeType::angle(), exec_state)?;
|
||||
let tag = args.get_kw_arg_opt(NEW_TAG_KW)?;
|
||||
|
||||
let new_sketch = inner_tangential_arc(
|
||||
sketch,
|
||||
end_absolute.map(|p| untype_point(p).0),
|
||||
end.map(|p| untype_point(p).0),
|
||||
radius,
|
||||
angle,
|
||||
tag,
|
||||
exec_state,
|
||||
args,
|
||||
)
|
||||
.await?;
|
||||
let new_sketch = inner_tangential_arc(sketch, end_absolute, end, radius, angle, tag, exec_state, args).await?;
|
||||
Ok(KclValue::Sketch {
|
||||
value: Box::new(new_sketch),
|
||||
})
|
||||
@ -1949,8 +1929,8 @@ pub async fn tangential_arc(exec_state: &mut ExecState, args: Args) -> Result<Kc
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
async fn inner_tangential_arc(
|
||||
sketch: Sketch,
|
||||
end_absolute: Option<[f64; 2]>,
|
||||
end: Option<[f64; 2]>,
|
||||
end_absolute: Option<[TyF64; 2]>,
|
||||
end: Option<[TyF64; 2]>,
|
||||
radius: Option<TyF64>,
|
||||
angle: Option<TyF64>,
|
||||
tag: Option<TagNode>,
|
||||
@ -2014,14 +1994,14 @@ async fn inner_tangential_arc_radius_angle(
|
||||
let from: Point2d = sketch.current_pen_position()?;
|
||||
// next set of lines is some undocumented voodoo from get_tangential_arc_to_info
|
||||
let tangent_info = sketch.get_tangential_info_from_paths(); //this function desperately needs some documentation
|
||||
let tan_previous_point = tangent_info.tan_previous_point(from.into());
|
||||
let tan_previous_point = tangent_info.tan_previous_point(from.ignore_units());
|
||||
|
||||
let id = exec_state.next_uuid();
|
||||
|
||||
let (center, to, ccw) = match data {
|
||||
TangentialArcData::RadiusAndOffset { radius, offset } => {
|
||||
// KCL stdlib types use degrees.
|
||||
let offset = Angle::from_degrees(offset.n);
|
||||
let offset = Angle::from_degrees(offset.to_degrees());
|
||||
|
||||
// Calculate the end point from the angle and radius.
|
||||
// atan2 outputs radians.
|
||||
@ -2043,14 +2023,19 @@ async fn inner_tangential_arc_radius_angle(
|
||||
// but the above logic *should* capture that behavior
|
||||
let start_angle = previous_end_tangent + tangent_to_arc_start_angle;
|
||||
let end_angle = start_angle + offset;
|
||||
let (center, to) = arc_center_and_end(from.into(), start_angle, end_angle, radius.n);
|
||||
let (center, to) = arc_center_and_end(
|
||||
from.ignore_units(),
|
||||
start_angle,
|
||||
end_angle,
|
||||
radius.to_length_units(from.units),
|
||||
);
|
||||
|
||||
args.batch_modeling_cmd(
|
||||
id,
|
||||
ModelingCmd::from(mcmd::ExtendPath {
|
||||
path: sketch.id.into(),
|
||||
segment: PathSegment::TangentialArc {
|
||||
radius: LengthUnit(radius.n),
|
||||
radius: LengthUnit(radius.to_mm()),
|
||||
offset,
|
||||
},
|
||||
}),
|
||||
@ -2064,7 +2049,7 @@ async fn inner_tangential_arc_radius_angle(
|
||||
ccw,
|
||||
center,
|
||||
base: BasePath {
|
||||
from: from.into(),
|
||||
from: from.ignore_units(),
|
||||
to,
|
||||
tag: tag.clone(),
|
||||
units: sketch.units,
|
||||
@ -2085,19 +2070,22 @@ async fn inner_tangential_arc_radius_angle(
|
||||
Ok(new_sketch)
|
||||
}
|
||||
|
||||
fn tan_arc_to(sketch: &Sketch, to: &[f64; 2]) -> ModelingCmd {
|
||||
// `to` must be in sketch.units
|
||||
fn tan_arc_to(sketch: &Sketch, to: [f64; 2]) -> ModelingCmd {
|
||||
ModelingCmd::from(mcmd::ExtendPath {
|
||||
path: sketch.id.into(),
|
||||
segment: PathSegment::TangentialArcTo {
|
||||
angle_snap_increment: None,
|
||||
to: KPoint2d::from(*to).with_z(0.0).map(LengthUnit),
|
||||
to: KPoint2d::from(untyped_point_to_mm(to, sketch.units))
|
||||
.with_z(0.0)
|
||||
.map(LengthUnit),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
async fn inner_tangential_arc_to_point(
|
||||
sketch: Sketch,
|
||||
point: [f64; 2],
|
||||
point: [TyF64; 2],
|
||||
is_absolute: bool,
|
||||
tag: Option<TagNode>,
|
||||
exec_state: &mut ExecState,
|
||||
@ -2105,7 +2093,9 @@ async fn inner_tangential_arc_to_point(
|
||||
) -> Result<Sketch, KclError> {
|
||||
let from: Point2d = sketch.current_pen_position()?;
|
||||
let tangent_info = sketch.get_tangential_info_from_paths();
|
||||
let tan_previous_point = tangent_info.tan_previous_point(from.into());
|
||||
let tan_previous_point = tangent_info.tan_previous_point(from.ignore_units());
|
||||
|
||||
let point = point_to_len_unit(point, from.units);
|
||||
|
||||
let to = if is_absolute {
|
||||
point
|
||||
@ -2115,7 +2105,7 @@ async fn inner_tangential_arc_to_point(
|
||||
let [to_x, to_y] = to;
|
||||
let result = get_tangential_arc_to_info(TangentialArcInfoInput {
|
||||
arc_start_point: [from.x, from.y],
|
||||
arc_end_point: to,
|
||||
arc_end_point: [to_x, to_y],
|
||||
tan_previous_point,
|
||||
obtuse: true,
|
||||
});
|
||||
@ -2142,11 +2132,11 @@ async fn inner_tangential_arc_to_point(
|
||||
point
|
||||
};
|
||||
let id = exec_state.next_uuid();
|
||||
args.batch_modeling_cmd(id, tan_arc_to(&sketch, &delta)).await?;
|
||||
args.batch_modeling_cmd(id, tan_arc_to(&sketch, delta)).await?;
|
||||
|
||||
let current_path = Path::TangentialArcTo {
|
||||
base: BasePath {
|
||||
from: from.into(),
|
||||
from: from.ignore_units(),
|
||||
to,
|
||||
tag: tag.clone(),
|
||||
units: sketch.units,
|
||||
@ -2227,7 +2217,10 @@ async fn inner_bezier_curve(
|
||||
|
||||
let relative = true;
|
||||
let delta = end.clone();
|
||||
let to = [from.x + end[0].n, from.y + end[1].n];
|
||||
let to = [
|
||||
from.x + end[0].to_length_units(from.units),
|
||||
from.y + end[1].to_length_units(from.units),
|
||||
];
|
||||
|
||||
let id = exec_state.next_uuid();
|
||||
|
||||
@ -2236,9 +2229,9 @@ async fn inner_bezier_curve(
|
||||
ModelingCmd::from(mcmd::ExtendPath {
|
||||
path: sketch.id.into(),
|
||||
segment: PathSegment::Bezier {
|
||||
control1: KPoint2d::from(untype_point(control1).0).with_z(0.0).map(LengthUnit),
|
||||
control2: KPoint2d::from(untype_point(control2).0).with_z(0.0).map(LengthUnit),
|
||||
end: KPoint2d::from(untype_point(delta).0).with_z(0.0).map(LengthUnit),
|
||||
control1: KPoint2d::from(point_to_mm(control1)).with_z(0.0).map(LengthUnit),
|
||||
control2: KPoint2d::from(point_to_mm(control2)).with_z(0.0).map(LengthUnit),
|
||||
end: KPoint2d::from(point_to_mm(delta)).with_z(0.0).map(LengthUnit),
|
||||
relative,
|
||||
},
|
||||
}),
|
||||
@ -2247,7 +2240,7 @@ async fn inner_bezier_curve(
|
||||
|
||||
let current_path = Path::ToPoint {
|
||||
base: BasePath {
|
||||
from: from.into(),
|
||||
from: from.ignore_units(),
|
||||
to,
|
||||
tag: tag.clone(),
|
||||
units: sketch.units,
|
||||
|
Reference in New Issue
Block a user