Compare commits
34 Commits
nested_dir
...
pierremtb/
Author | SHA1 | Date | |
---|---|---|---|
c9f7336edc | |||
2dbe418eb6 | |||
d6ade678f8 | |||
157f199d09 | |||
2501266c70 | |||
6acd7ef275 | |||
6a2e85aa36 | |||
a48df0296b | |||
6194fb79a5 | |||
79f54bbdf4 | |||
fe5be95023 | |||
26966361d4 | |||
e9695ff47b | |||
18ccc18f24 | |||
8e65fb8a4e | |||
3dd23d8e04 | |||
afa8f1d585 | |||
64ca39b1dc | |||
bd1c993af6 | |||
2b2230888d | |||
5b98a53258 | |||
7c2bf8164b | |||
43f16b3aac | |||
5faac34a51 | |||
143cd49b42 | |||
214763cc2b | |||
90aa4aa64e | |||
dc72284583 | |||
070fe47719 | |||
29bb282b5b | |||
2eb4eb603c | |||
b310b18f48 | |||
3628be27e8 | |||
175aa282b7 |
@ -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 = [
|
const shellPointAndClickCapCases = [
|
||||||
{ shouldPreselect: true },
|
{ shouldPreselect: true },
|
||||||
{ shouldPreselect: false },
|
{ shouldPreselect: false },
|
||||||
@ -1030,4 +1091,12 @@ extrude001 = extrude(40, sketch001)
|
|||||||
})
|
})
|
||||||
await scene.expectPixelColor([49, 49, 49], testPoint, 15)
|
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)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
@ -1149,11 +1149,17 @@ export async function deleteFromSelection(
|
|||||||
((selection?.artifact?.type === 'wall' ||
|
((selection?.artifact?.type === 'wall' ||
|
||||||
selection?.artifact?.type === 'cap') &&
|
selection?.artifact?.type === 'cap') &&
|
||||||
varDec.node.init.type === 'PipeExpression') ||
|
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 extrudeNameToDelete = ''
|
||||||
let pathToNode: PathToNode | null = null
|
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
|
const varDecName = varDec.node.id.name
|
||||||
traverse(astClone, {
|
traverse(astClone, {
|
||||||
enter: (node, path) => {
|
enter: (node, path) => {
|
||||||
@ -1169,6 +1175,17 @@ export async function deleteFromSelection(
|
|||||||
pathToNode = path
|
pathToNode = path
|
||||||
extrudeNameToDelete = dec.id.name
|
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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
@ -69,7 +69,7 @@ interface SegmentArtifactRich extends BaseArtifact {
|
|||||||
/** A Sweep is a more generic term for extrude, revolve, loft and sweep*/
|
/** A Sweep is a more generic term for extrude, revolve, loft and sweep*/
|
||||||
interface SweepArtifact extends BaseArtifact {
|
interface SweepArtifact extends BaseArtifact {
|
||||||
type: 'sweep'
|
type: 'sweep'
|
||||||
subType: 'extrusion' | 'revolve'
|
subType: 'extrusion' | 'revolve' | 'loft'
|
||||||
pathId: string
|
pathId: string
|
||||||
surfaceIds: Array<string>
|
surfaceIds: Array<string>
|
||||||
edgeIds: Array<string>
|
edgeIds: Array<string>
|
||||||
@ -77,7 +77,7 @@ interface SweepArtifact extends BaseArtifact {
|
|||||||
}
|
}
|
||||||
interface SweepArtifactRich extends BaseArtifact {
|
interface SweepArtifactRich extends BaseArtifact {
|
||||||
type: 'sweep'
|
type: 'sweep'
|
||||||
subType: 'extrusion' | 'revolve'
|
subType: 'extrusion' | 'revolve' | 'loft'
|
||||||
path: PathArtifact
|
path: PathArtifact
|
||||||
surfaces: Array<WallArtifact | CapArtifact>
|
surfaces: Array<WallArtifact | CapArtifact>
|
||||||
edges: Array<SweepEdge>
|
edges: Array<SweepEdge>
|
||||||
@ -393,6 +393,33 @@ export function getArtifactsToUpdate({
|
|||||||
artifact: { ...path, sweepId: id },
|
artifact: { ...path, sweepId: id },
|
||||||
})
|
})
|
||||||
return returnArr
|
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 (
|
} else if (
|
||||||
cmd.type === 'solid3d_get_extrusion_face_info' &&
|
cmd.type === 'solid3d_get_extrusion_face_info' &&
|
||||||
response?.type === 'modeling' &&
|
response?.type === 'modeling' &&
|
||||||
|
@ -143,6 +143,8 @@ async fn inner_loft(
|
|||||||
}
|
}
|
||||||
|
|
||||||
let id = exec_state.next_uuid();
|
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(
|
args.batch_modeling_cmd(
|
||||||
id,
|
id,
|
||||||
ModelingCmd::from(mcmd::Loft {
|
ModelingCmd::from(mcmd::Loft {
|
||||||
@ -151,10 +153,16 @@ async fn inner_loft(
|
|||||||
bez_approximate_rational,
|
bez_approximate_rational,
|
||||||
tolerance: LengthUnit(tolerance.unwrap_or(default_tolerance(&args.ctx.settings.units))),
|
tolerance: LengthUnit(tolerance.unwrap_or(default_tolerance(&args.ctx.settings.units))),
|
||||||
v_degree,
|
v_degree,
|
||||||
|
solid_id,
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
// Using the first sketch as the base curve, idk we might want to change this later.
|
// Take the sketch with the most paths, as its edges are spawning the loft faces
|
||||||
do_post_extrude(sketches[0].clone(), 0.0, exec_state, args).await
|
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
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user