use face edge info for some mirrors (#7174)
* use face edge info for some mirrors
* add functionality for other mirror function
* Fix to create new Sketch when mirror results in a new path
* use the original ids and clone the sketches
* remove mirror param
* clippy fix
* debuggin, rm yarn
* Revert "remove mirror param"
This reverts commit a848e243f8.
* use arrbitrary edge_id as sketch mirror id
* additinoal clenaup
* Update rust/kcl-lib/src/std/mirror.rs
Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
* set .mirror for continuous case
* fix warning
* works without the for loops
* add error handling
* remove duplicate setter
* rm unused var
* clenaup
* unused import
* remove unused let
* Update snapshots
* Update snapshots
* cleanup
* update sim tests
---------
Co-authored-by: gserena <serena@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
			
			
| 
		 Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 52 KiB  | 
| 
		 Before Width: | Height: | Size: 58 KiB After Width: | Height: | Size: 58 KiB  | 
| 
		 Before Width: | Height: | Size: 83 KiB After Width: | Height: | Size: 83 KiB  | 
@ -175,10 +175,10 @@ pub(crate) async fn do_post_extrude<'a>(
 | 
			
		||||
        )
 | 
			
		||||
        .await?;
 | 
			
		||||
 | 
			
		||||
    let any_edge_id = if let Some(id) = edge_id {
 | 
			
		||||
        id
 | 
			
		||||
    } else if let Some(edge_id) = sketch.mirror {
 | 
			
		||||
    let any_edge_id = if let Some(edge_id) = sketch.mirror {
 | 
			
		||||
        edge_id
 | 
			
		||||
    } else if let Some(id) = edge_id {
 | 
			
		||||
        id
 | 
			
		||||
    } else {
 | 
			
		||||
        // The "get extrusion face info" API call requires *any* edge on the sketch being extruded.
 | 
			
		||||
        // So, let's just use the first one.
 | 
			
		||||
 | 
			
		||||
@ -3,8 +3,8 @@
 | 
			
		||||
use anyhow::Result;
 | 
			
		||||
use kcmc::{each_cmd as mcmd, ModelingCmd};
 | 
			
		||||
use kittycad_modeling_cmds::{
 | 
			
		||||
    self as kcmc, length_unit::LengthUnit, ok_response::OkModelingCmdResponse, output::EntityGetAllChildUuids,
 | 
			
		||||
    shared::Point3d, websocket::OkWebSocketResponseData,
 | 
			
		||||
    self as kcmc, length_unit::LengthUnit, ok_response::OkModelingCmdResponse, shared::Point3d,
 | 
			
		||||
    websocket::OkWebSocketResponseData,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
use crate::{
 | 
			
		||||
@ -41,19 +41,14 @@ async fn inner_mirror_2d(
 | 
			
		||||
) -> Result<Vec<Sketch>, KclError> {
 | 
			
		||||
    let mut starting_sketches = sketches.clone();
 | 
			
		||||
 | 
			
		||||
    // Update all to have a mirror.
 | 
			
		||||
    starting_sketches.iter_mut().for_each(|sketch| {
 | 
			
		||||
        sketch.mirror = Some(exec_state.next_uuid());
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    if args.ctx.no_engine_commands().await {
 | 
			
		||||
        return Ok(starting_sketches);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    match axis {
 | 
			
		||||
        Axis2dOrEdgeReference::Axis { direction, origin } => {
 | 
			
		||||
            exec_state
 | 
			
		||||
                .batch_modeling_cmd(
 | 
			
		||||
            let resp = exec_state
 | 
			
		||||
                .send_modeling_cmd(
 | 
			
		||||
                    (&args).into(),
 | 
			
		||||
                    ModelingCmd::from(mcmd::EntityMirror {
 | 
			
		||||
                        ids: starting_sketches.iter().map(|sketch| sketch.id).collect(),
 | 
			
		||||
@ -70,12 +65,42 @@ async fn inner_mirror_2d(
 | 
			
		||||
                    }),
 | 
			
		||||
                )
 | 
			
		||||
                .await?;
 | 
			
		||||
 | 
			
		||||
            if let OkWebSocketResponseData::Modeling {
 | 
			
		||||
                modeling_response: OkModelingCmdResponse::EntityMirror(mirror_info),
 | 
			
		||||
            } = &resp
 | 
			
		||||
            {
 | 
			
		||||
                let face_edge_info = &mirror_info.entity_face_edge_ids;
 | 
			
		||||
 | 
			
		||||
                starting_sketches
 | 
			
		||||
                    .iter_mut()
 | 
			
		||||
                    .zip(face_edge_info.iter())
 | 
			
		||||
                    .try_for_each(|(sketch, info)| {
 | 
			
		||||
                        sketch.id = info.object_id;
 | 
			
		||||
                        let first_edge = info.edges.first().copied();
 | 
			
		||||
                        match first_edge {
 | 
			
		||||
                            Some(edge) => sketch.mirror = Some(edge),
 | 
			
		||||
                            None => {
 | 
			
		||||
                                return Err(KclError::new_engine(KclErrorDetails::new(
 | 
			
		||||
                                    "No edges found in mirror info".to_string(),
 | 
			
		||||
                                    vec![args.source_range],
 | 
			
		||||
                                )))
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                        Ok(())
 | 
			
		||||
                    })?;
 | 
			
		||||
            } else {
 | 
			
		||||
                return Err(KclError::new_engine(KclErrorDetails::new(
 | 
			
		||||
                    format!("EntityMirror response was not as expected: {:?}", resp),
 | 
			
		||||
                    vec![args.source_range],
 | 
			
		||||
                )));
 | 
			
		||||
            };
 | 
			
		||||
        }
 | 
			
		||||
        Axis2dOrEdgeReference::Edge(edge) => {
 | 
			
		||||
            let edge_id = edge.get_engine_id(exec_state, &args)?;
 | 
			
		||||
 | 
			
		||||
            exec_state
 | 
			
		||||
                .batch_modeling_cmd(
 | 
			
		||||
            let resp = exec_state
 | 
			
		||||
                .send_modeling_cmd(
 | 
			
		||||
                    (&args).into(),
 | 
			
		||||
                    ModelingCmd::from(mcmd::EntityMirrorAcrossEdge {
 | 
			
		||||
                        ids: starting_sketches.iter().map(|sketch| sketch.id).collect(),
 | 
			
		||||
@ -83,41 +108,36 @@ async fn inner_mirror_2d(
 | 
			
		||||
                    }),
 | 
			
		||||
                )
 | 
			
		||||
                .await?;
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    // After the mirror, get the first child uuid for the path.
 | 
			
		||||
    // The "get extrusion face info" API call requires *any* edge on the sketch being extruded.
 | 
			
		||||
    // But if you mirror2d a sketch these IDs might change so we need to get the children versus
 | 
			
		||||
    // using the IDs we already have.
 | 
			
		||||
    // We only do this with mirrors because otherwise it is a waste of a websocket call.
 | 
			
		||||
    for sketch in &mut starting_sketches {
 | 
			
		||||
        let response = exec_state
 | 
			
		||||
            .send_modeling_cmd(
 | 
			
		||||
                (&args).into(),
 | 
			
		||||
                ModelingCmd::from(mcmd::EntityGetAllChildUuids { entity_id: sketch.id }),
 | 
			
		||||
            )
 | 
			
		||||
            .await?;
 | 
			
		||||
        let OkWebSocketResponseData::Modeling {
 | 
			
		||||
            modeling_response:
 | 
			
		||||
                OkModelingCmdResponse::EntityGetAllChildUuids(EntityGetAllChildUuids { entity_ids: child_ids }),
 | 
			
		||||
        } = response
 | 
			
		||||
        else {
 | 
			
		||||
            return Err(KclError::new_internal(KclErrorDetails::new(
 | 
			
		||||
                "Expected a successful response from EntityGetAllChildUuids".to_string(),
 | 
			
		||||
                vec![args.source_range],
 | 
			
		||||
            )));
 | 
			
		||||
        };
 | 
			
		||||
            if let OkWebSocketResponseData::Modeling {
 | 
			
		||||
                modeling_response: OkModelingCmdResponse::EntityMirrorAcrossEdge(mirror_info),
 | 
			
		||||
            } = &resp
 | 
			
		||||
            {
 | 
			
		||||
                let face_edge_info = &mirror_info.entity_face_edge_ids;
 | 
			
		||||
 | 
			
		||||
        if child_ids.len() >= 2 {
 | 
			
		||||
            // The first child is the original sketch, the second is the mirrored sketch.
 | 
			
		||||
            let child_id = child_ids[1];
 | 
			
		||||
            sketch.mirror = Some(child_id);
 | 
			
		||||
        } else {
 | 
			
		||||
            return Err(KclError::new_type(KclErrorDetails::new(
 | 
			
		||||
                "Expected child uuids to be >= 2".to_string(),
 | 
			
		||||
                vec![args.source_range],
 | 
			
		||||
            )));
 | 
			
		||||
                starting_sketches
 | 
			
		||||
                    .iter_mut()
 | 
			
		||||
                    .zip(face_edge_info.iter())
 | 
			
		||||
                    .try_for_each(|(sketch, info)| {
 | 
			
		||||
                        sketch.id = info.object_id;
 | 
			
		||||
                        let first_edge = info.edges.first().copied();
 | 
			
		||||
                        match first_edge {
 | 
			
		||||
                            Some(edge) => sketch.mirror = Some(edge),
 | 
			
		||||
                            None => {
 | 
			
		||||
                                return Err(KclError::new_engine(KclErrorDetails::new(
 | 
			
		||||
                                    "No edges found in mirror info".to_string(),
 | 
			
		||||
                                    vec![args.source_range],
 | 
			
		||||
                                )))
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                        Ok(())
 | 
			
		||||
                    })?;
 | 
			
		||||
            } else {
 | 
			
		||||
                return Err(KclError::new_engine(KclErrorDetails::new(
 | 
			
		||||
                    format!("EntityMirrorAcrossEdge response was not as expected: {:?}", resp),
 | 
			
		||||
                    vec![args.source_range],
 | 
			
		||||
                )));
 | 
			
		||||
            };
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
		 Before Width: | Height: | Size: 83 KiB After Width: | Height: | Size: 83 KiB  | 
@ -148,14 +148,6 @@ description: Artifact commands bottle.kcl
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "cmdId": "[uuid]",
 | 
			
		||||
      "range": [],
 | 
			
		||||
      "command": {
 | 
			
		||||
        "type": "entity_get_all_child_uuids",
 | 
			
		||||
        "entity_id": "[uuid]"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "cmdId": "[uuid]",
 | 
			
		||||
      "range": [],
 | 
			
		||||
 | 
			
		||||
@ -327,14 +327,6 @@ description: Artifact commands cold-plate.kcl
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "cmdId": "[uuid]",
 | 
			
		||||
      "range": [],
 | 
			
		||||
      "command": {
 | 
			
		||||
        "type": "entity_get_all_child_uuids",
 | 
			
		||||
        "entity_id": "[uuid]"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "cmdId": "[uuid]",
 | 
			
		||||
      "range": [],
 | 
			
		||||
 | 
			
		||||
@ -4828,14 +4828,6 @@ description: Artifact commands cpu-cooler.kcl
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "cmdId": "[uuid]",
 | 
			
		||||
      "range": [],
 | 
			
		||||
      "command": {
 | 
			
		||||
        "type": "entity_get_all_child_uuids",
 | 
			
		||||
        "entity_id": "[uuid]"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "cmdId": "[uuid]",
 | 
			
		||||
      "range": [],
 | 
			
		||||
@ -4856,14 +4848,6 @@ description: Artifact commands cpu-cooler.kcl
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "cmdId": "[uuid]",
 | 
			
		||||
      "range": [],
 | 
			
		||||
      "command": {
 | 
			
		||||
        "type": "entity_get_all_child_uuids",
 | 
			
		||||
        "entity_id": "[uuid]"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "cmdId": "[uuid]",
 | 
			
		||||
      "range": [],
 | 
			
		||||
@ -6095,14 +6079,6 @@ description: Artifact commands cpu-cooler.kcl
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "cmdId": "[uuid]",
 | 
			
		||||
      "range": [],
 | 
			
		||||
      "command": {
 | 
			
		||||
        "type": "entity_get_all_child_uuids",
 | 
			
		||||
        "entity_id": "[uuid]"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "cmdId": "[uuid]",
 | 
			
		||||
      "range": [],
 | 
			
		||||
@ -6436,14 +6412,6 @@ description: Artifact commands cpu-cooler.kcl
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "cmdId": "[uuid]",
 | 
			
		||||
      "range": [],
 | 
			
		||||
      "command": {
 | 
			
		||||
        "type": "entity_get_all_child_uuids",
 | 
			
		||||
        "entity_id": "[uuid]"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "cmdId": "[uuid]",
 | 
			
		||||
      "range": [],
 | 
			
		||||
 | 
			
		||||
@ -1136,14 +1136,6 @@ description: Artifact commands helium-tank.kcl
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "cmdId": "[uuid]",
 | 
			
		||||
      "range": [],
 | 
			
		||||
      "command": {
 | 
			
		||||
        "type": "entity_get_all_child_uuids",
 | 
			
		||||
        "entity_id": "[uuid]"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "cmdId": "[uuid]",
 | 
			
		||||
      "range": [],
 | 
			
		||||
@ -1362,14 +1354,6 @@ description: Artifact commands helium-tank.kcl
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "cmdId": "[uuid]",
 | 
			
		||||
      "range": [],
 | 
			
		||||
      "command": {
 | 
			
		||||
        "type": "entity_get_all_child_uuids",
 | 
			
		||||
        "entity_id": "[uuid]"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "cmdId": "[uuid]",
 | 
			
		||||
      "range": [],
 | 
			
		||||
 | 
			
		||||
@ -176,14 +176,6 @@ description: Artifact commands i-beam.kcl
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "cmdId": "[uuid]",
 | 
			
		||||
      "range": [],
 | 
			
		||||
      "command": {
 | 
			
		||||
        "type": "entity_get_all_child_uuids",
 | 
			
		||||
        "entity_id": "[uuid]"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "cmdId": "[uuid]",
 | 
			
		||||
      "range": [],
 | 
			
		||||
@ -204,14 +196,6 @@ description: Artifact commands i-beam.kcl
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "cmdId": "[uuid]",
 | 
			
		||||
      "range": [],
 | 
			
		||||
      "command": {
 | 
			
		||||
        "type": "entity_get_all_child_uuids",
 | 
			
		||||
        "entity_id": "[uuid]"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "cmdId": "[uuid]",
 | 
			
		||||
      "range": [],
 | 
			
		||||
 | 
			
		||||
@ -342,14 +342,6 @@ description: Artifact commands t-slot-rail.kcl
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "cmdId": "[uuid]",
 | 
			
		||||
      "range": [],
 | 
			
		||||
      "command": {
 | 
			
		||||
        "type": "entity_get_all_child_uuids",
 | 
			
		||||
        "entity_id": "[uuid]"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "cmdId": "[uuid]",
 | 
			
		||||
      "range": [],
 | 
			
		||||
@ -370,14 +362,6 @@ description: Artifact commands t-slot-rail.kcl
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "cmdId": "[uuid]",
 | 
			
		||||
      "range": [],
 | 
			
		||||
      "command": {
 | 
			
		||||
        "type": "entity_get_all_child_uuids",
 | 
			
		||||
        "entity_id": "[uuid]"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "cmdId": "[uuid]",
 | 
			
		||||
      "range": [],
 | 
			
		||||
@ -398,14 +382,6 @@ description: Artifact commands t-slot-rail.kcl
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "cmdId": "[uuid]",
 | 
			
		||||
      "range": [],
 | 
			
		||||
      "command": {
 | 
			
		||||
        "type": "entity_get_all_child_uuids",
 | 
			
		||||
        "entity_id": "[uuid]"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "cmdId": "[uuid]",
 | 
			
		||||
      "range": [],
 | 
			
		||||
 | 
			
		||||
@ -1170,14 +1170,6 @@ description: Artifact commands subtract_regression10.kcl
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "cmdId": "[uuid]",
 | 
			
		||||
      "range": [],
 | 
			
		||||
      "command": {
 | 
			
		||||
        "type": "entity_get_all_child_uuids",
 | 
			
		||||
        "entity_id": "[uuid]"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "cmdId": "[uuid]",
 | 
			
		||||
      "range": [],
 | 
			
		||||
@ -1639,14 +1631,6 @@ description: Artifact commands subtract_regression10.kcl
 | 
			
		||||
        "edge_id": "[uuid]"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "cmdId": "[uuid]",
 | 
			
		||||
      "range": [],
 | 
			
		||||
      "command": {
 | 
			
		||||
        "type": "entity_get_all_child_uuids",
 | 
			
		||||
        "entity_id": "[uuid]"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "cmdId": "[uuid]",
 | 
			
		||||
      "range": [],
 | 
			
		||||
@ -1895,14 +1879,6 @@ description: Artifact commands subtract_regression10.kcl
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "cmdId": "[uuid]",
 | 
			
		||||
      "range": [],
 | 
			
		||||
      "command": {
 | 
			
		||||
        "type": "entity_get_all_child_uuids",
 | 
			
		||||
        "entity_id": "[uuid]"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "cmdId": "[uuid]",
 | 
			
		||||
      "range": [],
 | 
			
		||||
 | 
			
		||||