Shell two at once from the same sketch on face (#3908)
* shell two at once from the same obhject Signed-off-by: Jess Frazelle <github@jessfraz.com> * docs Signed-off-by: Jess Frazelle <github@jessfraz.com> --------- Signed-off-by: Jess Frazelle <github@jessfraz.com>
This commit is contained in:
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
11470
docs/kcl/std.json
11470
docs/kcl/std.json
File diff suppressed because it is too large
Load Diff
@ -8,7 +8,7 @@ use serde::{Deserialize, Serialize};
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
errors::{KclError, KclErrorDetails},
|
errors::{KclError, KclErrorDetails},
|
||||||
executor::{ExecState, ExtrudeGroup, KclValue},
|
executor::{ExecState, ExtrudeGroup, ExtrudeGroupSet, KclValue},
|
||||||
std::{sketch::FaceTag, Args},
|
std::{sketch::FaceTag, Args},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -25,10 +25,10 @@ pub struct ShellData {
|
|||||||
|
|
||||||
/// Create a shell.
|
/// Create a shell.
|
||||||
pub async fn shell(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
pub async fn shell(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
||||||
let (data, extrude_group): (ShellData, Box<ExtrudeGroup>) = args.get_data_and_extrude_group()?;
|
let (data, extrude_group_set): (ShellData, ExtrudeGroupSet) = args.get_data_and_extrude_group_set()?;
|
||||||
|
|
||||||
let extrude_group = inner_shell(data, extrude_group, exec_state, args).await?;
|
let result = inner_shell(data, extrude_group_set, exec_state, args).await?;
|
||||||
Ok(KclValue::ExtrudeGroup(extrude_group))
|
Ok(result.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Remove volume from a 3-dimensional shape such that a wall of the
|
/// Remove volume from a 3-dimensional shape such that a wall of the
|
||||||
@ -148,15 +148,40 @@ pub async fn shell(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K
|
|||||||
/// // We put "thing1" in the shell function to shell the end face of the object.
|
/// // We put "thing1" in the shell function to shell the end face of the object.
|
||||||
/// shell({ faces: ['end'], thickness: 5 }, thing1)
|
/// shell({ faces: ['end'], thickness: 5 }, thing1)
|
||||||
/// ```
|
/// ```
|
||||||
|
///
|
||||||
|
/// ```no_run
|
||||||
|
/// // Shell sketched on face objects on the end face, include all sketches to shell
|
||||||
|
/// // the entire object.
|
||||||
|
///
|
||||||
|
/// let size = 100
|
||||||
|
/// const case = startSketchOn('XY')
|
||||||
|
/// |> startProfileAt([-size, -size], %)
|
||||||
|
/// |> line([2 * size, 0], %)
|
||||||
|
/// |> line([0, 2 * size], %)
|
||||||
|
/// |> tangentialArcTo([-size, size], %)
|
||||||
|
/// |> close(%)
|
||||||
|
/// |> extrude(65, %)
|
||||||
|
///
|
||||||
|
/// const thing1 = startSketchOn(case, 'end')
|
||||||
|
/// |> circle([-size / 2, -size / 2], 25, %)
|
||||||
|
/// |> extrude(50, %)
|
||||||
|
///
|
||||||
|
/// const thing2 = startSketchOn(case, 'end')
|
||||||
|
/// |> circle([size / 2, -size / 2], 25, %)
|
||||||
|
/// |> extrude(50, %)
|
||||||
|
///
|
||||||
|
/// // We put "thing1" and "thing2" in the shell function to shell the end face of the object.
|
||||||
|
/// shell({ faces: ['end'], thickness: 5 }, [thing1, thing2])
|
||||||
|
/// ```
|
||||||
#[stdlib {
|
#[stdlib {
|
||||||
name = "shell",
|
name = "shell",
|
||||||
}]
|
}]
|
||||||
async fn inner_shell(
|
async fn inner_shell(
|
||||||
data: ShellData,
|
data: ShellData,
|
||||||
extrude_group: Box<ExtrudeGroup>,
|
extrude_group_set: ExtrudeGroupSet,
|
||||||
exec_state: &mut ExecState,
|
exec_state: &mut ExecState,
|
||||||
args: Args,
|
args: Args,
|
||||||
) -> Result<Box<ExtrudeGroup>, KclError> {
|
) -> Result<ExtrudeGroupSet, KclError> {
|
||||||
if data.faces.is_empty() {
|
if data.faces.is_empty() {
|
||||||
return Err(KclError::Type(KclErrorDetails {
|
return Err(KclError::Type(KclErrorDetails {
|
||||||
message: "Expected at least one face".to_string(),
|
message: "Expected at least one face".to_string(),
|
||||||
@ -164,11 +189,26 @@ async fn inner_shell(
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut face_ids = Vec::new();
|
let extrude_groups: Vec<Box<ExtrudeGroup>> = extrude_group_set.clone().into();
|
||||||
for tag in data.faces {
|
if extrude_groups.is_empty() {
|
||||||
let extrude_plane_id = tag.get_face_id(&extrude_group, exec_state, &args, false).await?;
|
return Err(KclError::Type(KclErrorDetails {
|
||||||
|
message: "Expected at least one extrude group".to_string(),
|
||||||
|
source_ranges: vec![args.source_range],
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
face_ids.push(extrude_plane_id);
|
let mut face_ids = Vec::new();
|
||||||
|
for extrude_group in &extrude_groups {
|
||||||
|
// Flush the batch for our fillets/chamfers if there are any.
|
||||||
|
// If we do not do these for sketch on face, things will fail with face does not exist.
|
||||||
|
args.flush_batch_for_extrude_group_set(exec_state, extrude_group.clone().into())
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
for tag in &data.faces {
|
||||||
|
let extrude_plane_id = tag.get_face_id(extrude_group, exec_state, &args, false).await?;
|
||||||
|
|
||||||
|
face_ids.push(extrude_plane_id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if face_ids.is_empty() {
|
if face_ids.is_empty() {
|
||||||
@ -178,23 +218,28 @@ async fn inner_shell(
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Flush the batch for our fillets/chamfers if there are any.
|
// Make sure all the extrude groups have the same id, as we are going to shell them all at
|
||||||
// If we do not do these for sketch on face, things will fail with face does not exist.
|
// once.
|
||||||
args.flush_batch_for_extrude_group_set(exec_state, extrude_group.clone().into())
|
if !extrude_groups.iter().all(|eg| eg.id == extrude_groups[0].id) {
|
||||||
.await?;
|
return Err(KclError::Type(KclErrorDetails {
|
||||||
|
message: "All extrude groups stem from the same root object, like multiple sketch on face extrusions, etc."
|
||||||
|
.to_string(),
|
||||||
|
source_ranges: vec![args.source_range],
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
args.batch_modeling_cmd(
|
args.batch_modeling_cmd(
|
||||||
uuid::Uuid::new_v4(),
|
uuid::Uuid::new_v4(),
|
||||||
ModelingCmd::Solid3DShellFace {
|
ModelingCmd::Solid3DShellFace {
|
||||||
hollow: false,
|
hollow: false,
|
||||||
face_ids,
|
face_ids,
|
||||||
object_id: extrude_group.id,
|
object_id: extrude_groups[0].id,
|
||||||
shell_thickness: data.thickness,
|
shell_thickness: data.thickness,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
Ok(extrude_group)
|
Ok(extrude_group_set)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Make the inside of a 3D object hollow.
|
/// Make the inside of a 3D object hollow.
|
||||||
@ -211,6 +256,7 @@ pub async fn hollow(exec_state: &mut ExecState, args: Args) -> Result<KclValue,
|
|||||||
/// provided thickness remains around the exterior of the shape.
|
/// provided thickness remains around the exterior of the shape.
|
||||||
///
|
///
|
||||||
/// ```no_run
|
/// ```no_run
|
||||||
|
/// // Hollow a basic sketch.
|
||||||
/// const firstSketch = startSketchOn('XY')
|
/// const firstSketch = startSketchOn('XY')
|
||||||
/// |> startProfileAt([-12, 12], %)
|
/// |> startProfileAt([-12, 12], %)
|
||||||
/// |> line([24, 0], %)
|
/// |> line([24, 0], %)
|
||||||
@ -222,6 +268,7 @@ pub async fn hollow(exec_state: &mut ExecState, args: Args) -> Result<KclValue,
|
|||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// ```no_run
|
/// ```no_run
|
||||||
|
/// // Hollow a basic sketch.
|
||||||
/// const firstSketch = startSketchOn('-XZ')
|
/// const firstSketch = startSketchOn('-XZ')
|
||||||
/// |> startProfileAt([-12, 12], %)
|
/// |> startProfileAt([-12, 12], %)
|
||||||
/// |> line([24, 0], %)
|
/// |> line([24, 0], %)
|
||||||
@ -231,6 +278,28 @@ pub async fn hollow(exec_state: &mut ExecState, args: Args) -> Result<KclValue,
|
|||||||
/// |> extrude(6, %)
|
/// |> extrude(6, %)
|
||||||
/// |> hollow (0.5, %)
|
/// |> hollow (0.5, %)
|
||||||
/// ```
|
/// ```
|
||||||
|
///
|
||||||
|
/// ```no_run
|
||||||
|
/// // Hollow a sketch on face object.
|
||||||
|
/// let size = 100
|
||||||
|
/// const case = startSketchOn('-XZ')
|
||||||
|
/// |> startProfileAt([-size, -size], %)
|
||||||
|
/// |> line([2 * size, 0], %)
|
||||||
|
/// |> line([0, 2 * size], %)
|
||||||
|
/// |> tangentialArcTo([-size, size], %)
|
||||||
|
/// |> close(%)
|
||||||
|
/// |> extrude(65, %)
|
||||||
|
///
|
||||||
|
/// const thing1 = startSketchOn(case, 'end')
|
||||||
|
/// |> circle([-size / 2, -size / 2], 25, %)
|
||||||
|
/// |> extrude(50, %)
|
||||||
|
///
|
||||||
|
/// const thing2 = startSketchOn(case, 'end')
|
||||||
|
/// |> circle([size / 2, -size / 2], 25, %)
|
||||||
|
/// |> extrude(50, %)
|
||||||
|
///
|
||||||
|
/// hollow(0.5, case)
|
||||||
|
/// ```
|
||||||
#[stdlib {
|
#[stdlib {
|
||||||
name = "hollow",
|
name = "hollow",
|
||||||
}]
|
}]
|
||||||
|
BIN
src/wasm-lib/kcl/tests/outputs/serial_test_example_hollow2.png
Normal file
BIN
src/wasm-lib/kcl/tests/outputs/serial_test_example_hollow2.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 69 KiB |
BIN
src/wasm-lib/kcl/tests/outputs/serial_test_example_shell6.png
Normal file
BIN
src/wasm-lib/kcl/tests/outputs/serial_test_example_shell6.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 55 KiB |
Reference in New Issue
Block a user