Compare commits
	
		
			2 Commits
		
	
	
		
			revert-580
			...
			achalmers/
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 98dae3aa9a | |||
| 52dc8842f7 | 
							
								
								
									
										4
									
								
								src/wasm-lib/Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										4
									
								
								src/wasm-lib/Cargo.lock
									
									
									
										generated
									
									
									
								
							| @ -1819,9 +1819,9 @@ dependencies = [ | ||||
|  | ||||
| [[package]] | ||||
| name = "kittycad-modeling-cmds" | ||||
| version = "0.2.79" | ||||
| version = "0.2.82" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "10a9cab4476455be70ea57643c31444068b056d091bd348cab6044c0d8ad7fcc" | ||||
| checksum = "e209a26f2ef14afbb25de6a4641bc899e8468a62ae30c6c40d3a2840c7a6ce76" | ||||
| dependencies = [ | ||||
|  "anyhow", | ||||
|  "chrono", | ||||
|  | ||||
| @ -76,7 +76,7 @@ members = [ | ||||
| [workspace.dependencies] | ||||
| http = "1" | ||||
| kittycad = { version = "0.3.28", default-features = false, features = ["js", "requests"] } | ||||
| kittycad-modeling-cmds = { version = "0.2.79", features = ["websocket"] } | ||||
| kittycad-modeling-cmds = { version = "0.2.82", features = ["websocket"] } | ||||
|  | ||||
| [workspace.lints.clippy] | ||||
| assertions_on_result_states = "warn" | ||||
|  | ||||
| @ -31,3 +31,5 @@ new-sim-test test_name render_to_png="true": | ||||
|     {{cita}} -p kcl-lib -- simulation_tests::{{test_name}}::unparse | ||||
|     TWENTY_TWENTY=overwrite {{cita}} -p kcl-lib -- tests::{{test_name}}::kcl_test_execute | ||||
|  | ||||
| bench-lego: | ||||
|     cargo criterion -p kcl-lib --bench executor_benchmark_criterion -- lego | ||||
|  | ||||
| @ -265,6 +265,7 @@ pub trait EngineManager: std::fmt::Debug + Send + Sync + 'static { | ||||
|             }) | ||||
|             .collect(); | ||||
|  | ||||
|         dbg!(&requests); | ||||
|         let batched_requests = WebSocketRequest::ModelingCmdBatchReq(ModelingBatch { | ||||
|             requests, | ||||
|             batch_id: uuid::Uuid::new_v4().into(), | ||||
|  | ||||
| @ -8,7 +8,10 @@ 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 kittycad_modeling_cmds::{ | ||||
|     self as kcmc, | ||||
|     shared::{ExtrudedFaceInfo, SideFace}, | ||||
| }; | ||||
| use uuid::Uuid; | ||||
|  | ||||
| use crate::{ | ||||
| @ -108,12 +111,27 @@ async fn inner_extrude( | ||||
|         ) | ||||
|         .await?; | ||||
|  | ||||
|         // Choose IDs for the new faces that will be created when extruding. | ||||
|         let _sketch_is_on_face = matches!(sketch.on, SketchSurface::Face(_)); | ||||
|         let new_faces = ExtrudedFaceInfo { | ||||
|             bottom: Some(exec_state.id_generator.next_uuid()), | ||||
|             top: exec_state.id_generator.next_uuid(), | ||||
|             sides: sketch | ||||
|                 .paths | ||||
|                 .iter() | ||||
|                 .map(|path| SideFace { | ||||
|                     path_id: path.get_id(), | ||||
|                     face_id: exec_state.id_generator.next_uuid(), | ||||
|                 }) | ||||
|                 .collect(), | ||||
|         }; | ||||
|  | ||||
|         args.batch_modeling_cmd( | ||||
|             id, | ||||
|             ModelingCmd::from(mcmd::Extrude { | ||||
|                 target: sketch.id.into(), | ||||
|                 distance: LengthUnit(length), | ||||
|                 faces: Default::default(), | ||||
|                 faces: Some(new_faces.clone()), | ||||
|             }), | ||||
|         ) | ||||
|         .await?; | ||||
| @ -124,7 +142,7 @@ async fn inner_extrude( | ||||
|             ModelingCmd::SketchModeDisable(mcmd::SketchModeDisable {}), | ||||
|         ) | ||||
|         .await?; | ||||
|         solids.push(do_post_extrude(sketch.clone(), length, exec_state, args.clone()).await?); | ||||
|         solids.push(do_post_extrude(sketch.clone(), length, Some(new_faces), exec_state, args.clone()).await?); | ||||
|     } | ||||
|  | ||||
|     Ok(solids.into()) | ||||
| @ -133,6 +151,7 @@ async fn inner_extrude( | ||||
| pub(crate) async fn do_post_extrude( | ||||
|     sketch: Sketch, | ||||
|     length: f64, | ||||
|     new_faces: Option<ExtrudedFaceInfo>, | ||||
|     exec_state: &mut ExecState, | ||||
|     args: Args, | ||||
| ) -> Result<Box<Solid>, KclError> { | ||||
| @ -160,60 +179,65 @@ pub(crate) async fn do_post_extrude( | ||||
|         sketch.id = face.solid.sketch.id; | ||||
|     } | ||||
|  | ||||
|     let solid3d_info = args | ||||
|         .send_modeling_cmd( | ||||
|             exec_state.id_generator.next_uuid(), | ||||
|             ModelingCmd::from(mcmd::Solid3dGetExtrusionFaceInfo { | ||||
|                 edge_id: any_edge_id, | ||||
|                 object_id: sketch.id, | ||||
|             }), | ||||
|         ) | ||||
|         .await?; | ||||
|     let face_infos = match new_faces { | ||||
|         Some(new_faces) => new_faces.list_faces(), | ||||
|         None => { | ||||
|             let solid3d_info = args | ||||
|                 .send_modeling_cmd( | ||||
|                     exec_state.id_generator.next_uuid(), | ||||
|                     ModelingCmd::from(mcmd::Solid3dGetExtrusionFaceInfo { | ||||
|                         edge_id: any_edge_id, | ||||
|                         object_id: sketch.id, | ||||
|                     }), | ||||
|                 ) | ||||
|                 .await?; | ||||
|  | ||||
|     let face_infos = if let OkWebSocketResponseData::Modeling { | ||||
|         modeling_response: OkModelingCmdResponse::Solid3dGetExtrusionFaceInfo(data), | ||||
|     } = solid3d_info | ||||
|     { | ||||
|         data.faces | ||||
|     } else { | ||||
|         vec![] | ||||
|     }; | ||||
|  | ||||
|     for (curve_id, face_id) in face_infos | ||||
|         .iter() | ||||
|         .filter(|face_info| face_info.cap == ExtrusionFaceCapType::None) | ||||
|         .filter_map(|face_info| { | ||||
|             if let (Some(curve_id), Some(face_id)) = (face_info.curve_id, face_info.face_id) { | ||||
|                 Some((curve_id, face_id)) | ||||
|             let face_infos: Vec<ExtrusionFaceInfo> = if let OkWebSocketResponseData::Modeling { | ||||
|                 modeling_response: OkModelingCmdResponse::Solid3dGetExtrusionFaceInfo(data), | ||||
|             } = solid3d_info | ||||
|             { | ||||
|                 data.faces | ||||
|             } else { | ||||
|                 None | ||||
|             } | ||||
|         }) | ||||
|     { | ||||
|         // Batch these commands, because the Rust code doesn't actually care about the outcome. | ||||
|         // So, there's no need to await them. | ||||
|         // Instead, the Typescript codebases (which handles WebSocket sends when compiled via Wasm) | ||||
|         // uses this to build the artifact graph, which the UI needs. | ||||
|         args.batch_modeling_cmd( | ||||
|             exec_state.id_generator.next_uuid(), | ||||
|             ModelingCmd::from(mcmd::Solid3dGetOppositeEdge { | ||||
|                 edge_id: curve_id, | ||||
|                 object_id: sketch.id, | ||||
|                 face_id, | ||||
|             }), | ||||
|         ) | ||||
|         .await?; | ||||
|                 vec![] | ||||
|             }; | ||||
|             for (curve_id, face_id) in face_infos | ||||
|                 .iter() | ||||
|                 .filter(|face_info| face_info.cap == ExtrusionFaceCapType::None) | ||||
|                 .filter_map(|face_info| { | ||||
|                     if let (Some(curve_id), Some(face_id)) = (face_info.curve_id, face_info.face_id) { | ||||
|                         Some((curve_id, face_id)) | ||||
|                     } else { | ||||
|                         None | ||||
|                     } | ||||
|                 }) | ||||
|             { | ||||
|                 // Batch these commands, because the Rust code doesn't actually care about the outcome. | ||||
|                 // So, there's no need to await them. | ||||
|                 // Instead, the Typescript codebases (which handles WebSocket sends when compiled via Wasm) | ||||
|                 // uses this to build the artifact graph, which the UI needs. | ||||
|                 args.batch_modeling_cmd( | ||||
|                     exec_state.id_generator.next_uuid(), | ||||
|                     ModelingCmd::from(mcmd::Solid3dGetOppositeEdge { | ||||
|                         edge_id: curve_id, | ||||
|                         object_id: sketch.id, | ||||
|                         face_id, | ||||
|                     }), | ||||
|                 ) | ||||
|                 .await?; | ||||
|  | ||||
|         args.batch_modeling_cmd( | ||||
|             exec_state.id_generator.next_uuid(), | ||||
|             ModelingCmd::from(mcmd::Solid3dGetNextAdjacentEdge { | ||||
|                 edge_id: curve_id, | ||||
|                 object_id: sketch.id, | ||||
|                 face_id, | ||||
|             }), | ||||
|         ) | ||||
|         .await?; | ||||
|     } | ||||
|                 args.batch_modeling_cmd( | ||||
|                     exec_state.id_generator.next_uuid(), | ||||
|                     ModelingCmd::from(mcmd::Solid3dGetNextAdjacentEdge { | ||||
|                         edge_id: curve_id, | ||||
|                         object_id: sketch.id, | ||||
|                         face_id, | ||||
|                     }), | ||||
|                 ) | ||||
|                 .await?; | ||||
|             } | ||||
|             face_infos | ||||
|         } | ||||
|     }; | ||||
|  | ||||
|     let Faces { | ||||
|         sides: face_id_map, | ||||
|  | ||||
| @ -155,5 +155,5 @@ async fn inner_loft( | ||||
|     .await?; | ||||
|  | ||||
|     // Using the first sketch as the base curve, idk we might want to change this later. | ||||
|     do_post_extrude(sketches[0].clone(), 0.0, exec_state, args).await | ||||
|     do_post_extrude(sketches[0].clone(), 0.0, None, exec_state, args).await | ||||
| } | ||||
|  | ||||
| @ -295,7 +295,7 @@ async fn inner_revolve( | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     do_post_extrude(sketch, 0.0, exec_state, args).await | ||||
|     do_post_extrude(sketch, 0.0, None, exec_state, args).await | ||||
| } | ||||
|  | ||||
| #[cfg(test)] | ||||
|  | ||||
| @ -98,5 +98,5 @@ async fn inner_sweep( | ||||
|     ) | ||||
|     .await?; | ||||
|  | ||||
|     do_post_extrude(sketch, 0.0, exec_state, args).await | ||||
|     do_post_extrude(sketch, 0.0, None, exec_state, args).await | ||||
| } | ||||
|  | ||||
| @ -1,36 +1,36 @@ | ||||
| // 2x8 Lego Brick | ||||
| // A standard Lego brick with 2 bumps wide and 8 bumps long. | ||||
| // Define constants | ||||
| const lbumps = 10 // number of bumps long | ||||
| const wbumps = {{N}} // number of bumps wide | ||||
| const pitch = 8.0 | ||||
| const clearance = 0.1 | ||||
| const bumpDiam = 4.8 | ||||
| const bumpHeight = 1.8 | ||||
| const height = 9.6 | ||||
| const t = (pitch - (2 * clearance) - bumpDiam) / 2.0 | ||||
| const totalLength = lbumps * pitch - (2.0 * clearance) | ||||
| const totalWidth = wbumps * pitch - (2.0 * clearance) | ||||
| lbumps = 10 // number of bumps long | ||||
| wbumps = {{N}} // number of bumps wide | ||||
| pitch = 8.0 | ||||
| clearance = 0.1 | ||||
| bumpDiam = 4.8 | ||||
| bumpHeight = 1.8 | ||||
| height = 9.6 | ||||
| t = (pitch - (2 * clearance) - bumpDiam) / 2.0 | ||||
| totalLength = lbumps * pitch - (2.0 * clearance) | ||||
| totalWidth = wbumps * pitch - (2.0 * clearance) | ||||
| // Create the plane for the pegs. This is a hack so that the pegs can be patterned along the face of the lego base. | ||||
| const pegFace = { | ||||
|   plane: { | ||||
|     origin: { x: 0, y: 0, z: height }, | ||||
|     xAxis: { x: 1, y: 0, z: 0 }, | ||||
|     yAxis: { x: 0, y: 1, z: 0 }, | ||||
|     zAxis: { x: 0, y: 0, z: 1 } | ||||
| pegFace = { | ||||
|   plane = { | ||||
|     origin = { x = 0, y = 0, z = height }, | ||||
|     xAxis = { x = 1, y = 0, z = 0 }, | ||||
|     yAxis = { x = 0, y = 1, z = 0 }, | ||||
|     zAxis = { x = 0, y = 0, z = 1 } | ||||
|   } | ||||
| } | ||||
| // Create the plane for the tubes underneath the lego. This is a hack so that the tubes can be patterned underneath the lego. | ||||
| const tubeFace = { | ||||
|     plane: { | ||||
|     origin: { x: 0, y: 0, z: height - t }, | ||||
|     xAxis: { x: 1, y: 0, z: 0 }, | ||||
|     yAxis: { x: 0, y: 1, z: 0 }, | ||||
|     zAxis: { x: 0, y: 0, z: 1 } | ||||
| tubeFace = { | ||||
|   plane = { | ||||
|     origin = { x = 0, y = 0, z = height - t }, | ||||
|     xAxis = { x = 1, y = 0, z = 0 }, | ||||
|     yAxis = { x = 0, y = 1, z = 0 }, | ||||
|     zAxis = { x = 0, y = 0, z = 1 } | ||||
|   } | ||||
| } | ||||
| // Make the base | ||||
| const s = startSketchOn('XY') | ||||
| s = startSketchOn('XY') | ||||
|   |> startProfileAt([-totalWidth / 2, -totalLength / 2], %) | ||||
|   |> line([totalWidth, 0], %) | ||||
|   |> line([0, totalLength], %) | ||||
| @ -39,7 +39,7 @@ const s = startSketchOn('XY') | ||||
|   |> extrude(height, %) | ||||
|  | ||||
| // Sketch and extrude a rectangular shape to create the shell underneath the lego. This is a hack until we have a shell function. | ||||
| const shellExtrude = startSketchOn(s, "start") | ||||
| shellExtrude = startSketchOn(s, "start") | ||||
|   |> startProfileAt([ | ||||
|        -(totalWidth / 2 - t), | ||||
|        -(totalLength / 2 - t) | ||||
| @ -50,32 +50,33 @@ const shellExtrude = startSketchOn(s, "start") | ||||
|   |> close(%) | ||||
|   |> extrude(-(height - t), %) | ||||
|  | ||||
| fn tr = (i) => { | ||||
|   let j = i + 1 | ||||
|   let x = (j/wbumps) * pitch | ||||
|   let y = (j % wbumps) * pitch | ||||
|   return { | ||||
|     translate: [x, y, 0], | ||||
|   } | ||||
| fn tr(i) { | ||||
|   j = i + 1 | ||||
|   x = j / wbumps * pitch | ||||
|   y = j % wbumps * pitch | ||||
|   return { translate = [x, y, 0] } | ||||
| } | ||||
|  | ||||
| // Create the pegs on the top of the base | ||||
| const totalBumps = (wbumps * lbumps)-1 | ||||
| const peg = startSketchOn(s, 'end') | ||||
|   |> circle({ center: [ | ||||
|        -(pitch*(wbumps-1)/2), | ||||
|        -(pitch*(lbumps-1)/2) | ||||
|      ], radius: bumpDiam / 2 }, %) | ||||
|   |> patternLinear2d({ | ||||
|        axis: [1, 0], | ||||
|        instances: wbumps, | ||||
|        distance: pitch | ||||
| totalBumps = wbumps * lbumps - 1 | ||||
| peg = startSketchOn(s, 'end') | ||||
|   |> circle({ | ||||
|        center = [ | ||||
|          -(pitch * (wbumps - 1) / 2), | ||||
|          -(pitch * (lbumps - 1) / 2) | ||||
|        ], | ||||
|        radius = bumpDiam / 2 | ||||
|      }, %) | ||||
|   |> patternLinear2d({ | ||||
|        axis: [0, 1], | ||||
|        instances: lbumps, | ||||
|        distance: pitch | ||||
|        axis = [1, 0], | ||||
|        instances = wbumps, | ||||
|        distance = pitch | ||||
|      }, %) | ||||
|   |> patternLinear2d({ | ||||
|        axis = [0, 1], | ||||
|        instances = lbumps, | ||||
|        distance = pitch | ||||
|      }, %) | ||||
|   |> extrude(bumpHeight, %) | ||||
|   // |> patternTransform(int(totalBumps-1), tr, %) | ||||
| // |> patternTransform(int(totalBumps-1), tr, %) | ||||
|  | ||||
|  | ||||
| @ -62,6 +62,16 @@ async fn kcl_test_execute_i_shape() { | ||||
|     assert_out("i_shape", &result); | ||||
| } | ||||
|  | ||||
| #[tokio::test(flavor = "multi_thread")] | ||||
| async fn kcl_test_execute_slow_lego() { | ||||
|     // This is some code from lee that starts a pipe expression with a variable. | ||||
|     let code = include_str!("inputs/slow_lego.kcl.tmpl"); | ||||
|     let code = code.replace("{{N}}", "1"); | ||||
|  | ||||
|     let result = execute_and_snapshot(&code, UnitLength::Mm, None).await.unwrap(); | ||||
|     assert_out("i_shape", &result); | ||||
| } | ||||
|  | ||||
| #[tokio::test(flavor = "multi_thread")] | ||||
| #[ignore] // No longer a stack overflow problem, instead it causes an engine internal error. | ||||
| async fn kcl_test_execute_pipes_on_pipes() { | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	