tag as top level part 2 (#2773)

* updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)

* updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* fmt

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* unit tests pass

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* playwright

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* format

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* format

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* more literals gone

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* fixes

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* remove console log

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* fixes

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* remove only

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* fix some recast shit

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* last

Signed-off-by: Jess Frazelle <github@jessfraz.com>

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
This commit is contained in:
Jess Frazelle
2024-06-24 22:39:04 -07:00
committed by GitHub
parent ad5bfa1a29
commit da6cd5cf9f
44 changed files with 720 additions and 536 deletions

View File

@ -17,11 +17,8 @@ angleToMatchLengthX(segment_name: TagIdentifier, to: number, sketch_group: Sketc
```js ```js
const sketch001 = startSketchOn('XZ') const sketch001 = startSketchOn('XZ')
|> startProfileAt([0, 0], %) |> startProfileAt([0, 0], %)
|> line([2, 5], %, 'seg01') |> line([2, 5], %, $seg01)
|> angledLineToX([ |> angledLineToX([-angleToMatchLengthX(seg01, 7, %), 10], %)
-angleToMatchLengthX('seg01', 7, %),
10
], %)
|> close(%) |> close(%)
const extrusion = extrude(5, sketch001) const extrusion = extrude(5, sketch001)

View File

@ -17,9 +17,9 @@ angleToMatchLengthY(segment_name: TagIdentifier, to: number, sketch_group: Sketc
```js ```js
const sketch001 = startSketchOn('XZ') const sketch001 = startSketchOn('XZ')
|> startProfileAt([0, 0], %) |> startProfileAt([0, 0], %)
|> line([1, 2], %, 'seg01') |> line([1, 2], %, $seg01)
|> angledLine({ |> angledLine({
angle: angleToMatchLengthY('seg01', 15, %), angle: angleToMatchLengthY(seg01, 15, %),
length: 5 length: 5
}, %) }, %)
|> yLineTo(0, %) |> yLineTo(0, %)

View File

@ -17,10 +17,10 @@ angledLineOfXLength(data: AngledLineData, sketch_group: SketchGroup, tag?: TagDe
```js ```js
const sketch001 = startSketchOn('XZ') const sketch001 = startSketchOn('XZ')
|> startProfileAt([0, 0], %) |> startProfileAt([0, 0], %)
|> angledLineOfXLength({ angle: 45, length: 10 }, %, "edge1") |> angledLineOfXLength({ angle: 45, length: 10 }, %, $edge1)
|> angledLineOfXLength({ angle: -15, length: 20 }, %, "edge2") |> angledLineOfXLength({ angle: -15, length: 20 }, %, $edge2)
|> line([0, -5], %) |> line([0, -5], %)
|> close(%, "edge3") |> close(%, $edge3)
const extrusion = extrude(10, sketch001) const extrusion = extrude(10, sketch001)
``` ```

View File

@ -18,7 +18,7 @@ angledLineThatIntersects(data: AngledLineThatIntersectsData, sketch_group: Sketc
const exampleSketch = startSketchOn('XZ') const exampleSketch = startSketchOn('XZ')
|> startProfileAt([0, 0], %) |> startProfileAt([0, 0], %)
|> lineTo([5, 10], %) |> lineTo([5, 10], %)
|> lineTo([-10, 10], %, "lineToIntersect") |> lineTo([-10, 10], %, $lineToIntersect)
|> lineTo([0, 20], %) |> lineTo([0, 20], %)
|> angledLineThatIntersects({ |> angledLineThatIntersects({
angle: 80, angle: 80,

View File

@ -22,19 +22,19 @@ const chamferLength = 2
const mountingPlateSketch = startSketchOn("XY") const mountingPlateSketch = startSketchOn("XY")
|> startProfileAt([-width / 2, -length / 2], %) |> startProfileAt([-width / 2, -length / 2], %)
|> lineTo([width / 2, -length / 2], %, 'edge1') |> lineTo([width / 2, -length / 2], %, $edge1)
|> lineTo([width / 2, length / 2], %, 'edge2') |> lineTo([width / 2, length / 2], %, $edge2)
|> lineTo([-width / 2, length / 2], %, 'edge3') |> lineTo([-width / 2, length / 2], %, $edge3)
|> close(%, 'edge4') |> close(%, $edge4)
const mountingPlate = extrude(thickness, mountingPlateSketch) const mountingPlate = extrude(thickness, mountingPlateSketch)
|> chamfer({ |> chamfer({
length: chamferLength, length: chamferLength,
tags: [ tags: [
getNextAdjacentEdge('edge1', %), getNextAdjacentEdge(edge1, %),
getNextAdjacentEdge('edge2', %), getNextAdjacentEdge(edge2, %),
getNextAdjacentEdge('edge3', %), getNextAdjacentEdge(edge3, %),
getNextAdjacentEdge('edge4', %) getNextAdjacentEdge(edge4, %)
] ]
}, %) }, %)
``` ```

View File

@ -9,7 +9,7 @@ Sketch a circle.
```js ```js
circle(center: [number], radius: number, tag?: TagDeclarator, sketch_surface_or_group: SketchSurfaceOrGroup) -> SketchGroup circle(center: [number], radius: number, sketch_surface_or_group: SketchSurfaceOrGroup, tag?: TagDeclarator) -> SketchGroup
``` ```
### Examples ### Examples
@ -41,14 +41,6 @@ const example = extrude(5, exampleSketch)
* `center`: `[number]` (REQUIRED) * `center`: `[number]` (REQUIRED)
* `radius`: `number` (REQUIRED) * `radius`: `number` (REQUIRED)
* `tag`: `TagDeclarator` (OPTIONAL)
```js
{
end: number,
start: number,
value: string,
}
```
* `sketch_surface_or_group`: `SketchSurfaceOrGroup` - A sketch surface or a sketch group. (REQUIRED) * `sketch_surface_or_group`: `SketchSurfaceOrGroup` - A sketch surface or a sketch group. (REQUIRED)
```js ```js
{ {
@ -510,6 +502,14 @@ const example = extrude(5, exampleSketch)
}], }],
} }
``` ```
* `tag`: `TagDeclarator` (OPTIONAL)
```js
{
end: number,
start: number,
value: string,
}
```
### Returns ### Returns

View File

@ -22,19 +22,19 @@ const filletRadius = 2
const mountingPlateSketch = startSketchOn("XY") const mountingPlateSketch = startSketchOn("XY")
|> startProfileAt([-width / 2, -length / 2], %) |> startProfileAt([-width / 2, -length / 2], %)
|> lineTo([width / 2, -length / 2], %, 'edge1') |> lineTo([width / 2, -length / 2], %, $edge1)
|> lineTo([width / 2, length / 2], %, 'edge2') |> lineTo([width / 2, length / 2], %, $edge2)
|> lineTo([-width / 2, length / 2], %, 'edge3') |> lineTo([-width / 2, length / 2], %, $edge3)
|> close(%, 'edge4') |> close(%, $edge4)
const mountingPlate = extrude(thickness, mountingPlateSketch) const mountingPlate = extrude(thickness, mountingPlateSketch)
|> fillet({ |> fillet({
radius: filletRadius, radius: filletRadius,
tags: [ tags: [
getNextAdjacentEdge('edge1', %), getNextAdjacentEdge(edge1, %),
getNextAdjacentEdge('edge2', %), getNextAdjacentEdge(edge2, %),
getNextAdjacentEdge('edge3', %), getNextAdjacentEdge(edge3, %),
getNextAdjacentEdge('edge4', %) getNextAdjacentEdge(edge4, %)
] ]
}, %) }, %)
``` ```

View File

@ -17,7 +17,7 @@ getEdge(tag: TagIdentifier, extrude_group: ExtrudeGroup) -> Uuid
```js ```js
const box = startSketchOn('XZ') const box = startSketchOn('XZ')
|> startProfileAt([0, 0], %) |> startProfileAt([0, 0], %)
|> line([0, 10], %, 'revolveAxis') |> line([0, 10], %, $revolveAxis)
|> line([10, 0], %) |> line([10, 0], %)
|> line([0, -10], %) |> line([0, -10], %)
|> close(%) |> close(%)
@ -30,7 +30,7 @@ const revolution = startSketchOn(box, "revolveAxis")
|> line([0, -10], %) |> line([0, -10], %)
|> close(%) |> close(%)
|> revolve({ |> revolve({
axis: getEdge('revolveAxis', box), axis: getEdge(revolveAxis, box),
angle: 90 angle: 90
}, %) }, %)
``` ```

View File

@ -21,15 +21,13 @@ const exampleSketch = startSketchOn('XZ')
|> angledLine({ angle: 60, length: 10 }, %) |> angledLine({ angle: 60, length: 10 }, %)
|> angledLine({ angle: 120, length: 10 }, %) |> angledLine({ angle: 120, length: 10 }, %)
|> line([-10, 0], %) |> line([-10, 0], %)
|> angledLine({ angle: 240, length: 10 }, %, 'referenceEdge') |> angledLine({ angle: 240, length: 10 }, %, $referenceEdge)
|> close(%) |> close(%)
const example = extrude(5, exampleSketch) const example = extrude(5, exampleSketch)
|> fillet({ |> fillet({
radius: 3, radius: 3,
tags: [ tags: [getNextAdjacentEdge(referenceEdge, %)]
getNextAdjacentEdge("referenceEdge", %)
]
}, %) }, %)
``` ```

View File

@ -21,13 +21,13 @@ const exampleSketch = startSketchOn('XZ')
|> angledLine({ angle: 60, length: 10 }, %) |> angledLine({ angle: 60, length: 10 }, %)
|> angledLine({ angle: 120, length: 10 }, %) |> angledLine({ angle: 120, length: 10 }, %)
|> line([-10, 0], %) |> line([-10, 0], %)
|> angledLine({ angle: 240, length: 10 }, %, 'referenceEdge') |> angledLine({ angle: 240, length: 10 }, %, $referenceEdge)
|> close(%) |> close(%)
const example = extrude(5, exampleSketch) const example = extrude(5, exampleSketch)
|> fillet({ |> fillet({
radius: 3, radius: 3,
tags: [getOppositeEdge("referenceEdge", %)] tags: [getOppositeEdge(referenceEdge, %)]
}, %) }, %)
``` ```

View File

@ -21,14 +21,14 @@ const exampleSketch = startSketchOn('XZ')
|> angledLine({ angle: 60, length: 10 }, %) |> angledLine({ angle: 60, length: 10 }, %)
|> angledLine({ angle: 120, length: 10 }, %) |> angledLine({ angle: 120, length: 10 }, %)
|> line([-10, 0], %) |> line([-10, 0], %)
|> angledLine({ angle: 240, length: 10 }, %, 'referenceEdge') |> angledLine({ angle: 240, length: 10 }, %, $referenceEdge)
|> close(%) |> close(%)
const example = extrude(5, exampleSketch) const example = extrude(5, exampleSketch)
|> fillet({ |> fillet({
radius: 3, radius: 3,
tags: [ tags: [
getPreviousAdjacentEdge("referenceEdge", %) getPreviousAdjacentEdge(referenceEdge, %)
] ]
}, %) }, %)
``` ```

View File

@ -17,9 +17,9 @@ profileStart(sketch_group: SketchGroup) -> [number]
```js ```js
const sketch001 = startSketchOn('XY') const sketch001 = startSketchOn('XY')
|> startProfileAt([5, 2], %) |> startProfileAt([5, 2], %)
|> angledLine({ angle: 120, length: 50 }, %, 'seg01') |> angledLine({ angle: 120, length: 50 }, %, $seg01)
|> angledLine({ |> angledLine({
angle: segAng('seg01', %) + 120, angle: segAng(seg01, %) + 120,
length: 50 length: 50
}, %) }, %)
|> lineTo(profileStart(%), %) |> lineTo(profileStart(%), %)

View File

@ -99,7 +99,7 @@ const box = startSketchOn('XY')
|> startProfileAt([0, 0], %) |> startProfileAt([0, 0], %)
|> line([0, 20], %) |> line([0, 20], %)
|> line([20, 0], %) |> line([20, 0], %)
|> line([0, -20], %, 'revolveAxis') |> line([0, -20], %, $revolveAxis)
|> close(%) |> close(%)
|> extrude(20, %) |> extrude(20, %)
@ -107,7 +107,7 @@ const sketch001 = startSketchOn(box, "END")
|> circle([10, 10], 4, %) |> circle([10, 10], 4, %)
|> revolve({ |> revolve({
angle: 90, angle: 90,
axis: getOppositeEdge('revolveAxis', box) axis: getOppositeEdge(revolveAxis, box)
}, %) }, %)
``` ```

View File

@ -18,11 +18,11 @@ segAng(segment_name: TagIdentifier, sketch_group: SketchGroup) -> number
const exampleSketch = startSketchOn('XZ') const exampleSketch = startSketchOn('XZ')
|> startProfileAt([0, 0], %) |> startProfileAt([0, 0], %)
|> line([10, 0], %) |> line([10, 0], %)
|> line([5, 10], %, 'seg01') |> line([5, 10], %, $seg01)
|> line([-10, 0], %) |> line([-10, 0], %)
|> angledLine([segAng('seg01', %), 10], %) |> angledLine([segAng(seg01, %), 10], %)
|> line([-10, 0], %) |> line([-10, 0], %)
|> angledLine([segAng('seg01', %), -15], %) |> angledLine([segAng(seg01, %), -15], %)
|> close(%) |> close(%)
const example = extrude(4, exampleSketch) const example = extrude(4, exampleSketch)

View File

@ -17,9 +17,9 @@ segEndX(segment_name: TagIdentifier, sketch_group: SketchGroup) -> number
```js ```js
const exampleSketch = startSketchOn('XZ') const exampleSketch = startSketchOn('XZ')
|> startProfileAt([0, 0], %) |> startProfileAt([0, 0], %)
|> line([20, 0], %, "thing") |> line([20, 0], %, $thing)
|> line([0, 5], %) |> line([0, 5], %)
|> line([segEndX("thing", %), 0], %) |> line([segEndX(thing, %), 0], %)
|> line([-20, 10], %) |> line([-20, 10], %)
|> close(%) |> close(%)

View File

@ -18,9 +18,9 @@ segEndY(segment_name: TagIdentifier, sketch_group: SketchGroup) -> number
const exampleSketch = startSketchOn('XZ') const exampleSketch = startSketchOn('XZ')
|> startProfileAt([0, 0], %) |> startProfileAt([0, 0], %)
|> line([20, 0], %) |> line([20, 0], %)
|> line([0, 3], %, "thing") |> line([0, 3], %, $thing)
|> line([-10, 0], %) |> line([-10, 0], %)
|> line([0, segEndY("thing", %)], %) |> line([0, segEndY(thing, %)], %)
|> line([-10, 0], %) |> line([-10, 0], %)
|> close(%) |> close(%)

View File

@ -17,12 +17,9 @@ segLen(segment_name: TagIdentifier, sketch_group: SketchGroup) -> number
```js ```js
const exampleSketch = startSketchOn("XZ") const exampleSketch = startSketchOn("XZ")
|> startProfileAt([0, 0], %) |> startProfileAt([0, 0], %)
|> angledLine({ angle: 60, length: 10 }, %, "thing") |> angledLine({ angle: 60, length: 10 }, %, $thing)
|> tangentialArc({ offset: -120, radius: 5 }, %) |> tangentialArc({ offset: -120, radius: 5 }, %)
|> angledLine({ |> angledLine({ angle: -60, length: segLen(thing, %) }, %)
angle: -60,
length: segLen("thing", %)
}, %)
|> close(%) |> close(%)
const example = extrude(5, exampleSketch) const example = extrude(5, exampleSketch)

View File

@ -49,7 +49,7 @@ const example003 = extrude(5, exampleSketch003)
const exampleSketch = startSketchOn("XY") const exampleSketch = startSketchOn("XY")
|> startProfileAt([0, 0], %) |> startProfileAt([0, 0], %)
|> line([10, 0], %) |> line([10, 0], %)
|> line([0, 10], %, 'sketchingFace') |> line([0, 10], %, $sketchingFace)
|> line([-10, 0], %) |> line([-10, 0], %)
|> close(%) |> close(%)
@ -60,7 +60,7 @@ const exampleSketch002 = startSketchOn(example, 'sketchingFace')
|> line([8, 0], %) |> line([8, 0], %)
|> line([0, 8], %) |> line([0, 8], %)
|> line([-8, 0], %) |> line([-8, 0], %)
|> close(%, 'sketchingFace002') |> close(%, $sketchingFace002)
const example002 = extrude(10, exampleSketch002) const example002 = extrude(10, exampleSketch002)

View File

@ -2127,7 +2127,7 @@
"unpublished": false, "unpublished": false,
"deprecated": false, "deprecated": false,
"examples": [ "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([-angleToMatchLengthX(seg01, 7, %), 10], %)\n |> close(%)\n\nconst extrusion = extrude(5, sketch001)"
] ]
}, },
{ {
@ -4192,7 +4192,7 @@
"unpublished": false, "unpublished": false,
"deprecated": false, "deprecated": false,
"examples": [ "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)"
] ]
}, },
{ {
@ -12332,7 +12332,7 @@
"unpublished": false, "unpublished": false,
"deprecated": false, "deprecated": false,
"examples": [ "examples": [
"const sketch001 = startSketchOn('XZ')\n |> startProfileAt([0, 0], %)\n |> angledLineOfXLength({ angle: 45, length: 10 }, %, \"edge1\")\n |> angledLineOfXLength({ angle: -15, length: 20 }, %, \"edge2\")\n |> line([0, -5], %)\n |> close(%, \"edge3\")\n\nconst extrusion = extrude(10, sketch001)" "const sketch001 = startSketchOn('XZ')\n |> startProfileAt([0, 0], %)\n |> angledLineOfXLength({ angle: 45, length: 10 }, %, $edge1)\n |> angledLineOfXLength({ angle: -15, length: 20 }, %, $edge2)\n |> line([0, -5], %)\n |> close(%, $edge3)\n\nconst extrusion = extrude(10, sketch001)"
] ]
}, },
{ {
@ -20494,7 +20494,7 @@
"unpublished": false, "unpublished": false,
"deprecated": false, "deprecated": false,
"examples": [ "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)"
] ]
}, },
{ {
@ -40165,7 +40165,7 @@
"unpublished": false, "unpublished": false,
"deprecated": false, "deprecated": false,
"examples": [ "examples": [
"const width = 20\nconst length = 10\nconst thickness = 1\nconst chamferLength = 2\n\nconst mountingPlateSketch = startSketchOn(\"XY\")\n |> startProfileAt([-width / 2, -length / 2], %)\n |> lineTo([width / 2, -length / 2], %, 'edge1')\n |> lineTo([width / 2, length / 2], %, 'edge2')\n |> lineTo([-width / 2, length / 2], %, 'edge3')\n |> close(%, 'edge4')\n\nconst mountingPlate = extrude(thickness, mountingPlateSketch)\n |> chamfer({\n length: chamferLength,\n tags: [\n getNextAdjacentEdge('edge1', %),\n getNextAdjacentEdge('edge2', %),\n getNextAdjacentEdge('edge3', %),\n getNextAdjacentEdge('edge4', %)\n ]\n }, %)" "const width = 20\nconst length = 10\nconst thickness = 1\nconst chamferLength = 2\n\nconst mountingPlateSketch = startSketchOn(\"XY\")\n |> startProfileAt([-width / 2, -length / 2], %)\n |> lineTo([width / 2, -length / 2], %, $edge1)\n |> lineTo([width / 2, length / 2], %, $edge2)\n |> lineTo([-width / 2, length / 2], %, $edge3)\n |> close(%, $edge4)\n\nconst mountingPlate = extrude(thickness, mountingPlateSketch)\n |> chamfer({\n length: chamferLength,\n tags: [\n getNextAdjacentEdge(edge1, %),\n getNextAdjacentEdge(edge2, %),\n getNextAdjacentEdge(edge3, %),\n getNextAdjacentEdge(edge4, %)\n ]\n }, %)"
] ]
}, },
{ {
@ -40197,35 +40197,6 @@
}, },
"required": true "required": true
}, },
{
"name": "tag",
"type": "TagDeclarator",
"schema": {
"type": "object",
"required": [
"end",
"start",
"value"
],
"properties": {
"end": {
"type": "integer",
"format": "uint",
"minimum": 0.0
},
"start": {
"type": "integer",
"format": "uint",
"minimum": 0.0
},
"value": {
"type": "string"
}
},
"nullable": true
},
"required": false
},
{ {
"name": "sketch_surface_or_group", "name": "sketch_surface_or_group",
"type": "SketchSurfaceOrGroup", "type": "SketchSurfaceOrGroup",
@ -42811,6 +42782,35 @@
] ]
}, },
"required": true "required": true
},
{
"name": "tag",
"type": "TagDeclarator",
"schema": {
"type": "object",
"required": [
"end",
"start",
"value"
],
"properties": {
"end": {
"type": "integer",
"format": "uint",
"minimum": 0.0
},
"start": {
"type": "integer",
"format": "uint",
"minimum": 0.0
},
"value": {
"type": "string"
}
},
"nullable": true
},
"required": false
} }
], ],
"returnValue": { "returnValue": {
@ -58390,7 +58390,7 @@
"unpublished": false, "unpublished": false,
"deprecated": false, "deprecated": false,
"examples": [ "examples": [
"const width = 20\nconst length = 10\nconst thickness = 1\nconst filletRadius = 2\n\nconst mountingPlateSketch = startSketchOn(\"XY\")\n |> startProfileAt([-width / 2, -length / 2], %)\n |> lineTo([width / 2, -length / 2], %, 'edge1')\n |> lineTo([width / 2, length / 2], %, 'edge2')\n |> lineTo([-width / 2, length / 2], %, 'edge3')\n |> close(%, 'edge4')\n\nconst mountingPlate = extrude(thickness, mountingPlateSketch)\n |> fillet({\n radius: filletRadius,\n tags: [\n getNextAdjacentEdge('edge1', %),\n getNextAdjacentEdge('edge2', %),\n getNextAdjacentEdge('edge3', %),\n getNextAdjacentEdge('edge4', %)\n ]\n }, %)" "const width = 20\nconst length = 10\nconst thickness = 1\nconst filletRadius = 2\n\nconst mountingPlateSketch = startSketchOn(\"XY\")\n |> startProfileAt([-width / 2, -length / 2], %)\n |> lineTo([width / 2, -length / 2], %, $edge1)\n |> lineTo([width / 2, length / 2], %, $edge2)\n |> lineTo([-width / 2, length / 2], %, $edge3)\n |> close(%, $edge4)\n\nconst mountingPlate = extrude(thickness, mountingPlateSketch)\n |> fillet({\n radius: filletRadius,\n tags: [\n getNextAdjacentEdge(edge1, %),\n getNextAdjacentEdge(edge2, %),\n getNextAdjacentEdge(edge3, %),\n getNextAdjacentEdge(edge4, %)\n ]\n }, %)"
] ]
}, },
{ {
@ -60071,7 +60071,7 @@
"unpublished": false, "unpublished": false,
"deprecated": false, "deprecated": false,
"examples": [ "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(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 }, %)" "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 }, %)"
] ]
}, },
{ {
@ -61719,7 +61719,7 @@
"unpublished": false, "unpublished": false,
"deprecated": false, "deprecated": false,
"examples": [ "examples": [
"const exampleSketch = startSketchOn('XZ')\n |> startProfileAt([0, 0], %)\n |> line([10, 0], %)\n |> angledLine({ angle: 60, length: 10 }, %)\n |> angledLine({ angle: 120, length: 10 }, %)\n |> line([-10, 0], %)\n |> angledLine({ angle: 240, length: 10 }, %, 'referenceEdge')\n |> close(%)\n\nconst example = extrude(5, exampleSketch)\n |> fillet({\n radius: 3,\n tags: [\n getNextAdjacentEdge(\"referenceEdge\", %)\n ]\n }, %)" "const exampleSketch = startSketchOn('XZ')\n |> startProfileAt([0, 0], %)\n |> line([10, 0], %)\n |> angledLine({ angle: 60, length: 10 }, %)\n |> angledLine({ angle: 120, length: 10 }, %)\n |> line([-10, 0], %)\n |> angledLine({ angle: 240, length: 10 }, %, $referenceEdge)\n |> close(%)\n\nconst example = extrude(5, exampleSketch)\n |> fillet({\n radius: 3,\n tags: [getNextAdjacentEdge(referenceEdge, %)]\n }, %)"
] ]
}, },
{ {
@ -63367,7 +63367,7 @@
"unpublished": false, "unpublished": false,
"deprecated": false, "deprecated": false,
"examples": [ "examples": [
"const exampleSketch = startSketchOn('XZ')\n |> startProfileAt([0, 0], %)\n |> line([10, 0], %)\n |> angledLine({ angle: 60, length: 10 }, %)\n |> angledLine({ angle: 120, length: 10 }, %)\n |> line([-10, 0], %)\n |> angledLine({ angle: 240, length: 10 }, %, 'referenceEdge')\n |> close(%)\n\nconst example = extrude(5, exampleSketch)\n |> fillet({\n radius: 3,\n tags: [getOppositeEdge(\"referenceEdge\", %)]\n }, %)" "const exampleSketch = startSketchOn('XZ')\n |> startProfileAt([0, 0], %)\n |> line([10, 0], %)\n |> angledLine({ angle: 60, length: 10 }, %)\n |> angledLine({ angle: 120, length: 10 }, %)\n |> line([-10, 0], %)\n |> angledLine({ angle: 240, length: 10 }, %, $referenceEdge)\n |> close(%)\n\nconst example = extrude(5, exampleSketch)\n |> fillet({\n radius: 3,\n tags: [getOppositeEdge(referenceEdge, %)]\n }, %)"
] ]
}, },
{ {
@ -65015,7 +65015,7 @@
"unpublished": false, "unpublished": false,
"deprecated": false, "deprecated": false,
"examples": [ "examples": [
"const exampleSketch = startSketchOn('XZ')\n |> startProfileAt([0, 0], %)\n |> line([10, 0], %)\n |> angledLine({ angle: 60, length: 10 }, %)\n |> angledLine({ angle: 120, length: 10 }, %)\n |> line([-10, 0], %)\n |> angledLine({ angle: 240, length: 10 }, %, 'referenceEdge')\n |> close(%)\n\nconst example = extrude(5, exampleSketch)\n |> fillet({\n radius: 3,\n tags: [\n getPreviousAdjacentEdge(\"referenceEdge\", %)\n ]\n }, %)" "const exampleSketch = startSketchOn('XZ')\n |> startProfileAt([0, 0], %)\n |> line([10, 0], %)\n |> angledLine({ angle: 60, length: 10 }, %)\n |> angledLine({ angle: 120, length: 10 }, %)\n |> line([-10, 0], %)\n |> angledLine({ angle: 240, length: 10 }, %, $referenceEdge)\n |> close(%)\n\nconst example = extrude(5, exampleSketch)\n |> fillet({\n radius: 3,\n tags: [\n getPreviousAdjacentEdge(referenceEdge, %)\n ]\n }, %)"
] ]
}, },
{ {
@ -108585,7 +108585,7 @@
"unpublished": false, "unpublished": false,
"deprecated": false, "deprecated": false,
"examples": [ "examples": [
"const sketch001 = startSketchOn('XY')\n |> startProfileAt([5, 2], %)\n |> angledLine({ angle: 120, length: 50 }, %, 'seg01')\n |> angledLine({\n angle: segAng('seg01', %) + 120,\n length: 50\n }, %)\n |> lineTo(profileStart(%), %)\n |> close(%)\n |> extrude(20, %)" "const sketch001 = startSketchOn('XY')\n |> startProfileAt([5, 2], %)\n |> angledLine({ angle: 120, length: 50 }, %, $seg01)\n |> angledLine({\n angle: segAng(seg01, %) + 120,\n length: 50\n }, %)\n |> lineTo(profileStart(%), %)\n |> close(%)\n |> extrude(20, %)"
] ]
}, },
{ {
@ -116372,7 +116372,7 @@
"const part001 = startSketchOn('XY')\n |> startProfileAt([4, 12], %)\n |> line([2, 0], %)\n |> line([0, -6], %)\n |> line([4, -6], %)\n |> line([0, -6], %)\n |> line([-3.75, -4.5], %)\n |> line([0, -5.5], %)\n |> line([-2, 0], %)\n |> close(%)\n |> revolve({ axis: 'y', angle: 180 }, %)", "const part001 = startSketchOn('XY')\n |> startProfileAt([4, 12], %)\n |> line([2, 0], %)\n |> line([0, -6], %)\n |> line([4, -6], %)\n |> line([0, -6], %)\n |> line([-3.75, -4.5], %)\n |> line([0, -5.5], %)\n |> line([-2, 0], %)\n |> close(%)\n |> revolve({ axis: 'y', angle: 180 }, %)",
"const part001 = startSketchOn('XY')\n |> startProfileAt([4, 12], %)\n |> line([2, 0], %)\n |> line([0, -6], %)\n |> line([4, -6], %)\n |> line([0, -6], %)\n |> line([-3.75, -4.5], %)\n |> line([0, -5.5], %)\n |> line([-2, 0], %)\n |> close(%)\n |> revolve({ axis: 'y', angle: 180 }, %)\nconst part002 = startSketchOn(part001, 'end')\n |> startProfileAt([4.5, -5], %)\n |> line([0, 5], %)\n |> line([5, 0], %)\n |> line([0, -5], %)\n |> close(%)\n |> extrude(5, %)", "const part001 = startSketchOn('XY')\n |> startProfileAt([4, 12], %)\n |> line([2, 0], %)\n |> line([0, -6], %)\n |> line([4, -6], %)\n |> line([0, -6], %)\n |> line([-3.75, -4.5], %)\n |> line([0, -5.5], %)\n |> line([-2, 0], %)\n |> close(%)\n |> revolve({ axis: 'y', angle: 180 }, %)\nconst part002 = startSketchOn(part001, 'end')\n |> startProfileAt([4.5, -5], %)\n |> line([0, 5], %)\n |> line([5, 0], %)\n |> line([0, -5], %)\n |> close(%)\n |> extrude(5, %)",
"const box = startSketchOn('XY')\n |> startProfileAt([0, 0], %)\n |> line([0, 20], %)\n |> line([20, 0], %)\n |> line([0, -20], %)\n |> close(%)\n |> extrude(20, %)\n\nconst sketch001 = startSketchOn(box, \"END\")\n |> circle([10, 10], 4, %)\n |> revolve({ angle: -90, axis: 'y' }, %)", "const box = startSketchOn('XY')\n |> startProfileAt([0, 0], %)\n |> line([0, 20], %)\n |> line([20, 0], %)\n |> line([0, -20], %)\n |> close(%)\n |> extrude(20, %)\n\nconst sketch001 = startSketchOn(box, \"END\")\n |> circle([10, 10], 4, %)\n |> revolve({ angle: -90, axis: 'y' }, %)",
"const box = startSketchOn('XY')\n |> startProfileAt([0, 0], %)\n |> line([0, 20], %)\n |> line([20, 0], %)\n |> line([0, -20], %, 'revolveAxis')\n |> close(%)\n |> extrude(20, %)\n\nconst sketch001 = startSketchOn(box, \"END\")\n |> circle([10, 10], 4, %)\n |> revolve({\n angle: 90,\n axis: getOppositeEdge('revolveAxis', box)\n }, %)", "const box = startSketchOn('XY')\n |> startProfileAt([0, 0], %)\n |> line([0, 20], %)\n |> line([20, 0], %)\n |> line([0, -20], %, $revolveAxis)\n |> close(%)\n |> extrude(20, %)\n\nconst sketch001 = startSketchOn(box, \"END\")\n |> circle([10, 10], 4, %)\n |> revolve({\n angle: 90,\n axis: getOppositeEdge(revolveAxis, box)\n }, %)",
"const sketch001 = startSketchOn('XY')\n |> startProfileAt([10, 0], %)\n |> line([5, -5], %)\n |> line([5, 5], %)\n |> lineTo([profileStartX(%), profileStartY(%)], %)\n |> close(%)\n\nconst part001 = revolve({\n axis: {\n custom: {\n axis: [0.0, 1.0, 0.0],\n origin: [0.0, 0.0, 0.0]\n }\n }\n}, sketch001)" "const sketch001 = startSketchOn('XY')\n |> startProfileAt([10, 0], %)\n |> line([5, -5], %)\n |> line([5, 5], %)\n |> lineTo([profileStartX(%), profileStartY(%)], %)\n |> close(%)\n\nconst part001 = revolve({\n axis: {\n custom: {\n axis: [0.0, 1.0, 0.0],\n origin: [0.0, 0.0, 0.0]\n }\n }\n}, sketch001)"
] ]
}, },
@ -118429,7 +118429,7 @@
"unpublished": false, "unpublished": false,
"deprecated": false, "deprecated": false,
"examples": [ "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)"
] ]
}, },
{ {
@ -120485,7 +120485,7 @@
"unpublished": false, "unpublished": false,
"deprecated": false, "deprecated": false,
"examples": [ "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)"
] ]
}, },
{ {
@ -122541,7 +122541,7 @@
"unpublished": false, "unpublished": false,
"deprecated": false, "deprecated": false,
"examples": [ "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)"
] ]
}, },
{ {
@ -124597,7 +124597,7 @@
"unpublished": false, "unpublished": false,
"deprecated": false, "deprecated": false,
"examples": [ "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({ angle: -60, length: segLen(thing, %) }, %)\n |> close(%)\n\nconst example = extrude(5, exampleSketch)"
] ]
}, },
{ {
@ -136709,7 +136709,7 @@
"deprecated": false, "deprecated": false,
"examples": [ "examples": [
"const exampleSketch = startSketchOn(\"XY\")\n |> startProfileAt([0, 0], %)\n |> line([10, 0], %)\n |> line([0, 10], %)\n |> line([-10, 0], %)\n |> close(%)\n\nconst example = extrude(5, exampleSketch)\n\nconst exampleSketch002 = startSketchOn(example, 'end')\n |> startProfileAt([1, 1], %)\n |> line([8, 0], %)\n |> line([0, 8], %)\n |> line([-8, 0], %)\n |> close(%)\n\nconst example002 = extrude(5, exampleSketch002)\n\nconst exampleSketch003 = startSketchOn(example002, 'end')\n |> startProfileAt([2, 2], %)\n |> line([6, 0], %)\n |> line([0, 6], %)\n |> line([-6, 0], %)\n |> close(%)\n\nconst example003 = extrude(5, exampleSketch003)", "const exampleSketch = startSketchOn(\"XY\")\n |> startProfileAt([0, 0], %)\n |> line([10, 0], %)\n |> line([0, 10], %)\n |> line([-10, 0], %)\n |> close(%)\n\nconst example = extrude(5, exampleSketch)\n\nconst exampleSketch002 = startSketchOn(example, 'end')\n |> startProfileAt([1, 1], %)\n |> line([8, 0], %)\n |> line([0, 8], %)\n |> line([-8, 0], %)\n |> close(%)\n\nconst example002 = extrude(5, exampleSketch002)\n\nconst exampleSketch003 = startSketchOn(example002, 'end')\n |> startProfileAt([2, 2], %)\n |> line([6, 0], %)\n |> line([0, 6], %)\n |> line([-6, 0], %)\n |> close(%)\n\nconst example003 = extrude(5, exampleSketch003)",
"const exampleSketch = startSketchOn(\"XY\")\n |> startProfileAt([0, 0], %)\n |> line([10, 0], %)\n |> line([0, 10], %, 'sketchingFace')\n |> line([-10, 0], %)\n |> close(%)\n\nconst example = extrude(10, exampleSketch)\n\nconst exampleSketch002 = startSketchOn(example, 'sketchingFace')\n |> startProfileAt([1, 1], %)\n |> line([8, 0], %)\n |> line([0, 8], %)\n |> line([-8, 0], %)\n |> close(%, 'sketchingFace002')\n\nconst example002 = extrude(10, exampleSketch002)\n\nconst exampleSketch003 = startSketchOn(example002, 'sketchingFace002')\n |> startProfileAt([-8, 12], %)\n |> line([0, 6], %)\n |> line([6, 0], %)\n |> line([0, -6], %)\n |> close(%)\n\nconst example003 = extrude(5, exampleSketch003)", "const exampleSketch = startSketchOn(\"XY\")\n |> startProfileAt([0, 0], %)\n |> line([10, 0], %)\n |> line([0, 10], %, $sketchingFace)\n |> line([-10, 0], %)\n |> close(%)\n\nconst example = extrude(10, exampleSketch)\n\nconst exampleSketch002 = startSketchOn(example, 'sketchingFace')\n |> startProfileAt([1, 1], %)\n |> line([8, 0], %)\n |> line([0, 8], %)\n |> line([-8, 0], %)\n |> close(%, $sketchingFace002)\n\nconst example002 = extrude(10, exampleSketch002)\n\nconst exampleSketch003 = startSketchOn(example002, 'sketchingFace002')\n |> startProfileAt([-8, 12], %)\n |> line([0, 6], %)\n |> line([6, 0], %)\n |> line([0, -6], %)\n |> close(%)\n\nconst example003 = extrude(5, exampleSketch003)",
"const exampleSketch = startSketchOn('XY')\n |> startProfileAt([4, 12], %)\n |> line([2, 0], %)\n |> line([0, -6], %)\n |> line([4, -6], %)\n |> line([0, -6], %)\n |> line([-3.75, -4.5], %)\n |> line([0, -5.5], %)\n |> line([-2, 0], %)\n |> close(%)\n\nconst example = revolve({ axis: 'y', angle: 180 }, exampleSketch)\n\nconst exampleSketch002 = startSketchOn(example, 'end')\n |> startProfileAt([4.5, -5], %)\n |> line([0, 5], %)\n |> line([5, 0], %)\n |> line([0, -5], %)\n |> close(%)\n\nconst example002 = extrude(5, exampleSketch002)", "const exampleSketch = startSketchOn('XY')\n |> startProfileAt([4, 12], %)\n |> line([2, 0], %)\n |> line([0, -6], %)\n |> line([4, -6], %)\n |> line([0, -6], %)\n |> line([-3.75, -4.5], %)\n |> line([0, -5.5], %)\n |> line([-2, 0], %)\n |> close(%)\n\nconst example = revolve({ axis: 'y', angle: 180 }, exampleSketch)\n\nconst exampleSketch002 = startSketchOn(example, 'end')\n |> startProfileAt([4.5, -5], %)\n |> line([0, 5], %)\n |> line([5, 0], %)\n |> line([0, -5], %)\n |> close(%)\n\nconst example002 = extrude(5, exampleSketch002)",
"const a1 = startSketchOn({\n plane: {\n origin: { x: 0, y: 0, z: 0 },\n x_axis: { x: 1, y: 0, z: 0 },\n y_axis: { x: 0, y: 1, z: 0 },\n z_axis: { x: 0, y: 0, z: 1 }\n }\n })\n |> startProfileAt([0, 0], %)\n |> line([100.0, 0], %)\n |> yLine(-100.0, %)\n |> xLine(-100.0, %)\n |> yLine(100.0, %)\n |> close(%)\n |> extrude(3.14, %)" "const a1 = startSketchOn({\n plane: {\n origin: { x: 0, y: 0, z: 0 },\n x_axis: { x: 1, y: 0, z: 0 },\n y_axis: { x: 0, y: 1, z: 0 },\n z_axis: { x: 0, y: 0, z: 1 }\n }\n })\n |> startProfileAt([0, 0], %)\n |> line([100.0, 0], %)\n |> yLine(-100.0, %)\n |> xLine(-100.0, %)\n |> yLine(100.0, %)\n |> close(%)\n |> extrude(3.14, %)"
] ]

View File

@ -191,9 +191,9 @@ async function doBasicSketch(page: Page, openPanes: string[]) {
await u.openKclCodePanel() await u.openKclCodePanel()
await expect(u.codeLocator).toHaveText(`const sketch001 = startSketchOn('XZ') await expect(u.codeLocator).toHaveText(`const sketch001 = startSketchOn('XZ')
|> startProfileAt(${commonPoints.startAt}, %) |> startProfileAt(${commonPoints.startAt}, %)
|> line([${commonPoints.num1}, 0], %, 'seg01') |> line([${commonPoints.num1}, 0], %, $seg01)
|> line([0, ${commonPoints.num1 + 0.01}], %) |> line([0, ${commonPoints.num1 + 0.01}], %)
|> angledLine([180, segLen('seg01', %)], %)`) |> angledLine([180, segLen(seg01, %)], %)`)
} }
test.describe('Basic sketch', () => { test.describe('Basic sketch', () => {
@ -1891,7 +1891,7 @@ test.describe('Testing selections', () => {
|> angledLine({ angle: 3 + 0, length: 3.14 + 0 }, %) |> angledLine({ angle: 3 + 0, length: 3.14 + 0 }, %)
|> lineTo([20.14 + 0, -0.14 + 0], %) |> lineTo([20.14 + 0, -0.14 + 0], %)
|> xLineTo(29 + 0, %) |> xLineTo(29 + 0, %)
|> yLine(-3.14 + 0, %, 'a') |> yLine(-3.14 + 0, %, $a)
|> xLine(1.63, %) |> xLine(1.63, %)
|> angledLineOfXLength({ angle: 3 + 0, length: 3.14 }, %) |> angledLineOfXLength({ angle: 3 + 0, length: 3.14 }, %)
|> angledLineOfYLength({ angle: 30, length: 3 + 0 }, %) |> angledLineOfYLength({ angle: 30, length: 3 + 0 }, %)
@ -1899,7 +1899,7 @@ test.describe('Testing selections', () => {
|> angledLineToY({ angle: 30, to: 11.14 }, %) |> angledLineToY({ angle: 30, to: 11.14 }, %)
|> angledLineThatIntersects({ |> angledLineThatIntersects({
angle: 3.14, angle: 3.14,
intersectTag: 'a', intersectTag: a,
offset: 0 offset: 0
}, %) }, %)
|> tangentialArcTo([13.14 + 0, 13.14], %) |> tangentialArcTo([13.14 + 0, 13.14], %)
@ -1983,7 +1983,7 @@ test.describe('Testing selections', () => {
|> line([2.48, 2.44], %) |> line([2.48, 2.44], %)
|> line([2.66, 1.17], %) |> line([2.66, 1.17], %)
|> line([3.75, 0.46], %) |> line([3.75, 0.46], %)
|> line([4.99, -0.46], %, 'seg01') |> line([4.99, -0.46], %, $seg01)
|> line([3.3, -2.12], %) |> line([3.3, -2.12], %)
|> line([2.16, -3.33], %) |> line([2.16, -3.33], %)
|> line([0.85, -3.08], %) |> line([0.85, -3.08], %)
@ -2005,7 +2005,7 @@ const extrude001 = extrude(10, sketch001)
await u.closeDebugPanel() await u.closeDebugPanel()
const selectUnExtrudable = () => const selectUnExtrudable = () =>
page.getByText(`line([4.99, -0.46], %, 'seg01')`).click() page.getByText(`line([4.99, -0.46], %, $seg01)`).click()
const clickEmpty = () => page.mouse.click(700, 460) const clickEmpty = () => page.mouse.click(700, 460)
await selectUnExtrudable() await selectUnExtrudable()
// expect extrude button to be disabled // expect extrude button to be disabled
@ -2019,7 +2019,7 @@ const extrude001 = extrude(10, sketch001)
await expect(page.getByRole('button', { name: 'Extrude' })).toBeDisabled() await expect(page.getByRole('button', { name: 'Extrude' })).toBeDisabled()
const codeToAdd = `${await u.codeLocator.allInnerTexts()} const codeToAdd = `${await u.codeLocator.allInnerTexts()}
const sketch002 = startSketchOn(extrude001, 'seg01') const sketch002 = startSketchOn(extrude001, $seg01)
|> startProfileAt([-12.94, 6.6], %) |> startProfileAt([-12.94, 6.6], %)
|> line([2.45, -0.2], %) |> line([2.45, -0.2], %)
|> line([-2, -1.25], %) |> line([-2, -1.25], %)
@ -2046,11 +2046,11 @@ const sketch002 = startSketchOn(extrude001, 'seg01')
const cases = [ const cases = [
{ {
pos: [694, 185], pos: [694, 185],
expectedCode: "line([74.36, 130.4], %, 'seg01')", expectedCode: 'line([74.36, 130.4], %, $seg01)',
}, },
{ {
pos: [816, 244], pos: [816, 244],
expectedCode: "angledLine([segAng('seg01', %), yo], %)", expectedCode: 'angledLine([segAng(seg01, %), yo], %)',
}, },
{ {
pos: [1107, 161], pos: [1107, 161],
@ -2912,7 +2912,7 @@ test('Can edit a sketch that has been extruded in the same pipe', async ({
const startPX = [665, 458] const startPX = [665, 458]
const dragPX = 80 const dragPX = 40
await page.getByText('startProfileAt([4.61, -14.01], %)').click() await page.getByText('startProfileAt([4.61, -14.01], %)').click()
await expect(page.getByRole('button', { name: 'Edit Sketch' })).toBeVisible() await expect(page.getByRole('button', { name: 'Edit Sketch' })).toBeVisible()
@ -2925,7 +2925,7 @@ test('Can edit a sketch that has been extruded in the same pipe', async ({
// drag startProfieAt handle // drag startProfieAt handle
await page.dragAndDrop('#stream', '#stream', { await page.dragAndDrop('#stream', '#stream', {
sourcePosition: { x: startPX[0], y: startPX[1] }, sourcePosition: { x: startPX[0], y: startPX[1] },
targetPosition: { x: startPX[0] + dragPX, y: startPX[1] - dragPX }, targetPosition: { x: startPX[0] + dragPX, y: startPX[1] + dragPX },
}) })
await page.waitForTimeout(100) await page.waitForTimeout(100)
await expect(page.locator('.cm-content')).not.toHaveText(prevContent) await expect(page.locator('.cm-content')).not.toHaveText(prevContent)
@ -2938,7 +2938,7 @@ test('Can edit a sketch that has been extruded in the same pipe', async ({
await page.waitForTimeout(100) await page.waitForTimeout(100)
await page.dragAndDrop('#stream', '#stream', { await page.dragAndDrop('#stream', '#stream', {
sourcePosition: { x: lineEnd.x - 5, y: lineEnd.y }, sourcePosition: { x: lineEnd.x - 5, y: lineEnd.y },
targetPosition: { x: lineEnd.x + dragPX, y: lineEnd.y - dragPX }, targetPosition: { x: lineEnd.x + dragPX, y: lineEnd.y + dragPX },
}) })
await expect(page.locator('.cm-content')).not.toHaveText(prevContent) await expect(page.locator('.cm-content')).not.toHaveText(prevContent)
prevContent = await page.locator('.cm-content').innerText() prevContent = await page.locator('.cm-content').innerText()
@ -2949,7 +2949,7 @@ test('Can edit a sketch that has been extruded in the same pipe', async ({
sourcePosition: { x: tangentEnd.x, y: tangentEnd.y - 5 }, sourcePosition: { x: tangentEnd.x, y: tangentEnd.y - 5 },
targetPosition: { targetPosition: {
x: tangentEnd.x + dragPX, x: tangentEnd.x + dragPX,
y: tangentEnd.y - dragPX, y: tangentEnd.y + dragPX,
}, },
}) })
await page.waitForTimeout(100) await page.waitForTimeout(100)
@ -2958,10 +2958,10 @@ test('Can edit a sketch that has been extruded in the same pipe', async ({
// expect the code to have changed // expect the code to have changed
await expect(page.locator('.cm-content')) await expect(page.locator('.cm-content'))
.toHaveText(`const sketch001 = startSketchOn('XZ') .toHaveText(`const sketch001 = startSketchOn('XZ')
|> startProfileAt([6.44, -12.07], %) |> startProfileAt([7.12, -16.82], %)
|> line([14.72, 2.01], %) |> line([15.4, -2.74], %)
|> tangentialArcTo([24.95, -5.38], %) |> tangentialArcTo([24.95, -5.38], %)
|> line([1.97, 2.06], %) |> line([2.65, -2.69], %)
|> close(%) |> close(%)
|> extrude(5, %)`) |> extrude(5, %)`)
}) })
@ -3206,6 +3206,7 @@ test('Sketch on face', async ({ page }) => {
true true
) )
await page.waitForTimeout(150) await page.waitForTimeout(150)
await u.closeDebugPanel()
const firstClickPosition = [612, 238] const firstClickPosition = [612, 238]
const secondClickPosition = [661, 242] const secondClickPosition = [661, 242]
@ -3231,7 +3232,7 @@ test('Sketch on face', async ({ page }) => {
previousCodeContent = await page.locator('.cm-content').innerText() previousCodeContent = await page.locator('.cm-content').innerText()
await expect(page.locator('.cm-content')) await expect(page.locator('.cm-content'))
.toContainText(`const sketch002 = startSketchOn(extrude001, 'seg01') .toContainText(`const sketch002 = startSketchOn(extrude001, seg01)
|> startProfileAt([-12.94, 6.6], %) |> startProfileAt([-12.94, 6.6], %)
|> line([2.45, -0.2], %) |> line([2.45, -0.2], %)
|> line([-2.6, -1.25], %) |> line([-2.6, -1.25], %)
@ -3267,7 +3268,7 @@ test('Sketch on face', async ({ page }) => {
await expect(page.locator('.cm-content')).not.toHaveText(previousCodeContent) await expect(page.locator('.cm-content')).not.toHaveText(previousCodeContent)
previousCodeContent = await page.locator('.cm-content').innerText() previousCodeContent = await page.locator('.cm-content').innerText()
const result = makeTemplate`const sketch002 = startSketchOn(extrude001, 'seg01') const result = makeTemplate`const sketch002 = startSketchOn(extrude001, seg01)
|> startProfileAt([-12.83, 6.7], %) |> startProfileAt([-12.83, 6.7], %)
|> line([${[2.28, 2.35]}, -${0.07}], %) |> line([${[2.28, 2.35]}, -${0.07}], %)
|> line([-3.05, -1.47], %) |> line([-3.05, -1.47], %)
@ -3406,15 +3407,15 @@ test.describe('Testing constraints', () => {
`const yo = 79 `const yo = 79
const part001 = startSketchOn('XZ') const part001 = startSketchOn('XZ')
|> startProfileAt([-7.54, -26.74], %) |> startProfileAt([-7.54, -26.74], %)
|> line([74.36, 130.4], %, 'seg01') |> line([74.36, 130.4], %, $seg01)
|> line([78.92, -120.11], %) |> line([78.92, -120.11], %)
|> angledLine([segAng('seg01', %), yo], %) |> angledLine([segAng(seg01, %), yo], %)
|> line([41.19, 28.97 + 5], %) |> line([41.19, 28.97 + 5], %)
const part002 = startSketchOn('XZ') const part002 = startSketchOn('XZ')
|> startProfileAt([299.05, 231.45], %) |> startProfileAt([299.05, 231.45], %)
|> xLine(-425.34, %, 'seg-what') |> xLine(-425.34, %, $seg_what)
|> yLine(-264.06, %) |> yLine(-264.06, %)
|> xLine(segLen('seg-what', %), %) |> xLine(segLen(seg_what, %), %)
|> lineTo([profileStartX(%), profileStartY(%)], %)` |> lineTo([profileStartX(%), profileStartY(%)], %)`
) )
}) })
@ -3423,7 +3424,7 @@ const part002 = startSketchOn('XZ')
await page.goto('/') await page.goto('/')
await u.waitForAuthSkipAppStart() await u.waitForAuthSkipAppStart()
await page.getByText("line([74.36, 130.4], %, 'seg01')").click() await page.getByText('line([74.36, 130.4], %, $seg01)').click()
await page.getByRole('button', { name: 'Edit Sketch' }).click() await page.getByRole('button', { name: 'Edit Sketch' }).click()
const line3 = await u.getSegmentBodyCoords(`[data-overlay-index="${2}"]`) const line3 = await u.getSegmentBodyCoords(`[data-overlay-index="${2}"]`)
@ -3466,15 +3467,15 @@ const part002 = startSketchOn('XZ')
`const yo = 5 `const yo = 5
const part001 = startSketchOn('XZ') const part001 = startSketchOn('XZ')
|> startProfileAt([-7.54, -26.74], %) |> startProfileAt([-7.54, -26.74], %)
|> line([74.36, 130.4], %, 'seg01') |> line([74.36, 130.4], %, $seg01)
|> line([78.92, -120.11], %) |> line([78.92, -120.11], %)
|> angledLine([segAng('seg01', %), 78.33], %) |> angledLine([segAng(seg01, %), 78.33], %)
|> line([41.19, 28.97], %) |> line([41.19, 28.97], %)
const part002 = startSketchOn('XZ') const part002 = startSketchOn('XZ')
|> startProfileAt([299.05, 231.45], %) |> startProfileAt([299.05, 231.45], %)
|> xLine(-425.34, %, 'seg-what') |> xLine(-425.34, %, $seg_what)
|> yLine(-264.06, %) |> yLine(-264.06, %)
|> xLine(segLen('seg-what', %), %) |> xLine(segLen(seg_what, %), %)
|> lineTo([profileStartX(%), profileStartY(%)], %)` |> lineTo([profileStartX(%), profileStartY(%)], %)`
) )
}) })
@ -3483,7 +3484,7 @@ const part002 = startSketchOn('XZ')
await page.goto('/') await page.goto('/')
await u.waitForAuthSkipAppStart() await u.waitForAuthSkipAppStart()
await page.getByText("line([74.36, 130.4], %, 'seg01')").click() await page.getByText('line([74.36, 130.4], %, $seg01)').click()
await page.getByRole('button', { name: 'Edit Sketch' }).click() await page.getByRole('button', { name: 'Edit Sketch' }).click()
const [line1, line3] = await Promise.all([ const [line1, line3] = await Promise.all([
@ -3525,7 +3526,7 @@ const part002 = startSketchOn('XZ')
const activeLinesContent = await page.locator('.cm-activeLine').all() const activeLinesContent = await page.locator('.cm-activeLine').all()
await expect(activeLinesContent[0]).toHaveText( await expect(activeLinesContent[0]).toHaveText(
`|> line([74.36, 130.4], %, 'seg01')` `|> line([74.36, 130.4], %, $seg01)`
) )
await expect(activeLinesContent[1]).toHaveText(`}, %)`) await expect(activeLinesContent[1]).toHaveText(`}, %)`)
@ -3539,22 +3540,22 @@ const part002 = startSketchOn('XZ')
{ {
testName: 'Add variable', testName: 'Add variable',
constraint: 'horizontal distance', constraint: 'horizontal distance',
value: "segEndX('seg01', %) + xDis001, 61.34", value: 'segEndX(seg01, %) + xDis001, 61.34',
}, },
{ {
testName: 'No variable', testName: 'No variable',
constraint: 'horizontal distance', constraint: 'horizontal distance',
value: "segEndX('seg01', %) + 88.08, 61.34", value: 'segEndX(seg01, %) + 88.08, 61.34',
}, },
{ {
testName: 'Add variable', testName: 'Add variable',
constraint: 'vertical distance', constraint: 'vertical distance',
value: "154.9, segEndY('seg01', %) - yDis001", value: '154.9, segEndY(seg01, %) - yDis001',
}, },
{ {
testName: 'No variable', testName: 'No variable',
constraint: 'vertical distance', constraint: 'vertical distance',
value: "154.9, segEndY('seg01', %) - 42.32", value: '154.9, segEndY(seg01, %) - 42.32',
}, },
] as const ] as const
for (const { testName, value, constraint } of cases) { for (const { testName, value, constraint } of cases) {
@ -3571,9 +3572,9 @@ const part001 = startSketchOn('XZ')
|> line([41.19, 28.97], %) |> line([41.19, 28.97], %)
const part002 = startSketchOn('XZ') const part002 = startSketchOn('XZ')
|> startProfileAt([299.05, 231.45], %) |> startProfileAt([299.05, 231.45], %)
|> xLine(-425.34, %, 'seg-what') |> xLine(-425.34, %, $seg_what)
|> yLine(-264.06, %) |> yLine(-264.06, %)
|> xLine(segLen('seg-what', %), %) |> xLine(segLen(seg_what, %), %)
|> lineTo([profileStartX(%), profileStartY(%)], %)` |> lineTo([profileStartX(%), profileStartY(%)], %)`
) )
}) })
@ -3618,7 +3619,7 @@ const part002 = startSketchOn('XZ')
// checking activeLines assures the cursors are where they should be // checking activeLines assures the cursors are where they should be
const codeAfter = [ const codeAfter = [
`|> line([74.36, 130.4], %, 'seg01')`, `|> line([74.36, 130.4], %, $seg01)`,
`|> lineTo([${value}], %)`, `|> lineTo([${value}], %)`,
] ]
@ -3679,9 +3680,9 @@ const part001 = startSketchOn('XZ')
|> line([41.19, 28.97], %) |> line([41.19, 28.97], %)
const part002 = startSketchOn('XZ') const part002 = startSketchOn('XZ')
|> startProfileAt([299.05, 231.45], %) |> startProfileAt([299.05, 231.45], %)
|> xLine(-425.34, %, 'seg-what') |> xLine(-425.34, %, $seg_what)
|> yLine(-264.06, %) |> yLine(-264.06, %)
|> xLine(segLen('seg-what', %), %) |> xLine(segLen(seg_what, %), %)
|> lineTo([profileStartX(%), profileStartY(%)], %)` |> lineTo([profileStartX(%), profileStartY(%)], %)`
) )
}) })
@ -3751,13 +3752,13 @@ const part002 = startSketchOn('XZ')
testName: 'Add variable', testName: 'Add variable',
addVariable: true, addVariable: true,
axisSelect: false, axisSelect: false,
value: "segAng('seg01', %) + angle001", value: 'segAng(seg01, %) + angle001',
}, },
{ {
testName: 'No variable', testName: 'No variable',
addVariable: false, addVariable: false,
axisSelect: false, axisSelect: false,
value: "segAng('seg01', %) + 22.69", value: 'segAng(seg01, %) + 22.69',
}, },
{ {
testName: 'Add variable, selecting axis', testName: 'Add variable, selecting axis',
@ -3786,9 +3787,9 @@ const part001 = startSketchOn('XZ')
|> line([41.19, 28.97], %) |> line([41.19, 28.97], %)
const part002 = startSketchOn('XZ') const part002 = startSketchOn('XZ')
|> startProfileAt([299.05, 231.45], %) |> startProfileAt([299.05, 231.45], %)
|> xLine(-425.34, %, 'seg-what') |> xLine(-425.34, %, $seg_what)
|> yLine(-264.06, %) |> yLine(-264.06, %)
|> xLine(segLen('seg-what', %), %) |> xLine(segLen(seg_what, %), %)
|> lineTo([profileStartX(%), profileStartY(%)], %)` |> lineTo([profileStartX(%), profileStartY(%)], %)`
) )
}) })
@ -3834,7 +3835,7 @@ const part002 = startSketchOn('XZ')
// checking activeLines assures the cursors are where they should be // checking activeLines assures the cursors are where they should be
const codeAfter = [ const codeAfter = [
"|> line([74.36, 130.4], %, 'seg01')", '|> line([74.36, 130.4], %, $seg01)',
`|> angledLine([${value}, 78.33], %)`, `|> angledLine([${value}, 78.33], %)`,
] ]
if (axisSelect) codeAfter.shift() if (axisSelect) codeAfter.shift()
@ -3896,9 +3897,9 @@ const part001 = startSketchOn('XZ')
|> line([41.19, 28.97], %) |> line([41.19, 28.97], %)
const part002 = startSketchOn('XZ') const part002 = startSketchOn('XZ')
|> startProfileAt([299.05, 231.45], %) |> startProfileAt([299.05, 231.45], %)
|> xLine(-425.34, %, 'seg-what') |> xLine(-425.34, %, $seg_what)
|> yLine(-264.06, %) |> yLine(-264.06, %)
|> xLine(segLen('seg-what', %), %) |> xLine(segLen(seg_what, %), %)
|> lineTo([profileStartX(%), profileStartY(%)], %)` |> lineTo([profileStartX(%), profileStartY(%)], %)`
) )
}) })
@ -3972,9 +3973,9 @@ const part001 = startSketchOn('XZ')
|> line([41.19, 28.97], %) |> line([41.19, 28.97], %)
const part002 = startSketchOn('XZ') const part002 = startSketchOn('XZ')
|> startProfileAt([299.05, 231.45], %) |> startProfileAt([299.05, 231.45], %)
|> xLine(-425.34, %, 'seg-what') |> xLine(-425.34, %, $seg_what)
|> yLine(-264.06, %) |> yLine(-264.06, %)
|> xLine(segLen('seg-what', %), %) |> xLine(segLen(seg_what, %), %)
|> lineTo([profileStartX(%), profileStartY(%)], %)` |> lineTo([profileStartX(%), profileStartY(%)], %)`
) )
}) })
@ -4039,19 +4040,19 @@ const part002 = startSketchOn('XZ')
test.describe('Two segment - no modal constraints', () => { test.describe('Two segment - no modal constraints', () => {
const cases = [ const cases = [
{ {
codeAfter: `|> angledLine([83, segLen('seg01', %)], %)`, codeAfter: `|> angledLine([83, segLen(seg01, %)], %)`,
constraintName: 'Equal Length', constraintName: 'Equal Length',
}, },
{ {
codeAfter: `|> angledLine([segAng('seg01', %), 78.33], %)`, codeAfter: `|> angledLine([segAng(seg01, %), 78.33], %)`,
constraintName: 'Parallel', constraintName: 'Parallel',
}, },
{ {
codeAfter: `|> lineTo([segEndX('seg01', %), 61.34], %)`, codeAfter: `|> lineTo([segEndX(seg01, %), 61.34], %)`,
constraintName: 'Vertically Align', constraintName: 'Vertically Align',
}, },
{ {
codeAfter: `|> lineTo([154.9, segEndY('seg01', %)], %)`, codeAfter: `|> lineTo([154.9, segEndY(seg01, %)], %)`,
constraintName: 'Horizontally Align', constraintName: 'Horizontally Align',
}, },
] as const ] as const
@ -4068,9 +4069,9 @@ const part001 = startSketchOn('XZ')
|> line([9.16, 77.79], %) |> line([9.16, 77.79], %)
const part002 = startSketchOn('XZ') const part002 = startSketchOn('XZ')
|> startProfileAt([299.05, 231.45], %) |> startProfileAt([299.05, 231.45], %)
|> xLine(-425.34, %, 'seg-what') |> xLine(-425.34, %, $seg_what)
|> yLine(-264.06, %) |> yLine(-264.06, %)
|> xLine(segLen('seg-what', %), %) |> xLine(segLen(seg_what, %), %)
|> lineTo([profileStartX(%), profileStartY(%)], %)` |> lineTo([profileStartX(%), profileStartY(%)], %)`
) )
}) })
@ -4113,7 +4114,7 @@ const part002 = startSketchOn('XZ')
// check both cursors are where they should be after constraint is applied // check both cursors are where they should be after constraint is applied
await expect(activeLinesContent[0]).toHaveText( await expect(activeLinesContent[0]).toHaveText(
"|> line([74.36, 130.4], %, 'seg01')" '|> line([74.36, 130.4], %, $seg01)'
) )
await expect(activeLinesContent[1]).toHaveText(codeAfter) await expect(activeLinesContent[1]).toHaveText(codeAfter)
}) })
@ -4145,9 +4146,9 @@ const part001 = startSketchOn('XZ')
|> line([9.16, 77.79], %) |> line([9.16, 77.79], %)
const part002 = startSketchOn('XZ') const part002 = startSketchOn('XZ')
|> startProfileAt([299.05, 231.45], %) |> startProfileAt([299.05, 231.45], %)
|> xLine(-425.34, %, 'seg-what') |> xLine(-425.34, %, $seg_what)
|> yLine(-264.06, %) |> yLine(-264.06, %)
|> xLine(segLen('seg-what', %), %) |> xLine(segLen(seg_what, %), %)
|> lineTo([profileStartX(%), profileStartY(%)], %)` |> lineTo([profileStartX(%), profileStartY(%)], %)`
) )
}) })
@ -4194,7 +4195,7 @@ const part002 = startSketchOn('XZ')
'persistCode', 'persistCode',
`const sketch001 = startSketchOn('XY') `const sketch001 = startSketchOn('XY')
|> startProfileAt([-1.05, -1.07], %) |> startProfileAt([-1.05, -1.07], %)
|> line([3.79, 2.68], %, 'seg01') |> line([3.79, 2.68], %, $seg01)
|> line([3.13, -2.4], %)` |> line([3.13, -2.4], %)`
) )
}) })
@ -4203,7 +4204,7 @@ const part002 = startSketchOn('XZ')
await page.goto('/') await page.goto('/')
await u.waitForAuthSkipAppStart() await u.waitForAuthSkipAppStart()
await page.getByText("line([3.79, 2.68], %, 'seg01')").click() await page.getByText('line([3.79, 2.68], %, $seg01)').click()
await page.getByRole('button', { name: 'Edit Sketch' }).click() await page.getByRole('button', { name: 'Edit Sketch' }).click()
await page.waitForTimeout(100) await page.waitForTimeout(100)
@ -4438,7 +4439,7 @@ test.describe('Testing segment overlays', () => {
|> angledLine({ angle: 3 + 0, length: 32 + 0 }, %) |> angledLine({ angle: 3 + 0, length: 32 + 0 }, %)
|> lineTo([5 + 33, 20 + 11.5 + 0], %) |> lineTo([5 + 33, 20 + 11.5 + 0], %)
|> xLineTo(5 + 9 - 5, %) |> xLineTo(5 + 9 - 5, %)
|> yLineTo(20 + -10.77, %, 'a') |> yLineTo(20 + -10.77, %, $a)
|> xLine(26.04, %) |> xLine(26.04, %)
|> yLine(21.14 + 0, %) |> yLine(21.14 + 0, %)
|> angledLineOfXLength({ angle: 181 + 0, length: 23.14 }, %) |> angledLineOfXLength({ angle: 181 + 0, length: 23.14 }, %)
@ -4447,7 +4448,7 @@ test.describe('Testing segment overlays', () => {
|> angledLineToY({ angle: 89, to: 20 + 9.14 + 0 }, %) |> angledLineToY({ angle: 89, to: 20 + 9.14 + 0 }, %)
|> angledLineThatIntersects({ |> angledLineThatIntersects({
angle: 4.14, angle: 4.14,
intersectTag: 'a', intersectTag: a,
offset: 9 offset: 9
}, %) }, %)
|> tangentialArcTo([5 + 3.14 + 13, 20 + 3.14], %) |> tangentialArcTo([5 + 3.14 + 13, 20 + 3.14], %)
@ -4606,7 +4607,7 @@ const part001 = startSketchOn('XZ')
|> angledLine({ angle: angle001, length: len001 }, %) |> angledLine({ angle: angle001, length: len001 }, %)
|> lineTo([33, yAbs001], %) |> lineTo([33, yAbs001], %)
|> xLineTo(xAbs002, %) |> xLineTo(xAbs002, %)
|> yLineTo(-10.77, %, 'a') |> yLineTo(-10.77, %, $a)
|> xLine(26.04, %) |> xLine(26.04, %)
|> yLine(21.14 + 0, %) |> yLine(21.14 + 0, %)
|> angledLineOfXLength({ angle: 181 + 0, length: 23.14 }, %) |> angledLineOfXLength({ angle: 181 + 0, length: 23.14 }, %)
@ -4643,9 +4644,9 @@ const part001 = startSketchOn('XZ')
await clickUnconstrained({ await clickUnconstrained({
hoverPos: { x: yLineTo.x, y: yLineTo.y }, hoverPos: { x: yLineTo.x, y: yLineTo.y },
constraintType: 'yAbsolute', constraintType: 'yAbsolute',
expectBeforeUnconstrained: "yLineTo(-10.77, %, 'a')", expectBeforeUnconstrained: 'yLineTo(-10.77, %, $a)',
expectAfterUnconstrained: "yLineTo(yAbs002, %, 'a')", expectAfterUnconstrained: 'yLineTo(yAbs002, %, $a)',
expectFinal: "yLineTo(-10.77, %, 'a')", expectFinal: 'yLineTo(-10.77, %, $a)',
ang: ang + 180, ang: ang + 180,
locator: '[data-overlay-toolbar-index="4"]', locator: '[data-overlay-toolbar-index="4"]',
}) })
@ -4676,7 +4677,7 @@ const part001 = startSketchOn('XZ')
|> angledLine({ angle: 3 + 0, length: 32 + 0 }, %) |> angledLine({ angle: 3 + 0, length: 32 + 0 }, %)
|> lineTo([33, 11.5 + 0], %) |> lineTo([33, 11.5 + 0], %)
|> xLineTo(9 - 5, %) |> xLineTo(9 - 5, %)
|> yLineTo(-10.77, %, 'a') |> yLineTo(-10.77, %, $a)
|> xLine(26.04, %) |> xLine(26.04, %)
|> yLine(21.14 + 0, %) |> yLine(21.14 + 0, %)
|> angledLineOfXLength({ angle: 181 + 0, length: 23.14 }, %) |> angledLineOfXLength({ angle: 181 + 0, length: 23.14 }, %)
@ -4685,7 +4686,7 @@ const part001 = startSketchOn('XZ')
|> angledLineToY({ angle: 89, to: 9.14 + 0 }, %) |> angledLineToY({ angle: 89, to: 9.14 + 0 }, %)
|> angledLineThatIntersects({ |> angledLineThatIntersects({
angle: 4.14, angle: 4.14,
intersectTag: 'a', intersectTag: a,
offset: 9 offset: 9
}, %) }, %)
|> tangentialArcTo([3.14 + 13, 3.14], %) |> tangentialArcTo([3.14 + 13, 3.14], %)
@ -4804,7 +4805,7 @@ const part001 = startSketchOn('XZ')
|> angledLine({ angle: 3 + 0, length: 32 + 0 }, %) |> angledLine({ angle: 3 + 0, length: 32 + 0 }, %)
|> lineTo([33, 11.5 + 0], %) |> lineTo([33, 11.5 + 0], %)
|> xLineTo(9 - 5, %) |> xLineTo(9 - 5, %)
|> yLineTo(-10.77, %, 'a') |> yLineTo(-10.77, %, $a)
|> xLine(26.04, %) |> xLine(26.04, %)
|> yLine(21.14 + 0, %) |> yLine(21.14 + 0, %)
|> angledLineOfXLength({ angle: 181 + 0, length: 23.14 }, %) |> angledLineOfXLength({ angle: 181 + 0, length: 23.14 }, %)
@ -4813,7 +4814,7 @@ const part001 = startSketchOn('XZ')
|> angledLineToY({ angle: 89, to: 9.14 + 0 }, %) |> angledLineToY({ angle: 89, to: 9.14 + 0 }, %)
|> angledLineThatIntersects({ |> angledLineThatIntersects({
angle: 4.14, angle: 4.14,
intersectTag: 'a', intersectTag: a,
offset: 9 offset: 9
}, %) }, %)
|> tangentialArcTo([3.14 + 13, 1.14], %) |> tangentialArcTo([3.14 + 13, 1.14], %)
@ -4908,18 +4909,18 @@ const part001 = startSketchOn('XZ')
constraintType: 'angle', constraintType: 'angle',
expectBeforeUnconstrained: `angledLineThatIntersects({ expectBeforeUnconstrained: `angledLineThatIntersects({
angle: 4.14, angle: 4.14,
intersectTag: 'a', intersectTag: a,
offset: 9 offset: 9
}, %)`, }, %)`,
expectAfterUnconstrained: `angledLineThatIntersects({ expectAfterUnconstrained: `angledLineThatIntersects({
angle: angle003, angle: angle003,
intersectTag: 'a', intersectTag: a,
offset: 9 offset: 9
}, %)`, }, %)`,
expectFinal: `angledLineThatIntersects({ expectFinal: `angledLineThatIntersects({
angle: -176, angle: -176,
offset: 9, offset: 9,
intersectTag: 'a' intersectTag: a
}, %)`, }, %)`,
ang: ang + 180, ang: ang + 180,
locator: '[data-overlay-toolbar-index="11"]', locator: '[data-overlay-toolbar-index="11"]',
@ -4934,17 +4935,17 @@ const part001 = startSketchOn('XZ')
expectBeforeUnconstrained: `angledLineThatIntersects({ expectBeforeUnconstrained: `angledLineThatIntersects({
angle: -176, angle: -176,
offset: 9, offset: 9,
intersectTag: 'a' intersectTag: a
}, %)`, }, %)`,
expectAfterUnconstrained: `angledLineThatIntersects({ expectAfterUnconstrained: `angledLineThatIntersects({
angle: -176, angle: -176,
offset: perpDist001, offset: perpDist001,
intersectTag: 'a' intersectTag: a
}, %)`, }, %)`,
expectFinal: `angledLineThatIntersects({ expectFinal: `angledLineThatIntersects({
angle: -176, angle: -176,
offset: 9, offset: 9,
intersectTag: 'a' intersectTag: a
}, %)`, }, %)`,
ang: ang + 180, ang: ang + 180,
locator: '[data-overlay-toolbar-index="11"]', locator: '[data-overlay-toolbar-index="11"]',
@ -4960,7 +4961,7 @@ const part001 = startSketchOn('XZ')
|> angledLine({ angle: 3 + 0, length: 32 + 0 }, %) |> angledLine({ angle: 3 + 0, length: 32 + 0 }, %)
|> lineTo([33, 11.5 + 0], %) |> lineTo([33, 11.5 + 0], %)
|> xLineTo(9 - 5, %) |> xLineTo(9 - 5, %)
|> yLineTo(-10.77, %, 'a') |> yLineTo(-10.77, %, $a)
|> xLine(26.04, %) |> xLine(26.04, %)
|> yLine(21.14 + 0, %) |> yLine(21.14 + 0, %)
|> angledLineOfXLength({ angle: 181 + 0, length: 23.14 }, %) |> angledLineOfXLength({ angle: 181 + 0, length: 23.14 }, %)
@ -4969,7 +4970,7 @@ const part001 = startSketchOn('XZ')
|> angledLineToY({ angle: 89, to: 9.14 + 0 }, %) |> angledLineToY({ angle: 89, to: 9.14 + 0 }, %)
|> angledLineThatIntersects({ |> angledLineThatIntersects({
angle: 4.14, angle: 4.14,
intersectTag: 'a', intersectTag: a,
offset: 9 offset: 9
}, %) }, %)
|> tangentialArcTo([3.14 + 13, -3.14], %) |> tangentialArcTo([3.14 + 13, -3.14], %)
@ -5073,7 +5074,7 @@ const part001 = startSketchOn('XZ')
|> angledLine({ angle: 3 + 0, length: 32 + 0 }, %) |> angledLine({ angle: 3 + 0, length: 32 + 0 }, %)
|> lineTo([33, 11.5 + 0], %) |> lineTo([33, 11.5 + 0], %)
|> xLineTo(9 - 5, %) |> xLineTo(9 - 5, %)
|> yLineTo(-10.77, %, 'a') |> yLineTo(-10.77, %, $a)
|> xLine(26.04, %) |> xLine(26.04, %)
|> yLine(21.14 + 0, %) |> yLine(21.14 + 0, %)
|> angledLineOfXLength({ angle: 181 + 0, length: 23.14 }, %) |> angledLineOfXLength({ angle: 181 + 0, length: 23.14 }, %)
@ -5082,7 +5083,7 @@ const part001 = startSketchOn('XZ')
|> angledLineToY({ angle: 89, to: 9.14 + 0 }, %) |> angledLineToY({ angle: 89, to: 9.14 + 0 }, %)
|> angledLineThatIntersects({ |> angledLineThatIntersects({
angle: 4.14, angle: 4.14,
intersectTag: 'a', intersectTag: a,
offset: 9 offset: 9
}, %) }, %)
|> tangentialArcTo([3.14 + 13, 1.14], %) |> tangentialArcTo([3.14 + 13, 1.14], %)
@ -5129,7 +5130,7 @@ const part001 = startSketchOn('XZ')
hoverPos: { x: segmentToDelete.x, y: segmentToDelete.y }, hoverPos: { x: segmentToDelete.x, y: segmentToDelete.y },
codeToBeDeleted: `angledLineThatIntersects({ codeToBeDeleted: `angledLineThatIntersects({
angle: 4.14, angle: 4.14,
intersectTag: 'a', intersectTag: a,
offset: 9 offset: 9
}, %)`, }, %)`,
stdLibFnName: 'angledLineThatIntersects', stdLibFnName: 'angledLineThatIntersects',
@ -5204,7 +5205,7 @@ const part001 = startSketchOn('XZ')
ang = await u.getAngle(`[data-overlay-index="${4}"]`) ang = await u.getAngle(`[data-overlay-index="${4}"]`)
await deleteSegmentSequence({ await deleteSegmentSequence({
hoverPos: { x: segmentToDelete.x, y: segmentToDelete.y }, hoverPos: { x: segmentToDelete.x, y: segmentToDelete.y },
codeToBeDeleted: "yLineTo(-10.77, %, 'a')", codeToBeDeleted: 'yLineTo(-10.77, %, $a)',
stdLibFnName: 'yLineTo', stdLibFnName: 'yLineTo',
ang: ang + 180, ang: ang + 180,
locator: '[data-overlay-toolbar-index="4"]', locator: '[data-overlay-toolbar-index="4"]',
@ -5278,20 +5279,20 @@ const part001 = startSketchOn('XZ')
}) })
test.describe('Testing delete with dependent segments', () => { test.describe('Testing delete with dependent segments', () => {
const cases = [ const cases = [
"line([22, 2], %, 'seg01')", 'line([22, 2], %, $seg01)',
"angledLine([5, 23.03], %, 'seg01')", 'angledLine([5, 23.03], %, $seg01)',
"xLine(23, %, 'seg01')", 'xLine(23, %, $seg01)',
"yLine(-8, %, 'seg01')", 'yLine(-8, %, $seg01)',
"xLineTo(30, %, 'seg01')", 'xLineTo(30, %, $seg01)',
"yLineTo(-4, %, 'seg01')", 'yLineTo(-4, %, $seg01)',
"angledLineOfXLength([3, 30], %, 'seg01')", 'angledLineOfXLength([3, 30], %, $seg01)',
"angledLineOfXLength({ angle: 3, length: 30 }, %, 'seg01')", 'angledLineOfXLength({ angle: 3, length: 30 }, %, $seg01)',
"angledLineOfYLength([3, 1.5], %, 'seg01')", 'angledLineOfYLength([3, 1.5], %, $seg01)',
"angledLineOfYLength({ angle: 3, length: 1.5 }, %, 'seg01')", 'angledLineOfYLength({ angle: 3, length: 1.5 }, %, $seg01)',
"angledLineToX([3, 30], %, 'seg01')", 'angledLineToX([3, 30], %, $seg01)',
"angledLineToX({ angle: 3, to: 30 }, %, 'seg01')", 'angledLineToX({ angle: 3, to: 30 }, %, $seg01)',
"angledLineToY([3, 7], %, 'seg01')", 'angledLineToY([3, 7], %, $seg01)',
"angledLineToY({ angle: 3, to: 7 }, %, 'seg01')", 'angledLineToY({ angle: 3, to: 7 }, %, $seg01)',
] ]
for (const doesHaveTagOutsideSketch of [true, false]) { for (const doesHaveTagOutsideSketch of [true, false]) {
for (const lineOfInterest of cases) { for (const lineOfInterest of cases) {
@ -5307,8 +5308,8 @@ const part001 = startSketchOn('XZ')
|> startProfileAt([5, 6], %) |> startProfileAt([5, 6], %)
|> ${lineToBeDeleted} |> ${lineToBeDeleted}
|> line([-10, -15], %) |> line([-10, -15], %)
|> angledLine([-176, segLen('seg01', %)], %) |> angledLine([-176, segLen(seg01, %)], %)
${extraLine ? "const myVar = segLen('seg01', part001)" : ''}` ${extraLine ? 'const myVar = segLen(seg01, part001)' : ''}`
) )
}, },
{ {
@ -5394,61 +5395,61 @@ ${extraLine ? "const myVar = segLen('seg01', part001)" : ''}`
test.describe('Testing remove constraints segments', () => { test.describe('Testing remove constraints segments', () => {
const cases = [ const cases = [
{ {
before: `line([22 + 0, 2 + 0], %, 'seg01')`, before: `line([22 + 0, 2 + 0], %, $seg01)`,
after: `line([22, 2], %, 'seg01')`, after: `line([22, 2], %, $seg01)`,
}, },
{ {
before: `angledLine([5 + 0, 23.03 + 0], %, 'seg01')`, before: `angledLine([5 + 0, 23.03 + 0], %, $seg01)`,
after: `line([22.94, 2.01], %, 'seg01')`, after: `line([22.94, 2.01], %, $seg01)`,
}, },
{ {
before: `xLine(23 + 0, %, 'seg01')`, before: `xLine(23 + 0, %, $seg01)`,
after: `line([23, 0], %, 'seg01')`, after: `line([23, 0], %, $seg01)`,
}, },
{ {
before: `yLine(-8 + 0, %, 'seg01')`, before: `yLine(-8 + 0, %, $seg01)`,
after: `line([0, -8], %, 'seg01')`, after: `line([0, -8], %, $seg01)`,
}, },
{ {
before: `xLineTo(30 + 0, %, 'seg01')`, before: `xLineTo(30 + 0, %, $seg01)`,
after: `line([25, 0], %, 'seg01')`, after: `line([25, 0], %, $seg01)`,
}, },
{ {
before: `yLineTo(-4 + 0, %, 'seg01')`, before: `yLineTo(-4 + 0, %, $seg01)`,
after: `line([0, -10], %, 'seg01')`, after: `line([0, -10], %, $seg01)`,
}, },
{ {
before: `angledLineOfXLength([3 + 0, 30 + 0], %, 'seg01')`, before: `angledLineOfXLength([3 + 0, 30 + 0], %, $seg01)`,
after: `line([30, 1.57], %, 'seg01')`, after: `line([30, 1.57], %, $seg01)`,
}, },
{ {
before: `angledLineOfYLength([3 + 0, 1.5 + 0], %, 'seg01')`, before: `angledLineOfYLength([3 + 0, 1.5 + 0], %, $seg01)`,
after: `line([28.62, 1.5], %, 'seg01')`, after: `line([28.62, 1.5], %, $seg01)`,
}, },
{ {
before: `angledLineToX([3 + 0, 30 + 0], %, 'seg01')`, before: `angledLineToX([3 + 0, 30 + 0], %, $seg01)`,
after: `line([25, 1.31], %, 'seg01')`, after: `line([25, 1.31], %, $seg01)`,
}, },
{ {
before: `angledLineToY([3 + 0, 7 + 0], %, 'seg01')`, before: `angledLineToY([3 + 0, 7 + 0], %, $seg01)`,
after: `line([19.08, 1], %, 'seg01')`, after: `line([19.08, 1], %, $seg01)`,
}, },
{ {
before: `angledLineOfXLength({ angle: 3 + 0, length: 30 + 0 }, %, 'seg01')`, before: `angledLineOfXLength({ angle: 3 + 0, length: 30 + 0 }, %, $seg01)`,
after: `line([30, 1.57], %, 'seg01')`, after: `line([30, 1.57], %, $seg01)`,
}, },
{ {
before: `angledLineOfYLength({ angle: 3 + 0, length: 1.5 + 0 }, %, 'seg01')`, before: `angledLineOfYLength({ angle: 3 + 0, length: 1.5 + 0 }, %, $seg01)`,
after: `line([28.62, 1.5], %, 'seg01')`, after: `line([28.62, 1.5], %, $seg01)`,
}, },
{ {
before: `angledLineToX({ angle: 3 + 0, to: 30 + 0 }, %, 'seg01')`, before: `angledLineToX({ angle: 3 + 0, to: 30 + 0 }, %, $seg01)`,
after: `line([25, 1.31], %, 'seg01')`, after: `line([25, 1.31], %, $seg01)`,
}, },
{ {
before: `angledLineToY({ angle: 3 + 0, to: 7 + 0 }, %, 'seg01')`, before: `angledLineToY({ angle: 3 + 0, to: 7 + 0 }, %, $seg01)`,
after: `line([19.08, 1], %, 'seg01')`, after: `line([19.08, 1], %, $seg01)`,
}, },
] ]
@ -5465,7 +5466,7 @@ ${extraLine ? "const myVar = segLen('seg01', part001)" : ''}`
|> startProfileAt([5, 6], %) |> startProfileAt([5, 6], %)
|> ${lineToBeDeleted} |> ${lineToBeDeleted}
|> line([-10, -15], %) |> line([-10, -15], %)
|> angledLine([-176, segLen('seg01', %)], %)` |> angledLine([-176, segLen(seg01, %)], %)`
) )
}, },
{ {
@ -6143,27 +6144,27 @@ const part001 = startSketchOn('-XZ')
|> angledLineToY({ |> angledLineToY({
angle: topAng, angle: topAng,
to: totalHeightHalf, to: totalHeightHalf,
}, %, 'seg04') }, %, $seg04)
|> xLineTo(totalLen, %, 'seg03') |> xLineTo(totalLen, %, $seg03)
|> yLine(-armThick, %, 'seg01') |> yLine(-armThick, %, $seg01)
|> angledLineThatIntersects({ |> angledLineThatIntersects({
angle: HALF_TURN, angle: HALF_TURN,
offset: -armThick, offset: -armThick,
intersectTag: 'seg04' intersectTag: seg04
}, %) }, %)
|> angledLineToY([segAng('seg04', %) + 180, ZERO], %) |> angledLineToY([segAng(seg04, %) + 180, ZERO], %)
|> angledLineToY({ |> angledLineToY({
angle: -bottomAng, angle: -bottomAng,
to: -totalHeightHalf - armThick, to: -totalHeightHalf - armThick,
}, %, 'seg02') }, %, $seg02)
|> xLineTo(segEndX('seg03', %) + 0, %) |> xLineTo(segEndX(seg03, %) + 0, %)
|> yLine(-segLen('seg01', %), %) |> yLine(-segLen(seg01, %), %)
|> angledLineThatIntersects({ |> angledLineThatIntersects({
angle: HALF_TURN, angle: HALF_TURN,
offset: -armThick, offset: -armThick,
intersectTag: 'seg02' intersectTag: seg02
}, %) }, %)
|> angledLineToY([segAng('seg02', %) + 180, -baseHeight], %) |> angledLineToY([segAng(seg02, %) + 180, -baseHeight], %)
|> xLineTo(ZERO, %) |> xLineTo(ZERO, %)
|> close(%) |> close(%)
|> extrude(4, %)` |> extrude(4, %)`

Binary file not shown.

Before

Width:  |  Height:  |  Size: 66 KiB

After

Width:  |  Height:  |  Size: 69 KiB

View File

@ -1783,6 +1783,31 @@ function prepareTruncatedMemoryAndAst(
const programMemoryOverride = programMemoryInit() const programMemoryOverride = programMemoryInit()
if (err(programMemoryOverride)) return programMemoryOverride if (err(programMemoryOverride)) return programMemoryOverride
// Grab all the TagDeclarators and TagIdentifiers from memory.
let start = _node.node.start
for (const key in programMemory.root) {
const value = programMemory.root[key]
if (!('__meta' in value)) {
continue
}
if (
value.__meta === undefined ||
value.__meta.length === 0 ||
value.__meta[0].sourceRange === undefined
) {
continue
}
if (value.__meta[0].sourceRange[0] >= start) {
// We only want things before our start point.
continue
}
if (value.type === 'TagIdentifier') {
programMemoryOverride.root[key] = JSON.parse(JSON.stringify(value))
}
}
for (let i = 0; i < bodyIndex; i++) { for (let i = 0; i < bodyIndex; i++) {
const node = _ast.body[i] const node = _ast.body[i]
if (node.type !== 'VariableDeclaration') { if (node.type !== 'VariableDeclaration') {

View File

@ -128,6 +128,7 @@ export const Stream = ({ className = '' }: { className?: string }) => {
<div <div
className="absolute inset-0 z-0" className="absolute inset-0 z-0"
data-testid="stream" data-testid="stream"
id="stream"
onMouseUp={handleMouseUp} onMouseUp={handleMouseUp}
onMouseDown={handleMouseDown} onMouseDown={handleMouseDown}
onContextMenu={(e) => e.preventDefault()} onContextMenu={(e) => e.preventDefault()}

View File

@ -502,11 +502,10 @@ describe('testing pipe operator special', () => {
}, },
{ type: 'PipeSubstitution', start: 82, end: 83 }, { type: 'PipeSubstitution', start: 82, end: 83 },
{ {
type: 'Literal', type: 'TagDeclarator',
start: 85, start: 85,
end: 93, end: 93,
value: 'myPath', value: 'myPath',
raw: '"myPath"',
}, },
], ],
optional: false, optional: false,
@ -1657,11 +1656,10 @@ describe('should recognise callExpresions in binaryExpressions', () => {
callee: { type: 'Identifier', start: 8, end: 15, name: 'segEndX' }, callee: { type: 'Identifier', start: 8, end: 15, name: 'segEndX' },
arguments: [ arguments: [
{ {
type: 'Literal', type: 'Identifier',
start: 16, start: 16,
end: 23, end: 23,
value: 'seg02', name: 'seg02',
raw: "'seg02'",
}, },
{ type: 'PipeSubstitution', start: 25, end: 26 }, { type: 'PipeSubstitution', start: 25, end: 26 },
], ],

View File

@ -128,7 +128,7 @@ const mySketch001 = startSketchOn('XY')
const sk1 = startSketchOn('XY') const sk1 = startSketchOn('XY')
|> startProfileAt([0, 0], %) |> startProfileAt([0, 0], %)
|> lineTo([-2.5, 0], %) |> lineTo([-2.5, 0], %)
|> lineTo([0, 10], %, "p") |> lineTo([0, 10], %, $p)
|> lineTo([2.5, 0], %) |> lineTo([2.5, 0], %)
// |> rx(45, %) // |> rx(45, %)
// |> translate([1,0,1], %) // |> translate([1,0,1], %)
@ -138,7 +138,7 @@ const theExtrude = extrude(2, sk1)
const sk2 = startSketchOn('XY') const sk2 = startSketchOn('XY')
|> startProfileAt([0, 0], %) |> startProfileAt([0, 0], %)
|> lineTo([-2.5, 0], %) |> lineTo([-2.5, 0], %)
|> lineTo([0, 3], %, "p") |> lineTo([0, 3], %, $o)
|> lineTo([2.5, 0], %) |> lineTo([2.5, 0], %)
// |> transform(theTransf, %) // |> transform(theTransf, %)
|> extrude(2, %) |> extrude(2, %)
@ -163,20 +163,20 @@ const sk2 = startSketchOn('XY')
type: 'extrudePlane', type: 'extrudePlane',
faceId: expect.any(String), faceId: expect.any(String),
tag: { tag: {
end: 117, end: 116,
start: 114, start: 114,
type: 'TagDeclarator', type: 'TagDeclarator',
value: 'p', value: 'p',
}, },
id: expect.any(String), id: expect.any(String),
sourceRange: [95, 118], sourceRange: [95, 117],
}, },
{ {
type: 'extrudePlane', type: 'extrudePlane',
faceId: expect.any(String), faceId: expect.any(String),
tag: null, tag: null,
id: expect.any(String), id: expect.any(String),
sourceRange: [124, 143], sourceRange: [123, 142],
}, },
], ],
sketchGroup: { sketchGroup: {
@ -201,14 +201,14 @@ const sk2 = startSketchOn('XY')
from: [-2.5, 0], from: [-2.5, 0],
to: [0, 10], to: [0, 10],
tag: { tag: {
end: 117, end: 116,
start: 114, start: 114,
type: 'TagDeclarator', type: 'TagDeclarator',
value: 'p', value: 'p',
}, },
__geoMeta: { __geoMeta: {
id: expect.any(String), id: expect.any(String),
sourceRange: [95, 118], sourceRange: [95, 117],
}, },
}, },
{ {
@ -218,7 +218,7 @@ const sk2 = startSketchOn('XY')
tag: null, tag: null,
__geoMeta: { __geoMeta: {
id: expect.any(String), id: expect.any(String),
sourceRange: [124, 143], sourceRange: [123, 142],
}, },
}, },
], ],
@ -237,26 +237,26 @@ const sk2 = startSketchOn('XY')
faceId: expect.any(String), faceId: expect.any(String),
tag: null, tag: null,
id: expect.any(String), id: expect.any(String),
sourceRange: [374, 394], sourceRange: [373, 393],
}, },
{ {
type: 'extrudePlane', type: 'extrudePlane',
faceId: expect.any(String), faceId: expect.any(String),
tag: { tag: {
end: 421, end: 419,
start: 418, start: 417,
type: 'TagDeclarator', type: 'TagDeclarator',
value: 'p', value: 'o',
}, },
id: expect.any(String), id: expect.any(String),
sourceRange: [400, 422], sourceRange: [399, 420],
}, },
{ {
type: 'extrudePlane', type: 'extrudePlane',
faceId: expect.any(String), faceId: expect.any(String),
tag: null, tag: null,
id: expect.any(String), id: expect.any(String),
sourceRange: [428, 447], sourceRange: [426, 445],
}, },
], ],
sketchGroup: { sketchGroup: {
@ -273,7 +273,7 @@ const sk2 = startSketchOn('XY')
tag: null, tag: null,
__geoMeta: { __geoMeta: {
id: expect.any(String), id: expect.any(String),
sourceRange: [374, 394], sourceRange: [373, 393],
}, },
}, },
{ {
@ -281,14 +281,14 @@ const sk2 = startSketchOn('XY')
from: [-2.5, 0], from: [-2.5, 0],
to: [0, 3], to: [0, 3],
tag: { tag: {
end: 421, end: 419,
start: 418, start: 417,
type: 'TagDeclarator', type: 'TagDeclarator',
value: 'p', value: 'o',
}, },
__geoMeta: { __geoMeta: {
id: expect.any(String), id: expect.any(String),
sourceRange: [400, 422], sourceRange: [399, 420],
}, },
}, },
{ {
@ -298,7 +298,7 @@ const sk2 = startSketchOn('XY')
tag: null, tag: null,
__geoMeta: { __geoMeta: {
id: expect.any(String), id: expect.any(String),
sourceRange: [428, 447], sourceRange: [426, 445],
}, },
}, },
], ],
@ -306,7 +306,7 @@ const sk2 = startSketchOn('XY')
height: 2, height: 2,
startCapId: expect.any(String), startCapId: expect.any(String),
endCapId: expect.any(String), endCapId: expect.any(String),
__meta: [{ sourceRange: [343, 368] }], __meta: [{ sourceRange: [342, 367] }],
}, },
]) ])
}) })

View File

@ -163,25 +163,25 @@ describe('Testing giveSketchFnCallTag', () => {
code, code,
'line([0, 0.83], %)' 'line([0, 0.83], %)'
) )
expect(newCode).toContain("line([0, 0.83], %, 'seg01')") expect(newCode).toContain('line([0, 0.83], %, $seg01)')
expect(tag).toBe('seg01') expect(tag).toBe('seg01')
expect(isTagExisting).toBe(false) expect(isTagExisting).toBe(false)
}) })
it('Should create a unique tag if seg01 already exists', () => { it('Should create a unique tag if seg01 already exists', () => {
let _code = code.replace( let _code = code.replace(
'line([-2.57, -0.13], %)', 'line([-2.57, -0.13], %)',
"line([-2.57, -0.13], %, 'seg01')" 'line([-2.57, -0.13], %, $seg01)'
) )
const { newCode, tag, isTagExisting } = giveSketchFnCallTagTestHelper( const { newCode, tag, isTagExisting } = giveSketchFnCallTagTestHelper(
_code, _code,
'line([0, 0.83], %)' 'line([0, 0.83], %)'
) )
expect(newCode).toContain("line([0, 0.83], %, 'seg02')") expect(newCode).toContain('line([0, 0.83], %, $seg02)')
expect(tag).toBe('seg02') expect(tag).toBe('seg02')
expect(isTagExisting).toBe(false) expect(isTagExisting).toBe(false)
}) })
it('Should return existing tag if it already exists', () => { it('Should return existing tag if it already exists', () => {
const lineButWithTag = "line([-2.57, -0.13], %, 'butts')" const lineButWithTag = 'line([-2.57, -0.13], %, $butts)'
let _code = code.replace('line([-2.57, -0.13], %)', lineButWithTag) let _code = code.replace('line([-2.57, -0.13], %)', lineButWithTag)
const { newCode, tag, isTagExisting } = giveSketchFnCallTagTestHelper( const { newCode, tag, isTagExisting } = giveSketchFnCallTagTestHelper(
_code, _code,
@ -328,11 +328,11 @@ describe('testing sketchOnExtrudedFace', () => {
const newCode = recast(modifiedAst) const newCode = recast(modifiedAst)
expect(newCode).toContain(`const part001 = startSketchOn('-XZ') expect(newCode).toContain(`const part001 = startSketchOn('-XZ')
|> startProfileAt([3.58, 2.06], %) |> startProfileAt([3.58, 2.06], %)
|> line([9.7, 9.19], %, 'seg01') |> line([9.7, 9.19], %, $seg01)
|> line([8.62, -9.57], %) |> line([8.62, -9.57], %)
|> close(%) |> close(%)
|> extrude(5 + 7, %) |> extrude(5 + 7, %)
const sketch001 = startSketchOn(part001, 'seg01')`) const sketch001 = startSketchOn(part001, seg01)`)
}) })
test('it should be able to extrude on close segments', async () => { test('it should be able to extrude on close segments', async () => {
const code = `const part001 = startSketchOn('-XZ') const code = `const part001 = startSketchOn('-XZ')
@ -371,9 +371,9 @@ const sketch001 = startSketchOn(part001, 'seg01')`)
|> startProfileAt([3.58, 2.06], %) |> startProfileAt([3.58, 2.06], %)
|> line([9.7, 9.19], %) |> line([9.7, 9.19], %)
|> line([8.62, -9.57], %) |> line([8.62, -9.57], %)
|> close(%, 'seg01') |> close(%, $seg01)
|> extrude(5 + 7, %) |> extrude(5 + 7, %)
const sketch001 = startSketchOn(part001, 'seg01')`) const sketch001 = startSketchOn(part001, seg01)`)
}) })
test('it should be able to extrude on start-end caps', async () => { test('it should be able to extrude on start-end caps', async () => {
const code = `const part001 = startSketchOn('-XZ') const code = `const part001 = startSketchOn('-XZ')
@ -457,7 +457,7 @@ const sketch001 = startSketchOn(part001, 'END')`)
if (err(updatedAst)) throw updatedAst if (err(updatedAst)) throw updatedAst
const newCode = recast(updatedAst.modifiedAst) const newCode = recast(updatedAst.modifiedAst)
expect(newCode).toContain(`const part001 = extrude(5 + 7, sketch001) expect(newCode).toContain(`const part001 = extrude(5 + 7, sketch001)
const sketch002 = startSketchOn(part001, 'seg01')`) const sketch002 = startSketchOn(part001, seg01)`)
}) })
}) })
@ -499,49 +499,49 @@ describe('Testing deleteSegmentFromPipeExpression', () => {
replace2 = '' replace2 = ''
) => `const part001 = startSketchOn('-XZ') ) => `const part001 = startSketchOn('-XZ')
|> startProfileAt([54.78, -95.91], %) |> startProfileAt([54.78, -95.91], %)
|> line([306.21, 198.82], %, 'b') |> line([306.21, 198.82], %, $b)
${!replace1 ? ` |> ${line}\n` : ''} |> angledLine([-65, ${ ${!replace1 ? ` |> ${line}\n` : ''} |> angledLine([-65, ${
!replace1 ? "segLen('a', %)" : replace1 !replace1 ? 'segLen(a, %)' : replace1
}], %) }], %)
|> line([306.21, 198.87], %) |> line([306.21, 198.87], %)
|> angledLine([65, ${!replace2 ? "segAng('a', %)" : replace2}], %) |> angledLine([65, ${!replace2 ? 'segAng(a, %)' : replace2}], %)
|> line([-963.39, -154.67], %) |> line([-963.39, -154.67], %)
` `
test.each([ test.each([
['line', "line([306.21, 198.85], %, 'a')", ['365.11', '33']], ['line', 'line([306.21, 198.85], %, $a)', ['365.11', '33']],
['lineTo', "lineTo([306.21, 198.85], %, 'a')", ['110.48', '119.73']], ['lineTo', 'lineTo([306.21, 198.85], %, $a)', ['110.48', '119.73']],
['yLine', "yLine(198.85, %, 'a')", ['198.85', '90']], ['yLine', 'yLine(198.85, %, $a)', ['198.85', '90']],
['xLine', "xLine(198.85, %, 'a')", ['198.85', '0']], ['xLine', 'xLine(198.85, %, $a)', ['198.85', '0']],
['yLineTo', "yLineTo(198.85, %, 'a')", ['95.94', '90']], ['yLineTo', 'yLineTo(198.85, %, $a)', ['95.94', '90']],
['xLineTo', "xLineTo(198.85, %, 'a')", ['162.14', '180']], ['xLineTo', 'xLineTo(198.85, %, $a)', ['162.14', '180']],
[ [
'angledLine', 'angledLine',
"angledLine({ angle: 45.5, length: 198.85 }, %, 'a')", 'angledLine({ angle: 45.5, length: 198.85 }, %, $a)',
['198.85', '45.5'], ['198.85', '45.5'],
], ],
[ [
'angledLineOfXLength', 'angledLineOfXLength',
"angledLineOfXLength({ angle: 45.5, length: 198.85 }, %, 'a')", 'angledLineOfXLength({ angle: 45.5, length: 198.85 }, %, $a)',
['283.7', '45.5'], ['283.7', '45.5'],
], ],
[ [
'angledLineOfYLength', 'angledLineOfYLength',
"angledLineOfYLength({ angle: 45.5, length: 198.85 }, %, 'a')", 'angledLineOfYLength({ angle: 45.5, length: 198.85 }, %, $a)',
['278.79', '45.5'], ['278.79', '45.5'],
], ],
[ [
'angledLineToX', 'angledLineToX',
"angledLineToX({ angle: 45.5, to: 198.85 }, %, 'a')", 'angledLineToX({ angle: 45.5, to: 198.85 }, %, $a)',
['231.33', '134.5'], ['231.33', '134.5'],
], ],
[ [
'angledLineToY', 'angledLineToY',
"angledLineToY({ angle: 45.5, to: 198.85 }, %, 'a')", 'angledLineToY({ angle: 45.5, to: 198.85 }, %, $a)',
['134.51', '45.5'], ['134.51', '45.5'],
], ],
[ [
'angledLineThatIntersects', 'angledLineThatIntersects',
`angledLineThatIntersects({ angle: 45.5, intersectTag: 'b', offset: 198.85 }, %, 'a')`, `angledLineThatIntersects({ angle: 45.5, intersectTag: b, offset: 198.85 }, %, $a)`,
['918.4', '45.5'], ['918.4', '45.5'],
], ],
])(`%s`, async (_, line, [replace1, replace2]) => { ])(`%s`, async (_, line, [replace1, replace2]) => {
@ -579,7 +579,7 @@ describe('Testing removeSingleConstraintInfo', () => {
|> lineTo([6.14 + 0, 3.14 + 0], %) |> lineTo([6.14 + 0, 3.14 + 0], %)
|> xLineTo(8 + 0, %) |> xLineTo(8 + 0, %)
|> yLineTo(5 + 0, %) |> yLineTo(5 + 0, %)
|> yLine(3.14 + 0, %, 'a') |> yLine(3.14 + 0, %, $a)
|> xLine(3.14 + 0, %) |> xLine(3.14 + 0, %)
|> angledLineOfXLength({ angle: 3 + 0, length: 3.14 + 0 }, %) |> angledLineOfXLength({ angle: 3 + 0, length: 3.14 + 0 }, %)
|> angledLineOfYLength({ angle: 30 + 0, length: 3 + 0 }, %) |> angledLineOfYLength({ angle: 30 + 0, length: 3 + 0 }, %)
@ -587,7 +587,7 @@ describe('Testing removeSingleConstraintInfo', () => {
|> angledLineToY({ angle: 30 + 0, to: 10.14 + 0 }, %) |> angledLineToY({ angle: 30 + 0, to: 10.14 + 0 }, %)
|> angledLineThatIntersects({ |> angledLineThatIntersects({
angle: 3.14 + 0, angle: 3.14 + 0,
intersectTag: 'a', intersectTag: a,
offset: 0 + 0 offset: 0 + 0
}, %) }, %)
|> tangentialArcTo([3.14 + 0, 13.14 + 0], %)` |> tangentialArcTo([3.14 + 0, 13.14 + 0], %)`
@ -601,7 +601,7 @@ describe('Testing removeSingleConstraintInfo', () => {
['lineTo([6.14, 3.14 + 0], %)', 'arrayIndex', 0], ['lineTo([6.14, 3.14 + 0], %)', 'arrayIndex', 0],
['xLineTo(8, %)', '', ''], ['xLineTo(8, %)', '', ''],
['yLineTo(5, %)', '', ''], ['yLineTo(5, %)', '', ''],
["yLine(3.14, %, 'a')", '', ''], ['yLine(3.14, %, $a)', '', ''],
['xLine(3.14, %)', '', ''], ['xLine(3.14, %)', '', ''],
[ [
'angledLineOfXLength({ angle: 3, length: 3.14 + 0 }, %)', 'angledLineOfXLength({ angle: 3, length: 3.14 + 0 }, %)',
@ -627,7 +627,7 @@ describe('Testing removeSingleConstraintInfo', () => {
`angledLineThatIntersects({ `angledLineThatIntersects({
angle: 3.14 + 0, angle: 3.14 + 0,
offset: 0, offset: 0,
intersectTag: 'a' intersectTag: a
}, %)`, }, %)`,
'objectProperty', 'objectProperty',
'offset', 'offset',

View File

@ -37,6 +37,7 @@ import { DefaultPlaneStr } from 'clientSideScene/sceneEntities'
import { isOverlap, roundOff } from 'lib/utils' import { isOverlap, roundOff } from 'lib/utils'
import { KCL_DEFAULT_CONSTANT_PREFIXES } from 'lib/constants' import { KCL_DEFAULT_CONSTANT_PREFIXES } from 'lib/constants'
import { ConstrainInfo } from './std/stdTypes' import { ConstrainInfo } from './std/stdTypes'
import { TagDeclarator } from 'wasm-lib/kcl/bindings/TagDeclarator'
export function startSketchOnDefault( export function startSketchOnDefault(
node: Program, node: Program,
@ -379,7 +380,7 @@ export function sketchOnExtrudedFace(
const { node: extrudeVarDec } = _node3 const { node: extrudeVarDec } = _node3
const extrudeName = extrudeVarDec.id?.name const extrudeName = extrudeVarDec.id?.name
let _tag = '' let _tag = null
if (cap === 'none') { if (cap === 'none') {
const __tag = addTagForSketchOnFace( const __tag = addTagForSketchOnFace(
{ {
@ -391,17 +392,17 @@ export function sketchOnExtrudedFace(
) )
if (err(__tag)) return __tag if (err(__tag)) return __tag
const { modifiedAst, tag } = __tag const { modifiedAst, tag } = __tag
_tag = tag _tag = createIdentifier(tag)
_node = modifiedAst _node = modifiedAst
} else { } else {
_tag = cap.toUpperCase() _tag = createLiteral(cap.toUpperCase())
} }
const newSketch = createVariableDeclaration( const newSketch = createVariableDeclaration(
newSketchName, newSketchName,
createCallExpressionStdLib('startSketchOn', [ createCallExpressionStdLib('startSketchOn', [
createIdentifier(extrudeName ? extrudeName : oldSketchName), createIdentifier(extrudeName ? extrudeName : oldSketchName),
createLiteral(_tag), _tag,
]), ]),
'const' 'const'
) )
@ -483,6 +484,15 @@ export function createLiteral(value: string | number): Literal {
} }
} }
export function createTagDeclarator(value: string): TagDeclarator {
return {
type: 'TagDeclarator',
start: 0,
end: 0,
value,
}
}
export function createIdentifier(name: string): Identifier { export function createIdentifier(name: string): Identifier {
return { return {
type: 'Identifier', type: 'Identifier',
@ -657,17 +667,18 @@ export function giveSketchFnCallTag(
// Tag is always 3rd expression now, using arg index feels brittle // Tag is always 3rd expression now, using arg index feels brittle
// but we can come up with a better way to identify tag later. // but we can come up with a better way to identify tag later.
const thirdArg = primaryCallExp.arguments?.[2] const thirdArg = primaryCallExp.arguments?.[2]
const tagLiteral = const tagDeclarator =
thirdArg || (createLiteral(tag || findUniqueName(ast, 'seg', 2)) as Literal) thirdArg ||
(createTagDeclarator(tag || findUniqueName(ast, 'seg', 2)) as TagDeclarator)
const isTagExisting = !!thirdArg const isTagExisting = !!thirdArg
if (!isTagExisting) { if (!isTagExisting) {
primaryCallExp.arguments[2] = tagLiteral primaryCallExp.arguments[2] = tagDeclarator
} }
if ('value' in tagLiteral) { if ('value' in tagDeclarator) {
// Now TypeScript knows tagLiteral has a value property // Now TypeScript knows tagDeclarator has a value property
return { return {
modifiedAst: ast, modifiedAst: ast,
tag: String(tagLiteral.value), tag: String(tagDeclarator.value),
isTagExisting, isTagExisting,
pathToNode: path, pathToNode: path,
} }

View File

@ -19,6 +19,7 @@ import {
createPipeSubstitution, createPipeSubstitution,
} from './modifyAst' } from './modifyAst'
import { err } from 'lib/trap' import { err } from 'lib/trap'
import { warn } from 'node:console'
beforeAll(async () => { beforeAll(async () => {
await initPromise await initPromise
@ -412,15 +413,15 @@ describe('Testing findUsesOfTagInPipe', () => {
const exampleCode = `const part001 = startSketchOn('-XZ') const exampleCode = `const part001 = startSketchOn('-XZ')
|> startProfileAt([68.12, 156.65], %) |> startProfileAt([68.12, 156.65], %)
|> line([306.21, 198.82], %) |> line([306.21, 198.82], %)
|> line([306.21, 198.85], %, 'seg01') |> line([306.21, 198.85], %, $seg01)
|> angledLine([-65, segLen('seg01', %)], %) |> angledLine([-65, segLen(seg01, %)], %)
|> line([306.21, 198.87], %) |> line([306.21, 198.87], %)
|> angledLine([65, segLen('seg01', %)], %)` |> angledLine([65, segLen(seg01, %)], %)`
it('finds the current segment', async () => { it('finds the current segment', async () => {
const ast = parse(exampleCode) const ast = parse(exampleCode)
if (err(ast)) throw ast if (err(ast)) throw ast
const lineOfInterest = `198.85], %, 'seg01'` const lineOfInterest = `198.85], %, $seg01`
const characterIndex = const characterIndex =
exampleCode.indexOf(lineOfInterest) + lineOfInterest.length exampleCode.indexOf(lineOfInterest) + lineOfInterest.length
const pathToNode = getNodePathFromSourceRange(ast, [ const pathToNode = getNodePathFromSourceRange(ast, [
@ -455,7 +456,7 @@ describe('Testing hasSketchPipeBeenExtruded', () => {
|> line([2.48, 2.44], %) |> line([2.48, 2.44], %)
|> line([2.66, 1.17], %) |> line([2.66, 1.17], %)
|> line([3.75, 0.46], %) |> line([3.75, 0.46], %)
|> line([4.99, -0.46], %, 'seg01') |> line([4.99, -0.46], %, $seg01)
|> line([3.3, -2.12], %) |> line([3.3, -2.12], %)
|> line([2.16, -3.33], %) |> line([2.16, -3.33], %)
|> line([0.85, -3.08], %) |> line([0.85, -3.08], %)
@ -464,7 +465,7 @@ describe('Testing hasSketchPipeBeenExtruded', () => {
|> line([-17.67, 0.85], %) |> line([-17.67, 0.85], %)
|> close(%) |> close(%)
const extrude001 = extrude(10, sketch001) const extrude001 = extrude(10, sketch001)
const sketch002 = startSketchOn(extrude001, 'seg01') const sketch002 = startSketchOn(extrude001, $seg01)
|> startProfileAt([-12.94, 6.6], %) |> startProfileAt([-12.94, 6.6], %)
|> line([2.45, -0.2], %) |> line([2.45, -0.2], %)
|> line([-2, -1.25], %) |> line([-2, -1.25], %)
@ -474,7 +475,7 @@ const sketch002 = startSketchOn(extrude001, 'seg01')
it('finds sketch001 pipe to be extruded', async () => { it('finds sketch001 pipe to be extruded', async () => {
const ast = parse(exampleCode) const ast = parse(exampleCode)
if (err(ast)) throw ast if (err(ast)) throw ast
const lineOfInterest = `line([4.99, -0.46], %, 'seg01')` const lineOfInterest = `line([4.99, -0.46], %, $seg01)`
const characterIndex = const characterIndex =
exampleCode.indexOf(lineOfInterest) + lineOfInterest.length exampleCode.indexOf(lineOfInterest) + lineOfInterest.length
const extruded = hasSketchPipeBeenExtruded( const extruded = hasSketchPipeBeenExtruded(
@ -512,7 +513,7 @@ describe('Testing hasExtrudableGeometry', () => {
|> line([-17.67, 0.85], %) |> line([-17.67, 0.85], %)
|> close(%) |> close(%)
const extrude001 = extrude(10, sketch001) const extrude001 = extrude(10, sketch001)
const sketch002 = startSketchOn(extrude001, 'seg01') const sketch002 = startSketchOn(extrude001, $seg01)
|> startProfileAt([-12.94, 6.6], %) |> startProfileAt([-12.94, 6.6], %)
|> line([2.45, -0.2], %) |> line([2.45, -0.2], %)
|> line([-2, -1.25], %) |> line([-2, -1.25], %)

View File

@ -365,6 +365,8 @@ export function traverse(
// do nothing // do nothing
} else if (_node.type === 'Literal') { } else if (_node.type === 'Literal') {
// do nothing // do nothing
} else if (_node.type === 'TagDeclarator') {
// do nothing
} else if (_node.type === 'ArrayExpression') { } else if (_node.type === 'ArrayExpression') {
_node.elements.forEach((el, index) => _node.elements.forEach((el, index) =>
_traverse(el, [ _traverse(el, [
@ -785,8 +787,14 @@ export function findUsesOfTagInPipe(
if (node.type !== 'CallExpression') return [] if (node.type !== 'CallExpression') return []
const tagIndex = node.callee.name === 'close' ? 1 : 2 const tagIndex = node.callee.name === 'close' ? 1 : 2
const thirdParam = node.arguments[tagIndex] const thirdParam = node.arguments[tagIndex]
if (thirdParam?.type !== 'Literal') return [] if (
const tag = String(thirdParam.value) !(thirdParam?.type === 'TagDeclarator' || thirdParam?.type === 'Identifier')
)
return []
const tag =
thirdParam?.type === 'TagDeclarator'
? String(thirdParam.value)
: thirdParam.name
const varDec = getNodeFromPath<VariableDeclaration>( const varDec = getNodeFromPath<VariableDeclaration>(
ast, ast,
@ -807,9 +815,11 @@ export function findUsesOfTagInPipe(
) )
return return
const tagArg = node.arguments[0] const tagArg = node.arguments[0]
if (tagArg.type !== 'Literal') return if (!(tagArg.type === 'TagDeclarator' || tagArg.type === 'Identifier'))
if (String(tagArg.value) === tag) return
dependentRanges.push([node.start, node.end]) const tagArgValue =
tagArg.type === 'TagDeclarator' ? String(tagArg.value) : tagArg.name
if (tagArgValue === tag) dependentRanges.push([node.start, node.end])
}, },
}) })
return dependentRanges return dependentRanges

View File

@ -76,9 +76,9 @@ log(5, myVar)
}) })
it('recast sketch declaration', () => { it('recast sketch declaration', () => {
let code = `const mySketch = startSketchAt([0, 0]) let code = `const mySketch = startSketchAt([0, 0])
|> lineTo([0, 1], %, "myPath") |> lineTo([0, 1], %, $myPath)
|> lineTo([1, 1], %) |> lineTo([1, 1], %)
|> lineTo([1, 0], %, "rightPath") |> lineTo([1, 0], %, $rightPath)
|> close(%) |> close(%)
` `
const { ast } = code2ast(code) const { ast } = code2ast(code)
@ -90,7 +90,7 @@ log(5, myVar)
const code = [ const code = [
'const mySk1 = startSketchAt([0, 0])', 'const mySk1 = startSketchAt([0, 0])',
' |> lineTo([1, 1], %)', ' |> lineTo([1, 1], %)',
' |> lineTo([0, 1], %, "myTag")', ' |> lineTo([0, 1], %, $myTag)',
' |> lineTo([1, 1], %)', ' |> lineTo([1, 1], %)',
' |> rx(90, %)', ' |> rx(90, %)',
].join('\n') ].join('\n')
@ -266,7 +266,7 @@ const key = 'c'
const code = [ const code = [
'const mySk1 = startSketchAt([0, 0])', 'const mySk1 = startSketchAt([0, 0])',
' |> lineTo([1, 1], %)', ' |> lineTo([1, 1], %)',
' |> lineTo([0, 1], %, "myTag")', ' |> lineTo([0, 1], %, $myTag)',
' |> lineTo([1, 1], %)', ' |> lineTo([1, 1], %)',
' // a comment', ' // a comment',
' |> rx(90, %)', ' |> rx(90, %)',
@ -283,7 +283,7 @@ const key = 'c'
const mySk1 = startSketchAt([0, 0]) const mySk1 = startSketchAt([0, 0])
|> lineTo([1, 1], %) |> lineTo([1, 1], %)
// comment here // comment here
|> lineTo([0, 1], %, 'myTag') |> lineTo([0, 1], %, $myTag)
|> lineTo([1, 1], %) /* and |> lineTo([1, 1], %) /* and
here here
*/ */
@ -306,7 +306,7 @@ one more for good measure
const mySk1 = startSketchAt([0, 0]) const mySk1 = startSketchAt([0, 0])
|> lineTo([1, 1], %) |> lineTo([1, 1], %)
// comment here // comment here
|> lineTo([0, 1], %, 'myTag') |> lineTo([0, 1], %, $myTag)
|> lineTo([1, 1], %) /* and |> lineTo([1, 1], %) /* and
here */ here */
// a comment between pipe expression statements // a comment between pipe expression statements
@ -356,12 +356,12 @@ describe('testing call Expressions in BinaryExpressions and UnaryExpressions', (
describe('it recasts wrapped object expressions in pipe bodies with correct indentation', () => { describe('it recasts wrapped object expressions in pipe bodies with correct indentation', () => {
it('with a single line', () => { it('with a single line', () => {
const code = `const part001 = startSketchAt([-0.01, -0.08]) const code = `const part001 = startSketchAt([-0.01, -0.08])
|> line([0.62, 4.15], %, 'seg01') |> line([0.62, 4.15], %, $seg01)
|> line([2.77, -1.24], %) |> line([2.77, -1.24], %)
|> angledLineThatIntersects({ |> angledLineThatIntersects({
angle: 201, angle: 201,
offset: -1.35, offset: -1.35,
intersectTag: 'seg01' intersectTag: $seg01
}, %) }, %)
|> line([-0.42, -1.72], %) |> line([-0.42, -1.72], %)
` `
@ -374,7 +374,7 @@ describe('it recasts wrapped object expressions in pipe bodies with correct inde
const code = `angledLineThatIntersects({ const code = `angledLineThatIntersects({
angle: 201, angle: 201,
offset: -1.35, offset: -1.35,
intersectTag: 'seg01' intersectTag: $seg01
}, %) }, %)
` `
const { ast } = code2ast(code) const { ast } = code2ast(code)

View File

@ -230,7 +230,7 @@ describe('testing addTagForSketchOnFace', () => {
if (err(sketchOnFaceRetVal)) return sketchOnFaceRetVal if (err(sketchOnFaceRetVal)) return sketchOnFaceRetVal
const { modifiedAst } = sketchOnFaceRetVal const { modifiedAst } = sketchOnFaceRetVal
const expectedCode = genCode("lineTo([-1.59, -1.54], %, 'seg01')") const expectedCode = genCode('lineTo([-1.59, -1.54], %, $seg01)')
expect(recast(modifiedAst)).toBe(expectedCode) expect(recast(modifiedAst)).toBe(expectedCode)
}) })
}) })

View File

@ -11,6 +11,7 @@ import {
Value, Value,
Literal, Literal,
VariableDeclaration, VariableDeclaration,
Identifier,
} from 'lang/wasm' } from 'lang/wasm'
import { import {
getNodeFromPath, getNodeFromPath,
@ -23,7 +24,11 @@ import {
isNotLiteralArrayOrStatic, isNotLiteralArrayOrStatic,
} from 'lang/std/sketchcombos' } from 'lang/std/sketchcombos'
import { toolTips, ToolTip } from '../../useStore' import { toolTips, ToolTip } from '../../useStore'
import { createPipeExpression, splitPathAtPipeExpression } from '../modifyAst' import {
createIdentifier,
createPipeExpression,
splitPathAtPipeExpression,
} from '../modifyAst'
import { import {
SketchLineHelper, SketchLineHelper,
@ -40,6 +45,7 @@ import {
import { import {
createLiteral, createLiteral,
createTagDeclarator,
createCallExpression, createCallExpression,
createArrayExpression, createArrayExpression,
createPipeSubstitution, createPipeSubstitution,
@ -51,6 +57,7 @@ import {
import { roundOff, getLength, getAngle } from 'lib/utils' import { roundOff, getLength, getAngle } from 'lib/utils'
import { err } from 'lib/trap' import { err } from 'lib/trap'
import { perpendicularDistance } from 'sketch-helpers' import { perpendicularDistance } from 'sketch-helpers'
import { TagDeclarator } from 'wasm-lib/kcl/bindings/TagDeclarator'
export type Coords2d = [number, number] export type Coords2d = [number, number]
@ -1406,7 +1413,7 @@ export const angledLineThatIntersects: SketchLineHelper = {
?.value || createLiteral('') ?.value || createLiteral('')
: createLiteral('') : createLiteral('')
const intersectTagName = const intersectTagName =
intersectTag.type === 'Literal' ? intersectTag.value : '' intersectTag.type === 'Identifier' ? intersectTag.name : ''
const nodeMeta2 = getNodeFromPath<VariableDeclaration>( const nodeMeta2 = getNodeFromPath<VariableDeclaration>(
_node, _node,
pathToNode, pathToNode,
@ -1497,23 +1504,23 @@ export const angledLineThatIntersects: SketchLineHelper = {
) )
} }
if (intersectTag !== -1) { if (intersectTag !== -1) {
const tag = firstArg.properties[intersectTag]?.value const tag = firstArg.properties[intersectTag]?.value as Identifier
const pathToTagProp: PathToNode = [ const pathToTagProp: PathToNode = [
...pathToObjectExp, ...pathToObjectExp,
[intersectTag, 'index'], [intersectTag, 'index'],
['value', 'Property'], ['value', 'Property'],
] ]
returnVal.push( const info = constrainInfo(
constrainInfo(
'intersectionTag', 'intersectionTag',
isNotLiteralArrayOrStatic(tag), // This will always be a tag identifier.
false,
code.slice(tag.start, tag.end), code.slice(tag.start, tag.end),
'angledLineThatIntersects', 'angledLineThatIntersects',
'intersectTag', 'intersectTag',
[tag.start, tag.end], [tag.start, tag.end],
pathToTagProp pathToTagProp
) )
) returnVal.push(info)
} }
return returnVal return returnVal
}, },
@ -1830,17 +1837,18 @@ function addTag(tagIndex = 2): addTagFn {
// Tag is always 3rd expression now, using arg index feels brittle // Tag is always 3rd expression now, using arg index feels brittle
// but we can come up with a better way to identify tag later. // but we can come up with a better way to identify tag later.
const thirdArg = primaryCallExp.arguments?.[tagIndex] const thirdArg = primaryCallExp.arguments?.[tagIndex]
const tagLiteral = const tagDeclarator =
thirdArg || (createLiteral(findUniqueName(_node, 'seg', 2)) as Literal) thirdArg ||
(createTagDeclarator(findUniqueName(_node, 'seg', 2)) as TagDeclarator)
const isTagExisting = !!thirdArg const isTagExisting = !!thirdArg
if (!isTagExisting) { if (!isTagExisting) {
primaryCallExp.arguments[tagIndex] = tagLiteral primaryCallExp.arguments[tagIndex] = tagDeclarator
} }
if ('value' in tagLiteral) { if ('value' in tagDeclarator) {
// Now TypeScript knows tagLiteral has a value property // Now TypeScript knows tagDeclarator has a value property
return { return {
modifiedAst: _node, modifiedAst: _node,
tag: String(tagLiteral.value), tag: String(tagDeclarator.value),
} }
} else { } else {
return new Error('Unable to assign tag without value') return new Error('Unable to assign tag without value')

View File

@ -65,17 +65,17 @@ describe('testing swapping out sketch calls with xLine/xLineTo', () => {
const bigExampleArr = [ const bigExampleArr = [
`const part001 = startSketchOn('XY')`, `const part001 = startSketchOn('XY')`,
` |> startProfileAt([0, 0], %)`, ` |> startProfileAt([0, 0], %)`,
` |> lineTo([1, 1], %, 'abc1')`, ` |> lineTo([1, 1], %, $abc1)`,
` |> line([-2.04, -0.7], %, 'abc2')`, ` |> line([-2.04, -0.7], %, $abc2)`,
` |> angledLine({ angle: 157, length: 1.69 }, %, 'abc3')`, ` |> angledLine({ angle: 157, length: 1.69 }, %, $abc3)`,
` |> angledLineOfXLength({ angle: 217, length: 0.86 }, %, 'abc4')`, ` |> angledLineOfXLength({ angle: 217, length: 0.86 }, %, $abc4)`,
` |> angledLineOfYLength({ angle: 104, length: 1.58 }, %, 'abc5')`, ` |> angledLineOfYLength({ angle: 104, length: 1.58 }, %, $abc5)`,
` |> angledLineToX({ angle: 55, to: -2.89 }, %, 'abc6')`, ` |> angledLineToX({ angle: 55, to: -2.89 }, %, $abc6)`,
` |> angledLineToY({ angle: 330, to: 2.53 }, %, 'abc7')`, ` |> angledLineToY({ angle: 330, to: 2.53 }, %, $abc7)`,
` |> xLine(1.47, %, 'abc8')`, ` |> xLine(1.47, %, $abc8)`,
` |> yLine(1.57, %, 'abc9')`, ` |> yLine(1.57, %, $abc9)`,
` |> xLineTo(1.49, %, 'abc10')`, ` |> xLineTo(1.49, %, $abc10)`,
` |> yLineTo(2.64, %, 'abc11')`, ` |> yLineTo(2.64, %, $abc11)`,
` |> lineTo([2.55, 3.58], %) // lineTo`, ` |> lineTo([2.55, 3.58], %) // lineTo`,
` |> line([0.73, -0.75], %)`, ` |> line([0.73, -0.75], %)`,
` |> angledLine([63, 1.38], %) // angledLine`, ` |> angledLine([63, 1.38], %) // angledLine`,
@ -90,8 +90,8 @@ describe('testing swapping out sketch calls with xLine/xLineTo', () => {
] ]
const bigExample = bigExampleArr.join('\n') const bigExample = bigExampleArr.join('\n')
it('line with tag converts to xLine', async () => { it('line with tag converts to xLine', async () => {
const callToSwap = "line([-2.04, -0.7], %, 'abc2')" const callToSwap = 'line([-2.04, -0.7], %, $abc2)'
const expectedLine = "xLine(-2.04, %, 'abc2')" const expectedLine = 'xLine(-2.04, %, $abc2)'
const { newCode, originalRange } = await testingSwapSketchFnCall({ const { newCode, originalRange } = await testingSwapSketchFnCall({
inputCode: bigExample, inputCode: bigExample,
callToSwap, callToSwap,
@ -116,10 +116,10 @@ describe('testing swapping out sketch calls with xLine/xLineTo', () => {
it('lineTo with tag converts to xLineTo', async () => { it('lineTo with tag converts to xLineTo', async () => {
const { newCode, originalRange } = await testingSwapSketchFnCall({ const { newCode, originalRange } = await testingSwapSketchFnCall({
inputCode: bigExample, inputCode: bigExample,
callToSwap: "lineTo([1, 1], %, 'abc1')", callToSwap: 'lineTo([1, 1], %, $abc1)',
constraintType: 'horizontal', constraintType: 'horizontal',
}) })
const expectedLine = "xLineTo(1, %, 'abc1')" const expectedLine = 'xLineTo(1, %, $abc1)'
expect(newCode).toContain(expectedLine) expect(newCode).toContain(expectedLine)
// new line should start at the same place as the old line // new line should start at the same place as the old line
expect(originalRange[0]).toBe(newCode.indexOf(expectedLine)) expect(originalRange[0]).toBe(newCode.indexOf(expectedLine))
@ -138,10 +138,10 @@ describe('testing swapping out sketch calls with xLine/xLineTo', () => {
it('angledLine with tag converts to xLine', async () => { it('angledLine with tag converts to xLine', async () => {
const { newCode, originalRange } = await testingSwapSketchFnCall({ const { newCode, originalRange } = await testingSwapSketchFnCall({
inputCode: bigExample, inputCode: bigExample,
callToSwap: "angledLine({ angle: 157, length: 1.69 }, %, 'abc3')", callToSwap: 'angledLine({ angle: 157, length: 1.69 }, %, $abc3)',
constraintType: 'horizontal', constraintType: 'horizontal',
}) })
const expectedLine = "xLine(-1.56, %, 'abc3')" const expectedLine = 'xLine(-1.56, %, $abc3)'
console.log(newCode) console.log(newCode)
expect(newCode).toContain(expectedLine) expect(newCode).toContain(expectedLine)
// new line should start at the same place as the old line // new line should start at the same place as the old line
@ -161,11 +161,10 @@ describe('testing swapping out sketch calls with xLine/xLineTo', () => {
it('angledLineOfXLength with tag converts to xLine', async () => { it('angledLineOfXLength with tag converts to xLine', async () => {
const { newCode, originalRange } = await testingSwapSketchFnCall({ const { newCode, originalRange } = await testingSwapSketchFnCall({
inputCode: bigExample, inputCode: bigExample,
callToSwap: callToSwap: 'angledLineOfXLength({ angle: 217, length: 0.86 }, %, $abc4)',
"angledLineOfXLength({ angle: 217, length: 0.86 }, %, 'abc4')",
constraintType: 'horizontal', constraintType: 'horizontal',
}) })
const expectedLine = "xLine(-0.86, %, 'abc4')" const expectedLine = 'xLine(-0.86, %, $abc4)'
// hmm "-0.86" is correct since the angle is 104, but need to make sure this is compatible `-myVar` // hmm "-0.86" is correct since the angle is 104, but need to make sure this is compatible `-myVar`
expect(newCode).toContain(expectedLine) expect(newCode).toContain(expectedLine)
// new line should start at the same place as the old line // new line should start at the same place as the old line
@ -185,11 +184,10 @@ describe('testing swapping out sketch calls with xLine/xLineTo', () => {
it('angledLineOfYLength with tag converts to yLine', async () => { it('angledLineOfYLength with tag converts to yLine', async () => {
const { newCode, originalRange } = await testingSwapSketchFnCall({ const { newCode, originalRange } = await testingSwapSketchFnCall({
inputCode: bigExample, inputCode: bigExample,
callToSwap: callToSwap: 'angledLineOfYLength({ angle: 104, length: 1.58 }, %, $abc5)',
"angledLineOfYLength({ angle: 104, length: 1.58 }, %, 'abc5')",
constraintType: 'vertical', constraintType: 'vertical',
}) })
const expectedLine = "yLine(1.58, %, 'abc5')" const expectedLine = 'yLine(1.58, %, $abc5)'
expect(newCode).toContain(expectedLine) expect(newCode).toContain(expectedLine)
// new line should start at the same place as the old line // new line should start at the same place as the old line
expect(originalRange[0]).toBe(newCode.indexOf(expectedLine)) expect(originalRange[0]).toBe(newCode.indexOf(expectedLine))
@ -208,10 +206,10 @@ describe('testing swapping out sketch calls with xLine/xLineTo', () => {
it('angledLineToX with tag converts to xLineTo', async () => { it('angledLineToX with tag converts to xLineTo', async () => {
const { newCode, originalRange } = await testingSwapSketchFnCall({ const { newCode, originalRange } = await testingSwapSketchFnCall({
inputCode: bigExample, inputCode: bigExample,
callToSwap: "angledLineToX({ angle: 55, to: -2.89 }, %, 'abc6')", callToSwap: 'angledLineToX({ angle: 55, to: -2.89 }, %, $abc6)',
constraintType: 'horizontal', constraintType: 'horizontal',
}) })
const expectedLine = "xLineTo(-2.89, %, 'abc6')" const expectedLine = 'xLineTo(-2.89, %, $abc6)'
expect(newCode).toContain(expectedLine) expect(newCode).toContain(expectedLine)
// new line should start at the same place as the old line // new line should start at the same place as the old line
expect(originalRange[0]).toBe(newCode.indexOf(expectedLine)) expect(originalRange[0]).toBe(newCode.indexOf(expectedLine))
@ -230,10 +228,10 @@ describe('testing swapping out sketch calls with xLine/xLineTo', () => {
it('angledLineToY with tag converts to yLineTo', async () => { it('angledLineToY with tag converts to yLineTo', async () => {
const { newCode, originalRange } = await testingSwapSketchFnCall({ const { newCode, originalRange } = await testingSwapSketchFnCall({
inputCode: bigExample, inputCode: bigExample,
callToSwap: "angledLineToY({ angle: 330, to: 2.53 }, %, 'abc7')", callToSwap: 'angledLineToY({ angle: 330, to: 2.53 }, %, $abc7)',
constraintType: 'vertical', constraintType: 'vertical',
}) })
const expectedLine = "yLineTo(2.53, %, 'abc7')" const expectedLine = 'yLineTo(2.53, %, $abc7)'
expect(newCode).toContain(expectedLine) expect(newCode).toContain(expectedLine)
// new line should start at the same place as the old line // new line should start at the same place as the old line
expect(originalRange[0]).toBe(newCode.indexOf(expectedLine)) expect(originalRange[0]).toBe(newCode.indexOf(expectedLine))

View File

@ -139,70 +139,70 @@ const myAng = 40
const myAng2 = 134 const myAng2 = 134
const part001 = startSketchOn('XY') const part001 = startSketchOn('XY')
|> startProfileAt([0, 0], %) |> startProfileAt([0, 0], %)
|> line([1, 3.82], %, 'seg01') // ln-should-get-tag |> line([1, 3.82], %, $seg01) // ln-should-get-tag
|> angledLineToX([ |> angledLineToX([
-angleToMatchLengthX('seg01', myVar, %), -angleToMatchLengthX(seg01, myVar, %),
myVar myVar
], %) // ln-lineTo-xAbsolute should use angleToMatchLengthX helper ], %) // ln-lineTo-xAbsolute should use angleToMatchLengthX helper
|> angledLineToY([ |> angledLineToY([
-angleToMatchLengthY('seg01', myVar, %), -angleToMatchLengthY(seg01, myVar, %),
myVar myVar
], %) // ln-lineTo-yAbsolute should use angleToMatchLengthY helper ], %) // ln-lineTo-yAbsolute should use angleToMatchLengthY helper
|> angledLine([45, segLen('seg01', %)], %) // ln-lineTo-free should become angledLine |> angledLine([45, segLen(seg01, %)], %) // ln-lineTo-free should become angledLine
|> angledLine([45, segLen('seg01', %)], %) // ln-angledLineToX-free should become angledLine |> angledLine([45, segLen(seg01, %)], %) // ln-angledLineToX-free should become angledLine
|> angledLine([myAng, segLen('seg01', %)], %) // ln-angledLineToX-angle should become angledLine |> angledLine([myAng, segLen(seg01, %)], %) // ln-angledLineToX-angle should become angledLine
|> angledLineToX([ |> angledLineToX([
angleToMatchLengthX('seg01', myVar2, %), angleToMatchLengthX(seg01, myVar2, %),
myVar2 myVar2
], %) // ln-angledLineToX-xAbsolute should use angleToMatchLengthX to get angle ], %) // ln-angledLineToX-xAbsolute should use angleToMatchLengthX to get angle
|> angledLine([-45, segLen('seg01', %)], %) // ln-angledLineToY-free should become angledLine |> angledLine([-45, segLen(seg01, %)], %) // ln-angledLineToY-free should become angledLine
|> angledLine([myAng2, segLen('seg01', %)], %) // ln-angledLineToY-angle should become angledLine |> angledLine([myAng2, segLen(seg01, %)], %) // ln-angledLineToY-angle should become angledLine
|> angledLineToY([ |> angledLineToY([
angleToMatchLengthY('seg01', myVar3, %), angleToMatchLengthY(seg01, myVar3, %),
myVar3 myVar3
], %) // ln-angledLineToY-yAbsolute should use angleToMatchLengthY to get angle ], %) // ln-angledLineToY-yAbsolute should use angleToMatchLengthY to get angle
|> line([ |> line([
min(segLen('seg01', %), myVar), min(segLen(seg01, %), myVar),
legLen(segLen('seg01', %), myVar) legLen(segLen(seg01, %), myVar)
], %) // ln-should use legLen for y ], %) // ln-should use legLen for y
|> line([ |> line([
min(segLen('seg01', %), myVar), min(segLen(seg01, %), myVar),
-legLen(segLen('seg01', %), myVar) -legLen(segLen(seg01, %), myVar)
], %) // ln-legLen but negative ], %) // ln-legLen but negative
|> angledLine([-112, segLen('seg01', %)], %) // ln-should become angledLine |> angledLine([-112, segLen(seg01, %)], %) // ln-should become angledLine
|> angledLine([myVar, segLen('seg01', %)], %) // ln-use segLen for second arg |> angledLine([myVar, segLen(seg01, %)], %) // ln-use segLen for second arg
|> angledLine([45, segLen('seg01', %)], %) // ln-segLen again |> angledLine([45, segLen(seg01, %)], %) // ln-segLen again
|> angledLine([54, segLen('seg01', %)], %) // ln-should be transformed to angledLine |> angledLine([54, segLen(seg01, %)], %) // ln-should be transformed to angledLine
|> angledLineOfXLength([ |> angledLineOfXLength([
legAngX(segLen('seg01', %), myVar), legAngX(segLen(seg01, %), myVar),
min(segLen('seg01', %), myVar) min(segLen(seg01, %), myVar)
], %) // ln-should use legAngX to calculate angle ], %) // ln-should use legAngX to calculate angle
|> angledLineOfXLength([ |> angledLineOfXLength([
180 + legAngX(segLen('seg01', %), myVar), 180 + legAngX(segLen(seg01, %), myVar),
min(segLen('seg01', %), myVar) min(segLen(seg01, %), myVar)
], %) // ln-same as above but should have + 180 to match original quadrant ], %) // ln-same as above but should have + 180 to match original quadrant
|> line([ |> line([
legLen(segLen('seg01', %), myVar), legLen(segLen(seg01, %), myVar),
min(segLen('seg01', %), myVar) min(segLen(seg01, %), myVar)
], %) // ln-legLen again but yRelative ], %) // ln-legLen again but yRelative
|> line([ |> line([
-legLen(segLen('seg01', %), myVar), -legLen(segLen(seg01, %), myVar),
min(segLen('seg01', %), myVar) min(segLen(seg01, %), myVar)
], %) // ln-negative legLen yRelative ], %) // ln-negative legLen yRelative
|> angledLine([58, segLen('seg01', %)], %) // ln-angledLineOfYLength-free should become angledLine |> angledLine([58, segLen(seg01, %)], %) // ln-angledLineOfYLength-free should become angledLine
|> angledLine([myAng, segLen('seg01', %)], %) // ln-angledLineOfYLength-angle should become angledLine |> angledLine([myAng, segLen(seg01, %)], %) // ln-angledLineOfYLength-angle should become angledLine
|> angledLineOfXLength([ |> angledLineOfXLength([
legAngY(segLen('seg01', %), myVar), legAngY(segLen(seg01, %), myVar),
min(segLen('seg01', %), myVar) min(segLen(seg01, %), myVar)
], %) // ln-angledLineOfYLength-yRelative use legAngY ], %) // ln-angledLineOfYLength-yRelative use legAngY
|> angledLineOfXLength([ |> angledLineOfXLength([
270 + legAngY(segLen('seg01', %), myVar), 270 + legAngY(segLen(seg01, %), myVar),
min(segLen('seg01', %), myVar) min(segLen(seg01, %), myVar)
], %) // ln-angledLineOfYLength-yRelative with angle > 90 use binExp ], %) // ln-angledLineOfYLength-yRelative with angle > 90 use binExp
|> xLine(segLen('seg01', %), %) // ln-xLine-free should sub in segLen |> xLine(segLen(seg01, %), %) // ln-xLine-free should sub in segLen
|> yLine(segLen('seg01', %), %) // ln-yLine-free should sub in segLen |> yLine(segLen(seg01, %), %) // ln-yLine-free should sub in segLen
|> xLine(segLen('seg01', %), %) // ln-xLineTo-free should convert to xLine |> xLine(segLen(seg01, %), %) // ln-xLineTo-free should convert to xLine
|> yLine(segLen('seg01', %), %) // ln-yLineTo-free should convert to yLine |> yLine(segLen(seg01, %), %) // ln-yLineTo-free should convert to yLine
` `
it('should transform the ast', async () => { it('should transform the ast', async () => {
const ast = parse(inputScript) const ast = parse(inputScript)
@ -417,10 +417,10 @@ const part001 = startSketchOn('XY')
'setVertDistance' 'setVertDistance'
) )
expect(expectedHorizontalCode).toContain( expect(expectedHorizontalCode).toContain(
`lineTo([segEndX('seg01', %) + 0.9, 4.59], %) // free` `lineTo([segEndX(seg01, %) + 0.9, 4.59], %) // free`
) )
expect(expectedVerticalCode).toContain( expect(expectedVerticalCode).toContain(
`lineTo([1.21, segEndY('seg01', %) + 2.92], %) // free` `lineTo([1.21, segEndY(seg01, %) + 2.92], %) // free`
) )
}) })
it('testing for xRelative to vertical distance', async () => { it('testing for xRelative to vertical distance', async () => {
@ -431,7 +431,7 @@ const part001 = startSketchOn('XY')
) )
expect(expectedCode).toContain(`|> lineTo([ expect(expectedCode).toContain(`|> lineTo([
lastSegX(%) + myVar, lastSegX(%) + myVar,
segEndY('seg01', %) + 2.93 segEndY(seg01, %) + 2.93
], %) // xRelative`) ], %) // xRelative`)
}) })
it('testing for yRelative to horizontal distance', async () => { it('testing for yRelative to horizontal distance', async () => {
@ -441,7 +441,7 @@ const part001 = startSketchOn('XY')
'setHorzDistance' 'setHorzDistance'
) )
expect(expectedCode).toContain(`|> lineTo([ expect(expectedCode).toContain(`|> lineTo([
segEndX('seg01', %) + 2.6, segEndX(seg01, %) + 2.6,
lastSegY(%) + myVar lastSegY(%) + myVar
], %) // yRelative`) ], %) // yRelative`)
}) })

View File

@ -462,7 +462,7 @@ const setAngledIntersectLineForLines: TransformInfo['createNode'] =
angleVal, angleVal,
offsetVal: offsetVal:
forceValueUsedInTransform || createLiteral(valueUsedInTransform), forceValueUsedInTransform || createLiteral(valueUsedInTransform),
intersectTag: createLiteral(referenceSegName), intersectTag: createIdentifier(referenceSegName),
tag, tag,
valueUsedInTransform, valueUsedInTransform,
}) })
@ -481,7 +481,7 @@ const setAngledIntersectForAngledLines: TransformInfo['createNode'] =
angleVal: varValA, angleVal: varValA,
offsetVal: offsetVal:
forceValueUsedInTransform || createLiteral(valueUsedInTransform), forceValueUsedInTransform || createLiteral(valueUsedInTransform),
intersectTag: createLiteral(referenceSegName), intersectTag: createIdentifier(referenceSegName),
tag, tag,
valueUsedInTransform, valueUsedInTransform,
}) })
@ -675,7 +675,7 @@ const transformMap: TransformMap = {
const angleToMatchLengthXCall = createCallExpression( const angleToMatchLengthXCall = createCallExpression(
'angleToMatchLengthX', 'angleToMatchLengthX',
[ [
createLiteral(referenceSegName), createIdentifier(referenceSegName),
varValA, varValA,
createPipeSubstitution(), createPipeSubstitution(),
] ]
@ -708,7 +708,7 @@ const transformMap: TransformMap = {
const angleToMatchLengthYCall = createCallExpression( const angleToMatchLengthYCall = createCallExpression(
'angleToMatchLengthY', 'angleToMatchLengthY',
[ [
createLiteral(referenceSegName), createIdentifier(referenceSegName),
varValB, varValB,
createPipeSubstitution(), createPipeSubstitution(),
] ]
@ -973,7 +973,7 @@ const transformMap: TransformMap = {
const angleToMatchLengthXCall = createCallExpression( const angleToMatchLengthXCall = createCallExpression(
'angleToMatchLengthX', 'angleToMatchLengthX',
[ [
createLiteral(referenceSegName), createIdentifier(referenceSegName),
varValB, varValB,
createPipeSubstitution(), createPipeSubstitution(),
] ]
@ -1023,7 +1023,7 @@ const transformMap: TransformMap = {
const angleToMatchLengthXCall = createCallExpression( const angleToMatchLengthXCall = createCallExpression(
'angleToMatchLengthY', 'angleToMatchLengthY',
[ [
createLiteral(referenceSegName), createIdentifier(referenceSegName),
varValB, varValB,
createPipeSubstitution(), createPipeSubstitution(),
] ]
@ -1174,7 +1174,7 @@ export function getRemoveConstraintsTransform(
// fnName: name, // fnName: name,
// angleVal: args[0], // angleVal: args[0],
// offsetVal: args[1], // offsetVal: args[1],
// intersectTag: createLiteral(referenceSegName), // intersectTag: createIdentifier(referenceSegName),
// tag, // tag,
// }) // })
// } // }
@ -1593,8 +1593,8 @@ export function transformAstSketchLines({
const _referencedSegmentName = const _referencedSegmentName =
referenceSegName || referenceSegName ||
(_referencedSegmentNameVal && (_referencedSegmentNameVal &&
_referencedSegmentNameVal.type === 'Literal' && _referencedSegmentNameVal.type === 'Identifier' &&
String(_referencedSegmentNameVal.value)) || String(_referencedSegmentNameVal.name)) ||
'' ''
const { val } = firstArg const { val } = firstArg
const [varValA, varValB] = Array.isArray(val) ? val : [val, val] const [varValA, varValB] = Array.isArray(val) ? val : [val, val]
@ -1714,21 +1714,21 @@ export function transformAstSketchLines({
function createSegLen(referenceSegName: string): Value { function createSegLen(referenceSegName: string): Value {
return createCallExpression('segLen', [ return createCallExpression('segLen', [
createLiteral(referenceSegName), createIdentifier(referenceSegName),
createPipeSubstitution(), createPipeSubstitution(),
]) ])
} }
function createSegAngle(referenceSegName: string): Value { function createSegAngle(referenceSegName: string): Value {
return createCallExpression('segAng', [ return createCallExpression('segAng', [
createLiteral(referenceSegName), createIdentifier(referenceSegName),
createPipeSubstitution(), createPipeSubstitution(),
]) ])
} }
function createSegEnd(referenceSegName: string, isX: boolean): CallExpression { function createSegEnd(referenceSegName: string, isX: boolean): CallExpression {
return createCallExpression(isX ? 'segEndX' : 'segEndY', [ return createCallExpression(isX ? 'segEndX' : 'segEndY', [
createLiteral(referenceSegName), createIdentifier(referenceSegName),
createPipeSubstitution(), createPipeSubstitution(),
]) ])
} }

View File

@ -22,20 +22,20 @@ const filletR = 0.25
// Sketch the bracket and extrude with fillets // Sketch the bracket and extrude with fillets
const bracket = startSketchOn('XY') const bracket = startSketchOn('XY')
|> startProfileAt([0, 0], %) |> startProfileAt([0, 0], %)
|> line([0, wallMountL], %, 'outerEdge') |> line([0, wallMountL], %, $outerEdge)
|> line([-shelfMountL, 0], %) |> line([-shelfMountL, 0], %)
|> line([0, -thickness], %) |> line([0, -thickness], %)
|> line([shelfMountL - thickness, 0], %, 'innerEdge') |> line([shelfMountL - thickness, 0], %, $innerEdge)
|> line([0, -wallMountL + thickness], %) |> line([0, -wallMountL + thickness], %)
|> close(%) |> close(%)
|> extrude(width, %) |> extrude(width, %)
|> fillet({ |> fillet({
radius: filletR, radius: filletR,
tags: [getPreviousAdjacentEdge('innerEdge', %)] tags: [getPreviousAdjacentEdge(innerEdge, %)]
}, %) }, %)
|> fillet({ |> fillet({
radius: filletR + thickness, radius: filletR + thickness,
tags: [getPreviousAdjacentEdge('outerEdge', %)] tags: [getPreviousAdjacentEdge(outerEdge, %)]
}, %)` }, %)`
function findLineInExampleCode({ function findLineInExampleCode({

View File

@ -2,8 +2,10 @@ import {
createArrayExpression, createArrayExpression,
createBinaryExpression, createBinaryExpression,
createCallExpressionStdLib, createCallExpressionStdLib,
createIdentifier,
createLiteral, createLiteral,
createPipeSubstitution, createPipeSubstitution,
createTagDeclarator,
createUnaryExpression, createUnaryExpression,
} from 'lang/modifyAst' } from 'lang/modifyAst'
import { roundOff } from './utils' import { roundOff } from './utils'
@ -35,13 +37,13 @@ export const getRectangleCallExpressions = (
createLiteral(0), // This will be the width of the rectangle createLiteral(0), // This will be the width of the rectangle
]), ]),
createPipeSubstitution(), createPipeSubstitution(),
createLiteral(tags[0]), createTagDeclarator(tags[0]),
]), ]),
createCallExpressionStdLib('angledLine', [ createCallExpressionStdLib('angledLine', [
createArrayExpression([ createArrayExpression([
createBinaryExpression([ createBinaryExpression([
createCallExpressionStdLib('segAng', [ createCallExpressionStdLib('segAng', [
createLiteral(tags[0]), createIdentifier(tags[0]),
createPipeSubstitution(), createPipeSubstitution(),
]), ]),
'+', '+',
@ -50,24 +52,24 @@ export const getRectangleCallExpressions = (
createLiteral(0), // This will be the height of the rectangle createLiteral(0), // This will be the height of the rectangle
]), ]),
createPipeSubstitution(), createPipeSubstitution(),
createLiteral(tags[1]), createTagDeclarator(tags[1]),
]), ]),
createCallExpressionStdLib('angledLine', [ createCallExpressionStdLib('angledLine', [
createArrayExpression([ createArrayExpression([
createCallExpressionStdLib('segAng', [ createCallExpressionStdLib('segAng', [
createLiteral(tags[0]), createIdentifier(tags[0]),
createPipeSubstitution(), createPipeSubstitution(),
]), // same angle as the first line ]), // same angle as the first line
createUnaryExpression( createUnaryExpression(
createCallExpressionStdLib('segLen', [ createCallExpressionStdLib('segLen', [
createLiteral(tags[0]), createIdentifier(tags[0]),
createPipeSubstitution(), createPipeSubstitution(),
]), ]),
'-' '-'
), // negative height ), // negative height
]), ]),
createPipeSubstitution(), createPipeSubstitution(),
createLiteral(tags[2]), createTagDeclarator(tags[2]),
]), ]),
createCallExpressionStdLib('lineTo', [ createCallExpressionStdLib('lineTo', [
createArrayExpression([ createArrayExpression([
@ -101,7 +103,7 @@ export function updateRectangleSketch(
.arguments[0] as ArrayExpression) = createArrayExpression([ .arguments[0] as ArrayExpression) = createArrayExpression([
createBinaryExpression([ createBinaryExpression([
createCallExpressionStdLib('segAng', [ createCallExpressionStdLib('segAng', [
createLiteral(tag), createIdentifier(tag),
createPipeSubstitution(), createPipeSubstitution(),
]), ]),
Math.sign(y) === Math.sign(x) ? '+' : '-', Math.sign(y) === Math.sign(x) ? '+' : '-',

View File

@ -3947,10 +3947,10 @@ const hole_diam = 5
fn rectShape = (pos, w, l) => { fn rectShape = (pos, w, l) => {
const rr = startSketchOn('xy') const rr = startSketchOn('xy')
|> startProfileAt([pos[0] - (w / 2), pos[1] - (l / 2)], %) |> startProfileAt([pos[0] - (w / 2), pos[1] - (l / 2)], %)
|> lineTo([pos[0] + w / 2, pos[1] - (l / 2)], %, "edge1") |> lineTo([pos[0] + w / 2, pos[1] - (l / 2)], %,$edge1)
|> lineTo([pos[0] + w / 2, pos[1] + l / 2], %, "edge2") |> lineTo([pos[0] + w / 2, pos[1] + l / 2], %, $edge2)
|> lineTo([pos[0] - (w / 2), pos[1] + l / 2], %, "edge3") |> lineTo([pos[0] - (w / 2), pos[1] + l / 2], %, $edge3)
|> close(%, "edge4") |> close(%, $edge4)
return rr return rr
} }
// build the body of the focusrite scarlett solo gen 4 // build the body of the focusrite scarlett solo gen 4
@ -3960,10 +3960,10 @@ const scarlett_body = rectShape([0, 0], width, length)
|> fillet({ |> fillet({
radius: radius, radius: radius,
tags: [ tags: [
getEdge("edge2", %), getEdge(edge2, %),
getEdge("edge4", %), getEdge(edge4, %),
getOppositeEdge("edge2", %), getOppositeEdge(edge2, %),
getOppositeEdge("edge4", %) getOppositeEdge(edge4, %)
] ]
}, %) }, %)
// build the bracket sketch around the body // build the bracket sketch around the body
@ -3977,14 +3977,14 @@ fn bracketSketch = (w, d, t) => {
} }
}) })
|> startProfileAt([-w / 2 - t, d + t], %) |> startProfileAt([-w / 2 - t, d + t], %)
|> lineTo([-w / 2 - t, -t], %, "edge1") |> lineTo([-w / 2 - t, -t], %, $edge1)
|> lineTo([w / 2 + t, -t], %, "edge2") |> lineTo([w / 2 + t, -t], %, $edge2)
|> lineTo([w / 2 + t, d + t], %, "edge3") |> lineTo([w / 2 + t, d + t], %, $edge3)
|> lineTo([w / 2, d + t], %, "edge4") |> lineTo([w / 2, d + t], %, $edge4)
|> lineTo([w / 2, 0], %, "edge5") |> lineTo([w / 2, 0], %, $edge5)
|> lineTo([-w / 2, 0], %, "edge6") |> lineTo([-w / 2, 0], %, $edge6)
|> lineTo([-w / 2, d + t], %, "edge7") |> lineTo([-w / 2, d + t], %, $edge7)
|> close(%, "edge8") |> close(%, $edge8)
return s return s
} }
// build the body of the bracket // build the body of the bracket
@ -3993,10 +3993,10 @@ const bracket_body = bracketSketch(width, depth, thk)
|> fillet({ |> fillet({
radius: radius, radius: radius,
tags: [ tags: [
getNextAdjacentEdge("edge7", %), getNextAdjacentEdge(edge7, %),
getNextAdjacentEdge("edge2", %), getNextAdjacentEdge(edge2, %),
getNextAdjacentEdge("edge3", %), getNextAdjacentEdge(edge3, %),
getNextAdjacentEdge("edge6", %) getNextAdjacentEdge(edge6, %)
] ]
}, %) }, %)
// build the tabs of the mounting bracket (right side) // build the tabs of the mounting bracket (right side)
@ -4067,10 +4067,10 @@ const hole_diam = 5
fn rectShape = (pos, w, l) => { fn rectShape = (pos, w, l) => {
const rr = startSketchOn('xy') const rr = startSketchOn('xy')
|> startProfileAt([pos[0] - (w / 2), pos[1] - (l / 2)], %) |> startProfileAt([pos[0] - (w / 2), pos[1] - (l / 2)], %)
|> lineTo([pos[0] + w / 2, pos[1] - (l / 2)], %, "edge1") |> lineTo([pos[0] + w / 2, pos[1] - (l / 2)], %, $edge1)
|> lineTo([pos[0] + w / 2, pos[1] + l / 2], %, "edge2") |> lineTo([pos[0] + w / 2, pos[1] + l / 2], %, $edge2)
|> lineTo([pos[0] - (w / 2), pos[1] + l / 2], %, "edge3") |> lineTo([pos[0] - (w / 2), pos[1] + l / 2], %, $edge3)
|> close(%, "edge4") |> close(%, $edge4)
return rr return rr
} }
// build the body of the focusrite scarlett solo gen 4 // build the body of the focusrite scarlett solo gen 4
@ -4080,10 +4080,10 @@ const scarlett_body = rectShape([0, 0], width, length)
|> fillet({ |> fillet({
radius: radius, radius: radius,
tags: [ tags: [
getEdge("edge2", %), getEdge(edge2, %),
getEdge("edge4", %), getEdge(edge4, %),
getOppositeEdge("edge2", %), getOppositeEdge(edge2, %),
getOppositeEdge("edge4", %) getOppositeEdge(edge4, %)
] ]
}, %) }, %)
// build the bracket sketch around the body // build the bracket sketch around the body
@ -4097,14 +4097,14 @@ fn bracketSketch = (w, d, t) => {
} }
}) })
|> startProfileAt([-w / 2 - t, d + t], %) |> startProfileAt([-w / 2 - t, d + t], %)
|> lineTo([-w / 2 - t, -t], %, "edge1") |> lineTo([-w / 2 - t, -t], %, $edge1)
|> lineTo([w / 2 + t, -t], %, "edge2") |> lineTo([w / 2 + t, -t], %, $edge2)
|> lineTo([w / 2 + t, d + t], %, "edge3") |> lineTo([w / 2 + t, d + t], %, $edge3)
|> lineTo([w / 2, d + t], %, "edge4") |> lineTo([w / 2, d + t], %, $edge4)
|> lineTo([w / 2, 0], %, "edge5") |> lineTo([w / 2, 0], %, $edge5)
|> lineTo([-w / 2, 0], %, "edge6") |> lineTo([-w / 2, 0], %, $edge6)
|> lineTo([-w / 2, d + t], %, "edge7") |> lineTo([-w / 2, d + t], %, $edge7)
|> close(%, "edge8") |> close(%, $edge8)
return s return s
} }
// build the body of the bracket // build the body of the bracket
@ -4113,10 +4113,10 @@ const bracket_body = bracketSketch(width, depth, thk)
|> fillet({ |> fillet({
radius: radius, radius: radius,
tags: [ tags: [
getNextAdjacentEdge("edge7", %), getNextAdjacentEdge(edge7, %),
getNextAdjacentEdge("edge2", %), getNextAdjacentEdge(edge2, %),
getNextAdjacentEdge("edge3", %), getNextAdjacentEdge(edge3, %),
getNextAdjacentEdge("edge6", %) getNextAdjacentEdge(edge6, %)
] ]
}, %) }, %)
// build the tabs of the mounting bracket (right side) // build the tabs of the mounting bracket (right side)
@ -4426,7 +4426,7 @@ const mySk1 = startSketchOn('XY')
|> startProfileAt([0, 0], %) |> startProfileAt([0, 0], %)
|> lineTo([1, 1], %) |> lineTo([1, 1], %)
// comment here // comment here
|> lineTo([0, 1], %, 'myTag') |> lineTo([0, 1], %, $myTag)
|> lineTo([1, 1], %) |> lineTo([1, 1], %)
/* and /* and
here here
@ -4449,7 +4449,7 @@ const mySk1 = startSketchOn('XY')
|> startProfileAt([0, 0], %) |> startProfileAt([0, 0], %)
|> lineTo([1, 1], %) |> lineTo([1, 1], %)
// comment here // comment here
|> lineTo([0, 1], %, 'myTag') |> lineTo([0, 1], %, $myTag)
|> lineTo([1, 1], %) |> lineTo([1, 1], %)
/* and /* and
here */ here */
@ -4467,12 +4467,12 @@ const mySk1 = startSketchOn('XY')
fn test_recast_multiline_object() { fn test_recast_multiline_object() {
let some_program_string = r#"const part001 = startSketchOn('XY') let some_program_string = r#"const part001 = startSketchOn('XY')
|> startProfileAt([-0.01, -0.08], %) |> startProfileAt([-0.01, -0.08], %)
|> line([0.62, 4.15], %, 'seg01') |> line([0.62, 4.15], %, $seg01)
|> line([2.77, -1.24], %) |> line([2.77, -1.24], %)
|> angledLineThatIntersects({ |> angledLineThatIntersects({
angle: 201, angle: 201,
offset: -1.35, offset: -1.35,
intersectTag: 'seg01' intersectTag: seg01
}, %) }, %)
|> line([-0.42, -1.72], %)"#; |> line([-0.42, -1.72], %)"#;
let tokens = crate::token::lexer(some_program_string).unwrap(); let tokens = crate::token::lexer(some_program_string).unwrap();
@ -4557,13 +4557,13 @@ const myAng = 40
const myAng2 = 134 const myAng2 = 134
const part001 = startSketchOn('XY') const part001 = startSketchOn('XY')
|> startProfileAt([0, 0], %) |> startProfileAt([0, 0], %)
|> line([1, 3.82], %, 'seg01') // ln-should-get-tag |> line([1, 3.82], %, $seg01) // ln-should-get-tag
|> angledLineToX([ |> angledLineToX([
-angleToMatchLengthX('seg01', myVar, %), -angleToMatchLengthX(seg01, myVar, %),
myVar myVar
], %) // ln-lineTo-xAbsolute should use angleToMatchLengthX helper ], %) // ln-lineTo-xAbsolute should use angleToMatchLengthX helper
|> angledLineToY([ |> angledLineToY([
-angleToMatchLengthY('seg01', myVar, %), -angleToMatchLengthY(seg01, myVar, %),
myVar myVar
], %) // ln-lineTo-yAbsolute should use angleToMatchLengthY helper"#; ], %) // ln-lineTo-yAbsolute should use angleToMatchLengthY helper"#;
let tokens = crate::token::lexer(some_program_string).unwrap(); let tokens = crate::token::lexer(some_program_string).unwrap();
@ -4583,13 +4583,13 @@ const myAng = 40
const myAng2 = 134 const myAng2 = 134
const part001 = startSketchOn('XY') const part001 = startSketchOn('XY')
|> startProfileAt([0, 0], %) |> startProfileAt([0, 0], %)
|> line([1, 3.82], %, 'seg01') // ln-should-get-tag |> line([1, 3.82], %, $seg01) // ln-should-get-tag
|> angledLineToX([ |> angledLineToX([
-angleToMatchLengthX('seg01', myVar, %), -angleToMatchLengthX(seg01, myVar, %),
myVar myVar
], %) // ln-lineTo-xAbsolute should use angleToMatchLengthX helper ], %) // ln-lineTo-xAbsolute should use angleToMatchLengthX helper
|> angledLineToY([ |> angledLineToY([
-angleToMatchLengthY('seg01', myVar, %), -angleToMatchLengthY(seg01, myVar, %),
myVar myVar
], %) // ln-lineTo-yAbsolute should use angleToMatchLengthY helper ], %) // ln-lineTo-yAbsolute should use angleToMatchLengthY helper
"#; "#;
@ -5233,4 +5233,38 @@ const thickness = sqrt(distance * p * FOS * 6 / (sigmaAllow * width))"#;
assert_eq!(l.raw, "false"); assert_eq!(l.raw, "false");
} }
#[tokio::test(flavor = "multi_thread")]
async fn test_parse_tag_named_std_lib() {
let some_program_string = r#"startSketchOn('XY')
|> startProfileAt([0, 0], %)
|> line([5, 5], %, $xLine)
"#;
let tokens = crate::token::lexer(some_program_string).unwrap();
let parser = crate::parser::Parser::new(tokens);
let result = parser.ast();
assert!(result.is_err());
assert_eq!(
result.unwrap_err().to_string(),
r#"syntax: KclErrorDetails { source_ranges: [SourceRange([76, 82])], message: "Cannot assign a tag to a reserved keyword: xLine" }"#
);
}
#[tokio::test(flavor = "multi_thread")]
async fn test_parse_empty_tag() {
let some_program_string = r#"startSketchOn('XY')
|> startProfileAt([0, 0], %)
|> line([5, 5], %, $)
"#;
let tokens = crate::token::lexer(some_program_string).unwrap();
let parser = crate::parser::Parser::new(tokens);
let result = parser.ast();
assert!(result.is_err());
assert_eq!(
result.unwrap_err().to_string(),
r#"syntax: KclErrorDetails { source_ranges: [SourceRange([57, 59])], message: "Unexpected token" }"#
);
}
} }

View File

@ -912,8 +912,8 @@ fn value_allowed_in_pipe_expr(i: TokenSlice) -> PResult<Value> {
alt(( alt((
member_expression.map(Box::new).map(Value::MemberExpression), member_expression.map(Box::new).map(Value::MemberExpression),
bool_value.map(Box::new).map(Value::Literal), bool_value.map(Box::new).map(Value::Literal),
literal.map(Box::new).map(Value::Literal),
tag.map(Box::new).map(Value::TagDeclarator), tag.map(Box::new).map(Value::TagDeclarator),
literal.map(Box::new).map(Value::Literal),
fn_call.map(Box::new).map(Value::CallExpression), fn_call.map(Box::new).map(Value::CallExpression),
identifier.map(Box::new).map(Value::Identifier), identifier.map(Box::new).map(Value::Identifier),
array.map(Box::new).map(Value::ArrayExpression), array.map(Box::new).map(Value::ArrayExpression),
@ -1067,6 +1067,19 @@ impl TryFrom<Token> for TagDeclarator {
} }
} }
impl TagDeclarator {
fn into_valid_binding_name(self) -> Result<Self, KclError> {
// Make sure they are not assigning a variable to a stdlib function.
if crate::std::name_in_stdlib(&self.name) {
return Err(KclError::Syntax(KclErrorDetails {
source_ranges: vec![SourceRange([self.start, self.end])],
message: format!("Cannot assign a tag to a reserved keyword: {}", self.name),
}));
}
Ok(self)
}
}
/// Parse a Kcl tag that starts with a `$`. /// Parse a Kcl tag that starts with a `$`.
fn tag(i: TokenSlice) -> PResult<TagDeclarator> { fn tag(i: TokenSlice) -> PResult<TagDeclarator> {
dollar.parse_next(i)?; dollar.parse_next(i)?;
@ -1468,7 +1481,99 @@ fn binding_name(i: TokenSlice) -> PResult<Identifier> {
fn fn_call(i: TokenSlice) -> PResult<CallExpression> { fn fn_call(i: TokenSlice) -> PResult<CallExpression> {
let fn_name = identifier(i)?; let fn_name = identifier(i)?;
let _ = terminated(open_paren, opt(whitespace)).parse_next(i)?; let _ = terminated(open_paren, opt(whitespace)).parse_next(i)?;
let args = arguments(i)?; let mut args = arguments(i)?;
if let Some(std_fn) = crate::std::get_stdlib_fn(&fn_name.name) {
// Type check the arguments.
for (i, spec_arg) in std_fn.args().iter().enumerate() {
let Some(arg) = &args.get(i) else {
// The executor checks the number of arguments, so we don't need to check it here.
continue;
};
match spec_arg.type_.as_ref() {
"TagDeclarator" => {
match &arg {
Value::Identifier(_) => {
// These are fine since we want someone to be able to map a variable to a tag declarator.
}
Value::TagDeclarator(tag) => {
tag.clone()
.into_valid_binding_name()
.map_err(|e| ErrMode::Cut(ContextError::from(e)))?;
}
Value::Literal(literal) => {
let LiteralValue::String(name) = &literal.value else {
return Err(ErrMode::Cut(
KclError::Syntax(KclErrorDetails {
source_ranges: vec![SourceRange([arg.start(), arg.end()])],
message: format!("Expected a tag declarator like `$name`, found {:?}", literal),
})
.into(),
));
};
// Convert this to a TagDeclarator.
let tag = TagDeclarator {
start: literal.start,
end: literal.end,
name: name.to_string(),
};
let tag = tag
.into_valid_binding_name()
.map_err(|e| ErrMode::Cut(ContextError::from(e)))?;
// Replace the literal with the tag.
args[i] = Value::TagDeclarator(Box::new(tag));
}
e => {
return Err(ErrMode::Cut(
KclError::Syntax(KclErrorDetails {
source_ranges: vec![SourceRange([arg.start(), arg.end()])],
message: format!("Expected a tag declarator like `$name`, found {:?}", e),
})
.into(),
));
}
}
}
"TagIdentifier" => {
match &arg {
Value::Identifier(_) => {}
Value::Literal(literal) => {
let LiteralValue::String(name) = &literal.value else {
return Err(ErrMode::Cut(
KclError::Syntax(KclErrorDetails {
source_ranges: vec![SourceRange([arg.start(), arg.end()])],
message: format!("Expected a tag declarator like `$name`, found {:?}", literal),
})
.into(),
));
};
// Convert this to a TagDeclarator.
let tag = Identifier {
start: literal.start,
end: literal.end,
name: name.to_string(),
};
// Replace the literal with the tag.
args[i] = Value::Identifier(Box::new(tag));
}
e => {
return Err(ErrMode::Cut(
KclError::Syntax(KclErrorDetails {
source_ranges: vec![SourceRange([arg.start(), arg.end()])],
message: format!("Expected a tag identifier like `tagName`, found {:?}", e),
})
.into(),
));
}
}
}
_ => {}
}
}
}
let end = preceded(opt(whitespace), close_paren).parse_next(i)?.end; let end = preceded(opt(whitespace), close_paren).parse_next(i)?.end;
Ok(CallExpression { Ok(CallExpression {
start: fn_name.start, start: fn_name.start,

View File

@ -110,12 +110,11 @@ expression: actual
"end": 65 "end": 65
}, },
{ {
"type": "Literal", "type": "TagDeclarator",
"type": "Literal", "type": "TagDeclarator",
"start": 67, "start": 67,
"end": 75, "end": 75,
"value": "myPath", "value": "myPath"
"raw": "'myPath'"
} }
], ],
"optional": false "optional": false
@ -208,12 +207,11 @@ expression: actual
"end": 133 "end": 133
}, },
{ {
"type": "Literal", "type": "TagDeclarator",
"type": "Literal", "type": "TagDeclarator",
"start": 135, "start": 135,
"end": 146, "end": 146,
"value": "rightPath", "value": "rightPath"
"raw": "'rightPath'"
} }
], ],
"optional": false "optional": false

View File

@ -124,6 +124,10 @@ pub fn name_in_stdlib(name: &str) -> bool {
CORE_FNS.iter().any(|f| f.name() == name) CORE_FNS.iter().any(|f| f.name() == name)
} }
pub fn get_stdlib_fn(name: &str) -> Option<Box<dyn StdLibFn>> {
CORE_FNS.iter().find(|f| f.name() == name).cloned()
}
pub struct StdLib { pub struct StdLib {
pub fns: HashMap<String, Box<dyn StdLibFn>>, pub fns: HashMap<String, Box<dyn StdLibFn>>,
pub kcl_fns: HashMap<String, Box<dyn KclStdLibFn>>, pub kcl_fns: HashMap<String, Box<dyn KclStdLibFn>>,

View File

@ -26,7 +26,7 @@ pub async fn circle(args: Args) -> Result<MemoryItem, KclError> {
let (center, radius, sketch_surface_or_group, tag): ([f64; 2], f64, SketchSurfaceOrGroup, Option<TagDeclarator>) = let (center, radius, sketch_surface_or_group, tag): ([f64; 2], f64, SketchSurfaceOrGroup, Option<TagDeclarator>) =
args.get_circle_args()?; args.get_circle_args()?;
let sketch_group = inner_circle(center, radius, tag, sketch_surface_or_group, args).await?; let sketch_group = inner_circle(center, radius, sketch_surface_or_group, tag, args).await?;
Ok(MemoryItem::SketchGroup(sketch_group)) Ok(MemoryItem::SketchGroup(sketch_group))
} }
@ -55,8 +55,8 @@ pub async fn circle(args: Args) -> Result<MemoryItem, KclError> {
async fn inner_circle( async fn inner_circle(
center: [f64; 2], center: [f64; 2],
radius: f64, radius: f64,
tag: Option<TagDeclarator>,
sketch_surface_or_group: SketchSurfaceOrGroup, sketch_surface_or_group: SketchSurfaceOrGroup,
tag: Option<TagDeclarator>,
args: Args, args: Args,
) -> Result<Box<SketchGroup>, KclError> { ) -> Result<Box<SketchGroup>, KclError> {
let sketch_surface = match sketch_surface_or_group { let sketch_surface = match sketch_surface_or_group {

View File

@ -1,41 +1,37 @@
fn triangle = (len) => {
return startSketchOn('XY')
|> startProfileAt([0, 0], %)
|> angledLine({angle: 60, length: len}, %, 'a')
|> angledLine({angle: 180, length: len}, %, 'b')
|> angledLine({angle: 300, length: len}, %, 'c')
}
let triangleHeight = 200 let triangleHeight = 200
let plumbusLen = 100 let plumbusLen = 100
let radius = 80 let radius = 80
let circ = {angle_start: 0, angle_end: 360, radius: radius} let circ = {angle_start: 0, angle_end: 360, radius: radius}
let triangleLen = 500 let triangleLen = 500
const p = triangle(triangleLen) const p = startSketchOn('XY')
|> startProfileAt([0, 0], %)
|> angledLine({angle: 60, length:triangleLen}, %, $a)
|> angledLine({angle: 180, length: triangleLen}, %, $b)
|> angledLine({angle: 300, length: triangleLen}, %, $c)
|> extrude(triangleHeight, %) |> extrude(triangleHeight, %)
fn circl = (x, tag) => { fn circl = (x, face, tag) => {
return startSketchOn(p, tag) return startSketchOn(p, face)
|> startProfileAt([x + radius, triangleHeight/2], %) |> startProfileAt([x + radius, triangleHeight/2], %)
|> arc(circ, %, 'arc-' + tag) |> arc(circ, %, tag)
|> close(%) |> close(%)
} }
const plumbus1 = const plumbus1 =
circl(-200, 'c') circl(-200,c, $arc_c)
|> extrude(plumbusLen, %) |> extrude(plumbusLen, %)
|> fillet({ |> fillet({
radius: 5, radius: 5,
tags: ['arc-c', getOppositeEdge('arc-c', %)] tags: [arc_c, getOppositeEdge(arc_c, %)]
}, %) }, %)
const plumbus0 = const plumbus0 =
circl(200, 'a') circl(200, a, $arc_a)
|> extrude(plumbusLen, %) |> extrude(plumbusLen, %)
|> fillet({ |> fillet({
radius: 5, radius: 5,
tags: ['arc-a', getOppositeEdge('arc-a', %)] tags: [arc_a, getOppositeEdge(arc_a, %)]
}, %) }, %)

View File

@ -1731,58 +1731,58 @@ const part002 = startSketchOn(part001, 'end')
#[tokio::test(flavor = "multi_thread")] #[tokio::test(flavor = "multi_thread")]
async fn serial_test_plumbus_fillets() { async fn serial_test_plumbus_fillets() {
let code = r#"fn make_circle = (face, tag, pos, radius) => { let code = r#"fn make_circle = (ext, face, tag ,pos, radius) => {
const sg = startSketchOn(face, tag) const sg = startSketchOn(ext, face)
|> startProfileAt([pos[0] + radius, pos[1]], %) |> startProfileAt([pos[0] + radius, pos[1]], %)
|> arc({ |> arc({
angle_end: 360, angle_end: 360,
angle_start: 0, angle_start: 0,
radius: radius radius: radius
}, %, 'arc-' + tag) }, %, tag)
|> close(%) |> close(%)
return sg return sg
} }
fn pentagon = (len) => { fn pentagon = (len, taga, tagb, tagc) => {
const sg = startSketchOn('XY') const sg = startSketchOn('XY')
|> startProfileAt([-len / 2, -len / 2], %) |> startProfileAt([-len / 2, -len / 2], %)
|> angledLine({ angle: 0, length: len }, %, 'a') |> angledLine({ angle: 0, length: len }, %,taga)
|> angledLine({ |> angledLine({
angle: segAng('a', %) + 180 - 108, angle: segAng(a, %) + 180 - 108,
length: len length: len
}, %, 'b') }, %, tagb)
|> angledLine({ |> angledLine({
angle: segAng('b', %) + 180 - 108, angle: segAng(b, %) + 180 - 108,
length: len length: len
}, %, 'c') }, %,tagc)
|> angledLine({ |> angledLine({
angle: segAng('c', %) + 180 - 108, angle: segAng(c, %) + 180 - 108,
length: len length: len
}, %, 'd') }, %, $d)
|> angledLine({ |> angledLine({
angle: segAng('d', %) + 180 - 108, angle: segAng(d, %) + 180 - 108,
length: len length: len
}, %) }, %)
return sg return sg
} }
const p = pentagon(32) const p = pentagon(32, $a, $b, $c)
|> extrude(10, %) |> extrude(10, %)
const plumbus0 = make_circle(p, 'a', [0, 0], 2.5) const plumbus0 = make_circle(p,a, $arc_a, [0, 0], 2.5)
|> extrude(10, %) |> extrude(10, %)
|> fillet({ |> fillet({
radius: 0.5, radius: 0.5,
tags: ['arc-a', getOppositeEdge('arc-a', %)] tags: [arc_a, getOppositeEdge(arc_a, %)]
}, %) }, %)
const plumbus1 = make_circle(p, 'b', [0, 0], 2.5) const plumbus1 = make_circle(p, b,$arc_b, [0, 0], 2.5)
|> extrude(10, %) |> extrude(10, %)
|> fillet({ |> fillet({
radius: 0.5, radius: 0.5,
tags: ['arc-b', getOppositeEdge('arc-b', %)] tags: [arc_b, getOppositeEdge(arc_b, %)]
}, %) }, %)
"#; "#;