Improve KCL Samples (#5767)

* improve KCL Samples & .gitignore

* update block and car wheel assembly

* update flange and lego, delete flange xy

* artifacts

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* scale

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* docs

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
Co-authored-by: Jess Frazelle <github@jessfraz.com>
This commit is contained in:
Josh Gomez
2025-03-13 23:38:51 -07:00
committed by GitHub
parent dd99c27d56
commit 58e0c0e916
101 changed files with 107664 additions and 57348 deletions

View File

@ -1338,6 +1338,7 @@ impl<'a> FromKclValue<'a> for crate::execution::SolidOrImportedGeometry {
fn from_kcl_val(arg: &'a KclValue) -> Option<Self> {
match arg {
KclValue::Solid { value } => Some(Self::Solid(value.clone())),
KclValue::Solids { value } => Some(Self::SolidSet(value.clone())),
KclValue::ImportedGeometry(value) => Some(Self::ImportedGeometry(Box::new(value.clone()))),
_ => None,
}

View File

@ -24,12 +24,12 @@ pub enum SweepPath {
/// Extrude a sketch along a path.
pub async fn sweep(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let sketch = args.get_unlabeled_kw_arg("sketch")?;
let sketch_set = args.get_unlabeled_kw_arg("sketch_set")?;
let path: SweepPath = args.get_kw_arg("path")?;
let sectional = args.get_kw_arg_opt("sectional")?;
let tolerance = args.get_kw_arg_opt("tolerance")?;
let value = inner_sweep(sketch, path, sectional, tolerance, exec_state, args).await?;
let value = inner_sweep(sketch_set, path, sectional, tolerance, exec_state, args).await?;
Ok(value.into())
}

View File

@ -19,11 +19,11 @@ use crate::{
/// Scale a solid.
pub async fn scale(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let solid = args.get_unlabeled_kw_arg("solid")?;
let solid_set = args.get_unlabeled_kw_arg("solid_set")?;
let scale = args.get_kw_arg("scale")?;
let global = args.get_kw_arg_opt("global")?;
let solid = inner_scale(solid, scale, global, exec_state, args).await?;
let solid = inner_scale(solid_set, scale, global, exec_state, args).await?;
Ok(solid.into())
}
@ -84,58 +84,94 @@ pub async fn scale(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K
/// scale = [1.0, 1.0, 2.5],
/// )
/// ```
///
/// ```
/// // Sweep two sketches along the same path.
///
/// sketch001 = startSketchOn('XY')
/// rectangleSketch = startProfileAt([-200, 23.86], sketch001)
/// |> angledLine([0, 73.47], %, $rectangleSegmentA001)
/// |> angledLine([
/// segAng(rectangleSegmentA001) - 90,
/// 50.61
/// ], %)
/// |> angledLine([
/// segAng(rectangleSegmentA001),
/// -segLen(rectangleSegmentA001)
/// ], %)
/// |> line(endAbsolute = [profileStartX(%), profileStartY(%)])
/// |> close()
///
/// circleSketch = circle(sketch001, center = [200, -30.29], radius = 32.63)
///
/// sketch002 = startSketchOn('YZ')
/// sweepPath = startProfileAt([0, 0], sketch002)
/// |> yLine(length = 231.81)
/// |> tangentialArc({
/// radius = 80,
/// offset = -90,
/// }, %)
/// |> xLine(length = 384.93)
///
/// parts = sweep([rectangleSketch, circleSketch], path = sweepPath)
///
/// // Scale the sweep.
/// scale(parts, scale = [1.0, 1.0, 0.5])
/// ```
#[stdlib {
name = "scale",
feature_tree_operation = false,
keywords = true,
unlabeled_first = true,
args = {
solid = {docs = "The solid to scale."},
solid_set = {docs = "The solid or set of solids to scale."},
scale = {docs = "The scale factor for the x, y, and z axes."},
global = {docs = "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."}
}
}]
async fn inner_scale(
solid: SolidOrImportedGeometry,
solid_set: SolidOrImportedGeometry,
scale: [f64; 3],
global: Option<bool>,
exec_state: &mut ExecState,
args: Args,
) -> Result<SolidOrImportedGeometry, KclError> {
let id = exec_state.next_uuid();
for solid_id in solid_set.ids() {
let id = exec_state.next_uuid();
args.batch_modeling_cmd(
id,
ModelingCmd::from(mcmd::SetObjectTransform {
object_id: solid.id(),
transforms: vec![shared::ComponentTransform {
scale: Some(shared::TransformBy::<Point3d<f64>> {
property: Point3d {
x: scale[0],
y: scale[1],
z: scale[2],
},
set: false,
is_local: !global.unwrap_or(false),
}),
translate: None,
rotate_rpy: None,
rotate_angle_axis: None,
}],
}),
)
.await?;
args.batch_modeling_cmd(
id,
ModelingCmd::from(mcmd::SetObjectTransform {
object_id: solid_id,
transforms: vec![shared::ComponentTransform {
scale: Some(shared::TransformBy::<Point3d<f64>> {
property: Point3d {
x: scale[0],
y: scale[1],
z: scale[2],
},
set: false,
is_local: !global.unwrap_or(false),
}),
translate: None,
rotate_rpy: None,
rotate_angle_axis: None,
}],
}),
)
.await?;
}
Ok(solid)
Ok(solid_set)
}
/// Move a solid.
pub async fn translate(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let solid = args.get_unlabeled_kw_arg("solid")?;
let solid_set = args.get_unlabeled_kw_arg("solid_set")?;
let translate = args.get_kw_arg("translate")?;
let global = args.get_kw_arg_opt("global")?;
let solid = inner_translate(solid, translate, global, exec_state, args).await?;
let solid = inner_translate(solid_set, translate, global, exec_state, args).await?;
Ok(solid.into())
}
@ -188,54 +224,90 @@ pub async fn translate(exec_state: &mut ExecState, args: Args) -> Result<KclValu
/// translate = [1.0, 1.0, 2.5],
/// )
/// ```
///
/// ```
/// // Sweep two sketches along the same path.
///
/// sketch001 = startSketchOn('XY')
/// rectangleSketch = startProfileAt([-200, 23.86], sketch001)
/// |> angledLine([0, 73.47], %, $rectangleSegmentA001)
/// |> angledLine([
/// segAng(rectangleSegmentA001) - 90,
/// 50.61
/// ], %)
/// |> angledLine([
/// segAng(rectangleSegmentA001),
/// -segLen(rectangleSegmentA001)
/// ], %)
/// |> line(endAbsolute = [profileStartX(%), profileStartY(%)])
/// |> close()
///
/// circleSketch = circle(sketch001, center = [200, -30.29], radius = 32.63)
///
/// sketch002 = startSketchOn('YZ')
/// sweepPath = startProfileAt([0, 0], sketch002)
/// |> yLine(length = 231.81)
/// |> tangentialArc({
/// radius = 80,
/// offset = -90,
/// }, %)
/// |> xLine(length = 384.93)
///
/// parts = sweep([rectangleSketch, circleSketch], path = sweepPath)
///
/// // Move the sweeps.
/// translate(parts, translate = [1.0, 1.0, 2.5])
/// ```
#[stdlib {
name = "translate",
feature_tree_operation = false,
keywords = true,
unlabeled_first = true,
args = {
solid = {docs = "The solid to move."},
solid_set = {docs = "The solid or set of solids to move."},
translate = {docs = "The amount to move the solid in all three axes."},
global = {docs = "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."}
}
}]
async fn inner_translate(
solid: SolidOrImportedGeometry,
solid_set: SolidOrImportedGeometry,
translate: [f64; 3],
global: Option<bool>,
exec_state: &mut ExecState,
args: Args,
) -> Result<SolidOrImportedGeometry, KclError> {
let id = exec_state.next_uuid();
for solid_id in solid_set.ids() {
let id = exec_state.next_uuid();
args.batch_modeling_cmd(
id,
ModelingCmd::from(mcmd::SetObjectTransform {
object_id: solid.id(),
transforms: vec![shared::ComponentTransform {
translate: Some(shared::TransformBy::<Point3d<LengthUnit>> {
property: shared::Point3d {
x: LengthUnit(translate[0]),
y: LengthUnit(translate[1]),
z: LengthUnit(translate[2]),
},
set: false,
is_local: !global.unwrap_or(false),
}),
scale: None,
rotate_rpy: None,
rotate_angle_axis: None,
}],
}),
)
.await?;
args.batch_modeling_cmd(
id,
ModelingCmd::from(mcmd::SetObjectTransform {
object_id: solid_id,
transforms: vec![shared::ComponentTransform {
translate: Some(shared::TransformBy::<Point3d<LengthUnit>> {
property: shared::Point3d {
x: LengthUnit(translate[0]),
y: LengthUnit(translate[1]),
z: LengthUnit(translate[2]),
},
set: false,
is_local: !global.unwrap_or(false),
}),
scale: None,
rotate_rpy: None,
rotate_angle_axis: None,
}],
}),
)
.await?;
}
Ok(solid)
Ok(solid_set)
}
/// Rotate a solid.
pub async fn rotate(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let solid = args.get_unlabeled_kw_arg("solid")?;
let solid_set = args.get_unlabeled_kw_arg("solid_set")?;
let roll = args.get_kw_arg_opt("roll")?;
let pitch = args.get_kw_arg_opt("pitch")?;
let yaw = args.get_kw_arg_opt("yaw")?;
@ -343,7 +415,7 @@ pub async fn rotate(exec_state: &mut ExecState, args: Args) -> Result<KclValue,
}
}
let solid = inner_rotate(solid, roll, pitch, yaw, axis, angle, global, exec_state, args).await?;
let solid = inner_rotate(solid_set, roll, pitch, yaw, axis, angle, global, exec_state, args).await?;
Ok(solid.into())
}
@ -459,13 +531,47 @@ pub async fn rotate(exec_state: &mut ExecState, args: Args) -> Result<KclValue,
/// angle = 90,
/// )
/// ```
///
/// ```
/// // Sweep two sketches along the same path.
///
/// sketch001 = startSketchOn('XY')
/// rectangleSketch = startProfileAt([-200, 23.86], sketch001)
/// |> angledLine([0, 73.47], %, $rectangleSegmentA001)
/// |> angledLine([
/// segAng(rectangleSegmentA001) - 90,
/// 50.61
/// ], %)
/// |> angledLine([
/// segAng(rectangleSegmentA001),
/// -segLen(rectangleSegmentA001)
/// ], %)
/// |> line(endAbsolute = [profileStartX(%), profileStartY(%)])
/// |> close()
///
/// circleSketch = circle(sketch001, center = [200, -30.29], radius = 32.63)
///
/// sketch002 = startSketchOn('YZ')
/// sweepPath = startProfileAt([0, 0], sketch002)
/// |> yLine(length = 231.81)
/// |> tangentialArc({
/// radius = 80,
/// offset = -90,
/// }, %)
/// |> xLine(length = 384.93)
///
/// parts = sweep([rectangleSketch, circleSketch], path = sweepPath)
///
/// // Rotate the sweeps.
/// rotate(parts, axis = [0, 0, 1.0], angle = 90)
/// ```
#[stdlib {
name = "rotate",
feature_tree_operation = false,
keywords = true,
unlabeled_first = true,
args = {
solid = {docs = "The solid to rotate."},
solid_set = {docs = "The solid or set of solids to rotate."},
roll = {docs = "The roll angle in degrees. Must be used with `pitch` and `yaw`. Must be between -360 and 360.", include_in_snippet = true},
pitch = {docs = "The pitch angle in degrees. Must be used with `roll` and `yaw`. Must be between -360 and 360.", include_in_snippet = true},
yaw = {docs = "The yaw angle in degrees. Must be used with `roll` and `pitch`. Must be between -360 and 360.", include_in_snippet = true},
@ -476,7 +582,7 @@ pub async fn rotate(exec_state: &mut ExecState, args: Args) -> Result<KclValue,
}]
#[allow(clippy::too_many_arguments)]
async fn inner_rotate(
solid: SolidOrImportedGeometry,
solid_set: SolidOrImportedGeometry,
roll: Option<f64>,
pitch: Option<f64>,
yaw: Option<f64>,
@ -486,58 +592,60 @@ async fn inner_rotate(
exec_state: &mut ExecState,
args: Args,
) -> Result<SolidOrImportedGeometry, KclError> {
let id = exec_state.next_uuid();
for solid_id in solid_set.ids() {
let id = exec_state.next_uuid();
if let (Some(roll), Some(pitch), Some(yaw)) = (roll, pitch, yaw) {
args.batch_modeling_cmd(
id,
ModelingCmd::from(mcmd::SetObjectTransform {
object_id: solid.id(),
transforms: vec![shared::ComponentTransform {
rotate_rpy: Some(shared::TransformBy::<Point3d<f64>> {
property: shared::Point3d {
x: roll,
y: pitch,
z: yaw,
},
set: false,
is_local: !global.unwrap_or(false),
}),
scale: None,
rotate_angle_axis: None,
translate: None,
}],
}),
)
.await?;
if let (Some(roll), Some(pitch), Some(yaw)) = (roll, pitch, yaw) {
args.batch_modeling_cmd(
id,
ModelingCmd::from(mcmd::SetObjectTransform {
object_id: solid_id,
transforms: vec![shared::ComponentTransform {
rotate_rpy: Some(shared::TransformBy::<Point3d<f64>> {
property: shared::Point3d {
x: roll,
y: pitch,
z: yaw,
},
set: false,
is_local: !global.unwrap_or(false),
}),
scale: None,
rotate_angle_axis: None,
translate: None,
}],
}),
)
.await?;
}
if let (Some(axis), Some(angle)) = (axis, angle) {
args.batch_modeling_cmd(
id,
ModelingCmd::from(mcmd::SetObjectTransform {
object_id: solid_id,
transforms: vec![shared::ComponentTransform {
rotate_angle_axis: Some(shared::TransformBy::<Point4d<f64>> {
property: shared::Point4d {
x: axis[0],
y: axis[1],
z: axis[2],
w: angle,
},
set: false,
is_local: !global.unwrap_or(false),
}),
scale: None,
rotate_rpy: None,
translate: None,
}],
}),
)
.await?;
}
}
if let (Some(axis), Some(angle)) = (axis, angle) {
args.batch_modeling_cmd(
id,
ModelingCmd::from(mcmd::SetObjectTransform {
object_id: solid.id(),
transforms: vec![shared::ComponentTransform {
rotate_angle_axis: Some(shared::TransformBy::<Point4d<f64>> {
property: shared::Point4d {
x: axis[0],
y: axis[1],
z: axis[2],
w: angle,
},
set: false,
is_local: !global.unwrap_or(false),
}),
scale: None,
rotate_rpy: None,
translate: None,
}],
}),
)
.await?;
}
Ok(solid)
Ok(solid_set)
}
#[cfg(test)]