Compare commits
1 Commits
nested_dir
...
mirror-2d-
Author | SHA1 | Date | |
---|---|---|---|
7e49a9c733 |
@ -3092,3 +3092,24 @@ mod error_revolve_on_edge_get_edge {
|
||||
super::execute(TEST_NAME, true).await
|
||||
}
|
||||
}
|
||||
mod mirror_sketch_extrude_2_artifacts {
|
||||
const TEST_NAME: &str = "mirror_sketch_extrude_2_artifacts";
|
||||
|
||||
/// Test parsing KCL.
|
||||
#[test]
|
||||
fn parse() {
|
||||
super::parse(TEST_NAME)
|
||||
}
|
||||
|
||||
/// Test that parsing and unparsing KCL produces the original KCL input.
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn unparse() {
|
||||
super::unparse(TEST_NAME).await
|
||||
}
|
||||
|
||||
/// Test that KCL is executed correctly.
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn kcl_test_execute() {
|
||||
super::execute(TEST_NAME, true).await
|
||||
}
|
||||
}
|
||||
|
@ -3,8 +3,12 @@
|
||||
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,
|
||||
output::{EntityMirror, EntityMirrorAcrossEdge},
|
||||
shared::Point3d,
|
||||
websocket::OkWebSocketResponseData,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
@ -54,72 +58,83 @@ async fn inner_mirror_2d(
|
||||
return Ok(starting_sketches);
|
||||
}
|
||||
|
||||
match axis {
|
||||
Axis2dOrEdgeReference::Axis { direction, origin } => {
|
||||
args.batch_modeling_cmd(
|
||||
exec_state.next_uuid(),
|
||||
ModelingCmd::from(mcmd::EntityMirror {
|
||||
ids: starting_sketches.iter().map(|sketch| sketch.id).collect(),
|
||||
axis: Point3d {
|
||||
x: direction[0].to_mm(),
|
||||
y: direction[1].to_mm(),
|
||||
z: 0.0,
|
||||
},
|
||||
point: Point3d {
|
||||
x: LengthUnit(origin[0].to_mm()),
|
||||
y: LengthUnit(origin[1].to_mm()),
|
||||
z: LengthUnit(0.0),
|
||||
},
|
||||
}),
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
Axis2dOrEdgeReference::Edge(edge) => {
|
||||
let edge_id = edge.get_engine_id(exec_state, &args)?;
|
||||
for sketch in &starting_sketches.clone() {
|
||||
let results = match &axis {
|
||||
Axis2dOrEdgeReference::Axis { direction, origin } => {
|
||||
let response = args
|
||||
.send_modeling_cmd(
|
||||
sketch.mirror.unwrap(), // This is safe we just made it above.
|
||||
ModelingCmd::from(mcmd::EntityMirror {
|
||||
ids: vec![sketch.id],
|
||||
axis: Point3d {
|
||||
x: direction[0].to_mm(),
|
||||
y: direction[1].to_mm(),
|
||||
z: 0.0,
|
||||
},
|
||||
point: Point3d {
|
||||
x: LengthUnit(origin[0].to_mm()),
|
||||
y: LengthUnit(origin[1].to_mm()),
|
||||
z: LengthUnit(0.0),
|
||||
},
|
||||
}),
|
||||
)
|
||||
.await?;
|
||||
|
||||
args.batch_modeling_cmd(
|
||||
exec_state.next_uuid(),
|
||||
ModelingCmd::from(mcmd::EntityMirrorAcrossEdge {
|
||||
ids: starting_sketches.iter().map(|sketch| sketch.id).collect(),
|
||||
edge_id,
|
||||
}),
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
};
|
||||
let OkWebSocketResponseData::Modeling {
|
||||
modeling_response:
|
||||
OkModelingCmdResponse::EntityMirror(EntityMirror {
|
||||
entity_face_edge_ids, ..
|
||||
}),
|
||||
} = response
|
||||
else {
|
||||
return Err(KclError::Internal(KclErrorDetails {
|
||||
message: "Expected a successful response from EntityMirror".to_string(),
|
||||
source_ranges: vec![args.source_range],
|
||||
}));
|
||||
};
|
||||
|
||||
// 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],
|
||||
}));
|
||||
entity_face_edge_ids
|
||||
}
|
||||
Axis2dOrEdgeReference::Edge(edge) => {
|
||||
let edge_id = edge.get_engine_id(exec_state, &args)?;
|
||||
|
||||
let response = args
|
||||
.send_modeling_cmd(
|
||||
sketch.mirror.unwrap(), // This is safe we just made it above.
|
||||
ModelingCmd::from(mcmd::EntityMirrorAcrossEdge {
|
||||
ids: vec![sketch.id],
|
||||
edge_id,
|
||||
}),
|
||||
)
|
||||
.await?;
|
||||
|
||||
let OkWebSocketResponseData::Modeling {
|
||||
modeling_response:
|
||||
OkModelingCmdResponse::EntityMirrorAcrossEdge(EntityMirrorAcrossEdge {
|
||||
entity_face_edge_ids, ..
|
||||
}),
|
||||
} = response
|
||||
else {
|
||||
return Err(KclError::Internal(KclErrorDetails {
|
||||
message: "Expected a successful response from EntityMirrorAcrossEdge".to_string(),
|
||||
source_ranges: vec![args.source_range],
|
||||
}));
|
||||
};
|
||||
|
||||
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::Type(KclErrorDetails {
|
||||
message: "Expected child uuids to be >= 2".to_string(),
|
||||
source_ranges: vec![args.source_range],
|
||||
}));
|
||||
println!("Mirror response: {:?}", results);
|
||||
for result in results {
|
||||
if result.object_id != sketch.id {
|
||||
// Add a new sketch to the list.
|
||||
let mut new_sketch = sketch.clone();
|
||||
new_sketch.id = result.object_id;
|
||||
new_sketch.original_id = sketch.id;
|
||||
|
||||
starting_sketches.push(new_sketch);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
2591
rust/kcl-lib/tests/mirror_sketch_extrude_2_artifacts/ast.snap
Normal file
2591
rust/kcl-lib/tests/mirror_sketch_extrude_2_artifacts/ast.snap
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,44 @@
|
||||
@settings(defaultLengthUnit = in)
|
||||
|
||||
// Define parameters
|
||||
trussSupportAngle = 15
|
||||
height = 120
|
||||
thickness = 4
|
||||
|
||||
sketch001 = startSketchOn(YZ)
|
||||
profile001 = startProfile(sketch001, at = [60, 0])
|
||||
|> xLine(length = -120)
|
||||
|> yLine(length = 12)
|
||||
|> angledLine(angle = 25, endAbsoluteX = 0, tag = $tag001)
|
||||
|> angledLine(angle = -25, endAbsoluteX = 60)
|
||||
|> close()
|
||||
|
||||
profile002 = startProfile(sketch001, at = [60-thickness, thickness])
|
||||
|> xLine(endAbsolute = thickness/2)
|
||||
|> yLine(endAbsolute = segEndY(tag001)-thickness) // update
|
||||
|> angledLine(endAbsoluteX = profileStartX(%), angle = -25)
|
||||
|> close(%)
|
||||
|
||||
profile003 = startProfile(sketch001, at = [-60+thickness, thickness])
|
||||
|> xLine(endAbsolute = -thickness/2)
|
||||
|> yLine(endAbsolute = segEndY(tag001)-thickness) // update
|
||||
|> angledLine(endAbsoluteX = profileStartX(%), angle = 205)
|
||||
|> close(%)
|
||||
|
||||
// profile003 = mirror2d(profile002, axis = Y)
|
||||
|
||||
profile004 = subtract2d(profile001, tool = profile002)
|
||||
subtract2d(profile001, tool = profile003)
|
||||
|
||||
body001 = extrude(profile001, length = 2)
|
||||
|
||||
sketch002 = startSketchOn(offsetPlane(YZ, offset = .1))
|
||||
profile006 = startProfile(sketch002, at = [thickness/2-1, 14])
|
||||
|> angledLine(angle = 30, length = 25)
|
||||
|> angledLine(angle = -25, length = 5)
|
||||
|> angledLine(angle = 210, endAbsoluteX = profileStartX(%))
|
||||
|> close(%)
|
||||
|
||||
profile007 = mirror2d(profile006, axis = Y)
|
||||
|
||||
beams = extrude([ profile007], length = 1.8)
|
File diff suppressed because it is too large
Load Diff
Binary file not shown.
After Width: | Height: | Size: 20 KiB |
@ -0,0 +1,48 @@
|
||||
---
|
||||
source: kcl-lib/src/simulation_tests.rs
|
||||
description: Result of unparsing mirror_sketch_extrude_2_artifacts.kcl
|
||||
---
|
||||
@settings(defaultLengthUnit = in)
|
||||
|
||||
// Define parameters
|
||||
trussSupportAngle = 15
|
||||
height = 120
|
||||
thickness = 4
|
||||
|
||||
sketch001 = startSketchOn(YZ)
|
||||
profile001 = startProfile(sketch001, at = [60, 0])
|
||||
|> xLine(length = -120)
|
||||
|> yLine(length = 12)
|
||||
|> angledLine(angle = 25, endAbsoluteX = 0, tag = $tag001)
|
||||
|> angledLine(angle = -25, endAbsoluteX = 60)
|
||||
|> close()
|
||||
|
||||
profile002 = startProfile(sketch001, at = [60 - thickness, thickness])
|
||||
|> xLine(endAbsolute = thickness / 2)
|
||||
|> yLine(endAbsolute = segEndY(tag001) - thickness) // update
|
||||
|> angledLine(endAbsoluteX = profileStartX(%), angle = -25)
|
||||
|> close(%)
|
||||
|
||||
profile003 = startProfile(sketch001, at = [-60 + thickness, thickness])
|
||||
|> xLine(endAbsolute = -thickness / 2)
|
||||
|> yLine(endAbsolute = segEndY(tag001) - thickness) // update
|
||||
|> angledLine(endAbsoluteX = profileStartX(%), angle = 205)
|
||||
|> close(%)
|
||||
|
||||
// profile003 = mirror2d(profile002, axis = Y)
|
||||
|
||||
profile004 = subtract2d(profile001, tool = profile002)
|
||||
subtract2d(profile001, tool = profile003)
|
||||
|
||||
body001 = extrude(profile001, length = 2)
|
||||
|
||||
sketch002 = startSketchOn(offsetPlane(YZ, offset = .1))
|
||||
profile006 = startProfile(sketch002, at = [thickness / 2 - 1, 14])
|
||||
|> angledLine(angle = 30, length = 25)
|
||||
|> angledLine(angle = -25, length = 5)
|
||||
|> angledLine(angle = 210, endAbsoluteX = profileStartX(%))
|
||||
|> close(%)
|
||||
|
||||
profile007 = mirror2d(profile006, axis = Y)
|
||||
|
||||
beams = extrude([profile007], length = 1.8)
|
Reference in New Issue
Block a user