diff --git a/src/clientSideScene/CameraControls.ts b/src/clientSideScene/CameraControls.ts index 4a1e636335..2cf0394efa 100644 --- a/src/clientSideScene/CameraControls.ts +++ b/src/clientSideScene/CameraControls.ts @@ -444,8 +444,19 @@ export class CameraControls { } onMouseWheel = (event: WheelEvent) => { + const interaction = this.getInteractionType(event) + if (interaction === 'none') return + event.preventDefault() + if (this.syncDirection === 'engineToClient') { - this.zoomDataFromLastFrame = event.deltaY + if (interaction === 'zoom') { + this.zoomDataFromLastFrame = event.deltaY + } else { + // This case will get handled when we add pan and rotate using Apple trackpad. + console.error( + `Unexpected interaction type for engineToClient wheel event: ${interaction}` + ) + } return } @@ -455,8 +466,16 @@ export class CameraControls { // zoom commands to engine. This means dropping some zoom // commands too. // From onMouseMove zoom handling which seems to be really smooth + this.handleStart() - this.pendingZoom = 1 + (event.deltaY / window.devicePixelRatio) * 0.001 + if (interaction === 'zoom') { + this.pendingZoom = 1 + (event.deltaY / window.devicePixelRatio) * 0.001 + } else { + // This case will get handled when we add pan and rotate using Apple trackpad. + console.error( + `Unexpected interaction type for wheel event: ${interaction}` + ) + } this.handleEnd() } @@ -1123,7 +1142,7 @@ export class CameraControls { this.deferReactUpdate(this.reactCameraProperties) Object.values(this._camChangeCallbacks).forEach((cb) => cb()) } - getInteractionType = (event: any) => + getInteractionType = (event: MouseEvent) => _getInteractionType( this.interactionGuards, event, @@ -1231,16 +1250,21 @@ function _lookAt(position: Vector3, target: Vector3, up: Vector3): Quaternion { function _getInteractionType( interactionGuards: MouseGuard, - event: any, + event: MouseEvent | WheelEvent, enablePan: boolean, enableRotate: boolean, enableZoom: boolean ): interactionType | 'none' { - let state: interactionType | 'none' = 'none' - if (enablePan && interactionGuards.pan.callback(event)) return 'pan' - if (enableRotate && interactionGuards.rotate.callback(event)) return 'rotate' - if (enableZoom && interactionGuards.zoom.dragCallback(event)) return 'zoom' - return state + if (event instanceof WheelEvent) { + if (enableZoom && interactionGuards.zoom.scrollCallback(event)) + return 'zoom' + } else { + if (enablePan && interactionGuards.pan.callback(event)) return 'pan' + if (enableRotate && interactionGuards.rotate.callback(event)) + return 'rotate' + if (enableZoom && interactionGuards.zoom.dragCallback(event)) return 'zoom' + } + return 'none' } /** diff --git a/src/components/Stream.tsx b/src/components/Stream.tsx index 3a90f83e58..64a8b5ee40 100644 --- a/src/components/Stream.tsx +++ b/src/components/Stream.tsx @@ -260,7 +260,7 @@ export const Stream = () => { if (state.matches('Sketch')) return if (state.matches({ idle: 'showPlanes' })) return - if (btnName(e).left) { + if (btnName(e.nativeEvent).left) { // eslint-disable-next-line @typescript-eslint/no-floating-promises sendSelectEventToEngine(e, videoRef.current) } diff --git a/src/lib/cameraControls.ts b/src/lib/cameraControls.ts index 48346121fd..8ad6b4930c 100644 --- a/src/lib/cameraControls.ts +++ b/src/lib/cameraControls.ts @@ -6,7 +6,7 @@ const META = PLATFORM === 'macos' ? 'Cmd' : PLATFORM === 'windows' ? 'Win' : 'Super' const ALT = PLATFORM === 'macos' ? 'Option' : 'Alt' -const noModifiersPressed = (e: React.MouseEvent) => +const noModifiersPressed = (e: MouseEvent) => !e.ctrlKey && !e.shiftKey && !e.altKey && !e.metaKey export type CameraSystem = @@ -53,14 +53,14 @@ export function mouseControlsToCameraSystem( interface MouseGuardHandler { description: string - callback: (e: React.MouseEvent) => boolean + callback: (e: MouseEvent) => boolean lenientDragStartButton?: number } interface MouseGuardZoomHandler { description: string - dragCallback: (e: React.MouseEvent) => boolean - scrollCallback: (e: React.MouseEvent) => boolean + dragCallback: (e: MouseEvent) => boolean + scrollCallback: (e: WheelEvent) => boolean lenientDragStartButton?: number } @@ -70,7 +70,7 @@ export interface MouseGuard { rotate: MouseGuardHandler } -export const btnName = (e: React.MouseEvent) => ({ +export const btnName = (e: MouseEvent) => ({ middle: !!(e.buttons & 4) || e.button === 1, right: !!(e.buttons & 2) || e.button === 2, left: !!(e.buttons & 1) || e.button === 0, diff --git a/src/wasm-lib/Cargo.lock b/src/wasm-lib/Cargo.lock index f7339207a3..8beff4a616 100644 --- a/src/wasm-lib/Cargo.lock +++ b/src/wasm-lib/Cargo.lock @@ -264,7 +264,7 @@ dependencies = [ "bitvec", "chrono", "hex", - "indexmap 2.2.5", + "indexmap 2.5.0", "js-sys", "once_cell", "rand 0.8.5", @@ -1067,7 +1067,7 @@ dependencies = [ "futures-sink", "futures-util", "http 0.2.12", - "indexmap 2.2.5", + "indexmap 2.5.0", "slab", "tokio", "tokio-util", @@ -1293,12 +1293,13 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.2.5" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b0b929d511467233429c45a44ac1dcaa21ba0f5ba11e4879e6ed28ddb4f9df4" +checksum = "68b900aa2f7301e21c36462b170ee99994de34dff39a4a6a528e80e7376d07e5" dependencies = [ "equivalent", "hashbrown 0.14.3", + "serde", ] [[package]] @@ -1422,6 +1423,7 @@ dependencies = [ "http 0.2.12", "iai", "image", + "indexmap 2.5.0", "insta", "itertools 0.13.0", "js-sys", @@ -2740,7 +2742,7 @@ version = "1.0.128" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" dependencies = [ - "indexmap 2.2.5", + "indexmap 2.5.0", "itoa", "memchr", "ryu", @@ -3268,7 +3270,7 @@ version = "0.22.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "583c44c02ad26b0c3f3066fe629275e50627026c51ac2e595cca4c230ce1ce1d" dependencies = [ - "indexmap 2.2.5", + "indexmap 2.5.0", "serde", "serde_spanned", "toml_datetime", @@ -4035,6 +4037,6 @@ dependencies = [ "crc32fast", "crossbeam-utils", "displaydoc", - "indexmap 2.2.5", + "indexmap 2.5.0", "thiserror", ] diff --git a/src/wasm-lib/kcl/Cargo.toml b/src/wasm-lib/kcl/Cargo.toml index 2e5017cae6..a979f808cb 100644 --- a/src/wasm-lib/kcl/Cargo.toml +++ b/src/wasm-lib/kcl/Cargo.toml @@ -27,6 +27,7 @@ git_rev = "0.1.0" gltf-json = "1.4.1" http = { workspace = true } image = { version = "0.25.1", default-features = false, features = ["png"] } +indexmap = { version = "2.5.0", features = ["serde"] } kittycad = { workspace = true } kittycad-modeling-cmds = { workspace = true } lazy_static = "1.5.0" diff --git a/src/wasm-lib/kcl/src/ast/modify.rs b/src/wasm-lib/kcl/src/ast/modify.rs index 373173e04d..7e4f4fa3bb 100644 --- a/src/wasm-lib/kcl/src/ast/modify.rs +++ b/src/wasm-lib/kcl/src/ast/modify.rs @@ -1,10 +1,9 @@ use std::sync::Arc; -use kcmc::each_cmd as mcmd; -use kcmc::ok_response::OkModelingCmdResponse; -use kcmc::shared::PathCommand; -use kcmc::websocket::OkWebSocketResponseData; -use kcmc::ModelingCmd; +use kcmc::{ + each_cmd as mcmd, ok_response::OkModelingCmdResponse, shared::PathCommand, websocket::OkWebSocketResponseData, + ModelingCmd, +}; use kittycad_modeling_cmds as kcmc; use crate::{ diff --git a/src/wasm-lib/kcl/src/engine/conn.rs b/src/wasm-lib/kcl/src/engine/conn.rs index adc1838504..d0cfade1a3 100644 --- a/src/wasm-lib/kcl/src/engine/conn.rs +++ b/src/wasm-lib/kcl/src/engine/conn.rs @@ -1,19 +1,19 @@ //! Functions for setting up our WebSocket and WebRTC connections for communications with the //! engine. -use std::{ - collections::HashMap, - sync::{Arc, Mutex}, -}; +use std::sync::{Arc, Mutex}; use anyhow::{anyhow, Result}; use dashmap::DashMap; use futures::{SinkExt, StreamExt}; -use kcmc::websocket::{ - BatchResponse, FailureWebSocketResponse, ModelingCmdReq, ModelingSessionData, OkWebSocketResponseData, - SuccessWebSocketResponse, WebSocketRequest, WebSocketResponse, +use indexmap::IndexMap; +use kcmc::{ + websocket::{ + BatchResponse, FailureWebSocketResponse, ModelingCmdReq, ModelingSessionData, OkWebSocketResponseData, + SuccessWebSocketResponse, WebSocketRequest, WebSocketResponse, + }, + ModelingCmd, }; -use kcmc::ModelingCmd; use kittycad_modeling_cmds as kcmc; use tokio::sync::{mpsc, oneshot, RwLock}; use tokio_tungstenite::tungstenite::Message as WsMsg; @@ -39,7 +39,7 @@ pub struct EngineConnection { tcp_read_handle: Arc, socket_health: Arc>, batch: Arc>>, - batch_end: Arc>>, + batch_end: Arc>>, /// The default planes for the scene. default_planes: Arc>>, @@ -269,7 +269,7 @@ impl EngineConnection { responses, socket_health, batch: Arc::new(Mutex::new(Vec::new())), - batch_end: Arc::new(Mutex::new(HashMap::new())), + batch_end: Arc::new(Mutex::new(IndexMap::new())), default_planes: Default::default(), session_data, }) @@ -282,7 +282,7 @@ impl EngineManager for EngineConnection { self.batch.clone() } - fn batch_end(&self) -> Arc>> { + fn batch_end(&self) -> Arc>> { self.batch_end.clone() } diff --git a/src/wasm-lib/kcl/src/engine/conn_mock.rs b/src/wasm-lib/kcl/src/engine/conn_mock.rs index c6b75b5aad..fa951eaba2 100644 --- a/src/wasm-lib/kcl/src/engine/conn_mock.rs +++ b/src/wasm-lib/kcl/src/engine/conn_mock.rs @@ -7,10 +7,13 @@ use std::{ }; use anyhow::Result; -use kcmc::ok_response::OkModelingCmdResponse; -use kcmc::websocket::{ - BatchResponse, ModelingBatch, OkWebSocketResponseData, SuccessWebSocketResponse, WebSocketRequest, - WebSocketResponse, +use indexmap::IndexMap; +use kcmc::{ + ok_response::OkModelingCmdResponse, + websocket::{ + BatchResponse, ModelingBatch, OkWebSocketResponseData, SuccessWebSocketResponse, WebSocketRequest, + WebSocketResponse, + }, }; use kittycad_modeling_cmds::{self as kcmc}; @@ -19,14 +22,14 @@ use crate::{errors::KclError, executor::DefaultPlanes}; #[derive(Debug, Clone)] pub struct EngineConnection { batch: Arc>>, - batch_end: Arc>>, + batch_end: Arc>>, } impl EngineConnection { pub async fn new() -> Result { Ok(EngineConnection { batch: Arc::new(Mutex::new(Vec::new())), - batch_end: Arc::new(Mutex::new(HashMap::new())), + batch_end: Arc::new(Mutex::new(IndexMap::new())), }) } } @@ -37,7 +40,7 @@ impl crate::engine::EngineManager for EngineConnection { self.batch.clone() } - fn batch_end(&self) -> Arc>> { + fn batch_end(&self) -> Arc>> { self.batch_end.clone() } diff --git a/src/wasm-lib/kcl/src/engine/conn_wasm.rs b/src/wasm-lib/kcl/src/engine/conn_wasm.rs index 93a950c0d4..bcb44d1229 100644 --- a/src/wasm-lib/kcl/src/engine/conn_wasm.rs +++ b/src/wasm-lib/kcl/src/engine/conn_wasm.rs @@ -6,6 +6,7 @@ use std::{ }; use anyhow::Result; +use indexmap::IndexMap; use kcmc::websocket::{WebSocketRequest, WebSocketResponse}; use kittycad_modeling_cmds as kcmc; use wasm_bindgen::prelude::*; @@ -43,7 +44,7 @@ extern "C" { pub struct EngineConnection { manager: Arc, batch: Arc>>, - batch_end: Arc>>, + batch_end: Arc>>, } // Safety: WebAssembly will only ever run in a single-threaded context. @@ -55,7 +56,7 @@ impl EngineConnection { Ok(EngineConnection { manager: Arc::new(manager), batch: Arc::new(Mutex::new(Vec::new())), - batch_end: Arc::new(Mutex::new(HashMap::new())), + batch_end: Arc::new(Mutex::new(IndexMap::new())), }) } } @@ -66,7 +67,7 @@ impl crate::engine::EngineManager for EngineConnection { self.batch.clone() } - fn batch_end(&self) -> Arc>> { + fn batch_end(&self) -> Arc>> { self.batch_end.clone() } diff --git a/src/wasm-lib/kcl/src/engine/mod.rs b/src/wasm-lib/kcl/src/engine/mod.rs index b59f261b83..900d717ec9 100644 --- a/src/wasm-lib/kcl/src/engine/mod.rs +++ b/src/wasm-lib/kcl/src/engine/mod.rs @@ -13,15 +13,18 @@ use std::{ sync::{Arc, Mutex}, }; -use kcmc::each_cmd as mcmd; -use kcmc::length_unit::LengthUnit; -use kcmc::ok_response::OkModelingCmdResponse; -use kcmc::shared::Color; -use kcmc::websocket::ModelingBatch; -use kcmc::websocket::{ - BatchResponse, ModelingCmdReq, ModelingSessionData, OkWebSocketResponseData, WebSocketRequest, WebSocketResponse, +use indexmap::IndexMap; +use kcmc::{ + each_cmd as mcmd, + length_unit::LengthUnit, + ok_response::OkModelingCmdResponse, + shared::Color, + websocket::{ + BatchResponse, ModelingBatch, ModelingCmdReq, ModelingSessionData, OkWebSocketResponseData, WebSocketRequest, + WebSocketResponse, + }, + ModelingCmd, }; -use kcmc::ModelingCmd; use kittycad_modeling_cmds as kcmc; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; @@ -44,7 +47,7 @@ pub trait EngineManager: std::fmt::Debug + Send + Sync + 'static { fn batch(&self) -> Arc>>; /// Get the batch of end commands to be sent to the engine. - fn batch_end(&self) -> Arc>>; + fn batch_end(&self) -> Arc>>; /// Get the default planes. async fn default_planes( diff --git a/src/wasm-lib/kcl/src/executor.rs b/src/wasm-lib/kcl/src/executor.rs index 71d5b9a442..5f56f77bed 100644 --- a/src/wasm-lib/kcl/src/executor.rs +++ b/src/wasm-lib/kcl/src/executor.rs @@ -4,10 +4,12 @@ use std::{collections::HashMap, sync::Arc}; use anyhow::Result; use async_recursion::async_recursion; -use kcmc::each_cmd as mcmd; -use kcmc::ok_response::{output::TakeSnapshot, OkModelingCmdResponse}; -use kcmc::websocket::{ModelingSessionData, OkWebSocketResponseData}; -use kcmc::{ImageFormat, ModelingCmd}; +use kcmc::{ + each_cmd as mcmd, + ok_response::{output::TakeSnapshot, OkModelingCmdResponse}, + websocket::{ModelingSessionData, OkWebSocketResponseData}, + ImageFormat, ModelingCmd, +}; use kittycad_modeling_cmds as kcmc; use kittycad_modeling_cmds::length_unit::LengthUnit; use parse_display::{Display, FromStr}; diff --git a/src/wasm-lib/kcl/src/std/args.rs b/src/wasm-lib/kcl/src/std/args.rs index 88efc1b0cd..68e5512c99 100644 --- a/src/wasm-lib/kcl/src/std/args.rs +++ b/src/wasm-lib/kcl/src/std/args.rs @@ -1,8 +1,7 @@ use std::any::type_name; use anyhow::Result; -use kcmc::websocket::OkWebSocketResponseData; -use kcmc::ModelingCmd; +use kcmc::{websocket::OkWebSocketResponseData, ModelingCmd}; use kittycad_modeling_cmds as kcmc; use serde::de::DeserializeOwned; @@ -166,7 +165,7 @@ impl Args { // before what ever we call next. for id in ids { // Pop it off the batch_end and add it to the batch. - let Some(item) = self.ctx.engine.batch_end().lock().unwrap().remove(&id) else { + let Some(item) = self.ctx.engine.batch_end().lock().unwrap().shift_remove(&id) else { // It might be in the batch already. continue; }; diff --git a/src/wasm-lib/kcl/src/std/array.rs b/src/wasm-lib/kcl/src/std/array.rs index 22be0efa8a..2517d10642 100644 --- a/src/wasm-lib/kcl/src/std/array.rs +++ b/src/wasm-lib/kcl/src/std/array.rs @@ -1,14 +1,13 @@ use derive_docs::stdlib; use schemars::JsonSchema; +use super::{args::FromArgs, Args, FnAsArg}; use crate::{ errors::{KclError, KclErrorDetails}, executor::{ExecState, KclValue, SketchGroup, SourceRange, UserVal}, function_param::FunctionParam, }; -use super::{args::FromArgs, Args, FnAsArg}; - /// For each item in an array, update a value. pub async fn array_reduce(exec_state: &mut ExecState, args: Args) -> Result { let (array, start, f): (Vec, SketchGroup, FnAsArg<'_>) = FromArgs::from_args(&args, 0)?; diff --git a/src/wasm-lib/kcl/src/std/chamfer.rs b/src/wasm-lib/kcl/src/std/chamfer.rs index df6399c045..e49e792b0a 100644 --- a/src/wasm-lib/kcl/src/std/chamfer.rs +++ b/src/wasm-lib/kcl/src/std/chamfer.rs @@ -2,9 +2,7 @@ use anyhow::Result; use derive_docs::stdlib; -use kcmc::each_cmd as mcmd; -use kcmc::length_unit::LengthUnit; -use kcmc::{shared::CutType, ModelingCmd}; +use kcmc::{each_cmd as mcmd, length_unit::LengthUnit, shared::CutType, ModelingCmd}; use kittycad_modeling_cmds as kcmc; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; @@ -130,7 +128,6 @@ async fn inner_chamfer( } let mut extrude_group = extrude_group.clone(); - let mut edge_cuts = Vec::new(); for edge_tag in data.tags { let edge_id = match edge_tag { EdgeReference::Uuid(uuid) => uuid, @@ -146,12 +143,15 @@ async fn inner_chamfer( radius: LengthUnit(data.length), tolerance: LengthUnit(DEFAULT_TOLERANCE), // We can let the user set this in the future. cut_type: CutType::Chamfer, + // We pass in the command id as the face id. + // So the resulting face of the fillet will be the same. + // This is because that's how most other endpoints work. face_id: Some(id), }), ) .await?; - edge_cuts.push(EdgeCut::Chamfer { + extrude_group.edge_cuts.push(EdgeCut::Chamfer { id, edge_id, length: data.length, @@ -170,7 +170,5 @@ async fn inner_chamfer( } } - extrude_group.edge_cuts = edge_cuts; - Ok(extrude_group) } diff --git a/src/wasm-lib/kcl/src/std/extrude.rs b/src/wasm-lib/kcl/src/std/extrude.rs index 652ac40c28..adb7e051d2 100644 --- a/src/wasm-lib/kcl/src/std/extrude.rs +++ b/src/wasm-lib/kcl/src/std/extrude.rs @@ -4,11 +4,10 @@ use std::collections::HashMap; use anyhow::Result; use derive_docs::stdlib; -use kcmc::each_cmd as mcmd; -use kcmc::length_unit::LengthUnit; -use kcmc::ok_response::OkModelingCmdResponse; -use kcmc::websocket::OkWebSocketResponseData; -use kcmc::{output::ExtrusionFaceInfo, shared::ExtrusionFaceCapType, ModelingCmd}; +use kcmc::{ + each_cmd as mcmd, length_unit::LengthUnit, ok_response::OkModelingCmdResponse, output::ExtrusionFaceInfo, + shared::ExtrusionFaceCapType, websocket::OkWebSocketResponseData, ModelingCmd, +}; use kittycad_modeling_cmds as kcmc; use schemars::JsonSchema; use uuid::Uuid; diff --git a/src/wasm-lib/kcl/src/std/fillet.rs b/src/wasm-lib/kcl/src/std/fillet.rs index 1abcfa69b7..f4980fda4e 100644 --- a/src/wasm-lib/kcl/src/std/fillet.rs +++ b/src/wasm-lib/kcl/src/std/fillet.rs @@ -2,11 +2,10 @@ use anyhow::Result; use derive_docs::stdlib; -use kcmc::each_cmd as mcmd; -use kcmc::length_unit::LengthUnit; -use kcmc::ok_response::OkModelingCmdResponse; -use kcmc::websocket::OkWebSocketResponseData; -use kcmc::{shared::CutType, ModelingCmd}; +use kcmc::{ + each_cmd as mcmd, length_unit::LengthUnit, ok_response::OkModelingCmdResponse, shared::CutType, + websocket::OkWebSocketResponseData, ModelingCmd, +}; use kittycad_modeling_cmds as kcmc; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; @@ -134,7 +133,6 @@ async fn inner_fillet( } let mut extrude_group = extrude_group.clone(); - let mut edge_cuts = Vec::new(); for edge_tag in data.tags { let edge_id = match edge_tag { EdgeReference::Uuid(uuid) => uuid, @@ -150,12 +148,15 @@ async fn inner_fillet( radius: LengthUnit(data.radius), tolerance: LengthUnit(data.tolerance.unwrap_or(default_tolerance(&args.ctx.settings.units))), cut_type: CutType::Fillet, - face_id: None, + // We pass in the command id as the face id. + // So the resulting face of the fillet will be the same. + // This is because that's how most other endpoints work. + face_id: Some(id), }), ) .await?; - edge_cuts.push(EdgeCut::Fillet { + extrude_group.edge_cuts.push(EdgeCut::Fillet { id, edge_id, radius: data.radius, @@ -164,7 +165,7 @@ async fn inner_fillet( if let Some(ref tag) = tag { extrude_group.value.push(ExtrudeSurface::Fillet(FilletSurface { - face_id: edge_id, + face_id: id, tag: Some(tag.clone()), geo_meta: GeoMeta { id, @@ -174,8 +175,6 @@ async fn inner_fillet( } } - extrude_group.edge_cuts = edge_cuts; - Ok(extrude_group) } diff --git a/src/wasm-lib/kcl/src/std/helix.rs b/src/wasm-lib/kcl/src/std/helix.rs index 28bc72ae6f..2b8211b6d1 100644 --- a/src/wasm-lib/kcl/src/std/helix.rs +++ b/src/wasm-lib/kcl/src/std/helix.rs @@ -2,10 +2,7 @@ use anyhow::Result; use derive_docs::stdlib; -use kcmc::each_cmd as mcmd; -use kcmc::length_unit::LengthUnit; -use kcmc::shared::Angle; -use kcmc::ModelingCmd; +use kcmc::{each_cmd as mcmd, length_unit::LengthUnit, shared::Angle, ModelingCmd}; use kittycad_modeling_cmds as kcmc; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; diff --git a/src/wasm-lib/kcl/src/std/import.rs b/src/wasm-lib/kcl/src/std/import.rs index 47e568ce61..e0fe724f40 100644 --- a/src/wasm-lib/kcl/src/std/import.rs +++ b/src/wasm-lib/kcl/src/std/import.rs @@ -4,14 +4,16 @@ use std::str::FromStr; use anyhow::Result; use derive_docs::stdlib; -use kcmc::coord::{Axis, AxisDirectionPair, Direction, System}; -use kcmc::each_cmd as mcmd; -use kcmc::format::InputFormat; -use kcmc::ok_response::OkModelingCmdResponse; -use kcmc::shared::FileImportFormat; -use kcmc::units::UnitLength; -use kcmc::websocket::OkWebSocketResponseData; -use kcmc::{ImportFile, ModelingCmd}; +use kcmc::{ + coord::{Axis, AxisDirectionPair, Direction, System}, + each_cmd as mcmd, + format::InputFormat, + ok_response::OkModelingCmdResponse, + shared::FileImportFormat, + units::UnitLength, + websocket::OkWebSocketResponseData, + ImportFile, ModelingCmd, +}; use kittycad_modeling_cmds as kcmc; use schemars::JsonSchema; diff --git a/src/wasm-lib/kcl/src/std/loft.rs b/src/wasm-lib/kcl/src/std/loft.rs index eae953be1e..4920d38faa 100644 --- a/src/wasm-lib/kcl/src/std/loft.rs +++ b/src/wasm-lib/kcl/src/std/loft.rs @@ -2,9 +2,7 @@ use anyhow::Result; use derive_docs::stdlib; -use kcmc::each_cmd as mcmd; -use kcmc::length_unit::LengthUnit; -use kcmc::ModelingCmd; +use kcmc::{each_cmd as mcmd, length_unit::LengthUnit, ModelingCmd}; use kittycad_modeling_cmds as kcmc; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; diff --git a/src/wasm-lib/kcl/src/std/patterns.rs b/src/wasm-lib/kcl/src/std/patterns.rs index 932356b178..866b9464fb 100644 --- a/src/wasm-lib/kcl/src/std/patterns.rs +++ b/src/wasm-lib/kcl/src/std/patterns.rs @@ -2,12 +2,10 @@ use anyhow::Result; use derive_docs::stdlib; -use kcmc::each_cmd as mcmd; -use kcmc::length_unit::LengthUnit; -use kcmc::ok_response::OkModelingCmdResponse; -use kcmc::shared::Transform; -use kcmc::websocket::OkWebSocketResponseData; -use kcmc::ModelingCmd; +use kcmc::{ + each_cmd as mcmd, length_unit::LengthUnit, ok_response::OkModelingCmdResponse, shared::Transform, + websocket::OkWebSocketResponseData, ModelingCmd, +}; use kittycad_modeling_cmds::{self as kcmc}; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; diff --git a/src/wasm-lib/kcl/src/std/revolve.rs b/src/wasm-lib/kcl/src/std/revolve.rs index e3264770b6..4bf525a3bb 100644 --- a/src/wasm-lib/kcl/src/std/revolve.rs +++ b/src/wasm-lib/kcl/src/std/revolve.rs @@ -2,10 +2,7 @@ use anyhow::Result; use derive_docs::stdlib; -use kcmc::each_cmd as mcmd; -use kcmc::length_unit::LengthUnit; -use kcmc::shared::Angle; -use kcmc::ModelingCmd; +use kcmc::{each_cmd as mcmd, length_unit::LengthUnit, shared::Angle, ModelingCmd}; use kittycad_modeling_cmds::{self as kcmc}; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; diff --git a/src/wasm-lib/kcl/src/std/shell.rs b/src/wasm-lib/kcl/src/std/shell.rs index 3d934c629a..69b25db941 100644 --- a/src/wasm-lib/kcl/src/std/shell.rs +++ b/src/wasm-lib/kcl/src/std/shell.rs @@ -2,9 +2,7 @@ use anyhow::Result; use derive_docs::stdlib; -use kcmc::each_cmd as mcmd; -use kcmc::length_unit::LengthUnit; -use kcmc::ModelingCmd; +use kcmc::{each_cmd as mcmd, length_unit::LengthUnit, ModelingCmd}; use kittycad_modeling_cmds as kcmc; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; diff --git a/src/wasm-lib/kcl/src/std/sketch.rs b/src/wasm-lib/kcl/src/std/sketch.rs index 2b4a272040..18e226ac05 100644 --- a/src/wasm-lib/kcl/src/std/sketch.rs +++ b/src/wasm-lib/kcl/src/std/sketch.rs @@ -4,11 +4,8 @@ use std::collections::HashMap; use anyhow::Result; use derive_docs::stdlib; -use kcmc::each_cmd as mcmd; -use kcmc::length_unit::LengthUnit; -use kcmc::shared::Angle; use kcmc::shared::Point2d as KPoint2d; // Point2d is already defined in this pkg, to impl ts_rs traits. -use kcmc::ModelingCmd; +use kcmc::{each_cmd as mcmd, length_unit::LengthUnit, shared::Angle, ModelingCmd}; use kittycad_modeling_cmds as kcmc; use kittycad_modeling_cmds::shared::PathSegment; use parse_display::{Display, FromStr}; diff --git a/src/wasm-lib/tests/executor/inputs/sketch-on-chamfer-two-times-different-order.kcl b/src/wasm-lib/tests/executor/inputs/sketch-on-chamfer-two-times-different-order.kcl new file mode 100644 index 0000000000..b1c79c80d0 --- /dev/null +++ b/src/wasm-lib/tests/executor/inputs/sketch-on-chamfer-two-times-different-order.kcl @@ -0,0 +1,48 @@ +const sketch001 = startSketchOn('XZ') + |> startProfileAt([75.8, 317.2], %) // [$startCapTag, $EndCapTag] + |> angledLine([0, 268.43], %, $rectangleSegmentA001) + |> angledLine([ + segAng(rectangleSegmentA001) - 90, + 217.26 + ], %, $seg01) + |> angledLine([ + segAng(rectangleSegmentA001), + -segLen(rectangleSegmentA001) + ], %) + |> lineTo([profileStartX(%), profileStartY(%)], %, $seg02) + |> close(%) +const extrude001 = extrude(100, sketch001) + |> fillet({ radius: 20, tags: [seg01] }, %) + |> chamfer({ + length: 50, + tags: [getOppositeEdge(seg01)] + }, %, $seg03) + |> chamfer({ length: 50, tags: [seg02] }, %, $seg04) + +const sketch003 = startSketchOn(extrude001, seg04) + |> startProfileAt([-69.1, 277.34], %) + |> angledLine([0, 41.48], %, $rectangleSegmentA003) + |> angledLine([ + segAng(rectangleSegmentA003) - 90, + 104.8 + ], %, $rectangleSegmentB002) + |> angledLine([ + segAng(rectangleSegmentA003), + -segLen(rectangleSegmentA003) + ], %, $rectangleSegmentC002) + |> lineTo([profileStartX(%), profileStartY(%)], %) + |> close(%) +const sketch002 = startSketchOn(extrude001, seg03) + |> startProfileAt([159.25, 278.35], %) + |> angledLine([0, 40.82], %, $rectangleSegmentA002) + |> angledLine([ + segAng(rectangleSegmentA002) - 90, + 132.27 + ], %, $rectangleSegmentB001) + |> angledLine([ + segAng(rectangleSegmentA002), + -segLen(rectangleSegmentA002) + ], %, $rectangleSegmentC001) + |> lineTo([profileStartX(%), profileStartY(%)], %) + |> close(%) +const extrude002 = extrude(50, sketch002) diff --git a/src/wasm-lib/tests/executor/inputs/sketch-on-chamfer-two-times.kcl b/src/wasm-lib/tests/executor/inputs/sketch-on-chamfer-two-times.kcl new file mode 100644 index 0000000000..2ab94d0113 --- /dev/null +++ b/src/wasm-lib/tests/executor/inputs/sketch-on-chamfer-two-times.kcl @@ -0,0 +1,48 @@ +const sketch001 = startSketchOn('XZ') + |> startProfileAt([75.8, 317.2], %) // [$startCapTag, $EndCapTag] + |> angledLine([0, 268.43], %, $rectangleSegmentA001) + |> angledLine([ + segAng(rectangleSegmentA001) - 90, + 217.26 + ], %, $seg01) + |> angledLine([ + segAng(rectangleSegmentA001), + -segLen(rectangleSegmentA001) + ], %) + |> lineTo([profileStartX(%), profileStartY(%)], %, $seg02) + |> close(%) +const extrude001 = extrude(100, sketch001) + |> fillet({ radius: 20, tags: [seg01] }, %) + |> chamfer({ length: 50, tags: [seg02] }, %, $seg04) + |> chamfer({ + length: 50, + tags: [getOppositeEdge(seg01)] + }, %, $seg03) + +const sketch003 = startSketchOn(extrude001, seg04) + |> startProfileAt([-69.1, 277.34], %) + |> angledLine([0, 41.48], %, $rectangleSegmentA003) + |> angledLine([ + segAng(rectangleSegmentA003) - 90, + 104.8 + ], %, $rectangleSegmentB002) + |> angledLine([ + segAng(rectangleSegmentA003), + -segLen(rectangleSegmentA003) + ], %, $rectangleSegmentC002) + |> lineTo([profileStartX(%), profileStartY(%)], %) + |> close(%) +const sketch002 = startSketchOn(extrude001, seg03) + |> startProfileAt([159.25, 278.35], %) + |> angledLine([0, 40.82], %, $rectangleSegmentA002) + |> angledLine([ + segAng(rectangleSegmentA002) - 90, + 132.27 + ], %, $rectangleSegmentB001) + |> angledLine([ + segAng(rectangleSegmentA002), + -segLen(rectangleSegmentA002) + ], %, $rectangleSegmentC001) + |> lineTo([profileStartX(%), profileStartY(%)], %) + |> close(%) +const extrude002 = extrude(50, sketch002) diff --git a/src/wasm-lib/tests/executor/outputs/sketch-on-chamfer-two-times-different-order.png b/src/wasm-lib/tests/executor/outputs/sketch-on-chamfer-two-times-different-order.png new file mode 100644 index 0000000000..d0c26c126b Binary files /dev/null and b/src/wasm-lib/tests/executor/outputs/sketch-on-chamfer-two-times-different-order.png differ diff --git a/src/wasm-lib/tests/executor/outputs/sketch-on-chamfer-two-times.png b/src/wasm-lib/tests/executor/outputs/sketch-on-chamfer-two-times.png new file mode 100644 index 0000000000..d0c26c126b Binary files /dev/null and b/src/wasm-lib/tests/executor/outputs/sketch-on-chamfer-two-times.png differ diff --git a/src/wasm-lib/tests/executor/visuals.rs b/src/wasm-lib/tests/executor/visuals.rs index 13cf9638b8..14b0d9238f 100644 --- a/src/wasm-lib/tests/executor/visuals.rs +++ b/src/wasm-lib/tests/executor/visuals.rs @@ -57,3 +57,8 @@ kcl_test!("lego", kcl_test_lego); kcl_test!("riddle_small", kcl_test_riddle_small); kcl_test!("tan_arc_x_line", kcl_test_tan_arc_x_line); kcl_test!("fillet-and-shell", kcl_test_fillet_and_shell); +kcl_test!("sketch-on-chamfer-two-times", kcl_test_sketch_on_chamfer_two_times); +kcl_test!( + "sketch-on-chamfer-two-times-different-order", + kcl_test_sketch_on_chamfer_two_times_different_order +); diff --git a/src/wasm-lib/tests/modify/main.rs b/src/wasm-lib/tests/modify/main.rs index cacc0612bd..5b8868c486 100644 --- a/src/wasm-lib/tests/modify/main.rs +++ b/src/wasm-lib/tests/modify/main.rs @@ -3,9 +3,7 @@ use kcl_lib::{ ast::{modify::modify_ast_for_sketch, types::Program}, executor::{ExecutorContext, KclValue, PlaneType, SketchGroup, SourceRange}, }; -use kittycad_modeling_cmds::shared::Point3d; -use kittycad_modeling_cmds::ModelingCmd; -use kittycad_modeling_cmds::{each_cmd as mcmd, length_unit::LengthUnit}; +use kittycad_modeling_cmds::{each_cmd as mcmd, length_unit::LengthUnit, shared::Point3d, ModelingCmd}; use pretty_assertions::assert_eq; /// Setup the engine and parse code for an ast.