WIP: Send engine the extruded face IDs
This commit is contained in:
		
							
								
								
									
										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
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -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