rotate a named axis (#7087)

updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>
This commit is contained in:
Jess Frazelle
2025-05-19 15:11:35 -07:00
committed by GitHub
parent 9df476543a
commit 978d5d44a2
11 changed files with 163 additions and 41 deletions

View File

@ -9,6 +9,7 @@ use kittycad_modeling_cmds as kcmc;
use schemars::JsonSchema;
use serde::Serialize;
pub use crate::execution::fn_call::Args;
use crate::{
errors::{KclError, KclErrorDetails},
execution::{
@ -27,8 +28,6 @@ use crate::{
ModuleId,
};
pub use crate::execution::fn_call::Args;
const ERROR_STRING_SKETCH_TO_SOLID_HELPER: &str =
"You can convert a sketch (2D) into a Solid (3D) by calling a function like `extrude` or `revolve`";

View File

@ -15,6 +15,7 @@ use kittycad_modeling_cmds::{
use serde::Serialize;
use uuid::Uuid;
use super::axis_or_reference::Axis3dOrPoint3d;
use crate::{
errors::{KclError, KclErrorDetails},
execution::{
@ -31,8 +32,6 @@ use crate::{
ExecutorContext, SourceRange,
};
use super::axis_or_reference::Axis3dOrPoint3d;
const MUST_HAVE_ONE_INSTANCE: &str = "There must be at least 1 instance of your geometry";
/// Repeat some 3D solid, changing each repetition slightly.
@ -1008,7 +1007,16 @@ pub async fn pattern_circular_3d(exec_state: &mut ExecState, args: Args) -> Resu
// If instances is 1, this has no effect.
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)?;
let axis: Axis3dOrPoint3d = args.get_kw_arg_typed(
"axis",
&RuntimeType::Union(vec![
RuntimeType::Primitive(PrimitiveType::Axis3d),
RuntimeType::point3d(),
]),
exec_state,
)?;
let axis = axis.to_point3d();
// The center about which to make the pattern. This is a 3D vector.
let center: [TyF64; 3] = args.get_kw_arg_typed("center", &RuntimeType::point3d(), exec_state)?;
// The arc angle (in degrees) to place the repetitions. Must be greater than 0.
@ -1040,6 +1048,24 @@ pub async fn pattern_circular_3d(exec_state: &mut ExecState, args: Args) -> Resu
/// solid with respect to the center of the circle is maintained.
///
/// ```no_run
/// /// Pattern using a named axis.
///
/// exampleSketch = startSketchOn(XZ)
/// |> circle(center = [0, 0], radius = 1)
///
/// example = extrude(exampleSketch, length = -5)
/// |> patternCircular3d(
/// axis = X,
/// center = [10, -20, 0],
/// instances = 11,
/// arcDegrees = 360,
/// rotateDuplicates = true
/// )
/// ```
///
/// ```no_run
/// /// Pattern using a raw axis.
///
/// exampleSketch = startSketchOn(XZ)
/// |> circle(center = [0, 0], radius = 1)
///

View File

@ -11,11 +11,13 @@ use kcmc::{
};
use kittycad_modeling_cmds as kcmc;
use super::args::TyF64;
use crate::{
errors::{KclError, KclErrorDetails},
execution::{types::RuntimeType, ExecState, KclValue, SolidOrSketchOrImportedGeometry},
std::Args,
execution::{
types::{PrimitiveType, RuntimeType},
ExecState, KclValue, SolidOrSketchOrImportedGeometry,
},
std::{args::TyF64, axis_or_reference::Axis3dOrPoint3d, Args},
};
/// Scale a solid or a sketch.
@ -446,7 +448,15 @@ pub async fn rotate(exec_state: &mut ExecState, args: Args) -> Result<KclValue,
let roll: Option<TyF64> = args.get_kw_arg_opt_typed("roll", &RuntimeType::degrees(), exec_state)?;
let pitch: Option<TyF64> = args.get_kw_arg_opt_typed("pitch", &RuntimeType::degrees(), exec_state)?;
let yaw: Option<TyF64> = args.get_kw_arg_opt_typed("yaw", &RuntimeType::degrees(), exec_state)?;
let axis: Option<[TyF64; 3]> = args.get_kw_arg_opt_typed("axis", &RuntimeType::point3d(), exec_state)?;
let axis: Option<Axis3dOrPoint3d> = args.get_kw_arg_opt_typed(
"axis",
&RuntimeType::Union(vec![
RuntimeType::Primitive(PrimitiveType::Axis3d),
RuntimeType::point3d(),
]),
exec_state,
)?;
let axis = axis.map(|a| a.to_point3d());
let angle: Option<TyF64> = args.get_kw_arg_opt_typed("angle", &RuntimeType::degrees(), exec_state)?;
let global = args.get_kw_arg_opt("global")?;
@ -642,7 +652,51 @@ pub async fn rotate(exec_state: &mut ExecState, args: Args) -> Result<KclValue,
/// ```
///
/// ```no_run
/// // Rotate a pipe about an axis with an angle.
/// // Rotate a pipe about a named axis with an angle.
///
/// // Create a path for the sweep.
/// sweepPath = startSketchOn(XZ)
/// |> startProfile(at = [0.05, 0.05])
/// |> line(end = [0, 7])
/// |> tangentialArc(angle = 90, radius = 5)
/// |> line(end = [-3, 0])
/// |> tangentialArc(angle = -90, radius = 5)
/// |> line(end = [0, 7])
///
/// // Create a hole for the pipe.
/// pipeHole = startSketchOn(XY)
/// |> circle(
/// center = [0, 0],
/// radius = 1.5,
/// )
///
/// sweepSketch = startSketchOn(XY)
/// |> circle(
/// center = [0, 0],
/// radius = 2,
/// )
/// |> subtract2d(tool = pipeHole)
/// |> sweep(path = sweepPath)
/// |> rotate(
/// axis = Z,
/// angle = 90,
/// )
/// ```
///
/// ```no_run
/// // Rotate an imported model.
///
/// import "tests/inputs/cube.sldprt" as cube
///
/// cube
/// |> rotate(
/// axis = [0, 0, 1.0],
/// angle = 9,
/// )
/// ```
///
/// ```no_run
/// // Rotate a pipe about a raw axis with an angle.
///
/// // Create a path for the sweep.
/// sweepPath = startSketchOn(XZ)
@ -673,18 +727,6 @@ pub async fn rotate(exec_state: &mut ExecState, args: Args) -> Result<KclValue,
/// )
/// ```
///
/// ```no_run
/// // Rotate an imported model.
///
/// import "tests/inputs/cube.sldprt" as cube
///
/// cube
/// |> rotate(
/// axis = [0, 0, 1.0],
/// angle = 9,
/// )
/// ```
///
/// ```
/// // Sweep two sketches along the same path.
///