KCL: Getter for axes of planes (#7662)
## Goal Currently, there's no way in KCL to get fields of a plane, e.g. the underlying X axis, Y axis or origin. This would be useful for geometry calculations in KCL. It would help KCL users write transformations between planes for rotating geometry. For example, this enables ```kcl export fn crossProduct(@vectors) { a = vectors[0] b = vectors[1] x = a[1] * b[2] - (a[2] * b[1]) y = a[2] * b[0] - (a[0] * b[2]) z = a[0] * b[1] - (a[1] * b[0]) return [x, y, z] } export fn normalOf(@plane) { return crossProduct([plane.xAxis, plane.yAxis]) } ``` ## Implementation My goal was just to enable a simple getter for planes, like `myPlane.xAxis` and yAxis and origins. That's nearly what happened, except I discovered that there's two ways to represent a plane: either `KclValue::Plane` or `KclValue::Object` with the right fields. No matter which format your plane is represented as, it should behave consistently when you get its properties. Those properties should be returned as `[number; 3]` because that is how KCL represents points. Unfortunately we actually require planes-as-objects to be defined with axes like `myPlane = { xAxis = { x = 1, y = 0, z = 0 }, ...}`, but that's a mistake in my opinion. So if you do use that representation of a plane, it should still return a [number; 3]. This required some futzing around so that we let you access object fields .x and .y as [0] and [1], which is weird, but whatever, I think it's good. This PR is tested via planestuff.kcl which has a Rust unit test. Part of the hole efforts, see https://github.com/KittyCAD/modeling-app/discussions/7543
This commit is contained in:
@ -458,6 +458,31 @@ impl KclValue {
|
||||
}
|
||||
}
|
||||
|
||||
/// Put the point into a KCL point.
|
||||
pub fn array_from_point3d(p: [f64; 3], ty: NumericType, meta: Vec<Metadata>) -> Self {
|
||||
let [x, y, z] = p;
|
||||
Self::HomArray {
|
||||
value: vec![
|
||||
Self::Number {
|
||||
value: x,
|
||||
meta: meta.clone(),
|
||||
ty,
|
||||
},
|
||||
Self::Number {
|
||||
value: y,
|
||||
meta: meta.clone(),
|
||||
ty,
|
||||
},
|
||||
Self::Number {
|
||||
value: z,
|
||||
meta: meta.clone(),
|
||||
ty,
|
||||
},
|
||||
],
|
||||
ty: ty.into(),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn as_usize(&self) -> Option<usize> {
|
||||
match self {
|
||||
KclValue::Number { value, .. } => crate::try_f64_to_usize(*value),
|
||||
|
Reference in New Issue
Block a user