profile start constrain overlays (#6795)
* constrain profile start * add test * make sure it works on segment drag too, fix tests * remove old log * some tests fixes * Bump more segment counters * Two more fixes * Two more test fixes * small test fix * moretest fixes * another test --------- Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com> Co-authored-by: Pierre Jacquier <pierre@zoo.dev>
This commit is contained in:
@ -138,7 +138,9 @@ extrude001 = extrude(sketch001, length = 5)`
|
|||||||
|
|
||||||
// Ensure badge is present
|
// Ensure badge is present
|
||||||
const codePaneButtonHolder = page.locator('#code-button-holder')
|
const codePaneButtonHolder = page.locator('#code-button-holder')
|
||||||
await expect(codePaneButtonHolder).toContainText('notification')
|
await expect(codePaneButtonHolder).toContainText('notification', {
|
||||||
|
timeout: 20_000,
|
||||||
|
})
|
||||||
|
|
||||||
// Ensure we have no errors in the gutter, since error out of view.
|
// Ensure we have no errors in the gutter, since error out of view.
|
||||||
await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible()
|
await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible()
|
||||||
|
@ -1180,6 +1180,8 @@ sketch001 = startSketchOn(XZ)
|
|||||||
page,
|
page,
|
||||||
homePage,
|
homePage,
|
||||||
editor,
|
editor,
|
||||||
|
scene,
|
||||||
|
cmdBar,
|
||||||
}) => {
|
}) => {
|
||||||
const u = await getUtils(page)
|
const u = await getUtils(page)
|
||||||
await page.addInitScript(async () => {
|
await page.addInitScript(async () => {
|
||||||
@ -1198,9 +1200,7 @@ sketch001 = startSketchOn(XZ)
|
|||||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||||
|
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await expect(
|
await scene.settled(cmdBar)
|
||||||
page.getByRole('button', { name: 'Start Sketch' })
|
|
||||||
).not.toBeDisabled()
|
|
||||||
|
|
||||||
await page.waitForTimeout(100)
|
await page.waitForTimeout(100)
|
||||||
await u.openAndClearDebugPanel()
|
await u.openAndClearDebugPanel()
|
||||||
@ -1236,7 +1236,7 @@ sketch001 = startSketchOn(XZ)
|
|||||||
await page.waitForTimeout(400)
|
await page.waitForTimeout(400)
|
||||||
let prevContent = await page.locator('.cm-content').innerText()
|
let prevContent = await page.locator('.cm-content').innerText()
|
||||||
|
|
||||||
await expect(page.getByTestId('segment-overlay')).toHaveCount(2)
|
await expect(page.getByTestId('segment-overlay')).toHaveCount(3)
|
||||||
|
|
||||||
// drag startProfileAt handle
|
// drag startProfileAt handle
|
||||||
await page.dragAndDrop('#stream', '#stream', {
|
await page.dragAndDrop('#stream', '#stream', {
|
||||||
@ -1278,9 +1278,9 @@ sketch001 = startSketchOn(XZ)
|
|||||||
// expect the code to have changed
|
// expect the code to have changed
|
||||||
await editor.expectEditor.toContain(
|
await editor.expectEditor.toContain(
|
||||||
`sketch001 = startSketchOn(XZ)
|
`sketch001 = startSketchOn(XZ)
|
||||||
|> startProfile(at = [2.71, -2.71])
|
|> startProfile(at = [5.36, -5.36])
|
||||||
|> line(end = [15.4, -2.78])
|
|> line(end = [12.73, -0.09])
|
||||||
|> tangentialArc(endAbsolute = [27.6, -3.05])
|
|> tangentialArc(endAbsolute = [24.95, -0.38])
|
||||||
|> close()
|
|> close()
|
||||||
|> extrude(length = 5)`,
|
|> extrude(length = 5)`,
|
||||||
{ shouldNormalise: true }
|
{ shouldNormalise: true }
|
||||||
@ -1294,7 +1294,7 @@ sketch001 = startSketchOn(XZ)
|
|||||||
await editor.expectEditor.toContain(
|
await editor.expectEditor.toContain(
|
||||||
`sketch001 = startSketchOn(XZ)
|
`sketch001 = startSketchOn(XZ)
|
||||||
|> startProfile(at = [2.71, -2.71])
|
|> startProfile(at = [2.71, -2.71])
|
||||||
|> line(end = [15.4, -2.78])
|
|> line(end = [12.73, -0.09])
|
||||||
|> tangentialArc(endAbsolute = [24.95, -0.38])
|
|> tangentialArc(endAbsolute = [24.95, -0.38])
|
||||||
|> close()
|
|> close()
|
||||||
|> extrude(length = 5)`,
|
|> extrude(length = 5)`,
|
||||||
@ -1308,7 +1308,7 @@ sketch001 = startSketchOn(XZ)
|
|||||||
|
|
||||||
await editor.expectEditor.toContain(
|
await editor.expectEditor.toContain(
|
||||||
`sketch001 = startSketchOn(XZ)
|
`sketch001 = startSketchOn(XZ)
|
||||||
|> startProfile(at = [2.71, -2.71])
|
|> startProfile(at = [4.61, -10.01])
|
||||||
|> line(end = [12.73, -0.09])
|
|> line(end = [12.73, -0.09])
|
||||||
|> tangentialArc(endAbsolute = [24.95, -0.38])
|
|> tangentialArc(endAbsolute = [24.95, -0.38])
|
||||||
|> close()
|
|> close()
|
||||||
@ -1505,7 +1505,7 @@ sketch001 = startSketchOn(XZ)
|
|||||||
await page.waitForTimeout(1000)
|
await page.waitForTimeout(1000)
|
||||||
|
|
||||||
// Verify segment is selected (you can check for visual indicators or state)
|
// Verify segment is selected (you can check for visual indicators or state)
|
||||||
const element = page.locator('[data-overlay-index="1"]')
|
const element = page.locator('[data-overlay-index="2"]')
|
||||||
await expect(element).toHaveAttribute('data-overlay-visible', 'true')
|
await expect(element).toHaveAttribute('data-overlay-visible', 'true')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -543,6 +543,9 @@ sketch001 = startSketchOn(XZ)
|
|||||||
page,
|
page,
|
||||||
homePage,
|
homePage,
|
||||||
editor,
|
editor,
|
||||||
|
toolbar,
|
||||||
|
scene,
|
||||||
|
cmdBar,
|
||||||
}) => {
|
}) => {
|
||||||
const u = await getUtils(page)
|
const u = await getUtils(page)
|
||||||
await page.addInitScript(async () => {
|
await page.addInitScript(async () => {
|
||||||
@ -559,10 +562,12 @@ sketch001 = startSketchOn(XZ)
|
|||||||
})
|
})
|
||||||
|
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
|
await toolbar.waitForFeatureTreeToBeBuilt()
|
||||||
|
await scene.settled(cmdBar)
|
||||||
|
|
||||||
await expect(
|
await expect(
|
||||||
page.getByRole('button', { name: 'Start Sketch' })
|
page.getByRole('button', { name: 'Start Sketch' })
|
||||||
).not.toBeDisabled()
|
).not.toBeDisabled({ timeout: 10_000 })
|
||||||
|
|
||||||
await page.waitForTimeout(100)
|
await page.waitForTimeout(100)
|
||||||
await u.openAndClearDebugPanel()
|
await u.openAndClearDebugPanel()
|
||||||
@ -598,7 +603,7 @@ sketch001 = startSketchOn(XZ)
|
|||||||
await page.waitForTimeout(400)
|
await page.waitForTimeout(400)
|
||||||
let prevContent = await page.locator('.cm-content').innerText()
|
let prevContent = await page.locator('.cm-content').innerText()
|
||||||
|
|
||||||
await expect(page.getByTestId('segment-overlay')).toHaveCount(2)
|
await expect(page.getByTestId('segment-overlay')).toHaveCount(3)
|
||||||
|
|
||||||
// drag startProfileAt handle
|
// drag startProfileAt handle
|
||||||
await page.dragAndDrop('#stream', '#stream', {
|
await page.dragAndDrop('#stream', '#stream', {
|
||||||
@ -612,7 +617,7 @@ sketch001 = startSketchOn(XZ)
|
|||||||
// drag line handle
|
// drag line handle
|
||||||
await page.waitForTimeout(100)
|
await page.waitForTimeout(100)
|
||||||
|
|
||||||
const lineEnd = await u.getBoundingBox('[data-overlay-index="0"]')
|
const lineEnd = await u.getBoundingBox('[data-overlay-index="1"]')
|
||||||
await page.dragAndDrop('#stream', '#stream', {
|
await page.dragAndDrop('#stream', '#stream', {
|
||||||
sourcePosition: { x: lineEnd.x - 15, y: lineEnd.y },
|
sourcePosition: { x: lineEnd.x - 15, y: lineEnd.y },
|
||||||
targetPosition: { x: lineEnd.x, y: lineEnd.y + 15 },
|
targetPosition: { x: lineEnd.x, y: lineEnd.y + 15 },
|
||||||
@ -622,7 +627,7 @@ sketch001 = startSketchOn(XZ)
|
|||||||
prevContent = await page.locator('.cm-content').innerText()
|
prevContent = await page.locator('.cm-content').innerText()
|
||||||
|
|
||||||
// drag tangentialArc handle
|
// drag tangentialArc handle
|
||||||
const tangentEnd = await u.getBoundingBox('[data-overlay-index="1"]')
|
const tangentEnd = await u.getBoundingBox('[data-overlay-index="0"]')
|
||||||
await page.dragAndDrop('#stream', '#stream', {
|
await page.dragAndDrop('#stream', '#stream', {
|
||||||
sourcePosition: { x: tangentEnd.x + 10, y: tangentEnd.y - 5 },
|
sourcePosition: { x: tangentEnd.x + 10, y: tangentEnd.y - 5 },
|
||||||
targetPosition: {
|
targetPosition: {
|
||||||
@ -638,7 +643,7 @@ sketch001 = startSketchOn(XZ)
|
|||||||
`sketch001 = startSketchOn(XZ)
|
`sketch001 = startSketchOn(XZ)
|
||||||
|> startProfile(at = [7.12, -12.68])
|
|> startProfile(at = [7.12, -12.68])
|
||||||
|> line(end = [12.68, -1.09])
|
|> line(end = [12.68, -1.09])
|
||||||
|> tangentialArc(endAbsolute = [24.89, 0.68])
|
|> tangentialArc(endAbsolute = [24.95, -0.38])
|
||||||
|> close()
|
|> close()
|
||||||
|> extrude(length = 5)`,
|
|> extrude(length = 5)`,
|
||||||
{ shouldNormalise: true }
|
{ shouldNormalise: true }
|
||||||
@ -709,7 +714,7 @@ sketch001 = startSketchOn(XZ)
|
|||||||
|
|
||||||
const step5 = { steps: 5 }
|
const step5 = { steps: 5 }
|
||||||
|
|
||||||
await expect(page.getByTestId('segment-overlay')).toHaveCount(2)
|
await expect(page.getByTestId('segment-overlay')).toHaveCount(3)
|
||||||
|
|
||||||
// drag startProfileAt handle
|
// drag startProfileAt handle
|
||||||
await page.mouse.move(startPX[0], startPX[1])
|
await page.mouse.move(startPX[0], startPX[1])
|
||||||
@ -744,10 +749,10 @@ sketch001 = startSketchOn(XZ)
|
|||||||
// expect the code to have changed
|
// expect the code to have changed
|
||||||
await editor.expectEditor.toContain(
|
await editor.expectEditor.toContain(
|
||||||
`sketch001 = startSketchOn(XZ)
|
`sketch001 = startSketchOn(XZ)
|
||||||
|> startProfile(at = [6.44, -12.07])
|
|> startProfile(at = [8.41, -9.97])
|
||||||
|> line(end = [14.72, 1.97])
|
|> line(end = [12.73, -0.09])
|
||||||
|
|> line(end = [1.99, 2.06])
|
||||||
|> tangentialArc(endAbsolute = [24.95, -5.38])
|
|> tangentialArc(endAbsolute = [24.95, -5.38])
|
||||||
|> line(end = [1.97, 2.06])
|
|
||||||
|> close()
|
|> close()
|
||||||
|> revolve(axis = X)`,
|
|> revolve(axis = X)`,
|
||||||
{ shouldNormalise: true }
|
{ shouldNormalise: true }
|
||||||
|
@ -108,7 +108,7 @@ test.describe('Testing constraints', () => {
|
|||||||
// Wait for overlays to populate
|
// Wait for overlays to populate
|
||||||
await page.waitForTimeout(1000)
|
await page.waitForTimeout(1000)
|
||||||
|
|
||||||
const line3 = await u.getSegmentBodyCoords(`[data-overlay-index="${2}"]`)
|
const line3 = await u.getSegmentBodyCoords(`[data-overlay-index="${3}"]`)
|
||||||
|
|
||||||
await page.mouse.click(line3.x, line3.y)
|
await page.mouse.click(line3.x, line3.y)
|
||||||
await page.waitForTimeout(100) // this wait is needed for webkit - not sure why
|
await page.waitForTimeout(100) // this wait is needed for webkit - not sure why
|
||||||
@ -127,7 +127,7 @@ test.describe('Testing constraints', () => {
|
|||||||
)
|
)
|
||||||
|
|
||||||
// checking the count of the overlays is a good proxy check that the client sketch scene is in a good state
|
// checking the count of the overlays is a good proxy check that the client sketch scene is in a good state
|
||||||
await expect(page.getByTestId('segment-overlay')).toHaveCount(4)
|
await expect(page.getByTestId('segment-overlay')).toHaveCount(5)
|
||||||
})
|
})
|
||||||
test.describe('Test perpendicular distance constraint', () => {
|
test.describe('Test perpendicular distance constraint', () => {
|
||||||
const cases = [
|
const cases = [
|
||||||
@ -174,8 +174,8 @@ test.describe('Testing constraints', () => {
|
|||||||
await page.waitForTimeout(1000)
|
await page.waitForTimeout(1000)
|
||||||
|
|
||||||
const [line1, line3] = await Promise.all([
|
const [line1, line3] = await Promise.all([
|
||||||
u.getSegmentBodyCoords(`[data-overlay-index="${0}"]`),
|
u.getSegmentBodyCoords(`[data-overlay-index="${1}"]`),
|
||||||
u.getSegmentBodyCoords(`[data-overlay-index="${2}"]`),
|
u.getSegmentBodyCoords(`[data-overlay-index="${3}"]`),
|
||||||
])
|
])
|
||||||
|
|
||||||
await page.mouse.click(line1.x, line1.y)
|
await page.mouse.click(line1.x, line1.y)
|
||||||
@ -223,7 +223,7 @@ test.describe('Testing constraints', () => {
|
|||||||
)
|
)
|
||||||
|
|
||||||
// checking the count of the overlays is a good proxy check that the client sketch scene is in a good state
|
// checking the count of the overlays is a good proxy check that the client sketch scene is in a good state
|
||||||
await expect(page.getByTestId('segment-overlay')).toHaveCount(4)
|
await expect(page.getByTestId('segment-overlay')).toHaveCount(5)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -289,8 +289,8 @@ test.describe('Testing constraints', () => {
|
|||||||
await page.waitForTimeout(1000)
|
await page.waitForTimeout(1000)
|
||||||
|
|
||||||
const [line1, line3] = await Promise.all([
|
const [line1, line3] = await Promise.all([
|
||||||
u.getSegmentBodyCoords(`[data-overlay-index="${0}"]`),
|
u.getSegmentBodyCoords(`[data-overlay-index="${1}"]`),
|
||||||
u.getSegmentBodyCoords(`[data-overlay-index="${2}"]`),
|
u.getSegmentBodyCoords(`[data-overlay-index="${3}"]`),
|
||||||
])
|
])
|
||||||
|
|
||||||
await page.mouse.click(line1.x, line1.y)
|
await page.mouse.click(line1.x, line1.y)
|
||||||
@ -335,7 +335,7 @@ test.describe('Testing constraints', () => {
|
|||||||
)
|
)
|
||||||
|
|
||||||
// checking the count of the overlays is a good proxy check that the client sketch scene is in a good state
|
// checking the count of the overlays is a good proxy check that the client sketch scene is in a good state
|
||||||
await expect(page.getByTestId('segment-overlay')).toHaveCount(4)
|
await expect(page.getByTestId('segment-overlay')).toHaveCount(5)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -405,7 +405,7 @@ test.describe('Testing constraints', () => {
|
|||||||
await page.waitForTimeout(1000)
|
await page.waitForTimeout(1000)
|
||||||
|
|
||||||
const [line3] = await Promise.all([
|
const [line3] = await Promise.all([
|
||||||
u.getSegmentBodyCoords(`[data-overlay-index="${2}"]`),
|
u.getSegmentBodyCoords(`[data-overlay-index="${3}"]`),
|
||||||
])
|
])
|
||||||
|
|
||||||
if (constraint === 'Absolute X') {
|
if (constraint === 'Absolute X') {
|
||||||
@ -454,7 +454,7 @@ test.describe('Testing constraints', () => {
|
|||||||
)
|
)
|
||||||
|
|
||||||
// checking the count of the overlays is a good proxy check that the client sketch scene is in a good state
|
// checking the count of the overlays is a good proxy check that the client sketch scene is in a good state
|
||||||
await expect(page.getByTestId('segment-overlay')).toHaveCount(4)
|
await expect(page.getByTestId('segment-overlay')).toHaveCount(5)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -519,8 +519,8 @@ test.describe('Testing constraints', () => {
|
|||||||
await page.waitForTimeout(1000)
|
await page.waitForTimeout(1000)
|
||||||
|
|
||||||
const [line1, line3] = await Promise.all([
|
const [line1, line3] = await Promise.all([
|
||||||
u.getSegmentBodyCoords(`[data-overlay-index="${0}"]`),
|
u.getSegmentBodyCoords(`[data-overlay-index="${1}"]`),
|
||||||
u.getSegmentBodyCoords(`[data-overlay-index="${2}"]`),
|
u.getSegmentBodyCoords(`[data-overlay-index="${3}"]`),
|
||||||
])
|
])
|
||||||
|
|
||||||
if (axisSelect) {
|
if (axisSelect) {
|
||||||
@ -569,7 +569,7 @@ test.describe('Testing constraints', () => {
|
|||||||
)
|
)
|
||||||
|
|
||||||
// checking the count of the overlays is a good proxy check that the client sketch scene is in a good state
|
// checking the count of the overlays is a good proxy check that the client sketch scene is in a good state
|
||||||
await expect(page.getByTestId('segment-overlay')).toHaveCount(4)
|
await expect(page.getByTestId('segment-overlay')).toHaveCount(5)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -622,7 +622,7 @@ test.describe('Testing constraints', () => {
|
|||||||
await page.waitForTimeout(1000)
|
await page.waitForTimeout(1000)
|
||||||
|
|
||||||
const line3 = await u.getSegmentBodyCoords(
|
const line3 = await u.getSegmentBodyCoords(
|
||||||
`[data-overlay-index="${2}"]`
|
`[data-overlay-index="${3}"]`
|
||||||
)
|
)
|
||||||
|
|
||||||
await page.mouse.click(line3.x, line3.y)
|
await page.mouse.click(line3.x, line3.y)
|
||||||
@ -647,7 +647,7 @@ test.describe('Testing constraints', () => {
|
|||||||
await expect(page.locator('.cm-activeLine')).toHaveText(changedCode)
|
await expect(page.locator('.cm-activeLine')).toHaveText(changedCode)
|
||||||
|
|
||||||
// checking the count of the overlays is a good proxy check that the client sketch scene is in a good state
|
// checking the count of the overlays is a good proxy check that the client sketch scene is in a good state
|
||||||
await expect(page.getByTestId('segment-overlay')).toHaveCount(4)
|
await expect(page.getByTestId('segment-overlay')).toHaveCount(5)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -715,7 +715,7 @@ part002 = startSketchOn(XZ)
|
|||||||
await page.getByRole('button', { name: 'Edit Sketch' }).click()
|
await page.getByRole('button', { name: 'Edit Sketch' }).click()
|
||||||
|
|
||||||
const line3 = await u.getSegmentBodyCoords(
|
const line3 = await u.getSegmentBodyCoords(
|
||||||
`[data-overlay-index="${2}"]`
|
`[data-overlay-index="${3}"]`
|
||||||
)
|
)
|
||||||
|
|
||||||
await page.mouse.click(line3.x, line3.y)
|
await page.mouse.click(line3.x, line3.y)
|
||||||
@ -733,16 +733,17 @@ part002 = startSketchOn(XZ)
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
await expect(cmdBarKclInput).toHaveText('78.33')
|
await expect(cmdBarKclInput).toHaveText('78.33')
|
||||||
await cmdBarSubmitButton.click()
|
await page.waitForTimeout(500)
|
||||||
|
|
||||||
const [ang, len] = value.split(', ')
|
const [ang, len] = value.split(', ')
|
||||||
const changedCode = `|> angledLine(angle = ${ang}, length = ${len})`
|
const changedCode = `|> angledLine(angle = ${ang}, length = ${len})`
|
||||||
|
await cmdBarSubmitButton.click()
|
||||||
await expect(page.locator('.cm-content')).toContainText(changedCode)
|
await expect(page.locator('.cm-content')).toContainText(changedCode)
|
||||||
|
|
||||||
// checking active assures the cursor is where it should be
|
// checking active assures the cursor is where it should be
|
||||||
await expect(page.locator('.cm-activeLine')).toHaveText(changedCode)
|
await expect(page.locator('.cm-activeLine')).toHaveText(changedCode)
|
||||||
|
|
||||||
// checking the count of the overlays is a good proxy check that the client sketch scene is in a good state
|
// checking the count of the overlays is a good proxy check that the client sketch scene is in a good state
|
||||||
await expect(page.getByTestId('segment-overlay')).toHaveCount(4)
|
await expect(page.getByTestId('segment-overlay')).toHaveCount(5)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -799,13 +800,13 @@ part002 = startSketchOn(XZ)
|
|||||||
await page.waitForTimeout(1000)
|
await page.waitForTimeout(1000)
|
||||||
|
|
||||||
const line1 = await u.getSegmentBodyCoords(
|
const line1 = await u.getSegmentBodyCoords(
|
||||||
`[data-overlay-index="${0}"]`
|
`[data-overlay-index="${1}"]`
|
||||||
)
|
)
|
||||||
const line3 = await u.getSegmentBodyCoords(
|
const line3 = await u.getSegmentBodyCoords(
|
||||||
`[data-overlay-index="${2}"]`
|
`[data-overlay-index="${3}"]`
|
||||||
)
|
)
|
||||||
const line4 = await u.getSegmentBodyCoords(
|
const line4 = await u.getSegmentBodyCoords(
|
||||||
`[data-overlay-index="${3}"]`
|
`[data-overlay-index="${4}"]`
|
||||||
)
|
)
|
||||||
|
|
||||||
// select two segments by holding down shift
|
// select two segments by holding down shift
|
||||||
@ -899,8 +900,8 @@ part002 = startSketchOn(XZ)
|
|||||||
// Wait for overlays to populate
|
// Wait for overlays to populate
|
||||||
await page.waitForTimeout(1000)
|
await page.waitForTimeout(1000)
|
||||||
|
|
||||||
const line1 = await u.getBoundingBox(`[data-overlay-index="${0}"]`)
|
const line1 = await u.getBoundingBox(`[data-overlay-index="${1}"]`)
|
||||||
const line3 = await u.getBoundingBox(`[data-overlay-index="${2}"]`)
|
const line3 = await u.getBoundingBox(`[data-overlay-index="${3}"]`)
|
||||||
|
|
||||||
// select two segments by holding down shift
|
// select two segments by holding down shift
|
||||||
await page.mouse.click(line1.x - 20, line1.y + 20)
|
await page.mouse.click(line1.x - 20, line1.y + 20)
|
||||||
@ -981,7 +982,7 @@ part002 = startSketchOn(XZ)
|
|||||||
// Wait for overlays to populate
|
// Wait for overlays to populate
|
||||||
await page.waitForTimeout(1000)
|
await page.waitForTimeout(1000)
|
||||||
|
|
||||||
const line3 = await u.getBoundingBox(`[data-overlay-index="${2}"]`)
|
const line3 = await u.getBoundingBox(`[data-overlay-index="${3}"]`)
|
||||||
|
|
||||||
// select segment and axis by holding down shift
|
// select segment and axis by holding down shift
|
||||||
await page.mouse.click(line3.x - 3, line3.y + 20)
|
await page.mouse.click(line3.x - 3, line3.y + 20)
|
||||||
@ -1044,7 +1045,7 @@ part002 = startSketchOn(XZ)
|
|||||||
|
|
||||||
await page.waitForTimeout(100)
|
await page.waitForTimeout(100)
|
||||||
const lineBefore = await u.getSegmentBodyCoords(
|
const lineBefore = await u.getSegmentBodyCoords(
|
||||||
`[data-overlay-index="1"]`,
|
`[data-overlay-index="2"]`,
|
||||||
0
|
0
|
||||||
)
|
)
|
||||||
expect(
|
expect(
|
||||||
@ -1075,15 +1076,15 @@ part002 = startSketchOn(XZ)
|
|||||||
|
|
||||||
// If the overlay-angle is updated the THREE.js scene is in a good state
|
// If the overlay-angle is updated the THREE.js scene is in a good state
|
||||||
await expect(
|
await expect(
|
||||||
await page.locator('[data-overlay-index="1"]')
|
await page.locator('[data-overlay-index="2"]')
|
||||||
).toHaveAttribute('data-overlay-angle', '0')
|
).toHaveAttribute('data-overlay-angle', '0')
|
||||||
|
|
||||||
const lineAfter = await u.getSegmentBodyCoords(
|
const lineAfter = await u.getSegmentBodyCoords(
|
||||||
`[data-overlay-index="1"]`,
|
`[data-overlay-index="2"]`,
|
||||||
0
|
0
|
||||||
)
|
)
|
||||||
|
|
||||||
const linebb = await u.getBoundingBox('[data-overlay-index="1"]')
|
const linebb = await u.getBoundingBox('[data-overlay-index="2"]')
|
||||||
await page.mouse.move(linebb.x, linebb.y, { steps: 25 })
|
await page.mouse.move(linebb.x, linebb.y, { steps: 25 })
|
||||||
await page.mouse.click(linebb.x, linebb.y)
|
await page.mouse.click(linebb.x, linebb.y)
|
||||||
|
|
||||||
@ -1097,6 +1098,7 @@ part002 = startSketchOn(XZ)
|
|||||||
await page.waitForTimeout(200)
|
await page.waitForTimeout(200)
|
||||||
// await page.getByRole('button', { name: 'length', exact: true }).click()
|
// await page.getByRole('button', { name: 'length', exact: true }).click()
|
||||||
await page.getByTestId('constraint-length').click()
|
await page.getByTestId('constraint-length').click()
|
||||||
|
await page.waitForTimeout(500)
|
||||||
|
|
||||||
await page.getByTestId('cmd-bar-arg-value').getByRole('textbox').fill('10')
|
await page.getByTestId('cmd-bar-arg-value').getByRole('textbox').fill('10')
|
||||||
await page
|
await page
|
||||||
@ -1112,7 +1114,7 @@ part002 = startSketchOn(XZ)
|
|||||||
)
|
)
|
||||||
|
|
||||||
// checking the count of the overlays is a good proxy check that the client sketch scene is in a good state
|
// checking the count of the overlays is a good proxy check that the client sketch scene is in a good state
|
||||||
await expect(page.getByTestId('segment-overlay')).toHaveCount(2)
|
await expect(page.getByTestId('segment-overlay')).toHaveCount(3)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
test.describe('Electron constraint tests', () => {
|
test.describe('Electron constraint tests', () => {
|
||||||
|
@ -691,7 +691,13 @@ test.describe('Testing segment overlays', () => {
|
|||||||
locator: '[data-overlay-toolbar-index="11"]',
|
locator: '[data-overlay-toolbar-index="11"]',
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
test('for segment [tangentialArc]', async ({ page, editor, homePage }) => {
|
test('for segment [tangentialArc]', async ({
|
||||||
|
page,
|
||||||
|
editor,
|
||||||
|
homePage,
|
||||||
|
scene,
|
||||||
|
cmdBar,
|
||||||
|
}) => {
|
||||||
await page.addInitScript(async () => {
|
await page.addInitScript(async () => {
|
||||||
localStorage.setItem(
|
localStorage.setItem(
|
||||||
'persistCode',
|
'persistCode',
|
||||||
@ -719,6 +725,7 @@ test.describe('Testing segment overlays', () => {
|
|||||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||||
|
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
|
await scene.settled(cmdBar)
|
||||||
|
|
||||||
// wait for execution done
|
// wait for execution done
|
||||||
await u.openDebugPanel()
|
await u.openDebugPanel()
|
||||||
@ -730,13 +737,13 @@ test.describe('Testing segment overlays', () => {
|
|||||||
await page.getByRole('button', { name: 'Edit Sketch' }).click()
|
await page.getByRole('button', { name: 'Edit Sketch' }).click()
|
||||||
await page.waitForTimeout(500)
|
await page.waitForTimeout(500)
|
||||||
|
|
||||||
await expect(page.getByTestId('segment-overlay')).toHaveCount(13)
|
await expect(page.getByTestId('segment-overlay')).toHaveCount(14)
|
||||||
|
|
||||||
const clickUnconstrained = _clickUnconstrained(page, editor)
|
const clickUnconstrained = _clickUnconstrained(page, editor)
|
||||||
const clickConstrained = _clickConstrained(page, editor)
|
const clickConstrained = _clickConstrained(page, editor)
|
||||||
|
|
||||||
const tangentialArc = await u.getBoundingBox('[data-overlay-index="12"]')
|
const tangentialArc = await u.getBoundingBox('[data-overlay-index="13"]')
|
||||||
let ang = await u.getAngle('[data-overlay-index="12"]')
|
let ang = await u.getAngle('[data-overlay-index="13"]')
|
||||||
console.log('tangentialArc')
|
console.log('tangentialArc')
|
||||||
await clickConstrained({
|
await clickConstrained({
|
||||||
hoverPos: { x: tangentialArc.x, y: tangentialArc.y },
|
hoverPos: { x: tangentialArc.x, y: tangentialArc.y },
|
||||||
@ -747,7 +754,7 @@ test.describe('Testing segment overlays', () => {
|
|||||||
expectFinal: 'tangentialArc(endAbsolute = [xAbs001, -3.14])',
|
expectFinal: 'tangentialArc(endAbsolute = [xAbs001, -3.14])',
|
||||||
ang: ang + 180,
|
ang: ang + 180,
|
||||||
steps: 6,
|
steps: 6,
|
||||||
locator: '[data-overlay-toolbar-index="12"]',
|
locator: '[data-overlay-toolbar-index="13"]',
|
||||||
})
|
})
|
||||||
console.log('tangentialArc2')
|
console.log('tangentialArc2')
|
||||||
await clickUnconstrained({
|
await clickUnconstrained({
|
||||||
@ -760,7 +767,7 @@ test.describe('Testing segment overlays', () => {
|
|||||||
expectFinal: 'tangentialArc(endAbsolute = [xAbs001, -3.14])',
|
expectFinal: 'tangentialArc(endAbsolute = [xAbs001, -3.14])',
|
||||||
ang: ang + 180,
|
ang: ang + 180,
|
||||||
steps: 10,
|
steps: 10,
|
||||||
locator: '[data-overlay-toolbar-index="12"]',
|
locator: '[data-overlay-toolbar-index="13"]',
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
test('for segment [arcTo]', async ({
|
test('for segment [arcTo]', async ({
|
||||||
@ -983,7 +990,7 @@ part001 = startSketchOn(XZ)
|
|||||||
'persistCode',
|
'persistCode',
|
||||||
`@settings(defaultLengthUnit = in)
|
`@settings(defaultLengthUnit = in)
|
||||||
part001 = startSketchOn(XZ)
|
part001 = startSketchOn(XZ)
|
||||||
|>startProfile(at = [0, 0])
|
|> startProfile(at = [0, 0])
|
||||||
|> line(end = [0.5, -14 + 0])
|
|> line(end = [0.5, -14 + 0])
|
||||||
|> angledLine(angle = 3 + 0, length = 32 + 0)
|
|> angledLine(angle = 3 + 0, length = 32 + 0)
|
||||||
|> line(endAbsolute = [33, 11.5 + 0])
|
|> line(endAbsolute = [33, 11.5 + 0])
|
||||||
@ -1017,141 +1024,167 @@ part001 = startSketchOn(XZ)
|
|||||||
await page.getByRole('button', { name: 'Edit Sketch' }).click()
|
await page.getByRole('button', { name: 'Edit Sketch' }).click()
|
||||||
await page.waitForTimeout(500)
|
await page.waitForTimeout(500)
|
||||||
|
|
||||||
await expect(page.getByTestId('segment-overlay')).toHaveCount(16)
|
await expect(page.getByTestId('segment-overlay')).toHaveCount(17)
|
||||||
const deleteSegmentSequence = _deleteSegmentSequence(page, editor)
|
const deleteSegmentSequence = _deleteSegmentSequence(page, editor)
|
||||||
|
|
||||||
let segmentToDelete
|
let segmentToDelete
|
||||||
|
let ang = 0
|
||||||
|
|
||||||
const getOverlayByIndex = (index: number) =>
|
const getOverlayByIndex = (index: number) =>
|
||||||
u.getBoundingBox(`[data-overlay-index="${index}"]`)
|
u.getBoundingBox(`[data-overlay-index="${index}"]`)
|
||||||
|
|
||||||
segmentToDelete = await getOverlayByIndex(14)
|
let overlayIndex = 15
|
||||||
let ang = await u.getAngle('[data-overlay-index="14"]')
|
|
||||||
|
|
||||||
await editor.scrollToText('angleEnd')
|
|
||||||
|
|
||||||
|
segmentToDelete = await getOverlayByIndex(overlayIndex)
|
||||||
|
ang = await u.getAngle(`[data-overlay-index="${overlayIndex}"]`)
|
||||||
await deleteSegmentSequence({
|
await deleteSegmentSequence({
|
||||||
hoverPos: { x: segmentToDelete.x, y: segmentToDelete.y },
|
hoverPos: { x: segmentToDelete.x, y: segmentToDelete.y },
|
||||||
codeToBeDeleted: `arc(angleStart = 40.27, angleEnd = -38.05, radius = 9.03)`,
|
codeToBeDeleted: `arc(angleStart = 40.27, angleEnd = -38.05, radius = 9.03)`,
|
||||||
stdLibFnName: 'arc',
|
stdLibFnName: 'arc',
|
||||||
ang: ang + 180,
|
ang: ang + 180,
|
||||||
steps: 6,
|
steps: 6,
|
||||||
locator: '[data-overlay-toolbar-index="14"]',
|
locator: `[data-overlay-toolbar-index="${overlayIndex}"]`,
|
||||||
})
|
})
|
||||||
segmentToDelete = await getOverlayByIndex(13)
|
|
||||||
ang = await u.getAngle('[data-overlay-index="13"]')
|
overlayIndex--
|
||||||
|
|
||||||
|
segmentToDelete = await getOverlayByIndex(overlayIndex)
|
||||||
|
ang = await u.getAngle(`[data-overlay-index="${overlayIndex}"]`)
|
||||||
await deleteSegmentSequence({
|
await deleteSegmentSequence({
|
||||||
hoverPos: { x: segmentToDelete.x, y: segmentToDelete.y },
|
hoverPos: { x: segmentToDelete.x, y: segmentToDelete.y },
|
||||||
codeToBeDeleted: `arc(interiorAbsolute = [16.25, 5.12], endAbsolute = [21.61, 4.15])`,
|
codeToBeDeleted: `arc(interiorAbsolute = [16.25, 5.12], endAbsolute = [21.61, 4.15])`,
|
||||||
stdLibFnName: 'arc',
|
stdLibFnName: 'arc',
|
||||||
ang: ang,
|
ang: ang,
|
||||||
steps: 6,
|
steps: 6,
|
||||||
locator: '[data-overlay-toolbar-index="13"]',
|
locator: `[data-overlay-toolbar-index="${overlayIndex}"]`,
|
||||||
})
|
})
|
||||||
segmentToDelete = await getOverlayByIndex(12)
|
|
||||||
ang = await u.getAngle('[data-overlay-index="12"]')
|
overlayIndex--
|
||||||
|
|
||||||
|
segmentToDelete = await getOverlayByIndex(overlayIndex)
|
||||||
|
ang = await u.getAngle(`[data-overlay-index="${overlayIndex}"]`)
|
||||||
await deleteSegmentSequence({
|
await deleteSegmentSequence({
|
||||||
hoverPos: { x: segmentToDelete.x, y: segmentToDelete.y },
|
hoverPos: { x: segmentToDelete.x, y: segmentToDelete.y },
|
||||||
codeToBeDeleted: 'tangentialArc(endAbsolute = [3.14 + 13, 1.14])',
|
codeToBeDeleted: 'tangentialArc(endAbsolute = [3.14 + 13, 1.14])',
|
||||||
stdLibFnName: 'tangentialArc',
|
stdLibFnName: 'tangentialArc',
|
||||||
ang: ang + 180,
|
ang: ang + 180,
|
||||||
steps: 6,
|
steps: 6,
|
||||||
locator: '[data-overlay-toolbar-index="12"]',
|
locator: `[data-overlay-toolbar-index="${overlayIndex}"]`,
|
||||||
})
|
})
|
||||||
|
|
||||||
segmentToDelete = await getOverlayByIndex(11)
|
overlayIndex--
|
||||||
ang = await u.getAngle('[data-overlay-index="11"]')
|
|
||||||
|
segmentToDelete = await getOverlayByIndex(overlayIndex)
|
||||||
|
ang = await u.getAngle(`[data-overlay-index="${overlayIndex}"]`)
|
||||||
await deleteSegmentSequence({
|
await deleteSegmentSequence({
|
||||||
hoverPos: { x: segmentToDelete.x, y: segmentToDelete.y },
|
hoverPos: { x: segmentToDelete.x, y: segmentToDelete.y },
|
||||||
codeToBeDeleted: `angledLineThatIntersects(angle = 4.14, intersectTag = a, offset = 9)`,
|
codeToBeDeleted: `angledLineThatIntersects(angle = 4.14, intersectTag = a, offset = 9)`,
|
||||||
stdLibFnName: 'angledLineThatIntersects',
|
stdLibFnName: 'angledLineThatIntersects',
|
||||||
ang: ang + 180,
|
ang: ang + 180,
|
||||||
steps: 7,
|
steps: 7,
|
||||||
locator: '[data-overlay-toolbar-index="11"]',
|
locator: `[data-overlay-toolbar-index="${overlayIndex}"]`,
|
||||||
})
|
})
|
||||||
|
|
||||||
segmentToDelete = await getOverlayByIndex(10)
|
overlayIndex--
|
||||||
ang = await u.getAngle('[data-overlay-index="10"]')
|
|
||||||
|
segmentToDelete = await getOverlayByIndex(overlayIndex)
|
||||||
|
ang = await u.getAngle(`[data-overlay-index="${overlayIndex}"]`)
|
||||||
await deleteSegmentSequence({
|
await deleteSegmentSequence({
|
||||||
hoverPos: { x: segmentToDelete.x, y: segmentToDelete.y },
|
hoverPos: { x: segmentToDelete.x, y: segmentToDelete.y },
|
||||||
codeToBeDeleted: 'angledLine(angle = 89, endAbsoluteY = 9.14 + 0)',
|
codeToBeDeleted: 'angledLine(angle = 89, endAbsoluteY = 9.14 + 0)',
|
||||||
stdLibFnName: 'angledLineToY',
|
stdLibFnName: 'angledLineToY',
|
||||||
ang: ang + 180,
|
ang: ang + 180,
|
||||||
locator: '[data-overlay-toolbar-index="10"]',
|
locator: `[data-overlay-toolbar-index="${overlayIndex}"]`,
|
||||||
})
|
})
|
||||||
|
|
||||||
segmentToDelete = await getOverlayByIndex(9)
|
overlayIndex--
|
||||||
ang = await u.getAngle('[data-overlay-index="9"]')
|
|
||||||
|
segmentToDelete = await getOverlayByIndex(overlayIndex)
|
||||||
|
ang = await u.getAngle(`[data-overlay-index="${overlayIndex}"]`)
|
||||||
await deleteSegmentSequence({
|
await deleteSegmentSequence({
|
||||||
hoverPos: { x: segmentToDelete.x, y: segmentToDelete.y },
|
hoverPos: { x: segmentToDelete.x, y: segmentToDelete.y },
|
||||||
codeToBeDeleted: 'angledLine(angle = 3 + 0, endAbsoluteX = 26)',
|
codeToBeDeleted: 'angledLine(angle = 3 + 0, endAbsoluteX = 26)',
|
||||||
stdLibFnName: 'angledLineToX',
|
stdLibFnName: 'angledLineToX',
|
||||||
ang: ang + 180,
|
ang: ang + 180,
|
||||||
locator: '[data-overlay-toolbar-index="9"]',
|
locator: `[data-overlay-toolbar-index="${overlayIndex}"]`,
|
||||||
})
|
})
|
||||||
|
|
||||||
segmentToDelete = await getOverlayByIndex(8)
|
overlayIndex--
|
||||||
ang = await u.getAngle('[data-overlay-index="8"]')
|
|
||||||
|
segmentToDelete = await getOverlayByIndex(overlayIndex)
|
||||||
|
ang = await u.getAngle(`[data-overlay-index="${overlayIndex}"]`)
|
||||||
await deleteSegmentSequence({
|
await deleteSegmentSequence({
|
||||||
hoverPos: { x: segmentToDelete.x, y: segmentToDelete.y },
|
hoverPos: { x: segmentToDelete.x, y: segmentToDelete.y },
|
||||||
codeToBeDeleted: 'angledLine(angle = -91, lengthY = 19 + 0)',
|
codeToBeDeleted: 'angledLine(angle = -91, lengthY = 19 + 0)',
|
||||||
stdLibFnName: 'angledLineOfYLength',
|
stdLibFnName: 'angledLineOfYLength',
|
||||||
ang: ang + 180,
|
ang: ang + 180,
|
||||||
locator: '[data-overlay-toolbar-index="8"]',
|
locator: `[data-overlay-toolbar-index="${overlayIndex}"]`,
|
||||||
})
|
})
|
||||||
|
|
||||||
segmentToDelete = await getOverlayByIndex(7)
|
overlayIndex--
|
||||||
ang = await u.getAngle('[data-overlay-index="7"]')
|
|
||||||
|
segmentToDelete = await getOverlayByIndex(overlayIndex)
|
||||||
|
ang = await u.getAngle(`[data-overlay-index="${overlayIndex}"]`)
|
||||||
await deleteSegmentSequence({
|
await deleteSegmentSequence({
|
||||||
hoverPos: { x: segmentToDelete.x, y: segmentToDelete.y },
|
hoverPos: { x: segmentToDelete.x, y: segmentToDelete.y },
|
||||||
codeToBeDeleted: 'angledLine(angle = 181 + 0, lengthX = 23.14)',
|
codeToBeDeleted: 'angledLine(angle = 181 + 0, lengthX = 23.14)',
|
||||||
stdLibFnName: 'angledLineOfXLength',
|
stdLibFnName: 'angledLineOfXLength',
|
||||||
ang: ang + 180,
|
ang: ang + 180,
|
||||||
locator: '[data-overlay-toolbar-index="7"]',
|
locator: `[data-overlay-toolbar-index="${overlayIndex}"]`,
|
||||||
})
|
})
|
||||||
|
|
||||||
segmentToDelete = await getOverlayByIndex(6)
|
overlayIndex--
|
||||||
ang = await u.getAngle('[data-overlay-index="6"]')
|
|
||||||
|
segmentToDelete = await getOverlayByIndex(overlayIndex)
|
||||||
|
ang = await u.getAngle(`[data-overlay-index="${overlayIndex}"]`)
|
||||||
await deleteSegmentSequence({
|
await deleteSegmentSequence({
|
||||||
hoverPos: { x: segmentToDelete.x, y: segmentToDelete.y },
|
hoverPos: { x: segmentToDelete.x, y: segmentToDelete.y },
|
||||||
codeToBeDeleted: 'yLine(length = 21.14 + 0)',
|
codeToBeDeleted: 'yLine(length = 21.14 + 0)',
|
||||||
stdLibFnName: 'yLine',
|
stdLibFnName: 'yLine',
|
||||||
ang: ang + 180,
|
ang: ang + 180,
|
||||||
locator: '[data-overlay-toolbar-index="6"]',
|
locator: `[data-overlay-toolbar-index="${overlayIndex}"]`,
|
||||||
})
|
})
|
||||||
|
|
||||||
segmentToDelete = await getOverlayByIndex(5)
|
overlayIndex--
|
||||||
ang = await u.getAngle('[data-overlay-index="5"]')
|
|
||||||
|
segmentToDelete = await getOverlayByIndex(overlayIndex)
|
||||||
|
ang = await u.getAngle(`[data-overlay-index="${overlayIndex}"]`)
|
||||||
await deleteSegmentSequence({
|
await deleteSegmentSequence({
|
||||||
hoverPos: { x: segmentToDelete.x, y: segmentToDelete.y },
|
hoverPos: { x: segmentToDelete.x, y: segmentToDelete.y },
|
||||||
codeToBeDeleted: 'xLine(length = 26.04)',
|
codeToBeDeleted: 'xLine(length = 26.04)',
|
||||||
stdLibFnName: 'xLine',
|
stdLibFnName: 'xLine',
|
||||||
ang: ang + 180,
|
ang: ang + 180,
|
||||||
locator: '[data-overlay-toolbar-index="5"]',
|
locator: `[data-overlay-toolbar-index="${overlayIndex}"]`,
|
||||||
})
|
})
|
||||||
|
|
||||||
segmentToDelete = await getOverlayByIndex(4)
|
overlayIndex--
|
||||||
ang = await u.getAngle('[data-overlay-index="4"]')
|
|
||||||
|
segmentToDelete = await getOverlayByIndex(overlayIndex)
|
||||||
|
ang = await u.getAngle(`[data-overlay-index="${overlayIndex}"]`)
|
||||||
await deleteSegmentSequence({
|
await deleteSegmentSequence({
|
||||||
hoverPos: { x: segmentToDelete.x, y: segmentToDelete.y },
|
hoverPos: { x: segmentToDelete.x, y: segmentToDelete.y },
|
||||||
codeToBeDeleted: 'yLine(endAbsolute = -10.77, tag = $a)',
|
codeToBeDeleted: 'yLine(endAbsolute = -10.77, tag = $a)',
|
||||||
stdLibFnName: 'yLineTo',
|
stdLibFnName: 'yLineTo',
|
||||||
ang: ang + 180,
|
ang: ang + 180,
|
||||||
locator: '[data-overlay-toolbar-index="4"]',
|
locator: `[data-overlay-toolbar-index="${overlayIndex}"]`,
|
||||||
})
|
})
|
||||||
|
|
||||||
segmentToDelete = await getOverlayByIndex(3)
|
overlayIndex--
|
||||||
ang = await u.getAngle('[data-overlay-index="3"]')
|
|
||||||
|
segmentToDelete = await getOverlayByIndex(overlayIndex)
|
||||||
|
ang = await u.getAngle(`[data-overlay-index="${overlayIndex}"]`)
|
||||||
await deleteSegmentSequence({
|
await deleteSegmentSequence({
|
||||||
hoverPos: { x: segmentToDelete.x, y: segmentToDelete.y },
|
hoverPos: { x: segmentToDelete.x, y: segmentToDelete.y },
|
||||||
codeToBeDeleted: 'xLine(endAbsolute = 9 - 5)',
|
codeToBeDeleted: 'xLine(endAbsolute = 9 - 5)',
|
||||||
stdLibFnName: 'xLineTo',
|
stdLibFnName: 'xLineTo',
|
||||||
ang: ang + 180,
|
ang: ang + 180,
|
||||||
locator: '[data-overlay-toolbar-index="3"]',
|
locator: `[data-overlay-toolbar-index="${overlayIndex}"]`,
|
||||||
})
|
})
|
||||||
|
|
||||||
segmentToDelete = await getOverlayByIndex(2)
|
overlayIndex--
|
||||||
ang = await u.getAngle('[data-overlay-index="2"]')
|
|
||||||
|
segmentToDelete = await getOverlayByIndex(overlayIndex)
|
||||||
|
ang = await u.getAngle(`[data-overlay-index="${overlayIndex}"]`)
|
||||||
await expect(page.getByText('Added variable')).not.toBeVisible()
|
await expect(page.getByText('Added variable')).not.toBeVisible()
|
||||||
|
|
||||||
const hoverPos = { x: segmentToDelete.x, y: segmentToDelete.y }
|
const hoverPos = { x: segmentToDelete.x, y: segmentToDelete.y }
|
||||||
@ -1167,7 +1200,7 @@ part001 = startSketchOn(XZ)
|
|||||||
ang,
|
ang,
|
||||||
10,
|
10,
|
||||||
5,
|
5,
|
||||||
'[data-overlay-toolbar-index="2"]'
|
`[data-overlay-toolbar-index="${overlayIndex}"]`
|
||||||
)
|
)
|
||||||
await page.mouse.move(hoverPos.x, hoverPos.y)
|
await page.mouse.move(hoverPos.x, hoverPos.y)
|
||||||
|
|
||||||
@ -1183,18 +1216,22 @@ part001 = startSketchOn(XZ)
|
|||||||
shouldNormalise: true,
|
shouldNormalise: true,
|
||||||
})
|
})
|
||||||
|
|
||||||
segmentToDelete = await getOverlayByIndex(1)
|
overlayIndex--
|
||||||
ang = await u.getAngle('[data-overlay-index="1"]')
|
|
||||||
|
segmentToDelete = await getOverlayByIndex(overlayIndex)
|
||||||
|
ang = await u.getAngle(`[data-overlay-index="${overlayIndex}"]`)
|
||||||
await deleteSegmentSequence({
|
await deleteSegmentSequence({
|
||||||
hoverPos: { x: segmentToDelete.x, y: segmentToDelete.y },
|
hoverPos: { x: segmentToDelete.x, y: segmentToDelete.y },
|
||||||
codeToBeDeleted: 'angledLine(angle = 3 + 0, length = 32 + 0)',
|
codeToBeDeleted: 'angledLine(angle = 3 + 0, length = 32 + 0)',
|
||||||
stdLibFnName: 'angledLine',
|
stdLibFnName: 'angledLine',
|
||||||
ang: ang + 180,
|
ang: ang + 180,
|
||||||
locator: '[data-overlay-toolbar-index="1"]',
|
locator: `[data-overlay-toolbar-index="${overlayIndex}"]`,
|
||||||
})
|
})
|
||||||
|
|
||||||
segmentToDelete = await getOverlayByIndex(0)
|
overlayIndex--
|
||||||
ang = await u.getAngle('[data-overlay-index="0"]')
|
|
||||||
|
segmentToDelete = await getOverlayByIndex(overlayIndex)
|
||||||
|
ang = await u.getAngle(`[data-overlay-index="${overlayIndex}"]`)
|
||||||
await deleteSegmentSequence({
|
await deleteSegmentSequence({
|
||||||
hoverPos: { x: segmentToDelete.x, y: segmentToDelete.y },
|
hoverPos: { x: segmentToDelete.x, y: segmentToDelete.y },
|
||||||
codeToBeDeleted: 'line(end = [0.5, -14 + 0])',
|
codeToBeDeleted: 'line(end = [0.5, -14 + 0])',
|
||||||
@ -1414,11 +1451,11 @@ part001 = startSketchOn(XZ)
|
|||||||
await page.getByRole('button', { name: 'Edit Sketch' }).click()
|
await page.getByRole('button', { name: 'Edit Sketch' }).click()
|
||||||
await page.waitForTimeout(500)
|
await page.waitForTimeout(500)
|
||||||
|
|
||||||
await expect(page.getByTestId('segment-overlay')).toHaveCount(3)
|
await expect(page.getByTestId('segment-overlay')).toHaveCount(4)
|
||||||
await expect(page.getByText('Added variable')).not.toBeVisible()
|
await expect(page.getByText('Added variable')).not.toBeVisible()
|
||||||
|
|
||||||
const hoverPos = await u.getBoundingBox(`[data-overlay-index="0"]`)
|
const hoverPos = await u.getBoundingBox(`[data-overlay-index="1"]`)
|
||||||
let ang = await u.getAngle('[data-overlay-index="0"]')
|
let ang = await u.getAngle('[data-overlay-index="1"]')
|
||||||
ang += 180
|
ang += 180
|
||||||
|
|
||||||
await page.mouse.move(0, 0)
|
await page.mouse.move(0, 0)
|
||||||
@ -1437,7 +1474,7 @@ part001 = startSketchOn(XZ)
|
|||||||
ang,
|
ang,
|
||||||
10,
|
10,
|
||||||
5,
|
5,
|
||||||
'[data-overlay-toolbar-index="0"]'
|
'[data-overlay-toolbar-index="1"]'
|
||||||
)
|
)
|
||||||
await page.mouse.move(x, y)
|
await page.mouse.move(x, y)
|
||||||
|
|
||||||
@ -1451,7 +1488,7 @@ part001 = startSketchOn(XZ)
|
|||||||
|
|
||||||
// check the cursor was left in the correct place after transform
|
// check the cursor was left in the correct place after transform
|
||||||
await expect(page.locator('.cm-activeLine')).toHaveText('|> ' + after)
|
await expect(page.locator('.cm-activeLine')).toHaveText('|> ' + after)
|
||||||
await expect(page.getByTestId('segment-overlay')).toHaveCount(3)
|
await expect(page.getByTestId('segment-overlay')).toHaveCount(4)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -1587,6 +1624,87 @@ profile002 = circle(sketch001, center = [345, 0], radius = 238.38)
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
test('startProfile x y overlays', async ({
|
||||||
|
page,
|
||||||
|
editor,
|
||||||
|
homePage,
|
||||||
|
scene,
|
||||||
|
cmdBar,
|
||||||
|
toolbar,
|
||||||
|
}) => {
|
||||||
|
await page.addInitScript(async () => {
|
||||||
|
localStorage.setItem(
|
||||||
|
'persistCode',
|
||||||
|
`sketch001 = startSketchOn(XZ)
|
||||||
|
profile001 = startProfile(sketch001, at = [15, 15])
|
||||||
|
|> line(end = [114.78, 232])
|
||||||
|
|> line(end = [228.75, -208.39])
|
||||||
|
`
|
||||||
|
)
|
||||||
|
// Set flag to always show overlays without hover
|
||||||
|
localStorage.setItem('showAllOverlays', 'true')
|
||||||
|
})
|
||||||
|
|
||||||
|
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||||
|
|
||||||
|
await homePage.goToModelingScene()
|
||||||
|
await scene.connectionEstablished()
|
||||||
|
await scene.settled(cmdBar)
|
||||||
|
|
||||||
|
await toolbar.waitForFeatureTreeToBeBuilt()
|
||||||
|
await toolbar.editSketch(0)
|
||||||
|
await page.waitForTimeout(600)
|
||||||
|
await expect(page.getByTestId('segment-overlay')).toHaveCount(3)
|
||||||
|
|
||||||
|
// 1. constrain x coordinate
|
||||||
|
const xConstraintBtn = page.locator(
|
||||||
|
'[data-constraint-type="xAbsolute"][data-is-constrained="false"]'
|
||||||
|
)
|
||||||
|
await expect(xConstraintBtn).toBeVisible()
|
||||||
|
await xConstraintBtn.click()
|
||||||
|
|
||||||
|
await expect(
|
||||||
|
page.getByTestId('cmd-bar-arg-value').getByRole('textbox')
|
||||||
|
).toBeFocused()
|
||||||
|
await cmdBar.progressCmdBar()
|
||||||
|
|
||||||
|
await editor.expectEditor.toContain('at = [xAbs001, 15]', {
|
||||||
|
shouldNormalise: true,
|
||||||
|
})
|
||||||
|
|
||||||
|
// 2. constrain y coordinate
|
||||||
|
const yConstraintBtn = page.locator(
|
||||||
|
'[data-constraint-type="yAbsolute"][data-is-constrained="false"]'
|
||||||
|
)
|
||||||
|
await expect(yConstraintBtn).toBeVisible()
|
||||||
|
await yConstraintBtn.click()
|
||||||
|
|
||||||
|
await expect(
|
||||||
|
page.getByTestId('cmd-bar-arg-value').getByRole('textbox')
|
||||||
|
).toBeFocused()
|
||||||
|
await cmdBar.progressCmdBar()
|
||||||
|
await editor.expectEditor.toContain('at = [xAbs001, yAbs001]', {
|
||||||
|
shouldNormalise: true,
|
||||||
|
})
|
||||||
|
// 3. unconstrain x coordinate
|
||||||
|
const constrainedXBtn = page.locator(
|
||||||
|
'[data-constraint-type="xAbsolute"][data-is-constrained="true"]'
|
||||||
|
)
|
||||||
|
await expect(constrainedXBtn).toBeVisible()
|
||||||
|
await constrainedXBtn.click()
|
||||||
|
await editor.expectEditor.toContain('at = [15, yAbs001]', {
|
||||||
|
shouldNormalise: true,
|
||||||
|
})
|
||||||
|
// 4. unconstrain y coordinate
|
||||||
|
const constrainedYBtn = page.locator(
|
||||||
|
'[data-constraint-type="yAbsolute"][data-is-constrained="true"]'
|
||||||
|
)
|
||||||
|
await expect(constrainedYBtn).toBeVisible()
|
||||||
|
await constrainedYBtn.click()
|
||||||
|
await editor.expectEditor.toContain('at = [15, 15]', {
|
||||||
|
shouldNormalise: true,
|
||||||
|
})
|
||||||
|
})
|
||||||
test('arc with interiorAbsolute and endAbsolute kwargs overlay constraints', async ({
|
test('arc with interiorAbsolute and endAbsolute kwargs overlay constraints', async ({
|
||||||
page,
|
page,
|
||||||
editor,
|
editor,
|
||||||
@ -1605,7 +1723,7 @@ profile001 = circleThreePoint(
|
|||||||
p2 = [445.16, 116.92],
|
p2 = [445.16, 116.92],
|
||||||
p3 = [546.85, 103],
|
p3 = [546.85, 103],
|
||||||
)
|
)
|
||||||
profile003 = startProfileAt([64.39, 35.16], sketch001)
|
profile003 = startProfile(sketch001, at = [64.39, 35.16])
|
||||||
|> line(end = [60.69, 23.02])
|
|> line(end = [60.69, 23.02])
|
||||||
|> arc(interiorAbsolute = [159.26, 100.58], endAbsolute = [237.05, 84.07])
|
|> arc(interiorAbsolute = [159.26, 100.58], endAbsolute = [237.05, 84.07])
|
||||||
|> line(end = [70.31, 42.28])`
|
|> line(end = [70.31, 42.28])`
|
||||||
@ -1628,7 +1746,7 @@ profile003 = startProfileAt([64.39, 35.16], sketch001)
|
|||||||
|
|
||||||
// Verify overlays are visible
|
// Verify overlays are visible
|
||||||
// 3 for the three point arc, and 4 for the 3 segments (arc has two)
|
// 3 for the three point arc, and 4 for the 3 segments (arc has two)
|
||||||
await expect(page.getByTestId('segment-overlay')).toHaveCount(7)
|
await expect(page.getByTestId('segment-overlay')).toHaveCount(8)
|
||||||
|
|
||||||
// ---- Testing interior point constraints ----
|
// ---- Testing interior point constraints ----
|
||||||
|
|
||||||
@ -1637,7 +1755,7 @@ profile003 = startProfileAt([64.39, 35.16], sketch001)
|
|||||||
.locator(
|
.locator(
|
||||||
'[data-constraint-type="xAbsolute"][data-is-constrained="false"]'
|
'[data-constraint-type="xAbsolute"][data-is-constrained="false"]'
|
||||||
)
|
)
|
||||||
.nth(3)
|
.nth(4)
|
||||||
await expect(interiorXConstraintBtn).toBeVisible()
|
await expect(interiorXConstraintBtn).toBeVisible()
|
||||||
await interiorXConstraintBtn.click()
|
await interiorXConstraintBtn.click()
|
||||||
|
|
||||||
@ -1660,7 +1778,7 @@ profile003 = startProfileAt([64.39, 35.16], sketch001)
|
|||||||
.locator(
|
.locator(
|
||||||
'[data-constraint-type="yAbsolute"][data-is-constrained="false"]'
|
'[data-constraint-type="yAbsolute"][data-is-constrained="false"]'
|
||||||
)
|
)
|
||||||
.nth(3)
|
.nth(4)
|
||||||
await expect(interiorYConstraintBtn).toBeVisible()
|
await expect(interiorYConstraintBtn).toBeVisible()
|
||||||
await interiorYConstraintBtn.click()
|
await interiorYConstraintBtn.click()
|
||||||
|
|
||||||
@ -1685,7 +1803,7 @@ profile003 = startProfileAt([64.39, 35.16], sketch001)
|
|||||||
.locator(
|
.locator(
|
||||||
'[data-constraint-type="xAbsolute"][data-is-constrained="false"]'
|
'[data-constraint-type="xAbsolute"][data-is-constrained="false"]'
|
||||||
)
|
)
|
||||||
.nth(3) // still number 3 because the interior ones are now constrained
|
.nth(4) // still number 3 because the interior ones are now constrained
|
||||||
await expect(endXConstraintBtn).toBeVisible()
|
await expect(endXConstraintBtn).toBeVisible()
|
||||||
await endXConstraintBtn.click()
|
await endXConstraintBtn.click()
|
||||||
|
|
||||||
@ -1705,7 +1823,7 @@ profile003 = startProfileAt([64.39, 35.16], sketch001)
|
|||||||
.locator(
|
.locator(
|
||||||
'[data-constraint-type="yAbsolute"][data-is-constrained="false"]'
|
'[data-constraint-type="yAbsolute"][data-is-constrained="false"]'
|
||||||
)
|
)
|
||||||
.nth(3) // still number 3 because the interior ones are now constrained
|
.nth(4) // still number 3 because the interior ones are now constrained
|
||||||
await expect(endYConstraintBtn).toBeVisible()
|
await expect(endYConstraintBtn).toBeVisible()
|
||||||
await endYConstraintBtn.click()
|
await endYConstraintBtn.click()
|
||||||
|
|
||||||
|
@ -797,7 +797,7 @@ test.describe(
|
|||||||
|
|
||||||
// We use the line tool as a proxy for sketch mode
|
// We use the line tool as a proxy for sketch mode
|
||||||
await expect(lineToolButton).toBeVisible()
|
await expect(lineToolButton).toBeVisible()
|
||||||
await expect(segmentOverlays).toHaveCount(4)
|
await expect(segmentOverlays).toHaveCount(5)
|
||||||
// but we allow more time to pass for animating to the sketch
|
// but we allow more time to pass for animating to the sketch
|
||||||
await page.waitForTimeout(1000)
|
await page.waitForTimeout(1000)
|
||||||
})
|
})
|
||||||
|
@ -318,8 +318,9 @@ const Overlay = ({
|
|||||||
this will likely change soon when we implement multi-profile so we'll leave it for now
|
this will likely change soon when we implement multi-profile so we'll leave it for now
|
||||||
issue: https://github.com/KittyCAD/modeling-app/issues/3910
|
issue: https://github.com/KittyCAD/modeling-app/issues/3910
|
||||||
*/}
|
*/}
|
||||||
{callExpression?.callee?.name.name !== 'circle' &&
|
{!['circleThreePoint', 'circle', 'startProfile'].includes(
|
||||||
callExpression?.callee?.name.name !== 'circleThreePoint' && (
|
callExpression?.callee?.name.name
|
||||||
|
) && (
|
||||||
<SegmentMenu
|
<SegmentMenu
|
||||||
verticalPosition={
|
verticalPosition={
|
||||||
overlay.windowCoords[1] > window.innerHeight / 2
|
overlay.windowCoords[1] > window.innerHeight / 2
|
||||||
|
@ -321,6 +321,18 @@ export class SceneEntities {
|
|||||||
callBack && !err(callBack) && callbacks.push(callBack)
|
callBack && !err(callBack) && callbacks.push(callBack)
|
||||||
if (segment.name === PROFILE_START) {
|
if (segment.name === PROFILE_START) {
|
||||||
segment.scale.set(factor, factor, factor)
|
segment.scale.set(factor, factor, factor)
|
||||||
|
const startProfileCallBack: () => SegmentOverlayPayload | null = () => {
|
||||||
|
return this.sceneInfra.updateOverlayDetails({
|
||||||
|
handle: segment,
|
||||||
|
group: segment,
|
||||||
|
isHandlesVisible: true,
|
||||||
|
from: segment.userData.from,
|
||||||
|
to: segment.userData.to,
|
||||||
|
hasThreeDotMenu: false,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
callbacks.push(startProfileCallBack)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
if (this.axisGroup) {
|
if (this.axisGroup) {
|
||||||
@ -702,10 +714,7 @@ export class SceneEntities {
|
|||||||
maybeModdedAst,
|
maybeModdedAst,
|
||||||
sourceRangeFromRust(sketch.start.__geoMeta.sourceRange)
|
sourceRangeFromRust(sketch.start.__geoMeta.sourceRange)
|
||||||
)
|
)
|
||||||
if (
|
if (!['Circle', 'CircleThreePoint'].includes(sketch?.paths?.[0]?.type)) {
|
||||||
['Circle', 'CircleThreePoint'].includes(sketch?.paths?.[0]?.type) ===
|
|
||||||
false
|
|
||||||
) {
|
|
||||||
const _profileStart = createProfileStartHandle({
|
const _profileStart = createProfileStartHandle({
|
||||||
from: sketch.start.from,
|
from: sketch.start.from,
|
||||||
id: sketch.start.__geoMeta.id,
|
id: sketch.start.__geoMeta.id,
|
||||||
@ -723,6 +732,18 @@ export class SceneEntities {
|
|||||||
}
|
}
|
||||||
group.add(_profileStart)
|
group.add(_profileStart)
|
||||||
this.activeSegments[JSON.stringify(segPathToNode)] = _profileStart
|
this.activeSegments[JSON.stringify(segPathToNode)] = _profileStart
|
||||||
|
const startProfileCallBack: () => SegmentOverlayPayload | null = () => {
|
||||||
|
return this.sceneInfra.updateOverlayDetails({
|
||||||
|
handle: _profileStart,
|
||||||
|
group: _profileStart,
|
||||||
|
isHandlesVisible: true,
|
||||||
|
from: sketch.start.from,
|
||||||
|
to: sketch.start.to,
|
||||||
|
hasThreeDotMenu: true,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
callbacks.push(startProfileCallBack)
|
||||||
}
|
}
|
||||||
sketch.paths.forEach((segment, index) => {
|
sketch.paths.forEach((segment, index) => {
|
||||||
const isLastInProfile =
|
const isLastInProfile =
|
||||||
@ -3086,7 +3107,7 @@ export class SceneEntities {
|
|||||||
variables,
|
variables,
|
||||||
kclManager: this.kclManager,
|
kclManager: this.kclManager,
|
||||||
})
|
})
|
||||||
const callBacks: (() => SegmentOverlayPayload | null)[] = []
|
const callbacks: (() => SegmentOverlayPayload | null)[] = []
|
||||||
for (const sketchInfo of sketchesInfo) {
|
for (const sketchInfo of sketchesInfo) {
|
||||||
const { sketch, pathToNode: _pathToNode } = sketchInfo
|
const { sketch, pathToNode: _pathToNode } = sketchInfo
|
||||||
const varDecIndex = Number(_pathToNode[1][0])
|
const varDecIndex = Number(_pathToNode[1][0])
|
||||||
@ -3106,7 +3127,19 @@ export class SceneEntities {
|
|||||||
snappedToTangent
|
snappedToTangent
|
||||||
)
|
)
|
||||||
|
|
||||||
callBacks.push(
|
const startProfileCallBack: () => SegmentOverlayPayload | null = () => {
|
||||||
|
return this.sceneInfra.updateOverlayDetails({
|
||||||
|
handle: group,
|
||||||
|
group: group,
|
||||||
|
isHandlesVisible: true,
|
||||||
|
from: sketch.start.from,
|
||||||
|
to: sketch.start.to,
|
||||||
|
hasThreeDotMenu: true,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
callbacks.push(startProfileCallBack)
|
||||||
|
|
||||||
|
callbacks.push(
|
||||||
...sgPaths.map((group, index) =>
|
...sgPaths.map((group, index) =>
|
||||||
this.updateSegment(
|
this.updateSegment(
|
||||||
group,
|
group,
|
||||||
@ -3120,7 +3153,7 @@ export class SceneEntities {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
this.sceneInfra.overlayCallbacks(callBacks)
|
this.sceneInfra.overlayCallbacks(callbacks)
|
||||||
})().catch(reportRejection)
|
})().catch(reportRejection)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,6 +47,7 @@ import type {
|
|||||||
MouseState,
|
MouseState,
|
||||||
SegmentOverlayPayload,
|
SegmentOverlayPayload,
|
||||||
} from '@src/machines/modelingMachine'
|
} from '@src/machines/modelingMachine'
|
||||||
|
import { PROFILE_START } from '@src/clientSideScene/sceneConstants'
|
||||||
|
|
||||||
type SendType = ReturnType<typeof useModelingContext>['send']
|
type SendType = ReturnType<typeof useModelingContext>['send']
|
||||||
|
|
||||||
@ -230,7 +231,10 @@ export class SceneInfra {
|
|||||||
// Project that position to screen space
|
// Project that position to screen space
|
||||||
vector.project(this.camControls.camera)
|
vector.project(this.camControls.camera)
|
||||||
|
|
||||||
const _angle = typeof angle === 'number' ? angle : getAngle(from, to)
|
let _angle = 45
|
||||||
|
if (group.name !== PROFILE_START) {
|
||||||
|
_angle = typeof angle === 'number' ? angle : getAngle(from, to)
|
||||||
|
}
|
||||||
|
|
||||||
const x = (vector.x * 0.5 + 0.5) * window.innerWidth
|
const x = (vector.x * 0.5 + 0.5) * window.innerWidth
|
||||||
const y = (-vector.y * 0.5 + 0.5) * window.innerHeight
|
const y = (-vector.y * 0.5 + 0.5) * window.innerHeight
|
||||||
|
@ -26,7 +26,7 @@ import {
|
|||||||
applyConstraintLength,
|
applyConstraintLength,
|
||||||
} from '@src/components/Toolbar/setAngleLength'
|
} from '@src/components/Toolbar/setAngleLength'
|
||||||
import {
|
import {
|
||||||
SEGMENT_BODIES,
|
SEGMENT_BODIES_PLUS_PROFILE_START,
|
||||||
getParentGroup,
|
getParentGroup,
|
||||||
} from '@src/clientSideScene/sceneConstants'
|
} from '@src/clientSideScene/sceneConstants'
|
||||||
import { useFileContext } from '@src/hooks/useFileContext'
|
import { useFileContext } from '@src/hooks/useFileContext'
|
||||||
@ -222,14 +222,15 @@ export const ModelingMachineProvider = ({
|
|||||||
if (event.type !== 'Set mouse state') return {}
|
if (event.type !== 'Set mouse state') return {}
|
||||||
const nextSegmentHoverMap = () => {
|
const nextSegmentHoverMap = () => {
|
||||||
if (event.data.type === 'isHovering') {
|
if (event.data.type === 'isHovering') {
|
||||||
const parent = getParentGroup(event.data.on, SEGMENT_BODIES)
|
const parent = getParentGroup(
|
||||||
|
event.data.on,
|
||||||
|
SEGMENT_BODIES_PLUS_PROFILE_START
|
||||||
|
)
|
||||||
const pathToNode = parent?.userData?.pathToNode
|
const pathToNode = parent?.userData?.pathToNode
|
||||||
const pathToNodeString = JSON.stringify(pathToNode)
|
const pathToNodeString = JSON.stringify(pathToNode)
|
||||||
if (!parent || !pathToNode) return context.segmentHoverMap
|
if (!parent || !pathToNode) return context.segmentHoverMap
|
||||||
if (context.segmentHoverMap[pathToNodeString] !== undefined)
|
if (context.segmentHoverMap[pathToNodeString] !== undefined)
|
||||||
clearTimeout(
|
clearTimeout(context.segmentHoverMap[pathToNodeString])
|
||||||
context.segmentHoverMap[JSON.stringify(pathToNode)]
|
|
||||||
)
|
|
||||||
return {
|
return {
|
||||||
...context.segmentHoverMap,
|
...context.segmentHoverMap,
|
||||||
[pathToNodeString]: 0,
|
[pathToNodeString]: 0,
|
||||||
@ -240,7 +241,7 @@ export const ModelingMachineProvider = ({
|
|||||||
) {
|
) {
|
||||||
const mouseOnParent = getParentGroup(
|
const mouseOnParent = getParentGroup(
|
||||||
context.mouseState.on,
|
context.mouseState.on,
|
||||||
SEGMENT_BODIES
|
SEGMENT_BODIES_PLUS_PROFILE_START
|
||||||
)
|
)
|
||||||
if (!mouseOnParent || !mouseOnParent?.userData?.pathToNode)
|
if (!mouseOnParent || !mouseOnParent?.userData?.pathToNode)
|
||||||
return context.segmentHoverMap
|
return context.segmentHoverMap
|
||||||
@ -276,10 +277,11 @@ export const ModelingMachineProvider = ({
|
|||||||
'Set Segment Overlays': assign({
|
'Set Segment Overlays': assign({
|
||||||
segmentOverlays: ({ context: { segmentOverlays }, event }) => {
|
segmentOverlays: ({ context: { segmentOverlays }, event }) => {
|
||||||
if (event.type !== 'Set Segment Overlays') return {}
|
if (event.type !== 'Set Segment Overlays') return {}
|
||||||
if (event.data.type === 'set-many')
|
if (event.data.type === 'set-many') {
|
||||||
return {
|
return {
|
||||||
...event.data.overlays,
|
...event.data.overlays,
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (event.data.type === 'set-one')
|
if (event.data.type === 'set-one')
|
||||||
return {
|
return {
|
||||||
...segmentOverlays,
|
...segmentOverlays,
|
||||||
|
@ -28,6 +28,7 @@ export type ToolTip =
|
|||||||
| 'circleThreePoint'
|
| 'circleThreePoint'
|
||||||
| 'arcTo'
|
| 'arcTo'
|
||||||
| 'arc'
|
| 'arc'
|
||||||
|
| 'startProfile'
|
||||||
|
|
||||||
export const toolTips: Array<ToolTip> = [
|
export const toolTips: Array<ToolTip> = [
|
||||||
'line',
|
'line',
|
||||||
@ -46,6 +47,7 @@ export const toolTips: Array<ToolTip> = [
|
|||||||
'circleThreePoint',
|
'circleThreePoint',
|
||||||
'arc',
|
'arc',
|
||||||
'arcTo',
|
'arcTo',
|
||||||
|
'startProfile',
|
||||||
]
|
]
|
||||||
|
|
||||||
interface ExecutionResult {
|
interface ExecutionResult {
|
||||||
|
@ -1187,6 +1187,159 @@ export const tangentialArc: SketchLineHelperKw = {
|
|||||||
return constraints
|
return constraints
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const startProfile: SketchLineHelperKw = {
|
||||||
|
updateArgs: ({ node, pathToNode, input }) => {
|
||||||
|
if (input.type !== 'straight-segment') return STRAIGHT_SEGMENT_ERR
|
||||||
|
const { to } = input
|
||||||
|
const _node = { ...node }
|
||||||
|
const nodeMeta = getNodeFromPath<CallExpressionKw>(_node, pathToNode)
|
||||||
|
if (err(nodeMeta)) return nodeMeta
|
||||||
|
const { node: callExpression } = nodeMeta
|
||||||
|
|
||||||
|
const toArrExp = createArrayExpression([
|
||||||
|
createLiteral(roundOff(to[0], 2)),
|
||||||
|
createLiteral(roundOff(to[1], 2)),
|
||||||
|
])
|
||||||
|
|
||||||
|
mutateKwArg(ARG_AT, callExpression, toArrExp)
|
||||||
|
return {
|
||||||
|
modifiedAst: _node,
|
||||||
|
pathToNode,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getTag: getTagKwArg(),
|
||||||
|
addTag: addTagKw(),
|
||||||
|
add: ({ node, pathToNode, replaceExistingCallback, segmentInput }) => {
|
||||||
|
console.log('segmentInput', segmentInput)
|
||||||
|
if (segmentInput.type !== 'straight-segment') return STRAIGHT_SEGMENT_ERR
|
||||||
|
const { to } = segmentInput
|
||||||
|
const _node = structuredClone(node)
|
||||||
|
const nodeMeta = getNodeFromPath<PipeExpression | CallExpressionKw>(
|
||||||
|
_node,
|
||||||
|
pathToNode,
|
||||||
|
'PipeExpression'
|
||||||
|
)
|
||||||
|
if (err(nodeMeta)) return nodeMeta
|
||||||
|
|
||||||
|
const { node: pipe } = nodeMeta
|
||||||
|
const nodeMeta2 = getNodeFromPath<VariableDeclarator>(
|
||||||
|
_node,
|
||||||
|
pathToNode,
|
||||||
|
'VariableDeclarator'
|
||||||
|
)
|
||||||
|
if (err(nodeMeta2)) return nodeMeta2
|
||||||
|
|
||||||
|
const newXVal = createLiteral(roundOff(to[0], 2))
|
||||||
|
const newYVal = createLiteral(roundOff(to[1], 2))
|
||||||
|
|
||||||
|
if (!replaceExistingCallback && pipe.type === 'PipeExpression') {
|
||||||
|
const callExp = createCallExpressionStdLibKw('line', null, [
|
||||||
|
createLabeledArg(ARG_AT, createArrayExpression([newXVal, newYVal])),
|
||||||
|
])
|
||||||
|
const pathToNodeIndex = pathToNode.findIndex(
|
||||||
|
(x) => x[1] === 'PipeExpression'
|
||||||
|
)
|
||||||
|
const pipeIndex = pathToNode[pathToNodeIndex + 1][0]
|
||||||
|
if (typeof pipeIndex === 'undefined' || typeof pipeIndex === 'string') {
|
||||||
|
return new Error('pipeIndex is wrong')
|
||||||
|
}
|
||||||
|
pipe.body = [
|
||||||
|
...pipe.body.slice(0, pipeIndex),
|
||||||
|
callExp,
|
||||||
|
...pipe.body.slice(pipeIndex),
|
||||||
|
]
|
||||||
|
return {
|
||||||
|
modifiedAst: _node,
|
||||||
|
pathToNode,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (replaceExistingCallback && pipe.type === 'PipeExpression') {
|
||||||
|
const { index: callIndex } = splitPathAtPipeExpression(pathToNode)
|
||||||
|
const result = replaceExistingCallback([
|
||||||
|
{
|
||||||
|
type: 'labeledArgArrayItem',
|
||||||
|
key: ARG_AT,
|
||||||
|
index: 0,
|
||||||
|
argType: 'xAbsolute',
|
||||||
|
expr: newXVal,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'labeledArgArrayItem',
|
||||||
|
key: ARG_AT,
|
||||||
|
index: 1,
|
||||||
|
argType: 'yAbsolute',
|
||||||
|
expr: newYVal,
|
||||||
|
},
|
||||||
|
])
|
||||||
|
if (err(result)) return result
|
||||||
|
const { callExp, valueUsedInTransform } = result
|
||||||
|
pipe.body[callIndex] = callExp
|
||||||
|
return {
|
||||||
|
modifiedAst: _node,
|
||||||
|
pathToNode: [...pathToNode],
|
||||||
|
valueUsedInTransform,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
modifiedAst: _node,
|
||||||
|
pathToNode,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getConstraintInfo: (callExp, code, pathToNode) => {
|
||||||
|
if (callExp.type !== 'CallExpressionKw') return []
|
||||||
|
if (callExp.callee.name.name !== 'startProfile') return []
|
||||||
|
const expr = findKwArgWithIndex(ARG_AT, callExp)?.expr
|
||||||
|
if (expr?.type !== 'ArrayExpression') {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
const argIndex = findKwArgAnyIndex([ARG_AT], callExp)
|
||||||
|
if (argIndex === undefined) {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
const pathToXYArray: PathToNode = [
|
||||||
|
...pathToNode,
|
||||||
|
['arguments', 'CallExpressionKw'],
|
||||||
|
[argIndex, ARG_INDEX_FIELD],
|
||||||
|
['arg', LABELED_ARG_FIELD],
|
||||||
|
['elements', 'ArrayExpression'],
|
||||||
|
]
|
||||||
|
const xArg = expr.elements[0]
|
||||||
|
const yArg = expr.elements[1]
|
||||||
|
const constraints: ConstrainInfo[] = [
|
||||||
|
{
|
||||||
|
stdLibFnName: 'startProfile',
|
||||||
|
type: 'xAbsolute',
|
||||||
|
isConstrained: isNotLiteralArrayOrStatic(xArg),
|
||||||
|
sourceRange: topLevelRange(xArg.start, xArg.end),
|
||||||
|
pathToNode: [...pathToXYArray, [0, 'index']],
|
||||||
|
value: code.slice(xArg.start, xArg.end),
|
||||||
|
argPosition: {
|
||||||
|
type: 'labeledArgArrayItem',
|
||||||
|
index: 0,
|
||||||
|
key: ARG_AT,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
stdLibFnName: 'startProfile',
|
||||||
|
type: 'yAbsolute',
|
||||||
|
isConstrained: isNotLiteralArrayOrStatic(yArg),
|
||||||
|
sourceRange: topLevelRange(yArg.start, yArg.end),
|
||||||
|
pathToNode: [...pathToXYArray, [1, 'index']],
|
||||||
|
value: code.slice(yArg.start, yArg.end),
|
||||||
|
argPosition: {
|
||||||
|
type: 'labeledArgArrayItem',
|
||||||
|
index: 1,
|
||||||
|
key: ARG_AT,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]
|
||||||
|
return constraints
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
export const circle: SketchLineHelperKw = {
|
export const circle: SketchLineHelperKw = {
|
||||||
add: ({ node, pathToNode, segmentInput, replaceExistingCallback }) => {
|
add: ({ node, pathToNode, segmentInput, replaceExistingCallback }) => {
|
||||||
if (segmentInput.type !== 'arc-segment') return ARC_SEGMENT_ERR()
|
if (segmentInput.type !== 'arc-segment') return ARC_SEGMENT_ERR()
|
||||||
@ -3123,6 +3276,7 @@ export const sketchLineHelperMapKw: { [key: string]: SketchLineHelperKw } = {
|
|||||||
angledLineToX,
|
angledLineToX,
|
||||||
angledLineToY,
|
angledLineToY,
|
||||||
tangentialArc,
|
tangentialArc,
|
||||||
|
startProfile,
|
||||||
} as const
|
} as const
|
||||||
|
|
||||||
export function changeSketchArguments(
|
export function changeSketchArguments(
|
||||||
@ -3215,6 +3369,7 @@ export function fnNameToToolTipFromSegment(
|
|||||||
case 'circle':
|
case 'circle':
|
||||||
case 'tangentialArc':
|
case 'tangentialArc':
|
||||||
case 'angledLine':
|
case 'angledLine':
|
||||||
|
case 'startProfile':
|
||||||
return fnName
|
return fnName
|
||||||
default:
|
default:
|
||||||
const err = `Unknown sketch line function ${fnName}`
|
const err = `Unknown sketch line function ${fnName}`
|
||||||
@ -3254,6 +3409,7 @@ export function fnNameToTooltip(
|
|||||||
case 'circleThreePoint':
|
case 'circleThreePoint':
|
||||||
case 'circle':
|
case 'circle':
|
||||||
case 'tangentialArc':
|
case 'tangentialArc':
|
||||||
|
case 'startProfile':
|
||||||
return fnName
|
return fnName
|
||||||
case 'angledLine': {
|
case 'angledLine': {
|
||||||
const argmap: Record<string, ToolTip> = {
|
const argmap: Record<string, ToolTip> = {
|
||||||
@ -3878,6 +4034,28 @@ export const getArc = (
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const getStartProfile = (
|
||||||
|
callExp: CallExpressionKw
|
||||||
|
):
|
||||||
|
| {
|
||||||
|
val: [Expr, Expr]
|
||||||
|
tag?: Expr
|
||||||
|
}
|
||||||
|
| Error => {
|
||||||
|
const absoluteCoords = findKwArg('at', callExp)
|
||||||
|
const tag = findKwArg(ARG_TAG, callExp)
|
||||||
|
if (absoluteCoords) {
|
||||||
|
if (absoluteCoords.type === 'ArrayExpression') {
|
||||||
|
console.log('absoluteCoords', absoluteCoords)
|
||||||
|
return {
|
||||||
|
val: [absoluteCoords.elements[0], absoluteCoords.elements[1]],
|
||||||
|
tag,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new Error('expected the arguments to be for a start profile')
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Given a line call, return whether it's using absolute or relative end.
|
Given a line call, return whether it's using absolute or relative end.
|
||||||
*/
|
*/
|
||||||
@ -3916,6 +4094,8 @@ export function isAbsoluteLine(lineCall: CallExpressionKw): boolean | Error {
|
|||||||
findKwArgAny([ARG_END_ABSOLUTE_X, ARG_END_ABSOLUTE_Y], lineCall) !==
|
findKwArgAny([ARG_END_ABSOLUTE_X, ARG_END_ABSOLUTE_Y], lineCall) !==
|
||||||
undefined
|
undefined
|
||||||
)
|
)
|
||||||
|
case 'startProfile':
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
return new Error(`Unknown sketch function ${name}`)
|
return new Error(`Unknown sketch function ${name}`)
|
||||||
}
|
}
|
||||||
@ -3946,6 +4126,8 @@ export function getArgForEnd(lineCall: CallExpressionKw):
|
|||||||
return getAngledLineThatIntersects(lineCall)
|
return getAngledLineThatIntersects(lineCall)
|
||||||
case 'arc':
|
case 'arc':
|
||||||
return getArc(lineCall)
|
return getArc(lineCall)
|
||||||
|
case 'startProfile':
|
||||||
|
return getStartProfile(lineCall)
|
||||||
case 'yLine':
|
case 'yLine':
|
||||||
case 'xLine': {
|
case 'xLine': {
|
||||||
const arg = findKwArgAny(DETERMINING_ARGS, lineCall)
|
const arg = findKwArgAny(DETERMINING_ARGS, lineCall)
|
||||||
|
@ -1648,7 +1648,7 @@ function getTransformMapPathKw(
|
|||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if (name === 'startProfile') {
|
if (name === 'startProfile' || name === 'startSketchOn') {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
const tooltip = fnNameToTooltip(allLabels(sketchFnExp), name)
|
const tooltip = fnNameToTooltip(allLabels(sketchFnExp), name)
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import type { Node } from '@rust/kcl-lib/bindings/Node'
|
import type { Node } from '@rust/kcl-lib/bindings/Node'
|
||||||
|
|
||||||
import type {
|
import type {
|
||||||
|
ARG_AT,
|
||||||
ARG_END_ABSOLUTE,
|
ARG_END_ABSOLUTE,
|
||||||
ARG_END_ABSOLUTE_X,
|
ARG_END_ABSOLUTE_X,
|
||||||
ARG_END_ABSOLUTE_Y,
|
ARG_END_ABSOLUTE_Y,
|
||||||
@ -116,6 +117,7 @@ export type InputArgKeys =
|
|||||||
| 'p2'
|
| 'p2'
|
||||||
| 'p3'
|
| 'p3'
|
||||||
| 'end'
|
| 'end'
|
||||||
|
| typeof ARG_AT
|
||||||
| typeof ARG_INTERIOR_ABSOLUTE
|
| typeof ARG_INTERIOR_ABSOLUTE
|
||||||
| typeof ARG_END_ABSOLUTE
|
| typeof ARG_END_ABSOLUTE
|
||||||
| typeof ARG_END_ABSOLUTE_X
|
| typeof ARG_END_ABSOLUTE_X
|
||||||
|
@ -314,7 +314,6 @@ export type ModelingMachineEvent =
|
|||||||
type: 'Delete selection'
|
type: 'Delete selection'
|
||||||
}
|
}
|
||||||
| { type: 'Sketch no face' }
|
| { type: 'Sketch no face' }
|
||||||
| { type: 'Toggle gui mode' }
|
|
||||||
| { type: 'Cancel'; cleanup?: () => void }
|
| { type: 'Cancel'; cleanup?: () => void }
|
||||||
| { type: 'CancelSketch' }
|
| { type: 'CancelSketch' }
|
||||||
| {
|
| {
|
||||||
|
Reference in New Issue
Block a user