Skip to content

Commit 427e190

Browse files
committed
KCL: Add 'factor' arg for scale
`scale(factor = 2)` is equivalent to `scale(x = 2, y = 2, z = 2)`. Requested by Nick Boone.
1 parent 3a7f58d commit 427e190

File tree

6 files changed

+1243
-8
lines changed

6 files changed

+1243
-8
lines changed

docs/kcl-std/functions/std-transform-scale.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ scale(
1414
y?: number(_),
1515
z?: number(_),
1616
global?: bool,
17+
factor?: number(_),
1718
): [Solid; 1+] | [Sketch; 1+] | ImportedGeometry
1819
```
1920

@@ -39,6 +40,7 @@ look like the model moves and gets bigger at the same time. Say you have a squar
3940
| `y` | [`number(_)`](/docs/kcl-std/types/std-types-number) | The scale factor for the y axis. | No |
4041
| `z` | [`number(_)`](/docs/kcl-std/types/std-types-number) | The scale factor for the z axis. | No |
4142
| `global` | [`bool`](/docs/kcl-std/types/std-types-bool) | If true, the transform is applied in global space. The origin of the model will move. By default, the transform is applied in local sketch axis, therefore the origin will not move. | No |
43+
| `factor` | [`number(_)`](/docs/kcl-std/types/std-types-number) | If given, scale the solid by this much. Equivalent to setting `x`, `y` and `z` all to this number. Incompatible with `x`, `y` or `z`. | No |
4244

4345
### Returns
4446

@@ -151,4 +153,35 @@ scale(parts, z = 0.5)
151153
>
152154
</model-viewer>
153155
156+
```kcl
157+
// Make one button (i.e. just a cylinder)
158+
button1 = startSketchOn(XY)
159+
|> circle(center = [0, 0], radius = 1.53)
160+
|> extrude(length = 1)
161+
162+
// Duplicate it, but use `scale` to make it smaller.
163+
button2 = startSketchOn(XY)
164+
|> circle(center = [0, 0], radius = 1.53)
165+
|> extrude(length = 1)
166+
|> translate(x = 4)
167+
// Make it 50% smaller and gold
168+
|> scale(factor = 0.5)
169+
|> appearance(color = "#ff9922")
170+
171+
```
172+
173+
174+
<model-viewer
175+
class="kcl-example"
176+
alt="Example showing a rendered KCL program that uses the scale function"
177+
src="/kcl-test-outputs/models/serial_test_example_fn_std-transform-scale3_output.gltf"
178+
ar
179+
environment-image="/moon_1k.hdr"
180+
poster="/kcl-test-outputs/serial_test_example_fn_std-transform-scale3.png"
181+
shadow-intensity="1"
182+
camera-controls
183+
touch-action="pan-y"
184+
>
185+
</model-viewer>
186+
154187

rust/kcl-derive-docs/src/example_tests.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,7 @@ pub const TEST_NAMES: &[&str] = &[
268268
"std-transform-scale-0",
269269
"std-transform-scale-1",
270270
"std-transform-scale-2",
271+
"std-transform-scale-3",
271272
"std-units-toDegrees-0",
272273
"std-units-toRadians-0",
273274
"std-vector-add-0",

rust/kcl-lib/src/std/transform.rs

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -42,16 +42,26 @@ pub async fn scale(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K
4242
let scale_x: Option<TyF64> = args.get_kw_arg_opt("x", &RuntimeType::count(), exec_state)?;
4343
let scale_y: Option<TyF64> = args.get_kw_arg_opt("y", &RuntimeType::count(), exec_state)?;
4444
let scale_z: Option<TyF64> = args.get_kw_arg_opt("z", &RuntimeType::count(), exec_state)?;
45+
let factor: Option<TyF64> = args.get_kw_arg_opt("factor", &RuntimeType::count(), exec_state)?;
46+
let (scale_x, scale_y, scale_z) = match (scale_x, scale_y, scale_z, factor) {
47+
(None, None, None, Some(factor)) => (Some(factor.clone()), Some(factor.clone()), Some(factor)),
48+
(Some(x), Some(y), Some(z), None) => (Some(x), Some(y), Some(z)),
49+
// Ensure at least one scale value is provided.
50+
(None, None, None, None) => {
51+
return Err(KclError::new_semantic(KclErrorDetails::new(
52+
"Expected `x`, `y`, `z` or `factor` to be provided.".to_string(),
53+
vec![args.source_range],
54+
)));
55+
}
56+
_ => {
57+
return Err(KclError::new_semantic(KclErrorDetails::new(
58+
"If you give `factor` then you cannot use `x`, `y`, or `z`".to_string(),
59+
vec![args.source_range],
60+
)));
61+
}
62+
};
4563
let global = args.get_kw_arg_opt("global", &RuntimeType::bool(), exec_state)?;
4664

47-
// Ensure at least one scale value is provided.
48-
if scale_x.is_none() && scale_y.is_none() && scale_z.is_none() {
49-
return Err(KclError::new_semantic(KclErrorDetails::new(
50-
"Expected `x`, `y`, or `z` to be provided.".to_string(),
51-
vec![args.source_range],
52-
)));
53-
}
54-
5565
let objects = inner_scale(
5666
objects,
5767
scale_x.map(|t| t.n),

rust/kcl-lib/std/transform.kcl

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -604,6 +604,21 @@ export fn rotate(
604604
/// // Scale the sweep.
605605
/// scale(parts, z = 0.5)
606606
/// ```
607+
/// ```kcl
608+
/// // Make one button (i.e. just a cylinder)
609+
/// button1 = startSketchOn(XY)
610+
/// |> circle(center = [0, 0], radius = 1.53)
611+
/// |> extrude(length = 1)
612+
///
613+
/// // Duplicate it, but use `scale` to make it smaller.
614+
/// button2 = startSketchOn(XY)
615+
/// |> circle(center = [0, 0], radius = 1.53)
616+
/// |> extrude(length = 1)
617+
/// |> translate(x = 4)
618+
/// // Make it 50% smaller and gold
619+
/// |> scale(factor = 0.5)
620+
/// |> appearance(color = "#ff9922")
621+
/// ```
607622
@(impl = std_rust, feature_tree = true)
608623
export fn scale(
609624
/// The solid, sketch, or set of solids or sketches to scale.
@@ -619,4 +634,8 @@ export fn scale(
619634
z?: number(Count) = 1,
620635
/// If true, the transform is applied in global space. The origin of the model will move. By default, the transform is applied in local sketch axis, therefore the origin will not move.
621636
global?: bool = false,
637+
/// If given, scale the solid by this much.
638+
/// Equivalent to setting `x`, `y` and `z` all to this number.
639+
/// Incompatible with `x`, `y` or `z`.
640+
factor?: number(Count) = 1,
622641
): [Solid; 1+] | [Sketch; 1+] | ImportedGeometry {}

rust/kcl-lib/tests/outputs/models/serial_test_example_fn_std-transform-scale3_output.gltf

Lines changed: 1172 additions & 0 deletions
Large diffs are not rendered by default.
55 KB
Loading

0 commit comments

Comments
 (0)