[BUG] offsetPlane back-side startSketchOn (#7622)

offset backPlane selection bug
This commit is contained in:
Kurt Hutten
2025-06-27 21:36:42 +10:00
committed by GitHub
parent 107adc77b3
commit 0f8375cbb4
8 changed files with 337 additions and 39 deletions

View File

@ -5,6 +5,7 @@ import { uuidv4 } from '@src/lib/utils'
import type { HomePageFixture } from '@e2e/playwright/fixtures/homePageFixture'
import type { SceneFixture } from '@e2e/playwright/fixtures/sceneFixture'
import type { ToolbarFixture } from '@e2e/playwright/fixtures/toolbarFixture'
import type { CmdBarFixture } from '@e2e/playwright/fixtures/cmdBarFixture'
import { getUtils } from '@e2e/playwright/test-utils'
import { expect, test } from '@e2e/playwright/zoo-test'
@ -14,13 +15,18 @@ test.describe('Can create sketches on all planes and their back sides', () => {
homePage: HomePageFixture,
scene: SceneFixture,
toolbar: ToolbarFixture,
cmdBar: CmdBarFixture,
plane: string,
clickCoords: { x: number; y: number }
) => {
const u = await getUtils(page)
// await page.addInitScript(() => {
// localStorage.setItem('persistCode', '@settings(defaultLengthUnit = in)')
// })
await page.setBodyDimensions({ width: 1200, height: 500 })
await homePage.goToModelingScene()
// await scene.settled(cmdBar)
const XYPlanRed: [number, number, number] = [98, 50, 51]
await scene.expectPixelColor(XYPlanRed, { x: 700, y: 300 }, 15)
@ -119,12 +125,166 @@ test.describe('Can create sketches on all planes and their back sides', () => {
]
for (const config of planeConfigs) {
test(config.plane, async ({ page, homePage, scene, toolbar }) => {
test(config.plane, async ({ page, homePage, scene, toolbar, cmdBar }) => {
await sketchOnPlaneAndBackSideTest(
page,
homePage,
scene,
toolbar,
cmdBar,
config.plane,
config.coords
)
})
}
})
test.describe('Can create sketches on offset planes and their back sides', () => {
const sketchOnPlaneAndBackSideTest = async (
page: Page,
homePage: HomePageFixture,
scene: SceneFixture,
toolbar: ToolbarFixture,
cmdbar: CmdBarFixture,
plane: string,
clickCoords: { x: number; y: number }
) => {
const u = await getUtils(page)
await page.addInitScript(() => {
localStorage.setItem(
'persistCode',
`@settings(defaultLengthUnit = in)
xyPlane = offsetPlane(XY, offset = 0.05)
xzPlane = offsetPlane(XZ, offset = 0.05)
yzPlane = offsetPlane(YZ, offset = 0.05)
`
)
})
await page.setBodyDimensions({ width: 1200, height: 500 })
await homePage.goToModelingScene()
// await scene.settled(cmdbar)
const XYPlanRed: [number, number, number] = [74, 74, 74]
await scene.expectPixelColor(XYPlanRed, { x: 700, y: 300 }, 15)
await u.openDebugPanel()
const coord =
plane === '-XY' || plane === '-YZ' || plane === 'XZ' ? -100 : 100
const camCommand: EngineCommand = {
type: 'modeling_cmd_req',
cmd_id: uuidv4(),
cmd: {
type: 'default_camera_look_at',
center: { x: 0, y: 0, z: 0 },
vantage: { x: coord, y: coord, z: coord },
up: { x: 0, y: 0, z: 1 },
},
}
const updateCamCommand: EngineCommand = {
type: 'modeling_cmd_req',
cmd_id: uuidv4(),
cmd: {
type: 'default_camera_get_settings',
},
}
const prefix = plane.length === 3 ? '-' : ''
const planeName = plane
.slice(plane.length === 3 ? 1 : 0)
.toLocaleLowerCase()
const codeLine1 = `sketch001 = startSketchOn(${prefix}${planeName}Plane)`
const codeLine2 = `profile001 = startProfile(sketch001, at = [${0.91 + (plane[0] === '-' ? 0.01 : 0)}, -${1.21 + (plane[0] === '-' ? 0.01 : 0)}])`
await u.openDebugPanel()
await u.clearCommandLogs()
await page.getByRole('button', { name: 'Start Sketch' }).click()
await u.sendCustomCmd(camCommand)
await page.waitForTimeout(100)
await u.sendCustomCmd(updateCamCommand)
await u.closeDebugPanel()
await toolbar.openFeatureTreePane()
await toolbar.getDefaultPlaneVisibilityButton('XY').click()
await toolbar.getDefaultPlaneVisibilityButton('XZ').click()
await toolbar.getDefaultPlaneVisibilityButton('YZ').click()
await expect(
toolbar
.getDefaultPlaneVisibilityButton('YZ')
.locator('[aria-label="eye crossed out"]')
).toBeVisible()
await page.mouse.click(clickCoords.x, clickCoords.y)
await page.waitForTimeout(600) // wait for animation
await toolbar.waitUntilSketchingReady()
await expect(
page.getByRole('button', { name: 'line Line', exact: true })
).toBeVisible()
await u.closeDebugPanel()
await page.mouse.click(707, 393)
await expect(page.locator('.cm-content')).toContainText(codeLine1)
await expect(page.locator('.cm-content')).toContainText(codeLine2)
await page
.getByRole('button', { name: 'line Line', exact: true })
.first()
.click()
await u.openAndClearDebugPanel()
await page.getByRole('button', { name: 'Exit Sketch' }).click()
await u.expectCmdLog('[data-message-type="execution-done"]')
await u.clearCommandLogs()
await u.removeCurrentCode()
}
const planeConfigs = [
{
plane: 'XY',
coords: { x: 600, y: 388 },
description: 'red plane',
},
{
plane: 'YZ',
coords: { x: 700, y: 250 },
description: 'green plane',
},
{
plane: 'XZ',
coords: { x: 684, y: 427 },
description: 'blue plane',
},
{
plane: '-XY',
coords: { x: 600, y: 118 },
description: 'back of red plane',
},
{
plane: '-YZ',
coords: { x: 700, y: 219 },
description: 'back of green plane',
},
{
plane: '-XZ',
coords: { x: 700, y: 80 },
description: 'back of blue plane',
},
]
for (const config of planeConfigs) {
test(config.plane, async ({ page, homePage, scene, toolbar, cmdBar }) => {
await sketchOnPlaneAndBackSideTest(
page,
homePage,
scene,
toolbar,
cmdBar,
config.plane,
config.coords
)

View File

@ -274,6 +274,13 @@ export class ToolbarFixture {
.nth(operationIndex)
}
getDefaultPlaneVisibilityButton(plane: 'XY' | 'XZ' | 'YZ' = 'XY') {
const index = plane === 'XZ' ? 0 : plane === 'XY' ? 1 : 2
return this.featureTreePane
.getByTestId('feature-tree-visibility-toggle')
.nth(index)
}
/**
* View source on a specific operation in the Feature Tree pane.
* @param operationName The name of the operation type

View File

@ -107,7 +107,12 @@ const CustomIconMap = {
</svg>
),
beaker: (
<svg viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<svg
viewBox="0 0 20 20"
fill="none"
xmlns="http://www.w3.org/2000/svg"
aria-label="beaker"
>
<path
d="M13.4747 4.1582L12.5353 6.97363L15.8322 14.3906L15.9015 14.5781C16.1808 15.5181 15.4786 16.5 14.4611 16.5H5.61828C4.50321 16.5 3.77781 15.3265 4.27649 14.3291L7.96008 6.96191L7.02551 4.1582L7.50012 3.5H13.0001L13.4747 4.1582ZM13.6183 11.873C13.2276 11.7045 12.8282 11.6908 12.38 11.7686C11.8504 11.8605 11.3185 12.0648 10.6671 12.2764C9.48553 12.6601 8.08344 12.9938 6.49133 12.1348L5.17102 14.7764C5.00479 15.1088 5.24659 15.5 5.61828 15.5H14.4611C14.8002 15.5 15.0346 15.1727 14.9415 14.8594L14.9181 14.7969L13.6183 11.873ZM8.97473 6.8418L9.04016 7.03809L6.9386 11.2402C8.17525 11.9192 9.24713 11.6862 10.3585 11.3252C10.9385 11.1368 11.5865 10.8913 12.2091 10.7832C12.5041 10.732 12.8059 10.7103 13.1124 10.7344L11.5431 7.20312L11.464 7.02539L11.5255 6.8418L12.3058 4.5H8.19445L8.97473 6.8418Z"
fill="currentColor"
@ -190,7 +195,12 @@ const CustomIconMap = {
</svg>
),
chat: (
<svg viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<svg
viewBox="0 0 20 20"
fill="none"
xmlns="http://www.w3.org/2000/svg"
aria-label="chat"
>
<path
fillRule="evenodd"
clipRule="evenodd"
@ -326,6 +336,7 @@ const CustomIconMap = {
viewBox="0 0 20 20"
fill="none"
xmlns="http://www.w3.org/2000/svg"
aria-label="command"
>
<path
fillRule="evenodd"
@ -351,7 +362,12 @@ const CustomIconMap = {
</svg>
),
elephant: (
<svg viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<svg
viewBox="0 0 20 20"
fill="none"
xmlns="http://www.w3.org/2000/svg"
aria-label="elephant"
>
<path
fillRule="evenodd"
clipRule="evenodd"
@ -417,7 +433,12 @@ const CustomIconMap = {
</svg>
),
eyeOpen: (
<svg viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<svg
viewBox="0 0 20 20"
fill="none"
xmlns="http://www.w3.org/2000/svg"
aria-label="eye open"
>
<path
fillRule="evenodd"
clipRule="evenodd"
@ -427,7 +448,12 @@ const CustomIconMap = {
</svg>
),
eyeCrossedOut: (
<svg viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<svg
viewBox="0 0 20 20"
fill="none"
xmlns="http://www.w3.org/2000/svg"
aria-label="eye crossed out"
>
<path
fillRule="evenodd"
clipRule="evenodd"
@ -563,7 +589,12 @@ const CustomIconMap = {
</svg>
),
helix: (
<svg viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<svg
viewBox="0 0 20 20"
fill="none"
xmlns="http://www.w3.org/2000/svg"
aria-label="helix"
>
<path
fillRule="evenodd"
clipRule="evenodd"
@ -588,7 +619,12 @@ const CustomIconMap = {
</svg>
),
hollow: (
<svg viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<svg
viewBox="0 0 20 20"
fill="none"
xmlns="http://www.w3.org/2000/svg"
aria-label="hollow"
>
<path
fillRule="evenodd"
clipRule="evenodd"
@ -666,6 +702,7 @@ const CustomIconMap = {
viewBox="0 0 20 20"
fill="none"
xmlns="http://www.w3.org/2000/svg"
aria-label="download"
>
<path
fillRule="evenodd"
@ -749,7 +786,12 @@ const CustomIconMap = {
</svg>
),
loading: (
<svg viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<svg
viewBox="0 0 20 20"
fill="none"
xmlns="http://www.w3.org/2000/svg"
aria-label="loading"
>
<path
fillRule="evenodd"
clipRule="evenodd"
@ -864,7 +906,12 @@ const CustomIconMap = {
</svg>
),
model: (
<svg viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<svg
viewBox="0 0 20 20"
fill="none"
xmlns="http://www.w3.org/2000/svg"
aria-label="model"
>
<path
fillRule="evenodd"
clipRule="evenodd"
@ -889,7 +936,12 @@ const CustomIconMap = {
</svg>
),
play: (
<svg viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<svg
viewBox="0 0 20 20"
fill="none"
xmlns="http://www.w3.org/2000/svg"
aria-label="play"
>
<path
d="M14.2842 9.83887L14.2617 10.6758L7.76172 14.6758L7 14.25V5.75L7.78418 5.33887L14.2842 9.83887ZM8 13.3555L13.0859 10.2246L8 6.70312V13.3555Z"
fill="currentColor"
@ -901,7 +953,7 @@ const CustomIconMap = {
viewBox="0 0 20 20"
fill="none"
xmlns="http://www.w3.org/2000/svg"
aria-label="move"
aria-label="rotate"
>
<path
fillRule="evenodd"
@ -916,7 +968,7 @@ const CustomIconMap = {
viewBox="0 0 20 20"
fill="none"
xmlns="http://www.w3.org/2000/svg"
aria-label="move"
aria-label="clone"
>
<path
fillRule="evenodd"
@ -972,7 +1024,12 @@ const CustomIconMap = {
</svg>
),
patternCircular2d: (
<svg viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<svg
viewBox="0 0 20 20"
fill="none"
xmlns="http://www.w3.org/2000/svg"
aria-label="pattern circular 2d"
>
<path
fillRule="evenodd"
clipRule="evenodd"
@ -982,7 +1039,12 @@ const CustomIconMap = {
</svg>
),
patternCircular3d: (
<svg viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<svg
viewBox="0 0 20 20"
fill="none"
xmlns="http://www.w3.org/2000/svg"
aria-label="pattern circular 3d"
>
<path
fillRule="evenodd"
clipRule="evenodd"
@ -998,7 +1060,12 @@ const CustomIconMap = {
</svg>
),
patternLinear2d: (
<svg viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<svg
viewBox="0 0 20 20"
fill="none"
xmlns="http://www.w3.org/2000/svg"
aria-label="pattern linear 2d"
>
<path
fillRule="evenodd"
clipRule="evenodd"
@ -1008,7 +1075,12 @@ const CustomIconMap = {
</svg>
),
patternLinear3d: (
<svg viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<svg
viewBox="0 0 20 20"
fill="none"
xmlns="http://www.w3.org/2000/svg"
aria-label="pattern linear 3d"
>
<path
fillRule="evenodd"
clipRule="evenodd"
@ -1231,7 +1303,12 @@ const CustomIconMap = {
</svg>
),
sparkles: (
<svg viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<svg
viewBox="0 0 20 20"
fill="none"
xmlns="http://www.w3.org/2000/svg"
aria-label="sparkles"
>
<path
fillRule="evenodd"
clipRule="evenodd"
@ -1404,6 +1481,7 @@ const CustomIconMap = {
viewBox="0 0 20 20"
fill="none"
xmlns="http://www.w3.org/2000/svg"
aria-label="stopwatch"
>
<path
fillRule="evenodd"
@ -1425,7 +1503,7 @@ const CustomIconMap = {
viewBox="0 0 20 20"
fill="none"
xmlns="http://www.w3.org/2000/svg"
aria-label="y-relative"
aria-label="glasses"
>
<path
d="M13.9814 7C15.6383 7 16.9814 8.34317 16.9814 10C16.9814 11.6569 15.6383 13 13.9814 13C12.3764 12.9999 11.0656 11.7394 10.9854 10.1543L10.9814 10L10.9707 9.85352C10.9635 9.80499 10.9527 9.75695 10.9385 9.70996L10.9053 9.61719C10.8676 9.52625 10.8171 9.44105 10.7549 9.36523L10.6885 9.29297C10.5957 9.20021 10.4855 9.1264 10.3643 9.07617C10.243 9.02598 10.1127 9 9.98145 9C9.88308 9.00002 9.7852 9.01454 9.69141 9.04297L9.59863 9.07617C9.50772 9.11387 9.42249 9.16435 9.34668 9.22656L9.27441 9.29297C9.20485 9.36255 9.14585 9.44188 9.09961 9.52832L9.05762 9.61719C9.02796 9.6888 9.00749 9.76366 8.99512 9.83984C8.99791 9.89289 9 9.94626 9 10C9 11.6569 7.65685 13 6 13C4.3432 12.9999 3 11.6568 3 10C3.00003 8.34321 4.34322 7.00007 6 7C7.12596 7 8.10505 7.62155 8.61816 8.53906L8.71289 8.4541C8.86453 8.32967 9.03396 8.22772 9.21582 8.15234L9.40137 8.08594C9.58903 8.02906 9.78464 8.00002 9.98145 8C10.244 8 10.5045 8.0519 10.7471 8.15234L10.9248 8.23633C11.0819 8.32036 11.2268 8.42596 11.3564 8.54883C11.8679 7.6256 12.8513 7.00009 13.9814 7ZM6 8C4.89551 8.00007 4.00003 8.8955 4 10C4 11.1045 4.89549 11.9999 6 12C7.0357 12 7.88804 11.2128 7.99023 10.2041L8 10H7.98145C7.98145 9.93633 7.98419 9.87275 7.99023 9.80957C7.89427 8.79439 7.04029 8 6 8ZM13.9814 8C12.877 8.00013 11.9815 8.89554 11.9814 10C11.9814 11.1045 12.877 11.9999 13.9814 12C15.086 12 15.9814 11.1046 15.9814 10C15.9814 8.89546 15.086 8 13.9814 8Z"
@ -1434,7 +1512,12 @@ const CustomIconMap = {
</svg>
),
infinity: (
<svg viewBox="0 0 13 6" fill="none" xmlns="http://www.w3.org/2000/svg">
<svg
viewBox="0 0 13 6"
fill="none"
xmlns="http://www.w3.org/2000/svg"
aria-label="infinity"
>
<path
d="M10 0C11.6567 0.000169571 12.9999 1.34331 13 3C13 4.65671 11.6567 5.99983 10 6C9.08871 6 8.27123 5.59359 7.72168 4.95312V4.95215L6.58398 3.64941L5.43262 4.95703L5.43164 4.95605C4.88213 5.59421 4.06758 6 3.1582 6C1.50144 5.99992 0.15825 4.65677 0.158203 3C0.158279 1.34326 1.50146 7.54041e-05 3.1582 0C4.06727 0 4.88213 0.405203 5.43164 1.04297H5.43262L6.58496 2.34961L7.72461 1.04492C8.27414 0.406002 9.08999 0 10 0ZM3.1582 0.857422C1.97485 0.857497 1.0157 1.81664 1.01562 3C1.01567 4.18338 1.97483 5.1425 3.1582 5.14258C3.80891 5.14258 4.3915 4.85326 4.78516 4.39453L4.78906 4.38965L6.01562 3L4.78906 1.61035L4.78516 1.60547C4.3915 1.1468 3.80885 0.857422 3.1582 0.857422ZM10 0.857422C9.34921 0.857422 8.76573 1.14664 8.37207 1.60547L8.37012 1.6084L7.15527 3L8.37012 4.3916L8.37305 4.39453H8.37207C8.76573 4.85333 9.34924 5.14258 10 5.14258C11.1833 5.14241 12.1425 4.18332 12.1426 3C12.1425 1.8167 11.1833 0.857591 10 0.857422Z"
fill="currentColor"
@ -1442,7 +1525,12 @@ const CustomIconMap = {
</svg>
),
star: (
<svg viewBox="0 0 14 15" fill="none" xmlns="http://www.w3.org/2000/svg">
<svg
viewBox="0 0 14 15"
fill="none"
xmlns="http://www.w3.org/2000/svg"
aria-label="star"
>
<path
d="M8.93445 5.33667H13.6571L13.951 6.24097L10.1298 9.01636L11.5897 13.5085L10.8202 14.0671L6.99988 11.2908L3.17957 14.0671L2.41003 13.5085L3.86902 9.01636L0.0487061 6.24097L0.342651 5.33667H5.06531L6.52429 0.845459H7.47546L8.93445 5.33667ZM5.90417 5.99097L5.42859 6.33667H1.88074L4.75085 8.42163L4.9325 8.98022L3.83582 12.3533L6.70593 10.2693H7.29382L10.163 12.3533L9.06726 8.98022L9.2489 8.42163L12.119 6.33667H8.57117L8.09558 5.99097L6.99988 2.61792L5.90417 5.99097Z"
fill="currentColor"

View File

@ -485,7 +485,11 @@ export const ModelingMachineProvider = ({
input.extrudePathToNode,
input.faceInfo
)
: sketchOnOffsetPlane(kclManager.ast, input.pathToNode)
: sketchOnOffsetPlane(
kclManager.ast,
input.pathToNode,
input.negated
)
if (err(sketched)) {
const sketchedError = new Error(
'Incompatible face, please try another'

View File

@ -222,7 +222,11 @@ const VisibilityToggle = (props: VisibilityToggleProps) => {
}, [props.onVisibilityChange])
return (
<button onClick={handleToggleVisible} className="p-0 m-0">
<button
onClick={handleToggleVisible}
className="p-0 m-0"
data-testid="feature-tree-visibility-toggle"
>
<CustomIcon
name={visible ? 'eyeOpen' : 'eyeCrossedOut'}
className="w-5 h-5"
@ -265,6 +269,7 @@ const OperationItemWrapper = ({
<div
ref={menuRef}
className={`flex select-none items-center group/item my-0 py-0.5 px-1 ${selectable ? 'focus-within:bg-primary/10 hover:bg-primary/5' : ''}`}
data-testid="feature-tree-operation-item"
>
<button
{...props}

View File

@ -164,20 +164,49 @@ export function useEngineConnectionSubscriptions() {
if (artifact?.type === 'plane') {
const planeInfo =
await sceneEntitiesManager.getFaceDetails(planeOrFaceId)
// Apply camera-based orientation logic similar to default planes
let zAxis: [number, number, number] = [
planeInfo.z_axis.x,
planeInfo.z_axis.y,
planeInfo.z_axis.z,
]
let yAxis: [number, number, number] = [
planeInfo.y_axis.x,
planeInfo.y_axis.y,
planeInfo.y_axis.z,
]
// Get camera vector to determine which side of the plane we're viewing from
const camVector = sceneInfra.camControls.camera.position
.clone()
.sub(sceneInfra.camControls.target)
// Determine the canonical (absolute) plane orientation
const absZAxis: [number, number, number] = [
Math.abs(zAxis[0]),
Math.abs(zAxis[1]),
Math.abs(zAxis[2]),
]
// Find the dominant axis (like default planes do)
const maxComponent = Math.max(...absZAxis)
const dominantAxisIndex = absZAxis.indexOf(maxComponent)
// Check camera position against canonical orientation (like default planes)
const cameraComponents = [camVector.x, camVector.y, camVector.z]
let negated = cameraComponents[dominantAxisIndex] < 0
if (dominantAxisIndex === 1) {
// offset of the XZ is being weird, not sure if this is a camera bug
negated = !negated
}
sceneInfra.modelingSend({
type: 'Select sketch plane',
data: {
type: 'offsetPlane',
zAxis: [
planeInfo.z_axis.x,
planeInfo.z_axis.y,
planeInfo.z_axis.z,
],
yAxis: [
planeInfo.y_axis.x,
planeInfo.y_axis.y,
planeInfo.y_axis.z,
],
zAxis,
yAxis,
position: [
planeInfo.origin.x,
planeInfo.origin.y,
@ -189,6 +218,7 @@ export function useEngineConnectionSubscriptions() {
],
planeId: planeOrFaceId,
pathToNode: artifact.codeRef.pathToNode,
negated,
},
})
return

View File

@ -13,6 +13,7 @@ import {
createLiteral,
createLocalName,
createPipeExpression,
createUnaryExpression,
createVariableDeclaration,
findUniqueName,
} from '@src/lang/create'
@ -713,7 +714,8 @@ export function insertNamedConstant({
*/
export function sketchOnOffsetPlane(
node: Node<Program>,
offsetPathToNode: PathToNode
offsetPathToNode: PathToNode,
negated: boolean = false
) {
let _node = { ...node }
@ -728,6 +730,11 @@ export function sketchOnOffsetPlane(
const { node: offsetPlaneNode } = offsetPlaneDeclarator
const offsetPlaneName = offsetPlaneNode.id.name
// Create the plane argument - either the plane name or negated plane name
const planeArgument = negated
? createUnaryExpression(createLocalName(offsetPlaneName), '-')
: createLocalName(offsetPlaneName)
// Create a new sketch declaration
const newSketchName = findUniqueName(
node,
@ -735,11 +742,7 @@ export function sketchOnOffsetPlane(
)
const newSketch = createVariableDeclaration(
newSketchName,
createCallExpressionStdLibKw(
'startSketchOn',
createLocalName(offsetPlaneName),
[]
),
createCallExpressionStdLibKw('startSketchOn', planeArgument, []),
undefined,
'const'
)

View File

@ -280,6 +280,7 @@ export type OffsetPlane = {
pathToNode: PathToNode
zAxis: [number, number, number]
yAxis: [number, number, number]
negated: boolean
}
export type SegmentOverlayPayload =