KCL: small refactors to Extrude (#3768)
- Make post-extrude code more functional - impl Copy for Point3d
This commit is contained in:
@ -995,20 +995,20 @@ impl SketchSurface {
|
||||
}
|
||||
pub(crate) fn x_axis(&self) -> Point3d {
|
||||
match self {
|
||||
SketchSurface::Plane(plane) => plane.x_axis.clone(),
|
||||
SketchSurface::Face(face) => face.x_axis.clone(),
|
||||
SketchSurface::Plane(plane) => plane.x_axis,
|
||||
SketchSurface::Face(face) => face.x_axis,
|
||||
}
|
||||
}
|
||||
pub(crate) fn y_axis(&self) -> Point3d {
|
||||
match self {
|
||||
SketchSurface::Plane(plane) => plane.y_axis.clone(),
|
||||
SketchSurface::Face(face) => face.y_axis.clone(),
|
||||
SketchSurface::Plane(plane) => plane.y_axis,
|
||||
SketchSurface::Face(face) => face.y_axis,
|
||||
}
|
||||
}
|
||||
pub(crate) fn z_axis(&self) -> Point3d {
|
||||
match self {
|
||||
SketchSurface::Plane(plane) => plane.z_axis.clone(),
|
||||
SketchSurface::Face(face) => face.z_axis.clone(),
|
||||
SketchSurface::Plane(plane) => plane.z_axis,
|
||||
SketchSurface::Face(face) => face.z_axis,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1304,7 +1304,7 @@ impl Point2d {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize, PartialEq, Clone, ts_rs::TS, JsonSchema, Default)]
|
||||
#[derive(Debug, Deserialize, Serialize, PartialEq, Clone, Copy, ts_rs::TS, JsonSchema, Default)]
|
||||
#[ts(export)]
|
||||
pub struct Point3d {
|
||||
pub x: f64,
|
||||
@ -1313,6 +1313,7 @@ pub struct Point3d {
|
||||
}
|
||||
|
||||
impl Point3d {
|
||||
pub const ZERO: Self = Self { x: 0.0, y: 0.0, z: 0.0 };
|
||||
pub fn new(x: f64, y: f64, z: f64) -> Self {
|
||||
Self { x, y, z }
|
||||
}
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
|
||||
use anyhow::Result;
|
||||
use derive_docs::stdlib;
|
||||
use kittycad::types::ExtrusionFaceCapType;
|
||||
use schemars::JsonSchema;
|
||||
use uuid::Uuid;
|
||||
|
||||
@ -90,7 +91,7 @@ async fn inner_extrude(length: f64, sketch_group_set: SketchGroupSet, args: Args
|
||||
adjust_camera: false,
|
||||
planar_normal: if let SketchSurface::Plane(plane) = &sketch_group.on {
|
||||
// We pass in the normal for the plane here.
|
||||
Some(plane.z_axis.clone().into())
|
||||
Some(plane.z_axis.into())
|
||||
} else {
|
||||
None
|
||||
},
|
||||
@ -181,43 +182,55 @@ pub(crate) async fn do_post_extrude(
|
||||
vec![]
|
||||
};
|
||||
|
||||
for face_info in face_infos.iter() {
|
||||
if face_info.cap == kittycad::types::ExtrusionFaceCapType::None {
|
||||
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) {
|
||||
args.batch_modeling_cmd(
|
||||
uuid::Uuid::new_v4(),
|
||||
kittycad::types::ModelingCmd::Solid3DGetOppositeEdge {
|
||||
edge_id: curve_id,
|
||||
object_id: sketch_group.id,
|
||||
face_id,
|
||||
},
|
||||
)
|
||||
.await?;
|
||||
|
||||
args.batch_modeling_cmd(
|
||||
uuid::Uuid::new_v4(),
|
||||
kittycad::types::ModelingCmd::Solid3DGetPrevAdjacentEdge {
|
||||
edge_id: curve_id,
|
||||
object_id: sketch_group.id,
|
||||
face_id,
|
||||
},
|
||||
)
|
||||
.await?;
|
||||
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(
|
||||
uuid::Uuid::new_v4(),
|
||||
kittycad::types::ModelingCmd::Solid3DGetOppositeEdge {
|
||||
edge_id: curve_id,
|
||||
object_id: sketch_group.id,
|
||||
face_id,
|
||||
},
|
||||
)
|
||||
.await?;
|
||||
|
||||
args.batch_modeling_cmd(
|
||||
uuid::Uuid::new_v4(),
|
||||
kittycad::types::ModelingCmd::Solid3DGetPrevAdjacentEdge {
|
||||
edge_id: curve_id,
|
||||
object_id: sketch_group.id,
|
||||
face_id,
|
||||
},
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
|
||||
// Create a hashmap for quick id lookup
|
||||
let mut face_id_map = std::collections::HashMap::new();
|
||||
// creating fake ids for start and end caps is to make extrudes mock-execute safe
|
||||
let mut start_cap_id = if args.ctx.is_mock { Some(Uuid::new_v4()) } else { None };
|
||||
let mut end_cap_id = if args.ctx.is_mock { Some(Uuid::new_v4()) } else { None };
|
||||
|
||||
let (mut start_cap_id, mut end_cap_id) = if args.ctx.is_mock {
|
||||
(Some(Uuid::new_v4()), Some(Uuid::new_v4()))
|
||||
} else {
|
||||
(None, None)
|
||||
};
|
||||
for face_info in face_infos {
|
||||
match face_info.cap {
|
||||
kittycad::types::ExtrusionFaceCapType::Bottom => start_cap_id = face_info.face_id,
|
||||
kittycad::types::ExtrusionFaceCapType::Top => end_cap_id = face_info.face_id,
|
||||
_ => {
|
||||
ExtrusionFaceCapType::Bottom => start_cap_id = face_info.face_id,
|
||||
ExtrusionFaceCapType::Top => end_cap_id = face_info.face_id,
|
||||
ExtrusionFaceCapType::None => {
|
||||
if let Some(curve_id) = face_info.curve_id {
|
||||
face_id_map.insert(curve_id, face_info.face_id);
|
||||
}
|
||||
@ -226,46 +239,53 @@ pub(crate) async fn do_post_extrude(
|
||||
}
|
||||
|
||||
// Iterate over the sketch_group.value array and add face_id to GeoMeta
|
||||
let mut new_value: Vec<ExtrudeSurface> = Vec::new();
|
||||
for path in sketch_group.value.iter() {
|
||||
if let Some(Some(actual_face_id)) = face_id_map.get(&path.get_base().geo_meta.id) {
|
||||
match path {
|
||||
Path::TangentialArc { .. } | Path::TangentialArcTo { .. } => {
|
||||
let extrude_surface = ExtrudeSurface::ExtrudeArc(crate::executor::ExtrudeArc {
|
||||
face_id: *actual_face_id,
|
||||
tag: path.get_base().tag.clone(),
|
||||
geo_meta: GeoMeta {
|
||||
id: path.get_base().geo_meta.id,
|
||||
metadata: path.get_base().geo_meta.metadata.clone(),
|
||||
},
|
||||
});
|
||||
new_value.push(extrude_surface);
|
||||
}
|
||||
Path::Base { .. } | Path::ToPoint { .. } | Path::Horizontal { .. } | Path::AngledLineTo { .. } => {
|
||||
let extrude_surface = ExtrudeSurface::ExtrudePlane(crate::executor::ExtrudePlane {
|
||||
face_id: *actual_face_id,
|
||||
tag: path.get_base().tag.clone(),
|
||||
geo_meta: GeoMeta {
|
||||
id: path.get_base().geo_meta.id,
|
||||
metadata: path.get_base().geo_meta.metadata.clone(),
|
||||
},
|
||||
});
|
||||
new_value.push(extrude_surface);
|
||||
let new_value = sketch_group
|
||||
.value
|
||||
.iter()
|
||||
.flat_map(|path| {
|
||||
if let Some(Some(actual_face_id)) = face_id_map.get(&path.get_base().geo_meta.id) {
|
||||
match path {
|
||||
Path::TangentialArc { .. } | Path::TangentialArcTo { .. } => {
|
||||
let extrude_surface = ExtrudeSurface::ExtrudeArc(crate::executor::ExtrudeArc {
|
||||
face_id: *actual_face_id,
|
||||
tag: path.get_base().tag.clone(),
|
||||
geo_meta: GeoMeta {
|
||||
id: path.get_base().geo_meta.id,
|
||||
metadata: path.get_base().geo_meta.metadata.clone(),
|
||||
},
|
||||
});
|
||||
Some(extrude_surface)
|
||||
}
|
||||
Path::Base { .. } | Path::ToPoint { .. } | Path::Horizontal { .. } | Path::AngledLineTo { .. } => {
|
||||
let extrude_surface = ExtrudeSurface::ExtrudePlane(crate::executor::ExtrudePlane {
|
||||
face_id: *actual_face_id,
|
||||
tag: path.get_base().tag.clone(),
|
||||
geo_meta: GeoMeta {
|
||||
id: path.get_base().geo_meta.id,
|
||||
metadata: path.get_base().geo_meta.metadata.clone(),
|
||||
},
|
||||
});
|
||||
Some(extrude_surface)
|
||||
}
|
||||
}
|
||||
} else if args.ctx.is_mock {
|
||||
// Only pre-populate the extrude surface if we are in mock mode.
|
||||
|
||||
let extrude_surface = ExtrudeSurface::ExtrudePlane(crate::executor::ExtrudePlane {
|
||||
// pushing this values with a fake face_id to make extrudes mock-execute safe
|
||||
face_id: Uuid::new_v4(),
|
||||
tag: path.get_base().tag.clone(),
|
||||
geo_meta: GeoMeta {
|
||||
id: path.get_base().geo_meta.id,
|
||||
metadata: path.get_base().geo_meta.metadata.clone(),
|
||||
},
|
||||
});
|
||||
Some(extrude_surface)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
} else if args.ctx.is_mock {
|
||||
// Only pre-populate the extrude surface if we are in mock mode.
|
||||
new_value.push(ExtrudeSurface::ExtrudePlane(crate::executor::ExtrudePlane {
|
||||
// pushing this values with a fake face_id to make extrudes mock-execute safe
|
||||
face_id: Uuid::new_v4(),
|
||||
tag: path.get_base().tag.clone(),
|
||||
geo_meta: GeoMeta {
|
||||
id: path.get_base().geo_meta.id,
|
||||
metadata: path.get_base().geo_meta.metadata.clone(),
|
||||
},
|
||||
}));
|
||||
}
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
||||
Ok(Box::new(ExtrudeGroup {
|
||||
// Ok so you would think that the id would be the id of the extrude group,
|
||||
@ -273,11 +293,11 @@ pub(crate) async fn do_post_extrude(
|
||||
// sketch group.
|
||||
id: sketch_group.id,
|
||||
value: new_value,
|
||||
sketch_group: sketch_group.clone(),
|
||||
meta: sketch_group.meta.clone(),
|
||||
sketch_group,
|
||||
height: length,
|
||||
start_cap_id,
|
||||
end_cap_id,
|
||||
edge_cuts: vec![],
|
||||
meta: sketch_group.meta,
|
||||
}))
|
||||
}
|
||||
|
||||
@ -1269,7 +1269,7 @@ pub(crate) async fn inner_start_profile_at(
|
||||
adjust_camera: false,
|
||||
planar_normal: if let SketchSurface::Plane(plane) = &sketch_surface {
|
||||
// We pass in the normal for the plane here.
|
||||
Some(plane.z_axis.clone().into())
|
||||
Some(plane.z_axis.into())
|
||||
} else {
|
||||
None
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user