sketching on a mirror2d thats been extruded fixed! (#6149)
* updates Signed-off-by: Jess Frazelle <github@jessfraz.com> * snap Signed-off-by: Jess Frazelle <github@jessfraz.com> * fixes Signed-off-by: Jess Frazelle <github@jessfraz.com> * add sample Signed-off-by: Jess Frazelle <github@jessfraz.com> * updates Signed-off-by: Jess Frazelle <github@jessfraz.com> * updates Signed-off-by: Jess Frazelle <github@jessfraz.com> * updates Signed-off-by: Jess Frazelle <github@jessfraz.com> * fixes Signed-off-by: Jess Frazelle <github@jessfraz.com> * snap Signed-off-by: Jess Frazelle <github@jessfraz.com> --------- Signed-off-by: Jess Frazelle <github@jessfraz.com>
This commit is contained in:
@ -418,6 +418,9 @@ pub struct Sketch {
|
||||
pub artifact_id: ArtifactId,
|
||||
#[ts(skip)]
|
||||
pub original_id: uuid::Uuid,
|
||||
/// If the sketch includes a mirror.
|
||||
#[serde(skip)]
|
||||
pub mirror: Option<uuid::Uuid>,
|
||||
pub units: UnitLen,
|
||||
/// Metadata.
|
||||
#[serde(skip)]
|
||||
|
@ -13,7 +13,7 @@ use kcmc::{
|
||||
websocket::{ModelingCmdReq, OkWebSocketResponseData},
|
||||
ModelingCmd,
|
||||
};
|
||||
use kittycad_modeling_cmds as kcmc;
|
||||
use kittycad_modeling_cmds::{self as kcmc};
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::{
|
||||
@ -168,13 +168,18 @@ pub(crate) async fn do_post_extrude<'a>(
|
||||
)
|
||||
.await?;
|
||||
|
||||
// The "get extrusion face info" API call requires *any* edge on the sketch being extruded.
|
||||
// So, let's just use the first one.
|
||||
let Some(any_edge_id) = sketch.paths.first().map(|edge| edge.get_base().geo_meta.id) else {
|
||||
return Err(KclError::Type(KclErrorDetails {
|
||||
message: "Expected a non-empty sketch".to_string(),
|
||||
source_ranges: vec![args.source_range],
|
||||
}));
|
||||
let any_edge_id = if let Some(edge_id) = sketch.mirror {
|
||||
edge_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.
|
||||
let Some(any_edge_id) = sketch.paths.first().map(|edge| edge.get_base().geo_meta.id) else {
|
||||
return Err(KclError::Type(KclErrorDetails {
|
||||
message: "Expected a non-empty sketch".to_string(),
|
||||
source_ranges: vec![args.source_range],
|
||||
}));
|
||||
};
|
||||
any_edge_id
|
||||
};
|
||||
|
||||
let mut sketch = sketch.clone();
|
||||
|
@ -2,10 +2,13 @@
|
||||
|
||||
use anyhow::Result;
|
||||
use kcmc::{each_cmd as mcmd, ModelingCmd};
|
||||
use kittycad_modeling_cmds::{self as kcmc, length_unit::LengthUnit, shared::Point3d};
|
||||
use kittycad_modeling_cmds::{
|
||||
self as kcmc, length_unit::LengthUnit, ok_response::OkModelingCmdResponse, output::EntityGetAllChildUuids,
|
||||
shared::Point3d, websocket::OkWebSocketResponseData,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
errors::KclError,
|
||||
errors::{KclError, KclErrorDetails},
|
||||
execution::{
|
||||
types::{PrimitiveType, RuntimeType},
|
||||
ExecState, KclValue, Sketch,
|
||||
@ -31,13 +34,21 @@ pub async fn mirror_2d(exec_state: &mut ExecState, args: Args) -> Result<KclValu
|
||||
Ok(sketches.into())
|
||||
}
|
||||
|
||||
/// Mirror a sketch.
|
||||
///
|
||||
/// Only works on unclosed sketches for now.
|
||||
async fn inner_mirror_2d(
|
||||
sketches: Vec<Sketch>,
|
||||
axis: Axis2dOrEdgeReference,
|
||||
exec_state: &mut ExecState,
|
||||
args: Args,
|
||||
) -> Result<Vec<Sketch>, KclError> {
|
||||
let starting_sketches = sketches;
|
||||
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);
|
||||
@ -77,5 +88,40 @@ async fn inner_mirror_2d(
|
||||
}
|
||||
};
|
||||
|
||||
// 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 = args
|
||||
.send_modeling_cmd(
|
||||
exec_state.next_uuid(),
|
||||
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::Internal(KclErrorDetails {
|
||||
message: "Expected a successful response from EntityGetAllChildUuids".to_string(),
|
||||
source_ranges: vec![args.source_range],
|
||||
}));
|
||||
};
|
||||
|
||||
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::Type(KclErrorDetails {
|
||||
message: "Expected child uuids to be >= 2".to_string(),
|
||||
source_ranges: vec![args.source_range],
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
Ok(starting_sketches)
|
||||
}
|
||||
|
@ -1343,6 +1343,7 @@ pub(crate) async fn inner_start_profile_at(
|
||||
on: sketch_surface.clone(),
|
||||
paths: vec![],
|
||||
units: sketch_surface.units(),
|
||||
mirror: Default::default(),
|
||||
meta: vec![args.source_range.into()],
|
||||
tags: if let Some(tag) = &tag {
|
||||
let mut tag_identifier: TagIdentifier = tag.into();
|
||||
|
Reference in New Issue
Block a user