Compare commits
33 Commits
Author | SHA1 | Date | |
---|---|---|---|
777b225066 | |||
ae6373e4f5 | |||
87979b17cf | |||
4be63e7331 | |||
56d930c4f2 | |||
d48eb0c66c | |||
a69d7d03d0 | |||
00a8273173 | |||
51868f892b | |||
8e9286a747 | |||
023ed1a687 | |||
5b7d707b26 | |||
5b95194aa7 | |||
6080a99e73 | |||
5106c49e21 | |||
25f18845c7 | |||
0a7f1a41fc | |||
1625b58577 | |||
ab6115c4e2 | |||
fe621240c3 | |||
97faf5ae2b | |||
e3b9a6e5d8 | |||
e94b1bc12a | |||
c0eff5bc14 | |||
b0f92c2f6d | |||
718873b3bb | |||
9f815eecc1 | |||
0384e5e6c6 | |||
48ef0885b7 | |||
3b2731f924 | |||
bf4e04f9f1 | |||
24475bbcdf | |||
bcca736a8d |
4
.github/workflows/playwright.yml
vendored
@ -115,7 +115,7 @@ jobs:
|
||||
git fetch origin
|
||||
echo ${{ github.head_ref }}
|
||||
git checkout ${{ github.head_ref }}
|
||||
# TODO when safari works on ubuntu remove the os part of the commit message
|
||||
# TODO when webkit works on ubuntu remove the os part of the commit message
|
||||
git commit -am "A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)" || true
|
||||
git push
|
||||
git push origin ${{ github.head_ref }}
|
||||
@ -181,7 +181,7 @@ jobs:
|
||||
- name: build web
|
||||
run: yarn build:local
|
||||
- name: Run macos/safari flow
|
||||
# safari doesn't work on Ubuntu because of the same reason tauri doesn't (webRTC issues)
|
||||
# webkit doesn't work on Ubuntu because of the same reason tauri doesn't (webRTC issues)
|
||||
# TODO remove this and the matrix and run all tests on ubuntu when this is fixed
|
||||
run: yarn playwright test --project="webkit" e2e/playwright/flow-tests.spec.ts
|
||||
env:
|
||||
|
@ -21,7 +21,7 @@ abs(num: number) -> number
|
||||
```js
|
||||
const myAngle = -120
|
||||
|
||||
const sketch001 = startSketchOn('-XZ')
|
||||
const sketch001 = startSketchOn('XZ')
|
||||
|> startProfileAt([0, 0], %)
|
||||
|> line([8, 0], %)
|
||||
|> angledLine({ angle: abs(myAngle), length: 5 }, %)
|
||||
|
@ -15,7 +15,7 @@ angleToMatchLengthX(segment_name: string, to: number, sketch_group: SketchGroup)
|
||||
### Examples
|
||||
|
||||
```js
|
||||
const sketch001 = startSketchOn('-XZ')
|
||||
const sketch001 = startSketchOn('XZ')
|
||||
|> startProfileAt([0, 0], %)
|
||||
|> line([2, 5], %, 'seg01')
|
||||
|> angledLineToX([
|
||||
|
@ -15,7 +15,7 @@ angleToMatchLengthY(segment_name: string, to: number, sketch_group: SketchGroup)
|
||||
### Examples
|
||||
|
||||
```js
|
||||
const sketch001 = startSketchOn('-XZ')
|
||||
const sketch001 = startSketchOn('XZ')
|
||||
|> startProfileAt([0, 0], %)
|
||||
|> line([1, 2], %, 'seg01')
|
||||
|> angledLine({
|
||||
|
@ -15,7 +15,7 @@ angledLine(data: AngledLineData, sketch_group: SketchGroup, tag?: String) -> Ske
|
||||
### Examples
|
||||
|
||||
```js
|
||||
const exampleSketch = startSketchOn('-XZ')
|
||||
const exampleSketch = startSketchOn('XZ')
|
||||
|> startProfileAt([0, 0], %)
|
||||
|> yLineTo(15, %)
|
||||
|> angledLine({ angle: 30, length: 15 }, %)
|
||||
|
@ -15,7 +15,7 @@ angledLineThatIntersects(data: AngledLineThatIntersectsData, sketch_group: Sketc
|
||||
### Examples
|
||||
|
||||
```js
|
||||
const exampleSketch = startSketchOn('-XZ')
|
||||
const exampleSketch = startSketchOn('XZ')
|
||||
|> startProfileAt([0, 0], %)
|
||||
|> lineTo([5, 10], %)
|
||||
|> lineTo([-10, 10], %, "lineToIntersect")
|
||||
|
@ -15,7 +15,7 @@ angledLineToX(data: AngledLineToData, sketch_group: SketchGroup, tag?: String) -
|
||||
### Examples
|
||||
|
||||
```js
|
||||
const exampleSketch = startSketchOn('-XZ')
|
||||
const exampleSketch = startSketchOn('XZ')
|
||||
|> startProfileAt([0, 0], %)
|
||||
|> angledLineToX({ angle: 30, to: 10 }, %)
|
||||
|> line([0, 10], %)
|
||||
|
@ -15,7 +15,7 @@ angledLineToY(data: AngledLineToData, sketch_group: SketchGroup, tag?: String) -
|
||||
### Examples
|
||||
|
||||
```js
|
||||
const exampleSketch = startSketchOn('-XZ')
|
||||
const exampleSketch = startSketchOn('XZ')
|
||||
|> startProfileAt([0, 0], %)
|
||||
|> angledLineToY({ angle: 60, to: 20 }, %)
|
||||
|> line([-20, 0], %)
|
||||
|
@ -15,7 +15,7 @@ arc(data: ArcData, sketch_group: SketchGroup, tag?: String) -> SketchGroup
|
||||
### Examples
|
||||
|
||||
```js
|
||||
const exampleSketch = startSketchOn('-XZ')
|
||||
const exampleSketch = startSketchOn('XZ')
|
||||
|> startProfileAt([0, 0], %)
|
||||
|> line([10, 0], %)
|
||||
|> arc({
|
||||
|
@ -15,7 +15,7 @@ bezierCurve(data: BezierData, sketch_group: SketchGroup, tag?: String) -> Sketch
|
||||
### Examples
|
||||
|
||||
```js
|
||||
const exampleSketch = startSketchOn('-XZ')
|
||||
const exampleSketch = startSketchOn('XZ')
|
||||
|> startProfileAt([0, 0], %)
|
||||
|> line([0, 10], %)
|
||||
|> bezierCurve({
|
||||
|
@ -15,7 +15,7 @@ lastSegX(sketch_group: SketchGroup) -> number
|
||||
### Examples
|
||||
|
||||
```js
|
||||
const exampleSketch = startSketchOn("-XZ")
|
||||
const exampleSketch = startSketchOn("XZ")
|
||||
|> startProfileAt([0, 0], %)
|
||||
|> line([5, 0], %)
|
||||
|> line([20, 5], %)
|
||||
|
@ -15,7 +15,7 @@ lastSegY(sketch_group: SketchGroup) -> number
|
||||
### Examples
|
||||
|
||||
```js
|
||||
const exampleSketch = startSketchOn("-XZ")
|
||||
const exampleSketch = startSketchOn("XZ")
|
||||
|> startProfileAt([0, 0], %)
|
||||
|> line([5, 0], %)
|
||||
|> line([20, 5], %)
|
||||
|
@ -15,7 +15,7 @@ lineTo(to: [number], sketch_group: SketchGroup, tag?: String) -> SketchGroup
|
||||
### Examples
|
||||
|
||||
```js
|
||||
const exampleSketch = startSketchOn("-XZ")
|
||||
const exampleSketch = startSketchOn("XZ")
|
||||
|> startProfileAt([0, 0], %)
|
||||
|> lineTo([10, 0], %)
|
||||
|> lineTo([0, 10], %)
|
||||
|
@ -15,7 +15,7 @@ patternCircular2d(data: CircularPattern2dData, sketch_group: SketchGroup) -> [Sk
|
||||
### Examples
|
||||
|
||||
```js
|
||||
const exampleSketch = startSketchOn('-XZ')
|
||||
const exampleSketch = startSketchOn('XZ')
|
||||
|> startProfileAt([.5, 25], %)
|
||||
|> line([0, 5], %)
|
||||
|> line([-1, 0], %)
|
||||
|
@ -15,7 +15,7 @@ patternCircular3d(data: CircularPattern3dData, extrude_group: ExtrudeGroup) -> [
|
||||
### Examples
|
||||
|
||||
```js
|
||||
const exampleSketch = startSketchOn('-XZ')
|
||||
const exampleSketch = startSketchOn('XZ')
|
||||
|> circle([0, 0], 1, %)
|
||||
|
||||
const example = extrude(-5, exampleSketch)
|
||||
|
@ -15,7 +15,7 @@ patternLinear2d(data: LinearPattern2dData, sketch_group_set: SketchGroupSet) ->
|
||||
### Examples
|
||||
|
||||
```js
|
||||
const exampleSketch = startSketchOn('-XZ')
|
||||
const exampleSketch = startSketchOn('XZ')
|
||||
|> circle([0, 0], 1, %)
|
||||
|> patternLinear2d({
|
||||
axis: [1, 0],
|
||||
|
@ -15,7 +15,7 @@ patternLinear3d(data: LinearPattern3dData, extrude_group: ExtrudeGroup) -> [Extr
|
||||
### Examples
|
||||
|
||||
```js
|
||||
const exampleSketch = startSketchOn('-XZ')
|
||||
const exampleSketch = startSketchOn('XZ')
|
||||
|> startProfileAt([0, 0], %)
|
||||
|> line([0, 2], %)
|
||||
|> line([3, 1], %)
|
||||
|
@ -15,7 +15,7 @@ segAng(segment_name: string, sketch_group: SketchGroup) -> number
|
||||
### Examples
|
||||
|
||||
```js
|
||||
const exampleSketch = startSketchOn('-XZ')
|
||||
const exampleSketch = startSketchOn('XZ')
|
||||
|> startProfileAt([0, 0], %)
|
||||
|> line([10, 0], %)
|
||||
|> line([5, 10], %, 'seg01')
|
||||
|
@ -15,7 +15,7 @@ segEndX(segment_name: string, sketch_group: SketchGroup) -> number
|
||||
### Examples
|
||||
|
||||
```js
|
||||
const exampleSketch = startSketchOn('-XZ')
|
||||
const exampleSketch = startSketchOn('XZ')
|
||||
|> startProfileAt([0, 0], %)
|
||||
|> line([20, 0], %, "thing")
|
||||
|> line([0, 5], %)
|
||||
|
@ -15,7 +15,7 @@ segEndY(segment_name: string, sketch_group: SketchGroup) -> number
|
||||
### Examples
|
||||
|
||||
```js
|
||||
const exampleSketch = startSketchOn('-XZ')
|
||||
const exampleSketch = startSketchOn('XZ')
|
||||
|> startProfileAt([0, 0], %)
|
||||
|> line([20, 0], %)
|
||||
|> line([0, 3], %, "thing")
|
||||
|
@ -15,7 +15,7 @@ segLen(segment_name: string, sketch_group: SketchGroup) -> number
|
||||
### Examples
|
||||
|
||||
```js
|
||||
const exampleSketch = startSketchOn("-XZ")
|
||||
const exampleSketch = startSketchOn("XZ")
|
||||
|> startProfileAt([0, 0], %)
|
||||
|> angledLine({ angle: 60, length: 10 }, %, "thing")
|
||||
|> tangentialArc({ offset: -120, radius: 5 }, %)
|
||||
|
@ -29,7 +29,7 @@
|
||||
"unpublished": false,
|
||||
"deprecated": false,
|
||||
"examples": [
|
||||
"const myAngle = -120\n\nconst sketch001 = startSketchOn('-XZ')\n |> startProfileAt([0, 0], %)\n |> line([8, 0], %)\n |> angledLine({ angle: abs(myAngle), length: 5 }, %)\n |> line([-5, 0], %)\n |> angledLine({ angle: myAngle, length: 5 }, %)\n |> close(%)\n\nconst baseExtrusion = extrude(5, sketch001)"
|
||||
"const myAngle = -120\n\nconst sketch001 = startSketchOn('XZ')\n |> startProfileAt([0, 0], %)\n |> line([8, 0], %)\n |> angledLine({ angle: abs(myAngle), length: 5 }, %)\n |> line([-5, 0], %)\n |> angledLine({ angle: myAngle, length: 5 }, %)\n |> close(%)\n\nconst baseExtrusion = extrude(5, sketch001)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -62,7 +62,7 @@
|
||||
"unpublished": false,
|
||||
"deprecated": false,
|
||||
"examples": [
|
||||
"const myVar = acos(0.5)"
|
||||
"const sketch001 = startSketchOn('XZ')\n |> startProfileAt([0, 0], %)\n |> angledLine({\n angle: toDegrees(acos(0.5)),\n length: 10\n }, %)\n |> line([5, 0], %)\n |> lineTo([12, 0], %)\n |> close(%)\n\nconst extrude001 = extrude(5, sketch001)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -1068,7 +1068,7 @@
|
||||
"unpublished": false,
|
||||
"deprecated": false,
|
||||
"examples": [
|
||||
"const sketch001 = startSketchOn('-XZ')\n |> startProfileAt([0, 0], %)\n |> line([2, 5], %, 'seg01')\n |> angledLineToX([\n -angleToMatchLengthX('seg01', 7, %),\n 10\n ], %)\n |> close(%)\n\nconst extrusion = extrude(5, sketch001)"
|
||||
"const sketch001 = startSketchOn('XZ')\n |> startProfileAt([0, 0], %)\n |> line([2, 5], %, 'seg01')\n |> angledLineToX([\n -angleToMatchLengthX('seg01', 7, %),\n 10\n ], %)\n |> close(%)\n\nconst extrusion = extrude(5, sketch001)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -2074,7 +2074,7 @@
|
||||
"unpublished": false,
|
||||
"deprecated": false,
|
||||
"examples": [
|
||||
"const sketch001 = startSketchOn('-XZ')\n |> startProfileAt([0, 0], %)\n |> line([1, 2], %, 'seg01')\n |> angledLine({\n angle: angleToMatchLengthY('seg01', 15, %),\n length: 5\n }, %)\n |> yLineTo(0, %)\n |> close(%)\n\nconst extrusion = extrude(5, sketch001)"
|
||||
"const sketch001 = startSketchOn('XZ')\n |> startProfileAt([0, 0], %)\n |> line([1, 2], %, 'seg01')\n |> angledLine({\n angle: angleToMatchLengthY('seg01', 15, %),\n length: 5\n }, %)\n |> yLineTo(0, %)\n |> close(%)\n\nconst extrusion = extrude(5, sketch001)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -4070,7 +4070,7 @@
|
||||
"unpublished": false,
|
||||
"deprecated": false,
|
||||
"examples": [
|
||||
"const exampleSketch = startSketchOn('-XZ')\n |> startProfileAt([0, 0], %)\n |> yLineTo(15, %)\n |> angledLine({ angle: 30, length: 15 }, %)\n |> line([8, -10], %)\n |> yLineTo(0, %)\n |> close(%)\n\nconst example = extrude(10, exampleSketch)"
|
||||
"const exampleSketch = startSketchOn('XZ')\n |> startProfileAt([0, 0], %)\n |> yLineTo(15, %)\n |> angledLine({ angle: 30, length: 15 }, %)\n |> line([8, -10], %)\n |> yLineTo(0, %)\n |> close(%)\n\nconst example = extrude(10, exampleSketch)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -10048,7 +10048,7 @@
|
||||
"unpublished": false,
|
||||
"deprecated": false,
|
||||
"examples": [
|
||||
"const exampleSketch = startSketchOn('-XZ')\n |> startProfileAt([0, 0], %)\n |> lineTo([5, 10], %)\n |> lineTo([-10, 10], %, \"lineToIntersect\")\n |> lineTo([0, 20], %)\n |> angledLineThatIntersects({\n angle: 80,\n intersectTag: 'lineToIntersect',\n offset: 10\n }, %)\n |> close(%)\n\nconst example = extrude(10, exampleSketch)"
|
||||
"const exampleSketch = startSketchOn('XZ')\n |> startProfileAt([0, 0], %)\n |> lineTo([5, 10], %)\n |> lineTo([-10, 10], %, \"lineToIntersect\")\n |> lineTo([0, 20], %)\n |> angledLineThatIntersects({\n angle: 80,\n intersectTag: 'lineToIntersect',\n offset: 10\n }, %)\n |> close(%)\n\nconst example = extrude(10, exampleSketch)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -12029,7 +12029,7 @@
|
||||
"unpublished": false,
|
||||
"deprecated": false,
|
||||
"examples": [
|
||||
"const exampleSketch = startSketchOn('-XZ')\n |> startProfileAt([0, 0], %)\n |> angledLineToX({ angle: 30, to: 10 }, %)\n |> line([0, 10], %)\n |> line([-10, 0], %)\n |> close(%)\n\nconst example = extrude(10, exampleSketch)"
|
||||
"const exampleSketch = startSketchOn('XZ')\n |> startProfileAt([0, 0], %)\n |> angledLineToX({ angle: 30, to: 10 }, %)\n |> line([0, 10], %)\n |> line([-10, 0], %)\n |> close(%)\n\nconst example = extrude(10, exampleSketch)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -14010,7 +14010,7 @@
|
||||
"unpublished": false,
|
||||
"deprecated": false,
|
||||
"examples": [
|
||||
"const exampleSketch = startSketchOn('-XZ')\n |> startProfileAt([0, 0], %)\n |> angledLineToY({ angle: 60, to: 20 }, %)\n |> line([-20, 0], %)\n |> angledLineToY({ angle: 70, to: 10 }, %)\n |> close(%)\n\nconst example = extrude(10, exampleSketch)"
|
||||
"const exampleSketch = startSketchOn('XZ')\n |> startProfileAt([0, 0], %)\n |> angledLineToY({ angle: 60, to: 20 }, %)\n |> line([-20, 0], %)\n |> angledLineToY({ angle: 70, to: 10 }, %)\n |> close(%)\n\nconst example = extrude(10, exampleSketch)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -16038,7 +16038,7 @@
|
||||
"unpublished": false,
|
||||
"deprecated": false,
|
||||
"examples": [
|
||||
"const exampleSketch = startSketchOn('-XZ')\n |> startProfileAt([0, 0], %)\n |> line([10, 0], %)\n |> arc({\n angle_start: 0,\n angle_end: 280,\n radius: 16\n }, %)\n |> close(%)"
|
||||
"const exampleSketch = startSketchOn('XZ')\n |> startProfileAt([0, 0], %)\n |> line([10, 0], %)\n |> arc({\n angle_start: 0,\n angle_end: 280,\n radius: 16\n }, %)\n |> close(%)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -16071,7 +16071,7 @@
|
||||
"unpublished": false,
|
||||
"deprecated": false,
|
||||
"examples": [
|
||||
"const myVar = asin(0.5)"
|
||||
"const sketch001 = startSketchOn('XZ')\n |> startProfileAt([0, 0], %)\n |> angledLine({\n angle: toDegrees(asin(0.5)),\n length: 20\n }, %)\n |> yLineTo(0, %)\n |> close(%)\n\nconst extrude001 = extrude(5, sketch001)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -16104,7 +16104,7 @@
|
||||
"unpublished": false,
|
||||
"deprecated": false,
|
||||
"examples": [
|
||||
"const myVar = atan(1.0)"
|
||||
"const sketch001 = startSketchOn('XZ')\n |> startProfileAt([0, 0], %)\n |> angledLine({\n angle: toDegrees(atan(1.25)),\n length: 20\n }, %)\n |> yLineTo(0, %)\n |> close(%)\n\nconst extrude001 = extrude(5, sketch001)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -18106,7 +18106,7 @@
|
||||
"unpublished": false,
|
||||
"deprecated": false,
|
||||
"examples": [
|
||||
"const exampleSketch = startSketchOn('-XZ')\n |> startProfileAt([0, 0], %)\n |> line([0, 10], %)\n |> bezierCurve({\n to: [10, 10],\n control1: [5, 0],\n control2: [5, 10]\n }, %)\n |> lineTo([10, 0], %)\n |> close(%)\n\nconst example = extrude(10, exampleSketch)"
|
||||
"const exampleSketch = startSketchOn('XZ')\n |> startProfileAt([0, 0], %)\n |> line([0, 10], %)\n |> bezierCurve({\n to: [10, 10],\n control1: [5, 0],\n control2: [5, 10]\n }, %)\n |> lineTo([10, 0], %)\n |> close(%)\n\nconst example = extrude(10, exampleSketch)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -18139,7 +18139,7 @@
|
||||
"unpublished": false,
|
||||
"deprecated": false,
|
||||
"examples": [
|
||||
"const myVar = ceil(4.5)"
|
||||
"const sketch001 = startSketchOn('XZ')\n |> startProfileAt([0, 0], %)\n |> lineTo([12, 10], %)\n |> line([ceil(7.02986), 0], %)\n |> yLineTo(0, %)\n |> close(%)\n\nconst extrude001 = extrude(5, sketch001)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -20424,7 +20424,8 @@
|
||||
"unpublished": false,
|
||||
"deprecated": false,
|
||||
"examples": [
|
||||
"const exampleSketch = startSketchOn(\"-XZ\")\n |> circle([0, 0], 10, %)\n\nconst example = extrude(5, exampleSketch)"
|
||||
"const exampleSketch = startSketchOn(\"-XZ\")\n |> circle([0, 0], 10, %)\n\nconst example = extrude(5, exampleSketch)",
|
||||
"const exampleSketch = startSketchOn(\"XZ\")\n |> startProfileAt([-15, 0], %)\n |> line([30, 0], %)\n |> line([0, 30], %)\n |> line([-30, 0], %)\n |> close(%)\n |> hole(circle([0, 15], 5, %), %)\n\nconst example = extrude(5, exampleSketch)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -22414,7 +22415,7 @@
|
||||
"unpublished": false,
|
||||
"deprecated": false,
|
||||
"examples": [
|
||||
"const anotherVar = cos(2 * pi())"
|
||||
"const exampleSketch = startSketchOn(\"XZ\")\n |> startProfileAt([0, 0], %)\n |> angledLine({\n angle: 30,\n length: 3 / cos(toRadians(30))\n }, %)\n |> yLineTo(0, %)\n |> close(%)\n\nconst example = extrude(5, exampleSketch)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -22437,7 +22438,7 @@
|
||||
"unpublished": false,
|
||||
"deprecated": false,
|
||||
"examples": [
|
||||
"const myVar = e()"
|
||||
"const exampleSketch = startSketchOn(\"XZ\")\n |> startProfileAt([0, 0], %)\n |> angledLine({ angle: 30, length: 2 * e() ^ 2 }, %)\n |> yLineTo(0, %)\n |> close(%)\n\nconst example = extrude(10, exampleSketch)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -25953,8 +25954,8 @@
|
||||
"unpublished": false,
|
||||
"deprecated": false,
|
||||
"examples": [
|
||||
"const example = startSketchOn('-XZ')\n |> startProfileAt([0, 0], %)\n |> line([10, 0], %)\n |> arc({\n angle_end: 0,\n angle_start: 120,\n radius: 5\n }, %)\n |> line([5, 0], %)\n |> line([0, 10], %)\n |> bezierCurve({\n control1: [-10, 0],\n control2: [2, 10],\n to: [-5, 10]\n }, %)\n |> line([-5, -2], %)\n |> close(%)\n |> extrude(10, %)",
|
||||
"const exampleSketch = startSketchOn('-XZ')\n |> startProfileAt([-10, 0], %)\n |> arc({\n angle_end: -60,\n angle_start: 120,\n radius: 5\n }, %)\n |> line([10, 0], %)\n |> line([5, 0], %)\n |> bezierCurve({\n control1: [-3, 0],\n control2: [2, 10],\n to: [-5, 10]\n }, %)\n |> line([-4, 10], %)\n |> line([-5, -2], %)\n |> close(%)\n\nconst example = extrude(10, exampleSketch)"
|
||||
"const example = startSketchOn('XZ')\n |> startProfileAt([0, 0], %)\n |> line([10, 0], %)\n |> arc({\n angle_end: 0,\n angle_start: 120,\n radius: 5\n }, %)\n |> line([5, 0], %)\n |> line([0, 10], %)\n |> bezierCurve({\n control1: [-10, 0],\n control2: [2, 10],\n to: [-5, 10]\n }, %)\n |> line([-5, -2], %)\n |> close(%)\n |> extrude(10, %)",
|
||||
"const exampleSketch = startSketchOn('XZ')\n |> startProfileAt([-10, 0], %)\n |> arc({\n angle_end: -60,\n angle_start: 120,\n radius: 5\n }, %)\n |> line([10, 0], %)\n |> line([5, 0], %)\n |> bezierCurve({\n control1: [-3, 0],\n control2: [2, 10],\n to: [-5, 10]\n }, %)\n |> line([-4, 10], %)\n |> line([-5, -2], %)\n |> close(%)\n\nconst example = extrude(10, exampleSketch)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -27550,7 +27551,7 @@
|
||||
"unpublished": false,
|
||||
"deprecated": false,
|
||||
"examples": [
|
||||
"const myVar = floor(4.5)"
|
||||
"const sketch001 = startSketchOn('XZ')\n |> startProfileAt([0, 0], %)\n |> lineTo([12, 10], %)\n |> line([floor(7.02986), 0], %)\n |> yLineTo(0, %)\n |> close(%)\n\nconst extrude001 = extrude(5, sketch001)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -28336,7 +28337,7 @@
|
||||
"unpublished": false,
|
||||
"deprecated": false,
|
||||
"examples": [
|
||||
"const box = startSketchOn('XZ')\n |> startProfileAt([0, 0], %)\n |> line([0, 10], %, 'revolveAxis')\n |> line([10, 0], %)\n |> line([0, -10], %)\n |> close(%)\n |> extrude(10, %)\n\nconst revolution = startSketchOn('XZ')\n |> startProfileAt([-10, 0], %)\n |> line([0, 10], %)\n |> line([2, 0], %)\n |> line([0, -10], %)\n |> close(%)\n |> revolve({\n axis: getEdge('revolveAxis', box),\n angle: 90\n }, %)"
|
||||
"const box = startSketchOn('XZ')\n |> startProfileAt([0, 0], %)\n |> line([0, 10], %, 'revolveAxis')\n |> line([10, 0], %)\n |> line([0, -10], %)\n |> close(%)\n |> extrude(10, %)\n\nconst revolution = startSketchOn(box, \"revolveAxis\")\n |> startProfileAt([5, 10], %)\n |> line([0, 10], %)\n |> line([2, 0], %)\n |> line([0, -10], %)\n |> close(%)\n |> revolve({\n axis: getEdge('revolveAxis', box),\n angle: 90\n }, %)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -36161,7 +36162,7 @@
|
||||
"deprecated": false,
|
||||
"examples": [
|
||||
"const exampleSketch = startSketchOn('XY')\n |> startProfileAt([0, 0], %)\n |> line([0, 5], %)\n |> line([5, 0], %)\n |> line([0, -5], %)\n |> close(%)\n |> hole(circle([1, 1], .25, %), %)\n |> hole(circle([1, 4], .25, %), %)\n\nconst example = extrude(1, exampleSketch)",
|
||||
"fn squareHoleSketch = () => {\n const squareSketch = startSketchOn('-XZ')\n |> startProfileAt([-1, -1], %)\n |> line([2, 0], %)\n |> line([0, 2], %)\n |> line([-2, 0], %)\n |> close(%)\n return squareSketch\n}\n\nconst exampleSketch = startSketchOn('-XZ')\n |> circle([0, 0], 3, %)\n |> hole(squareHoleSketch(), %)"
|
||||
"fn squareHoleSketch = () => {\n const squareSketch = startSketchOn('-XZ')\n |> startProfileAt([-1, -1], %)\n |> line([2, 0], %)\n |> line([0, 2], %)\n |> line([-2, 0], %)\n |> close(%)\n return squareSketch\n}\n\nconst exampleSketch = startSketchOn('-XZ')\n |> circle([0, 0], 3, %)\n |> hole(squareHoleSketch(), %)\nconst example = extrude(1, exampleSketch)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -37807,7 +37808,7 @@
|
||||
"unpublished": false,
|
||||
"deprecated": false,
|
||||
"examples": [
|
||||
"const exampleSketch = startSketchOn(\"-XZ\")\n |> startProfileAt([0, 0], %)\n |> line([5, 0], %)\n |> line([20, 5], %)\n |> line([0, lastSegX(%)], %)\n |> line([-15, 0], %)\n |> close(%)\n\nconst example = extrude(5, exampleSketch)"
|
||||
"const exampleSketch = startSketchOn(\"XZ\")\n |> startProfileAt([0, 0], %)\n |> line([5, 0], %)\n |> line([20, 5], %)\n |> line([0, lastSegX(%)], %)\n |> line([-15, 0], %)\n |> close(%)\n\nconst example = extrude(5, exampleSketch)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -38796,7 +38797,7 @@
|
||||
"unpublished": false,
|
||||
"deprecated": false,
|
||||
"examples": [
|
||||
"const exampleSketch = startSketchOn(\"-XZ\")\n |> startProfileAt([0, 0], %)\n |> line([5, 0], %)\n |> line([20, 5], %)\n |> line([0, lastSegY(%)], %)\n |> line([-15, 0], %)\n |> close(%)\n\nconst example = extrude(5, exampleSketch)"
|
||||
"const exampleSketch = startSketchOn(\"XZ\")\n |> startProfileAt([0, 0], %)\n |> line([5, 0], %)\n |> line([20, 5], %)\n |> line([0, lastSegY(%)], %)\n |> line([-15, 0], %)\n |> close(%)\n\nconst example = extrude(5, exampleSketch)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -40892,7 +40893,8 @@
|
||||
"unpublished": false,
|
||||
"deprecated": false,
|
||||
"examples": [
|
||||
"const exampleSketch = startSketchOn(\"-XZ\")\n |> startProfileAt([0, 0], %)\n |> line([10, 0], %)\n |> line([0, 10], %)\n |> line([-10, 0], %)\n |> close(%)\n\nconst example = extrude(5, exampleSketch)"
|
||||
"const exampleSketch = startSketchOn(\"XZ\")\n |> startProfileAt([0, 0], %)\n |> line([25, 15], %)\n |> line([5, -6], %)\n |> line([-10, -10], %)\n |> close(%)\n\nconst example = extrude(5, exampleSketch)",
|
||||
"const exampleSketch = startSketchOn(\"XZ\")\n |> startProfileAt([0, 0], %)\n |> line([10, 0], %)\n |> line([0, 10], %)\n |> line([-10, 0], %)\n |> close(%)\n\nconst example = extrude(5, exampleSketch)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -42862,7 +42864,7 @@
|
||||
"unpublished": false,
|
||||
"deprecated": false,
|
||||
"examples": [
|
||||
"const exampleSketch = startSketchOn(\"-XZ\")\n |> startProfileAt([0, 0], %)\n |> lineTo([10, 0], %)\n |> lineTo([0, 10], %)\n |> lineTo([-10, 0], %)\n |> close(%)\n\nconst example = extrude(5, exampleSketch)"
|
||||
"const exampleSketch = startSketchOn(\"XZ\")\n |> startProfileAt([0, 0], %)\n |> lineTo([10, 0], %)\n |> lineTo([0, 10], %)\n |> lineTo([-10, 0], %)\n |> close(%)\n\nconst example = extrude(5, exampleSketch)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -42895,7 +42897,7 @@
|
||||
"unpublished": false,
|
||||
"deprecated": false,
|
||||
"examples": [
|
||||
"const myVar = ln(4)"
|
||||
"const exampleSketch = startSketchOn(\"XZ\")\n |> startProfileAt([0, 0], %)\n |> line([ln(100), 15], %)\n |> line([5, -6], %)\n |> line([-10, -10], %)\n |> close(%)\n\nconst example = extrude(5, exampleSketch)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -42937,7 +42939,7 @@
|
||||
"unpublished": false,
|
||||
"deprecated": false,
|
||||
"examples": [
|
||||
"const myVar = log(4, 2)"
|
||||
"const exampleSketch = startSketchOn(\"XZ\")\n |> startProfileAt([0, 0], %)\n |> line([log(100, 5), 0], %)\n |> line([5, 8], %)\n |> line([-10, 0], %)\n |> close(%)\n\nconst example = extrude(5, exampleSketch)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -42970,7 +42972,7 @@
|
||||
"unpublished": false,
|
||||
"deprecated": false,
|
||||
"examples": [
|
||||
"const myVar = log10(4)"
|
||||
"const exampleSketch = startSketchOn(\"XZ\")\n |> startProfileAt([0, 0], %)\n |> line([log10(100), 0], %)\n |> line([5, 8], %)\n |> line([-10, 0], %)\n |> close(%)\n\nconst example = extrude(5, exampleSketch)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -43003,7 +43005,7 @@
|
||||
"unpublished": false,
|
||||
"deprecated": false,
|
||||
"examples": [
|
||||
"const myVar = log2(4)"
|
||||
"const exampleSketch = startSketchOn(\"XZ\")\n |> startProfileAt([0, 0], %)\n |> line([log2(100), 0], %)\n |> line([5, 8], %)\n |> line([-10, 0], %)\n |> close(%)\n\nconst example = extrude(5, exampleSketch)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -43039,7 +43041,7 @@
|
||||
"unpublished": false,
|
||||
"deprecated": false,
|
||||
"examples": [
|
||||
"const myVar = max(4, 5, 6)"
|
||||
"const exampleSketch = startSketchOn(\"XZ\")\n |> startProfileAt([0, 0], %)\n |> angledLine({\n angle: 70,\n length: max(15, 31, 4, 13, 22)\n }, %)\n |> line([20, 0], %)\n |> close(%)\n\nconst example = extrude(5, exampleSketch)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -43075,7 +43077,7 @@
|
||||
"unpublished": false,
|
||||
"deprecated": false,
|
||||
"examples": [
|
||||
"const myVar = min(4, 5, 6)"
|
||||
"const exampleSketch = startSketchOn(\"XZ\")\n |> startProfileAt([0, 0], %)\n |> angledLine({\n angle: 70,\n length: min(15, 31, 4, 13, 22)\n }, %)\n |> line([20, 0], %)\n |> close(%)\n\nconst example = extrude(5, exampleSketch)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -45067,7 +45069,7 @@
|
||||
"unpublished": false,
|
||||
"deprecated": false,
|
||||
"examples": [
|
||||
"const exampleSketch = startSketchOn('-XZ')\n |> startProfileAt([.5, 25], %)\n |> line([0, 5], %)\n |> line([-1, 0], %)\n |> line([0, -5], %)\n |> close(%)\n |> patternCircular2d({\n center: [0, 0],\n repetitions: 12,\n arcDegrees: 360,\n rotateDuplicates: true\n }, %)\n\nconst example = extrude(1, exampleSketch)"
|
||||
"const exampleSketch = startSketchOn('XZ')\n |> startProfileAt([.5, 25], %)\n |> line([0, 5], %)\n |> line([-1, 0], %)\n |> line([0, -5], %)\n |> close(%)\n |> patternCircular2d({\n center: [0, 0],\n repetitions: 12,\n arcDegrees: 360,\n rotateDuplicates: true\n }, %)\n\nconst example = extrude(1, exampleSketch)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -46648,7 +46650,7 @@
|
||||
"unpublished": false,
|
||||
"deprecated": false,
|
||||
"examples": [
|
||||
"const exampleSketch = startSketchOn('-XZ')\n |> circle([0, 0], 1, %)\n\nconst example = extrude(-5, exampleSketch)\n |> patternCircular3d({\n axis: [1, -1, 0],\n center: [10, -20, 0],\n repetitions: 10,\n arcDegrees: 360,\n rotateDuplicates: true\n }, %)"
|
||||
"const exampleSketch = startSketchOn('XZ')\n |> circle([0, 0], 1, %)\n\nconst example = extrude(-5, exampleSketch)\n |> patternCircular3d({\n axis: [1, -1, 0],\n center: [10, -20, 0],\n repetitions: 10,\n arcDegrees: 360,\n rotateDuplicates: true\n }, %)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -49626,7 +49628,7 @@
|
||||
"unpublished": false,
|
||||
"deprecated": false,
|
||||
"examples": [
|
||||
"const exampleSketch = startSketchOn('-XZ')\n |> circle([0, 0], 1, %)\n |> patternLinear2d({\n axis: [1, 0],\n repetitions: 6,\n distance: 4\n }, %)\n\nconst example = extrude(1, exampleSketch)"
|
||||
"const exampleSketch = startSketchOn('XZ')\n |> circle([0, 0], 1, %)\n |> patternLinear2d({\n axis: [1, 0],\n repetitions: 6,\n distance: 4\n }, %)\n\nconst example = extrude(1, exampleSketch)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -51191,7 +51193,7 @@
|
||||
"unpublished": false,
|
||||
"deprecated": false,
|
||||
"examples": [
|
||||
"const exampleSketch = startSketchOn('-XZ')\n |> startProfileAt([0, 0], %)\n |> line([0, 2], %)\n |> line([3, 1], %)\n |> line([0, -4], %)\n |> close(%)\n\nconst example = extrude(1, exampleSketch)\n |> patternLinear3d({\n axis: [1, 0, 1],\n repetitions: 6,\n distance: 6\n }, %)"
|
||||
"const exampleSketch = startSketchOn('XZ')\n |> startProfileAt([0, 0], %)\n |> line([0, 2], %)\n |> line([3, 1], %)\n |> line([0, -4], %)\n |> close(%)\n\nconst example = extrude(1, exampleSketch)\n |> patternLinear3d({\n axis: [1, 0, 1],\n repetitions: 6,\n distance: 6\n }, %)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -51214,7 +51216,7 @@
|
||||
"unpublished": false,
|
||||
"deprecated": false,
|
||||
"examples": [
|
||||
"const myVar = pi() * 3.0"
|
||||
"const circumference = 70\n\nconst exampleSketch = startSketchOn(\"XZ\")\n |> circle([0, 0], circumference / (2 * pi()), %)\n\nconst example = extrude(5, exampleSketch)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -51256,7 +51258,7 @@
|
||||
"unpublished": false,
|
||||
"deprecated": false,
|
||||
"examples": [
|
||||
"const myVar = pow(4, 2)"
|
||||
"const exampleSketch = startSketchOn(\"XZ\")\n |> startProfileAt([0, 0], %)\n |> angledLine({ angle: 50, length: pow(5, 2) }, %)\n |> yLineTo(0, %)\n |> close(%)\n\nconst example = extrude(5, exampleSketch)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -57090,7 +57092,7 @@
|
||||
"unpublished": false,
|
||||
"deprecated": false,
|
||||
"examples": [
|
||||
"const exampleSketch = startSketchOn('-XZ')\n |> startProfileAt([0, 0], %)\n |> line([10, 0], %)\n |> line([5, 10], %, 'seg01')\n |> line([-10, 0], %)\n |> angledLine([segAng('seg01', %), 10], %)\n |> line([-10, 0], %)\n |> angledLine([segAng('seg01', %), -15], %)\n |> close(%)\n\nconst example = extrude(4, exampleSketch)"
|
||||
"const exampleSketch = startSketchOn('XZ')\n |> startProfileAt([0, 0], %)\n |> line([10, 0], %)\n |> line([5, 10], %, 'seg01')\n |> line([-10, 0], %)\n |> angledLine([segAng('seg01', %), 10], %)\n |> line([-10, 0], %)\n |> angledLine([segAng('seg01', %), -15], %)\n |> close(%)\n\nconst example = extrude(4, exampleSketch)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -58087,7 +58089,7 @@
|
||||
"unpublished": false,
|
||||
"deprecated": false,
|
||||
"examples": [
|
||||
"const exampleSketch = startSketchOn('-XZ')\n |> startProfileAt([0, 0], %)\n |> line([20, 0], %, \"thing\")\n |> line([0, 5], %)\n |> line([segEndX(\"thing\", %), 0], %)\n |> line([-20, 10], %)\n |> close(%)\n\nconst example = extrude(5, exampleSketch)"
|
||||
"const exampleSketch = startSketchOn('XZ')\n |> startProfileAt([0, 0], %)\n |> line([20, 0], %, \"thing\")\n |> line([0, 5], %)\n |> line([segEndX(\"thing\", %), 0], %)\n |> line([-20, 10], %)\n |> close(%)\n\nconst example = extrude(5, exampleSketch)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -59084,7 +59086,7 @@
|
||||
"unpublished": false,
|
||||
"deprecated": false,
|
||||
"examples": [
|
||||
"const exampleSketch = startSketchOn('-XZ')\n |> startProfileAt([0, 0], %)\n |> line([20, 0], %)\n |> line([0, 3], %, \"thing\")\n |> line([-10, 0], %)\n |> line([0, segEndY(\"thing\", %)], %)\n |> line([-10, 0], %)\n |> close(%)\n\nconst example = extrude(5, exampleSketch)"
|
||||
"const exampleSketch = startSketchOn('XZ')\n |> startProfileAt([0, 0], %)\n |> line([20, 0], %)\n |> line([0, 3], %, \"thing\")\n |> line([-10, 0], %)\n |> line([0, segEndY(\"thing\", %)], %)\n |> line([-10, 0], %)\n |> close(%)\n\nconst example = extrude(5, exampleSketch)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -60081,7 +60083,7 @@
|
||||
"unpublished": false,
|
||||
"deprecated": false,
|
||||
"examples": [
|
||||
"const exampleSketch = startSketchOn(\"-XZ\")\n |> startProfileAt([0, 0], %)\n |> angledLine({ angle: 60, length: 10 }, %, \"thing\")\n |> tangentialArc({ offset: -120, radius: 5 }, %)\n |> angledLine({\n angle: -60,\n length: segLen(\"thing\", %)\n }, %)\n |> close(%)\n\nconst example = extrude(5, exampleSketch)"
|
||||
"const exampleSketch = startSketchOn(\"XZ\")\n |> startProfileAt([0, 0], %)\n |> angledLine({ angle: 60, length: 10 }, %, \"thing\")\n |> tangentialArc({ offset: -120, radius: 5 }, %)\n |> angledLine({\n angle: -60,\n length: segLen(\"thing\", %)\n }, %)\n |> close(%)\n\nconst example = extrude(5, exampleSketch)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -60114,7 +60116,7 @@
|
||||
"unpublished": false,
|
||||
"deprecated": false,
|
||||
"examples": [
|
||||
"const myVar = sin(2 * pi())"
|
||||
"const exampleSketch = startSketchOn(\"XZ\")\n |> startProfileAt([0, 0], %)\n |> angledLine({\n angle: 50,\n length: 15 / sin(toDegrees(135))\n }, %)\n |> yLineTo(0, %)\n |> close(%)\n\nconst example = extrude(5, exampleSketch)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -60147,7 +60149,7 @@
|
||||
"unpublished": false,
|
||||
"deprecated": false,
|
||||
"examples": [
|
||||
"const myVar = sqrt(4)"
|
||||
"const exampleSketch = startSketchOn(\"XZ\")\n |> startProfileAt([0, 0], %)\n |> angledLine({ angle: 50, length: sqrt(2500) }, %)\n |> yLineTo(0, %)\n |> close(%)\n\nconst example = extrude(5, exampleSketch)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -61456,7 +61458,7 @@
|
||||
"unpublished": false,
|
||||
"deprecated": false,
|
||||
"examples": [
|
||||
"const exampleSketch = startSketchOn('-XZ')\n |> startProfileAt([0, 0], %)\n |> line([10, 0], %)\n |> line([0, 10], %)\n |> line([-10, 0], %)\n |> close(%)\n\nconst example = extrude(5, exampleSketch)",
|
||||
"const exampleSketch = startSketchOn('XZ')\n |> startProfileAt([0, 0], %)\n |> line([10, 0], %)\n |> line([0, 10], %)\n |> line([-10, 0], %)\n |> close(%)\n\nconst example = extrude(5, exampleSketch)",
|
||||
"const exampleSketch = startSketchOn('-XZ')\n |> startProfileAt([10, 10], %)\n |> line([10, 0], %)\n |> line([0, 10], %)\n |> line([-10, 0], %)\n |> close(%)\n\nconst example = extrude(5, exampleSketch)",
|
||||
"const exampleSketch = startSketchOn('-XZ')\n |> startProfileAt([-10, 23], %)\n |> line([10, 0], %)\n |> line([0, 10], %)\n |> line([-10, 0], %)\n |> close(%)\n\nconst example = extrude(5, exampleSketch)"
|
||||
]
|
||||
@ -63762,7 +63764,7 @@
|
||||
"unpublished": false,
|
||||
"deprecated": false,
|
||||
"examples": [
|
||||
"const myVar = tan(2 * pi())"
|
||||
"const exampleSketch = startSketchOn(\"XZ\")\n |> startProfileAt([0, 0], %)\n |> angledLine({ angle: 50, length: 50 * tan(1 / 2) }, %)\n |> yLineTo(0, %)\n |> close(%)\n\nconst example = extrude(5, exampleSketch)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -65757,7 +65759,7 @@
|
||||
"unpublished": false,
|
||||
"deprecated": false,
|
||||
"examples": [
|
||||
"const exampleSketch = startSketchOn('-XZ')\n |> startProfileAt([0, 0], %)\n |> angledLine({ angle: 60, length: 10 }, %)\n |> tangentialArc({ radius: 10, offset: -120 }, %)\n |> angledLine({ angle: -60, length: 10 }, %)\n |> close(%)\n\nconst example = extrude(10, exampleSketch)"
|
||||
"const exampleSketch = startSketchOn('XZ')\n |> startProfileAt([0, 0], %)\n |> angledLine({ angle: 60, length: 10 }, %)\n |> tangentialArc({ radius: 10, offset: -120 }, %)\n |> angledLine({ angle: -60, length: 10 }, %)\n |> close(%)\n\nconst example = extrude(10, exampleSketch)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -67727,7 +67729,7 @@
|
||||
"unpublished": false,
|
||||
"deprecated": false,
|
||||
"examples": [
|
||||
"const exampleSketch = startSketchOn('-XZ')\n |> startProfileAt([0, 0], %)\n |> angledLine({ angle: 60, length: 10 }, %)\n |> tangentialArcTo([15, 15], %)\n |> line([10, -15], %)\n |> close(%)\n\nconst example = extrude(10, exampleSketch)"
|
||||
"const exampleSketch = startSketchOn('XZ')\n |> startProfileAt([0, 0], %)\n |> angledLine({ angle: 60, length: 10 }, %)\n |> tangentialArcTo([15, 15], %)\n |> line([10, -15], %)\n |> close(%)\n\nconst example = extrude(10, exampleSketch)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -67750,7 +67752,7 @@
|
||||
"unpublished": false,
|
||||
"deprecated": false,
|
||||
"examples": [
|
||||
"const myVar = tau()"
|
||||
"const exampleSketch = startSketchOn(\"XZ\")\n |> startProfileAt([0, 0], %)\n |> angledLine({ angle: 50, length: 10 * tau() }, %)\n |> yLineTo(0, %)\n |> close(%)\n\nconst example = extrude(5, exampleSketch)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -67783,7 +67785,7 @@
|
||||
"unpublished": false,
|
||||
"deprecated": false,
|
||||
"examples": [
|
||||
"const myVar = toDegrees(2 * pi())"
|
||||
"const exampleSketch = startSketchOn(\"XZ\")\n |> startProfileAt([0, 0], %)\n |> angledLine({\n angle: 50,\n length: 70 * cos(toDegrees(pi() / 4))\n }, %)\n |> yLineTo(0, %)\n |> close(%)\n\nconst example = extrude(5, exampleSketch)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -67816,7 +67818,7 @@
|
||||
"unpublished": false,
|
||||
"deprecated": false,
|
||||
"examples": [
|
||||
"const myVar = toRadians(180)"
|
||||
"const exampleSketch = startSketchOn(\"XZ\")\n |> startProfileAt([0, 0], %)\n |> angledLine({\n angle: 50,\n length: 70 * cos(toRadians(45))\n }, %)\n |> yLineTo(0, %)\n |> close(%)\n\nconst example = extrude(5, exampleSketch)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -69781,7 +69783,7 @@
|
||||
"unpublished": false,
|
||||
"deprecated": false,
|
||||
"examples": [
|
||||
"const exampleSketch = startSketchOn('-XZ')\n |> startProfileAt([0, 0], %)\n |> xLine(15, %)\n |> angledLine({ angle: 80, length: 15 }, %)\n |> line([8, -10], %)\n |> xLine(10, %)\n |> angledLine({ angle: 120, length: 30 }, %)\n |> xLine(-15, %)\n |> close(%)\n\nconst example = extrude(10, exampleSketch)"
|
||||
"const exampleSketch = startSketchOn('XZ')\n |> startProfileAt([0, 0], %)\n |> xLine(15, %)\n |> angledLine({ angle: 80, length: 15 }, %)\n |> line([8, -10], %)\n |> xLine(10, %)\n |> angledLine({ angle: 120, length: 30 }, %)\n |> xLine(-15, %)\n |> close(%)\n\nconst example = extrude(10, exampleSketch)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -71746,7 +71748,7 @@
|
||||
"unpublished": false,
|
||||
"deprecated": false,
|
||||
"examples": [
|
||||
"const exampleSketch = startSketchOn('-XZ')\n |> startProfileAt([0, 0], %)\n |> xLineTo(15, %)\n |> angledLine({ angle: 80, length: 15 }, %)\n |> line([8, -10], %)\n |> xLineTo(40, %)\n |> angledLine({ angle: 135, length: 30 }, %)\n |> xLineTo(10, %)\n |> close(%)\n\nconst example = extrude(10, exampleSketch)"
|
||||
"const exampleSketch = startSketchOn('XZ')\n |> startProfileAt([0, 0], %)\n |> xLineTo(15, %)\n |> angledLine({ angle: 80, length: 15 }, %)\n |> line([8, -10], %)\n |> xLineTo(40, %)\n |> angledLine({ angle: 135, length: 30 }, %)\n |> xLineTo(10, %)\n |> close(%)\n\nconst example = extrude(10, exampleSketch)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -73711,7 +73713,7 @@
|
||||
"unpublished": false,
|
||||
"deprecated": false,
|
||||
"examples": [
|
||||
"const exampleSketch = startSketchOn('-XZ')\n |> startProfileAt([0, 0], %)\n |> yLine(15, %)\n |> angledLine({ angle: 30, length: 15 }, %)\n |> line([8, -10], %)\n |> yLine(-5, %)\n |> close(%)\n\nconst example = extrude(10, exampleSketch)"
|
||||
"const exampleSketch = startSketchOn('XZ')\n |> startProfileAt([0, 0], %)\n |> yLine(15, %)\n |> angledLine({ angle: 30, length: 15 }, %)\n |> line([8, -10], %)\n |> yLine(-5, %)\n |> close(%)\n\nconst example = extrude(10, exampleSketch)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -75676,7 +75678,7 @@
|
||||
"unpublished": false,
|
||||
"deprecated": false,
|
||||
"examples": [
|
||||
"startSketchOn('XZ')\n |> startProfileAt([0, 0], %)\n |> yLineTo(10, %, \"edge1\")\n |> line([10, 10], %)\n |> close(%, \"edge2\")\n |> extrude(10, %)\n |> fillet({ radius: 2, tags: [\"edge2\"] }, %)"
|
||||
"const exampleSketch = startSketchOn(\"XZ\")\n |> startProfileAt([0, 0], %)\n |> angledLine({ angle: 50, length: 45 }, %)\n |> yLineTo(0, %)\n |> close(%)\n\nconst example = extrude(5, exampleSketch)"
|
||||
]
|
||||
}
|
||||
]
|
@ -15,7 +15,7 @@ tangentialArc(data: TangentialArcData, sketch_group: SketchGroup, tag?: String)
|
||||
### Examples
|
||||
|
||||
```js
|
||||
const exampleSketch = startSketchOn('-XZ')
|
||||
const exampleSketch = startSketchOn('XZ')
|
||||
|> startProfileAt([0, 0], %)
|
||||
|> angledLine({ angle: 60, length: 10 }, %)
|
||||
|> tangentialArc({ radius: 10, offset: -120 }, %)
|
||||
|
@ -15,7 +15,7 @@ tangentialArcTo(to: [number], sketch_group: SketchGroup, tag?: String) -> Sketch
|
||||
### Examples
|
||||
|
||||
```js
|
||||
const exampleSketch = startSketchOn('-XZ')
|
||||
const exampleSketch = startSketchOn('XZ')
|
||||
|> startProfileAt([0, 0], %)
|
||||
|> angledLine({ angle: 60, length: 10 }, %)
|
||||
|> tangentialArcTo([15, 15], %)
|
||||
|
@ -15,7 +15,7 @@ xLine(length: number, sketch_group: SketchGroup, tag?: String) -> SketchGroup
|
||||
### Examples
|
||||
|
||||
```js
|
||||
const exampleSketch = startSketchOn('-XZ')
|
||||
const exampleSketch = startSketchOn('XZ')
|
||||
|> startProfileAt([0, 0], %)
|
||||
|> xLine(15, %)
|
||||
|> angledLine({ angle: 80, length: 15 }, %)
|
||||
|
@ -15,7 +15,7 @@ xLineTo(to: number, sketch_group: SketchGroup, tag?: String) -> SketchGroup
|
||||
### Examples
|
||||
|
||||
```js
|
||||
const exampleSketch = startSketchOn('-XZ')
|
||||
const exampleSketch = startSketchOn('XZ')
|
||||
|> startProfileAt([0, 0], %)
|
||||
|> xLineTo(15, %)
|
||||
|> angledLine({ angle: 80, length: 15 }, %)
|
||||
|
@ -15,7 +15,7 @@ yLine(length: number, sketch_group: SketchGroup, tag?: String) -> SketchGroup
|
||||
### Examples
|
||||
|
||||
```js
|
||||
const exampleSketch = startSketchOn('-XZ')
|
||||
const exampleSketch = startSketchOn('XZ')
|
||||
|> startProfileAt([0, 0], %)
|
||||
|> yLine(15, %)
|
||||
|> angledLine({ angle: 30, length: 15 }, %)
|
||||
|
Before Width: | Height: | Size: 224 KiB After Width: | Height: | Size: 249 KiB |
Before Width: | Height: | Size: 224 KiB After Width: | Height: | Size: 249 KiB |
Before Width: | Height: | Size: 224 KiB After Width: | Height: | Size: 249 KiB |
Before Width: | Height: | Size: 165 KiB After Width: | Height: | Size: 171 KiB |
Before Width: | Height: | Size: 165 KiB After Width: | Height: | Size: 171 KiB |
Before Width: | Height: | Size: 165 KiB After Width: | Height: | Size: 171 KiB |
Before Width: | Height: | Size: 165 KiB After Width: | Height: | Size: 171 KiB |
Before Width: | Height: | Size: 224 KiB After Width: | Height: | Size: 249 KiB |
Before Width: | Height: | Size: 165 KiB After Width: | Height: | Size: 171 KiB |
Before Width: | Height: | Size: 165 KiB After Width: | Height: | Size: 171 KiB |
@ -44,7 +44,7 @@ test.setTimeout(60_000)
|
||||
test('exports of each format should work', async ({ page, context }) => {
|
||||
// FYI this test doesn't work with only engine running locally
|
||||
// And you will need to have the KittyCAD CLI installed
|
||||
const u = getUtils(page)
|
||||
const u = await getUtils(page)
|
||||
await context.addInitScript(async () => {
|
||||
;(window as any).playwrightSkipFilePicker = true
|
||||
localStorage.setItem(
|
||||
@ -369,7 +369,7 @@ const extrudeDefaultPlane = async (context: any, page: any, plane: string) => {
|
||||
localStorage.setItem('persistCode', code)
|
||||
})
|
||||
|
||||
const u = getUtils(page)
|
||||
const u = await getUtils(page)
|
||||
await page.setViewportSize({ width: 1200, height: 500 })
|
||||
await page.goto('/')
|
||||
await u.waitForAuthSkipAppStart()
|
||||
@ -424,7 +424,7 @@ test.describe('extrude on default planes should be stable', () => {
|
||||
})
|
||||
|
||||
test('Draft segments should look right', async ({ page, context }) => {
|
||||
const u = getUtils(page)
|
||||
const u = await getUtils(page)
|
||||
await page.setViewportSize({ width: 1200, height: 500 })
|
||||
const PUR = 400 / 37.5 //pixeltoUnitRatio
|
||||
await page.goto('/')
|
||||
@ -447,7 +447,7 @@ test('Draft segments should look right', async ({ page, context }) => {
|
||||
await page.mouse.click(700, 200)
|
||||
|
||||
await expect(page.locator('.cm-content')).toHaveText(
|
||||
`const part001 = startSketchOn('-XZ')`
|
||||
`const part001 = startSketchOn('XZ')`
|
||||
)
|
||||
|
||||
await page.waitForTimeout(300) // TODO detect animation ending, or disable animation
|
||||
@ -455,7 +455,7 @@ test('Draft segments should look right', async ({ page, context }) => {
|
||||
const startXPx = 600
|
||||
await page.mouse.click(startXPx + PUR * 10, 500 - PUR * 10)
|
||||
await expect(page.locator('.cm-content'))
|
||||
.toHaveText(`const part001 = startSketchOn('-XZ')
|
||||
.toHaveText(`const part001 = startSketchOn('XZ')
|
||||
|> startProfileAt([9.06, -12.22], %)`)
|
||||
await page.waitForTimeout(100)
|
||||
|
||||
@ -469,7 +469,7 @@ test('Draft segments should look right', async ({ page, context }) => {
|
||||
await page.waitForTimeout(100)
|
||||
|
||||
await expect(page.locator('.cm-content'))
|
||||
.toHaveText(`const part001 = startSketchOn('-XZ')
|
||||
.toHaveText(`const part001 = startSketchOn('XZ')
|
||||
|> startProfileAt([9.06, -12.22], %)
|
||||
|> line([9.14, 0], %)`)
|
||||
|
||||
@ -483,7 +483,7 @@ test('Draft segments should look right', async ({ page, context }) => {
|
||||
})
|
||||
|
||||
test('Draft rectangles should look right', async ({ page, context }) => {
|
||||
const u = getUtils(page)
|
||||
const u = await getUtils(page)
|
||||
await page.setViewportSize({ width: 1200, height: 500 })
|
||||
const PUR = 400 / 37.5 //pixeltoUnitRatio
|
||||
await page.goto('/')
|
||||
@ -506,7 +506,7 @@ test('Draft rectangles should look right', async ({ page, context }) => {
|
||||
await page.mouse.click(700, 200)
|
||||
|
||||
await expect(page.locator('.cm-content')).toHaveText(
|
||||
`const part001 = startSketchOn('-XZ')`
|
||||
`const part001 = startSketchOn('XZ')`
|
||||
)
|
||||
|
||||
await page.waitForTimeout(500) // TODO detect animation ending, or disable animation
|
||||
@ -530,7 +530,7 @@ test('Draft rectangles should look right', async ({ page, context }) => {
|
||||
|
||||
test.describe('Client side scene scale should match engine scale', () => {
|
||||
test('Inch scale', async ({ page }) => {
|
||||
const u = getUtils(page)
|
||||
const u = await getUtils(page)
|
||||
await page.setViewportSize({ width: 1200, height: 500 })
|
||||
const PUR = 400 / 37.5 //pixeltoUnitRatio
|
||||
await page.goto('/')
|
||||
@ -555,7 +555,7 @@ test.describe('Client side scene scale should match engine scale', () => {
|
||||
await page.mouse.click(700, 200)
|
||||
|
||||
await expect(page.locator('.cm-content')).toHaveText(
|
||||
`const part001 = startSketchOn('-XZ')`
|
||||
`const part001 = startSketchOn('XZ')`
|
||||
)
|
||||
|
||||
await page.waitForTimeout(300) // TODO detect animation ending, or disable animation
|
||||
@ -563,7 +563,7 @@ test.describe('Client side scene scale should match engine scale', () => {
|
||||
const startXPx = 600
|
||||
await page.mouse.click(startXPx + PUR * 10, 500 - PUR * 10)
|
||||
await expect(page.locator('.cm-content'))
|
||||
.toHaveText(`const part001 = startSketchOn('-XZ')
|
||||
.toHaveText(`const part001 = startSketchOn('XZ')
|
||||
|> startProfileAt([9.06, -12.22], %)`)
|
||||
await page.waitForTimeout(100)
|
||||
|
||||
@ -573,7 +573,7 @@ test.describe('Client side scene scale should match engine scale', () => {
|
||||
await page.waitForTimeout(100)
|
||||
|
||||
await expect(page.locator('.cm-content'))
|
||||
.toHaveText(`const part001 = startSketchOn('-XZ')
|
||||
.toHaveText(`const part001 = startSketchOn('XZ')
|
||||
|> startProfileAt([9.06, -12.22], %)
|
||||
|> line([9.14, 0], %)`)
|
||||
|
||||
@ -583,7 +583,7 @@ test.describe('Client side scene scale should match engine scale', () => {
|
||||
await page.mouse.click(startXPx + PUR * 30, 500 - PUR * 20)
|
||||
|
||||
await expect(page.locator('.cm-content'))
|
||||
.toHaveText(`const part001 = startSketchOn('-XZ')
|
||||
.toHaveText(`const part001 = startSketchOn('XZ')
|
||||
|> startProfileAt([9.06, -12.22], %)
|
||||
|> line([9.14, 0], %)
|
||||
|> tangentialArcTo([27.34, -3.08], %)`)
|
||||
@ -633,7 +633,7 @@ test.describe('Client side scene scale should match engine scale', () => {
|
||||
}),
|
||||
}
|
||||
)
|
||||
const u = getUtils(page)
|
||||
const u = await getUtils(page)
|
||||
await page.setViewportSize({ width: 1200, height: 500 })
|
||||
const PUR = 400 / 37.5 //pixeltoUnitRatio
|
||||
await page.goto('/')
|
||||
@ -658,7 +658,7 @@ test.describe('Client side scene scale should match engine scale', () => {
|
||||
await page.mouse.click(700, 200)
|
||||
|
||||
await expect(page.locator('.cm-content')).toHaveText(
|
||||
`const part001 = startSketchOn('-XZ')`
|
||||
`const part001 = startSketchOn('XZ')`
|
||||
)
|
||||
|
||||
await page.waitForTimeout(300) // TODO detect animation ending, or disable animation
|
||||
@ -666,7 +666,7 @@ test.describe('Client side scene scale should match engine scale', () => {
|
||||
const startXPx = 600
|
||||
await page.mouse.click(startXPx + PUR * 10, 500 - PUR * 10)
|
||||
await expect(page.locator('.cm-content'))
|
||||
.toHaveText(`const part001 = startSketchOn('-XZ')
|
||||
.toHaveText(`const part001 = startSketchOn('XZ')
|
||||
|> startProfileAt([230.03, -310.32], %)`)
|
||||
await page.waitForTimeout(100)
|
||||
|
||||
@ -676,7 +676,7 @@ test.describe('Client side scene scale should match engine scale', () => {
|
||||
await page.waitForTimeout(100)
|
||||
|
||||
await expect(page.locator('.cm-content'))
|
||||
.toHaveText(`const part001 = startSketchOn('-XZ')
|
||||
.toHaveText(`const part001 = startSketchOn('XZ')
|
||||
|> startProfileAt([230.03, -310.32], %)
|
||||
|> line([232.2, 0], %)`)
|
||||
|
||||
@ -686,7 +686,7 @@ test.describe('Client side scene scale should match engine scale', () => {
|
||||
await page.mouse.click(startXPx + PUR * 30, 500 - PUR * 20)
|
||||
|
||||
await expect(page.locator('.cm-content'))
|
||||
.toHaveText(`const part001 = startSketchOn('-XZ')
|
||||
.toHaveText(`const part001 = startSketchOn('XZ')
|
||||
|> startProfileAt([230.03, -310.32], %)
|
||||
|> line([232.2, 0], %)
|
||||
|> tangentialArcTo([694.43, -78.12], %)`)
|
||||
@ -719,7 +719,7 @@ test.describe('Client side scene scale should match engine scale', () => {
|
||||
})
|
||||
|
||||
test('Sketch on face with none z-up', async ({ page, context }) => {
|
||||
const u = getUtils(page)
|
||||
const u = await getUtils(page)
|
||||
await context.addInitScript(async (KCL_DEFAULT_LENGTH) => {
|
||||
localStorage.setItem(
|
||||
'persistCode',
|
||||
@ -773,3 +773,76 @@ const part002 = startSketchOn(part001, 'seg01')
|
||||
maxDiffPixels: 100,
|
||||
})
|
||||
})
|
||||
|
||||
test('Zoom to fit on load - solid 2d', async ({ page, context }) => {
|
||||
const u = await getUtils(page)
|
||||
await context.addInitScript(async () => {
|
||||
localStorage.setItem(
|
||||
'persistCode',
|
||||
`const part001 = startSketchOn('XY')
|
||||
|> startProfileAt([-10, -10], %)
|
||||
|> line([20, 0], %)
|
||||
|> line([0, 20], %)
|
||||
|> line([-20, 0], %)
|
||||
|> close(%)
|
||||
`
|
||||
)
|
||||
}, KCL_DEFAULT_LENGTH)
|
||||
|
||||
await page.setViewportSize({ width: 1200, height: 500 })
|
||||
await page.goto('/')
|
||||
await u.waitForAuthSkipAppStart()
|
||||
|
||||
await u.openDebugPanel()
|
||||
// wait for execution done
|
||||
await expect(
|
||||
page.locator('[data-message-type="execution-done"]')
|
||||
).toHaveCount(2)
|
||||
await u.closeDebugPanel()
|
||||
|
||||
// Wait for the second extrusion to appear
|
||||
// TODO: Find a way to truly know that the objects have finished
|
||||
// rendering, because an execution-done message is not sufficient.
|
||||
await page.waitForTimeout(1000)
|
||||
|
||||
await expect(page).toHaveScreenshot({
|
||||
maxDiffPixels: 100,
|
||||
})
|
||||
})
|
||||
|
||||
test('Zoom to fit on load - solid 3d', async ({ page, context }) => {
|
||||
const u = await getUtils(page)
|
||||
await context.addInitScript(async () => {
|
||||
localStorage.setItem(
|
||||
'persistCode',
|
||||
`const part001 = startSketchOn('XY')
|
||||
|> startProfileAt([-10, -10], %)
|
||||
|> line([20, 0], %)
|
||||
|> line([0, 20], %)
|
||||
|> line([-20, 0], %)
|
||||
|> close(%)
|
||||
|> extrude(10, %)
|
||||
`
|
||||
)
|
||||
}, KCL_DEFAULT_LENGTH)
|
||||
|
||||
await page.setViewportSize({ width: 1200, height: 500 })
|
||||
await page.goto('/')
|
||||
await u.waitForAuthSkipAppStart()
|
||||
|
||||
await u.openDebugPanel()
|
||||
// wait for execution done
|
||||
await expect(
|
||||
page.locator('[data-message-type="execution-done"]')
|
||||
).toHaveCount(2)
|
||||
await u.closeDebugPanel()
|
||||
|
||||
// Wait for the second extrusion to appear
|
||||
// TODO: Find a way to truly know that the objects have finished
|
||||
// rendering, because an execution-done message is not sufficient.
|
||||
await page.waitForTimeout(1000)
|
||||
|
||||
await expect(page).toHaveScreenshot({
|
||||
maxDiffPixels: 100,
|
||||
})
|
||||
})
|
||||
|
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 40 KiB |
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 41 KiB |
Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 46 KiB |
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 42 KiB |
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 31 KiB |
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 34 KiB |
Before Width: | Height: | Size: 71 KiB After Width: | Height: | Size: 65 KiB |
After Width: | Height: | Size: 71 KiB |
After Width: | Height: | Size: 76 KiB |
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 43 KiB |
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 45 KiB |
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 43 KiB |
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 44 KiB |
Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 46 KiB |
Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 42 KiB |
@ -1,8 +1,9 @@
|
||||
import { expect, Page } from '@playwright/test'
|
||||
import { test, expect, Page } from '@playwright/test'
|
||||
import { EngineCommand } from '../../src/lang/std/engineConnection'
|
||||
import fsp from 'fs/promises'
|
||||
import pixelMatch from 'pixelmatch'
|
||||
import { PNG } from 'pngjs'
|
||||
import { Protocol } from 'playwright-core/types/protocol'
|
||||
|
||||
async function waitForPageLoad(page: Page) {
|
||||
// wait for 'Loading stream...' spinner
|
||||
@ -93,7 +94,12 @@ async function waitForCmdReceive(page: Page, commandType: string) {
|
||||
.waitFor()
|
||||
}
|
||||
|
||||
export function getUtils(page: Page) {
|
||||
export async function getUtils(page: Page) {
|
||||
const cdpSession =
|
||||
process.platform === 'darwin'
|
||||
? null
|
||||
: await page.context().newCDPSession(page)
|
||||
|
||||
return {
|
||||
waitForAuthSkipAppStart: () => waitForPageLoad(page),
|
||||
removeCurrentCode: () => removeCurrentCode(page),
|
||||
@ -180,6 +186,17 @@ export function getUtils(page: Page) {
|
||||
}
|
||||
}, 50)
|
||||
}),
|
||||
emulateNetworkConditions: async (
|
||||
networkOptions: Protocol.Network.emulateNetworkConditionsParameters
|
||||
) => {
|
||||
// Skip on non-Chromium browsers, since we need to use the CDP.
|
||||
test.skip(
|
||||
cdpSession === null,
|
||||
'Network emulation is only supported in Chromium'
|
||||
)
|
||||
|
||||
cdpSession?.send('Network.emulateNetworkConditions', networkOptions)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
18
package.json
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "untitled-app",
|
||||
"version": "0.21.6",
|
||||
"version": "0.21.8",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@codemirror/autocomplete": "^6.16.0",
|
||||
@ -10,16 +10,16 @@
|
||||
"@fortawesome/react-fontawesome": "^0.2.0",
|
||||
"@headlessui/react": "^1.7.19",
|
||||
"@headlessui/tailwindcss": "^0.2.0",
|
||||
"@kittycad/lib": "^0.0.60",
|
||||
"@kittycad/lib": "^0.0.63",
|
||||
"@lezer/javascript": "^1.4.9",
|
||||
"@open-rpc/client-js": "^1.8.1",
|
||||
"@react-hook/resize-observer": "^1.2.6",
|
||||
"@react-hook/resize-observer": "^2.0.1",
|
||||
"@replit/codemirror-interact": "^6.3.1",
|
||||
"@tauri-apps/api": "2.0.0-beta.8",
|
||||
"@tauri-apps/api": "2.0.0-beta.12",
|
||||
"@tauri-apps/plugin-dialog": "^2.0.0-beta.2",
|
||||
"@tauri-apps/plugin-fs": "^2.0.0-beta.3",
|
||||
"@tauri-apps/plugin-http": "^2.0.0-beta.2",
|
||||
"@tauri-apps/plugin-os": "^2.0.0-beta.2",
|
||||
"@tauri-apps/plugin-os": "^2.0.0-beta.3",
|
||||
"@tauri-apps/plugin-process": "^2.0.0-beta.2",
|
||||
"@tauri-apps/plugin-shell": "^2.0.0-beta.2",
|
||||
"@tauri-apps/plugin-updater": "^2.0.0-beta.3",
|
||||
@ -29,7 +29,7 @@
|
||||
"@ts-stack/markdown": "^1.5.0",
|
||||
"@tweenjs/tween.js": "^23.1.1",
|
||||
"@types/node": "^18.19.31",
|
||||
"@types/react": "^18.2.77",
|
||||
"@types/react": "^18.3.2",
|
||||
"@types/react-dom": "^18.2.25",
|
||||
"@uiw/react-codemirror": "^4.21.25",
|
||||
"@xstate/inspect": "^0.8.0",
|
||||
@ -45,7 +45,7 @@
|
||||
"jszip": "^3.10.1",
|
||||
"node-fetch": "^3.3.2",
|
||||
"re-resizable": "^6.9.11",
|
||||
"react": "^18.2.0",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-hot-toast": "^2.4.1",
|
||||
"react-hotkeys-hook": "^4.5.0",
|
||||
@ -61,11 +61,11 @@
|
||||
"ua-parser-js": "^1.0.37",
|
||||
"uuid": "^9.0.1",
|
||||
"vitest": "^1.6.0",
|
||||
"vscode-jsonrpc": "^8.1.0",
|
||||
"vscode-jsonrpc": "^8.2.1",
|
||||
"vscode-languageserver-protocol": "^3.17.5",
|
||||
"wasm-pack": "^0.12.1",
|
||||
"web-vitals": "^3.5.2",
|
||||
"ws": "^8.16.0",
|
||||
"ws": "^8.17.0",
|
||||
"xstate": "^4.38.2",
|
||||
"zustand": "^4.5.2"
|
||||
},
|
||||
|
34
src-tauri/Cargo.lock
generated
@ -195,6 +195,7 @@ dependencies = [
|
||||
"tauri-plugin-http",
|
||||
"tauri-plugin-log",
|
||||
"tauri-plugin-os",
|
||||
"tauri-plugin-persisted-scope",
|
||||
"tauri-plugin-process",
|
||||
"tauri-plugin-shell",
|
||||
"tauri-plugin-updater",
|
||||
@ -2567,7 +2568,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "kcl-lib"
|
||||
version = "0.1.55"
|
||||
version = "0.1.57"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"approx",
|
||||
@ -5370,9 +5371,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tauri-plugin-fs"
|
||||
version = "2.0.0-beta.6"
|
||||
version = "2.0.0-beta.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "609f53d90f08808679ecdd81455d9a4d0053291b92780695569f7400fdba27d5"
|
||||
checksum = "35377195c6923beda5f29482a16b492d431de964389fca9aaf81a0f7e908023f"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"glob",
|
||||
@ -5447,6 +5448,22 @@ dependencies = [
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tauri-plugin-persisted-scope"
|
||||
version = "2.0.0-beta.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b600c870217ec082b0f3482935a8edad347d18e8cd7d422a74bc92d035c0e394"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"bincode",
|
||||
"log",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tauri",
|
||||
"tauri-plugin-fs",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tauri-plugin-process"
|
||||
version = "2.0.0-beta.3"
|
||||
@ -6059,9 +6076,8 @@ checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b"
|
||||
|
||||
[[package]]
|
||||
name = "ts-rs"
|
||||
version = "7.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fc2cae1fc5d05d47aa24b64f9a4f7cba24cdc9187a2084dd97ac57bef5eccae6"
|
||||
version = "8.1.0"
|
||||
source = "git+https://github.com/Aleph-Alpha/ts-rs#f898578d80d3e2a54080c1c046c45f9eaa2435c3"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"thiserror",
|
||||
@ -6072,11 +6088,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ts-rs-macros"
|
||||
version = "7.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "73f7f9b821696963053a89a7bd8b292dc34420aea8294d7b225274d488f3ec92"
|
||||
version = "8.1.0"
|
||||
source = "git+https://github.com/Aleph-Alpha/ts-rs#f898578d80d3e2a54080c1c046c45f9eaa2435c3"
|
||||
dependencies = [
|
||||
"Inflector",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.65",
|
||||
|
@ -28,6 +28,7 @@ tauri-plugin-fs = { version = "2.0.0-beta.6" }
|
||||
tauri-plugin-http = { version = "2.0.0-beta.6" }
|
||||
tauri-plugin-log = { version = "2.0.0-beta.4" }
|
||||
tauri-plugin-os = { version = "2.0.0-beta.2" }
|
||||
tauri-plugin-persisted-scope = { version = "2.0.0-beta.7" }
|
||||
tauri-plugin-process = { version = "2.0.0-beta.2" }
|
||||
tauri-plugin-shell = { version = "2.0.0-beta.2" }
|
||||
tauri-plugin-updater = { version = "2.0.0-beta.4" }
|
||||
|
@ -32,6 +32,15 @@
|
||||
{
|
||||
"identifier": "fs:scope",
|
||||
"allow": [
|
||||
{
|
||||
"path": "$TEMP"
|
||||
},
|
||||
{
|
||||
"path": "$TEMP/**/*"
|
||||
},
|
||||
{
|
||||
"path": "$HOME"
|
||||
},
|
||||
{
|
||||
"path": "$HOME/**/*"
|
||||
},
|
||||
@ -56,6 +65,33 @@
|
||||
]
|
||||
},
|
||||
"shell:allow-open",
|
||||
{
|
||||
"identifier": "shell:allow-execute",
|
||||
"allow": [
|
||||
{
|
||||
"name": "open",
|
||||
"cmd": "open",
|
||||
"args": [
|
||||
"-R",
|
||||
{
|
||||
"validator": "\\S+"
|
||||
}
|
||||
],
|
||||
"sidecar": false
|
||||
},
|
||||
{
|
||||
"name": "explorer",
|
||||
"cmd": "explorer",
|
||||
"args": [
|
||||
"/select",
|
||||
{
|
||||
"validator": "\\S+"
|
||||
}
|
||||
],
|
||||
"sidecar": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"dialog:allow-open",
|
||||
"dialog:allow-save",
|
||||
"dialog:allow-message",
|
||||
|
@ -18,13 +18,21 @@ use oauth2::TokenResponse;
|
||||
use tauri::{ipc::InvokeError, Manager};
|
||||
use tauri_plugin_cli::CliExt;
|
||||
use tauri_plugin_shell::ShellExt;
|
||||
use tokio::process::Command;
|
||||
|
||||
const DEFAULT_HOST: &str = "https://api.zoo.dev";
|
||||
const SETTINGS_FILE_NAME: &str = "settings.toml";
|
||||
const PROJECT_SETTINGS_FILE_NAME: &str = "project.toml";
|
||||
const PROJECT_FOLDER: &str = "zoo-modeling-app-projects";
|
||||
|
||||
#[tauri::command]
|
||||
async fn rename_project_directory(project_path: &str, new_name: &str) -> Result<PathBuf, InvokeError> {
|
||||
let project_dir = std::path::Path::new(project_path);
|
||||
|
||||
kcl_lib::settings::types::file::rename_project_directory(project_dir, new_name)
|
||||
.await
|
||||
.map_err(InvokeError::from_anyhow)
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
fn get_initial_default_dir(app: tauri::AppHandle) -> Result<PathBuf, InvokeError> {
|
||||
let dir = match app.path().document_dir() {
|
||||
@ -323,10 +331,20 @@ async fn get_user(token: &str, hostname: &str) -> Result<kittycad::types::User,
|
||||
/// From this GitHub comment: https://github.com/tauri-apps/tauri/issues/4062#issuecomment-1338048169
|
||||
/// But with the Linux support removed since we don't need it for now.
|
||||
#[tauri::command]
|
||||
fn show_in_folder(path: &str) -> Result<(), InvokeError> {
|
||||
fn show_in_folder(app: tauri::AppHandle, path: &str) -> Result<(), InvokeError> {
|
||||
// Check if the file exists.
|
||||
// If it doesn't, return an error.
|
||||
if !Path::new(path).exists() {
|
||||
return Err(InvokeError::from_anyhow(anyhow::anyhow!(
|
||||
"The file `{}` does not exist",
|
||||
path
|
||||
)));
|
||||
}
|
||||
|
||||
#[cfg(not(unix))]
|
||||
{
|
||||
Command::new("explorer")
|
||||
app.shell()
|
||||
.command("explorer")
|
||||
.args(["/select,", path]) // The comma after select is not a typo
|
||||
.spawn()
|
||||
.map_err(|e| InvokeError::from_anyhow(e.into()))?;
|
||||
@ -334,7 +352,8 @@ fn show_in_folder(path: &str) -> Result<(), InvokeError> {
|
||||
|
||||
#[cfg(unix)]
|
||||
{
|
||||
Command::new("open")
|
||||
app.shell()
|
||||
.command("open")
|
||||
.args(["-R", path])
|
||||
.spawn()
|
||||
.map_err(|e| InvokeError::from_anyhow(e.into()))?;
|
||||
@ -389,6 +408,7 @@ fn main() -> Result<()> {
|
||||
write_app_settings_file,
|
||||
read_project_settings_file,
|
||||
write_project_settings_file,
|
||||
rename_project_directory,
|
||||
])
|
||||
.plugin(tauri_plugin_cli::init())
|
||||
.plugin(tauri_plugin_deep_link::init())
|
||||
@ -405,6 +425,7 @@ fn main() -> Result<()> {
|
||||
.build(),
|
||||
)
|
||||
.plugin(tauri_plugin_os::init())
|
||||
.plugin(tauri_plugin_persisted_scope::init())
|
||||
.plugin(tauri_plugin_process::init())
|
||||
.plugin(tauri_plugin_shell::init())
|
||||
.setup(|app| {
|
||||
|
@ -74,5 +74,5 @@
|
||||
}
|
||||
},
|
||||
"productName": "Zoo Modeling App",
|
||||
"version": "0.21.6"
|
||||
"version": "0.21.8"
|
||||
}
|
||||
|
@ -58,9 +58,8 @@ export function App() {
|
||||
const {
|
||||
app: { onboardingStatus },
|
||||
} = settings.context
|
||||
const { state, send } = useModelingContext()
|
||||
const { state } = useModelingContext()
|
||||
|
||||
useHotkeys('esc', () => send('Cancel'))
|
||||
useHotkeys('backspace', (e) => {
|
||||
e.preventDefault()
|
||||
})
|
||||
|
101
src/Toolbar.tsx
@ -12,6 +12,8 @@ import {
|
||||
} from 'components/NetworkHealthIndicator'
|
||||
import { useStore } from 'useStore'
|
||||
import { ActionButtonDropdown } from 'components/ActionButtonDropdown'
|
||||
import { useHotkeys } from 'react-hotkeys-hook'
|
||||
import Tooltip from 'components/Tooltip'
|
||||
|
||||
export const Toolbar = () => {
|
||||
const { commandBarSend } = useCommandsContext()
|
||||
@ -40,6 +42,56 @@ export const Toolbar = () => {
|
||||
const disableAllButtons =
|
||||
overallState !== NetworkHealthState.Ok || isExecuting || !isStreamReady
|
||||
|
||||
useHotkeys(
|
||||
'l',
|
||||
() =>
|
||||
state.matches('Sketch.Line tool')
|
||||
? send('CancelSketch')
|
||||
: send('Equip Line tool'),
|
||||
{ enabled: !disableAllButtons, scopes: ['sketch'] }
|
||||
)
|
||||
useHotkeys(
|
||||
'a',
|
||||
() =>
|
||||
state.matches('Sketch.Tangential arc to')
|
||||
? send('CancelSketch')
|
||||
: send('Equip tangential arc to'),
|
||||
{ enabled: !disableAllButtons, scopes: ['sketch'] }
|
||||
)
|
||||
useHotkeys(
|
||||
'r',
|
||||
() =>
|
||||
state.matches('Sketch.Rectangle tool')
|
||||
? send('CancelSketch')
|
||||
: send('Equip rectangle tool'),
|
||||
{ enabled: !disableAllButtons, scopes: ['sketch'] }
|
||||
)
|
||||
useHotkeys(
|
||||
's',
|
||||
() =>
|
||||
state.nextEvents.includes('Enter sketch') && pathId
|
||||
? send({ type: 'Enter sketch' })
|
||||
: send({ type: 'Enter sketch', data: { forceNewSketch: true } }),
|
||||
{ enabled: !disableAllButtons, scopes: ['modeling'] }
|
||||
)
|
||||
useHotkeys(
|
||||
'esc',
|
||||
() =>
|
||||
state.matches('Sketch.SketchIdle')
|
||||
? send('Cancel')
|
||||
: send('CancelSketch'),
|
||||
{ enabled: !disableAllButtons, scopes: ['sketch'] }
|
||||
)
|
||||
useHotkeys(
|
||||
'e',
|
||||
() =>
|
||||
commandBarSend({
|
||||
type: 'Find and select command',
|
||||
data: { name: 'Extrude', ownerMachine: 'modeling' },
|
||||
}),
|
||||
{ enabled: !disableAllButtons, scopes: ['modeling'] }
|
||||
)
|
||||
|
||||
function handleToolbarButtonsWheelEvent(ev: WheelEvent<HTMLSpanElement>) {
|
||||
const span = toolbarButtonsRef.current
|
||||
if (!span) {
|
||||
@ -77,6 +129,13 @@ export const Toolbar = () => {
|
||||
disabled={disableAllButtons}
|
||||
>
|
||||
<span data-testid="start-sketch">Start Sketch</span>
|
||||
<Tooltip
|
||||
delay={1250}
|
||||
position="bottom"
|
||||
className="!px-2 !text-xs"
|
||||
>
|
||||
Shortcut: S
|
||||
</Tooltip>
|
||||
</ActionButton>
|
||||
</li>
|
||||
)}
|
||||
@ -94,6 +153,13 @@ export const Toolbar = () => {
|
||||
disabled={disableAllButtons}
|
||||
>
|
||||
Edit Sketch
|
||||
<Tooltip
|
||||
delay={1250}
|
||||
position="bottom"
|
||||
className="!px-2 !text-xs"
|
||||
>
|
||||
Shortcut: S
|
||||
</Tooltip>
|
||||
</ActionButton>
|
||||
</li>
|
||||
)}
|
||||
@ -111,6 +177,13 @@ export const Toolbar = () => {
|
||||
disabled={disableAllButtons}
|
||||
>
|
||||
Exit Sketch
|
||||
<Tooltip
|
||||
delay={1250}
|
||||
position="bottom"
|
||||
className="!px-2 !text-xs"
|
||||
>
|
||||
Shortcut: Esc
|
||||
</Tooltip>
|
||||
</ActionButton>
|
||||
</li>
|
||||
)}
|
||||
@ -134,6 +207,13 @@ export const Toolbar = () => {
|
||||
disabled={disableAllButtons}
|
||||
>
|
||||
Line
|
||||
<Tooltip
|
||||
delay={1250}
|
||||
position="bottom"
|
||||
className="!px-2 !text-xs"
|
||||
>
|
||||
Shortcut: L
|
||||
</Tooltip>
|
||||
</ActionButton>
|
||||
</li>
|
||||
<li className="contents" key="tangential-arc-button">
|
||||
@ -158,6 +238,13 @@ export const Toolbar = () => {
|
||||
}
|
||||
>
|
||||
Tangential Arc
|
||||
<Tooltip
|
||||
delay={1250}
|
||||
position="bottom"
|
||||
className="!px-2 !text-xs"
|
||||
>
|
||||
Shortcut: A
|
||||
</Tooltip>
|
||||
</ActionButton>
|
||||
</li>
|
||||
<li className="contents" key="rectangle-button">
|
||||
@ -187,6 +274,13 @@ export const Toolbar = () => {
|
||||
}
|
||||
>
|
||||
Rectangle
|
||||
<Tooltip
|
||||
delay={1250}
|
||||
position="bottom"
|
||||
className="!px-2 !text-xs"
|
||||
>
|
||||
Shortcut: R
|
||||
</Tooltip>
|
||||
</ActionButton>
|
||||
</li>
|
||||
</>
|
||||
@ -264,6 +358,13 @@ export const Toolbar = () => {
|
||||
}}
|
||||
>
|
||||
Extrude
|
||||
<Tooltip
|
||||
delay={1250}
|
||||
position="bottom"
|
||||
className="!px-2 !text-xs"
|
||||
>
|
||||
Shortcut: E
|
||||
</Tooltip>
|
||||
</ActionButton>
|
||||
</li>
|
||||
)}
|
||||
|
@ -20,6 +20,7 @@ import {
|
||||
EngineCommand,
|
||||
Subscription,
|
||||
EngineCommandManager,
|
||||
UnreliableSubscription,
|
||||
} from 'lang/std/engineConnection'
|
||||
import { uuidv4 } from 'lib/utils'
|
||||
import { deg2Rad } from 'lib/utils2d'
|
||||
@ -232,9 +233,19 @@ export class CameraControls {
|
||||
this.update()
|
||||
this._usePerspectiveCamera()
|
||||
|
||||
const cb: Subscription<
|
||||
'default_camera_zoom' | 'camera_drag_end' | 'default_camera_get_settings'
|
||||
>['callback'] = ({ data, type }) => {
|
||||
type CallBackParam = Parameters<
|
||||
(
|
||||
| Subscription<
|
||||
| 'default_camera_zoom'
|
||||
| 'camera_drag_end'
|
||||
| 'default_camera_get_settings'
|
||||
| 'zoom_to_fit'
|
||||
>
|
||||
| UnreliableSubscription<'camera_drag_move'>
|
||||
)['callback']
|
||||
>[0]
|
||||
|
||||
const cb = ({ data, type }: CallBackParam) => {
|
||||
const camSettings = data.settings
|
||||
this.camera.position.set(
|
||||
camSettings.pos.x,
|
||||
@ -246,7 +257,13 @@ export class CameraControls {
|
||||
camSettings.center.y,
|
||||
camSettings.center.z
|
||||
)
|
||||
this.camera.up.set(camSettings.up.x, camSettings.up.y, camSettings.up.z)
|
||||
const quat = new Quaternion(
|
||||
camSettings.orientation.x,
|
||||
camSettings.orientation.y,
|
||||
camSettings.orientation.z,
|
||||
camSettings.orientation.w
|
||||
).invert()
|
||||
this.camera.up.copy(new Vector3(0, 1, 0).applyQuaternion(quat))
|
||||
if (this.camera instanceof PerspectiveCamera && camSettings.ortho) {
|
||||
this.useOrthographicCamera()
|
||||
}
|
||||
@ -287,6 +304,14 @@ export class CameraControls {
|
||||
event: 'default_camera_get_settings',
|
||||
callback: cb,
|
||||
})
|
||||
this.engineCommandManager.subscribeTo({
|
||||
event: 'zoom_to_fit',
|
||||
callback: cb,
|
||||
})
|
||||
this.engineCommandManager.subscribeToUnreliable({
|
||||
event: 'camera_drag_move',
|
||||
callback: cb,
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -69,6 +69,7 @@ import {
|
||||
tangentialArcToSegment,
|
||||
} from './segments'
|
||||
import {
|
||||
addCallExpressionsToPipe,
|
||||
addCloseToPipe,
|
||||
addNewSketchLn,
|
||||
changeSketchArguments,
|
||||
@ -536,10 +537,34 @@ export class SceneEntities {
|
||||
|
||||
let modifiedAst
|
||||
if (profileStart) {
|
||||
modifiedAst = addCloseToPipe({
|
||||
const lastSegment = sketchGroup.value.slice(-1)[0]
|
||||
modifiedAst = addCallExpressionsToPipe({
|
||||
node: kclManager.ast,
|
||||
programMemory: kclManager.programMemory,
|
||||
pathToNode: sketchPathToNode,
|
||||
expressions: [
|
||||
createCallExpressionStdLib(
|
||||
lastSegment.type === 'TangentialArcTo'
|
||||
? 'tangentialArcTo'
|
||||
: 'lineTo',
|
||||
[
|
||||
createArrayExpression([
|
||||
createCallExpressionStdLib('profileStartX', [
|
||||
createPipeSubstitution(),
|
||||
]),
|
||||
createCallExpressionStdLib('profileStartY', [
|
||||
createPipeSubstitution(),
|
||||
]),
|
||||
]),
|
||||
createPipeSubstitution(),
|
||||
]
|
||||
),
|
||||
],
|
||||
})
|
||||
modifiedAst = addCloseToPipe({
|
||||
node: modifiedAst,
|
||||
programMemory: kclManager.programMemory,
|
||||
pathToNode: sketchPathToNode,
|
||||
})
|
||||
} else if (intersection2d) {
|
||||
const lastSegment = sketchGroup.value.slice(-1)[0]
|
||||
@ -560,13 +585,17 @@ export class SceneEntities {
|
||||
}
|
||||
|
||||
await kclManager.executeAstMock(modifiedAst)
|
||||
this.setUpDraftSegment(
|
||||
sketchPathToNode,
|
||||
forward,
|
||||
up,
|
||||
origin,
|
||||
segmentName
|
||||
)
|
||||
if (profileStart) {
|
||||
sceneInfra.modelingSend({ type: 'CancelSketch' })
|
||||
} else {
|
||||
this.setUpDraftSegment(
|
||||
sketchPathToNode,
|
||||
forward,
|
||||
up,
|
||||
origin,
|
||||
segmentName
|
||||
)
|
||||
}
|
||||
},
|
||||
onMove: (args) => {
|
||||
this.onDragSegment({
|
||||
@ -1396,7 +1425,7 @@ export class SceneEntities {
|
||||
zAxis = posNorm ? [1, 0, 0] : [-1, 0, 0]
|
||||
yAxis = [0, 0, 1]
|
||||
} else if (type === XZ_PLANE) {
|
||||
planeString = posNorm ? 'XZ' : '-XZ'
|
||||
planeString = posNorm ? '-XZ' : 'XZ'
|
||||
zAxis = posNorm ? [0, 1, 0] : [0, -1, 0]
|
||||
yAxis = [0, 0, 1]
|
||||
}
|
||||
|