Compare commits
7 Commits
v0.52.0
...
nightly-v2
Author | SHA1 | Date | |
---|---|---|---|
3e4505e2e3 | |||
1fe1cfb397 | |||
2f721c84ed | |||
9112ff8c0a | |||
96e12b5aba | |||
bec3ba71cd | |||
c6766d2a73 |
@ -111905,7 +111905,8 @@
|
||||
"unpublished": false,
|
||||
"deprecated": true,
|
||||
"examples": [
|
||||
"fn cube(center) {\n return startSketchOn(XY)\n |> startProfileAt([center[0] - 10, center[1] - 10], %)\n |> line(endAbsolute = [center[0] + 10, center[1] - 10])\n |> line(endAbsolute = [center[0] + 10, center[1] + 10])\n |> line(endAbsolute = [center[0] - 10, center[1] + 10])\n |> close()\n |> extrude(length = 10)\n}\n\npart001 = cube([0, 0])\npart002 = cube([8, 8])\n\nintersectedPart = intersect([part001, part002])"
|
||||
"// Intersect two cubes using the stdlib functions.\n\n\nfn cube(center) {\n return startSketchOn(XY)\n |> startProfileAt([center[0] - 10, center[1] - 10], %)\n |> line(endAbsolute = [center[0] + 10, center[1] - 10])\n |> line(endAbsolute = [center[0] + 10, center[1] + 10])\n |> line(endAbsolute = [center[0] - 10, center[1] + 10])\n |> close()\n |> extrude(length = 10)\n}\n\npart001 = cube([0, 0])\npart002 = cube([8, 8])\n\nintersectedPart = intersect([part001, part002])",
|
||||
"// Intersect two cubes using operators.\n// NOTE: This will not work when using codemods through the UI.\n// Codemods will generate the stdlib function call instead.\n\n\nfn cube(center) {\n return startSketchOn(XY)\n |> startProfileAt([center[0] - 10, center[1] - 10], %)\n |> line(endAbsolute = [center[0] + 10, center[1] - 10])\n |> line(endAbsolute = [center[0] + 10, center[1] + 10])\n |> line(endAbsolute = [center[0] - 10, center[1] + 10])\n |> close()\n |> extrude(length = 10)\n}\n\npart001 = cube([0, 0])\npart002 = cube([8, 8])\n\n// This is the equivalent of: intersect([part001, part002])\nintersectedPart = part001 & part002"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -266059,7 +266060,7 @@
|
||||
"// Rotate a pipe with roll, pitch, and yaw.\n\n// Create a path for the sweep.\nsweepPath = startSketchOn(XZ)\n |> startProfileAt([0.05, 0.05], %)\n |> line(end = [0, 7])\n |> tangentialArc({ offset = 90, radius = 5 }, %)\n |> line(end = [-3, 0])\n |> tangentialArc({ offset = -90, radius = 5 }, %)\n |> line(end = [0, 7])\n\n// Create a hole for the pipe.\npipeHole = startSketchOn(XY)\n |> circle(center = [0, 0], radius = 1.5)\n\nsweepSketch = startSketchOn(XY)\n |> circle(center = [0, 0], radius = 2)\n |> hole(pipeHole, %)\n |> sweep(path = sweepPath)\n |> rotate(roll = 10, pitch = 10, yaw = 90)",
|
||||
"// Rotate a pipe with just roll.\n\n// Create a path for the sweep.\nsweepPath = startSketchOn(XZ)\n |> startProfileAt([0.05, 0.05], %)\n |> line(end = [0, 7])\n |> tangentialArc({ offset = 90, radius = 5 }, %)\n |> line(end = [-3, 0])\n |> tangentialArc({ offset = -90, radius = 5 }, %)\n |> line(end = [0, 7])\n\n// Create a hole for the pipe.\npipeHole = startSketchOn(XY)\n |> circle(center = [0, 0], radius = 1.5)\n\nsweepSketch = startSketchOn(XY)\n |> circle(center = [0, 0], radius = 2)\n |> hole(pipeHole, %)\n |> sweep(path = sweepPath)\n |> rotate(roll = 10)",
|
||||
"// Rotate a pipe about an axis with an angle.\n\n// Create a path for the sweep.\nsweepPath = startSketchOn(XZ)\n |> startProfileAt([0.05, 0.05], %)\n |> line(end = [0, 7])\n |> tangentialArc({ offset = 90, radius = 5 }, %)\n |> line(end = [-3, 0])\n |> tangentialArc({ offset = -90, radius = 5 }, %)\n |> line(end = [0, 7])\n\n// Create a hole for the pipe.\npipeHole = startSketchOn(XY)\n |> circle(center = [0, 0], radius = 1.5)\n\nsweepSketch = startSketchOn(XY)\n |> circle(center = [0, 0], radius = 2)\n |> hole(pipeHole, %)\n |> sweep(path = sweepPath)\n |> rotate(axis = [0, 0, 1.0], angle = 90)",
|
||||
"// Rotate an imported model.\n\n\nimport \"tests/inputs/cube.sldprt\" as cube\n\ncube\n |> rotate(axis = [0, 0, 1.0], angle = 90)",
|
||||
"// Rotate an imported model.\n\n\nimport \"tests/inputs/cube.sldprt\" as cube\n\ncube\n |> rotate(axis = [0, 0, 1.0], angle = 9)",
|
||||
"// Sweep two sketches along the same path.\n\n\nsketch001 = startSketchOn(XY)\nrectangleSketch = startProfileAt([-200, 23.86], sketch001)\n |> angledLine([0, 73.47], %, $rectangleSegmentA001)\n |> angledLine([\n segAng(rectangleSegmentA001) - 90,\n 50.61\n ], %)\n |> angledLine([\n segAng(rectangleSegmentA001),\n -segLen(rectangleSegmentA001)\n ], %)\n |> line(endAbsolute = [profileStartX(%), profileStartY(%)])\n |> close()\n\ncircleSketch = circle(sketch001, center = [200, -30.29], radius = 32.63)\n\nsketch002 = startSketchOn(YZ)\nsweepPath = startProfileAt([0, 0], sketch002)\n |> yLine(length = 231.81)\n |> tangentialArc({ radius = 80, offset = -90 }, %)\n |> xLine(length = 384.93)\n\nparts = sweep([rectangleSketch, circleSketch], path = sweepPath)\n\n// Rotate the sweeps.\nrotate(parts, axis = [0, 0, 1.0], angle = 90)",
|
||||
"// Translate and rotate a sketch to create a loft.\nsketch001 = startSketchOn(XY)\n\nfn square() {\n return startProfileAt([-10, 10], sketch001)\n |> xLine(length = 20)\n |> yLine(length = -20)\n |> xLine(length = -20)\n |> line(endAbsolute = [profileStartX(%), profileStartY(%)])\n |> close()\n}\n\nprofile001 = square()\n\nprofile002 = square()\n |> translate(x = 0, y = 0, z = 20)\n |> rotate(axis = [0, 0, 1.0], angle = 45)\n\nloft([profile001, profile002])"
|
||||
]
|
||||
@ -275841,7 +275842,7 @@
|
||||
"deprecated": false,
|
||||
"examples": [
|
||||
"// Scale a pipe.\n\n// Create a path for the sweep.\nsweepPath = startSketchOn(XZ)\n |> startProfileAt([0.05, 0.05], %)\n |> line(end = [0, 7])\n |> tangentialArc({ offset = 90, radius = 5 }, %)\n |> line(end = [-3, 0])\n |> tangentialArc({ offset = -90, radius = 5 }, %)\n |> line(end = [0, 7])\n\n// Create a hole for the pipe.\npipeHole = startSketchOn(XY)\n |> circle(center = [0, 0], radius = 1.5)\n\nsweepSketch = startSketchOn(XY)\n |> circle(center = [0, 0], radius = 2)\n |> hole(pipeHole, %)\n |> sweep(path = sweepPath)\n |> scale(z = 2.5)",
|
||||
"// Scale an imported model.\n\n\nimport \"tests/inputs/cube.sldprt\" as cube\n\ncube\n |> scale(z = 2.5)",
|
||||
"// Scale an imported model.\n\n\nimport \"tests/inputs/cube.sldprt\" as cube\n\ncube\n |> scale(y = 2.5)",
|
||||
"// Sweep two sketches along the same path.\n\n\nsketch001 = startSketchOn(XY)\nrectangleSketch = startProfileAt([-200, 23.86], sketch001)\n |> angledLine([0, 73.47], %, $rectangleSegmentA001)\n |> angledLine([\n segAng(rectangleSegmentA001) - 90,\n 50.61\n ], %)\n |> angledLine([\n segAng(rectangleSegmentA001),\n -segLen(rectangleSegmentA001)\n ], %)\n |> line(endAbsolute = [profileStartX(%), profileStartY(%)])\n |> close()\n\ncircleSketch = circle(sketch001, center = [200, -30.29], radius = 32.63)\n\nsketch002 = startSketchOn(YZ)\nsweepPath = startProfileAt([0, 0], sketch002)\n |> yLine(length = 231.81)\n |> tangentialArc({ radius = 80, offset = -90 }, %)\n |> xLine(length = 384.93)\n\nparts = sweep([rectangleSketch, circleSketch], path = sweepPath)\n\n// Scale the sweep.\nscale(parts, z = 0.5)"
|
||||
]
|
||||
},
|
||||
@ -294700,7 +294701,7 @@
|
||||
},
|
||||
"required": true,
|
||||
"includeInSnippet": true,
|
||||
"description": "The solids to intersect.",
|
||||
"description": "The solids to use as the base to subtract from.",
|
||||
"labelRequired": false
|
||||
},
|
||||
{
|
||||
@ -297904,7 +297905,8 @@
|
||||
"unpublished": false,
|
||||
"deprecated": true,
|
||||
"examples": [
|
||||
"fn cube(center) {\n return startSketchOn(XY)\n |> startProfileAt([center[0] - 10, center[1] - 10], %)\n |> line(endAbsolute = [center[0] + 10, center[1] - 10])\n |> line(endAbsolute = [center[0] + 10, center[1] + 10])\n |> line(endAbsolute = [center[0] - 10, center[1] + 10])\n |> close()\n |> extrude(length = 10)\n}\n\npart001 = cube([0, 0])\npart002 = startSketchOn(XY)\n |> circle(center = [0, 0], radius = 2)\n |> extrude(length = 10)\n\nsubtractedPart = subtract([part001], tools = [part002])"
|
||||
"// Subtract a cylinder from a cube using the stdlib functions.\n\n\nfn cube(center) {\n return startSketchOn(XY)\n |> startProfileAt([center[0] - 10, center[1] - 10], %)\n |> line(endAbsolute = [center[0] + 10, center[1] - 10])\n |> line(endAbsolute = [center[0] + 10, center[1] + 10])\n |> line(endAbsolute = [center[0] - 10, center[1] + 10])\n |> close()\n |> extrude(length = 10)\n}\n\npart001 = cube([0, 0])\npart002 = startSketchOn(XY)\n |> circle(center = [0, 0], radius = 2)\n |> extrude(length = 10)\n\nsubtractedPart = subtract([part001], tools = [part002])",
|
||||
"// Subtract a cylinder from a cube using operators.\n// NOTE: This will not work when using codemods through the UI.\n// Codemods will generate the stdlib function call instead.\n\n\nfn cube(center) {\n return startSketchOn(XY)\n |> startProfileAt([center[0] - 10, center[1] - 10], %)\n |> line(endAbsolute = [center[0] + 10, center[1] - 10])\n |> line(endAbsolute = [center[0] + 10, center[1] + 10])\n |> line(endAbsolute = [center[0] - 10, center[1] + 10])\n |> close()\n |> extrude(length = 10)\n}\n\npart001 = cube([0, 0])\npart002 = startSketchOn(XY)\n |> circle(center = [0, 0], radius = 2)\n |> extrude(length = 10)\n\n// This is the equivalent of: subtract([part001], tools=[part002])\nsubtractedPart = part001 - part002"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -334111,7 +334113,7 @@
|
||||
"deprecated": false,
|
||||
"examples": [
|
||||
"// Move a pipe.\n\n// Create a path for the sweep.\nsweepPath = startSketchOn(XZ)\n |> startProfileAt([0.05, 0.05], %)\n |> line(end = [0, 7])\n |> tangentialArc({ offset = 90, radius = 5 }, %)\n |> line(end = [-3, 0])\n |> tangentialArc({ offset = -90, radius = 5 }, %)\n |> line(end = [0, 7])\n\n// Create a hole for the pipe.\npipeHole = startSketchOn(XY)\n |> circle(center = [0, 0], radius = 1.5)\n\nsweepSketch = startSketchOn(XY)\n |> circle(center = [0, 0], radius = 2)\n |> hole(pipeHole, %)\n |> sweep(path = sweepPath)\n |> translate(x = 1.0, y = 1.0, z = 2.5)",
|
||||
"// Move an imported model.\n\n\nimport \"tests/inputs/cube.sldprt\" as cube\n\ncube\n |> translate(x = 1.0, y = 1.0, z = 2.5)",
|
||||
"// Move an imported model.\n\n\nimport \"tests/inputs/cube.sldprt\" as cube\n\n// Circle so you actually see the move.\nstartSketchOn(XY)\n |> circle(center = [-10, -10], radius = 10)\n |> extrude(length = 10)\n\ncube\n |> translate(x = 10.0, y = 10.0, z = 2.5)",
|
||||
"// Sweep two sketches along the same path.\n\n\nsketch001 = startSketchOn(XY)\nrectangleSketch = startProfileAt([-200, 23.86], sketch001)\n |> angledLine([0, 73.47], %, $rectangleSegmentA001)\n |> angledLine([\n segAng(rectangleSegmentA001) - 90,\n 50.61\n ], %)\n |> angledLine([\n segAng(rectangleSegmentA001),\n -segLen(rectangleSegmentA001)\n ], %)\n |> line(endAbsolute = [profileStartX(%), profileStartY(%)])\n |> close()\n\ncircleSketch = circle(sketch001, center = [200, -30.29], radius = 32.63)\n\nsketch002 = startSketchOn(YZ)\nsweepPath = startProfileAt([0, 0], sketch002)\n |> yLine(length = 231.81)\n |> tangentialArc({ radius = 80, offset = -90 }, %)\n |> xLine(length = 384.93)\n\nparts = sweep([rectangleSketch, circleSketch], path = sweepPath)\n\n// Move the sweeps.\ntranslate(\n parts,\n x = 1.0,\n y = 1.0,\n z = 2.5,\n)",
|
||||
"// Move a sketch.\n\n\nfn square(length) {\n l = length / 2\n p0 = [-l, -l]\n p1 = [-l, l]\n p2 = [l, l]\n p3 = [l, -l]\n\n return startSketchOn(XY)\n |> startProfileAt(p0, %)\n |> line(endAbsolute = p1)\n |> line(endAbsolute = p2)\n |> line(endAbsolute = p3)\n |> close()\n}\n\nsquare(10)\n |> translate(x = 5, y = 5)\n |> extrude(length = 10)",
|
||||
"// Translate and rotate a sketch to create a loft.\nsketch001 = startSketchOn(XY)\n\nfn square() {\n return startProfileAt([-10, 10], sketch001)\n |> xLine(length = 20)\n |> yLine(length = -20)\n |> xLine(length = -20)\n |> line(endAbsolute = [profileStartX(%), profileStartY(%)])\n |> close()\n}\n\nprofile001 = square()\n\nprofile002 = square()\n |> translate(z = 20)\n |> rotate(axis = [0, 0, 1.0], angle = 45)\n\nloft([profile001, profile002])"
|
||||
@ -337325,7 +337327,9 @@
|
||||
"unpublished": false,
|
||||
"deprecated": true,
|
||||
"examples": [
|
||||
"fn cube(center) {\n return startSketchOn(XY)\n |> startProfileAt([center[0] - 10, center[1] - 10], %)\n |> line(endAbsolute = [center[0] + 10, center[1] - 10])\n |> line(endAbsolute = [center[0] + 10, center[1] + 10])\n |> line(endAbsolute = [center[0] - 10, center[1] + 10])\n |> close()\n |> extrude(length = 10)\n}\n\npart001 = cube([0, 0])\npart002 = cube([20, 10])\n\nunionedPart = union([part001, part002])"
|
||||
"// Union two cubes using the stdlib functions.\n\n\nfn cube(center) {\n return startSketchOn(XY)\n |> startProfileAt([center[0] - 10, center[1] - 10], %)\n |> line(endAbsolute = [center[0] + 10, center[1] - 10])\n |> line(endAbsolute = [center[0] + 10, center[1] + 10])\n |> line(endAbsolute = [center[0] - 10, center[1] + 10])\n |> close()\n |> extrude(length = 10)\n}\n\npart001 = cube([0, 0])\npart002 = cube([20, 10])\n\nunionedPart = union([part001, part002])",
|
||||
"// Union two cubes using operators.\n// NOTE: This will not work when using codemods through the UI.\n// Codemods will generate the stdlib function call instead.\n\n\nfn cube(center) {\n return startSketchOn(XY)\n |> startProfileAt([center[0] - 10, center[1] - 10], %)\n |> line(endAbsolute = [center[0] + 10, center[1] - 10])\n |> line(endAbsolute = [center[0] + 10, center[1] + 10])\n |> line(endAbsolute = [center[0] - 10, center[1] + 10])\n |> close()\n |> extrude(length = 10)\n}\n\npart001 = cube([0, 0])\npart002 = cube([20, 10])\n\n// This is the equivalent of: union([part001, part002])\nunionedPart = part001 + part002",
|
||||
"// Union two cubes using the more programmer-friendly operator.\n// NOTE: This will not work when using codemods through the UI.\n// Codemods will generate the stdlib function call instead.\n\n\nfn cube(center) {\n return startSketchOn(XY)\n |> startProfileAt([center[0] - 10, center[1] - 10], %)\n |> line(endAbsolute = [center[0] + 10, center[1] - 10])\n |> line(endAbsolute = [center[0] + 10, center[1] + 10])\n |> line(endAbsolute = [center[0] - 10, center[1] + 10])\n |> close()\n |> extrude(length = 10)\n}\n\npart001 = cube([0, 0])\npart002 = cube([20, 10])\n\n// This is the equivalent of: union([part001, part002])\n// Programmers will understand `|` as a union operation, but mechanical engineers\n// will understand `+`, we made both work.\nunionedPart = part001 | part002"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
@ -1 +1,13 @@
|
||||
$ dpdm --no-warning --no-tree -T --skip-dynamic-imports=circular src/index.tsx• Circular Dependencies 01) src/lang/std/sketch.ts -> src/lang/modifyAst.ts -> src/lang/modifyAst/addEdgeTreatment.ts 02) src/lang/std/sketch.ts -> src/lang/modifyAst.ts 03) src/lang/std/sketch.ts -> src/lang/modifyAst.ts -> src/lang/std/sketchcombos.ts 04) src/clientSideScene/CameraControls.ts -> src/clientSideScene/sceneInfra.ts 05) src/lib/singletons.ts -> src/editor/manager.ts -> src/lib/selections.ts 06) src/lib/singletons.ts -> src/editor/manager.ts 07) src/lib/singletons.ts -> src/lang/KclSingleton.ts 08) src/lib/singletons.ts -> src/lang/codeManager.ts 09) src/lib/singletons.ts -> src/clientSideScene/sceneEntities.ts -> src/clientSideScene/segments.ts -> src/components/Toolbar/angleLengthInfo.ts 10) src/lib/singletons.ts -> src/clientSideScene/sceneEntities.ts -> src/clientSideScene/segments.ts -> src/machines/commandBarMachine.ts -> src/lib/commandBarConfigs/authCommandConfig.ts -> src/machines/appMachine.ts -> src/machines/settingsMachine.ts -> src/lib/commandBarConfigs/settingsCommandConfig.ts -> src/lib/createMachineCommand.ts -> src/routes/Settings.tsx -> src/components/Settings/AllSettingsFields.tsx -> src/components/LspProvider.tsx -> src/editor/plugins/lsp/copilot/index.ts 11) src/lib/singletons.ts -> src/clientSideScene/sceneEntities.ts -> src/clientSideScene/segments.ts -> src/machines/commandBarMachine.ts -> src/lib/commandBarConfigs/authCommandConfig.ts -> src/machines/appMachine.ts -> src/machines/settingsMachine.ts -> src/lib/commandBarConfigs/settingsCommandConfig.ts -> src/lib/createMachineCommand.ts -> src/routes/Settings.tsx -> src/components/Settings/AllSettingsFields.tsx -> src/components/LspProvider.tsx -> src/editor/plugins/lsp/kcl/language.ts -> src/editor/plugins/lsp/kcl/index.ts 12) src/lib/singletons.ts -> src/clientSideScene/sceneEntities.ts -> src/clientSideScene/segments.ts -> src/machines/commandBarMachine.ts -> src/lib/commandBarConfigs/authCommandConfig.ts -> src/machines/appMachine.ts -> src/machines/settingsMachine.ts -> src/lib/commandBarConfigs/settingsCommandConfig.ts -> src/lib/createMachineCommand.ts -> src/routes/Settings.tsx -> src/components/Settings/AllSettingsFields.tsx -> src/components/LspProvider.tsx 13) src/machines/appMachine.ts -> src/machines/settingsMachine.ts -> src/lib/commandBarConfigs/settingsCommandConfig.ts -> src/lib/createMachineCommand.ts -> src/routes/Settings.tsx -> src/components/Settings/AllSettingsFields.tsx -> src/components/LspProvider.tsx 14) src/machines/appMachine.ts -> src/machines/settingsMachine.ts -> src/lib/commandBarConfigs/settingsCommandConfig.ts -> src/lib/createMachineCommand.ts -> src/routes/Settings.tsx -> src/components/Settings/AllSettingsFields.tsx -> src/components/Settings/SettingsFieldInput.tsx 15) src/machines/appMachine.ts -> src/machines/settingsMachine.ts -> src/lib/commandBarConfigs/settingsCommandConfig.ts -> src/lib/createMachineCommand.ts -> src/routes/Settings.tsx -> src/components/Settings/AllSettingsFields.tsx 16) src/routes/Settings.tsx -> src/components/Settings/AllSettingsFields.tsx 17) src/machines/appMachine.ts -> src/machines/settingsMachine.ts -> src/lib/commandBarConfigs/settingsCommandConfig.ts -> src/lib/createMachineCommand.ts -> src/routes/Settings.tsx -> src/components/Settings/SettingsSearchBar.tsx 18) src/machines/appMachine.ts -> src/machines/settingsMachine.ts -> src/lib/commandBarConfigs/settingsCommandConfig.ts -> src/lib/createMachineCommand.ts -> src/routes/Settings.tsx -> src/components/Settings/SettingsSectionsList.tsx 19) src/lib/singletons.ts -> src/clientSideScene/sceneEntities.ts -> src/clientSideScene/segments.ts -> src/machines/commandBarMachine.ts -> src/lib/commandBarConfigs/authCommandConfig.ts -> src/machines/appMachine.ts -> src/machines/settingsMachine.ts 20) src/machines/commandBarMachine.ts -> src/lib/commandBarConfigs/authCommandConfig.ts -> src/machines/appMachine.ts -> src/machines/settingsMachine.ts 21) src/hooks/useModelingContext.ts -> src/components/ModelingMachineProvider.tsx -> src/components/Toolbar/Intersect.tsx -> src/components/SetHorVertDistanceModal.tsx -> src/lib/useCalculateKclExpression.ts 22) src/components/ToastTextToCad.tsx -> src/lib/textToCad.ts 23) src/hooks/useModelingContext.ts -> src/components/ModelingMachineProvider.tsx -> src/machines/modelingMachine.ts -> src/clientSideScene/ClientSideSceneComp.tsx 24) src/routes/Onboarding/index.tsx -> src/routes/Onboarding/Camera.tsx -> src/routes/Onboarding/utils.tsx
|
||||
$ dpdm --no-warning --no-tree -T --skip-dynamic-imports=circular src/index.tsx
|
||||
• Circular Dependencies
|
||||
01) src/lang/std/sketch.ts -> src/lang/modifyAst.ts -> src/lang/modifyAst/addEdgeTreatment.ts
|
||||
02) src/lang/std/sketch.ts -> src/lang/modifyAst.ts
|
||||
03) src/lang/std/sketch.ts -> src/lang/modifyAst.ts -> src/lang/std/sketchcombos.ts
|
||||
04) src/lib/singletons.ts -> src/editor/manager.ts -> src/lib/selections.ts
|
||||
05) src/lib/singletons.ts -> src/lang/KclSingleton.ts
|
||||
06) src/lib/singletons.ts -> src/lang/codeManager.ts
|
||||
07) src/lib/singletons.ts -> src/clientSideScene/sceneEntities.ts -> src/clientSideScene/segments.ts -> src/components/Toolbar/angleLengthInfo.ts
|
||||
08) src/lib/singletons.ts -> src/clientSideScene/sceneEntities.ts -> src/clientSideScene/segments.ts -> src/machines/commandBarMachine.ts -> src/lib/commandBarConfigs/authCommandConfig.ts -> src/machines/appMachine.ts -> src/machines/settingsMachine.ts
|
||||
09) src/machines/commandBarMachine.ts -> src/lib/commandBarConfigs/authCommandConfig.ts -> src/machines/appMachine.ts -> src/machines/settingsMachine.ts
|
||||
10) src/hooks/useModelingContext.ts -> src/components/ModelingMachineProvider.tsx -> src/components/Toolbar/Intersect.tsx -> src/components/SetHorVertDistanceModal.tsx -> src/lib/useCalculateKclExpression.ts
|
||||
11) src/routes/Onboarding/index.tsx -> src/routes/Onboarding/Camera.tsx -> src/routes/Onboarding/utils.tsx
|
||||
|
@ -103,6 +103,7 @@
|
||||
"lint-fix": "eslint --fix --ext .ts --ext .tsx src e2e packages/codemirror-lsp-client/src rust/kcl-language-server/client/src",
|
||||
"lint": "eslint --max-warnings 0 --ext .ts --ext .tsx src e2e packages/codemirror-lsp-client/src rust/kcl-language-server/client/src",
|
||||
"circular-deps": "dpdm --no-warning --no-tree -T --skip-dynamic-imports=circular src/index.tsx",
|
||||
"circular-deps:overwrite": "yarn circular-deps | sed '$d' | grep -v '^yarn run' > known-circular.txt",
|
||||
"circular-deps:diff": "./scripts/diff-circular-deps.sh",
|
||||
"files:set-version": "echo \"$(jq --arg v \"$VERSION\" '.version=$v' package.json --indent 2)\" > package.json",
|
||||
"files:set-notes": "./scripts/set-files-notes.sh",
|
||||
@ -232,7 +233,7 @@
|
||||
"ts-node": "^10.0.0",
|
||||
"typescript": "^5.8.2",
|
||||
"typescript-eslint": "^8.26.1",
|
||||
"vite": "^5.4.12",
|
||||
"vite": "^5.4.16",
|
||||
"vite-plugin-package-version": "^1.1.0",
|
||||
"vite-plugin-top-level-await": "^1.5.0",
|
||||
"vite-tsconfig-paths": "^4.3.2",
|
||||
|
@ -683,9 +683,9 @@ vite-tsconfig-paths@^4.3.2:
|
||||
tsconfck "^3.0.3"
|
||||
|
||||
vite@^5.0.0:
|
||||
version "5.4.14"
|
||||
resolved "https://registry.yarnpkg.com/vite/-/vite-5.4.14.tgz#ff8255edb02134df180dcfca1916c37a6abe8408"
|
||||
integrity sha512-EK5cY7Q1D8JNhSaPKVK4pwBFvaTmZxEnoKXLG/U9gmdDcihQGNzFlgIvaxezFR4glP1LsuiedwMBqCXH3wZccA==
|
||||
version "5.4.16"
|
||||
resolved "https://registry.yarnpkg.com/vite/-/vite-5.4.16.tgz#471983257a890ef33f2700cbbbc2134f2d08abf1"
|
||||
integrity sha512-Y5gnfp4NemVfgOTDQAunSD4346fal44L9mszGGY/e+qxsRT5y1sMlS/8tiQ8AFAp+MFgYNSINdfEchJiPm41vQ==
|
||||
dependencies:
|
||||
esbuild "^0.21.3"
|
||||
postcss "^8.4.43"
|
||||
|
20
rust/Cargo.lock
generated
@ -1780,7 +1780,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "kcl-bumper"
|
||||
version = "0.1.57"
|
||||
version = "0.1.58"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"clap",
|
||||
@ -1791,7 +1791,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "kcl-derive-docs"
|
||||
version = "0.1.57"
|
||||
version = "0.1.58"
|
||||
dependencies = [
|
||||
"Inflector",
|
||||
"anyhow",
|
||||
@ -1810,7 +1810,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "kcl-directory-test-macro"
|
||||
version = "0.1.57"
|
||||
version = "0.1.58"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -1819,7 +1819,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "kcl-language-server"
|
||||
version = "0.2.57"
|
||||
version = "0.2.58"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"clap",
|
||||
@ -1840,7 +1840,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "kcl-language-server-release"
|
||||
version = "0.1.57"
|
||||
version = "0.1.58"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"clap",
|
||||
@ -1860,7 +1860,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "kcl-lib"
|
||||
version = "0.2.57"
|
||||
version = "0.2.58"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"approx 0.5.1",
|
||||
@ -1928,7 +1928,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "kcl-python-bindings"
|
||||
version = "0.3.57"
|
||||
version = "0.3.58"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"kcl-lib",
|
||||
@ -1943,7 +1943,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "kcl-test-server"
|
||||
version = "0.1.57"
|
||||
version = "0.1.58"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"hyper 0.14.32",
|
||||
@ -1956,7 +1956,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "kcl-to-core"
|
||||
version = "0.1.57"
|
||||
version = "0.1.58"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
@ -1970,7 +1970,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "kcl-wasm-lib"
|
||||
version = "0.1.57"
|
||||
version = "0.1.58"
|
||||
dependencies = [
|
||||
"bson",
|
||||
"console_error_panic_hook",
|
||||
|
@ -1,7 +1,7 @@
|
||||
|
||||
[package]
|
||||
name = "kcl-bumper"
|
||||
version = "0.1.57"
|
||||
version = "0.1.58"
|
||||
edition = "2021"
|
||||
repository = "https://github.com/KittyCAD/modeling-api"
|
||||
rust-version = "1.76"
|
||||
|
@ -1,7 +1,7 @@
|
||||
[package]
|
||||
name = "kcl-derive-docs"
|
||||
description = "A tool for generating documentation from Rust derive macros"
|
||||
version = "0.1.57"
|
||||
version = "0.1.58"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
repository = "https://github.com/KittyCAD/modeling-app"
|
||||
|
@ -1,7 +1,7 @@
|
||||
[package]
|
||||
name = "kcl-directory-test-macro"
|
||||
description = "A tool for generating tests from a directory of kcl files"
|
||||
version = "0.1.57"
|
||||
version = "0.1.58"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
repository = "https://github.com/KittyCAD/modeling-app"
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "kcl-language-server-release"
|
||||
version = "0.1.57"
|
||||
version = "0.1.58"
|
||||
edition = "2021"
|
||||
authors = ["KittyCAD Inc <kcl@kittycad.io>"]
|
||||
publish = false
|
||||
|
@ -2,7 +2,7 @@
|
||||
name = "kcl-language-server"
|
||||
description = "A language server for KCL."
|
||||
authors = ["KittyCAD Inc <kcl@kittycad.io>"]
|
||||
version = "0.2.57"
|
||||
version = "0.2.58"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
@ -1,7 +1,7 @@
|
||||
[package]
|
||||
name = "kcl-lib"
|
||||
description = "KittyCAD Language implementation and tools"
|
||||
version = "0.2.57"
|
||||
version = "0.2.58"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
repository = "https://github.com/KittyCAD/modeling-app"
|
||||
|
@ -902,6 +902,33 @@ impl Node<BinaryExpression> {
|
||||
}
|
||||
}
|
||||
|
||||
// Then check if we have solids.
|
||||
if self.operator == BinaryOperator::Add || self.operator == BinaryOperator::Or {
|
||||
if let (KclValue::Solid { value: left }, KclValue::Solid { value: right }) = (&left_value, &right_value) {
|
||||
let args = crate::std::Args::new(Default::default(), self.into(), ctx.clone(), None);
|
||||
let result =
|
||||
crate::std::csg::inner_union(vec![*left.clone(), *right.clone()], exec_state, args).await?;
|
||||
return Ok(result.into());
|
||||
}
|
||||
} else if self.operator == BinaryOperator::Sub {
|
||||
// Check if we have solids.
|
||||
if let (KclValue::Solid { value: left }, KclValue::Solid { value: right }) = (&left_value, &right_value) {
|
||||
let args = crate::std::Args::new(Default::default(), self.into(), ctx.clone(), None);
|
||||
let result =
|
||||
crate::std::csg::inner_subtract(vec![*left.clone()], vec![*right.clone()], exec_state, args)
|
||||
.await?;
|
||||
return Ok(result.into());
|
||||
}
|
||||
} else if self.operator == BinaryOperator::And {
|
||||
// Check if we have solids.
|
||||
if let (KclValue::Solid { value: left }, KclValue::Solid { value: right }) = (&left_value, &right_value) {
|
||||
let args = crate::std::Args::new(Default::default(), self.into(), ctx.clone(), None);
|
||||
let result =
|
||||
crate::std::csg::inner_intersect(vec![*left.clone(), *right.clone()], exec_state, args).await?;
|
||||
return Ok(result.into());
|
||||
}
|
||||
}
|
||||
|
||||
// Check if we are doing logical operations on booleans.
|
||||
if self.operator == BinaryOperator::Or || self.operator == BinaryOperator::And {
|
||||
let KclValue::Bool {
|
||||
|
@ -28,6 +28,8 @@ pub async fn union(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K
|
||||
/// Union two or more solids into a single solid.
|
||||
///
|
||||
/// ```no_run
|
||||
/// // Union two cubes using the stdlib functions.
|
||||
///
|
||||
/// fn cube(center) {
|
||||
/// return startSketchOn('XY')
|
||||
/// |> startProfileAt([center[0] - 10, center[1] - 10], %)
|
||||
@ -43,6 +45,52 @@ pub async fn union(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K
|
||||
///
|
||||
/// unionedPart = union([part001, part002])
|
||||
/// ```
|
||||
///
|
||||
/// ```no_run
|
||||
/// // Union two cubes using operators.
|
||||
/// // NOTE: This will not work when using codemods through the UI.
|
||||
/// // Codemods will generate the stdlib function call instead.
|
||||
///
|
||||
/// fn cube(center) {
|
||||
/// return startSketchOn('XY')
|
||||
/// |> startProfileAt([center[0] - 10, center[1] - 10], %)
|
||||
/// |> line(endAbsolute = [center[0] + 10, center[1] - 10])
|
||||
/// |> line(endAbsolute = [center[0] + 10, center[1] + 10])
|
||||
/// |> line(endAbsolute = [center[0] - 10, center[1] + 10])
|
||||
/// |> close()
|
||||
/// |> extrude(length = 10)
|
||||
/// }
|
||||
///
|
||||
/// part001 = cube([0, 0])
|
||||
/// part002 = cube([20, 10])
|
||||
///
|
||||
/// // This is the equivalent of: union([part001, part002])
|
||||
/// unionedPart = part001 + part002
|
||||
/// ```
|
||||
///
|
||||
/// ```no_run
|
||||
/// // Union two cubes using the more programmer-friendly operator.
|
||||
/// // NOTE: This will not work when using codemods through the UI.
|
||||
/// // Codemods will generate the stdlib function call instead.
|
||||
///
|
||||
/// fn cube(center) {
|
||||
/// return startSketchOn('XY')
|
||||
/// |> startProfileAt([center[0] - 10, center[1] - 10], %)
|
||||
/// |> line(endAbsolute = [center[0] + 10, center[1] - 10])
|
||||
/// |> line(endAbsolute = [center[0] + 10, center[1] + 10])
|
||||
/// |> line(endAbsolute = [center[0] - 10, center[1] + 10])
|
||||
/// |> close()
|
||||
/// |> extrude(length = 10)
|
||||
/// }
|
||||
///
|
||||
/// part001 = cube([0, 0])
|
||||
/// part002 = cube([20, 10])
|
||||
///
|
||||
/// // This is the equivalent of: union([part001, part002])
|
||||
/// // Programmers will understand `|` as a union operation, but mechanical engineers
|
||||
/// // will understand `+`, we made both work.
|
||||
/// unionedPart = part001 | part002
|
||||
/// ```
|
||||
#[stdlib {
|
||||
name = "union",
|
||||
feature_tree_operation = true,
|
||||
@ -53,7 +101,11 @@ pub async fn union(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K
|
||||
solids = {docs = "The solids to union."},
|
||||
}
|
||||
}]
|
||||
async fn inner_union(solids: Vec<Solid>, exec_state: &mut ExecState, args: Args) -> Result<Vec<Solid>, KclError> {
|
||||
pub(crate) async fn inner_union(
|
||||
solids: Vec<Solid>,
|
||||
exec_state: &mut ExecState,
|
||||
args: Args,
|
||||
) -> Result<Vec<Solid>, KclError> {
|
||||
// Flush the fillets for the solids.
|
||||
args.flush_batch_for_solids(exec_state, &solids).await?;
|
||||
|
||||
@ -90,6 +142,8 @@ pub async fn intersect(exec_state: &mut ExecState, args: Args) -> Result<KclValu
|
||||
/// verifying fit, and analyzing overlapping geometries in assemblies.
|
||||
///
|
||||
/// ```no_run
|
||||
/// // Intersect two cubes using the stdlib functions.
|
||||
///
|
||||
/// fn cube(center) {
|
||||
/// return startSketchOn('XY')
|
||||
/// |> startProfileAt([center[0] - 10, center[1] - 10], %)
|
||||
@ -105,6 +159,28 @@ pub async fn intersect(exec_state: &mut ExecState, args: Args) -> Result<KclValu
|
||||
///
|
||||
/// intersectedPart = intersect([part001, part002])
|
||||
/// ```
|
||||
///
|
||||
/// ```no_run
|
||||
/// // Intersect two cubes using operators.
|
||||
/// // NOTE: This will not work when using codemods through the UI.
|
||||
/// // Codemods will generate the stdlib function call instead.
|
||||
///
|
||||
/// fn cube(center) {
|
||||
/// return startSketchOn('XY')
|
||||
/// |> startProfileAt([center[0] - 10, center[1] - 10], %)
|
||||
/// |> line(endAbsolute = [center[0] + 10, center[1] - 10])
|
||||
/// |> line(endAbsolute = [center[0] + 10, center[1] + 10])
|
||||
/// |> line(endAbsolute = [center[0] - 10, center[1] + 10])
|
||||
/// |> close()
|
||||
/// |> extrude(length = 10)
|
||||
/// }
|
||||
///
|
||||
/// part001 = cube([0, 0])
|
||||
/// part002 = cube([8, 8])
|
||||
///
|
||||
/// // This is the equivalent of: intersect([part001, part002])
|
||||
/// intersectedPart = part001 & part002
|
||||
/// ```
|
||||
#[stdlib {
|
||||
name = "intersect",
|
||||
feature_tree_operation = true,
|
||||
@ -115,7 +191,11 @@ pub async fn intersect(exec_state: &mut ExecState, args: Args) -> Result<KclValu
|
||||
solids = {docs = "The solids to intersect."},
|
||||
}
|
||||
}]
|
||||
async fn inner_intersect(solids: Vec<Solid>, exec_state: &mut ExecState, args: Args) -> Result<Vec<Solid>, KclError> {
|
||||
pub(crate) async fn inner_intersect(
|
||||
solids: Vec<Solid>,
|
||||
exec_state: &mut ExecState,
|
||||
args: Args,
|
||||
) -> Result<Vec<Solid>, KclError> {
|
||||
// Flush the fillets for the solids.
|
||||
args.flush_batch_for_solids(exec_state, &solids).await?;
|
||||
|
||||
@ -145,6 +225,8 @@ pub async fn subtract(exec_state: &mut ExecState, args: Args) -> Result<KclValue
|
||||
/// and complex multi-body part modeling.
|
||||
///
|
||||
/// ```no_run
|
||||
/// // Subtract a cylinder from a cube using the stdlib functions.
|
||||
///
|
||||
/// fn cube(center) {
|
||||
/// return startSketchOn('XY')
|
||||
/// |> startProfileAt([center[0] - 10, center[1] - 10], %)
|
||||
@ -162,6 +244,30 @@ pub async fn subtract(exec_state: &mut ExecState, args: Args) -> Result<KclValue
|
||||
///
|
||||
/// subtractedPart = subtract([part001], tools=[part002])
|
||||
/// ```
|
||||
///
|
||||
/// ```no_run
|
||||
/// // Subtract a cylinder from a cube using operators.
|
||||
/// // NOTE: This will not work when using codemods through the UI.
|
||||
/// // Codemods will generate the stdlib function call instead.
|
||||
///
|
||||
/// fn cube(center) {
|
||||
/// return startSketchOn('XY')
|
||||
/// |> startProfileAt([center[0] - 10, center[1] - 10], %)
|
||||
/// |> line(endAbsolute = [center[0] + 10, center[1] - 10])
|
||||
/// |> line(endAbsolute = [center[0] + 10, center[1] + 10])
|
||||
/// |> line(endAbsolute = [center[0] - 10, center[1] + 10])
|
||||
/// |> close()
|
||||
/// |> extrude(length = 10)
|
||||
/// }
|
||||
///
|
||||
/// part001 = cube([0, 0])
|
||||
/// part002 = startSketchOn('XY')
|
||||
/// |> circle(center = [0, 0], radius = 2)
|
||||
/// |> extrude(length = 10)
|
||||
///
|
||||
/// // This is the equivalent of: subtract([part001], tools=[part002])
|
||||
/// subtractedPart = part001 - part002
|
||||
/// ```
|
||||
#[stdlib {
|
||||
name = "subtract",
|
||||
feature_tree_operation = true,
|
||||
@ -169,11 +275,11 @@ pub async fn subtract(exec_state: &mut ExecState, args: Args) -> Result<KclValue
|
||||
unlabeled_first = true,
|
||||
deprecated = true,
|
||||
args = {
|
||||
solids = {docs = "The solids to intersect."},
|
||||
solids = {docs = "The solids to use as the base to subtract from."},
|
||||
tools = {docs = "The solids to subtract."},
|
||||
}
|
||||
}]
|
||||
async fn inner_subtract(
|
||||
pub(crate) async fn inner_subtract(
|
||||
solids: Vec<Solid>,
|
||||
tools: Vec<Solid>,
|
||||
exec_state: &mut ExecState,
|
||||
|
@ -104,7 +104,7 @@ pub async fn scale(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K
|
||||
///
|
||||
/// cube
|
||||
/// |> scale(
|
||||
/// z = 2.5,
|
||||
/// y = 2.5,
|
||||
/// )
|
||||
/// ```
|
||||
///
|
||||
@ -278,10 +278,20 @@ pub async fn translate(exec_state: &mut ExecState, args: Args) -> Result<KclValu
|
||||
///
|
||||
/// import "tests/inputs/cube.sldprt" as cube
|
||||
///
|
||||
/// // Circle so you actually see the move.
|
||||
/// startSketchOn('XY')
|
||||
/// |> circle(
|
||||
/// center = [-10, -10],
|
||||
/// radius = 10,
|
||||
/// )
|
||||
/// |> extrude(
|
||||
/// length = 10,
|
||||
/// )
|
||||
///
|
||||
/// cube
|
||||
/// |> translate(
|
||||
/// x = 1.0,
|
||||
/// y = 1.0,
|
||||
/// x = 10.0,
|
||||
/// y = 10.0,
|
||||
/// z = 2.5,
|
||||
/// )
|
||||
/// ```
|
||||
@ -680,7 +690,7 @@ pub async fn rotate(exec_state: &mut ExecState, args: Args) -> Result<KclValue,
|
||||
/// cube
|
||||
/// |> rotate(
|
||||
/// axis = [0, 0, 1.0],
|
||||
/// angle = 90,
|
||||
/// angle = 9,
|
||||
/// )
|
||||
/// ```
|
||||
///
|
||||
|
Before Width: | Height: | Size: 65 KiB After Width: | Height: | Size: 71 KiB |
BIN
rust/kcl-lib/tests/outputs/serial_test_example_intersect1.png
Normal file
After Width: | Height: | Size: 67 KiB |
Before Width: | Height: | Size: 74 KiB After Width: | Height: | Size: 66 KiB |
Before Width: | Height: | Size: 73 KiB After Width: | Height: | Size: 49 KiB |
BIN
rust/kcl-lib/tests/outputs/serial_test_example_subtract1.png
Normal file
After Width: | Height: | Size: 70 KiB |
Before Width: | Height: | Size: 74 KiB After Width: | Height: | Size: 74 KiB |
BIN
rust/kcl-lib/tests/outputs/serial_test_example_union1.png
Normal file
After Width: | Height: | Size: 62 KiB |
BIN
rust/kcl-lib/tests/outputs/serial_test_example_union2.png
Normal file
After Width: | Height: | Size: 62 KiB |
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "kcl-python-bindings"
|
||||
version = "0.3.57"
|
||||
version = "0.3.58"
|
||||
edition = "2021"
|
||||
repository = "https://github.com/kittycad/modeling-app"
|
||||
exclude = ["tests/*", "files/*", "venv/*"]
|
||||
|
@ -1,7 +1,7 @@
|
||||
[package]
|
||||
name = "kcl-test-server"
|
||||
description = "A test server for KCL"
|
||||
version = "0.1.57"
|
||||
version = "0.1.58"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
[package]
|
||||
name = "kcl-to-core"
|
||||
description = "Utility methods to convert kcl to engine core executable tests"
|
||||
version = "0.1.57"
|
||||
version = "0.1.58"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
repository = "https://github.com/KittyCAD/modeling-app"
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "kcl-wasm-lib"
|
||||
version = "0.1.57"
|
||||
version = "0.1.58"
|
||||
edition = "2021"
|
||||
repository = "https://github.com/KittyCAD/modeling-app"
|
||||
rust-version = "1.83"
|
||||
|
@ -1,5 +1,5 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
yarn circular-deps | sed '$d' | grep -v '^yarn run' | tr -d '\n' > /tmp/circular-deps.txt
|
||||
diff -w /tmp/circular-deps.txt ./known-circular.txt
|
||||
yarn circular-deps | sed '$d' | grep -v '^yarn run' > /tmp/circular-deps.txt
|
||||
diff --ignore-blank-lines -w /tmp/circular-deps.txt ./known-circular.txt
|
||||
|
@ -20,7 +20,7 @@ import {
|
||||
INTERSECTION_PLANE_LAYER,
|
||||
SKETCH_LAYER,
|
||||
ZOOM_MAGIC_NUMBER,
|
||||
} from '@src/clientSideScene/sceneInfra'
|
||||
} from '@src/clientSideScene/sceneUtils'
|
||||
import type { EngineCommand } from '@src/lang/std/artifactGraph'
|
||||
import type {
|
||||
EngineCommandManager,
|
||||
|
@ -1,8 +1,6 @@
|
||||
import { Dialog, Popover, Transition } from '@headlessui/react'
|
||||
import { Fragment, useEffect, useMemo, useRef, useState } from 'react'
|
||||
import { Popover } from '@headlessui/react'
|
||||
import { useEffect, useMemo, useRef, useState } from 'react'
|
||||
import toast from 'react-hot-toast'
|
||||
import type { InstanceProps } from 'react-modal-promise'
|
||||
import { create } from 'react-modal-promise'
|
||||
|
||||
import type { Node } from '@rust/kcl-lib/bindings/Node'
|
||||
|
||||
@ -15,16 +13,11 @@ import {
|
||||
import {
|
||||
ARROWHEAD,
|
||||
DEBUG_SHOW_BOTH_SCENES,
|
||||
} from '@src/clientSideScene/sceneInfra'
|
||||
import { ActionButton } from '@src/components/ActionButton'
|
||||
} from '@src/clientSideScene/sceneUtils'
|
||||
import type { CustomIconName } from '@src/components/CustomIcon'
|
||||
import { CustomIcon } from '@src/components/CustomIcon'
|
||||
import { useModelingContext } from '@src/hooks/useModelingContext'
|
||||
import { executeAstMock } from '@src/lang/langHelpers'
|
||||
import {
|
||||
deleteSegmentFromPipeExpression,
|
||||
removeSingleConstraintInfo,
|
||||
} from '@src/lang/modifyAst'
|
||||
import { removeSingleConstraintInfo } from '@src/lang/modifyAst'
|
||||
import { findUsesOfTagInPipe, getNodeFromPath } from '@src/lang/queryAst'
|
||||
import { getConstraintInfo, getConstraintInfoKw } from '@src/lang/std/sketch'
|
||||
import type { ConstrainInfo } from '@src/lang/std/stdTypes'
|
||||
@ -34,7 +27,6 @@ import type {
|
||||
CallExpressionKw,
|
||||
Expr,
|
||||
PathToNode,
|
||||
Program,
|
||||
} from '@src/lang/wasm'
|
||||
import { defaultSourceRange, parse, recast, resultIsOk } from '@src/lang/wasm'
|
||||
import { cameraMouseDragGuards } from '@src/lib/cameraControls'
|
||||
@ -43,7 +35,6 @@ import {
|
||||
editorManager,
|
||||
engineCommandManager,
|
||||
kclManager,
|
||||
rustContext,
|
||||
sceneEntitiesManager,
|
||||
sceneInfra,
|
||||
} from '@src/lib/singletons'
|
||||
@ -51,10 +42,7 @@ import { err, reportRejection, trap } from '@src/lib/trap'
|
||||
import { throttle, toSync } from '@src/lib/utils'
|
||||
import type { useSettings } from '@src/machines/appMachine'
|
||||
import { commandBarActor } from '@src/machines/commandBarMachine'
|
||||
import type {
|
||||
SegmentOverlay,
|
||||
SketchDetails,
|
||||
} from '@src/machines/modelingMachine'
|
||||
import type { SegmentOverlay } from '@src/machines/modelingMachine'
|
||||
|
||||
function useShouldHideScene(): { hideClient: boolean; hideServer: boolean } {
|
||||
const [isCamMoving, setIsCamMoving] = useState(false)
|
||||
@ -343,130 +331,6 @@ const Overlay = ({
|
||||
)
|
||||
}
|
||||
|
||||
type ConfirmModalProps = InstanceProps<boolean, boolean> & { text: string }
|
||||
|
||||
export const ConfirmModal = ({
|
||||
isOpen,
|
||||
onResolve,
|
||||
onReject,
|
||||
text,
|
||||
}: ConfirmModalProps) => {
|
||||
return (
|
||||
<Transition appear show={isOpen} as={Fragment}>
|
||||
<Dialog
|
||||
as="div"
|
||||
className="relative z-10"
|
||||
onClose={() => onResolve(false)}
|
||||
>
|
||||
<Transition.Child
|
||||
as={Fragment}
|
||||
enter="ease-out duration-300"
|
||||
enterFrom="opacity-0"
|
||||
enterTo="opacity-100"
|
||||
leave="ease-in duration-200"
|
||||
leaveFrom="opacity-100"
|
||||
leaveTo="opacity-0"
|
||||
>
|
||||
<div className="fixed inset-0 bg-black bg-opacity-25" />
|
||||
</Transition.Child>
|
||||
|
||||
<div className="fixed inset-0 overflow-y-auto">
|
||||
<div className="flex min-h-full items-center justify-center p-4 text-center">
|
||||
<Transition.Child
|
||||
as={Fragment}
|
||||
enter="ease-out duration-300"
|
||||
enterFrom="opacity-0 scale-95"
|
||||
enterTo="opacity-100 scale-100"
|
||||
leave="ease-in duration-200"
|
||||
leaveFrom="opacity-100 scale-100"
|
||||
leaveTo="opacity-0 scale-95"
|
||||
>
|
||||
<Dialog.Panel className="rounded relative mx-auto px-4 py-8 bg-chalkboard-10 dark:bg-chalkboard-100 border dark:border-chalkboard-70 max-w-xl w-full shadow-lg">
|
||||
<div>{text}</div>
|
||||
<div className="mt-8 flex justify-between">
|
||||
<ActionButton
|
||||
Element="button"
|
||||
onClick={() => onResolve(true)}
|
||||
>
|
||||
Continue and unconstrain
|
||||
</ActionButton>
|
||||
<ActionButton
|
||||
Element="button"
|
||||
onClick={() => onReject(false)}
|
||||
>
|
||||
Cancel
|
||||
</ActionButton>
|
||||
</div>
|
||||
</Dialog.Panel>
|
||||
</Transition.Child>
|
||||
</div>
|
||||
</div>
|
||||
</Dialog>
|
||||
</Transition>
|
||||
)
|
||||
}
|
||||
|
||||
export const confirmModal = create<ConfirmModalProps, boolean, boolean>(
|
||||
ConfirmModal
|
||||
)
|
||||
|
||||
export async function deleteSegment({
|
||||
pathToNode,
|
||||
sketchDetails,
|
||||
}: {
|
||||
pathToNode: PathToNode
|
||||
sketchDetails: SketchDetails | null
|
||||
}) {
|
||||
let modifiedAst: Node<Program> | Error = kclManager.ast
|
||||
const dependentRanges = findUsesOfTagInPipe(modifiedAst, pathToNode)
|
||||
|
||||
const shouldContinueSegDelete = dependentRanges.length
|
||||
? await confirmModal({
|
||||
text: `At least ${dependentRanges.length} segment rely on the segment you're deleting.\nDo you want to continue and unconstrain these segments?`,
|
||||
isOpen: true,
|
||||
})
|
||||
: true
|
||||
|
||||
if (!shouldContinueSegDelete) return
|
||||
|
||||
modifiedAst = deleteSegmentFromPipeExpression(
|
||||
dependentRanges,
|
||||
modifiedAst,
|
||||
kclManager.variables,
|
||||
codeManager.code,
|
||||
pathToNode
|
||||
)
|
||||
if (err(modifiedAst)) return Promise.reject(modifiedAst)
|
||||
|
||||
const newCode = recast(modifiedAst)
|
||||
const pResult = parse(newCode)
|
||||
if (err(pResult) || !resultIsOk(pResult)) return Promise.reject(pResult)
|
||||
modifiedAst = pResult.program
|
||||
|
||||
const testExecute = await executeAstMock({
|
||||
ast: modifiedAst,
|
||||
usePrevMemory: false,
|
||||
rustContext: rustContext,
|
||||
})
|
||||
if (testExecute.errors.length) {
|
||||
toast.error('Segment tag used outside of current Sketch. Could not delete.')
|
||||
return
|
||||
}
|
||||
|
||||
if (!sketchDetails) return
|
||||
await sceneEntitiesManager.updateAstAndRejigSketch(
|
||||
pathToNode,
|
||||
sketchDetails.sketchNodePaths,
|
||||
sketchDetails.planeNodePath,
|
||||
modifiedAst,
|
||||
sketchDetails.zAxis,
|
||||
sketchDetails.yAxis,
|
||||
sketchDetails.origin
|
||||
)
|
||||
|
||||
// Now 'Set sketchDetails' is called with the modified pathToNode
|
||||
}
|
||||
|
||||
const SegmentMenu = ({
|
||||
verticalPosition,
|
||||
pathToNode,
|
||||
|
72
src/clientSideScene/confirmModal.tsx
Normal file
@ -0,0 +1,72 @@
|
||||
import { Fragment } from 'react'
|
||||
import { create, type InstanceProps } from 'react-modal-promise'
|
||||
|
||||
import { Dialog, Transition } from '@headlessui/react'
|
||||
import { ActionButton } from '@src/components/ActionButton'
|
||||
|
||||
type ConfirmModalProps = InstanceProps<boolean, boolean> & { text: string }
|
||||
|
||||
export const ConfirmModal = ({
|
||||
isOpen,
|
||||
onResolve,
|
||||
onReject,
|
||||
text,
|
||||
}: ConfirmModalProps) => {
|
||||
return (
|
||||
<Transition appear show={isOpen} as={Fragment}>
|
||||
<Dialog
|
||||
as="div"
|
||||
className="relative z-10"
|
||||
onClose={() => onResolve(false)}
|
||||
>
|
||||
<Transition.Child
|
||||
as={Fragment}
|
||||
enter="ease-out duration-300"
|
||||
enterFrom="opacity-0"
|
||||
enterTo="opacity-100"
|
||||
leave="ease-in duration-200"
|
||||
leaveFrom="opacity-100"
|
||||
leaveTo="opacity-0"
|
||||
>
|
||||
<div className="fixed inset-0 bg-black bg-opacity-25" />
|
||||
</Transition.Child>
|
||||
|
||||
<div className="fixed inset-0 overflow-y-auto">
|
||||
<div className="flex min-h-full items-center justify-center p-4 text-center">
|
||||
<Transition.Child
|
||||
as={Fragment}
|
||||
enter="ease-out duration-300"
|
||||
enterFrom="opacity-0 scale-95"
|
||||
enterTo="opacity-100 scale-100"
|
||||
leave="ease-in duration-200"
|
||||
leaveFrom="opacity-100 scale-100"
|
||||
leaveTo="opacity-0 scale-95"
|
||||
>
|
||||
<Dialog.Panel className="rounded relative mx-auto px-4 py-8 bg-chalkboard-10 dark:bg-chalkboard-100 border dark:border-chalkboard-70 max-w-xl w-full shadow-lg">
|
||||
<div>{text}</div>
|
||||
<div className="mt-8 flex justify-between">
|
||||
<ActionButton
|
||||
Element="button"
|
||||
onClick={() => onResolve(true)}
|
||||
>
|
||||
Continue and unconstrain
|
||||
</ActionButton>
|
||||
<ActionButton
|
||||
Element="button"
|
||||
onClick={() => onReject(false)}
|
||||
>
|
||||
Cancel
|
||||
</ActionButton>
|
||||
</div>
|
||||
</Dialog.Panel>
|
||||
</Transition.Child>
|
||||
</div>
|
||||
</div>
|
||||
</Dialog>
|
||||
</Transition>
|
||||
)
|
||||
}
|
||||
|
||||
export const confirmModal = create<ConfirmModalProps, boolean, boolean>(
|
||||
ConfirmModal
|
||||
)
|
75
src/clientSideScene/deleteSegment.ts
Normal file
@ -0,0 +1,75 @@
|
||||
import toast from 'react-hot-toast'
|
||||
|
||||
import type { Node } from '@rust/kcl-lib/bindings/Node'
|
||||
|
||||
import { confirmModal } from '@src/clientSideScene/confirmModal'
|
||||
import { executeAstMock } from '@src/lang/langHelpers'
|
||||
import { deleteSegmentFromPipeExpression } from '@src/lang/modifyAst'
|
||||
import { findUsesOfTagInPipe } from '@src/lang/queryAst'
|
||||
import type { PathToNode, Program } from '@src/lang/wasm'
|
||||
import { parse, recast, resultIsOk } from '@src/lang/wasm'
|
||||
import {
|
||||
codeManager,
|
||||
kclManager,
|
||||
rustContext,
|
||||
sceneEntitiesManager,
|
||||
} from '@src/lib/singletons'
|
||||
import { err } from '@src/lib/trap'
|
||||
import type { SketchDetails } from '@src/machines/modelingMachine'
|
||||
|
||||
export async function deleteSegment({
|
||||
pathToNode,
|
||||
sketchDetails,
|
||||
}: {
|
||||
pathToNode: PathToNode
|
||||
sketchDetails: SketchDetails | null
|
||||
}) {
|
||||
let modifiedAst: Node<Program> | Error = kclManager.ast
|
||||
const dependentRanges = findUsesOfTagInPipe(modifiedAst, pathToNode)
|
||||
|
||||
const shouldContinueSegDelete = dependentRanges.length
|
||||
? await confirmModal({
|
||||
text: `At least ${dependentRanges.length} segment rely on the segment you're deleting.\nDo you want to continue and unconstrain these segments?`,
|
||||
isOpen: true,
|
||||
})
|
||||
: true
|
||||
|
||||
if (!shouldContinueSegDelete) return
|
||||
|
||||
modifiedAst = deleteSegmentFromPipeExpression(
|
||||
dependentRanges,
|
||||
modifiedAst,
|
||||
kclManager.variables,
|
||||
codeManager.code,
|
||||
pathToNode
|
||||
)
|
||||
if (err(modifiedAst)) return Promise.reject(modifiedAst)
|
||||
|
||||
const newCode = recast(modifiedAst)
|
||||
const pResult = parse(newCode)
|
||||
if (err(pResult) || !resultIsOk(pResult)) return Promise.reject(pResult)
|
||||
modifiedAst = pResult.program
|
||||
|
||||
const testExecute = await executeAstMock({
|
||||
ast: modifiedAst,
|
||||
usePrevMemory: false,
|
||||
rustContext: rustContext,
|
||||
})
|
||||
if (testExecute.errors.length) {
|
||||
toast.error('Segment tag used outside of current Sketch. Could not delete.')
|
||||
return
|
||||
}
|
||||
|
||||
if (!sketchDetails) return
|
||||
await sceneEntitiesManager.updateAstAndRejigSketch(
|
||||
pathToNode,
|
||||
sketchDetails.sketchNodePaths,
|
||||
sketchDetails.planeNodePath,
|
||||
modifiedAst,
|
||||
sketchDetails.zAxis,
|
||||
sketchDetails.yAxis,
|
||||
sketchDetails.origin
|
||||
)
|
||||
|
||||
// Now 'Set sketchDetails' is called with the modified pathToNode
|
||||
}
|
@ -86,7 +86,7 @@ import {
|
||||
X_AXIS,
|
||||
Y_AXIS,
|
||||
getSceneScale,
|
||||
} from '@src/clientSideScene/sceneInfra'
|
||||
} from '@src/clientSideScene/sceneUtils'
|
||||
import type { SegmentUtils } from '@src/clientSideScene/segments'
|
||||
import {
|
||||
createProfileStartHandle,
|
||||
|
@ -14,7 +14,6 @@ import {
|
||||
GridHelper,
|
||||
LineBasicMaterial,
|
||||
OrthographicCamera,
|
||||
PerspectiveCamera,
|
||||
Raycaster,
|
||||
Scene,
|
||||
TextureLoader,
|
||||
@ -26,6 +25,16 @@ import { CSS2DRenderer } from 'three/examples/jsm/renderers/CSS2DRenderer'
|
||||
|
||||
import { CameraControls } from '@src/clientSideScene/CameraControls'
|
||||
import { orthoScale, perspScale } from '@src/clientSideScene/helpers'
|
||||
import {
|
||||
AXIS_GROUP,
|
||||
DEBUG_SHOW_INTERSECTION_PLANE,
|
||||
INTERSECTION_PLANE_LAYER,
|
||||
RAYCASTABLE_PLANE,
|
||||
SKETCH_LAYER,
|
||||
X_AXIS,
|
||||
Y_AXIS,
|
||||
getSceneScale,
|
||||
} from '@src/clientSideScene/sceneUtils'
|
||||
import type { useModelingContext } from '@src/hooks/useModelingContext'
|
||||
import type { EngineCommandManager } from '@src/lang/std/engineConnection'
|
||||
import type { Coords2d } from '@src/lang/std/sketch'
|
||||
@ -41,37 +50,6 @@ import type {
|
||||
|
||||
type SendType = ReturnType<typeof useModelingContext>['send']
|
||||
|
||||
// 63.5 is definitely a bit of a magic number, play with it until it looked right
|
||||
// if it were 64, that would feel like it's something in the engine where a random
|
||||
// power of 2 is used, but it's the 0.5 seems to make things look much more correct
|
||||
export const ZOOM_MAGIC_NUMBER = 63.5
|
||||
|
||||
export const INTERSECTION_PLANE_LAYER = 1
|
||||
export const SKETCH_LAYER = 2
|
||||
|
||||
// redundant types so that it can be changed temporarily but CI will catch the wrong type
|
||||
export const DEBUG_SHOW_INTERSECTION_PLANE = false
|
||||
export const DEBUG_SHOW_BOTH_SCENES = false
|
||||
|
||||
export const RAYCASTABLE_PLANE = 'raycastable-plane'
|
||||
|
||||
export const X_AXIS = 'xAxis'
|
||||
export const Y_AXIS = 'yAxis'
|
||||
/** If a segment angle is less than this many degrees off a meanginful angle it'll snap to it */
|
||||
export const ANGLE_SNAP_THRESHOLD_DEGREES = 3
|
||||
/** the THREEjs representation of the group surrounding a "snapped" point that is not yet placed */
|
||||
export const DRAFT_POINT_GROUP = 'draft-point-group'
|
||||
/** the THREEjs representation of a "snapped" point that is not yet placed */
|
||||
export const DRAFT_POINT = 'draft-point'
|
||||
export const AXIS_GROUP = 'axisGroup'
|
||||
export const SKETCH_GROUP_SEGMENTS = 'sketch-group-segments'
|
||||
export const ARROWHEAD = 'arrowhead'
|
||||
export const SEGMENT_LENGTH_LABEL = 'segment-length-label'
|
||||
export const SEGMENT_LENGTH_LABEL_TEXT = 'segment-length-label-text'
|
||||
export const SEGMENT_LENGTH_LABEL_OFFSET_PX = 30
|
||||
export const CIRCLE_3_POINT_DRAFT_POINT = 'circle-3-point-draft-point'
|
||||
export const CIRCLE_3_POINT_DRAFT_CIRCLE = 'circle-3-point-draft-circle'
|
||||
|
||||
export interface OnMouseEnterLeaveArgs {
|
||||
selected: Object3D<Object3DEventMap>
|
||||
dragSelected?: Object3D<Object3DEventMap>
|
||||
@ -689,24 +667,6 @@ export class SceneInfra {
|
||||
}
|
||||
}
|
||||
|
||||
export function getSceneScale(
|
||||
camera: PerspectiveCamera | OrthographicCamera,
|
||||
target: Vector3
|
||||
): number {
|
||||
const distance =
|
||||
camera instanceof PerspectiveCamera
|
||||
? camera.position.distanceTo(target)
|
||||
: 63.7942123 / camera.zoom
|
||||
|
||||
if (distance <= 20) return 0.1
|
||||
else if (distance > 20 && distance <= 200) return 1
|
||||
else if (distance > 200 && distance <= 2000) return 10
|
||||
else if (distance > 2000 && distance <= 20000) return 100
|
||||
else if (distance > 20000) return 1000
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
function baseUnitTomm(baseUnit: BaseUnit) {
|
||||
switch (baseUnit) {
|
||||
case 'mm':
|
||||
|
@ -0,0 +1,52 @@
|
||||
// 63.5 is definitely a bit of a magic number, play with it until it looked right
|
||||
// if it were 64, that would feel like it's something in the engine where a random
|
||||
|
||||
import type { OrthographicCamera, Vector3 } from 'three'
|
||||
import { PerspectiveCamera } from 'three'
|
||||
|
||||
// power of 2 is used, but it's the 0.5 seems to make things look much more correct
|
||||
export const ZOOM_MAGIC_NUMBER = 63.5
|
||||
|
||||
export const INTERSECTION_PLANE_LAYER = 1
|
||||
export const SKETCH_LAYER = 2
|
||||
|
||||
// redundant types so that it can be changed temporarily but CI will catch the wrong type
|
||||
export const DEBUG_SHOW_INTERSECTION_PLANE = false
|
||||
export const DEBUG_SHOW_BOTH_SCENES = false
|
||||
|
||||
export const RAYCASTABLE_PLANE = 'raycastable-plane'
|
||||
|
||||
export const X_AXIS = 'xAxis'
|
||||
export const Y_AXIS = 'yAxis'
|
||||
/** If a segment angle is less than this many degrees off a meanginful angle it'll snap to it */
|
||||
export const ANGLE_SNAP_THRESHOLD_DEGREES = 3
|
||||
/** the THREEjs representation of the group surrounding a "snapped" point that is not yet placed */
|
||||
export const DRAFT_POINT_GROUP = 'draft-point-group'
|
||||
/** the THREEjs representation of a "snapped" point that is not yet placed */
|
||||
export const DRAFT_POINT = 'draft-point'
|
||||
export const AXIS_GROUP = 'axisGroup'
|
||||
export const SKETCH_GROUP_SEGMENTS = 'sketch-group-segments'
|
||||
export const ARROWHEAD = 'arrowhead'
|
||||
export const SEGMENT_LENGTH_LABEL = 'segment-length-label'
|
||||
export const SEGMENT_LENGTH_LABEL_TEXT = 'segment-length-label-text'
|
||||
export const SEGMENT_LENGTH_LABEL_OFFSET_PX = 30
|
||||
export const CIRCLE_3_POINT_DRAFT_POINT = 'circle-3-point-draft-point'
|
||||
export const CIRCLE_3_POINT_DRAFT_CIRCLE = 'circle-3-point-draft-circle'
|
||||
|
||||
export function getSceneScale(
|
||||
camera: PerspectiveCamera | OrthographicCamera,
|
||||
target: Vector3
|
||||
): number {
|
||||
const distance =
|
||||
camera instanceof PerspectiveCamera
|
||||
? camera.position.distanceTo(target)
|
||||
: 63.7942123 / camera.zoom
|
||||
|
||||
if (distance <= 20) return 0.1
|
||||
else if (distance > 20 && distance <= 200) return 1
|
||||
else if (distance > 200 && distance <= 2000) return 10
|
||||
else if (distance > 2000 && distance <= 20000) return 100
|
||||
else if (distance > 20000) return 1000
|
||||
|
||||
return 1
|
||||
}
|
||||
|
@ -71,7 +71,7 @@ import {
|
||||
SEGMENT_LENGTH_LABEL,
|
||||
SEGMENT_LENGTH_LABEL_OFFSET_PX,
|
||||
SEGMENT_LENGTH_LABEL_TEXT,
|
||||
} from '@src/clientSideScene/sceneInfra'
|
||||
} from '@src/clientSideScene/sceneUtils'
|
||||
import { angleLengthInfo } from '@src/components/Toolbar/angleLengthInfo'
|
||||
import type { Coords2d } from '@src/lang/std/sketch'
|
||||
import type { SegmentInputs } from '@src/lang/std/stdTypes'
|
||||
|
@ -13,7 +13,7 @@ import type { CoreDumpManager } from '@src/lib/coredump'
|
||||
import openWindow, { openExternalBrowserIfDesktop } from '@src/lib/openWindow'
|
||||
import { PATHS } from '@src/lib/paths'
|
||||
import { reportRejection } from '@src/lib/trap'
|
||||
import { APP_VERSION, getReleaseUrl } from '@src/routes/Settings'
|
||||
import { APP_VERSION, getReleaseUrl } from '@src/routes/utils'
|
||||
|
||||
export function LowerRightControls({
|
||||
children,
|
||||
|
@ -445,10 +445,15 @@ export const ModelingMachineProvider = ({
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// If there are engine commands that need sent off, send them
|
||||
// TODO: This should be handled outside of an action as its own
|
||||
// actor, so that the system state is more controlled.
|
||||
engineEvents &&
|
||||
engineEvents.forEach((event) => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
engineCommandManager.sendSceneCommand(event)
|
||||
engineCommandManager
|
||||
.sendSceneCommand(event)
|
||||
.catch(reportRejection)
|
||||
})
|
||||
updateSceneObjectColors()
|
||||
|
||||
@ -1566,9 +1571,7 @@ export const ModelingMachineProvider = ({
|
||||
data
|
||||
)
|
||||
if (err(result)) return reject(result)
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
codeManager.updateEditorWithAstAndWriteToFile(kclManager.ast)
|
||||
await codeManager.updateEditorWithAstAndWriteToFile(kclManager.ast)
|
||||
|
||||
return result
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ import {
|
||||
import { reportRejection } from '@src/lib/trap'
|
||||
import { toSync } from '@src/lib/utils'
|
||||
import { settingsActor, useSettings } from '@src/machines/appMachine'
|
||||
import { APP_VERSION, IS_NIGHTLY, getReleaseUrl } from '@src/routes/Settings'
|
||||
import { APP_VERSION, IS_NIGHTLY, getReleaseUrl } from '@src/routes/utils'
|
||||
|
||||
interface AllSettingsFieldsProps {
|
||||
searchParamTab: SettingsLevel
|
||||
@ -96,8 +96,7 @@ export const AllSettingsFields = forwardRef(
|
||||
}
|
||||
}
|
||||
}
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
navigateToOnboardingStart()
|
||||
navigateToOnboardingStart().catch(reportRejection)
|
||||
}, [
|
||||
isFileSettings,
|
||||
navigate,
|
||||
|
@ -30,7 +30,7 @@ import { isDesktop } from '@src/lib/isDesktop'
|
||||
import { openExternalBrowserIfDesktop } from '@src/lib/openWindow'
|
||||
import { PATHS } from '@src/lib/paths'
|
||||
import { codeManager, kclManager } from '@src/lib/singletons'
|
||||
import { sendTelemetry } from '@src/lib/textToCad'
|
||||
import { sendTelemetry } from '@src/lib/textToCadTelemetry'
|
||||
import type { Themes } from '@src/lib/theme'
|
||||
import { reportRejection } from '@src/lib/trap'
|
||||
import { commandBarActor } from '@src/machines/commandBarMachine'
|
||||
|
@ -5,7 +5,7 @@ import toast from 'react-hot-toast'
|
||||
import { ActionButton } from '@src/components/ActionButton'
|
||||
import { SafeRenderer } from '@src/lib/markdown'
|
||||
import { openExternalBrowserIfDesktop } from '@src/lib/openWindow'
|
||||
import { getReleaseUrl } from '@src/routes/Settings'
|
||||
import { getReleaseUrl } from '@src/routes/utils'
|
||||
|
||||
export function ToastUpdate({
|
||||
version,
|
||||
|
@ -11,10 +11,11 @@ import {
|
||||
addLineHighlight,
|
||||
addLineHighlightEvent,
|
||||
} from '@src/editor/highlightextension'
|
||||
import type { KclManager } from '@src/lang/KclSingleton'
|
||||
import type { EngineCommandManager } from '@src/lang/std/engineConnection'
|
||||
import { markOnce } from '@src/lib/performance'
|
||||
import type { Selection, Selections } from '@src/lib/selections'
|
||||
import { processCodeMirrorRanges } from '@src/lib/selections'
|
||||
import { engineCommandManager, kclManager } from '@src/lib/singletons'
|
||||
import { kclEditorActor } from '@src/machines/kclEditorMachine'
|
||||
import type {
|
||||
ModelingMachineEvent,
|
||||
@ -44,6 +45,8 @@ export const setDiagnosticsEvent = setDiagnosticsAnnotation.of(true)
|
||||
|
||||
export default class EditorManager {
|
||||
private _copilotEnabled: boolean = true
|
||||
private engineCommandManager: EngineCommandManager
|
||||
private kclManager: KclManager
|
||||
|
||||
private _isAllTextSelected: boolean = false
|
||||
private _isShiftDown: boolean = false
|
||||
@ -64,6 +67,14 @@ export default class EditorManager {
|
||||
|
||||
public _editorView: EditorView | null = null
|
||||
|
||||
constructor(
|
||||
engineCommandManager: EngineCommandManager,
|
||||
kclManager: KclManager
|
||||
) {
|
||||
this.engineCommandManager = engineCommandManager
|
||||
this.kclManager = kclManager
|
||||
}
|
||||
|
||||
setCopilotEnabled(enabled: boolean) {
|
||||
this._copilotEnabled = enabled
|
||||
}
|
||||
@ -379,8 +390,8 @@ export default class EditorManager {
|
||||
codeMirrorRanges: viewUpdate.state.selection.ranges,
|
||||
selectionRanges: this._selectionRanges,
|
||||
isShiftDown: this._isShiftDown,
|
||||
ast: kclManager.ast,
|
||||
artifactGraph: kclManager.artifactGraph,
|
||||
ast: this.kclManager.ast,
|
||||
artifactGraph: this.kclManager.artifactGraph,
|
||||
})
|
||||
|
||||
if (!eventInfo) {
|
||||
@ -407,7 +418,7 @@ export default class EditorManager {
|
||||
this._modelingSend(eventInfo.modelingEvent)
|
||||
eventInfo.engineEvents.forEach((event) => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
engineCommandManager.sendSceneCommand(event)
|
||||
this.engineCommandManager.sendSceneCommand(event)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -102,11 +102,14 @@ onmessage = function (event: MessageEvent) {
|
||||
intoServer.enqueue(data)
|
||||
const json: jsrpc.JSONRPCRequest = Codec.decode(data)
|
||||
if (null != json.id) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises, @typescript-eslint/no-non-null-assertion
|
||||
fromServer.responses.get(json.id)!.then((response) => {
|
||||
const encoded = Codec.encode(response as jsrpc.JSONRPCResponse)
|
||||
postMessage(encoded)
|
||||
})
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
fromServer.responses
|
||||
.get(json.id)!
|
||||
.then((response) => {
|
||||
const encoded = Codec.encode(response as jsrpc.JSONRPCResponse)
|
||||
postMessage(encoded)
|
||||
})
|
||||
.catch(reportRejection)
|
||||
}
|
||||
break
|
||||
default:
|
||||
|
@ -28,7 +28,7 @@ import type { Selections } from '@src/lib/selections'
|
||||
import { codeManager, kclManager } from '@src/lib/singletons'
|
||||
import { err } from '@src/lib/trap'
|
||||
import type { SketchTool, modelingMachine } from '@src/machines/modelingMachine'
|
||||
import { IS_NIGHTLY_OR_DEBUG } from '@src/routes/Settings'
|
||||
import { IS_NIGHTLY_OR_DEBUG } from '@src/routes/utils'
|
||||
|
||||
type OutputFormat = Models['OutputFormat3d_type']
|
||||
type OutputTypeKey = OutputFormat['type']
|
||||
|
@ -12,7 +12,7 @@ import type {
|
||||
import { isDesktop } from '@src/lib/isDesktop'
|
||||
import type RustContext from '@src/lib/rustContext'
|
||||
import screenshot from '@src/lib/screenshot'
|
||||
import { APP_VERSION } from '@src/routes/Settings'
|
||||
import { APP_VERSION } from '@src/routes/utils'
|
||||
|
||||
/* eslint-disable suggest-no-throw/suggest-no-throw --
|
||||
* All the throws in CoreDumpManager are intentional and should be caught and handled properly
|
||||
|
@ -16,7 +16,7 @@ import type {
|
||||
StateMachineCommandSetSchema,
|
||||
} from '@src/lib/commandTypes'
|
||||
import { isDesktop } from '@src/lib/isDesktop'
|
||||
import { IS_NIGHTLY_OR_DEBUG } from '@src/routes/Settings'
|
||||
import { IS_NIGHTLY_OR_DEBUG } from '@src/routes/utils'
|
||||
|
||||
interface CreateMachineCommandProps<
|
||||
T extends AnyStateMachine,
|
||||
|
@ -20,7 +20,7 @@ import {
|
||||
import type ModelingAppFile from '@src/lib/modelingAppFile'
|
||||
import type { DefaultPlaneStr } from '@src/lib/planes'
|
||||
import { defaultPlaneStrToKey } from '@src/lib/planes'
|
||||
import { err } from '@src/lib/trap'
|
||||
import { err, reportRejection } from '@src/lib/trap'
|
||||
import type { DeepPartial } from '@src/lib/types'
|
||||
import type { ModuleType } from '@src/lib/wasm_lib_wrapper'
|
||||
import { getModule } from '@src/lib/wasm_lib_wrapper'
|
||||
@ -48,10 +48,11 @@ export default class RustContext {
|
||||
constructor(engineCommandManager: EngineCommandManager) {
|
||||
this.engineCommandManager = engineCommandManager
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
this.ensureWasmInit().then(async () => {
|
||||
this.ctxInstance = await this.create()
|
||||
})
|
||||
this.ensureWasmInit()
|
||||
.then(async () => {
|
||||
this.ctxInstance = await this.create()
|
||||
})
|
||||
.catch(reportRejection)
|
||||
}
|
||||
|
||||
// Create a new context instance
|
||||
|
@ -10,7 +10,7 @@ import {
|
||||
SEGMENT_BODIES_PLUS_PROFILE_START,
|
||||
getParentGroup,
|
||||
} from '@src/clientSideScene/sceneConstants'
|
||||
import { AXIS_GROUP, X_AXIS } from '@src/clientSideScene/sceneInfra'
|
||||
import { AXIS_GROUP, X_AXIS } from '@src/clientSideScene/sceneUtils'
|
||||
import { getNodeFromPath, isSingleCursorInPipe } from '@src/lang/queryAst'
|
||||
import { getNodePathFromSourceRange } from '@src/lang/queryAstNodePathUtils'
|
||||
import type { Artifact, ArtifactId, CodeRef } from '@src/lang/std/artifactGraph'
|
||||
|
@ -34,7 +34,7 @@ kclManager.sceneInfraBaseUnitMultiplierSetter = (unit: BaseUnit) => {
|
||||
}
|
||||
|
||||
// This needs to be after sceneInfra and engineCommandManager are is created.
|
||||
export const editorManager = new EditorManager()
|
||||
export const editorManager = new EditorManager(engineCommandManager, kclManager)
|
||||
|
||||
export const rustContext = new RustContext(engineCommandManager)
|
||||
|
||||
|
@ -251,19 +251,3 @@ export async function submitAndAwaitTextToKcl({
|
||||
)
|
||||
return textToCadOutputCreated
|
||||
}
|
||||
|
||||
export async function sendTelemetry(
|
||||
id: string,
|
||||
feedback: Models['MlFeedback_type'],
|
||||
token?: string
|
||||
): Promise<void> {
|
||||
const url =
|
||||
VITE_KC_API_BASE_URL + '/user/text-to-cad/' + id + '?feedback=' + feedback
|
||||
await crossPlatformFetch(
|
||||
url,
|
||||
{
|
||||
method: 'POST',
|
||||
},
|
||||
token
|
||||
)
|
||||
}
|
||||
|
19
src/lib/textToCadTelemetry.ts
Normal file
@ -0,0 +1,19 @@
|
||||
import type { Models } from '@kittycad/lib/dist/types/src'
|
||||
import { VITE_KC_API_BASE_URL } from '@src/env'
|
||||
import crossPlatformFetch from '@src/lib/crossPlatformFetch'
|
||||
|
||||
export async function sendTelemetry(
|
||||
id: string,
|
||||
feedback: Models['MlFeedback_type'],
|
||||
token?: string
|
||||
): Promise<void> {
|
||||
const url =
|
||||
VITE_KC_API_BASE_URL + '/user/text-to-cad/' + id + '?feedback=' + feedback
|
||||
await crossPlatformFetch(
|
||||
url,
|
||||
{
|
||||
method: 'POST',
|
||||
},
|
||||
token
|
||||
)
|
||||
}
|
@ -9,7 +9,7 @@ import {
|
||||
isEditingExistingSketch,
|
||||
pipeHasCircle,
|
||||
} from '@src/machines/modelingMachine'
|
||||
import { IS_NIGHTLY_OR_DEBUG } from '@src/routes/Settings'
|
||||
import { IS_NIGHTLY_OR_DEBUG } from '@src/routes/utils'
|
||||
|
||||
export type ToolbarModeName = 'modeling' | 'sketching'
|
||||
|
||||
|
@ -238,8 +238,9 @@ async function getAndSyncStoredToken(input: {
|
||||
if (token) {
|
||||
// has just logged in, update storage
|
||||
localStorage.setItem(TOKEN_PERSIST_KEY, token)
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
isDesktop() && writeTokenFile(token)
|
||||
if (isDesktop()) {
|
||||
await writeTokenFile(token)
|
||||
}
|
||||
return token
|
||||
}
|
||||
if (!isDesktop()) return ''
|
||||
|
@ -4,13 +4,13 @@ import { assign, fromPromise, setup } from 'xstate'
|
||||
|
||||
import type { Node } from '@rust/kcl-lib/bindings/Node'
|
||||
|
||||
import { deleteSegment } from '@src/clientSideScene/ClientSideSceneComp'
|
||||
import { deleteSegment } from '@src/clientSideScene/deleteSegment'
|
||||
import {
|
||||
orthoScale,
|
||||
quaternionFromUpNForward,
|
||||
} from '@src/clientSideScene/helpers'
|
||||
import { DRAFT_DASHED_LINE } from '@src/clientSideScene/sceneConstants'
|
||||
import { DRAFT_POINT } from '@src/clientSideScene/sceneInfra'
|
||||
import { DRAFT_POINT } from '@src/clientSideScene/sceneUtils'
|
||||
import { createProfileStartHandle } from '@src/clientSideScene/segments'
|
||||
import type { MachineManager } from '@src/components/MachineManagerProvider'
|
||||
import type { ModelingMachineContext } from '@src/components/ModelingMachineProvider'
|
||||
|
@ -1,11 +1,8 @@
|
||||
import { Dialog, Transition } from '@headlessui/react'
|
||||
import { NODE_ENV } from '@src/env'
|
||||
import { Fragment, useEffect, useRef } from 'react'
|
||||
import { useHotkeys } from 'react-hotkeys-hook'
|
||||
import { useLocation, useNavigate, useSearchParams } from 'react-router-dom'
|
||||
|
||||
import { IS_PLAYWRIGHT_KEY } from '@e2e/playwright/storageStates'
|
||||
|
||||
import { CustomIcon } from '@src/components/CustomIcon'
|
||||
import { AllKeybindingsFields } from '@src/components/Settings/AllKeybindingsFields'
|
||||
import { AllSettingsFields } from '@src/components/Settings/AllSettingsFields'
|
||||
@ -14,35 +11,9 @@ import { SettingsSearchBar } from '@src/components/Settings/SettingsSearchBar'
|
||||
import { SettingsSectionsList } from '@src/components/Settings/SettingsSectionsList'
|
||||
import { SettingsTabs } from '@src/components/Settings/SettingsTabs'
|
||||
import { useDotDotSlash } from '@src/hooks/useDotDotSlash'
|
||||
import { isDesktop } from '@src/lib/isDesktop'
|
||||
import { PATHS } from '@src/lib/paths'
|
||||
import type { SettingsLevel } from '@src/lib/settings/settingsTypes'
|
||||
|
||||
const isTestEnv = window?.localStorage.getItem(IS_PLAYWRIGHT_KEY) === 'true'
|
||||
|
||||
export const APP_VERSION =
|
||||
isTestEnv && NODE_ENV === 'development'
|
||||
? '11.22.33'
|
||||
: isDesktop()
|
||||
? // @ts-ignore
|
||||
window.electron.packageJson.version
|
||||
: 'main'
|
||||
|
||||
export const PACKAGE_NAME = isDesktop()
|
||||
? window.electron.packageJson.name
|
||||
: 'zoo-modeling-app'
|
||||
|
||||
export const IS_NIGHTLY = PACKAGE_NAME.indexOf('-nightly') > -1
|
||||
|
||||
export const IS_NIGHTLY_OR_DEBUG =
|
||||
IS_NIGHTLY || APP_VERSION === '0.0.0' || APP_VERSION === '11.22.33'
|
||||
|
||||
export function getReleaseUrl(version: string = APP_VERSION) {
|
||||
return `https://github.com/KittyCAD/modeling-app/releases/tag/${
|
||||
IS_NIGHTLY ? 'nightly-' : ''
|
||||
}v${version}`
|
||||
}
|
||||
|
||||
export const Settings = () => {
|
||||
const navigate = useNavigate()
|
||||
const [searchParams, setSearchParams] = useSearchParams()
|
||||
|
@ -15,7 +15,7 @@ import { Themes, getSystemTheme } from '@src/lib/theme'
|
||||
import { reportRejection } from '@src/lib/trap'
|
||||
import { toSync } from '@src/lib/utils'
|
||||
import { authActor, useSettings } from '@src/machines/appMachine'
|
||||
import { APP_VERSION } from '@src/routes/Settings'
|
||||
import { APP_VERSION } from '@src/routes/utils'
|
||||
|
||||
const subtleBorder =
|
||||
'border border-solid border-chalkboard-30 dark:border-chalkboard-80'
|
||||
|
29
src/routes/utils.ts
Normal file
@ -0,0 +1,29 @@
|
||||
import { NODE_ENV } from '@src/env'
|
||||
import { isDesktop } from '@src/lib/isDesktop'
|
||||
|
||||
import { IS_PLAYWRIGHT_KEY } from '@e2e/playwright/storageStates'
|
||||
|
||||
const isTestEnv = window?.localStorage.getItem(IS_PLAYWRIGHT_KEY) === 'true'
|
||||
|
||||
export const APP_VERSION =
|
||||
isTestEnv && NODE_ENV === 'development'
|
||||
? '11.22.33'
|
||||
: isDesktop()
|
||||
? // @ts-ignore
|
||||
window.electron.packageJson.version
|
||||
: 'main'
|
||||
|
||||
export const PACKAGE_NAME = isDesktop()
|
||||
? window.electron.packageJson.name
|
||||
: 'zoo-modeling-app'
|
||||
|
||||
export const IS_NIGHTLY = PACKAGE_NAME.indexOf('-nightly') > -1
|
||||
|
||||
export const IS_NIGHTLY_OR_DEBUG =
|
||||
IS_NIGHTLY || APP_VERSION === '0.0.0' || APP_VERSION === '11.22.33'
|
||||
|
||||
export function getReleaseUrl(version: string = APP_VERSION) {
|
||||
return `https://github.com/KittyCAD/modeling-app/releases/tag/${
|
||||
IS_NIGHTLY ? 'nightly-' : ''
|
||||
}v${version}`
|
||||
}
|
@ -9446,10 +9446,10 @@ vite-tsconfig-paths@^4.3.2:
|
||||
globrex "^0.1.2"
|
||||
tsconfck "^3.0.3"
|
||||
|
||||
vite@^5.0.0, vite@^5.4.12:
|
||||
version "5.4.12"
|
||||
resolved "https://registry.yarnpkg.com/vite/-/vite-5.4.12.tgz#627d12ff06de3942557dfe8632fd712a12a072c7"
|
||||
integrity sha512-KwUaKB27TvWwDJr1GjjWthLMATbGEbeWYZIbGZ5qFIsgPP3vWzLu4cVooqhm5/Z2SPDUMjyPVjTztm5tYKwQxA==
|
||||
vite@^5.0.0, vite@^5.4.16:
|
||||
version "5.4.16"
|
||||
resolved "https://registry.yarnpkg.com/vite/-/vite-5.4.16.tgz#471983257a890ef33f2700cbbbc2134f2d08abf1"
|
||||
integrity sha512-Y5gnfp4NemVfgOTDQAunSD4346fal44L9mszGGY/e+qxsRT5y1sMlS/8tiQ8AFAp+MFgYNSINdfEchJiPm41vQ==
|
||||
dependencies:
|
||||
esbuild "^0.21.3"
|
||||
postcss "^8.4.43"
|
||||
|