Skip to content

Commit f2e4478

Browse files
committed
Convert all lengths to mm for engine calls
Signed-off-by: Nick Cameron <[email protected]>
1 parent 6414df7 commit f2e4478

File tree

80 files changed

+5670
-6052
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

80 files changed

+5670
-6052
lines changed

Diff for: docs/kcl/fromCm.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ layout: manual
88

99
Converts a number from centimeters to the current default unit.
1010

11-
*DEPRECATED* prefer using explicit numberic suffixes (e.g., `42cm`) or the `to...` conversion functions.
11+
*DEPRECATED* prefer using explicit numeric suffixes (e.g., `42cm`) or the `to...` conversion functions.
1212

1313
No matter what units the current file uses, this function will always return a number equivalent to the input in centimeters.
1414

Diff for: docs/kcl/fromFt.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ layout: manual
88

99
Converts a number from feet to the current default unit.
1010

11-
*DEPRECATED* prefer using explicit numberic suffixes (e.g., `42ft`) or the `to...` conversion functions.
11+
*DEPRECATED* prefer using explicit numeric suffixes (e.g., `42ft`) or the `to...` conversion functions.
1212

1313
No matter what units the current file uses, this function will always return a number equivalent to the input in feet.
1414

Diff for: docs/kcl/fromInches.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ layout: manual
88

99
Converts a number from inches to the current default unit.
1010

11-
*DEPRECATED* prefer using explicit numberic suffixes (e.g., `42inch`) or the `to...` conversion functions.
11+
*DEPRECATED* prefer using explicit numeric suffixes (e.g., `42inch`) or the `to...` conversion functions.
1212

1313
No matter what units the current file uses, this function will always return a number equivalent to the input in inches.
1414

Diff for: docs/kcl/fromM.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ layout: manual
88

99
Converts a number from meters to the current default unit.
1010

11-
*DEPRECATED* prefer using explicit numberic suffixes (e.g., `42m`) or the `to...` conversion functions.
11+
*DEPRECATED* prefer using explicit numeric suffixes (e.g., `42m`) or the `to...` conversion functions.
1212

1313
No matter what units the current file uses, this function will always return a number equivalent to the input in meters.
1414

Diff for: docs/kcl/fromMm.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ layout: manual
88

99
Converts a number from mm to the current default unit.
1010

11-
*DEPRECATED* prefer using explicit numberic suffixes (e.g., `42mm`) or the `to...` conversion functions.
11+
*DEPRECATED* prefer using explicit numeric suffixes (e.g., `42mm`) or the `to...` conversion functions.
1212

1313
No matter what units the current file uses, this function will always return a number equivalent to the input in millimeters.
1414

Diff for: docs/kcl/fromYd.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ layout: manual
88

99
Converts a number from yards to the current default unit.
1010

11-
*DEPRECATED* prefer using explicit numberic suffixes (e.g., `42yd`) or the `to...` conversion functions.
11+
*DEPRECATED* prefer using explicit numeric suffixes (e.g., `42yd`) or the `to...` conversion functions.
1212

1313
No matter what units the current file uses, this function will always return a number equivalent to the input in yards.
1414

Diff for: docs/kcl/std.json

+148-106
Large diffs are not rendered by default.

Diff for: rust/kcl-lib/src/execution/exec_ast.rs

-21
Original file line numberDiff line numberDiff line change
@@ -61,16 +61,6 @@ impl ExecutorContext {
6161
if exec_state.mod_local.settings.update_from_annotation(annotation)? {
6262
exec_state.mod_local.explicit_length_units = true;
6363
}
64-
let new_units = exec_state.length_unit();
65-
if !self.engine.execution_kind().await.is_isolated() {
66-
self.engine
67-
.set_units(
68-
new_units.into(),
69-
annotation.as_source_range(),
70-
exec_state.id_generator(),
71-
)
72-
.await?;
73-
}
7464
} else {
7565
exec_state.err(CompilationError::err(
7666
annotation.as_source_range(),
@@ -107,7 +97,6 @@ impl ExecutorContext {
10797
) -> Result<(Option<KclValue>, EnvironmentRef, Vec<String>), KclError> {
10898
crate::log::log(format!("enter module {path} {} {exec_kind:?}", exec_state.stack()));
10999

110-
let old_units = exec_state.length_unit();
111100
let original_execution = self.engine.replace_execution_kind(exec_kind).await;
112101

113102
let mut local_state = ModuleState::new(path.std_path(), exec_state.stack().memory.clone(), Some(module_id));
@@ -127,7 +116,6 @@ impl ExecutorContext {
127116
.exec_block(program, exec_state, crate::execution::BodyType::Root)
128117
.await;
129118

130-
let new_units = exec_state.length_unit();
131119
let env_ref = if preserve_mem {
132120
exec_state.mut_stack().pop_and_preserve_env()
133121
} else {
@@ -137,15 +125,6 @@ impl ExecutorContext {
137125
std::mem::swap(&mut exec_state.mod_local, &mut local_state);
138126
}
139127

140-
// We only need to reset the units if we are not on the Main path.
141-
// If we reset at the end of the main path, then we just add on an extra
142-
// command and we'd need to flush the batch again.
143-
// This avoids that.
144-
if !exec_kind.is_isolated() && new_units != old_units && *path != ModulePath::Main {
145-
self.engine
146-
.set_units(old_units.into(), Default::default(), exec_state.id_generator())
147-
.await?;
148-
}
149128
self.engine.replace_execution_kind(original_execution).await;
150129

151130
crate::log::log(format!("leave {path}"));

Diff for: rust/kcl-lib/src/execution/geometry.rs

+23-15
Original file line numberDiff line numberDiff line change
@@ -625,12 +625,6 @@ impl SketchSurface {
625625
SketchSurface::Face(face) => face.z_axis,
626626
}
627627
}
628-
pub(crate) fn units(&self) -> UnitLen {
629-
match self {
630-
SketchSurface::Plane(plane) => plane.units,
631-
SketchSurface::Face(face) => face.units,
632-
}
633-
}
634628
}
635629

636630
#[derive(Debug, Clone)]
@@ -741,6 +735,10 @@ impl Solid {
741735
pub(crate) fn get_all_edge_cut_ids(&self) -> impl Iterator<Item = uuid::Uuid> + '_ {
742736
self.edge_cuts.iter().map(|foc| foc.id())
743737
}
738+
739+
pub(crate) fn height_in_mm(&self) -> f64 {
740+
self.units.adjust_to(self.height, UnitLen::Mm).0
741+
}
744742
}
745743

746744
/// A fillet or a chamfer.
@@ -803,6 +801,7 @@ pub struct Point2d {
803801

804802
impl From<[TyF64; 2]> for Point2d {
805803
fn from(p: [TyF64; 2]) -> Self {
804+
// TODO should combine not just use x's type
806805
Self {
807806
x: p[0].n,
808807
y: p[1].n,
@@ -813,12 +812,14 @@ impl From<[TyF64; 2]> for Point2d {
813812

814813
impl From<Point2d> for [f64; 2] {
815814
fn from(p: Point2d) -> Self {
815+
// TODO should take into account units
816816
[p.x, p.y]
817817
}
818818
}
819819

820820
impl From<Point2d> for Point2D {
821821
fn from(p: Point2d) -> Self {
822+
// TODO should take into account units
822823
Self { x: p.x, y: p.y }
823824
}
824825
}
@@ -833,6 +834,14 @@ impl Point2d {
833834
pub fn new(x: f64, y: f64, units: UnitLen) -> Self {
834835
Self { x, y, units }
835836
}
837+
838+
pub fn into_x(self) -> TyF64 {
839+
TyF64::new(self.x, self.units.into())
840+
}
841+
842+
pub fn into_y(self) -> TyF64 {
843+
TyF64::new(self.y, self.units.into())
844+
}
836845
}
837846

838847
#[derive(Debug, Deserialize, Serialize, PartialEq, Clone, Copy, ts_rs::TS, JsonSchema, Default)]
@@ -880,9 +889,9 @@ impl From<Point3d> for Point3D {
880889
impl From<Point3d> for kittycad_modeling_cmds::shared::Point3d<LengthUnit> {
881890
fn from(p: Point3d) -> Self {
882891
Self {
883-
x: LengthUnit(p.x),
884-
y: LengthUnit(p.y),
885-
z: LengthUnit(p.z),
892+
x: LengthUnit(p.units.adjust_to(p.x, UnitLen::Mm).0),
893+
y: LengthUnit(p.units.adjust_to(p.y, UnitLen::Mm).0),
894+
z: LengthUnit(p.units.adjust_to(p.z, UnitLen::Mm).0),
886895
}
887896
}
888897
}
@@ -1230,9 +1239,9 @@ impl Path {
12301239
ccw: *ccw,
12311240
},
12321241
Path::ArcThreePoint { p1, p2, p3, .. } => {
1233-
let circle_center = crate::std::utils::calculate_circle_from_3_points([*p1, *p2, *p3]);
1242+
let circle = crate::std::utils::calculate_circle_from_3_points([*p1, *p2, *p3]);
12341243
GetTangentialInfoFromPathsResult::Arc {
1235-
center: circle_center.center,
1244+
center: circle.center,
12361245
ccw: crate::std::utils::is_points_ccw(&[*p1, *p2, *p3]) > 0,
12371246
}
12381247
}
@@ -1244,14 +1253,13 @@ impl Path {
12441253
radius: *radius,
12451254
},
12461255
Path::CircleThreePoint { p1, p2, p3, .. } => {
1247-
let circle_center = crate::std::utils::calculate_circle_from_3_points([*p1, *p2, *p3]);
1248-
let radius = linear_distance(&[circle_center.center[0], circle_center.center[1]], p1);
1249-
let center_point = [circle_center.center[0], circle_center.center[1]];
1256+
let circle = crate::std::utils::calculate_circle_from_3_points([*p1, *p2, *p3]);
1257+
let center_point = [circle.center[0], circle.center[1]];
12501258
GetTangentialInfoFromPathsResult::Circle {
12511259
center: center_point,
12521260
// Note: a circle is always ccw regardless of the order of points
12531261
ccw: true,
1254-
radius,
1262+
radius: circle.radius,
12551263
}
12561264
}
12571265
Path::ToPoint { .. } | Path::Horizontal { .. } | Path::AngledLineTo { .. } | Path::Base { .. } => {

Diff for: rust/kcl-lib/src/execution/types.rs

+8-9
Original file line numberDiff line numberDiff line change
@@ -593,12 +593,12 @@ impl NumericType {
593593
}
594594

595595
fn is_unknown(&self) -> bool {
596-
match self {
596+
matches!(
597+
self,
597598
NumericType::Unknown
598-
| NumericType::Known(UnitType::Angle(UnitAngle::Unknown))
599-
| NumericType::Known(UnitType::Length(UnitLen::Unknown)) => true,
600-
_ => false,
601-
}
599+
| NumericType::Known(UnitType::Angle(UnitAngle::Unknown))
600+
| NumericType::Known(UnitType::Length(UnitLen::Unknown))
601+
)
602602
}
603603

604604
fn example_ty(&self) -> Option<String> {
@@ -764,7 +764,7 @@ pub enum UnitLen {
764764
}
765765

766766
impl UnitLen {
767-
fn adjust_to(self, value: f64, to: UnitLen) -> (f64, UnitLen) {
767+
pub fn adjust_to(self, value: f64, to: UnitLen) -> (f64, UnitLen) {
768768
use UnitLen::*;
769769

770770
if self == to {
@@ -887,7 +887,7 @@ pub enum UnitAngle {
887887
}
888888

889889
impl UnitAngle {
890-
fn adjust_to(self, value: f64, to: UnitAngle) -> (f64, UnitAngle) {
890+
pub fn adjust_to(self, value: f64, to: UnitAngle) -> (f64, UnitAngle) {
891891
use std::f64::consts::PI;
892892

893893
use UnitAngle::*;
@@ -1042,8 +1042,7 @@ impl KclValue {
10421042
y_axis,
10431043
z_axis,
10441044
value: super::PlaneType::Uninit,
1045-
// TODO use length unit from origin
1046-
units: exec_state.length_unit(),
1045+
units: origin.units,
10471046
meta: meta.clone(),
10481047
};
10491048

Diff for: rust/kcl-lib/src/std/appearance.rs

+3-7
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,7 @@ use serde::Serialize;
1111

1212
use crate::{
1313
errors::{KclError, KclErrorDetails},
14-
execution::{
15-
types::{NumericType, PrimitiveType, RuntimeType},
16-
ExecState, KclValue, Solid,
17-
},
14+
execution::{types::RuntimeType, ExecState, KclValue, Solid},
1815
std::Args,
1916
};
2017

@@ -46,9 +43,8 @@ pub async fn appearance(exec_state: &mut ExecState, args: Args) -> Result<KclVal
4643
let solids = args.get_unlabeled_kw_arg_typed("solids", &RuntimeType::solids(), exec_state)?;
4744

4845
let color: String = args.get_kw_arg("color")?;
49-
let count_ty = RuntimeType::Primitive(PrimitiveType::Number(NumericType::count()));
50-
let metalness: Option<TyF64> = args.get_kw_arg_opt_typed("metalness", &count_ty, exec_state)?;
51-
let roughness: Option<TyF64> = args.get_kw_arg_opt_typed("roughness", &count_ty, exec_state)?;
46+
let metalness: Option<TyF64> = args.get_kw_arg_opt_typed("metalness", &RuntimeType::count(), exec_state)?;
47+
let roughness: Option<TyF64> = args.get_kw_arg_opt_typed("roughness", &RuntimeType::count(), exec_state)?;
5248
let data = AppearanceData {
5349
color,
5450
metalness,

Diff for: rust/kcl-lib/src/std/args.rs

+49-5
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use crate::{
1414
errors::{KclError, KclErrorDetails},
1515
execution::{
1616
kcl_value::FunctionSource,
17-
types::{NumericType, PrimitiveType, RuntimeType, UnitLen},
17+
types::{NumericType, PrimitiveType, RuntimeType, UnitAngle, UnitLen, UnitType},
1818
ExecState, ExecutorContext, ExtrudeSurface, Helix, KclObjectFields, KclValue, Metadata, Sketch, SketchSurface,
1919
Solid, TagIdentifier,
2020
},
@@ -85,6 +85,34 @@ impl TyF64 {
8585
Self { n, ty }
8686
}
8787

88+
pub fn to_mm(&self) -> f64 {
89+
self.to_length_units(UnitLen::Mm)
90+
}
91+
92+
pub fn to_length_units(&self, units: UnitLen) -> f64 {
93+
let len = match &self.ty {
94+
NumericType::Default { len, .. } => *len,
95+
NumericType::Known(UnitType::Length(len)) => *len,
96+
t => unreachable!("expected length, found {t:?}"),
97+
};
98+
99+
assert_ne!(len, UnitLen::Unknown);
100+
101+
len.adjust_to(self.n, units).0
102+
}
103+
104+
pub fn to_degrees(&self) -> f64 {
105+
let angle = match self.ty {
106+
NumericType::Default { angle, .. } => angle,
107+
NumericType::Known(UnitType::Angle(angle)) => angle,
108+
_ => unreachable!(),
109+
};
110+
111+
assert_ne!(angle, UnitAngle::Unknown);
112+
113+
angle.adjust_to(self.n, UnitAngle::Degrees).0
114+
}
115+
88116
pub fn count(n: f64) -> Self {
89117
Self {
90118
n,
@@ -542,9 +570,9 @@ impl Args {
542570
}
543571

544572
pub(crate) fn get_number_typed(&self, ty: &RuntimeType, exec_state: &mut ExecState) -> Result<f64, KclError> {
545-
let Some(arg) = self.args.get(0) else {
573+
let Some(arg) = self.args.first() else {
546574
return Err(KclError::Semantic(KclErrorDetails {
547-
message: format!("Expected an argument"),
575+
message: "Expected an argument".to_owned(),
548576
source_ranges: vec![self.source_range],
549577
}));
550578
};
@@ -708,8 +736,24 @@ impl Args {
708736
FromArgs::from_args(self, 0)
709737
}
710738

711-
pub(crate) fn get_data_and_solid(&self, exec_state: &mut ExecState) -> Result<(TyF64, Box<Solid>), KclError> {
712-
let data = FromArgs::from_args(self, 0)?;
739+
pub(crate) fn get_length_and_solid(&self, exec_state: &mut ExecState) -> Result<(TyF64, Box<Solid>), KclError> {
740+
let Some(arg0) = self.args.first() else {
741+
return Err(KclError::Semantic(KclErrorDetails {
742+
message: "Expected a `number(Length)` for first argument".to_owned(),
743+
source_ranges: vec![self.source_range],
744+
}));
745+
};
746+
let val0 = arg0.value.coerce(&RuntimeType::length(), exec_state).map_err(|_| {
747+
KclError::Type(KclErrorDetails {
748+
message: format!(
749+
"Expected a `number(Length)` for second argument, found {}",
750+
arg0.value.human_friendly_type()
751+
),
752+
source_ranges: vec![self.source_range],
753+
})
754+
})?;
755+
let data = TyF64::from_kcl_val(&val0).unwrap();
756+
713757
let Some(arg1) = self.args.get(1) else {
714758
return Err(KclError::Semantic(KclErrorDetails {
715759
message: "Expected a solid for second argument".to_owned(),

Diff for: rust/kcl-lib/src/std/chamfer.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ async fn inner_chamfer(
137137
ModelingCmd::from(mcmd::Solid3dFilletEdge {
138138
edge_id,
139139
object_id: solid.id,
140-
radius: LengthUnit(length.n),
140+
radius: LengthUnit(length.to_mm()),
141141
tolerance: LengthUnit(DEFAULT_TOLERANCE), // We can let the user set this in the future.
142142
cut_type: CutType::Chamfer,
143143
}),

0 commit comments

Comments
 (0)