Compare commits

...

34 Commits

Author SHA1 Message Date
c9f7336edc POC: solid_id as loft field 2025-01-08 10:45:36 -05:00
2dbe418eb6 Trigger CI 2025-01-07 16:40:07 -05:00
d6ade678f8 A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores) 2025-01-07 21:18:00 +00:00
157f199d09 Trigger CI 2025-01-07 16:06:16 -05:00
2501266c70 A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores) 2025-01-07 21:01:21 +00:00
6acd7ef275 Trigger CI 2025-01-07 15:43:29 -05:00
6a2e85aa36 A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores) 2025-01-07 20:37:32 +00:00
a48df0296b Trigger CI 2025-01-07 15:22:02 -05:00
6194fb79a5 A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores) 2025-01-07 19:15:00 +00:00
79f54bbdf4 Merge branch 'main' into pierremtb/issue4662-Point-and-click-deletion-of-Lofts-and-Offset-Planes 2025-01-07 14:01:31 -05:00
fe5be95023 Revert the migration to promise actor 2025-01-07 10:16:08 -05:00
26966361d4 Add shell deletion via feature tree test 2025-01-07 10:07:03 -05:00
e9695ff47b Passing test 2025-01-07 09:36:08 -05:00
18ccc18f24 Set reenter: false as it was originally 2025-01-07 08:58:52 -05:00
8e65fb8a4e Point-and-click deletion of Lofts and Offset Planes
Fixes #4662
2025-01-07 07:41:26 -05:00
3dd23d8e04 A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-macos-8-cores) 2025-01-06 22:08:31 +00:00
afa8f1d585 A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-16-cores) 2025-01-06 21:58:20 +00:00
64ca39b1dc Add test for loft and offset plane deletion via selection 2025-01-06 16:50:00 -05:00
bd1c993af6 Merge branch 'main' into pierremtb/issue4662-Point-and-click-deletion-of-Lofts-and-Offset-Planes 2025-01-06 13:54:52 -05:00
2b2230888d Merge branch 'main' into pierremtb/issue4662-Point-and-click-deletion-of-Lofts-and-Offset-Planes 2025-01-03 16:13:14 -05:00
5b98a53258 Merge branch 'main' into pierremtb/issue4662-Point-and-click-deletion-of-Lofts-and-Offset-Planes 2025-01-03 13:27:20 -05:00
7c2bf8164b Clean up 2025-01-03 12:34:33 -05:00
43f16b3aac Working cap selection and deletion 2025-01-03 11:47:52 -05:00
5faac34a51 Clean up rust changes, taking the sketch with the most paths 2025-01-03 10:47:45 -05:00
143cd49b42 Revert "Clean up"
This reverts commit 214763cc2b.
2025-01-03 10:11:29 -05:00
214763cc2b Clean up 2025-01-02 16:43:00 -05:00
90aa4aa64e Merge branch 'main' into pierremtb/issue4662-Point-and-click-deletion-of-Lofts-and-Offset-Planes 2025-01-02 16:32:36 -05:00
dc72284583 Add feature tree deletion of shell 2025-01-02 16:28:30 -05:00
070fe47719 Add offset plane deletion 2025-01-02 15:40:11 -05:00
29bb282b5b Working wall deletion of loft 2025-01-02 15:20:01 -05:00
2eb4eb603c WIP: working Solid3dGetExtrusionFaceInfo for loft 2025-01-02 14:50:12 -05:00
b310b18f48 Update from main 2025-01-02 12:00:09 -05:00
3628be27e8 WIP logging 2024-12-18 16:58:36 -05:00
175aa282b7 Refactor 'Delete selection' as actor
Will fix #4662
2024-12-16 14:34:56 -05:00
4 changed files with 137 additions and 16 deletions

View File

@ -854,6 +854,67 @@ loftPointAndClickCases.forEach(({ shouldPreselect }) => {
})
})
// TODO: merge with above test. Right now we're not able to delete a loft
// right after creation via selection for some reason, so we go with a new instance
test('Loft and offset plane deletion via selection', async ({
context,
page,
homePage,
scene,
}) => {
const initialCode = `sketch001 = startSketchOn('XZ')
|> circle({ center = [0, 0], radius = 30 }, %)
plane001 = offsetPlane('XZ', 50)
sketch002 = startSketchOn(plane001)
|> circle({ center = [0, 0], radius = 20 }, %)
loft001 = loft([sketch001, sketch002])
`
await context.addInitScript((initialCode) => {
localStorage.setItem('persistCode', initialCode)
}, initialCode)
await page.setBodyDimensions({ width: 1000, height: 500 })
await homePage.goToModelingScene()
// One dumb hardcoded screen pixel value
const testPoint = { x: 575, y: 200 }
const [clickOnSketch1] = scene.makeMouseHelpers(testPoint.x, testPoint.y)
const [clickOnSketch2] = scene.makeMouseHelpers(testPoint.x, testPoint.y + 80)
await test.step(`Delete loft`, async () => {
// Check for loft
await scene.expectPixelColor([89, 89, 89], testPoint, 15)
await clickOnSketch1()
await expect(page.locator('.cm-activeLine')).toHaveText(`
|> circle({ center = [0, 0], radius = 30 }, %)
`)
await page.keyboard.press('Backspace')
// Check for sketch 1
await scene.expectPixelColor([254, 254, 254], testPoint, 15)
})
await test.step('Delete sketch002', async () => {
await page.waitForTimeout(1000)
await clickOnSketch2()
await expect(page.locator('.cm-activeLine')).toHaveText(`
|> circle({ center = [0, 0], radius = 20 }, %)
`)
await page.keyboard.press('Backspace')
// Check for plane001
await scene.expectPixelColor([228, 228, 228], testPoint, 15)
})
await test.step('Delete plane001', async () => {
await page.waitForTimeout(1000)
await clickOnSketch2()
await expect(page.locator('.cm-activeLine')).toHaveText(`
plane001 = offsetPlane('XZ', 50)
`)
await page.keyboard.press('Backspace')
// Check for sketch 1
await scene.expectPixelColor([254, 254, 254], testPoint, 15)
})
})
const shellPointAndClickCapCases = [
{ shouldPreselect: true },
{ shouldPreselect: false },
@ -1030,4 +1091,12 @@ extrude001 = extrude(40, sketch001)
})
await scene.expectPixelColor([49, 49, 49], testPoint, 15)
})
await test.step('Delete shell via feature tree selection', async () => {
await editor.closePane()
const operationButton = await toolbar.getFeatureTreeOperation('Shell', 0)
await operationButton.click({ button: 'left' })
await page.keyboard.press('Backspace')
await scene.expectPixelColor([99, 99, 99], testPoint, 15)
})
})

View File

@ -1149,11 +1149,17 @@ export async function deleteFromSelection(
((selection?.artifact?.type === 'wall' ||
selection?.artifact?.type === 'cap') &&
varDec.node.init.type === 'PipeExpression') ||
selection.artifact?.type === 'sweep'
selection.artifact?.type === 'sweep' ||
selection.artifact?.type === 'plane' ||
!selection.artifact // aka expected to be a shell at this point
) {
let extrudeNameToDelete = ''
let pathToNode: PathToNode | null = null
if (selection.artifact?.type !== 'sweep') {
if (
selection.artifact &&
selection.artifact.type !== 'sweep' &&
selection.artifact.type !== 'plane'
) {
const varDecName = varDec.node.id.name
traverse(astClone, {
enter: (node, path) => {
@ -1169,6 +1175,17 @@ export async function deleteFromSelection(
pathToNode = path
extrudeNameToDelete = dec.id.name
}
if (
dec.init.type === 'CallExpression' &&
dec.init.callee.name === 'loft' &&
dec.init.arguments?.[0].type === 'ArrayExpression' &&
dec.init.arguments?.[0].elements.some(
(a) => a.type === 'Identifier' && a.name === varDecName
)
) {
pathToNode = path
extrudeNameToDelete = dec.id.name
}
}
},
})

View File

@ -69,7 +69,7 @@ interface SegmentArtifactRich extends BaseArtifact {
/** A Sweep is a more generic term for extrude, revolve, loft and sweep*/
interface SweepArtifact extends BaseArtifact {
type: 'sweep'
subType: 'extrusion' | 'revolve'
subType: 'extrusion' | 'revolve' | 'loft'
pathId: string
surfaceIds: Array<string>
edgeIds: Array<string>
@ -77,7 +77,7 @@ interface SweepArtifact extends BaseArtifact {
}
interface SweepArtifactRich extends BaseArtifact {
type: 'sweep'
subType: 'extrusion' | 'revolve'
subType: 'extrusion' | 'revolve' | 'loft'
path: PathArtifact
surfaces: Array<WallArtifact | CapArtifact>
edges: Array<SweepEdge>
@ -393,6 +393,33 @@ export function getArtifactsToUpdate({
artifact: { ...path, sweepId: id },
})
return returnArr
} else if (
cmd.type === 'loft' &&
response.type === 'modeling' &&
response.data.modeling_response.type === 'loft'
) {
returnArr.push({
id,
artifact: {
type: 'sweep',
subType: 'loft',
id,
// TODO: make sure this is the right one to give here
pathId: cmd.section_ids[0],
surfaceIds: [],
edgeIds: [],
codeRef: { range, pathToNode },
},
})
for (const sectionId of cmd.section_ids) {
const path = getArtifact(sectionId)
if (path?.type === 'path')
returnArr.push({
id: sectionId,
artifact: { ...path, sweepId: id },
})
}
return returnArr
} else if (
cmd.type === 'solid3d_get_extrusion_face_info' &&
response?.type === 'modeling' &&

View File

@ -143,18 +143,26 @@ async fn inner_loft(
}
let id = exec_state.next_uuid();
let solid_id = exec_state.next_uuid();
// TODO: get engine team to add the solid_id field
args.batch_modeling_cmd(
id,
ModelingCmd::from(mcmd::Loft {
section_ids: sketches.iter().map(|group| group.id).collect(),
base_curve_index,
bez_approximate_rational,
tolerance: LengthUnit(tolerance.unwrap_or(default_tolerance(&args.ctx.settings.units))),
v_degree,
}),
)
.await?;
id,
ModelingCmd::from(mcmd::Loft {
section_ids: sketches.iter().map(|group| group.id).collect(),
base_curve_index,
bez_approximate_rational,
tolerance: LengthUnit(tolerance.unwrap_or(default_tolerance(&args.ctx.settings.units))),
v_degree,
solid_id,
}),
)
.await?;
// Using the first sketch as the base curve, idk we might want to change this later.
do_post_extrude(sketches[0].clone(), 0.0, exec_state, args).await
// Take the sketch with the most paths, as its edges are spawning the loft faces
let mut desc_sorted_sketches = sketches.to_vec();
desc_sorted_sketches.sort_by(|s0, s1| s1.paths.len().cmp(&s0.paths.len()));
let mut sketch = desc_sorted_sketches[0].clone();
// Overwrite the sketch id with the loft id, so it gets picked up to get the face info in post_extrude
sketch.id = solid_id;
do_post_extrude(sketch, 0.0, exec_state, args).await
}