diff --git a/e2e/playwright/fixtures/toolbarFixture.ts b/e2e/playwright/fixtures/toolbarFixture.ts index ae51d659a..f1be93061 100644 --- a/e2e/playwright/fixtures/toolbarFixture.ts +++ b/e2e/playwright/fixtures/toolbarFixture.ts @@ -241,6 +241,12 @@ export class ToolbarFixture { async openFeatureTreePane() { return this.openPane(this.featureTreeId) } + + async waitForFeatureTreeToBeBuilt() { + await this.openFeatureTreePane() + await expect(this.page.getByText('Building feature tree')).not.toBeVisible() + await this.closeFeatureTreePane() + } async closeFeatureTreePane() { await this.closePane(this.featureTreeId) } diff --git a/e2e/playwright/point-click.spec.ts b/e2e/playwright/point-click.spec.ts index 84fcf9bf7..1946f1b10 100644 --- a/e2e/playwright/point-click.spec.ts +++ b/e2e/playwright/point-click.spec.ts @@ -244,6 +244,7 @@ test.describe('Point-and-click tests', () => { await scene.moveCameraTo(cameraPos, cameraTarget) await test.step('check chamfer selection changes cursor position', async () => { + await toolbar.waitForFeatureTreeToBeBuilt() await expect(async () => { // sometimes initial click doesn't register await clickChamfer() @@ -283,6 +284,7 @@ test.describe('Point-and-click tests', () => { highlightedCode: '', diagnostics: [], }) + await toolbar.waitForFeatureTreeToBeBuilt() }) } test('works on all edge selections and can break up multi edges in a chamfer array', async ({ @@ -402,6 +404,7 @@ test.describe('Point-and-click tests', () => { await test.step('verify at the end of the test that final code is what is expected', async () => { await editor.expectEditor.toContain( `@settings(defaultLengthUnit = in) + sketch001 = startSketchOn(XZ) |> startProfile(at = [75.8, 317.2]) // [$startCapTag, $EndCapTag] |> angledLine(angle = 0, length = 268.43, tag = $rectangleSegmentA001) @@ -414,18 +417,11 @@ extrude001 = extrude(sketch001, length = 100) |> chamfer(length = 30, tags = [seg01], tag = $seg04) |> chamfer(length = 30, tags = [getNextAdjacentEdge(seg02)], tag = $seg05) |> chamfer(length = 30, tags = [getNextAdjacentEdge(yo)], tag = $seg06) -sketch005 = startSketchOn(extrude001, face = seg06) -profile004=startProfile(sketch005, at = [-23.43,19.69]) - |> angledLine(angle = 0, length = 9.1, tag = $rectangleSegmentA005) - |> angledLine(angle = segAng(rectangleSegmentA005) - 90, length = 84.07) - |> angledLine(angle = segAng(rectangleSegmentA005), length = -segLen(rectangleSegmentA005)) - |> line(endAbsolute=[profileStartX(%), profileStartY(%)]) - |> close() -sketch004 = startSketchOn(extrude001, face = seg05) -profile003 = startProfile(sketch004, at = [82.57, 322.96]) - |> angledLine(angle = 0, length = 11.16, tag = $rectangleSegmentA004) - |> angledLine(angle = segAng(rectangleSegmentA004) - 90, length = 103.07) - |> angledLine(angle = segAng(rectangleSegmentA004), length = -segLen(rectangleSegmentA004)) +sketch002 = startSketchOn(extrude001, face = seg03) +profile001 = startProfile(sketch002, at = [205.96, 254.59]) + |> angledLine(angle = 0, length = 11.39, tag = $rectangleSegmentA002) + |> angledLine(angle = segAng(rectangleSegmentA002) - 90, length = 105.26) + |> angledLine(angle = segAng(rectangleSegmentA002), length = -segLen(rectangleSegmentA002)) |> line(endAbsolute = [profileStartX(%), profileStartY(%)]) |> close() sketch003 = startSketchOn(extrude001, face = seg04) @@ -435,11 +431,18 @@ profile002 = startProfile(sketch003, at = [-209.64, 255.28]) |> angledLine(angle = segAng(rectangleSegmentA003), length = -segLen(rectangleSegmentA003)) |> line(endAbsolute = [profileStartX(%), profileStartY(%)]) |> close() -sketch002 = startSketchOn(extrude001, face = seg03) -profile001 = startProfile(sketch002, at = [205.96, 254.59]) - |> angledLine(angle = 0, length = 11.39, tag = $rectangleSegmentA002) - |> angledLine(angle = segAng(rectangleSegmentA002) - 90, length = 105.26) - |> angledLine(angle = segAng(rectangleSegmentA002), length = -segLen(rectangleSegmentA002)) +sketch004 = startSketchOn(extrude001, face = seg05) +profile003 = startProfile(sketch004, at = [82.57, 322.96]) + |> angledLine(angle = 0, length = 11.16, tag = $rectangleSegmentA004) + |> angledLine(angle = segAng(rectangleSegmentA004) - 90, length = 103.07) + |> angledLine(angle = segAng(rectangleSegmentA004), length = -segLen(rectangleSegmentA004)) + |> line(endAbsolute = [profileStartX(%), profileStartY(%)]) + |> close() +sketch005 = startSketchOn(extrude001, face = seg06) +profile004 = startProfile(sketch005, at = [-23.43, 19.69]) + |> angledLine(angle = 0, length = 9.1, tag = $rectangleSegmentA005) + |> angledLine(angle = segAng(rectangleSegmentA005) - 90, length = 84.07) + |> angledLine(angle = segAng(rectangleSegmentA005), length = -segLen(rectangleSegmentA005)) |> line(endAbsolute = [profileStartX(%), profileStartY(%)]) |> close() `, diff --git a/e2e/playwright/sketch-tests.spec.ts b/e2e/playwright/sketch-tests.spec.ts index 391887aab..254db97e0 100644 --- a/e2e/playwright/sketch-tests.spec.ts +++ b/e2e/playwright/sketch-tests.spec.ts @@ -1260,6 +1260,97 @@ profile001 = startProfile(sketch001, at = [299.72, 230.82]) }).toPass({ timeout: 40_000, intervals: [1_000] }) }) + test('sketch on face of a boolean works', async ({ + page, + homePage, + scene, + cmdBar, + toolbar, + editor, + }) => { + await page.setBodyDimensions({ width: 1000, height: 500 }) + + await page.addInitScript(async () => { + localStorage.setItem( + 'persistCode', + `@settings(defaultLengthUnit = mm) + +myVar = 50 +sketch001 = startSketchOn(XZ) +profile001 = circle(sketch001, center = [myVar, 43.9], radius = 41.05) +extrude001 = extrude(profile001, length = 200) + |> translate(x = 3.14, y = 3.14, z = -50.154) +sketch002 = startSketchOn(XY) +profile002 = startProfile(sketch002, at = [72.2, -52.05]) + |> angledLine(angle = 0, length = 181.26, tag = $rectangleSegmentA001) + |> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 21.54) + |> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001), tag = $mySeg) + |> line(endAbsolute = [profileStartX(%), profileStartY(%)], tag = $seg01) + |> close() + +extrude002 = extrude(profile002, length = 151) + |> chamfer( + %, + length = 15, + tags = [mySeg], + tag = $seg02, + ) +solid001 = subtract([extrude001], tools = [extrude002]) +` + ) + }) + + const [selectChamferFaceClk] = scene.makeMouseHelpers(671, 283) + const [circleCenterClk] = scene.makeMouseHelpers(700, 272) + const [circleRadiusClk] = scene.makeMouseHelpers(694, 264) + + await test.step('Setup', async () => { + await homePage.goToModelingScene() + await scene.settled(cmdBar) + + await scene.moveCameraTo( + { x: 180, y: -75, z: 116 }, + { x: 67, y: -114, z: -15 } + ) + }) + + await test.step('sketch on chamfer face that is part of a boolean', async () => { + await toolbar.startSketchPlaneSelection() + await selectChamferFaceClk() + + await expect + .poll(async () => { + const lineBtn = page.getByRole('button', { name: 'line Line' }) + return lineBtn.getAttribute('aria-pressed') + }) + .toBe('true') + + await editor.expectEditor.toContain( + 'startSketchOn(solid001, face = seg02)' + ) + }) + + await test.step('verify sketching still works', async () => { + await toolbar.circleBtn.click() + await expect + .poll(async () => { + const circleBtn = page.getByRole('button', { name: 'circle Circle' }) + return circleBtn.getAttribute('aria-pressed') + }) + .toBe('true') + + await circleCenterClk() + await editor.expectEditor.toContain( + 'profile003 = circle(sketch003, center' + ) + + await circleRadiusClk() + await editor.expectEditor.toContain( + 'profile003 = circle(sketch003, center = [119.41, -56.05], radius = 1.82)' + ) + }) + }) + test('Can sketch on face when user defined function was used in the sketch', async ({ page, homePage, diff --git a/rust/kcl-lib/src/execution/artifact.rs b/rust/kcl-lib/src/execution/artifact.rs index 07e26df39..04a416793 100644 --- a/rust/kcl-lib/src/execution/artifact.rs +++ b/rust/kcl-lib/src/execution/artifact.rs @@ -150,6 +150,10 @@ pub struct CompositeSolid { #[serde(default, skip_serializing_if = "Vec::is_empty")] pub tool_ids: Vec, pub code_ref: CodeRef, + /// This is the ID of the composite solid that this is part of, if any, as a + /// composite solid can be used as input for another composite solid. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub composite_solid_id: Option, } #[derive(Debug, Clone, Copy, Serialize, PartialEq, Eq, ts_rs::TS)] @@ -182,6 +186,10 @@ pub struct Path { #[serde(default, skip_serializing_if = "Option::is_none")] pub solid2d_id: Option, pub code_ref: CodeRef, + /// This is the ID of the composite solid that this is part of, if any, as + /// this can be used as input for another composite solid. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub composite_solid_id: Option, } #[derive(Debug, Clone, Serialize, PartialEq, ts_rs::TS)] @@ -585,6 +593,7 @@ impl CompositeSolid { }; merge_ids(&mut self.solid_ids, new.solid_ids); merge_ids(&mut self.tool_ids, new.tool_ids); + merge_opt_id(&mut self.composite_solid_id, new.composite_solid_id); None } @@ -609,6 +618,7 @@ impl Path { merge_opt_id(&mut self.sweep_id, new.sweep_id); merge_ids(&mut self.seg_ids, new.seg_ids); merge_opt_id(&mut self.solid2d_id, new.solid2d_id); + merge_opt_id(&mut self.composite_solid_id, new.composite_solid_id); None } @@ -921,6 +931,7 @@ fn artifacts_to_update( sweep_id: None, solid2d_id: None, code_ref, + composite_solid_id: None, })); let plane = artifacts.get(&ArtifactId::new(*current_plane_id)); if let Some(Artifact::Plane(plane)) = plane { @@ -1359,20 +1370,59 @@ fn artifacts_to_update( .for_each(|id| new_solid_ids.push(id)), _ => {} } - let return_arr = new_solid_ids - .into_iter() - .map(|solid_id| { - Artifact::CompositeSolid(CompositeSolid { - id: solid_id, - sub_type, - solid_ids: solid_ids.clone(), - tool_ids: tool_ids.clone(), - code_ref: code_ref.clone(), - }) - }) - .collect::>(); - // TODO: Should we add the reverse graph edges? + let mut return_arr = Vec::new(); + + // Create the new composite solids and update their linked artifacts + for solid_id in &new_solid_ids { + // Create the composite solid + return_arr.push(Artifact::CompositeSolid(CompositeSolid { + id: *solid_id, + sub_type, + solid_ids: solid_ids.clone(), + tool_ids: tool_ids.clone(), + code_ref: code_ref.clone(), + composite_solid_id: None, + })); + + // Update the artifacts that were used as input for this composite solid + for input_id in &solid_ids { + if let Some(artifact) = artifacts.get(input_id) { + match artifact { + Artifact::CompositeSolid(comp) => { + let mut new_comp = comp.clone(); + new_comp.composite_solid_id = Some(*solid_id); + return_arr.push(Artifact::CompositeSolid(new_comp)); + } + Artifact::Path(path) => { + let mut new_path = path.clone(); + new_path.composite_solid_id = Some(*solid_id); + return_arr.push(Artifact::Path(new_path)); + } + _ => {} + } + } + } + + // Update the tool artifacts if this is a subtract operation + for tool_id in &tool_ids { + if let Some(artifact) = artifacts.get(tool_id) { + match artifact { + Artifact::CompositeSolid(comp) => { + let mut new_comp = comp.clone(); + new_comp.composite_solid_id = Some(*solid_id); + return_arr.push(Artifact::CompositeSolid(new_comp)); + } + Artifact::Path(path) => { + let mut new_path = path.clone(); + new_path.composite_solid_id = Some(*solid_id); + return_arr.push(Artifact::Path(new_path)); + } + _ => {} + } + } + } + } return Ok(return_arr); } diff --git a/rust/kcl-lib/src/execution/artifact/mermaid_tests.rs b/rust/kcl-lib/src/execution/artifact/mermaid_tests.rs index a2af89d71..01d018b8b 100644 --- a/rust/kcl-lib/src/execution/artifact/mermaid_tests.rs +++ b/rust/kcl-lib/src/execution/artifact/mermaid_tests.rs @@ -92,10 +92,14 @@ impl Artifact { /// the graph. pub(crate) fn child_ids(&self) -> Vec { match self { - Artifact::CompositeSolid(_) => { + Artifact::CompositeSolid(a) => { // Note: Don't include these since they're parents: solid_ids, // tool_ids. - Vec::new() + let mut ids = Vec::new(); + if let Some(composite_solid_id) = a.composite_solid_id { + ids.push(composite_solid_id); + } + ids } Artifact::Plane(a) => a.path_ids.clone(), Artifact::Path(a) => { @@ -107,6 +111,9 @@ impl Artifact { if let Some(solid2d_id) = a.solid2d_id { ids.push(solid2d_id); } + if let Some(composite_solid_id) = a.composite_solid_id { + ids.push(composite_solid_id); + } ids } Artifact::Segment(a) => { diff --git a/rust/kcl-lib/tests/import_transform/rendered_model.png b/rust/kcl-lib/tests/import_transform/rendered_model.png index 545b296a2..c6c9dc8b0 100644 Binary files a/rust/kcl-lib/tests/import_transform/rendered_model.png and b/rust/kcl-lib/tests/import_transform/rendered_model.png differ diff --git a/rust/kcl-lib/tests/intersect_cubes/artifact_graph_flowchart.snap.md b/rust/kcl-lib/tests/intersect_cubes/artifact_graph_flowchart.snap.md index 332772bd5..7028a3e8d 100644 --- a/rust/kcl-lib/tests/intersect_cubes/artifact_graph_flowchart.snap.md +++ b/rust/kcl-lib/tests/intersect_cubes/artifact_graph_flowchart.snap.md @@ -57,14 +57,14 @@ flowchart LR 3 --- 11 3 --- 13 3 ---- 16 - 3 <--x 17 + 3 --- 17 4 --- 6 4 --- 7 4 --- 9 4 --- 12 4 --- 14 4 ---- 15 - 4 <--x 17 + 4 --- 17 5 --- 24 5 x--> 26 5 --- 35 diff --git a/rust/kcl-lib/tests/kcl_samples/dodecahedron/artifact_graph_flowchart.snap.md b/rust/kcl-lib/tests/kcl_samples/dodecahedron/artifact_graph_flowchart.snap.md index ddd9123f4..74831cec0 100644 --- a/rust/kcl-lib/tests/kcl_samples/dodecahedron/artifact_graph_flowchart.snap.md +++ b/rust/kcl-lib/tests/kcl_samples/dodecahedron/artifact_graph_flowchart.snap.md @@ -317,84 +317,84 @@ flowchart LR 13 --- 67 13 --- 73 13 ---- 90 - 13 <--x 106 + 13 --- 106 14 --- 27 14 --- 45 14 --- 50 14 --- 65 14 --- 74 14 ---- 92 - 14 <--x 101 + 14 --- 101 15 --- 32 15 --- 48 15 --- 51 15 --- 71 15 --- 75 15 ---- 93 - 15 <--x 99 + 15 --- 99 16 --- 29 16 --- 40 16 --- 56 16 --- 69 16 --- 76 16 ---- 96 - 16 <--x 100 + 16 --- 100 17 --- 26 17 --- 44 17 --- 52 17 --- 63 17 --- 77 17 ---- 95 - 17 <--x 105 + 17 --- 105 18 --- 28 18 --- 47 18 --- 58 18 --- 64 18 --- 78 18 ---- 94 - 18 <--x 102 + 18 --- 102 19 --- 35 19 --- 41 19 --- 57 19 --- 66 19 --- 79 19 ---- 89 - 19 <--x 98 + 19 --- 98 20 --- 34 20 --- 42 20 --- 55 20 --- 68 20 --- 80 20 ---- 87 - 20 <--x 104 + 20 --- 104 21 --- 30 21 --- 39 21 --- 60 21 --- 70 21 --- 81 21 ---- 91 - 21 <--x 103 + 21 --- 103 22 --- 25 22 --- 46 22 --- 54 22 --- 72 22 --- 82 22 ---- 88 - 22 <--x 104 + 22 --- 104 23 --- 36 23 --- 37 23 --- 49 23 --- 62 23 --- 83 23 ---- 86 - 23 <--x 107 + 23 --- 107 24 --- 33 24 --- 43 24 --- 53 24 --- 61 24 --- 84 24 ---- 85 - 24 <--x 97 + 24 --- 97 25 --- 120 25 x--> 158 25 --- 193 @@ -755,16 +755,16 @@ flowchart LR 96 --- 273 96 --- 274 96 --- 275 - 97 <--x 98 - 99 x--> 97 - 98 <--x 103 - 105 x--> 99 - 104 x--> 100 - 100 <--x 107 - 101 <--x 102 - 103 x--> 101 - 106 x--> 105 - 107 x--> 106 + 97 --- 98 + 99 --- 97 + 98 --- 103 + 105 --- 99 + 104 --- 100 + 100 --- 107 + 101 --- 102 + 103 --- 101 + 106 --- 105 + 107 --- 106 182 <--x 108 230 <--x 108 231 <--x 108 diff --git a/rust/kcl-lib/tests/kcl_samples/dual-basin-utility-sink/artifact_graph_flowchart.snap.md b/rust/kcl-lib/tests/kcl_samples/dual-basin-utility-sink/artifact_graph_flowchart.snap.md index a13d6eb9a..f2c5ff52b 100644 --- a/rust/kcl-lib/tests/kcl_samples/dual-basin-utility-sink/artifact_graph_flowchart.snap.md +++ b/rust/kcl-lib/tests/kcl_samples/dual-basin-utility-sink/artifact_graph_flowchart.snap.md @@ -608,7 +608,7 @@ flowchart LR 83 --- 246 83 --- 289 90 --- 159 - 90 x--> 193 + 90 x--> 192 90 --- 226 90 --- 271 104 --- 151 @@ -910,7 +910,7 @@ flowchart LR 211 <--x 191 212 <--x 191 213 <--x 191 - 226 <--x 192 + 226 <--x 193 239 <--x 195 240 <--x 195 241 <--x 195 diff --git a/rust/kcl-lib/tests/kcl_samples/walkie-talkie/artifact_graph_flowchart.snap.md b/rust/kcl-lib/tests/kcl_samples/walkie-talkie/artifact_graph_flowchart.snap.md index 8eab47124..8b8a2e6b9 100644 --- a/rust/kcl-lib/tests/kcl_samples/walkie-talkie/artifact_graph_flowchart.snap.md +++ b/rust/kcl-lib/tests/kcl_samples/walkie-talkie/artifact_graph_flowchart.snap.md @@ -709,6 +709,7 @@ flowchart LR 115 --- 179 115 x--> 228 115 --- 256 + 115 x--> 307 115 --- 308 164 <--x 116 116 --- 184 diff --git a/rust/kcl-lib/tests/subtract_cylinder_from_cube/artifact_graph_flowchart.snap.md b/rust/kcl-lib/tests/subtract_cylinder_from_cube/artifact_graph_flowchart.snap.md index d9deddde4..230592c91 100644 --- a/rust/kcl-lib/tests/subtract_cylinder_from_cube/artifact_graph_flowchart.snap.md +++ b/rust/kcl-lib/tests/subtract_cylinder_from_cube/artifact_graph_flowchart.snap.md @@ -45,11 +45,11 @@ flowchart LR 3 --- 8 3 --- 11 3 ---- 12 - 3 <--x 14 + 3 --- 14 4 --- 9 4 --- 10 4 ---- 13 - 4 <--x 14 + 4 --- 14 5 --- 18 5 x--> 21 5 --- 25 diff --git a/rust/kcl-lib/tests/subtract_doesnt_need_brackets/artifact_graph_flowchart.snap.md b/rust/kcl-lib/tests/subtract_doesnt_need_brackets/artifact_graph_flowchart.snap.md index 15802af18..c111a2f5f 100644 --- a/rust/kcl-lib/tests/subtract_doesnt_need_brackets/artifact_graph_flowchart.snap.md +++ b/rust/kcl-lib/tests/subtract_doesnt_need_brackets/artifact_graph_flowchart.snap.md @@ -57,14 +57,14 @@ flowchart LR 3 --- 11 3 --- 13 3 ---- 16 - 3 <--x 17 + 3 --- 17 4 --- 6 4 --- 7 4 --- 9 4 --- 12 4 --- 14 4 ---- 15 - 4 <--x 17 + 4 --- 17 5 --- 24 5 x--> 26 5 --- 35 diff --git a/rust/kcl-lib/tests/union_cubes/artifact_graph_flowchart.snap.md b/rust/kcl-lib/tests/union_cubes/artifact_graph_flowchart.snap.md index e99ad4c23..979532e7a 100644 --- a/rust/kcl-lib/tests/union_cubes/artifact_graph_flowchart.snap.md +++ b/rust/kcl-lib/tests/union_cubes/artifact_graph_flowchart.snap.md @@ -57,14 +57,14 @@ flowchart LR 3 --- 11 3 --- 13 3 ---- 16 - 3 <--x 17 + 3 --- 17 4 --- 6 4 --- 7 4 --- 9 4 --- 12 4 --- 14 4 ---- 15 - 4 <--x 17 + 4 --- 17 5 --- 24 5 x--> 26 5 --- 35 diff --git a/src/hooks/useEngineConnectionSubscriptions.ts b/src/hooks/useEngineConnectionSubscriptions.ts index a14ec7d10..c2dc95cd6 100644 --- a/src/hooks/useEngineConnectionSubscriptions.ts +++ b/src/hooks/useEngineConnectionSubscriptions.ts @@ -34,6 +34,7 @@ import type { ExtrudeFacePlane, } from '@src/machines/modelingMachine' import toast from 'react-hot-toast' +import { findAllChildrenAndOrderByPlaceInCode } from '@src/lang/modifyAst/boolean' import { localModuleSafePathSplit } from '@src/lib/paths' export function useEngineConnectionSubscriptions() { @@ -148,7 +149,7 @@ export function useEngineConnectionSubscriptions() { } sceneInfra.modelingSend({ - type: 'Select default plane', + type: 'Select sketch plane', data: { type: 'defaultPlane', planeId: planeId, @@ -165,7 +166,7 @@ export function useEngineConnectionSubscriptions() { const planeInfo = await sceneEntitiesManager.getFaceDetails(planeOrFaceId) sceneInfra.modelingSend({ - type: 'Select default plane', + type: 'Select sketch plane', data: { type: 'offsetPlane', zAxis: [ @@ -194,7 +195,7 @@ export function useEngineConnectionSubscriptions() { return } - // Artifact is likely an extrusion face + // Artifact is likely an sweep face const faceId = planeOrFaceId const extrusion = getSweepFromSuspectedSweepSurface( faceId, @@ -318,15 +319,31 @@ export function useEngineConnectionSubscriptions() { } : { type: 'wall' } + if (err(extrusion)) { + return Promise.reject( + new Error(`Extrusion is not a valid artifact: ${extrusion}`) + ) + } + + const lastChild = + findAllChildrenAndOrderByPlaceInCode( + { type: 'sweep', ...extrusion }, + kclManager.artifactGraph + )[0] || null + const lastChildCodeRef = + lastChild?.type === 'compositeSolid' + ? lastChild.codeRef.range + : null + const extrudePathToNode = !err(extrusion) ? getNodePathFromSourceRange( kclManager.ast, - extrusion.codeRef.range + lastChildCodeRef || extrusion.codeRef.range ) : [] sceneInfra.modelingSend({ - type: 'Select default plane', + type: 'Select sketch plane', data: { type: 'extrudeFace', zAxis: [z_axis.x, z_axis.y, z_axis.z], diff --git a/src/lang/modifyAst.ts b/src/lang/modifyAst.ts index ea25b1a39..0c99b9f53 100644 --- a/src/lang/modifyAst.ts +++ b/src/lang/modifyAst.ts @@ -461,7 +461,8 @@ export function sketchOnExtrudedFace( const expressionIndex = Math.max( sketchPathToNode[1][0] as number, - extrudePathToNode[1][0] as number + extrudePathToNode[1][0] as number, + node.body.length - 1 ) _node.body.splice(expressionIndex + 1, 0, newSketch) const newpathToNode: PathToNode = [ diff --git a/src/lang/modifyAst/boolean.ts b/src/lang/modifyAst/boolean.ts index a1f9cca21..07edade79 100644 --- a/src/lang/modifyAst/boolean.ts +++ b/src/lang/modifyAst/boolean.ts @@ -211,6 +211,13 @@ export function findAllChildrenAndOrderByPlaceInCode( pushToSomething(currentId, current?.segIds) } else if (current?.type === 'sweep') { pushToSomething(currentId, current?.surfaceIds) + const path = artifactGraph.get(current.pathId) + if (path && path.type === 'path') { + const compositeSolidId = path.compositeSolidId + if (compositeSolidId) { + result.push(compositeSolidId) + } + } } else if (current?.type === 'wall' || current?.type === 'cap') { pushToSomething(currentId, current?.pathIds) } else if (current?.type === 'segment') { diff --git a/src/machines/modelingMachine.ts b/src/machines/modelingMachine.ts index a09067d87..8d8722f76 100644 --- a/src/machines/modelingMachine.ts +++ b/src/machines/modelingMachine.ts @@ -305,7 +305,7 @@ export type ModelingMachineEvent = } | { type: 'Sketch On Face' } | { - type: 'Select default plane' + type: 'Select sketch plane' data: DefaultPlane | ExtrudeFacePlane | OffsetPlane } | { @@ -4255,7 +4255,7 @@ export const modelingMachine = setup({ exit: ['hide default planes', 'set selection filter to defaults'], on: { - 'Select default plane': { + 'Select sketch plane': { target: 'animating to plane', actions: ['reset sketch metadata'], }, @@ -4268,7 +4268,7 @@ export const modelingMachine = setup({ id: 'animate-to-face', input: ({ event }) => { - if (event.type !== 'Select default plane') return undefined + if (event.type !== 'Select sketch plane') return undefined return event.data },