Convert all lengths to mm for engine calls
Signed-off-by: Nick Cameron <nrc@ncameron.org>
This commit is contained in:
		| @ -8,7 +8,7 @@ layout: manual | ||||
|  | ||||
| Converts a number from centimeters to the current default unit. | ||||
|  | ||||
| *DEPRECATED* prefer using explicit numberic suffixes (e.g., `42cm`) or the `to...` conversion functions. | ||||
| *DEPRECATED* prefer using explicit numeric suffixes (e.g., `42cm`) or the `to...` conversion functions. | ||||
|  | ||||
| No matter what units the current file uses, this function will always return a number equivalent to the input in centimeters. | ||||
|  | ||||
|  | ||||
| @ -8,7 +8,7 @@ layout: manual | ||||
|  | ||||
| Converts a number from feet to the current default unit. | ||||
|  | ||||
| *DEPRECATED* prefer using explicit numberic suffixes (e.g., `42ft`) or the `to...` conversion functions. | ||||
| *DEPRECATED* prefer using explicit numeric suffixes (e.g., `42ft`) or the `to...` conversion functions. | ||||
|  | ||||
| No matter what units the current file uses, this function will always return a number equivalent to the input in feet. | ||||
|  | ||||
|  | ||||
| @ -8,7 +8,7 @@ layout: manual | ||||
|  | ||||
| Converts a number from inches to the current default unit. | ||||
|  | ||||
| *DEPRECATED* prefer using explicit numberic suffixes (e.g., `42inch`) or the `to...` conversion functions. | ||||
| *DEPRECATED* prefer using explicit numeric suffixes (e.g., `42inch`) or the `to...` conversion functions. | ||||
|  | ||||
| No matter what units the current file uses, this function will always return a number equivalent to the input in inches. | ||||
|  | ||||
|  | ||||
| @ -8,7 +8,7 @@ layout: manual | ||||
|  | ||||
| Converts a number from meters to the current default unit. | ||||
|  | ||||
| *DEPRECATED* prefer using explicit numberic suffixes (e.g., `42m`) or the `to...` conversion functions. | ||||
| *DEPRECATED* prefer using explicit numeric suffixes (e.g., `42m`) or the `to...` conversion functions. | ||||
|  | ||||
| No matter what units the current file uses, this function will always return a number equivalent to the input in meters. | ||||
|  | ||||
|  | ||||
| @ -8,7 +8,7 @@ layout: manual | ||||
|  | ||||
| Converts a number from mm to the current default unit. | ||||
|  | ||||
| *DEPRECATED* prefer using explicit numberic suffixes (e.g., `42mm`) or the `to...` conversion functions. | ||||
| *DEPRECATED* prefer using explicit numeric suffixes (e.g., `42mm`) or the `to...` conversion functions. | ||||
|  | ||||
| No matter what units the current file uses, this function will always return a number equivalent to the input in millimeters. | ||||
|  | ||||
|  | ||||
| @ -8,7 +8,7 @@ layout: manual | ||||
|  | ||||
| Converts a number from yards to the current default unit. | ||||
|  | ||||
| *DEPRECATED* prefer using explicit numberic suffixes (e.g., `42yd`) or the `to...` conversion functions. | ||||
| *DEPRECATED* prefer using explicit numeric suffixes (e.g., `42yd`) or the `to...` conversion functions. | ||||
|  | ||||
| No matter what units the current file uses, this function will always return a number equivalent to the input in yards. | ||||
|  | ||||
|  | ||||
							
								
								
									
										1275
									
								
								docs/kcl/std.json
									
									
									
									
									
								
							
							
						
						
									
										1275
									
								
								docs/kcl/std.json
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @ -31,7 +31,6 @@ A sketch type. | ||||
| | `xAxis` |[`Point3d`](/docs/kcl/types/Point3d)| What should the plane's X axis be? | No | | ||||
| | `yAxis` |[`Point3d`](/docs/kcl/types/Point3d)| What should the plane's Y axis be? | No | | ||||
| | `zAxis` |[`Point3d`](/docs/kcl/types/Point3d)| The z-axis (normal). | No | | ||||
| | `units` |[`UnitLen`](/docs/kcl/types/UnitLen)| A unit of length. | No | | ||||
|  | ||||
|  | ||||
| ---- | ||||
|  | ||||
| @ -278,7 +278,7 @@ test.describe('Point-and-click assemblies tests', () => { | ||||
|           highlightedHeaderArg: 'x', | ||||
|           commandName: 'Translate', | ||||
|         }) | ||||
|         await page.keyboard.insertText('5') | ||||
|         await page.keyboard.insertText('100') | ||||
|         await cmdBar.progressCmdBar() | ||||
|         await page.keyboard.insertText('0.1') | ||||
|         await cmdBar.progressCmdBar() | ||||
| @ -287,7 +287,7 @@ test.describe('Point-and-click assemblies tests', () => { | ||||
|         await cmdBar.expectState({ | ||||
|           stage: 'review', | ||||
|           headerArguments: { | ||||
|             X: '5', | ||||
|             X: '100', | ||||
|             Y: '0.1', | ||||
|             Z: '0.2', | ||||
|           }, | ||||
| @ -299,7 +299,7 @@ test.describe('Point-and-click assemblies tests', () => { | ||||
|         await editor.expectEditor.toContain( | ||||
|           ` | ||||
|         bracket | ||||
|           |> translate(x = 5, y = 0.1, z = 0.2) | ||||
|           |> translate(x = 100, y = 0.1, z = 0.2) | ||||
|         `, | ||||
|           { shouldNormalise: true } | ||||
|         ) | ||||
| @ -348,7 +348,7 @@ test.describe('Point-and-click assemblies tests', () => { | ||||
|         await editor.expectEditor.toContain( | ||||
|           ` | ||||
|         bracket | ||||
|           |> translate(x = 5, y = 0.1, z = 0.2) | ||||
|           |> translate(x = 100, y = 0.1, z = 0.2) | ||||
|           |> rotate(roll = 0.1, pitch = 0.2, yaw = 0.3) | ||||
|         `, | ||||
|           { shouldNormalise: true } | ||||
|  | ||||
| @ -180,10 +180,6 @@ pub trait EngineManager: std::fmt::Debug + Send + Sync + 'static { | ||||
|         ) | ||||
|         .await?; | ||||
|  | ||||
|         // Reset to the default units.  Modules assume the engine starts in the | ||||
|         // default state. | ||||
|         self.set_units(Default::default(), source_range, id_generator).await?; | ||||
|  | ||||
|         // Flush the batch queue, so clear is run right away. | ||||
|         // Otherwise the hooks below won't work. | ||||
|         self.flush_batch(false, source_range).await?; | ||||
| @ -298,23 +294,6 @@ pub trait EngineManager: std::fmt::Debug + Send + Sync + 'static { | ||||
|         Ok(()) | ||||
|     } | ||||
|  | ||||
|     async fn set_units( | ||||
|         &self, | ||||
|         units: crate::UnitLength, | ||||
|         source_range: SourceRange, | ||||
|         id_generator: &mut IdGenerator, | ||||
|     ) -> Result<(), crate::errors::KclError> { | ||||
|         // Before we even start executing the program, set the units. | ||||
|         self.batch_modeling_cmd( | ||||
|             id_generator.next_uuid(), | ||||
|             source_range, | ||||
|             &ModelingCmd::from(mcmd::SetSceneUnits { unit: units.into() }), | ||||
|         ) | ||||
|         .await?; | ||||
|  | ||||
|         Ok(()) | ||||
|     } | ||||
|  | ||||
|     /// Re-run the command to apply the settings. | ||||
|     async fn reapply_settings( | ||||
|         &self, | ||||
|  | ||||
| @ -60,14 +60,6 @@ impl ExecutorContext { | ||||
|                     if exec_state.mod_local.settings.update_from_annotation(annotation)? { | ||||
|                         exec_state.mod_local.explicit_length_units = true; | ||||
|                     } | ||||
|                     let new_units = exec_state.length_unit(); | ||||
|                     self.engine | ||||
|                         .set_units( | ||||
|                             new_units.into(), | ||||
|                             annotation.as_source_range(), | ||||
|                             exec_state.id_generator(), | ||||
|                         ) | ||||
|                         .await?; | ||||
|                 } else { | ||||
|                     exec_state.err(CompilationError::err( | ||||
|                         annotation.as_source_range(), | ||||
|  | ||||
| @ -10,14 +10,13 @@ use serde::{Deserialize, Serialize}; | ||||
|  | ||||
| use crate::{ | ||||
|     errors::KclError, | ||||
|     execution::{types::NumericType, ArtifactId, ExecState, Metadata, TagEngineInfo, TagIdentifier, UnitLen}, | ||||
|     execution::{ | ||||
|         types::NumericType, ArtifactId, ExecState, ExecutorContext, Metadata, TagEngineInfo, TagIdentifier, UnitLen, | ||||
|     }, | ||||
|     parsing::ast::types::{Node, NodeRef, TagDeclarator, TagNode}, | ||||
|     std::{args::TyF64, sketch::PlaneData}, | ||||
| }; | ||||
|  | ||||
| use super::ExecutorContext; | ||||
|  | ||||
| type Point2D = kcmc::shared::Point2d<f64>; | ||||
| type Point3D = kcmc::shared::Point3d<f64>; | ||||
|  | ||||
| /// A geometry. | ||||
| @ -265,7 +264,6 @@ pub struct Plane { | ||||
|     pub y_axis: Point3d, | ||||
|     /// The z-axis (normal). | ||||
|     pub z_axis: Point3d, | ||||
|     pub units: UnitLen, | ||||
|     #[serde(skip)] | ||||
|     pub meta: Vec<Metadata>, | ||||
| } | ||||
| @ -287,6 +285,8 @@ impl Plane { | ||||
|                             x: 1.0, | ||||
|                             y: 0.0, | ||||
|                             z: 0.0, | ||||
|                             // TODO axes must be normalized, so maybe these should all be count | ||||
|                             // rather than mm? | ||||
|                             units: UnitLen::Mm, | ||||
|                         }, | ||||
|                     y_axis: | ||||
| @ -483,7 +483,6 @@ impl Plane { | ||||
|                 y_axis: Point3d::new(0.0, 1.0, 0.0, UnitLen::Mm), | ||||
|                 z_axis: Point3d::new(0.0, 0.0, 1.0, UnitLen::Mm), | ||||
|                 value: PlaneType::XY, | ||||
|                 units: exec_state.length_unit(), | ||||
|                 meta: vec![], | ||||
|             }, | ||||
|             PlaneData::NegXY => Plane { | ||||
| @ -494,7 +493,6 @@ impl Plane { | ||||
|                 y_axis: Point3d::new(0.0, 1.0, 0.0, UnitLen::Mm), | ||||
|                 z_axis: Point3d::new(0.0, 0.0, -1.0, UnitLen::Mm), | ||||
|                 value: PlaneType::XY, | ||||
|                 units: exec_state.length_unit(), | ||||
|                 meta: vec![], | ||||
|             }, | ||||
|             PlaneData::XZ => Plane { | ||||
| @ -505,7 +503,6 @@ impl Plane { | ||||
|                 y_axis: Point3d::new(0.0, 0.0, 1.0, UnitLen::Mm), | ||||
|                 z_axis: Point3d::new(0.0, -1.0, 0.0, UnitLen::Mm), | ||||
|                 value: PlaneType::XZ, | ||||
|                 units: exec_state.length_unit(), | ||||
|                 meta: vec![], | ||||
|             }, | ||||
|             PlaneData::NegXZ => Plane { | ||||
| @ -516,7 +513,6 @@ impl Plane { | ||||
|                 y_axis: Point3d::new(0.0, 0.0, 1.0, UnitLen::Mm), | ||||
|                 z_axis: Point3d::new(0.0, 1.0, 0.0, UnitLen::Mm), | ||||
|                 value: PlaneType::XZ, | ||||
|                 units: exec_state.length_unit(), | ||||
|                 meta: vec![], | ||||
|             }, | ||||
|             PlaneData::YZ => Plane { | ||||
| @ -527,7 +523,6 @@ impl Plane { | ||||
|                 y_axis: Point3d::new(0.0, 0.0, 1.0, UnitLen::Mm), | ||||
|                 z_axis: Point3d::new(1.0, 0.0, 0.0, UnitLen::Mm), | ||||
|                 value: PlaneType::YZ, | ||||
|                 units: exec_state.length_unit(), | ||||
|                 meta: vec![], | ||||
|             }, | ||||
|             PlaneData::NegYZ => Plane { | ||||
| @ -538,7 +533,6 @@ impl Plane { | ||||
|                 y_axis: Point3d::new(0.0, 0.0, 1.0, UnitLen::Mm), | ||||
|                 z_axis: Point3d::new(-1.0, 0.0, 0.0, UnitLen::Mm), | ||||
|                 value: PlaneType::YZ, | ||||
|                 units: exec_state.length_unit(), | ||||
|                 meta: vec![], | ||||
|             }, | ||||
|             PlaneData::Plane { | ||||
| @ -556,7 +550,6 @@ impl Plane { | ||||
|                     y_axis, | ||||
|                     z_axis, | ||||
|                     value: PlaneType::Custom, | ||||
|                     units: exec_state.length_unit(), | ||||
|                     meta: vec![], | ||||
|                 } | ||||
|             } | ||||
| @ -713,12 +706,6 @@ impl SketchSurface { | ||||
|             SketchSurface::Face(face) => face.z_axis, | ||||
|         } | ||||
|     } | ||||
|     pub(crate) fn units(&self) -> UnitLen { | ||||
|         match self { | ||||
|             SketchSurface::Plane(plane) => plane.units, | ||||
|             SketchSurface::Face(face) => face.units, | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| #[derive(Debug, Clone)] | ||||
| @ -787,7 +774,8 @@ impl Sketch { | ||||
|             return Ok(Point2d::new(self.start.to[0], self.start.to[1], self.start.units)); | ||||
|         }; | ||||
|  | ||||
|         Ok(path.get_to().into()) | ||||
|         let to = path.get_base().to; | ||||
|         Ok(Point2d::new(to[0], to[1], path.get_base().units)) | ||||
|     } | ||||
|  | ||||
|     pub(crate) fn get_tangential_info_from_paths(&self) -> GetTangentialInfoFromPathsResult { | ||||
| @ -829,6 +817,10 @@ impl Solid { | ||||
|     pub(crate) fn get_all_edge_cut_ids(&self) -> impl Iterator<Item = uuid::Uuid> + '_ { | ||||
|         self.edge_cuts.iter().map(|foc| foc.id()) | ||||
|     } | ||||
|  | ||||
|     pub(crate) fn height_in_mm(&self) -> f64 { | ||||
|         self.units.adjust_to(self.height, UnitLen::Mm).0 | ||||
|     } | ||||
| } | ||||
|  | ||||
| /// A fillet or a chamfer. | ||||
| @ -889,28 +881,6 @@ pub struct Point2d { | ||||
|     pub units: UnitLen, | ||||
| } | ||||
|  | ||||
| impl From<[TyF64; 2]> for Point2d { | ||||
|     fn from(p: [TyF64; 2]) -> Self { | ||||
|         Self { | ||||
|             x: p[0].n, | ||||
|             y: p[1].n, | ||||
|             units: p[0].ty.expect_length(), | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl From<Point2d> for [f64; 2] { | ||||
|     fn from(p: Point2d) -> Self { | ||||
|         [p.x, p.y] | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl From<Point2d> for Point2D { | ||||
|     fn from(p: Point2d) -> Self { | ||||
|         Self { x: p.x, y: p.y } | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl Point2d { | ||||
|     pub const ZERO: Self = Self { | ||||
|         x: 0.0, | ||||
| @ -921,6 +891,18 @@ impl Point2d { | ||||
|     pub fn new(x: f64, y: f64, units: UnitLen) -> Self { | ||||
|         Self { x, y, units } | ||||
|     } | ||||
|  | ||||
|     pub fn into_x(self) -> TyF64 { | ||||
|         TyF64::new(self.x, self.units.into()) | ||||
|     } | ||||
|  | ||||
|     pub fn into_y(self) -> TyF64 { | ||||
|         TyF64::new(self.y, self.units.into()) | ||||
|     } | ||||
|  | ||||
|     pub fn ignore_units(self) -> [f64; 2] { | ||||
|         [self.x, self.y] | ||||
|     } | ||||
| } | ||||
|  | ||||
| #[derive(Debug, Deserialize, Serialize, PartialEq, Clone, Copy, ts_rs::TS, JsonSchema, Default)] | ||||
| @ -968,9 +950,9 @@ impl From<Point3d> for Point3D { | ||||
| impl From<Point3d> for kittycad_modeling_cmds::shared::Point3d<LengthUnit> { | ||||
|     fn from(p: Point3d) -> Self { | ||||
|         Self { | ||||
|             x: LengthUnit(p.x), | ||||
|             y: LengthUnit(p.y), | ||||
|             z: LengthUnit(p.z), | ||||
|             x: LengthUnit(p.units.adjust_to(p.x, UnitLen::Mm).0), | ||||
|             y: LengthUnit(p.units.adjust_to(p.y, UnitLen::Mm).0), | ||||
|             z: LengthUnit(p.units.adjust_to(p.z, UnitLen::Mm).0), | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -1318,9 +1300,9 @@ impl Path { | ||||
|                 ccw: *ccw, | ||||
|             }, | ||||
|             Path::ArcThreePoint { p1, p2, p3, .. } => { | ||||
|                 let circle_center = crate::std::utils::calculate_circle_from_3_points([*p1, *p2, *p3]); | ||||
|                 let circle = crate::std::utils::calculate_circle_from_3_points([*p1, *p2, *p3]); | ||||
|                 GetTangentialInfoFromPathsResult::Arc { | ||||
|                     center: circle_center.center, | ||||
|                     center: circle.center, | ||||
|                     ccw: crate::std::utils::is_points_ccw(&[*p1, *p2, *p3]) > 0, | ||||
|                 } | ||||
|             } | ||||
| @ -1332,14 +1314,13 @@ impl Path { | ||||
|                 radius: *radius, | ||||
|             }, | ||||
|             Path::CircleThreePoint { p1, p2, p3, .. } => { | ||||
|                 let circle_center = crate::std::utils::calculate_circle_from_3_points([*p1, *p2, *p3]); | ||||
|                 let radius = linear_distance(&[circle_center.center[0], circle_center.center[1]], p1); | ||||
|                 let center_point = [circle_center.center[0], circle_center.center[1]]; | ||||
|                 let circle = crate::std::utils::calculate_circle_from_3_points([*p1, *p2, *p3]); | ||||
|                 let center_point = [circle.center[0], circle.center[1]]; | ||||
|                 GetTangentialInfoFromPathsResult::Circle { | ||||
|                     center: center_point, | ||||
|                     // Note: a circle is always ccw regardless of the order of points | ||||
|                     ccw: true, | ||||
|                     radius, | ||||
|                     radius: circle.radius, | ||||
|                 } | ||||
|             } | ||||
|             Path::ToPoint { .. } | Path::Horizontal { .. } | Path::AngledLineTo { .. } | Path::Base { .. } => { | ||||
|  | ||||
| @ -440,7 +440,11 @@ impl NumericType { | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /// Combine two types when we expect them to be equal. | ||||
|     /// Combine two types when we expect them to be equal, erring on the side of less coercion. To be | ||||
|     /// precise, only adjusting one number or the other when they are of known types. | ||||
|     /// | ||||
|     /// This combinator function is suitable for comparisons or arithmetic where uncertainty should | ||||
|     /// be handled by the user. | ||||
|     pub fn combine_eq(a: TyF64, b: TyF64) -> (f64, f64, NumericType) { | ||||
|         use NumericType::*; | ||||
|         match (a.ty, b.ty) { | ||||
| @ -463,13 +467,20 @@ impl NumericType { | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /// Combine two types when we expect them to be equal. | ||||
|     /// Combine two types when we expect them to be equal, erring on the side of more coercion. Including adjusting when | ||||
|     /// we are certain about only one type. | ||||
|     /// | ||||
|     /// This combinator function is suitable for situations where the user would almost certainly want the types to be | ||||
|     /// coerced together, for example two arguments to the same function or two numbers in an array being used as a point. | ||||
|     /// | ||||
|     /// Prefer to use `combine_eq` if possible since using that prioritises correctness over ergonomics. | ||||
|     pub fn combine_eq_coerce(a: TyF64, b: TyF64) -> (f64, f64, NumericType) { | ||||
|         use NumericType::*; | ||||
|         match (a.ty, b.ty) { | ||||
|             (at, bt) if at == bt => (a.n, b.n, at), | ||||
|             (at, Any) => (a.n, b.n, at), | ||||
|             (Any, bt) => (a.n, b.n, bt), | ||||
|  | ||||
|             (Default { .. }, Default { .. }) | (_, Unknown) | (Unknown, _) => (a.n, b.n, Unknown), | ||||
|  | ||||
|             // Known types and compatible, but needs adjustment. | ||||
| @ -597,12 +608,12 @@ impl NumericType { | ||||
|     } | ||||
|  | ||||
|     fn is_unknown(&self) -> bool { | ||||
|         match self { | ||||
|         matches!( | ||||
|             self, | ||||
|             NumericType::Unknown | ||||
|             | NumericType::Known(UnitType::Angle(UnitAngle::Unknown)) | ||||
|             | NumericType::Known(UnitType::Length(UnitLen::Unknown)) => true, | ||||
|             _ => false, | ||||
|         } | ||||
|                 | NumericType::Known(UnitType::Angle(UnitAngle::Unknown)) | ||||
|                 | NumericType::Known(UnitType::Length(UnitLen::Unknown)) | ||||
|         ) | ||||
|     } | ||||
|  | ||||
|     fn example_ty(&self) -> Option<String> { | ||||
| @ -768,7 +779,7 @@ pub enum UnitLen { | ||||
| } | ||||
|  | ||||
| impl UnitLen { | ||||
|     fn adjust_to(self, value: f64, to: UnitLen) -> (f64, UnitLen) { | ||||
|     pub fn adjust_to(self, value: f64, to: UnitLen) -> (f64, UnitLen) { | ||||
|         use UnitLen::*; | ||||
|  | ||||
|         if self == to { | ||||
| @ -891,7 +902,7 @@ pub enum UnitAngle { | ||||
| } | ||||
|  | ||||
| impl UnitAngle { | ||||
|     fn adjust_to(self, value: f64, to: UnitAngle) -> (f64, UnitAngle) { | ||||
|     pub fn adjust_to(self, value: f64, to: UnitAngle) -> (f64, UnitAngle) { | ||||
|         use std::f64::consts::PI; | ||||
|  | ||||
|         use UnitAngle::*; | ||||
| @ -1046,8 +1057,6 @@ impl KclValue { | ||||
|                         y_axis, | ||||
|                         z_axis, | ||||
|                         value: super::PlaneType::Uninit, | ||||
|                         // TODO use length unit from origin | ||||
|                         units: exec_state.length_unit(), | ||||
|                         meta: meta.clone(), | ||||
|                     }; | ||||
|  | ||||
|  | ||||
| @ -1,7 +1,7 @@ | ||||
| use sha2::{Digest as DigestTrait, Sha256}; | ||||
|  | ||||
| use crate::parsing::ast::types::{ | ||||
|     Annotation, ArrayExpression, ArrayRangeExpression, Ascription, BinaryExpression, BinaryPart, BodyItem, | ||||
|     Annotation, ArrayExpression, ArrayRangeExpression, AscribedExpression, BinaryExpression, BinaryPart, BodyItem, | ||||
|     CallExpression, CallExpressionKw, DefaultParamVal, ElseIf, Expr, ExpressionStatement, FunctionExpression, | ||||
|     Identifier, IfExpression, ImportItem, ImportSelector, ImportStatement, ItemVisibility, KclNone, LabelledExpression, | ||||
|     Literal, LiteralIdentifier, LiteralValue, MemberExpression, MemberObject, Name, ObjectExpression, ObjectProperty, | ||||
| @ -464,7 +464,7 @@ impl LabelledExpression { | ||||
|     }); | ||||
| } | ||||
|  | ||||
| impl Ascription { | ||||
| impl AscribedExpression { | ||||
|     compute_digest!(|slf, hasher| { | ||||
|         hasher.update(slf.expr.compute_digest()); | ||||
|         hasher.update(slf.ty.compute_digest()); | ||||
|  | ||||
| @ -819,7 +819,7 @@ pub enum Expr { | ||||
|     UnaryExpression(BoxNode<UnaryExpression>), | ||||
|     IfExpression(BoxNode<IfExpression>), | ||||
|     LabelledExpression(BoxNode<LabelledExpression>), | ||||
|     AscribedExpression(BoxNode<Ascription>), | ||||
|     AscribedExpression(BoxNode<AscribedExpression>), | ||||
|     None(Node<KclNone>), | ||||
| } | ||||
|  | ||||
| @ -1092,7 +1092,7 @@ impl LabelledExpression { | ||||
| #[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)] | ||||
| #[ts(export)] | ||||
| #[serde(tag = "type")] | ||||
| pub struct Ascription { | ||||
| pub struct AscribedExpression { | ||||
|     pub expr: Expr, | ||||
|     pub ty: Node<Type>, | ||||
|  | ||||
| @ -1101,12 +1101,12 @@ pub struct Ascription { | ||||
|     pub digest: Option<Digest>, | ||||
| } | ||||
|  | ||||
| impl Ascription { | ||||
|     pub(crate) fn new(expr: Expr, ty: Node<Type>) -> Node<Ascription> { | ||||
| impl AscribedExpression { | ||||
|     pub(crate) fn new(expr: Expr, ty: Node<Type>) -> Node<AscribedExpression> { | ||||
|         let start = expr.start(); | ||||
|         let end = ty.end; | ||||
|         let module_id = expr.module_id(); | ||||
|         Node::new(Ascription { expr, ty, digest: None }, start, end, module_id) | ||||
|         Node::new(AscribedExpression { expr, ty, digest: None }, start, end, module_id) | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -3080,7 +3080,7 @@ impl PipeExpression { | ||||
| #[allow(clippy::large_enum_variant)] | ||||
| #[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)] | ||||
| #[ts(export)] | ||||
| #[serde(tag = "type")] | ||||
| #[serde(tag = "p_type")] | ||||
| pub enum PrimitiveType { | ||||
|     /// A string type. | ||||
|     String, | ||||
|  | ||||
| @ -14,7 +14,7 @@ use winnow::{ | ||||
| }; | ||||
|  | ||||
| use super::{ | ||||
|     ast::types::{Ascription, ImportPath, LabelledExpression}, | ||||
|     ast::types::{AscribedExpression, ImportPath, LabelledExpression}, | ||||
|     token::{NumericSuffix, RESERVED_WORDS}, | ||||
|     DeprecationKind, | ||||
| }; | ||||
| @ -2008,7 +2008,7 @@ fn expression_but_not_pipe(i: &mut TokenSlice) -> PResult<Expr> { | ||||
|  | ||||
|     let ty = opt((colon, opt(whitespace), argument_type)).parse_next(i)?; | ||||
|     if let Some((_, _, ty)) = ty { | ||||
|         expr = Expr::AscribedExpression(Box::new(Ascription::new(expr, ty))) | ||||
|         expr = Expr::AscribedExpression(Box::new(AscribedExpression::new(expr, ty))) | ||||
|     } | ||||
|     let label = opt(label).parse_next(i)?; | ||||
|     match label { | ||||
| @ -4516,13 +4516,13 @@ export fn cos(num: number(rad)): number(_) {}"#; | ||||
|     fn fn_decl_uom_ty() { | ||||
|         let some_program_string = r#"fn foo(x: number(mm)): number(_) { return 1 }"#; | ||||
|         let (_, errs) = assert_no_fatal(some_program_string); | ||||
|         assert!(errs.is_empty()); | ||||
|         assert!(errs.is_empty(), "Expected no errors, found: {errs:?}"); | ||||
|     } | ||||
|  | ||||
|     #[test] | ||||
|     fn error_underscore() { | ||||
|         let (_, errs) = assert_no_fatal("_foo(_blah, _)"); | ||||
|         assert_eq!(errs.len(), 3, "found: {:#?}", errs); | ||||
|         assert_eq!(errs.len(), 3, "found: {errs:#?}"); | ||||
|     } | ||||
|  | ||||
|     #[test] | ||||
|  | ||||
| @ -11,10 +11,7 @@ use serde::Serialize; | ||||
|  | ||||
| use crate::{ | ||||
|     errors::{KclError, KclErrorDetails}, | ||||
|     execution::{ | ||||
|         types::{NumericType, PrimitiveType, RuntimeType}, | ||||
|         ExecState, KclValue, SolidOrImportedGeometry, | ||||
|     }, | ||||
|     execution::{types::RuntimeType, ExecState, KclValue, SolidOrImportedGeometry}, | ||||
|     std::Args, | ||||
| }; | ||||
|  | ||||
| @ -50,9 +47,8 @@ pub async fn appearance(exec_state: &mut ExecState, args: Args) -> Result<KclVal | ||||
|     )?; | ||||
|  | ||||
|     let color: String = args.get_kw_arg("color")?; | ||||
|     let count_ty = RuntimeType::Primitive(PrimitiveType::Number(NumericType::count())); | ||||
|     let metalness: Option<TyF64> = args.get_kw_arg_opt_typed("metalness", &count_ty, exec_state)?; | ||||
|     let roughness: Option<TyF64> = args.get_kw_arg_opt_typed("roughness", &count_ty, exec_state)?; | ||||
|     let metalness: Option<TyF64> = args.get_kw_arg_opt_typed("metalness", &RuntimeType::count(), exec_state)?; | ||||
|     let roughness: Option<TyF64> = args.get_kw_arg_opt_typed("roughness", &RuntimeType::count(), exec_state)?; | ||||
|     let data = AppearanceData { | ||||
|         color, | ||||
|         metalness, | ||||
|  | ||||
| @ -14,7 +14,7 @@ use crate::{ | ||||
|     errors::{KclError, KclErrorDetails}, | ||||
|     execution::{ | ||||
|         kcl_value::FunctionSource, | ||||
|         types::{NumericType, PrimitiveType, RuntimeType, UnitLen}, | ||||
|         types::{NumericType, PrimitiveType, RuntimeType, UnitAngle, UnitLen, UnitType}, | ||||
|         ExecState, ExecutorContext, ExtrudeSurface, Helix, KclObjectFields, KclValue, Metadata, Sketch, SketchSurface, | ||||
|         Solid, TagIdentifier, | ||||
|     }, | ||||
| @ -88,6 +88,34 @@ impl TyF64 { | ||||
|         Self { n, ty } | ||||
|     } | ||||
|  | ||||
|     pub fn to_mm(&self) -> f64 { | ||||
|         self.to_length_units(UnitLen::Mm) | ||||
|     } | ||||
|  | ||||
|     pub fn to_length_units(&self, units: UnitLen) -> f64 { | ||||
|         let len = match &self.ty { | ||||
|             NumericType::Default { len, .. } => *len, | ||||
|             NumericType::Known(UnitType::Length(len)) => *len, | ||||
|             t => unreachable!("expected length, found {t:?}"), | ||||
|         }; | ||||
|  | ||||
|         assert_ne!(len, UnitLen::Unknown); | ||||
|  | ||||
|         len.adjust_to(self.n, units).0 | ||||
|     } | ||||
|  | ||||
|     pub fn to_degrees(&self) -> f64 { | ||||
|         let angle = match self.ty { | ||||
|             NumericType::Default { angle, .. } => angle, | ||||
|             NumericType::Known(UnitType::Angle(angle)) => angle, | ||||
|             _ => unreachable!(), | ||||
|         }; | ||||
|  | ||||
|         assert_ne!(angle, UnitAngle::Unknown); | ||||
|  | ||||
|         angle.adjust_to(self.n, UnitAngle::Degrees).0 | ||||
|     } | ||||
|  | ||||
|     pub fn count(n: f64) -> Self { | ||||
|         Self { | ||||
|             n, | ||||
| @ -548,9 +576,9 @@ impl Args { | ||||
|     } | ||||
|  | ||||
|     pub(crate) fn get_number_typed(&self, ty: &RuntimeType, exec_state: &mut ExecState) -> Result<f64, KclError> { | ||||
|         let Some(arg) = self.args.get(0) else { | ||||
|         let Some(arg) = self.args.first() else { | ||||
|             return Err(KclError::Semantic(KclErrorDetails { | ||||
|                 message: format!("Expected an argument"), | ||||
|                 message: "Expected an argument".to_owned(), | ||||
|                 source_ranges: vec![self.source_range], | ||||
|             })); | ||||
|         }; | ||||
| @ -680,8 +708,24 @@ impl Args { | ||||
|         FromArgs::from_args(self, 0) | ||||
|     } | ||||
|  | ||||
|     pub(crate) fn get_data_and_solid(&self, exec_state: &mut ExecState) -> Result<(TyF64, Box<Solid>), KclError> { | ||||
|         let data = FromArgs::from_args(self, 0)?; | ||||
|     pub(crate) fn get_length_and_solid(&self, exec_state: &mut ExecState) -> Result<(TyF64, Box<Solid>), KclError> { | ||||
|         let Some(arg0) = self.args.first() else { | ||||
|             return Err(KclError::Semantic(KclErrorDetails { | ||||
|                 message: "Expected a `number(Length)` for first argument".to_owned(), | ||||
|                 source_ranges: vec![self.source_range], | ||||
|             })); | ||||
|         }; | ||||
|         let val0 = arg0.value.coerce(&RuntimeType::length(), exec_state).map_err(|_| { | ||||
|             KclError::Type(KclErrorDetails { | ||||
|                 message: format!( | ||||
|                     "Expected a `number(Length)` for first argument, found {}", | ||||
|                     arg0.value.human_friendly_type() | ||||
|                 ), | ||||
|                 source_ranges: vec![self.source_range], | ||||
|             }) | ||||
|         })?; | ||||
|         let data = TyF64::from_kcl_val(&val0).unwrap(); | ||||
|  | ||||
|         let Some(arg1) = self.args.get(1) else { | ||||
|             return Err(KclError::Semantic(KclErrorDetails { | ||||
|                 message: "Expected a solid for second argument".to_owned(), | ||||
|  | ||||
| @ -137,7 +137,7 @@ async fn inner_chamfer( | ||||
|             ModelingCmd::from(mcmd::Solid3dFilletEdge { | ||||
|                 edge_id, | ||||
|                 object_id: solid.id, | ||||
|                 radius: LengthUnit(length.n), | ||||
|                 radius: LengthUnit(length.to_mm()), | ||||
|                 tolerance: LengthUnit(DEFAULT_TOLERANCE), // We can let the user set this in the future. | ||||
|                 cut_type: CutType::Chamfer, | ||||
|             }), | ||||
|  | ||||
| @ -40,9 +40,9 @@ pub async fn extrude(exec_state: &mut ExecState, args: Args) -> Result<KclValue, | ||||
|  | ||||
|     let result = inner_extrude( | ||||
|         sketches, | ||||
|         length.n, | ||||
|         length, | ||||
|         symmetric, | ||||
|         bidirectional_length.map(|t| t.n), | ||||
|         bidirectional_length, | ||||
|         tag_start, | ||||
|         tag_end, | ||||
|         exec_state, | ||||
| @ -164,9 +164,9 @@ pub async fn extrude(exec_state: &mut ExecState, args: Args) -> Result<KclValue, | ||||
| #[allow(clippy::too_many_arguments)] | ||||
| async fn inner_extrude( | ||||
|     sketches: Vec<Sketch>, | ||||
|     length: f64, | ||||
|     length: TyF64, | ||||
|     symmetric: Option<bool>, | ||||
|     bidirectional_length: Option<f64>, | ||||
|     bidirectional_length: Option<TyF64>, | ||||
|     tag_start: Option<TagNode>, | ||||
|     tag_end: Option<TagNode>, | ||||
|     exec_state: &mut ExecState, | ||||
| @ -183,7 +183,7 @@ async fn inner_extrude( | ||||
|         })); | ||||
|     } | ||||
|  | ||||
|     let bidirection = bidirectional_length.map(LengthUnit); | ||||
|     let bidirection = bidirectional_length.map(|l| LengthUnit(l.to_mm())); | ||||
|  | ||||
|     let opposite = match (symmetric, bidirection) { | ||||
|         (Some(true), _) => Opposite::Symmetric, | ||||
| @ -201,7 +201,7 @@ async fn inner_extrude( | ||||
|                 cmd_id: id.into(), | ||||
|                 cmd: ModelingCmd::from(mcmd::Extrude { | ||||
|                     target: sketch.id.into(), | ||||
|                     distance: LengthUnit(length), | ||||
|                     distance: LengthUnit(length.to_mm()), | ||||
|                     faces: Default::default(), | ||||
|                     opposite: opposite.clone(), | ||||
|                 }), | ||||
| @ -213,7 +213,7 @@ async fn inner_extrude( | ||||
|             do_post_extrude( | ||||
|                 sketch, | ||||
|                 id.into(), | ||||
|                 length, | ||||
|                 length.clone(), | ||||
|                 false, | ||||
|                 &NamedCapTags { | ||||
|                     start: tag_start.as_ref(), | ||||
| @ -238,7 +238,7 @@ pub(crate) struct NamedCapTags<'a> { | ||||
| pub(crate) async fn do_post_extrude<'a>( | ||||
|     sketch: &Sketch, | ||||
|     solid_id: ArtifactId, | ||||
|     length: f64, | ||||
|     length: TyF64, | ||||
|     sectional: bool, | ||||
|     named_cap_tags: &'a NamedCapTags<'a>, | ||||
|     exec_state: &mut ExecState, | ||||
| @ -470,8 +470,8 @@ pub(crate) async fn do_post_extrude<'a>( | ||||
|         value: new_value, | ||||
|         meta: sketch.meta.clone(), | ||||
|         units: sketch.units, | ||||
|         height: length.to_length_units(sketch.units), | ||||
|         sketch, | ||||
|         height: length, | ||||
|         start_cap_id, | ||||
|         end_cap_id, | ||||
|         edge_cuts: vec![], | ||||
|  | ||||
| @ -64,14 +64,14 @@ pub(super) fn validate_unique<T: Eq + std::hash::Hash>(tags: &[(T, SourceRange)] | ||||
| pub async fn fillet(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> { | ||||
|     let solid = args.get_unlabeled_kw_arg_typed("solid", &RuntimeType::solid(), exec_state)?; | ||||
|     let radius: TyF64 = args.get_kw_arg_typed("radius", &RuntimeType::length(), exec_state)?; | ||||
|     let tolerance: Option<TyF64> = args.get_kw_arg_opt_typed("tolerance", &RuntimeType::count(), exec_state)?; | ||||
|     let tolerance: Option<TyF64> = args.get_kw_arg_opt_typed("tolerance", &RuntimeType::length(), exec_state)?; | ||||
|     let tags = args.kw_arg_array_and_source::<EdgeReference>("tags")?; | ||||
|     let tag = args.get_kw_arg_opt("tag")?; | ||||
|  | ||||
|     // Run the function. | ||||
|     validate_unique(&tags)?; | ||||
|     let tags: Vec<EdgeReference> = tags.into_iter().map(|item| item.0).collect(); | ||||
|     let value = inner_fillet(solid, radius, tags, tolerance.map(|t| t.n), tag, exec_state, args).await?; | ||||
|     let value = inner_fillet(solid, radius, tags, tolerance, tag, exec_state, args).await?; | ||||
|     Ok(KclValue::Solid { value }) | ||||
| } | ||||
|  | ||||
| @ -148,7 +148,7 @@ async fn inner_fillet( | ||||
|     solid: Box<Solid>, | ||||
|     radius: TyF64, | ||||
|     tags: Vec<EdgeReference>, | ||||
|     tolerance: Option<f64>, | ||||
|     tolerance: Option<TyF64>, | ||||
|     tag: Option<TagNode>, | ||||
|     exec_state: &mut ExecState, | ||||
|     args: Args, | ||||
| @ -163,8 +163,8 @@ async fn inner_fillet( | ||||
|             ModelingCmd::from(mcmd::Solid3dFilletEdge { | ||||
|                 edge_id, | ||||
|                 object_id: solid.id, | ||||
|                 radius: LengthUnit(radius.n), | ||||
|                 tolerance: LengthUnit(tolerance.unwrap_or(DEFAULT_TOLERANCE)), | ||||
|                 radius: LengthUnit(radius.to_mm()), | ||||
|                 tolerance: LengthUnit(tolerance.as_ref().map(|t| t.to_mm()).unwrap_or(DEFAULT_TOLERANCE)), | ||||
|                 cut_type: CutType::Fillet, | ||||
|             }), | ||||
|         ) | ||||
|  | ||||
| @ -84,9 +84,9 @@ pub async fn helix(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K | ||||
|         revolutions.n, | ||||
|         angle_start.n, | ||||
|         ccw, | ||||
|         radius.map(|t| t.n), | ||||
|         radius, | ||||
|         axis, | ||||
|         length.map(|t| t.n), | ||||
|         length, | ||||
|         cylinder, | ||||
|         exec_state, | ||||
|         args, | ||||
| @ -100,9 +100,9 @@ async fn inner_helix( | ||||
|     revolutions: f64, | ||||
|     angle_start: f64, | ||||
|     ccw: Option<bool>, | ||||
|     radius: Option<f64>, | ||||
|     radius: Option<TyF64>, | ||||
|     axis: Option<Axis3dOrEdgeReference>, | ||||
|     length: Option<f64>, | ||||
|     length: Option<TyF64>, | ||||
|     cylinder: Option<Solid>, | ||||
|     exec_state: &mut ExecState, | ||||
|     args: Args, | ||||
| @ -130,7 +130,7 @@ async fn inner_helix( | ||||
|             ModelingCmd::from(mcmd::EntityMakeHelix { | ||||
|                 cylinder_id: cylinder.id, | ||||
|                 is_clockwise: !helix_result.ccw, | ||||
|                 length: LengthUnit(length.unwrap_or(cylinder.height)), | ||||
|                 length: LengthUnit(length.as_ref().map(|t| t.to_mm()).unwrap_or(cylinder.height_in_mm())), | ||||
|                 revolutions, | ||||
|                 start_angle: Angle::from_degrees(angle_start), | ||||
|             }), | ||||
| @ -150,20 +150,20 @@ async fn inner_helix( | ||||
|                 args.batch_modeling_cmd( | ||||
|                     id, | ||||
|                     ModelingCmd::from(mcmd::EntityMakeHelixFromParams { | ||||
|                         radius: LengthUnit(radius), | ||||
|                         radius: LengthUnit(radius.to_mm()), | ||||
|                         is_clockwise: !helix_result.ccw, | ||||
|                         length: LengthUnit(length), | ||||
|                         length: LengthUnit(length.to_mm()), | ||||
|                         revolutions, | ||||
|                         start_angle: Angle::from_degrees(angle_start), | ||||
|                         axis: Point3d { | ||||
|                             x: direction[0].n, | ||||
|                             y: direction[1].n, | ||||
|                             z: direction[2].n, | ||||
|                             x: direction[0].to_mm(), | ||||
|                             y: direction[1].to_mm(), | ||||
|                             z: direction[2].to_mm(), | ||||
|                         }, | ||||
|                         center: Point3d { | ||||
|                             x: LengthUnit(origin[0].n), | ||||
|                             y: LengthUnit(origin[1].n), | ||||
|                             z: LengthUnit(origin[2].n), | ||||
|                             x: LengthUnit(origin[0].to_mm()), | ||||
|                             y: LengthUnit(origin[1].to_mm()), | ||||
|                             z: LengthUnit(origin[2].to_mm()), | ||||
|                         }, | ||||
|                     }), | ||||
|                 ) | ||||
| @ -175,9 +175,9 @@ async fn inner_helix( | ||||
|                 args.batch_modeling_cmd( | ||||
|                     id, | ||||
|                     ModelingCmd::from(mcmd::EntityMakeHelixFromEdge { | ||||
|                         radius: LengthUnit(radius), | ||||
|                         radius: LengthUnit(radius.to_mm()), | ||||
|                         is_clockwise: !helix_result.ccw, | ||||
|                         length: length.map(LengthUnit), | ||||
|                         length: length.map(|t| LengthUnit(t.to_mm())), | ||||
|                         revolutions, | ||||
|                         start_angle: Angle::from_degrees(angle_start), | ||||
|                         edge_id, | ||||
|  | ||||
| @ -10,7 +10,10 @@ use kittycad_modeling_cmds as kcmc; | ||||
| use super::{args::TyF64, DEFAULT_TOLERANCE}; | ||||
| use crate::{ | ||||
|     errors::{KclError, KclErrorDetails}, | ||||
|     execution::{types::RuntimeType, ExecState, KclValue, Sketch, Solid}, | ||||
|     execution::{ | ||||
|         types::{NumericType, RuntimeType}, | ||||
|         ExecState, KclValue, Sketch, Solid, | ||||
|     }, | ||||
|     parsing::ast::types::TagNode, | ||||
|     std::{extrude::do_post_extrude, Args}, | ||||
| }; | ||||
| @ -30,7 +33,7 @@ pub async fn loft(exec_state: &mut ExecState, args: Args) -> Result<KclValue, Kc | ||||
|     // This can be set to override the automatically determined topological base curve, which is usually the first section encountered. | ||||
|     let base_curve_index: Option<u32> = args.get_kw_arg_opt("baseCurveIndex")?; | ||||
|     // Tolerance for the loft operation. | ||||
|     let tolerance: Option<TyF64> = args.get_kw_arg_opt_typed("tolerance", &RuntimeType::count(), exec_state)?; | ||||
|     let tolerance: Option<TyF64> = args.get_kw_arg_opt_typed("tolerance", &RuntimeType::length(), exec_state)?; | ||||
|     let tag_start = args.get_kw_arg_opt("tagStart")?; | ||||
|     let tag_end = args.get_kw_arg_opt("tagEnd")?; | ||||
|  | ||||
| @ -39,7 +42,7 @@ pub async fn loft(exec_state: &mut ExecState, args: Args) -> Result<KclValue, Kc | ||||
|         v_degree, | ||||
|         bez_approximate_rational, | ||||
|         base_curve_index, | ||||
|         tolerance.map(|t| t.n), | ||||
|         tolerance, | ||||
|         tag_start, | ||||
|         tag_end, | ||||
|         exec_state, | ||||
| @ -136,7 +139,7 @@ async fn inner_loft( | ||||
|     v_degree: NonZeroU32, | ||||
|     bez_approximate_rational: bool, | ||||
|     base_curve_index: Option<u32>, | ||||
|     tolerance: Option<f64>, | ||||
|     tolerance: Option<TyF64>, | ||||
|     tag_start: Option<TagNode>, | ||||
|     tag_end: Option<TagNode>, | ||||
|     exec_state: &mut ExecState, | ||||
| @ -160,7 +163,7 @@ async fn inner_loft( | ||||
|             section_ids: sketches.iter().map(|group| group.id).collect(), | ||||
|             base_curve_index, | ||||
|             bez_approximate_rational, | ||||
|             tolerance: LengthUnit(tolerance.unwrap_or(DEFAULT_TOLERANCE)), | ||||
|             tolerance: LengthUnit(tolerance.as_ref().map(|t| t.to_mm()).unwrap_or(DEFAULT_TOLERANCE)), | ||||
|             v_degree, | ||||
|         }), | ||||
|     ) | ||||
| @ -174,7 +177,7 @@ async fn inner_loft( | ||||
|         do_post_extrude( | ||||
|             &sketch, | ||||
|             id.into(), | ||||
|             0.0, | ||||
|             TyF64::new(0.0, NumericType::mm()), | ||||
|             false, | ||||
|             &super::extrude::NamedCapTags { | ||||
|                 start: tag_start.as_ref(), | ||||
|  | ||||
| @ -61,13 +61,13 @@ async fn inner_mirror_2d( | ||||
|                 ModelingCmd::from(mcmd::EntityMirror { | ||||
|                     ids: starting_sketches.iter().map(|sketch| sketch.id).collect(), | ||||
|                     axis: Point3d { | ||||
|                         x: direction[0].n, | ||||
|                         y: direction[1].n, | ||||
|                         x: direction[0].to_mm(), | ||||
|                         y: direction[1].to_mm(), | ||||
|                         z: 0.0, | ||||
|                     }, | ||||
|                     point: Point3d { | ||||
|                         x: LengthUnit(origin[0].n), | ||||
|                         y: LengthUnit(origin[1].n), | ||||
|                         x: LengthUnit(origin[0].to_mm()), | ||||
|                         y: LengthUnit(origin[1].to_mm()), | ||||
|                         z: LengthUnit(0.0), | ||||
|                     }, | ||||
|                 }), | ||||
|  | ||||
| @ -13,12 +13,12 @@ use kittycad_modeling_cmds::{ | ||||
|     shared::{Angle, OriginType, Rotation}, | ||||
| }; | ||||
| use schemars::JsonSchema; | ||||
| use serde::{Deserialize, Serialize}; | ||||
| use serde::Serialize; | ||||
| use uuid::Uuid; | ||||
|  | ||||
| use super::{ | ||||
|     args::Arg, | ||||
|     utils::{untype_point, untype_point_3d}, | ||||
|     utils::{point_3d_to_mm, point_to_mm}, | ||||
| }; | ||||
| use crate::{ | ||||
|     errors::{KclError, KclErrorDetails}, | ||||
| @ -34,7 +34,7 @@ use crate::{ | ||||
| const MUST_HAVE_ONE_INSTANCE: &str = "There must be at least 1 instance of your geometry"; | ||||
|  | ||||
| /// Data for a linear pattern on a 3D model. | ||||
| #[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)] | ||||
| #[derive(Debug, Clone, Serialize, PartialEq, ts_rs::TS, JsonSchema)] | ||||
| #[ts(export)] | ||||
| #[serde(rename_all = "camelCase")] | ||||
| pub struct LinearPattern3dData { | ||||
| @ -44,9 +44,9 @@ pub struct LinearPattern3dData { | ||||
|     /// If instances is 1, this has no effect. | ||||
|     pub instances: u32, | ||||
|     /// The distance between each repetition. This can also be referred to as spacing. | ||||
|     pub distance: f64, | ||||
|     pub distance: TyF64, | ||||
|     /// The axis of the pattern. | ||||
|     pub axis: [f64; 3], | ||||
|     pub axis: [TyF64; 3], | ||||
| } | ||||
|  | ||||
| /// Repeat some 3D solid, changing each repetition slightly. | ||||
| @ -498,15 +498,13 @@ fn transform_from_obj_fields<T: GeometryTrait>( | ||||
|     }; | ||||
|  | ||||
|     let scale = match transform.get("scale") { | ||||
|         Some(x) => untype_point_3d(T::array_to_point3d(x, source_ranges.clone(), exec_state)?) | ||||
|             .0 | ||||
|             .into(), | ||||
|         Some(x) => point_3d_to_mm(T::array_to_point3d(x, source_ranges.clone(), exec_state)?).into(), | ||||
|         None => kcmc::shared::Point3d { x: 1.0, y: 1.0, z: 1.0 }, | ||||
|     }; | ||||
|  | ||||
|     let translate = match transform.get("translate") { | ||||
|         Some(x) => { | ||||
|             let (arr, _) = untype_point_3d(T::array_to_point3d(x, source_ranges.clone(), exec_state)?); | ||||
|             let arr = point_3d_to_mm(T::array_to_point3d(x, source_ranges.clone(), exec_state)?); | ||||
|             kcmc::shared::Point3d::<LengthUnit> { | ||||
|                 x: LengthUnit(arr[0]), | ||||
|                 y: LengthUnit(arr[1]), | ||||
| @ -530,9 +528,7 @@ fn transform_from_obj_fields<T: GeometryTrait>( | ||||
|             })); | ||||
|         }; | ||||
|         if let Some(axis) = rot.get("axis") { | ||||
|             rotation.axis = untype_point_3d(T::array_to_point3d(axis, source_ranges.clone(), exec_state)?) | ||||
|                 .0 | ||||
|                 .into(); | ||||
|             rotation.axis = point_3d_to_mm(T::array_to_point3d(axis, source_ranges.clone(), exec_state)?).into(); | ||||
|         } | ||||
|         if let Some(angle) = rot.get("angle") { | ||||
|             match angle { | ||||
| @ -552,9 +548,7 @@ fn transform_from_obj_fields<T: GeometryTrait>( | ||||
|                 KclValue::String { value: s, meta: _ } if s == "local" => OriginType::Local, | ||||
|                 KclValue::String { value: s, meta: _ } if s == "global" => OriginType::Global, | ||||
|                 other => { | ||||
|                     let origin = untype_point_3d(T::array_to_point3d(other, source_ranges.clone(), exec_state)?) | ||||
|                         .0 | ||||
|                         .into(); | ||||
|                     let origin = point_3d_to_mm(T::array_to_point3d(other, source_ranges.clone(), exec_state)?).into(); | ||||
|                     OriginType::Custom { origin } | ||||
|                 } | ||||
|             }; | ||||
| @ -721,8 +715,7 @@ pub async fn pattern_linear_2d(exec_state: &mut ExecState, args: Args) -> Result | ||||
|     let axis: [TyF64; 2] = args.get_kw_arg_typed("axis", &RuntimeType::point2d(), exec_state)?; | ||||
|     let use_original: Option<bool> = args.get_kw_arg_opt("useOriginal")?; | ||||
|  | ||||
|     let axis = untype_point(axis).0; | ||||
|     if axis == [0.0, 0.0] { | ||||
|     if axis[0].n == 0.0 && axis[1].n == 0.0 { | ||||
|         return Err(KclError::Semantic(KclErrorDetails { | ||||
|             message: | ||||
|                 "The axis of the linear pattern cannot be the zero vector. Otherwise they will just duplicate in place." | ||||
| @ -731,8 +724,7 @@ pub async fn pattern_linear_2d(exec_state: &mut ExecState, args: Args) -> Result | ||||
|         })); | ||||
|     } | ||||
|  | ||||
|     let sketches = | ||||
|         inner_pattern_linear_2d(sketches, instances, distance.n, axis, use_original, exec_state, args).await?; | ||||
|     let sketches = inner_pattern_linear_2d(sketches, instances, distance, axis, use_original, exec_state, args).await?; | ||||
|     Ok(sketches.into()) | ||||
| } | ||||
|  | ||||
| @ -765,18 +757,18 @@ pub async fn pattern_linear_2d(exec_state: &mut ExecState, args: Args) -> Result | ||||
| async fn inner_pattern_linear_2d( | ||||
|     sketches: Vec<Sketch>, | ||||
|     instances: u32, | ||||
|     distance: f64, | ||||
|     axis: [f64; 2], | ||||
|     distance: TyF64, | ||||
|     axis: [TyF64; 2], | ||||
|     use_original: Option<bool>, | ||||
|     exec_state: &mut ExecState, | ||||
|     args: Args, | ||||
| ) -> Result<Vec<Sketch>, KclError> { | ||||
|     let [x, y] = axis; | ||||
|     let [x, y] = point_to_mm(axis); | ||||
|     let axis_len = f64::sqrt(x * x + y * y); | ||||
|     let normalized_axis = kcmc::shared::Point2d::from([x / axis_len, y / axis_len]); | ||||
|     let transforms: Vec<_> = (1..instances) | ||||
|         .map(|i| { | ||||
|             let d = distance * (i as f64); | ||||
|             let d = distance.to_mm() * (i as f64); | ||||
|             let translate = (normalized_axis * d).with_z(0.0).map(LengthUnit); | ||||
|             vec![Transform { | ||||
|                 translate, | ||||
| @ -802,8 +794,7 @@ pub async fn pattern_linear_3d(exec_state: &mut ExecState, args: Args) -> Result | ||||
|     let axis: [TyF64; 3] = args.get_kw_arg_typed("axis", &RuntimeType::point3d(), exec_state)?; | ||||
|     let use_original: Option<bool> = args.get_kw_arg_opt("useOriginal")?; | ||||
|  | ||||
|     let (axis, _) = untype_point_3d(axis); | ||||
|     if axis == [0.0, 0.0, 0.0] { | ||||
|     if axis[0].n == 0.0 && axis[1].n == 0.0 && axis[2].n == 0.0 { | ||||
|         return Err(KclError::Semantic(KclErrorDetails { | ||||
|             message: | ||||
|                 "The axis of the linear pattern cannot be the zero vector. Otherwise they will just duplicate in place." | ||||
| @ -812,7 +803,7 @@ pub async fn pattern_linear_3d(exec_state: &mut ExecState, args: Args) -> Result | ||||
|         })); | ||||
|     } | ||||
|  | ||||
|     let solids = inner_pattern_linear_3d(solids, instances, distance.n, axis, use_original, exec_state, args).await?; | ||||
|     let solids = inner_pattern_linear_3d(solids, instances, distance, axis, use_original, exec_state, args).await?; | ||||
|     Ok(solids.into()) | ||||
| } | ||||
|  | ||||
| @ -903,18 +894,18 @@ pub async fn pattern_linear_3d(exec_state: &mut ExecState, args: Args) -> Result | ||||
| async fn inner_pattern_linear_3d( | ||||
|     solids: Vec<Solid>, | ||||
|     instances: u32, | ||||
|     distance: f64, | ||||
|     axis: [f64; 3], | ||||
|     distance: TyF64, | ||||
|     axis: [TyF64; 3], | ||||
|     use_original: Option<bool>, | ||||
|     exec_state: &mut ExecState, | ||||
|     args: Args, | ||||
| ) -> Result<Vec<Solid>, KclError> { | ||||
|     let [x, y, z] = axis; | ||||
|     let [x, y, z] = point_3d_to_mm(axis); | ||||
|     let axis_len = f64::sqrt(x * x + y * y + z * z); | ||||
|     let normalized_axis = kcmc::shared::Point3d::from([x / axis_len, y / axis_len, z / axis_len]); | ||||
|     let transforms: Vec<_> = (1..instances) | ||||
|         .map(|i| { | ||||
|             let d = distance * (i as f64); | ||||
|             let d = distance.to_mm() * (i as f64); | ||||
|             let translate = (normalized_axis * d).map(LengthUnit); | ||||
|             vec![Transform { | ||||
|                 translate, | ||||
| @ -926,7 +917,7 @@ async fn inner_pattern_linear_3d( | ||||
| } | ||||
|  | ||||
| /// Data for a circular pattern on a 2D sketch. | ||||
| #[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)] | ||||
| #[derive(Debug, Clone, Serialize, PartialEq, ts_rs::TS, JsonSchema)] | ||||
| #[ts(export)] | ||||
| #[serde(rename_all = "camelCase")] | ||||
| struct CircularPattern2dData { | ||||
| @ -936,7 +927,7 @@ struct CircularPattern2dData { | ||||
|     /// If instances is 1, this has no effect. | ||||
|     pub instances: u32, | ||||
|     /// The center about which to make the pattern. This is a 2D vector. | ||||
|     pub center: [f64; 2], | ||||
|     pub center: [TyF64; 2], | ||||
|     /// The arc angle (in degrees) to place the repetitions. Must be greater than 0. | ||||
|     pub arc_degrees: f64, | ||||
|     /// Whether or not to rotate the duplicates as they are copied. | ||||
| @ -948,7 +939,7 @@ struct CircularPattern2dData { | ||||
| } | ||||
|  | ||||
| /// Data for a circular pattern on a 3D model. | ||||
| #[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)] | ||||
| #[derive(Debug, Clone, Serialize, PartialEq, ts_rs::TS, JsonSchema)] | ||||
| #[ts(export)] | ||||
| #[serde(rename_all = "camelCase")] | ||||
| pub struct CircularPattern3dData { | ||||
| @ -958,9 +949,10 @@ pub struct CircularPattern3dData { | ||||
|     /// If instances is 1, this has no effect. | ||||
|     pub instances: u32, | ||||
|     /// The axis around which to make the pattern. This is a 3D vector. | ||||
|     // Only the direction should matter, not the magnitude so don't adjust units to avoid normalisation issues. | ||||
|     pub axis: [f64; 3], | ||||
|     /// The center about which to make the pattern. This is a 3D vector. | ||||
|     pub center: [f64; 3], | ||||
|     pub center: [TyF64; 3], | ||||
|     /// The arc angle (in degrees) to place the repetitions. Must be greater than 0. | ||||
|     pub arc_degrees: f64, | ||||
|     /// Whether or not to rotate the duplicates as they are copied. | ||||
| @ -971,6 +963,7 @@ pub struct CircularPattern3dData { | ||||
|     pub use_original: Option<bool>, | ||||
| } | ||||
|  | ||||
| #[allow(clippy::large_enum_variant)] | ||||
| enum CircularPattern { | ||||
|     ThreeD(CircularPattern3dData), | ||||
|     TwoD(CircularPattern2dData), | ||||
| @ -999,14 +992,14 @@ impl CircularPattern { | ||||
|     pub fn axis(&self) -> [f64; 3] { | ||||
|         match self { | ||||
|             CircularPattern::TwoD(_lp) => [0.0, 0.0, 0.0], | ||||
|             CircularPattern::ThreeD(lp) => lp.axis, | ||||
|             CircularPattern::ThreeD(lp) => [lp.axis[0], lp.axis[1], lp.axis[2]], | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     pub fn center(&self) -> [f64; 3] { | ||||
|     pub fn center_mm(&self) -> [f64; 3] { | ||||
|         match self { | ||||
|             CircularPattern::TwoD(lp) => [lp.center[0], lp.center[1], 0.0], | ||||
|             CircularPattern::ThreeD(lp) => lp.center, | ||||
|             CircularPattern::TwoD(lp) => [lp.center[0].to_mm(), lp.center[1].to_mm(), 0.0], | ||||
|             CircularPattern::ThreeD(lp) => [lp.center[0].to_mm(), lp.center[1].to_mm(), lp.center[2].to_mm()], | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @ -1052,7 +1045,7 @@ pub async fn pattern_circular_2d(exec_state: &mut ExecState, args: Args) -> Resu | ||||
|     let sketches = inner_pattern_circular_2d( | ||||
|         sketches, | ||||
|         instances, | ||||
|         untype_point(center).0, | ||||
|         center, | ||||
|         arc_degrees.n, | ||||
|         rotate_duplicates, | ||||
|         use_original, | ||||
| @ -1101,7 +1094,7 @@ pub async fn pattern_circular_2d(exec_state: &mut ExecState, args: Args) -> Resu | ||||
| async fn inner_pattern_circular_2d( | ||||
|     sketch_set: Vec<Sketch>, | ||||
|     instances: u32, | ||||
|     center: [f64; 2], | ||||
|     center: [TyF64; 2], | ||||
|     arc_degrees: f64, | ||||
|     rotate_duplicates: bool, | ||||
|     use_original: Option<bool>, | ||||
| @ -1151,7 +1144,7 @@ pub async fn pattern_circular_3d(exec_state: &mut ExecState, args: Args) -> Resu | ||||
|     // This includes the original entity. For example, if instances is 2, | ||||
|     // there will be two copies -- the original, and one new copy. | ||||
|     // If instances is 1, this has no effect. | ||||
|     let instances: u32 = args.get_kw_arg("instances")?; | ||||
|     let instances: u32 = args.get_kw_arg_typed("instances", &RuntimeType::count(), exec_state)?; | ||||
|     // The axis around which to make the pattern. This is a 3D vector. | ||||
|     let axis: [TyF64; 3] = args.get_kw_arg_typed("axis", &RuntimeType::point3d(), exec_state)?; | ||||
|     // The center about which to make the pattern. This is a 3D vector. | ||||
| @ -1167,8 +1160,8 @@ pub async fn pattern_circular_3d(exec_state: &mut ExecState, args: Args) -> Resu | ||||
|     let solids = inner_pattern_circular_3d( | ||||
|         solids, | ||||
|         instances, | ||||
|         untype_point_3d(axis).0, | ||||
|         untype_point_3d(center).0, | ||||
|         [axis[0].n, axis[1].n, axis[2].n], | ||||
|         center, | ||||
|         arc_degrees.n, | ||||
|         rotate_duplicates, | ||||
|         use_original, | ||||
| @ -1217,7 +1210,7 @@ async fn inner_pattern_circular_3d( | ||||
|     solids: Vec<Solid>, | ||||
|     instances: u32, | ||||
|     axis: [f64; 3], | ||||
|     center: [f64; 3], | ||||
|     center: [TyF64; 3], | ||||
|     arc_degrees: f64, | ||||
|     rotate_duplicates: bool, | ||||
|     use_original: Option<bool>, | ||||
| @ -1286,7 +1279,7 @@ async fn pattern_circular( | ||||
|         } | ||||
|     }; | ||||
|  | ||||
|     let center = data.center(); | ||||
|     let center = data.center_mm(); | ||||
|     let resp = args | ||||
|         .send_modeling_cmd( | ||||
|             id, | ||||
|  | ||||
| @ -15,8 +15,7 @@ use crate::{ | ||||
| pub async fn offset_plane(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> { | ||||
|     let std_plane = args.get_unlabeled_kw_arg("plane")?; | ||||
|     let offset: TyF64 = args.get_kw_arg_typed("offset", &RuntimeType::length(), exec_state)?; | ||||
|     let plane = inner_offset_plane(std_plane, offset.n, exec_state).await?; | ||||
|     make_offset_plane_in_engine(&plane, exec_state, &args).await?; | ||||
|     let plane = inner_offset_plane(std_plane, offset, exec_state, &args).await?; | ||||
|     Ok(KclValue::Plane { value: Box::new(plane) }) | ||||
| } | ||||
|  | ||||
| @ -112,13 +111,19 @@ pub async fn offset_plane(exec_state: &mut ExecState, args: Args) -> Result<KclV | ||||
|         offset = { docs = "Distance from the standard plane this new plane will be created at." }, | ||||
|     } | ||||
| }] | ||||
| async fn inner_offset_plane(plane: PlaneData, offset: f64, exec_state: &mut ExecState) -> Result<Plane, KclError> { | ||||
| async fn inner_offset_plane( | ||||
|     plane: PlaneData, | ||||
|     offset: TyF64, | ||||
|     exec_state: &mut ExecState, | ||||
|     args: &Args, | ||||
| ) -> Result<Plane, KclError> { | ||||
|     let mut plane = Plane::from_plane_data(plane, exec_state); | ||||
|     // Though offset planes might be derived from standard planes, they are not | ||||
|     // standard planes themselves. | ||||
|     plane.value = PlaneType::Custom; | ||||
|  | ||||
|     plane.origin += plane.z_axis * offset; | ||||
|     plane.origin += plane.z_axis * offset.to_length_units(plane.origin.units); | ||||
|     make_offset_plane_in_engine(&plane, exec_state, args).await?; | ||||
|  | ||||
|     Ok(plane) | ||||
| } | ||||
|  | ||||
| @ -13,7 +13,7 @@ use super::{args::TyF64, DEFAULT_TOLERANCE}; | ||||
| use crate::{ | ||||
|     errors::{KclError, KclErrorDetails}, | ||||
|     execution::{ | ||||
|         types::{PrimitiveType, RuntimeType}, | ||||
|         types::{NumericType, PrimitiveType, RuntimeType}, | ||||
|         ExecState, KclValue, Sketch, Solid, | ||||
|     }, | ||||
|     parsing::ast::types::TagNode, | ||||
| @ -32,7 +32,7 @@ pub async fn revolve(exec_state: &mut ExecState, args: Args) -> Result<KclValue, | ||||
|         exec_state, | ||||
|     )?; | ||||
|     let angle: Option<TyF64> = args.get_kw_arg_opt_typed("angle", &RuntimeType::degrees(), exec_state)?; | ||||
|     let tolerance: Option<TyF64> = args.get_kw_arg_opt_typed("tolerance", &RuntimeType::count(), exec_state)?; | ||||
|     let tolerance: Option<TyF64> = args.get_kw_arg_opt_typed("tolerance", &RuntimeType::length(), exec_state)?; | ||||
|     let tag_start = args.get_kw_arg_opt("tagStart")?; | ||||
|     let tag_end = args.get_kw_arg_opt("tagEnd")?; | ||||
|     let symmetric = args.get_kw_arg_opt("symmetric")?; | ||||
| @ -43,7 +43,7 @@ pub async fn revolve(exec_state: &mut ExecState, args: Args) -> Result<KclValue, | ||||
|         sketches, | ||||
|         axis, | ||||
|         angle.map(|t| t.n), | ||||
|         tolerance.map(|t| t.n), | ||||
|         tolerance, | ||||
|         tag_start, | ||||
|         tag_end, | ||||
|         symmetric, | ||||
| @ -60,7 +60,7 @@ async fn inner_revolve( | ||||
|     sketches: Vec<Sketch>, | ||||
|     axis: Axis2dOrEdgeReference, | ||||
|     angle: Option<f64>, | ||||
|     tolerance: Option<f64>, | ||||
|     tolerance: Option<TyF64>, | ||||
|     tag_start: Option<TagNode>, | ||||
|     tag_end: Option<TagNode>, | ||||
|     symmetric: Option<bool>, | ||||
| @ -140,16 +140,16 @@ async fn inner_revolve( | ||||
|                         angle, | ||||
|                         target: sketch.id.into(), | ||||
|                         axis: Point3d { | ||||
|                             x: direction[0].n, | ||||
|                             y: direction[1].n, | ||||
|                             x: direction[0].to_mm(), | ||||
|                             y: direction[1].to_mm(), | ||||
|                             z: 0.0, | ||||
|                         }, | ||||
|                         origin: Point3d { | ||||
|                             x: LengthUnit(origin[0].n), | ||||
|                             y: LengthUnit(origin[1].n), | ||||
|                             x: LengthUnit(origin[0].to_mm()), | ||||
|                             y: LengthUnit(origin[1].to_mm()), | ||||
|                             z: LengthUnit(0.0), | ||||
|                         }, | ||||
|                         tolerance: LengthUnit(tolerance.unwrap_or(DEFAULT_TOLERANCE)), | ||||
|                         tolerance: LengthUnit(tolerance.as_ref().map(|t| t.to_mm()).unwrap_or(DEFAULT_TOLERANCE)), | ||||
|                         axis_is_2d: true, | ||||
|                         opposite: opposite.clone(), | ||||
|                     }), | ||||
| @ -164,7 +164,7 @@ async fn inner_revolve( | ||||
|                         angle, | ||||
|                         target: sketch.id.into(), | ||||
|                         edge_id, | ||||
|                         tolerance: LengthUnit(tolerance.unwrap_or(DEFAULT_TOLERANCE)), | ||||
|                         tolerance: LengthUnit(tolerance.as_ref().map(|t| t.to_mm()).unwrap_or(DEFAULT_TOLERANCE)), | ||||
|                         opposite: opposite.clone(), | ||||
|                     }), | ||||
|                 ) | ||||
| @ -176,7 +176,7 @@ async fn inner_revolve( | ||||
|             do_post_extrude( | ||||
|                 sketch, | ||||
|                 id.into(), | ||||
|                 0.0, | ||||
|                 TyF64::new(0.0, NumericType::mm()), | ||||
|                 false, | ||||
|                 &super::extrude::NamedCapTags { | ||||
|                     start: tag_start.as_ref(), | ||||
|  | ||||
| @ -464,7 +464,7 @@ fn inner_segment_angle(tag: &TagIdentifier, exec_state: &mut ExecState, args: Ar | ||||
|         }) | ||||
|     })?; | ||||
|  | ||||
|     let result = between(path.get_from().into(), path.get_to().into()); | ||||
|     let result = between(path.get_base().from, path.get_base().to); | ||||
|  | ||||
|     Ok(result.to_degrees()) | ||||
| } | ||||
| @ -584,7 +584,7 @@ async fn inner_tangent_to_end(tag: &TagIdentifier, exec_state: &mut ExecState, a | ||||
| /// Returns the angle to match the given length for x. | ||||
| pub async fn angle_to_match_length_x(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> { | ||||
|     let (tag, to, sketch) = args.get_tag_to_number_sketch()?; | ||||
|     let result = inner_angle_to_match_length_x(&tag, to.n, sketch, exec_state, args.clone())?; | ||||
|     let result = inner_angle_to_match_length_x(&tag, to, sketch, exec_state, args.clone())?; | ||||
|     Ok(args.make_user_val_from_f64_with_type(TyF64::new(result, NumericType::degrees()))) | ||||
| } | ||||
|  | ||||
| @ -607,7 +607,7 @@ pub async fn angle_to_match_length_x(exec_state: &mut ExecState, args: Args) -> | ||||
| }] | ||||
| fn inner_angle_to_match_length_x( | ||||
|     tag: &TagIdentifier, | ||||
|     to: f64, | ||||
|     to: TyF64, | ||||
|     sketch: Sketch, | ||||
|     exec_state: &mut ExecState, | ||||
|     args: Args, | ||||
| @ -633,8 +633,7 @@ fn inner_angle_to_match_length_x( | ||||
|         })? | ||||
|         .get_base(); | ||||
|  | ||||
|     // TODO assumption about the units of to | ||||
|     let diff = (to - last_line.to[0]).abs(); | ||||
|     let diff = (to.to_length_units(sketch.units) - last_line.to[0]).abs(); | ||||
|  | ||||
|     let angle_r = (diff / length).acos(); | ||||
|  | ||||
| @ -648,7 +647,7 @@ fn inner_angle_to_match_length_x( | ||||
| /// Returns the angle to match the given length for y. | ||||
| pub async fn angle_to_match_length_y(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> { | ||||
|     let (tag, to, sketch) = args.get_tag_to_number_sketch()?; | ||||
|     let result = inner_angle_to_match_length_y(&tag, to.n, sketch, exec_state, args.clone())?; | ||||
|     let result = inner_angle_to_match_length_y(&tag, to, sketch, exec_state, args.clone())?; | ||||
|     Ok(args.make_user_val_from_f64_with_type(TyF64::new(result, NumericType::degrees()))) | ||||
| } | ||||
|  | ||||
| @ -672,7 +671,7 @@ pub async fn angle_to_match_length_y(exec_state: &mut ExecState, args: Args) -> | ||||
| }] | ||||
| fn inner_angle_to_match_length_y( | ||||
|     tag: &TagIdentifier, | ||||
|     to: f64, | ||||
|     to: TyF64, | ||||
|     sketch: Sketch, | ||||
|     exec_state: &mut ExecState, | ||||
|     args: Args, | ||||
| @ -698,8 +697,7 @@ fn inner_angle_to_match_length_y( | ||||
|         })? | ||||
|         .get_base(); | ||||
|  | ||||
|     // TODO assumption about the units of to | ||||
|     let diff = (to - last_line.to[1]).abs(); | ||||
|     let diff = (to.to_length_units(sketch.units) - last_line.to[1]).abs(); | ||||
|  | ||||
|     let angle_r = (diff / length).asin(); | ||||
|  | ||||
|  | ||||
| @ -13,10 +13,16 @@ use kittycad_modeling_cmds::shared::PathSegment; | ||||
| use schemars::JsonSchema; | ||||
| use serde::Serialize; | ||||
|  | ||||
| use super::{args::TyF64, utils::untype_point}; | ||||
| use super::{ | ||||
|     args::TyF64, | ||||
|     utils::{point_to_len_unit, point_to_mm, point_to_typed, untype_point, untyped_point_to_mm}, | ||||
| }; | ||||
| use crate::{ | ||||
|     errors::{KclError, KclErrorDetails}, | ||||
|     execution::{types::RuntimeType, BasePath, ExecState, GeoMeta, KclValue, Path, Sketch, SketchSurface}, | ||||
|     execution::{ | ||||
|         types::{RuntimeType, UnitLen}, | ||||
|         BasePath, ExecState, GeoMeta, KclValue, Path, Sketch, SketchSurface, | ||||
|     }, | ||||
|     parsing::ast::types::TagNode, | ||||
|     std::{ | ||||
|         sketch::NEW_TAG_KW, | ||||
| @ -41,15 +47,7 @@ pub async fn circle(exec_state: &mut ExecState, args: Args) -> Result<KclValue, | ||||
|     let radius: TyF64 = args.get_kw_arg_typed("radius", &RuntimeType::length(), exec_state)?; | ||||
|     let tag = args.get_kw_arg_opt(NEW_TAG_KW)?; | ||||
|  | ||||
|     let sketch = inner_circle( | ||||
|         sketch_or_surface, | ||||
|         untype_point(center).0, | ||||
|         radius.n, | ||||
|         tag, | ||||
|         exec_state, | ||||
|         args, | ||||
|     ) | ||||
|     .await?; | ||||
|     let sketch = inner_circle(sketch_or_surface, center, radius, tag, exec_state, args).await?; | ||||
|     Ok(KclValue::Sketch { | ||||
|         value: Box::new(sketch), | ||||
|     }) | ||||
| @ -57,8 +55,8 @@ pub async fn circle(exec_state: &mut ExecState, args: Args) -> Result<KclValue, | ||||
|  | ||||
| async fn inner_circle( | ||||
|     sketch_or_surface: SketchOrSurface, | ||||
|     center: [f64; 2], | ||||
|     radius: f64, | ||||
|     center: [TyF64; 2], | ||||
|     radius: TyF64, | ||||
|     tag: Option<TagNode>, | ||||
|     exec_state: &mut ExecState, | ||||
|     args: Args, | ||||
| @ -67,17 +65,15 @@ async fn inner_circle( | ||||
|         SketchOrSurface::SketchSurface(surface) => surface, | ||||
|         SketchOrSurface::Sketch(s) => s.on, | ||||
|     }; | ||||
|     let units = sketch_surface.units(); | ||||
|     let sketch = crate::std::sketch::inner_start_profile_at( | ||||
|         [center[0] + radius, center[1]], | ||||
|         sketch_surface, | ||||
|         None, | ||||
|         exec_state, | ||||
|         args.clone(), | ||||
|     ) | ||||
|     .await?; | ||||
|     let (center_u, ty) = untype_point(center.clone()); | ||||
|     let units = ty.expect_length(); | ||||
|  | ||||
|     let from = [center_u[0] + radius.to_length_units(units), center_u[1]]; | ||||
|     let from_t = [TyF64::new(from[0], ty.clone()), TyF64::new(from[1], ty)]; | ||||
|  | ||||
|     let sketch = | ||||
|         crate::std::sketch::inner_start_profile_at(from_t, sketch_surface, None, exec_state, args.clone()).await?; | ||||
|  | ||||
|     let from = [center[0] + radius, center[1]]; | ||||
|     let angle_start = Angle::zero(); | ||||
|     let angle_end = Angle::turn(); | ||||
|  | ||||
| @ -90,8 +86,8 @@ async fn inner_circle( | ||||
|             segment: PathSegment::Arc { | ||||
|                 start: angle_start, | ||||
|                 end: angle_end, | ||||
|                 center: KPoint2d::from(center).map(LengthUnit), | ||||
|                 radius: radius.into(), | ||||
|                 center: KPoint2d::from(point_to_mm(center)).map(LengthUnit), | ||||
|                 radius: LengthUnit(radius.to_mm()), | ||||
|                 relative: false, | ||||
|             }, | ||||
|         }), | ||||
| @ -109,8 +105,8 @@ async fn inner_circle( | ||||
|                 metadata: args.source_range.into(), | ||||
|             }, | ||||
|         }, | ||||
|         radius, | ||||
|         center, | ||||
|         radius: radius.to_length_units(units), | ||||
|         center: center_u, | ||||
|         ccw: angle_start < angle_end, | ||||
|     }; | ||||
|  | ||||
| @ -135,16 +131,7 @@ pub async fn circle_three_point(exec_state: &mut ExecState, args: Args) -> Resul | ||||
|     let p3 = args.get_kw_arg_typed("p3", &RuntimeType::point2d(), exec_state)?; | ||||
|     let tag = args.get_kw_arg_opt("tag")?; | ||||
|  | ||||
|     let sketch = inner_circle_three_point( | ||||
|         sketch_surface_or_group, | ||||
|         untype_point(p1).0, | ||||
|         untype_point(p2).0, | ||||
|         untype_point(p3).0, | ||||
|         tag, | ||||
|         exec_state, | ||||
|         args, | ||||
|     ) | ||||
|     .await?; | ||||
|     let sketch = inner_circle_three_point(sketch_surface_or_group, p1, p2, p3, tag, exec_state, args).await?; | ||||
|     Ok(KclValue::Sketch { | ||||
|         value: Box::new(sketch), | ||||
|     }) | ||||
| @ -174,13 +161,20 @@ pub async fn circle_three_point(exec_state: &mut ExecState, args: Args) -> Resul | ||||
| // path so it can be used for other features, otherwise it's lost. | ||||
| async fn inner_circle_three_point( | ||||
|     sketch_surface_or_group: SketchOrSurface, | ||||
|     p1: [f64; 2], | ||||
|     p2: [f64; 2], | ||||
|     p3: [f64; 2], | ||||
|     p1: [TyF64; 2], | ||||
|     p2: [TyF64; 2], | ||||
|     p3: [TyF64; 2], | ||||
|     tag: Option<TagNode>, | ||||
|     exec_state: &mut ExecState, | ||||
|     args: Args, | ||||
| ) -> Result<Sketch, KclError> { | ||||
|     let ty = p1[0].ty.clone(); | ||||
|     let units = ty.expect_length(); | ||||
|  | ||||
|     let p1 = point_to_len_unit(p1, units); | ||||
|     let p2 = point_to_len_unit(p2, units); | ||||
|     let p3 = point_to_len_unit(p3, units); | ||||
|  | ||||
|     let center = calculate_circle_center(p1, p2, p3); | ||||
|     // It can be the distance to any of the 3 points - they all lay on the circumference. | ||||
|     let radius = distance(center, p2); | ||||
| @ -189,16 +183,15 @@ async fn inner_circle_three_point( | ||||
|         SketchOrSurface::SketchSurface(surface) => surface, | ||||
|         SketchOrSurface::Sketch(group) => group.on, | ||||
|     }; | ||||
|     let sketch = crate::std::sketch::inner_start_profile_at( | ||||
|         [center[0] + radius, center[1]], | ||||
|         sketch_surface, | ||||
|         None, | ||||
|         exec_state, | ||||
|         args.clone(), | ||||
|     ) | ||||
|     .await?; | ||||
|  | ||||
|     let from = [center[0] + radius, center[1]]; | ||||
|     let from = [ | ||||
|         TyF64::new(center[0] + radius, ty.clone()), | ||||
|         TyF64::new(center[1], ty.clone()), | ||||
|     ]; | ||||
|     let sketch = | ||||
|         crate::std::sketch::inner_start_profile_at(from.clone(), sketch_surface, None, exec_state, args.clone()) | ||||
|             .await?; | ||||
|  | ||||
|     let angle_start = Angle::zero(); | ||||
|     let angle_end = Angle::turn(); | ||||
|  | ||||
| @ -211,8 +204,8 @@ async fn inner_circle_three_point( | ||||
|             segment: PathSegment::Arc { | ||||
|                 start: angle_start, | ||||
|                 end: angle_end, | ||||
|                 center: KPoint2d::from(center).map(LengthUnit), | ||||
|                 radius: radius.into(), | ||||
|                 center: KPoint2d::from(untyped_point_to_mm(center, units)).map(LengthUnit), | ||||
|                 radius: units.adjust_to(radius, UnitLen::Mm).0.into(), | ||||
|                 relative: false, | ||||
|             }, | ||||
|         }), | ||||
| @ -221,10 +214,11 @@ async fn inner_circle_three_point( | ||||
|  | ||||
|     let current_path = Path::CircleThreePoint { | ||||
|         base: BasePath { | ||||
|             from, | ||||
|             to: from, | ||||
|             // It's fine to untype here because we know `from` has units as its units. | ||||
|             from: untype_point(from.clone()).0, | ||||
|             to: untype_point(from).0, | ||||
|             tag: tag.clone(), | ||||
|             units: sketch.units, | ||||
|             units, | ||||
|             geo_meta: GeoMeta { | ||||
|                 id, | ||||
|                 metadata: args.source_range.into(), | ||||
| @ -270,7 +264,7 @@ pub async fn polygon(exec_state: &mut ExecState, args: Args) -> Result<KclValue, | ||||
|         sketch_surface_or_group, | ||||
|         radius, | ||||
|         num_sides.n as u64, | ||||
|         untype_point(center).0, | ||||
|         center, | ||||
|         inscribed, | ||||
|         exec_state, | ||||
|         args, | ||||
| @ -324,7 +318,7 @@ async fn inner_polygon( | ||||
|     sketch_surface_or_group: SketchOrSurface, | ||||
|     radius: TyF64, | ||||
|     num_sides: u64, | ||||
|     center: [f64; 2], | ||||
|     center: [TyF64; 2], | ||||
|     inscribed: Option<bool>, | ||||
|     exec_state: &mut ExecState, | ||||
|     args: Args, | ||||
| @ -343,9 +337,9 @@ async fn inner_polygon( | ||||
|         })); | ||||
|     } | ||||
|  | ||||
|     let sketch_surface = match sketch_surface_or_group { | ||||
|         SketchOrSurface::SketchSurface(surface) => surface, | ||||
|         SketchOrSurface::Sketch(group) => group.on, | ||||
|     let (sketch_surface, units) = match sketch_surface_or_group { | ||||
|         SketchOrSurface::SketchSurface(surface) => (surface, radius.ty.expect_length()), | ||||
|         SketchOrSurface::Sketch(group) => (group.on, group.units), | ||||
|     }; | ||||
|  | ||||
|     let half_angle = std::f64::consts::PI / num_sides as f64; | ||||
| @ -360,18 +354,26 @@ async fn inner_polygon( | ||||
|  | ||||
|     let angle_step = std::f64::consts::TAU / num_sides as f64; | ||||
|  | ||||
|     let center_u = point_to_len_unit(center, units); | ||||
|  | ||||
|     let vertices: Vec<[f64; 2]> = (0..num_sides) | ||||
|         .map(|i| { | ||||
|             let angle = angle_step * i as f64; | ||||
|             [ | ||||
|                 center[0] + radius_to_vertices * angle.cos(), | ||||
|                 center[1] + radius_to_vertices * angle.sin(), | ||||
|                 center_u[0] + radius_to_vertices * angle.cos(), | ||||
|                 center_u[1] + radius_to_vertices * angle.sin(), | ||||
|             ] | ||||
|         }) | ||||
|         .collect(); | ||||
|  | ||||
|     let mut sketch = | ||||
|         crate::std::sketch::inner_start_profile_at(vertices[0], sketch_surface, None, exec_state, args.clone()).await?; | ||||
|     let mut sketch = crate::std::sketch::inner_start_profile_at( | ||||
|         point_to_typed(vertices[0], units), | ||||
|         sketch_surface, | ||||
|         None, | ||||
|         exec_state, | ||||
|         args.clone(), | ||||
|     ) | ||||
|     .await?; | ||||
|  | ||||
|     // Draw all the lines with unique IDs and modified tags | ||||
|     for vertex in vertices.iter().skip(1) { | ||||
| @ -383,7 +385,9 @@ async fn inner_polygon( | ||||
|             ModelingCmd::from(mcmd::ExtendPath { | ||||
|                 path: sketch.id.into(), | ||||
|                 segment: PathSegment::Line { | ||||
|                     end: KPoint2d::from(*vertex).with_z(0.0).map(LengthUnit), | ||||
|                     end: KPoint2d::from(untyped_point_to_mm(*vertex, units)) | ||||
|                         .with_z(0.0) | ||||
|                         .map(LengthUnit), | ||||
|                     relative: false, | ||||
|                 }, | ||||
|             }), | ||||
| @ -392,7 +396,7 @@ async fn inner_polygon( | ||||
|  | ||||
|         let current_path = Path::ToPoint { | ||||
|             base: BasePath { | ||||
|                 from: from.into(), | ||||
|                 from: from.ignore_units(), | ||||
|                 to: *vertex, | ||||
|                 tag: None, | ||||
|                 units: sketch.units, | ||||
| @ -415,7 +419,9 @@ async fn inner_polygon( | ||||
|         ModelingCmd::from(mcmd::ExtendPath { | ||||
|             path: sketch.id.into(), | ||||
|             segment: PathSegment::Line { | ||||
|                 end: KPoint2d::from(vertices[0]).with_z(0.0).map(LengthUnit), | ||||
|                 end: KPoint2d::from(untyped_point_to_mm(vertices[0], units)) | ||||
|                     .with_z(0.0) | ||||
|                     .map(LengthUnit), | ||||
|                 relative: false, | ||||
|             }, | ||||
|         }), | ||||
| @ -424,7 +430,7 @@ async fn inner_polygon( | ||||
|  | ||||
|     let current_path = Path::ToPoint { | ||||
|         base: BasePath { | ||||
|             from: from.into(), | ||||
|             from: from.ignore_units(), | ||||
|             to: vertices[0], | ||||
|             tag: None, | ||||
|             units: sketch.units, | ||||
|  | ||||
| @ -16,10 +16,10 @@ use super::args::TyF64; | ||||
| /// Create a shell. | ||||
| pub async fn shell(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> { | ||||
|     let solids = args.get_unlabeled_kw_arg_typed("solids", &RuntimeType::solids(), exec_state)?; | ||||
|     let thickness: TyF64 = args.get_kw_arg_typed("thickness", &RuntimeType::count(), exec_state)?; | ||||
|     let thickness: TyF64 = args.get_kw_arg_typed("thickness", &RuntimeType::length(), exec_state)?; | ||||
|     let faces = args.get_kw_arg("faces")?; | ||||
|  | ||||
|     let result = inner_shell(solids, thickness.n, faces, exec_state, args).await?; | ||||
|     let result = inner_shell(solids, thickness, faces, exec_state, args).await?; | ||||
|     Ok(result.into()) | ||||
| } | ||||
|  | ||||
| @ -182,7 +182,7 @@ pub async fn shell(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K | ||||
| }] | ||||
| async fn inner_shell( | ||||
|     solids: Vec<Solid>, | ||||
|     thickness: f64, | ||||
|     thickness: TyF64, | ||||
|     faces: Vec<FaceTag>, | ||||
|     exec_state: &mut ExecState, | ||||
|     args: Args, | ||||
| @ -237,7 +237,7 @@ async fn inner_shell( | ||||
|             hollow: false, | ||||
|             face_ids, | ||||
|             object_id: solids[0].id, | ||||
|             shell_thickness: LengthUnit(thickness), | ||||
|             shell_thickness: LengthUnit(thickness.to_mm()), | ||||
|         }), | ||||
|     ) | ||||
|     .await?; | ||||
| @ -247,9 +247,9 @@ async fn inner_shell( | ||||
|  | ||||
| /// Make the inside of a 3D object hollow. | ||||
| pub async fn hollow(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> { | ||||
|     let (thickness, solid) = args.get_data_and_solid(exec_state)?; | ||||
|     let (thickness, solid) = args.get_length_and_solid(exec_state)?; | ||||
|  | ||||
|     let value = inner_hollow(thickness.n, solid, exec_state, args).await?; | ||||
|     let value = inner_hollow(thickness, solid, exec_state, args).await?; | ||||
|     Ok(KclValue::Solid { value }) | ||||
| } | ||||
|  | ||||
| @ -308,7 +308,7 @@ pub async fn hollow(exec_state: &mut ExecState, args: Args) -> Result<KclValue, | ||||
|     feature_tree_operation = true, | ||||
| }] | ||||
| async fn inner_hollow( | ||||
|     thickness: f64, | ||||
|     thickness: TyF64, | ||||
|     solid: Box<Solid>, | ||||
|     exec_state: &mut ExecState, | ||||
|     args: Args, | ||||
| @ -323,7 +323,7 @@ async fn inner_hollow( | ||||
|             hollow: true, | ||||
|             face_ids: Vec::new(), // This is empty because we want to hollow the entire object. | ||||
|             object_id: solid.id, | ||||
|             shell_thickness: LengthUnit(thickness), | ||||
|             shell_thickness: LengthUnit(thickness.to_mm()), | ||||
|         }), | ||||
|     ) | ||||
|     .await?; | ||||
|  | ||||
| @ -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, | ||||
|  | ||||
| @ -10,7 +10,10 @@ use serde::Serialize; | ||||
| use super::{args::TyF64, DEFAULT_TOLERANCE}; | ||||
| use crate::{ | ||||
|     errors::KclError, | ||||
|     execution::{types::RuntimeType, ExecState, Helix, KclValue, Sketch, Solid}, | ||||
|     execution::{ | ||||
|         types::{NumericType, RuntimeType}, | ||||
|         ExecState, Helix, KclValue, Sketch, Solid, | ||||
|     }, | ||||
|     parsing::ast::types::TagNode, | ||||
|     std::{extrude::do_post_extrude, Args}, | ||||
| }; | ||||
| @ -33,19 +36,12 @@ pub async fn sweep(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K | ||||
|         exec_state, | ||||
|     )?; | ||||
|     let sectional = args.get_kw_arg_opt("sectional")?; | ||||
|     let tolerance: Option<TyF64> = args.get_kw_arg_opt_typed("tolerance", &RuntimeType::count(), exec_state)?; | ||||
|     let tolerance: Option<TyF64> = args.get_kw_arg_opt_typed("tolerance", &RuntimeType::length(), exec_state)?; | ||||
|     let tag_start = args.get_kw_arg_opt("tagStart")?; | ||||
|     let tag_end = args.get_kw_arg_opt("tagEnd")?; | ||||
|  | ||||
|     let value = inner_sweep( | ||||
|         sketches, | ||||
|         path, | ||||
|         sectional, | ||||
|         tolerance.map(|t| t.n), | ||||
|         tag_start, | ||||
|         tag_end, | ||||
|         exec_state, | ||||
|         args, | ||||
|         sketches, path, sectional, tolerance, tag_start, tag_end, exec_state, args, | ||||
|     ) | ||||
|     .await?; | ||||
|     Ok(value.into()) | ||||
| @ -171,7 +167,7 @@ async fn inner_sweep( | ||||
|     sketches: Vec<Sketch>, | ||||
|     path: SweepPath, | ||||
|     sectional: Option<bool>, | ||||
|     tolerance: Option<f64>, | ||||
|     tolerance: Option<TyF64>, | ||||
|     tag_start: Option<TagNode>, | ||||
|     tag_end: Option<TagNode>, | ||||
|     exec_state: &mut ExecState, | ||||
| @ -191,7 +187,7 @@ async fn inner_sweep( | ||||
|                 target: sketch.id.into(), | ||||
|                 trajectory, | ||||
|                 sectional: sectional.unwrap_or(false), | ||||
|                 tolerance: LengthUnit(tolerance.unwrap_or(DEFAULT_TOLERANCE)), | ||||
|                 tolerance: LengthUnit(tolerance.as_ref().map(|t| t.to_mm()).unwrap_or(DEFAULT_TOLERANCE)), | ||||
|             }), | ||||
|         ) | ||||
|         .await?; | ||||
| @ -200,7 +196,7 @@ async fn inner_sweep( | ||||
|             do_post_extrude( | ||||
|                 sketch, | ||||
|                 id.into(), | ||||
|                 0.0, | ||||
|                 TyF64::new(0.0, NumericType::mm()), | ||||
|                 sectional.unwrap_or(false), | ||||
|                 &super::extrude::NamedCapTags { | ||||
|                     start: tag_start.as_ref(), | ||||
|  | ||||
| @ -225,16 +225,7 @@ pub async fn translate(exec_state: &mut ExecState, args: Args) -> Result<KclValu | ||||
|         })); | ||||
|     } | ||||
|  | ||||
|     let objects = inner_translate( | ||||
|         objects, | ||||
|         translate_x.map(|t| t.n), | ||||
|         translate_y.map(|t| t.n), | ||||
|         translate_z.map(|t| t.n), | ||||
|         global, | ||||
|         exec_state, | ||||
|         args, | ||||
|     ) | ||||
|     .await?; | ||||
|     let objects = inner_translate(objects, translate_x, translate_y, translate_z, global, exec_state, args).await?; | ||||
|     Ok(objects.into()) | ||||
| } | ||||
|  | ||||
| @ -397,9 +388,9 @@ pub async fn translate(exec_state: &mut ExecState, args: Args) -> Result<KclValu | ||||
| }] | ||||
| async fn inner_translate( | ||||
|     objects: SolidOrSketchOrImportedGeometry, | ||||
|     x: Option<f64>, | ||||
|     y: Option<f64>, | ||||
|     z: Option<f64>, | ||||
|     x: Option<TyF64>, | ||||
|     y: Option<TyF64>, | ||||
|     z: Option<TyF64>, | ||||
|     global: Option<bool>, | ||||
|     exec_state: &mut ExecState, | ||||
|     args: Args, | ||||
| @ -421,9 +412,9 @@ async fn inner_translate( | ||||
|                 transforms: vec![shared::ComponentTransform { | ||||
|                     translate: Some(shared::TransformBy::<Point3d<LengthUnit>> { | ||||
|                         property: shared::Point3d { | ||||
|                             x: LengthUnit(x.unwrap_or_default()), | ||||
|                             y: LengthUnit(y.unwrap_or_default()), | ||||
|                             z: LengthUnit(z.unwrap_or_default()), | ||||
|                             x: LengthUnit(x.as_ref().map(|t| t.to_mm()).unwrap_or_default()), | ||||
|                             y: LengthUnit(y.as_ref().map(|t| t.to_mm()).unwrap_or_default()), | ||||
|                             z: LengthUnit(z.as_ref().map(|t| t.to_mm()).unwrap_or_default()), | ||||
|                         }, | ||||
|                         set: false, | ||||
|                         is_local: !global.unwrap_or(false), | ||||
| @ -544,7 +535,9 @@ pub async fn rotate(exec_state: &mut ExecState, args: Args) -> Result<KclValue, | ||||
|         roll.map(|t| t.n), | ||||
|         pitch.map(|t| t.n), | ||||
|         yaw.map(|t| t.n), | ||||
|         axis.map(|p| [p[0].n, p[1].n, p[2].n]), | ||||
|         // Don't adjust axis units since the axis must be normalized and only the direction | ||||
|         // should be significant, not the magnitude. | ||||
|         axis.map(|a| [a[0].n, a[1].n, a[2].n]), | ||||
|         angle.map(|t| t.n), | ||||
|         global, | ||||
|         exec_state, | ||||
| @ -780,7 +773,7 @@ async fn inner_rotate( | ||||
|     for object_id in objects.ids(&args.ctx).await? { | ||||
|         let id = exec_state.next_uuid(); | ||||
|  | ||||
|         if let (Some(axis), Some(angle)) = (axis, angle) { | ||||
|         if let (Some(axis), Some(angle)) = (&axis, angle) { | ||||
|             args.batch_modeling_cmd( | ||||
|                 id, | ||||
|                 ModelingCmd::from(mcmd::SetObjectTransform { | ||||
|  | ||||
| @ -25,7 +25,7 @@ pub async fn from_mm(exec_state: &mut ExecState, args: Args) -> Result<KclValue, | ||||
|  | ||||
| /// Converts a number from mm to the current default unit. | ||||
| /// | ||||
| /// *DEPRECATED* prefer using explicit numberic suffixes (e.g., `42mm`) or the `to...` conversion functions. | ||||
| /// *DEPRECATED* prefer using explicit numeric suffixes (e.g., `42mm`) or the `to...` conversion functions. | ||||
| /// | ||||
| /// No matter what units the current file uses, this function will always return a number equivalent | ||||
| /// to the input in millimeters. | ||||
| @ -74,7 +74,7 @@ pub async fn from_inches(exec_state: &mut ExecState, args: Args) -> Result<KclVa | ||||
|  | ||||
| /// Converts a number from inches to the current default unit. | ||||
| /// | ||||
| /// *DEPRECATED* prefer using explicit numberic suffixes (e.g., `42inch`) or the `to...` conversion functions. | ||||
| /// *DEPRECATED* prefer using explicit numeric suffixes (e.g., `42inch`) or the `to...` conversion functions. | ||||
| /// | ||||
| /// No matter what units the current file uses, this function will always return a number equivalent | ||||
| /// to the input in inches. | ||||
| @ -123,7 +123,7 @@ pub async fn from_ft(exec_state: &mut ExecState, args: Args) -> Result<KclValue, | ||||
|  | ||||
| /// Converts a number from feet to the current default unit. | ||||
| /// | ||||
| /// *DEPRECATED* prefer using explicit numberic suffixes (e.g., `42ft`) or the `to...` conversion functions. | ||||
| /// *DEPRECATED* prefer using explicit numeric suffixes (e.g., `42ft`) or the `to...` conversion functions. | ||||
| /// | ||||
| /// No matter what units the current file uses, this function will always return a number equivalent | ||||
| /// to the input in feet. | ||||
| @ -173,7 +173,7 @@ pub async fn from_m(exec_state: &mut ExecState, args: Args) -> Result<KclValue, | ||||
|  | ||||
| /// Converts a number from meters to the current default unit. | ||||
| /// | ||||
| /// *DEPRECATED* prefer using explicit numberic suffixes (e.g., `42m`) or the `to...` conversion functions. | ||||
| /// *DEPRECATED* prefer using explicit numeric suffixes (e.g., `42m`) or the `to...` conversion functions. | ||||
| /// | ||||
| /// No matter what units the current file uses, this function will always return a number equivalent | ||||
| /// to the input in meters. | ||||
| @ -223,7 +223,7 @@ pub async fn from_cm(exec_state: &mut ExecState, args: Args) -> Result<KclValue, | ||||
|  | ||||
| /// Converts a number from centimeters to the current default unit. | ||||
| /// | ||||
| /// *DEPRECATED* prefer using explicit numberic suffixes (e.g., `42cm`) or the `to...` conversion functions. | ||||
| /// *DEPRECATED* prefer using explicit numeric suffixes (e.g., `42cm`) or the `to...` conversion functions. | ||||
| /// | ||||
| /// No matter what units the current file uses, this function will always return a number equivalent | ||||
| /// to the input in centimeters. | ||||
| @ -273,7 +273,7 @@ pub async fn from_yd(exec_state: &mut ExecState, args: Args) -> Result<KclValue, | ||||
|  | ||||
| /// Converts a number from yards to the current default unit. | ||||
| /// | ||||
| /// *DEPRECATED* prefer using explicit numberic suffixes (e.g., `42yd`) or the `to...` conversion functions. | ||||
| /// *DEPRECATED* prefer using explicit numeric suffixes (e.g., `42yd`) or the `to...` conversion functions. | ||||
| /// | ||||
| /// No matter what units the current file uses, this function will always return a number equivalent | ||||
| /// to the input in yards. | ||||
|  | ||||
| @ -2,39 +2,54 @@ use std::f64::consts::PI; | ||||
|  | ||||
| use kittycad_modeling_cmds::shared::Angle; | ||||
|  | ||||
| use crate::{ | ||||
|     errors::{KclError, KclErrorDetails}, | ||||
|     execution::{types::NumericType, Point2d}, | ||||
|     source_range::SourceRange, | ||||
| }; | ||||
| use crate::execution::types::{NumericType, UnitLen}; | ||||
|  | ||||
| use super::args::TyF64; | ||||
|  | ||||
| pub fn untype_point(p: [TyF64; 2]) -> ([f64; 2], NumericType) { | ||||
| pub(crate) fn untype_point(p: [TyF64; 2]) -> ([f64; 2], NumericType) { | ||||
|     let (x, y, ty) = NumericType::combine_eq(p[0].clone(), p[1].clone()); | ||||
|     ([x, y], ty) | ||||
| } | ||||
|  | ||||
| pub fn untype_point_3d(p: [TyF64; 3]) -> ([f64; 3], NumericType) { | ||||
|     let (arr, ty) = NumericType::combine_eq_array(&[p[0].clone(), p[1].clone(), p[2].clone()]); | ||||
|     let mut iter = arr.into_iter(); | ||||
|     ([iter.next().unwrap(), iter.next().unwrap(), iter.next().unwrap()], ty) | ||||
| pub(crate) fn point_to_mm(p: [TyF64; 2]) -> [f64; 2] { | ||||
|     [p[0].to_mm(), p[1].to_mm()] | ||||
| } | ||||
|  | ||||
| pub(crate) fn untyped_point_to_mm(p: [f64; 2], units: UnitLen) -> [f64; 2] { | ||||
|     assert_ne!(units, UnitLen::Unknown); | ||||
|     [ | ||||
|         units.adjust_to(p[0], UnitLen::Mm).0, | ||||
|         units.adjust_to(p[1], UnitLen::Mm).0, | ||||
|     ] | ||||
| } | ||||
|  | ||||
| pub(crate) fn point_to_len_unit(p: [TyF64; 2], len: UnitLen) -> [f64; 2] { | ||||
|     [p[0].to_length_units(len), p[1].to_length_units(len)] | ||||
| } | ||||
|  | ||||
| /// Precondition, `p` must be in `len` units (this function does no conversion). | ||||
| pub(crate) fn point_to_typed(p: [f64; 2], len: UnitLen) -> [TyF64; 2] { | ||||
|     [TyF64::new(p[0], len.into()), TyF64::new(p[1], len.into())] | ||||
| } | ||||
|  | ||||
| pub(crate) fn point_3d_to_mm(p: [TyF64; 3]) -> [f64; 3] { | ||||
|     [p[0].to_mm(), p[1].to_mm(), p[2].to_mm()] | ||||
| } | ||||
|  | ||||
| /// Get the distance between two points. | ||||
| pub fn distance(a: Coords2d, b: Coords2d) -> f64 { | ||||
| pub(crate) fn distance(a: Coords2d, b: Coords2d) -> f64 { | ||||
|     ((b[0] - a[0]).powi(2) + (b[1] - a[1]).powi(2)).sqrt() | ||||
| } | ||||
|  | ||||
| /// Get the angle between these points | ||||
| pub fn between(a: Point2d, b: Point2d) -> Angle { | ||||
|     let x = b.x - a.x; | ||||
|     let y = b.y - a.y; | ||||
| pub(crate) fn between(a: Coords2d, b: Coords2d) -> Angle { | ||||
|     let x = b[0] - a[0]; | ||||
|     let y = b[1] - a[1]; | ||||
|     normalize(Angle::from_radians(y.atan2(x))) | ||||
| } | ||||
|  | ||||
| /// Normalize the angle | ||||
| pub fn normalize(angle: Angle) -> Angle { | ||||
| pub(crate) fn normalize(angle: Angle) -> Angle { | ||||
|     let deg = angle.to_degrees(); | ||||
|     let result = ((deg % 360.0) + 360.0) % 360.0; | ||||
|     Angle::from_degrees(if result > 180.0 { result - 360.0 } else { result }) | ||||
| @ -55,7 +70,7 @@ pub fn normalize(angle: Angle) -> Angle { | ||||
| ///     Angle::from_radians(PI / 8.0) | ||||
| /// ); | ||||
| /// ``` | ||||
| pub fn delta(from_angle: Angle, to_angle: Angle) -> Angle { | ||||
| pub(crate) fn delta(from_angle: Angle, to_angle: Angle) -> Angle { | ||||
|     let norm_from_angle = normalize_rad(from_angle.to_radians()); | ||||
|     let norm_to_angle = normalize_rad(to_angle.to_radians()); | ||||
|     let provisional = norm_to_angle - norm_from_angle; | ||||
| @ -72,7 +87,7 @@ pub fn delta(from_angle: Angle, to_angle: Angle) -> Angle { | ||||
|     Angle::default() | ||||
| } | ||||
|  | ||||
| pub fn normalize_rad(angle: f64) -> f64 { | ||||
| pub(crate) fn normalize_rad(angle: f64) -> f64 { | ||||
|     let draft = angle % (2.0 * PI); | ||||
|     if draft < 0.0 { | ||||
|         draft + 2.0 * PI | ||||
| @ -106,7 +121,7 @@ fn intersect(p1: Coords2d, p2: Coords2d, p3: Coords2d, p4: Coords2d) -> Coords2d | ||||
|     [x, y] | ||||
| } | ||||
|  | ||||
| pub fn intersection_with_parallel_line( | ||||
| pub(crate) fn intersection_with_parallel_line( | ||||
|     line1: &[Coords2d; 2], | ||||
|     line1_offset: f64, | ||||
|     line2_angle: f64, | ||||
| @ -128,7 +143,7 @@ fn offset_line(offset: f64, p1: Coords2d, p2: Coords2d) -> [Coords2d; 2] { | ||||
|     [[p1[0] + x_offset, p1[1]], [p2[0] + x_offset, p2[1]]] | ||||
| } | ||||
|  | ||||
| pub fn get_y_component(angle: Angle, x: f64) -> Coords2d { | ||||
| pub(crate) fn get_y_component(angle: Angle, x: f64) -> Coords2d { | ||||
|     let normalised_angle = ((angle.to_degrees() % 360.0) + 360.0) % 360.0; // between 0 and 360 | ||||
|     let y = x * f64::tan(normalised_angle.to_radians()); | ||||
|     let sign = if normalised_angle > 90.0 && normalised_angle <= 270.0 { | ||||
| @ -139,7 +154,7 @@ pub fn get_y_component(angle: Angle, x: f64) -> Coords2d { | ||||
|     [x * sign, y * sign] | ||||
| } | ||||
|  | ||||
| pub fn get_x_component(angle: Angle, y: f64) -> Coords2d { | ||||
| pub(crate) fn get_x_component(angle: Angle, y: f64) -> Coords2d { | ||||
|     let normalised_angle = ((angle.to_degrees() % 360.0) + 360.0) % 360.0; // between 0 and 360 | ||||
|     let x = y / f64::tan(normalised_angle.to_radians()); | ||||
|     let sign = if normalised_angle > 180.0 && normalised_angle <= 360.0 { | ||||
| @ -150,7 +165,12 @@ pub fn get_x_component(angle: Angle, y: f64) -> Coords2d { | ||||
|     [x * sign, y * sign] | ||||
| } | ||||
|  | ||||
| pub fn arc_center_and_end(from: Coords2d, start_angle: Angle, end_angle: Angle, radius: f64) -> (Coords2d, Coords2d) { | ||||
| pub(crate) fn arc_center_and_end( | ||||
|     from: Coords2d, | ||||
|     start_angle: Angle, | ||||
|     end_angle: Angle, | ||||
|     radius: f64, | ||||
| ) -> (Coords2d, Coords2d) { | ||||
|     let start_angle = start_angle.to_radians(); | ||||
|     let end_angle = end_angle.to_radians(); | ||||
|  | ||||
| @ -167,56 +187,9 @@ pub fn arc_center_and_end(from: Coords2d, start_angle: Angle, end_angle: Angle, | ||||
|     (center, end) | ||||
| } | ||||
|  | ||||
| pub fn arc_angles( | ||||
|     from: Coords2d, | ||||
|     to: Coords2d, | ||||
|     center: Coords2d, | ||||
|     radius: f64, | ||||
|     source_range: SourceRange, | ||||
| ) -> Result<(Angle, Angle), KclError> { | ||||
|     // First make sure that the points are on the circumference of the circle. | ||||
|     // If not, we'll return an error. | ||||
|     if !is_on_circumference(center, from, radius) { | ||||
|         return Err(KclError::Semantic(KclErrorDetails { | ||||
|             message: format!( | ||||
|                 "Point {:?} is not on the circumference of the circle with center {:?} and radius {}.", | ||||
|                 from, center, radius | ||||
|             ), | ||||
|             source_ranges: vec![source_range], | ||||
|         })); | ||||
|     } | ||||
|  | ||||
|     if !is_on_circumference(center, to, radius) { | ||||
|         return Err(KclError::Semantic(KclErrorDetails { | ||||
|             message: format!( | ||||
|                 "Point {:?} is not on the circumference of the circle with center {:?} and radius {}.", | ||||
|                 to, center, radius | ||||
|             ), | ||||
|             source_ranges: vec![source_range], | ||||
|         })); | ||||
|     } | ||||
|  | ||||
|     let start_angle = (from[1] - center[1]).atan2(from[0] - center[0]); | ||||
|     let end_angle = (to[1] - center[1]).atan2(to[0] - center[0]); | ||||
|  | ||||
|     Ok((Angle::from_radians(start_angle), Angle::from_radians(end_angle))) | ||||
| } | ||||
|  | ||||
| fn is_on_circumference(center: Coords2d, point: Coords2d, radius: f64) -> bool { | ||||
|     let dx = point[0] - center[0]; | ||||
|     let dy = point[1] - center[1]; | ||||
|  | ||||
|     let distance_squared = dx.powi(2) + dy.powi(2); | ||||
|  | ||||
|     // We'll check if the distance squared is approximately equal to radius squared. | ||||
|     // Due to potential floating point inaccuracies, we'll check if the difference | ||||
|     // is very small (e.g., 1e-9) rather than checking for strict equality. | ||||
|     (distance_squared - radius.powi(2)).abs() < 1e-9 | ||||
| } | ||||
|  | ||||
| // Calculate the center of 3 points using an algebraic method | ||||
| // Handles if 3 points lie on the same line (collinear) by returning the average of the points (could return None instead..) | ||||
| pub fn calculate_circle_center(p1: [f64; 2], p2: [f64; 2], p3: [f64; 2]) -> [f64; 2] { | ||||
| pub(crate) fn calculate_circle_center(p1: [f64; 2], p2: [f64; 2], p3: [f64; 2]) -> [f64; 2] { | ||||
|     let (x1, y1) = (p1[0], p1[1]); | ||||
|     let (x2, y2) = (p2[0], p2[1]); | ||||
|     let (x3, y3) = (p3[0], p3[1]); | ||||
| @ -268,7 +241,6 @@ mod tests { | ||||
|     use std::f64::consts::TAU; | ||||
|  | ||||
|     use super::{calculate_circle_center, get_x_component, get_y_component, Angle}; | ||||
|     use crate::SourceRange; | ||||
|  | ||||
|     static EACH_QUAD: [(i32, [i32; 2]); 12] = [ | ||||
|         (-315, [1, 1]), | ||||
| @ -366,34 +338,6 @@ mod tests { | ||||
|         assert_eq!(end[1].round(), 0.0); | ||||
|     } | ||||
|  | ||||
|     #[test] | ||||
|     fn test_arc_angles() { | ||||
|         let (angle_start, angle_end) = | ||||
|             super::arc_angles([0.0, 0.0], [-1.0, 1.0], [-1.0, 0.0], 1.0, SourceRange::default()).unwrap(); | ||||
|         assert_eq!(angle_start.to_degrees().round(), 0.0); | ||||
|         assert_eq!(angle_end.to_degrees().round(), 90.0); | ||||
|  | ||||
|         let (angle_start, angle_end) = | ||||
|             super::arc_angles([0.0, 0.0], [-2.0, 0.0], [-1.0, 0.0], 1.0, SourceRange::default()).unwrap(); | ||||
|         assert_eq!(angle_start.to_degrees().round(), 0.0); | ||||
|         assert_eq!(angle_end.to_degrees().round(), 180.0); | ||||
|  | ||||
|         let (angle_start, angle_end) = | ||||
|             super::arc_angles([0.0, 0.0], [-20.0, 0.0], [-10.0, 0.0], 10.0, SourceRange::default()).unwrap(); | ||||
|         assert_eq!(angle_start.to_degrees().round(), 0.0); | ||||
|         assert_eq!(angle_end.to_degrees().round(), 180.0); | ||||
|  | ||||
|         let result = super::arc_angles([0.0, 5.0], [5.0, 5.0], [10.0, -10.0], 10.0, SourceRange::default()); | ||||
|  | ||||
|         if let Err(err) = result { | ||||
|             assert!(err.to_string().contains("Point [0.0, 5.0] is not on the circumference of the circle with center [10.0, -10.0] and radius 10."), "found: `{}`", err); | ||||
|         } else { | ||||
|             panic!("Expected error"); | ||||
|         } | ||||
|         assert_eq!(angle_start.to_degrees().round(), 0.0); | ||||
|         assert_eq!(angle_end.to_degrees().round(), 180.0); | ||||
|     } | ||||
|  | ||||
|     #[test] | ||||
|     fn test_calculate_circle_center() { | ||||
|         const EPS: f64 = 1e-4; | ||||
| @ -464,7 +408,7 @@ mod tests { | ||||
|     } | ||||
| } | ||||
|  | ||||
| pub type Coords2d = [f64; 2]; | ||||
| pub(crate) type Coords2d = [f64; 2]; | ||||
|  | ||||
| pub fn is_points_ccw_wasm(points: &[f64]) -> i32 { | ||||
|     // CCW is positive as that the Math convention | ||||
| @ -478,7 +422,7 @@ pub fn is_points_ccw_wasm(points: &[f64]) -> i32 { | ||||
|     sum.signum() as i32 | ||||
| } | ||||
|  | ||||
| pub fn is_points_ccw(points: &[Coords2d]) -> i32 { | ||||
| pub(crate) fn is_points_ccw(points: &[Coords2d]) -> i32 { | ||||
|     let flattened_points: Vec<f64> = points.iter().flat_map(|&p| vec![p[0], p[1]]).collect(); | ||||
|     is_points_ccw_wasm(&flattened_points) | ||||
| } | ||||
| @ -587,7 +531,6 @@ pub struct TangentialArcInfoInput { | ||||
| } | ||||
|  | ||||
| /// Structure to hold the output data from calculating tangential arc information. | ||||
| #[allow(dead_code)] | ||||
| pub struct TangentialArcInfoOutput { | ||||
|     /// The center point of the arc. | ||||
|     pub center: Coords2d, | ||||
| @ -851,7 +794,7 @@ mod get_tangential_arc_to_info_tests { | ||||
|     } | ||||
| } | ||||
|  | ||||
| pub fn get_tangent_point_from_previous_arc( | ||||
| pub(crate) fn get_tangent_point_from_previous_arc( | ||||
|     last_arc_center: Coords2d, | ||||
|     last_arc_ccw: bool, | ||||
|     last_arc_end: Coords2d, | ||||
|  | ||||
| @ -35,7 +35,7 @@ pub enum Node<'a> { | ||||
|     IfExpression(NodeRef<'a, types::IfExpression>), | ||||
|     ElseIf(&'a types::ElseIf), | ||||
|     LabelledExpression(NodeRef<'a, types::LabelledExpression>), | ||||
|     Ascription(NodeRef<'a, types::Ascription>), | ||||
|     AscribedExpression(NodeRef<'a, types::AscribedExpression>), | ||||
|  | ||||
|     Parameter(&'a types::Parameter), | ||||
|  | ||||
| @ -79,7 +79,7 @@ impl Node<'_> { | ||||
|             Node::ElseIf(n) => n.digest, | ||||
|             Node::KclNone(n) => n.digest, | ||||
|             Node::LabelledExpression(n) => n.digest, | ||||
|             Node::Ascription(n) => n.digest, | ||||
|             Node::AscribedExpression(n) => n.digest, | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @ -124,7 +124,7 @@ impl Node<'_> { | ||||
|             Node::ElseIf(n) => *n as *const _ as *const (), | ||||
|             Node::KclNone(n) => *n as *const _ as *const (), | ||||
|             Node::LabelledExpression(n) => *n as *const _ as *const (), | ||||
|             Node::Ascription(n) => *n as *const _ as *const (), | ||||
|             Node::AscribedExpression(n) => *n as *const _ as *const (), | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -167,7 +167,7 @@ impl TryFrom<&Node<'_>> for SourceRange { | ||||
|             Node::ObjectProperty(n) => SourceRange::from(*n), | ||||
|             Node::IfExpression(n) => SourceRange::from(*n), | ||||
|             Node::LabelledExpression(n) => SourceRange::from(*n), | ||||
|             Node::Ascription(n) => SourceRange::from(*n), | ||||
|             Node::AscribedExpression(n) => SourceRange::from(*n), | ||||
|  | ||||
|             // This is broken too | ||||
|             Node::ElseIf(n) => SourceRange::new(n.cond.start(), n.cond.end(), n.cond.module_id()), | ||||
| @ -296,7 +296,7 @@ impl_from_ref!(Node, Parameter); | ||||
| impl_from!(Node, IfExpression); | ||||
| impl_from!(Node, ElseIf); | ||||
| impl_from!(Node, LabelledExpression); | ||||
| impl_from!(Node, Ascription); | ||||
| impl_from!(Node, AscribedExpression); | ||||
| impl_from!(Node, KclNone); | ||||
|  | ||||
| #[cfg(test)] | ||||
|  | ||||
| @ -131,7 +131,7 @@ impl<'tree> Visitable<'tree> for Node<'tree> { | ||||
|             Node::LabelledExpression(e) => { | ||||
|                 vec![(&e.expr).into(), (&e.label).into()] | ||||
|             } | ||||
|             Node::Ascription(e) => { | ||||
|             Node::AscribedExpression(e) => { | ||||
|                 vec![(&e.expr).into()] | ||||
|             } | ||||
|             Node::Name(n) => Some((&n.name).into()) | ||||
|  | ||||
| @ -28,37 +28,5 @@ description: Artifact commands add_lots.kcl | ||||
|       "object_id": "[uuid]", | ||||
|       "hidden": true | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   } | ||||
| ] | ||||
|  | ||||
| @ -360,37 +360,5 @@ description: Artifact commands angled_line.kcl | ||||
|       "edge_id": "[uuid]", | ||||
|       "face_id": "[uuid]" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   } | ||||
| ] | ||||
|  | ||||
| @ -220,9 +220,6 @@ description: Variables in memory after executing angled_line.kcl | ||||
|             "units": { | ||||
|               "type": "Mm" | ||||
|             } | ||||
|           }, | ||||
|           "units": { | ||||
|             "type": "Mm" | ||||
|           } | ||||
|         }, | ||||
|         "start": { | ||||
|  | ||||
| @ -28,37 +28,5 @@ description: Artifact commands argument_error.kcl | ||||
|       "object_id": "[uuid]", | ||||
|       "hidden": true | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   } | ||||
| ] | ||||
|  | ||||
| @ -28,37 +28,5 @@ description: Artifact commands array_elem_pop.kcl | ||||
|       "object_id": "[uuid]", | ||||
|       "hidden": true | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   } | ||||
| ] | ||||
|  | ||||
| @ -28,37 +28,5 @@ description: Artifact commands array_elem_pop_empty_fail.kcl | ||||
|       "object_id": "[uuid]", | ||||
|       "hidden": true | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   } | ||||
| ] | ||||
|  | ||||
| @ -28,37 +28,5 @@ description: Artifact commands array_elem_pop_fail.kcl | ||||
|       "object_id": "[uuid]", | ||||
|       "hidden": true | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   } | ||||
| ] | ||||
|  | ||||
| @ -28,37 +28,5 @@ description: Artifact commands array_elem_push.kcl | ||||
|       "object_id": "[uuid]", | ||||
|       "hidden": true | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   } | ||||
| ] | ||||
|  | ||||
| @ -28,37 +28,5 @@ description: Artifact commands array_elem_push_fail.kcl | ||||
|       "object_id": "[uuid]", | ||||
|       "hidden": true | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   } | ||||
| ] | ||||
|  | ||||
| @ -28,37 +28,5 @@ description: Artifact commands array_index_oob.kcl | ||||
|       "object_id": "[uuid]", | ||||
|       "hidden": true | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   } | ||||
| ] | ||||
|  | ||||
| @ -28,37 +28,5 @@ description: Artifact commands array_range_expr.kcl | ||||
|       "object_id": "[uuid]", | ||||
|       "hidden": true | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   } | ||||
| ] | ||||
|  | ||||
| @ -28,37 +28,5 @@ description: Artifact commands array_range_negative_expr.kcl | ||||
|       "object_id": "[uuid]", | ||||
|       "hidden": true | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   } | ||||
| ] | ||||
|  | ||||
| @ -520,37 +520,5 @@ description: Artifact commands artifact_graph_example_code1.kcl | ||||
|       "edge_id": "[uuid]", | ||||
|       "face_id": "[uuid]" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   } | ||||
| ] | ||||
|  | ||||
| @ -199,9 +199,6 @@ description: Variables in memory after executing artifact_graph_example_code1.kc | ||||
|             "units": { | ||||
|               "type": "Mm" | ||||
|             } | ||||
|           }, | ||||
|           "units": { | ||||
|             "type": "Mm" | ||||
|           } | ||||
|         }, | ||||
|         "start": { | ||||
| @ -599,9 +596,6 @@ description: Variables in memory after executing artifact_graph_example_code1.kc | ||||
|                   "units": { | ||||
|                     "type": "Mm" | ||||
|                   } | ||||
|                 }, | ||||
|                 "units": { | ||||
|                   "type": "Mm" | ||||
|                 } | ||||
|               }, | ||||
|               "start": { | ||||
| @ -861,9 +855,6 @@ description: Variables in memory after executing artifact_graph_example_code1.kc | ||||
|           "units": { | ||||
|             "type": "Mm" | ||||
|           } | ||||
|         }, | ||||
|         "units": { | ||||
|           "type": "Mm" | ||||
|         } | ||||
|       }, | ||||
|       "start": { | ||||
| @ -1207,9 +1198,6 @@ description: Variables in memory after executing artifact_graph_example_code1.kc | ||||
|                 "units": { | ||||
|                   "type": "Mm" | ||||
|                 } | ||||
|               }, | ||||
|               "units": { | ||||
|                 "type": "Mm" | ||||
|               } | ||||
|             }, | ||||
|             "start": { | ||||
|  | ||||
| @ -291,37 +291,5 @@ description: Artifact commands artifact_graph_example_code_no_3d.kcl | ||||
|         "angle_snap_increment": null | ||||
|       } | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   } | ||||
| ] | ||||
|  | ||||
| @ -174,9 +174,6 @@ description: Variables in memory after executing artifact_graph_example_code_no_ | ||||
|           "units": { | ||||
|             "type": "Mm" | ||||
|           } | ||||
|         }, | ||||
|         "units": { | ||||
|           "type": "Mm" | ||||
|         } | ||||
|       }, | ||||
|       "start": { | ||||
| @ -328,9 +325,6 @@ description: Variables in memory after executing artifact_graph_example_code_no_ | ||||
|           "units": { | ||||
|             "type": "Mm" | ||||
|           } | ||||
|         }, | ||||
|         "units": { | ||||
|           "type": "Mm" | ||||
|         } | ||||
|       }, | ||||
|       "start": { | ||||
|  | ||||
| @ -214,37 +214,5 @@ description: Artifact commands artifact_graph_example_code_offset_planes.kcl | ||||
|       "object_id": "[uuid]", | ||||
|       "hidden": true | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   } | ||||
| ] | ||||
|  | ||||
| @ -40,9 +40,6 @@ description: Variables in memory after executing artifact_graph_example_code_off | ||||
|         "units": { | ||||
|           "type": "Mm" | ||||
|         } | ||||
|       }, | ||||
|       "units": { | ||||
|         "type": "Mm" | ||||
|       } | ||||
|     } | ||||
|   }, | ||||
| @ -83,9 +80,6 @@ description: Variables in memory after executing artifact_graph_example_code_off | ||||
|         "units": { | ||||
|           "type": "Mm" | ||||
|         } | ||||
|       }, | ||||
|       "units": { | ||||
|         "type": "Mm" | ||||
|       } | ||||
|     } | ||||
|   }, | ||||
| @ -126,9 +120,6 @@ description: Variables in memory after executing artifact_graph_example_code_off | ||||
|         "units": { | ||||
|           "type": "Mm" | ||||
|         } | ||||
|       }, | ||||
|       "units": { | ||||
|         "type": "Mm" | ||||
|       } | ||||
|     } | ||||
|   }, | ||||
| @ -194,9 +185,6 @@ description: Variables in memory after executing artifact_graph_example_code_off | ||||
|           "units": { | ||||
|             "type": "Mm" | ||||
|           } | ||||
|         }, | ||||
|         "units": { | ||||
|           "type": "Mm" | ||||
|         } | ||||
|       }, | ||||
|       "start": { | ||||
|  | ||||
| @ -881,37 +881,5 @@ description: Artifact commands artifact_graph_sketch_on_face_etc.kcl | ||||
|       "edge_id": "[uuid]", | ||||
|       "face_id": "[uuid]" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   } | ||||
| ] | ||||
|  | ||||
| @ -161,9 +161,6 @@ description: Variables in memory after executing artifact_graph_sketch_on_face_e | ||||
|             "units": { | ||||
|               "type": "Mm" | ||||
|             } | ||||
|           }, | ||||
|           "units": { | ||||
|             "type": "Mm" | ||||
|           } | ||||
|         }, | ||||
|         "start": { | ||||
| @ -499,9 +496,6 @@ description: Variables in memory after executing artifact_graph_sketch_on_face_e | ||||
|                   "units": { | ||||
|                     "type": "Mm" | ||||
|                   } | ||||
|                 }, | ||||
|                 "units": { | ||||
|                   "type": "Mm" | ||||
|                 } | ||||
|               }, | ||||
|               "start": { | ||||
| @ -1021,9 +1015,6 @@ description: Variables in memory after executing artifact_graph_sketch_on_face_e | ||||
|                         "units": { | ||||
|                           "type": "Mm" | ||||
|                         } | ||||
|                       }, | ||||
|                       "units": { | ||||
|                         "type": "Mm" | ||||
|                       } | ||||
|                     }, | ||||
|                     "start": { | ||||
| @ -1721,9 +1712,6 @@ description: Variables in memory after executing artifact_graph_sketch_on_face_e | ||||
|                               "units": { | ||||
|                                 "type": "Mm" | ||||
|                               } | ||||
|                             }, | ||||
|                             "units": { | ||||
|                               "type": "Mm" | ||||
|                             } | ||||
|                           }, | ||||
|                           "start": { | ||||
| @ -2010,9 +1998,6 @@ description: Variables in memory after executing artifact_graph_sketch_on_face_e | ||||
|           "units": { | ||||
|             "type": "Mm" | ||||
|           } | ||||
|         }, | ||||
|         "units": { | ||||
|           "type": "Mm" | ||||
|         } | ||||
|       }, | ||||
|       "start": { | ||||
| @ -2314,9 +2299,6 @@ description: Variables in memory after executing artifact_graph_sketch_on_face_e | ||||
|                 "units": { | ||||
|                   "type": "Mm" | ||||
|                 } | ||||
|               }, | ||||
|               "units": { | ||||
|                 "type": "Mm" | ||||
|               } | ||||
|             }, | ||||
|             "start": { | ||||
| @ -2796,9 +2778,6 @@ description: Variables in memory after executing artifact_graph_sketch_on_face_e | ||||
|                       "units": { | ||||
|                         "type": "Mm" | ||||
|                       } | ||||
|                     }, | ||||
|                     "units": { | ||||
|                       "type": "Mm" | ||||
|                     } | ||||
|                   }, | ||||
|                   "start": { | ||||
| @ -3462,9 +3441,6 @@ description: Variables in memory after executing artifact_graph_sketch_on_face_e | ||||
|                             "units": { | ||||
|                               "type": "Mm" | ||||
|                             } | ||||
|                           }, | ||||
|                           "units": { | ||||
|                             "type": "Mm" | ||||
|                           } | ||||
|                         }, | ||||
|                         "start": { | ||||
|  | ||||
| @ -29,54 +29,6 @@ description: Artifact commands assembly_mixed_units_cubes.kcl | ||||
|       "hidden": true | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "in" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "in" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
| @ -132,8 +84,8 @@ description: Artifact commands assembly_mixed_units_cubes.kcl | ||||
|       "type": "move_path_pen", | ||||
|       "path": "[uuid]", | ||||
|       "to": { | ||||
|         "x": -10.0, | ||||
|         "y": -10.0, | ||||
|         "x": -254.0, | ||||
|         "y": -254.0, | ||||
|         "z": 0.0 | ||||
|       } | ||||
|     } | ||||
| @ -154,7 +106,7 @@ description: Artifact commands assembly_mixed_units_cubes.kcl | ||||
|       "segment": { | ||||
|         "type": "line", | ||||
|         "end": { | ||||
|           "x": 5.0, | ||||
|           "x": 127.0, | ||||
|           "y": 0.0, | ||||
|           "z": 0.0 | ||||
|         }, | ||||
| @ -172,7 +124,7 @@ description: Artifact commands assembly_mixed_units_cubes.kcl | ||||
|         "type": "line", | ||||
|         "end": { | ||||
|           "x": 0.0, | ||||
|           "y": -5.0, | ||||
|           "y": -127.0, | ||||
|           "z": 0.0 | ||||
|         }, | ||||
|         "relative": true | ||||
| @ -188,7 +140,7 @@ description: Artifact commands assembly_mixed_units_cubes.kcl | ||||
|       "segment": { | ||||
|         "type": "line", | ||||
|         "end": { | ||||
|           "x": -5.0, | ||||
|           "x": -127.0, | ||||
|           "y": 0.0, | ||||
|           "z": 0.0 | ||||
|         }, | ||||
| @ -205,8 +157,8 @@ description: Artifact commands assembly_mixed_units_cubes.kcl | ||||
|       "segment": { | ||||
|         "type": "line", | ||||
|         "end": { | ||||
|           "x": -10.0, | ||||
|           "y": -10.0, | ||||
|           "x": -254.0, | ||||
|           "y": -254.0, | ||||
|           "z": 0.0 | ||||
|         }, | ||||
|         "relative": false | ||||
| @ -243,7 +195,7 @@ description: Artifact commands assembly_mixed_units_cubes.kcl | ||||
|     "command": { | ||||
|       "type": "extrude", | ||||
|       "target": "[uuid]", | ||||
|       "distance": 5.0, | ||||
|       "distance": 127.0, | ||||
|       "faces": null, | ||||
|       "opposite": "None" | ||||
|     } | ||||
| @ -352,14 +304,6 @@ description: Artifact commands assembly_mixed_units_cubes.kcl | ||||
|       "face_id": "[uuid]" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|  | ||||
| @ -29,54 +29,6 @@ description: Artifact commands assembly_non_default_units.kcl | ||||
|       "hidden": true | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "in" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "in" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
| @ -132,7 +84,7 @@ description: Artifact commands assembly_non_default_units.kcl | ||||
|       "type": "move_path_pen", | ||||
|       "path": "[uuid]", | ||||
|       "to": { | ||||
|         "x": 1.0, | ||||
|         "x": 25.4, | ||||
|         "y": 0.0, | ||||
|         "z": 0.0 | ||||
|       } | ||||
| @ -157,7 +109,7 @@ description: Artifact commands assembly_non_default_units.kcl | ||||
|           "x": 0.0, | ||||
|           "y": 0.0 | ||||
|         }, | ||||
|         "radius": 1.0, | ||||
|         "radius": 25.4, | ||||
|         "start": { | ||||
|           "unit": "degrees", | ||||
|           "value": 0.0 | ||||
| @ -178,14 +130,6 @@ description: Artifact commands assembly_non_default_units.kcl | ||||
|       "path_id": "[uuid]" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "in" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
| @ -241,8 +185,8 @@ description: Artifact commands assembly_non_default_units.kcl | ||||
|       "type": "move_path_pen", | ||||
|       "path": "[uuid]", | ||||
|       "to": { | ||||
|         "x": 1.0, | ||||
|         "y": 2.0, | ||||
|         "x": 25.4, | ||||
|         "y": 50.8, | ||||
|         "z": 0.0 | ||||
|       } | ||||
|     } | ||||
| @ -264,9 +208,9 @@ description: Artifact commands assembly_non_default_units.kcl | ||||
|         "type": "arc", | ||||
|         "center": { | ||||
|           "x": 0.0, | ||||
|           "y": 2.0 | ||||
|           "y": 50.8 | ||||
|         }, | ||||
|         "radius": 1.0, | ||||
|         "radius": 25.4, | ||||
|         "start": { | ||||
|           "unit": "degrees", | ||||
|           "value": 0.0 | ||||
| @ -286,13 +230,5 @@ description: Artifact commands assembly_non_default_units.kcl | ||||
|       "type": "close_path", | ||||
|       "path_id": "[uuid]" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "in" | ||||
|     } | ||||
|   } | ||||
| ] | ||||
|  | ||||
| @ -28,37 +28,5 @@ description: Artifact commands bad_units_in_annotation.kcl | ||||
|       "object_id": "[uuid]", | ||||
|       "hidden": true | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   } | ||||
| ] | ||||
|  | ||||
| @ -320,37 +320,5 @@ description: Artifact commands basic_fillet_cube_close_opposite.kcl | ||||
|       "tolerance": 0.0000001, | ||||
|       "cut_type": "fillet" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   } | ||||
| ] | ||||
|  | ||||
| @ -192,9 +192,6 @@ description: Variables in memory after executing basic_fillet_cube_close_opposit | ||||
|             "units": { | ||||
|               "type": "Mm" | ||||
|             } | ||||
|           }, | ||||
|           "units": { | ||||
|             "type": "Mm" | ||||
|           } | ||||
|         }, | ||||
|         "start": { | ||||
|  | ||||
| @ -320,37 +320,5 @@ description: Artifact commands basic_fillet_cube_end.kcl | ||||
|       "tolerance": 0.0000001, | ||||
|       "cut_type": "fillet" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   } | ||||
| ] | ||||
|  | ||||
| @ -180,9 +180,6 @@ description: Variables in memory after executing basic_fillet_cube_end.kcl | ||||
|             "units": { | ||||
|               "type": "Mm" | ||||
|             } | ||||
|           }, | ||||
|           "units": { | ||||
|             "type": "Mm" | ||||
|           } | ||||
|         }, | ||||
|         "start": { | ||||
|  | ||||
| @ -308,37 +308,5 @@ description: Artifact commands basic_fillet_cube_next_adjacent.kcl | ||||
|       "tolerance": 0.0000001, | ||||
|       "cut_type": "fillet" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   } | ||||
| ] | ||||
|  | ||||
| @ -204,9 +204,6 @@ description: Variables in memory after executing basic_fillet_cube_next_adjacent | ||||
|             "units": { | ||||
|               "type": "Mm" | ||||
|             } | ||||
|           }, | ||||
|           "units": { | ||||
|             "type": "Mm" | ||||
|           } | ||||
|         }, | ||||
|         "start": { | ||||
|  | ||||
| @ -308,37 +308,5 @@ description: Artifact commands basic_fillet_cube_previous_adjacent.kcl | ||||
|       "tolerance": 0.0000001, | ||||
|       "cut_type": "fillet" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   } | ||||
| ] | ||||
|  | ||||
| @ -204,9 +204,6 @@ description: Variables in memory after executing basic_fillet_cube_previous_adja | ||||
|             "units": { | ||||
|               "type": "Mm" | ||||
|             } | ||||
|           }, | ||||
|           "units": { | ||||
|             "type": "Mm" | ||||
|           } | ||||
|         }, | ||||
|         "start": { | ||||
|  | ||||
| @ -310,37 +310,5 @@ description: Artifact commands basic_fillet_cube_start.kcl | ||||
|       "tolerance": 0.0000001, | ||||
|       "cut_type": "fillet" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   } | ||||
| ] | ||||
|  | ||||
| @ -180,9 +180,6 @@ description: Variables in memory after executing basic_fillet_cube_start.kcl | ||||
|             "units": { | ||||
|               "type": "Mm" | ||||
|             } | ||||
|           }, | ||||
|           "units": { | ||||
|             "type": "Mm" | ||||
|           } | ||||
|         }, | ||||
|         "start": { | ||||
|  | ||||
| @ -249,37 +249,5 @@ description: Artifact commands big_number_angle_to_match_length_x.kcl | ||||
|       "edge_id": "[uuid]", | ||||
|       "face_id": "[uuid]" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   } | ||||
| ] | ||||
|  | ||||
| @ -142,9 +142,6 @@ description: Variables in memory after executing big_number_angle_to_match_lengt | ||||
|             "units": { | ||||
|               "type": "Mm" | ||||
|             } | ||||
|           }, | ||||
|           "units": { | ||||
|             "type": "Mm" | ||||
|           } | ||||
|         }, | ||||
|         "start": { | ||||
|  | ||||
| @ -249,37 +249,5 @@ description: Artifact commands big_number_angle_to_match_length_y.kcl | ||||
|       "edge_id": "[uuid]", | ||||
|       "face_id": "[uuid]" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   } | ||||
| ] | ||||
|  | ||||
| @ -142,9 +142,6 @@ description: Variables in memory after executing big_number_angle_to_match_lengt | ||||
|             "units": { | ||||
|               "type": "Mm" | ||||
|             } | ||||
|           }, | ||||
|           "units": { | ||||
|             "type": "Mm" | ||||
|           } | ||||
|         }, | ||||
|         "start": { | ||||
|  | ||||
| @ -28,37 +28,5 @@ description: Artifact commands boolean_logical_and.kcl | ||||
|       "object_id": "[uuid]", | ||||
|       "hidden": true | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   } | ||||
| ] | ||||
|  | ||||
| @ -28,37 +28,5 @@ description: Artifact commands boolean_logical_multiple.kcl | ||||
|       "object_id": "[uuid]", | ||||
|       "hidden": true | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   } | ||||
| ] | ||||
|  | ||||
| @ -28,37 +28,5 @@ description: Artifact commands boolean_logical_or.kcl | ||||
|       "object_id": "[uuid]", | ||||
|       "hidden": true | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   } | ||||
| ] | ||||
|  | ||||
| @ -200,37 +200,5 @@ description: Artifact commands circle_three_point.kcl | ||||
|       "edge_id": "[uuid]", | ||||
|       "face_id": "[uuid]" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   } | ||||
| ] | ||||
|  | ||||
| @ -90,9 +90,6 @@ description: Variables in memory after executing circle_three_point.kcl | ||||
|             "units": { | ||||
|               "type": "Mm" | ||||
|             } | ||||
|           }, | ||||
|           "units": { | ||||
|             "type": "Mm" | ||||
|           } | ||||
|         }, | ||||
|         "start": { | ||||
|  | ||||
| @ -618,37 +618,5 @@ description: Artifact commands circular_pattern3d_a_pattern.kcl | ||||
|       "arc_degrees": 360.0, | ||||
|       "rotate_duplicates": false | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   } | ||||
| ] | ||||
|  | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @ -28,37 +28,5 @@ description: Artifact commands comparisons.kcl | ||||
|       "object_id": "[uuid]", | ||||
|       "hidden": true | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   } | ||||
| ] | ||||
|  | ||||
| @ -28,37 +28,5 @@ description: Artifact commands comparisons_multiple.kcl | ||||
|       "object_id": "[uuid]", | ||||
|       "hidden": true | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   } | ||||
| ] | ||||
|  | ||||
| @ -28,37 +28,5 @@ description: Artifact commands computed_var.kcl | ||||
|       "object_id": "[uuid]", | ||||
|       "hidden": true | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   } | ||||
| ] | ||||
|  | ||||
| @ -1655,37 +1655,5 @@ description: Artifact commands crazy_multi_profile.kcl | ||||
|       "edge_id": "[uuid]", | ||||
|       "face_id": "[uuid]" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   } | ||||
| ] | ||||
|  | ||||
| @ -173,9 +173,6 @@ description: Variables in memory after executing crazy_multi_profile.kcl | ||||
|             "units": { | ||||
|               "type": "Mm" | ||||
|             } | ||||
|           }, | ||||
|           "units": { | ||||
|             "type": "Mm" | ||||
|           } | ||||
|         }, | ||||
|         "start": { | ||||
| @ -527,9 +524,6 @@ description: Variables in memory after executing crazy_multi_profile.kcl | ||||
|                   "units": { | ||||
|                     "type": "Mm" | ||||
|                   } | ||||
|                 }, | ||||
|                 "units": { | ||||
|                   "type": "Mm" | ||||
|                 } | ||||
|               }, | ||||
|               "start": { | ||||
| @ -793,9 +787,6 @@ description: Variables in memory after executing crazy_multi_profile.kcl | ||||
|             "units": { | ||||
|               "type": "Mm" | ||||
|             } | ||||
|           }, | ||||
|           "units": { | ||||
|             "type": "Mm" | ||||
|           } | ||||
|         }, | ||||
|         "start": { | ||||
| @ -967,9 +958,6 @@ description: Variables in memory after executing crazy_multi_profile.kcl | ||||
|           "units": { | ||||
|             "type": "Mm" | ||||
|           } | ||||
|         }, | ||||
|         "units": { | ||||
|           "type": "Mm" | ||||
|         } | ||||
|       }, | ||||
|       "start": { | ||||
| @ -1249,9 +1237,6 @@ description: Variables in memory after executing crazy_multi_profile.kcl | ||||
|                 "units": { | ||||
|                   "type": "Mm" | ||||
|                 } | ||||
|               }, | ||||
|               "units": { | ||||
|                 "type": "Mm" | ||||
|               } | ||||
|             }, | ||||
|             "start": { | ||||
| @ -1629,9 +1614,6 @@ description: Variables in memory after executing crazy_multi_profile.kcl | ||||
|                 "units": { | ||||
|                   "type": "Mm" | ||||
|                 } | ||||
|               }, | ||||
|               "units": { | ||||
|                 "type": "Mm" | ||||
|               } | ||||
|             }, | ||||
|             "start": { | ||||
| @ -1990,9 +1972,6 @@ description: Variables in memory after executing crazy_multi_profile.kcl | ||||
|                 "units": { | ||||
|                   "type": "Mm" | ||||
|                 } | ||||
|               }, | ||||
|               "units": { | ||||
|                 "type": "Mm" | ||||
|               } | ||||
|             }, | ||||
|             "start": { | ||||
| @ -2294,9 +2273,6 @@ description: Variables in memory after executing crazy_multi_profile.kcl | ||||
|                 "units": { | ||||
|                   "type": "Mm" | ||||
|                 } | ||||
|               }, | ||||
|               "units": { | ||||
|                 "type": "Mm" | ||||
|               } | ||||
|             }, | ||||
|             "start": { | ||||
| @ -2649,9 +2625,6 @@ description: Variables in memory after executing crazy_multi_profile.kcl | ||||
|                 "units": { | ||||
|                   "type": "Mm" | ||||
|                 } | ||||
|               }, | ||||
|               "units": { | ||||
|                 "type": "Mm" | ||||
|               } | ||||
|             }, | ||||
|             "start": { | ||||
| @ -2805,9 +2778,6 @@ description: Variables in memory after executing crazy_multi_profile.kcl | ||||
|           "units": { | ||||
|             "type": "Mm" | ||||
|           } | ||||
|         }, | ||||
|         "units": { | ||||
|           "type": "Mm" | ||||
|         } | ||||
|       }, | ||||
|       "start": { | ||||
| @ -2954,9 +2924,6 @@ description: Variables in memory after executing crazy_multi_profile.kcl | ||||
|           "units": { | ||||
|             "type": "Mm" | ||||
|           } | ||||
|         }, | ||||
|         "units": { | ||||
|           "type": "Mm" | ||||
|         } | ||||
|       }, | ||||
|       "start": { | ||||
| @ -3103,9 +3070,6 @@ description: Variables in memory after executing crazy_multi_profile.kcl | ||||
|           "units": { | ||||
|             "type": "Mm" | ||||
|           } | ||||
|         }, | ||||
|         "units": { | ||||
|           "type": "Mm" | ||||
|         } | ||||
|       }, | ||||
|       "start": { | ||||
| @ -3201,9 +3165,6 @@ description: Variables in memory after executing crazy_multi_profile.kcl | ||||
|           "units": { | ||||
|             "type": "Mm" | ||||
|           } | ||||
|         }, | ||||
|         "units": { | ||||
|           "type": "Mm" | ||||
|         } | ||||
|       }, | ||||
|       "start": { | ||||
| @ -3375,9 +3336,6 @@ description: Variables in memory after executing crazy_multi_profile.kcl | ||||
|           "units": { | ||||
|             "type": "Mm" | ||||
|           } | ||||
|         }, | ||||
|         "units": { | ||||
|           "type": "Mm" | ||||
|         } | ||||
|       }, | ||||
|       "start": { | ||||
| @ -3706,9 +3664,6 @@ description: Variables in memory after executing crazy_multi_profile.kcl | ||||
|                   "units": { | ||||
|                     "type": "Mm" | ||||
|                   } | ||||
|                 }, | ||||
|                 "units": { | ||||
|                   "type": "Mm" | ||||
|                 } | ||||
|               }, | ||||
|               "start": { | ||||
| @ -3934,9 +3889,6 @@ description: Variables in memory after executing crazy_multi_profile.kcl | ||||
|             "units": { | ||||
|               "type": "Mm" | ||||
|             } | ||||
|           }, | ||||
|           "units": { | ||||
|             "type": "Mm" | ||||
|           } | ||||
|         }, | ||||
|         "start": { | ||||
| @ -4018,9 +3970,6 @@ description: Variables in memory after executing crazy_multi_profile.kcl | ||||
|         "units": { | ||||
|           "type": "Mm" | ||||
|         } | ||||
|       }, | ||||
|       "units": { | ||||
|         "type": "Mm" | ||||
|       } | ||||
|     } | ||||
|   }, | ||||
| @ -4222,9 +4171,6 @@ description: Variables in memory after executing crazy_multi_profile.kcl | ||||
|               "units": { | ||||
|                 "type": "Mm" | ||||
|               } | ||||
|             }, | ||||
|             "units": { | ||||
|               "type": "Mm" | ||||
|             } | ||||
|           }, | ||||
|           "start": { | ||||
| @ -4310,9 +4256,6 @@ description: Variables in memory after executing crazy_multi_profile.kcl | ||||
|         "units": { | ||||
|           "type": "Mm" | ||||
|         } | ||||
|       }, | ||||
|       "units": { | ||||
|         "type": "Mm" | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
| @ -303,37 +303,5 @@ description: Artifact commands cube.kcl | ||||
|       "edge_id": "[uuid]", | ||||
|       "face_id": "[uuid]" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   } | ||||
| ] | ||||
|  | ||||
| @ -178,9 +178,6 @@ description: Variables in memory after executing cube.kcl | ||||
|             "units": { | ||||
|               "type": "Mm" | ||||
|             } | ||||
|           }, | ||||
|           "units": { | ||||
|             "type": "Mm" | ||||
|           } | ||||
|         }, | ||||
|         "start": { | ||||
|  | ||||
| @ -223,37 +223,5 @@ description: Artifact commands cube_with_error.kcl | ||||
|       "object_id": "[uuid]", | ||||
|       "edge_id": "[uuid]" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   } | ||||
| ] | ||||
|  | ||||
| @ -28,37 +28,5 @@ description: Artifact commands double_map_fn.kcl | ||||
|       "object_id": "[uuid]", | ||||
|       "hidden": true | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   } | ||||
| ] | ||||
|  | ||||
| @ -1830,37 +1830,5 @@ description: Artifact commands fillet-and-shell.kcl | ||||
|       "shell_thickness": 1.0, | ||||
|       "hollow": false | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   } | ||||
| ] | ||||
|  | ||||
| @ -217,9 +217,6 @@ description: Variables in memory after executing fillet-and-shell.kcl | ||||
|             "units": { | ||||
|               "type": "Mm" | ||||
|             } | ||||
|           }, | ||||
|           "units": { | ||||
|             "type": "Mm" | ||||
|           } | ||||
|         }, | ||||
|         "start": { | ||||
| @ -618,9 +615,6 @@ description: Variables in memory after executing fillet-and-shell.kcl | ||||
|           "units": { | ||||
|             "type": "Mm" | ||||
|           } | ||||
|         }, | ||||
|         "units": { | ||||
|           "type": "Mm" | ||||
|         } | ||||
|       }, | ||||
|       "start": { | ||||
|  | ||||
| @ -29,14 +29,6 @@ description: Artifact commands flush_batch_on_end.kcl | ||||
|       "hidden": true | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "in" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
| @ -92,7 +84,7 @@ description: Artifact commands flush_batch_on_end.kcl | ||||
|       "type": "move_path_pen", | ||||
|       "path": "[uuid]", | ||||
|       "to": { | ||||
|         "x": 0.2734375, | ||||
|         "x": 6.9453125, | ||||
|         "y": 0.0, | ||||
|         "z": 0.0 | ||||
|       } | ||||
| @ -117,7 +109,7 @@ description: Artifact commands flush_batch_on_end.kcl | ||||
|           "x": 0.0, | ||||
|           "y": 0.0 | ||||
|         }, | ||||
|         "radius": 0.2734375, | ||||
|         "radius": 6.9453125, | ||||
|         "start": { | ||||
|           "unit": "degrees", | ||||
|           "value": 0.0 | ||||
| @ -168,7 +160,7 @@ description: Artifact commands flush_batch_on_end.kcl | ||||
|       "type": "move_path_pen", | ||||
|       "path": "[uuid]", | ||||
|       "to": { | ||||
|         "x": 0.182, | ||||
|         "x": 4.6228, | ||||
|         "y": 0.0, | ||||
|         "z": 0.0 | ||||
|       } | ||||
| @ -193,7 +185,7 @@ description: Artifact commands flush_batch_on_end.kcl | ||||
|           "x": 0.0, | ||||
|           "y": 0.0 | ||||
|         }, | ||||
|         "radius": 0.182, | ||||
|         "radius": 4.6228, | ||||
|         "start": { | ||||
|           "unit": "degrees", | ||||
|           "value": 0.0 | ||||
| @ -254,7 +246,7 @@ description: Artifact commands flush_batch_on_end.kcl | ||||
|     "command": { | ||||
|       "type": "extrude", | ||||
|       "target": "[uuid]", | ||||
|       "distance": 1.5, | ||||
|       "distance": 38.099999999999994, | ||||
|       "faces": null, | ||||
|       "opposite": "None" | ||||
|     } | ||||
| @ -322,37 +314,5 @@ description: Artifact commands flush_batch_on_end.kcl | ||||
|       "edge_id": "[uuid]", | ||||
|       "face_id": "[uuid]" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   } | ||||
| ] | ||||
|  | ||||
| @ -100,9 +100,6 @@ description: Variables in memory after executing flush_batch_on_end.kcl | ||||
|           "units": { | ||||
|             "type": "Mm" | ||||
|           } | ||||
|         }, | ||||
|         "units": { | ||||
|           "type": "Inches" | ||||
|         } | ||||
|       }, | ||||
|       "start": { | ||||
| @ -236,9 +233,6 @@ description: Variables in memory after executing flush_batch_on_end.kcl | ||||
|           "units": { | ||||
|             "type": "Mm" | ||||
|           } | ||||
|         }, | ||||
|         "units": { | ||||
|           "type": "Inches" | ||||
|         } | ||||
|       }, | ||||
|       "start": { | ||||
| @ -365,9 +359,6 @@ description: Variables in memory after executing flush_batch_on_end.kcl | ||||
|             "units": { | ||||
|               "type": "Mm" | ||||
|             } | ||||
|           }, | ||||
|           "units": { | ||||
|             "type": "Inches" | ||||
|           } | ||||
|         }, | ||||
|         "start": { | ||||
| @ -482,9 +473,6 @@ description: Variables in memory after executing flush_batch_on_end.kcl | ||||
|           "units": { | ||||
|             "type": "Mm" | ||||
|           } | ||||
|         }, | ||||
|         "units": { | ||||
|           "type": "Inches" | ||||
|         } | ||||
|       }, | ||||
|       "start": { | ||||
| @ -555,9 +543,6 @@ description: Variables in memory after executing flush_batch_on_end.kcl | ||||
|         "units": { | ||||
|           "type": "Mm" | ||||
|         } | ||||
|       }, | ||||
|       "units": { | ||||
|         "type": "Inches" | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
| @ -286,37 +286,5 @@ description: Artifact commands function_sketch.kcl | ||||
|       "edge_id": "[uuid]", | ||||
|       "face_id": "[uuid]" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   } | ||||
| ] | ||||
|  | ||||
| @ -159,9 +159,6 @@ description: Variables in memory after executing function_sketch.kcl | ||||
|             "units": { | ||||
|               "type": "Mm" | ||||
|             } | ||||
|           }, | ||||
|           "units": { | ||||
|             "type": "Mm" | ||||
|           } | ||||
|         }, | ||||
|         "start": { | ||||
|  | ||||
| @ -286,37 +286,5 @@ description: Artifact commands function_sketch_with_position.kcl | ||||
|       "edge_id": "[uuid]", | ||||
|       "face_id": "[uuid]" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   } | ||||
| ] | ||||
|  | ||||
| @ -159,9 +159,6 @@ description: Variables in memory after executing function_sketch_with_position.k | ||||
|             "units": { | ||||
|               "type": "Mm" | ||||
|             } | ||||
|           }, | ||||
|           "units": { | ||||
|             "type": "Mm" | ||||
|           } | ||||
|         }, | ||||
|         "start": { | ||||
|  | ||||
| @ -215,37 +215,5 @@ description: Artifact commands helix_ccw.kcl | ||||
|       "is_clockwise": false, | ||||
|       "length": 10.0 | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   } | ||||
| ] | ||||
|  | ||||
| @ -129,37 +129,5 @@ description: Artifact commands helix_simple.kcl | ||||
|       "is_clockwise": false, | ||||
|       "edge_id": "[uuid]" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "cmdId": "[uuid]", | ||||
|     "range": [], | ||||
|     "command": { | ||||
|       "type": "set_scene_units", | ||||
|       "unit": "mm" | ||||
|     } | ||||
|   } | ||||
| ] | ||||
|  | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user