WIP: Involute circles in KCL
This commit is contained in:
		
							
								
								
									
										8
									
								
								rust/Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										8
									
								
								rust/Cargo.lock
									
									
									
										generated
									
									
									
								
							@ -2033,9 +2033,9 @@ dependencies = [
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "kittycad-modeling-cmds"
 | 
			
		||||
version = "0.2.105"
 | 
			
		||||
version = "0.2.107"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "f64667cdf4b21ba87940b6733aad67ce9fd819b94fd3b6ca90f10389c1a3750c"
 | 
			
		||||
checksum = "cb129c1f4906a76e3518e58f61968f16cb56f1279366415d2bae6059aa68fce8"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "anyhow",
 | 
			
		||||
 "chrono",
 | 
			
		||||
@ -4389,9 +4389,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "uuid"
 | 
			
		||||
version = "1.15.1"
 | 
			
		||||
version = "1.16.0"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "e0f540e3240398cce6128b64ba83fdbdd86129c16a3aa1a3a252efd66eb3d587"
 | 
			
		||||
checksum = "458f7a779bf54acc9f347480ac654f68407d3aab21269a6e3c9f922acd9e2da9"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "getrandom 0.3.1",
 | 
			
		||||
 "js-sys",
 | 
			
		||||
 | 
			
		||||
@ -36,7 +36,7 @@ dashmap = { version = "6.1.0" }
 | 
			
		||||
http = "1"
 | 
			
		||||
indexmap = "2.7.0"
 | 
			
		||||
kittycad = { version = "0.3.33", default-features = false, features = ["js", "requests"] }
 | 
			
		||||
kittycad-modeling-cmds = { version = "0.2.105", features = ["ts-rs", "websocket"] }
 | 
			
		||||
kittycad-modeling-cmds = { version = "0.2.107", features = ["ts-rs", "websocket"] }
 | 
			
		||||
lazy_static = "1.5.0"
 | 
			
		||||
miette = "7.5.0"
 | 
			
		||||
pyo3 = { version = "0.24.0" }
 | 
			
		||||
 | 
			
		||||
@ -74,6 +74,7 @@ lazy_static! {
 | 
			
		||||
        Box::new(crate::std::shapes::Circle),
 | 
			
		||||
        Box::new(crate::std::shapes::CircleThreePoint),
 | 
			
		||||
        Box::new(crate::std::shapes::Polygon),
 | 
			
		||||
        Box::new(crate::std::sketch::InvoluteCircular),
 | 
			
		||||
        Box::new(crate::std::sketch::Line),
 | 
			
		||||
        Box::new(crate::std::sketch::XLine),
 | 
			
		||||
        Box::new(crate::std::sketch::YLine),
 | 
			
		||||
 | 
			
		||||
@ -4,8 +4,10 @@ use anyhow::Result;
 | 
			
		||||
use indexmap::IndexMap;
 | 
			
		||||
use kcl_derive_docs::stdlib;
 | 
			
		||||
use kcmc::shared::Point2d as KPoint2d; // Point2d is already defined in this pkg, to impl ts_rs traits.
 | 
			
		||||
use kcmc::shared::Point3d as KPoint3d; // Point3d is already defined in this pkg, to impl ts_rs traits.
 | 
			
		||||
use kcmc::{each_cmd as mcmd, length_unit::LengthUnit, shared::Angle, websocket::ModelingCmdReq, ModelingCmd};
 | 
			
		||||
use kittycad_modeling_cmds as kcmc;
 | 
			
		||||
use kittycad_modeling_cmds::ok_response::OkModelingCmdResponse;
 | 
			
		||||
use kittycad_modeling_cmds::shared::PathSegment;
 | 
			
		||||
use parse_display::{Display, FromStr};
 | 
			
		||||
use schemars::JsonSchema;
 | 
			
		||||
@ -94,6 +96,123 @@ pub enum StartOrEnd {
 | 
			
		||||
 | 
			
		||||
pub const NEW_TAG_KW: &str = "tag";
 | 
			
		||||
 | 
			
		||||
pub async fn involute_circular(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
 | 
			
		||||
    let sketch =
 | 
			
		||||
        args.get_unlabeled_kw_arg_typed("sketch", &RuntimeType::Primitive(PrimitiveType::Sketch), exec_state)?;
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     */
 | 
			
		||||
    let start_radius = args.get_kw_arg("startRadius")?;
 | 
			
		||||
    let end_radius = args.get_kw_arg("endRadius")?;
 | 
			
		||||
    let angle = args.get_kw_arg("angle")?;
 | 
			
		||||
    let reverse = args.get_kw_arg_opt("reverse")?;
 | 
			
		||||
    let tag = args.get_kw_arg_opt("tag")?;
 | 
			
		||||
    let new_sketch =
 | 
			
		||||
        inner_involute_circular(sketch, start_radius, end_radius, angle, reverse, tag, exec_state, args).await?;
 | 
			
		||||
    Ok(KclValue::Sketch {
 | 
			
		||||
        value: Box::new(new_sketch),
 | 
			
		||||
    })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Extend the current sketch with a new involute circular curve.
 | 
			
		||||
///
 | 
			
		||||
/// ```no_run
 | 
			
		||||
/// a = 10
 | 
			
		||||
/// b = 14
 | 
			
		||||
/// startSketchOn(XZ)
 | 
			
		||||
///   |> startProfileAt([0, 0], %)
 | 
			
		||||
///   |> involuteCircular(startRadius = a, endRadius = b, angle = 60)
 | 
			
		||||
///   |> involuteCircular(startRadius = a, endRadius = b, angle = 60, reverse = true)
 | 
			
		||||
///
 | 
			
		||||
/// ```
 | 
			
		||||
#[stdlib {
 | 
			
		||||
    name = "involuteCircular",
 | 
			
		||||
    keywords = true,
 | 
			
		||||
    unlabeled_first = true,
 | 
			
		||||
    args = {
 | 
			
		||||
        sketch = { docs = "Which sketch should this path be added to?"},
 | 
			
		||||
        start_radius  = { docs = "The involute is described between two circles, start_radius is the radius of the inner circle."},
 | 
			
		||||
        end_radius  = { docs = "The involute is described between two circles, end_radius is the radius of the outer circle."},
 | 
			
		||||
        angle  = { docs = "The angle to rotate the involute by. A value of zero will produce a curve with a tangent along the x-axis at the start point of the curve."},
 | 
			
		||||
        reverse  = { docs = "If reverse is true, the segment will start from the end of the involute, otherwise it will start from that start. Defaults to false."},
 | 
			
		||||
        tag = { docs = "Create a new tag which refers to this line"},
 | 
			
		||||
    }
 | 
			
		||||
}]
 | 
			
		||||
#[allow(clippy::too_many_arguments)]
 | 
			
		||||
async fn inner_involute_circular(
 | 
			
		||||
    sketch: Sketch,
 | 
			
		||||
    start_radius: f64,
 | 
			
		||||
    end_radius: f64,
 | 
			
		||||
    angle: f64,
 | 
			
		||||
    reverse: Option<bool>,
 | 
			
		||||
    tag: Option<TagNode>,
 | 
			
		||||
    exec_state: &mut ExecState,
 | 
			
		||||
    args: Args,
 | 
			
		||||
) -> Result<Sketch, KclError> {
 | 
			
		||||
    let id = exec_state.next_uuid();
 | 
			
		||||
    let segment = PathSegment::CircularInvolute {
 | 
			
		||||
        start_radius: LengthUnit(start_radius),
 | 
			
		||||
        end_radius: LengthUnit(end_radius),
 | 
			
		||||
        angle: Angle::from_degrees(angle),
 | 
			
		||||
        reverse: reverse.unwrap_or_default(),
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    args.batch_modeling_cmd(
 | 
			
		||||
        id,
 | 
			
		||||
        ModelingCmd::from(mcmd::ExtendPath {
 | 
			
		||||
            path: sketch.id.into(),
 | 
			
		||||
            segment,
 | 
			
		||||
        }),
 | 
			
		||||
    )
 | 
			
		||||
    .await?;
 | 
			
		||||
 | 
			
		||||
    let from = sketch.current_pen_position()?;
 | 
			
		||||
    let end: KPoint3d<LengthUnit> = Default::default(); // ADAM: TODO impl this below.
 | 
			
		||||
 | 
			
		||||
    // let path_json = path_to_json();
 | 
			
		||||
    // let end = args
 | 
			
		||||
    //     .send_modeling_cmd(
 | 
			
		||||
    //         exec_state.next_uuid(),
 | 
			
		||||
    //         ModelingCmd::EngineUtilEvaluatePath(mcmd::EngineUtilEvaluatePath { path_json, t: 1.0 }),
 | 
			
		||||
    //     )
 | 
			
		||||
    //     .await?;
 | 
			
		||||
 | 
			
		||||
    // let end = match end {
 | 
			
		||||
    //     kittycad_modeling_cmds::websocket::OkWebSocketResponseData::Modeling {
 | 
			
		||||
    //         modeling_response: OkModelingCmdResponse::EngineUtilEvaluatePath(eval_path),
 | 
			
		||||
    //     } => eval_path.pos,
 | 
			
		||||
    //     other => {
 | 
			
		||||
    //         return Err(KclError::Engine(KclErrorDetails {
 | 
			
		||||
    //             source_ranges: vec![args.source_range],
 | 
			
		||||
    //             message: format!("Expected EngineUtilEvaluatePath response but found {other:?}"),
 | 
			
		||||
    //         }))
 | 
			
		||||
    //     }
 | 
			
		||||
    // };
 | 
			
		||||
 | 
			
		||||
    let current_path = Path::ToPoint {
 | 
			
		||||
        base: BasePath {
 | 
			
		||||
            from: from.into(),
 | 
			
		||||
            to: [
 | 
			
		||||
                end.x.to_millimeters(sketch.units.into()),
 | 
			
		||||
                end.y.to_millimeters(sketch.units.into()),
 | 
			
		||||
            ],
 | 
			
		||||
            tag: tag.clone(),
 | 
			
		||||
            units: sketch.units,
 | 
			
		||||
            geo_meta: GeoMeta {
 | 
			
		||||
                id,
 | 
			
		||||
                metadata: args.source_range.into(),
 | 
			
		||||
            },
 | 
			
		||||
        },
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    let mut new_sketch = sketch.clone();
 | 
			
		||||
    if let Some(tag) = &tag {
 | 
			
		||||
        new_sketch.add_tag(tag, ¤t_path, exec_state);
 | 
			
		||||
    }
 | 
			
		||||
    new_sketch.paths.push(current_path);
 | 
			
		||||
    Ok(new_sketch)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Draw a line to a point.
 | 
			
		||||
pub async fn line(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
 | 
			
		||||
    // let (to, sketch, tag): ([f64; 2], Sketch, Option<TagNode>) = args.get_data_and_sketch_and_tag()?;
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user