Compare commits
92 Commits
Author | SHA1 | Date | |
---|---|---|---|
19a93e8deb | |||
b8c623e1ec | |||
4006c28479 | |||
8c932fdb8d | |||
a74c715c01 | |||
1ac39d95f2 | |||
41b1ec94fa | |||
525c803888 | |||
2ee1c78aad | |||
dc21034b86 | |||
1684786659 | |||
12505b4398 | |||
115f2fdea2 | |||
0df28abc4b | |||
1e07ea4986 | |||
f34c23d203 | |||
5295f0ae7d | |||
07a90b3171 | |||
54936f6932 | |||
6e296af507 | |||
60c152bf14 | |||
59de494125 | |||
1c44b01d16 | |||
789fb83a5d | |||
63fc287742 | |||
5e1b91b0e7 | |||
a1c2e817a4 | |||
6ed4e72e1d | |||
6477011c0f | |||
cd9dc3e6a5 | |||
4b424de5a6 | |||
0f1b94f8b9 | |||
8879f488bb | |||
67d0fb76f6 | |||
fff3c58560 | |||
8880df4fbb | |||
d94017c5e3 | |||
8fe91259fa | |||
57d4204f47 | |||
ee601f93bf | |||
b0b48a2e9f | |||
46f940ead5 | |||
014cedb2cc | |||
2375f900b9 | |||
9fd4fd0dd8 | |||
ee5037bf35 | |||
881745e131 | |||
49fce9ed57 | |||
fb7b2be427 | |||
2ec68e3c73 | |||
6e2dd53ee0 | |||
f5c262206e | |||
9c9b448705 | |||
615b03aea5 | |||
c3c435348d | |||
d13f7fd508 | |||
af842aeded | |||
0d4b7adf99 | |||
e708b6ee6b | |||
4dd8a25fdd | |||
029799215b | |||
e3b8807d6f | |||
0e5d88df0b | |||
95781143eb | |||
c184a7d4d8 | |||
c38e52fbb7 | |||
ea0a3ac3ba | |||
385589ddf9 | |||
22df47fa96 | |||
a68748abcf | |||
1b8688f274 | |||
397839da84 | |||
ac120838e5 | |||
e6a2ac9c4a | |||
6e7e6e96cf | |||
73e155d79b | |||
a782f26ec2 | |||
01076c3aed | |||
fe512611ac | |||
cba953c245 | |||
54ca6ea0b2 | |||
6a01608c3a | |||
530f15e04a | |||
725e59d987 | |||
54313c9b03 | |||
890d96496c | |||
35999366a7 | |||
2affc7271d | |||
d30fbf8b4b | |||
3f7e776464 | |||
79cff57f43 | |||
1cd2cd82b2 |
37
.github/ISSUE_TEMPLATE/cryptic_error.yml
vendored
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
name: Cryptic KCL Error
|
||||||
|
description: File a bug report for source code that produces a confusing error
|
||||||
|
title: "[CRYPTIC]: "
|
||||||
|
labels: ["cryptic-error"]
|
||||||
|
assignees: []
|
||||||
|
body:
|
||||||
|
- type: markdown
|
||||||
|
attributes:
|
||||||
|
value: "Thank you for taking the time to report a confusing error. Please provide as much information as possible to help us resolve it."
|
||||||
|
|
||||||
|
- type: textarea
|
||||||
|
id: kcl
|
||||||
|
attributes:
|
||||||
|
label: Paste minimal KCL source that produces a cryptic error
|
||||||
|
description: Minimal KCL reproducer that produces a cryptic error
|
||||||
|
placeholder: "const ..."
|
||||||
|
render: javascript
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
|
||||||
|
- type: textarea
|
||||||
|
id: expected-behavior
|
||||||
|
attributes:
|
||||||
|
label: Expected Behavior
|
||||||
|
description: Description of what you expected to happen (if you know).
|
||||||
|
placeholder: "I expected that..."
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
|
||||||
|
- type: textarea
|
||||||
|
id: additional-context
|
||||||
|
attributes:
|
||||||
|
label: Additional Context
|
||||||
|
description: Add any other context about the problem here.
|
||||||
|
placeholder: "Anything else you want to add..."
|
||||||
|
validations:
|
||||||
|
required: false
|
37
README.md
@ -124,28 +124,39 @@ Before you submit a contribution PR to this repo, please ensure that:
|
|||||||
|
|
||||||
## Release a new version
|
## Release a new version
|
||||||
|
|
||||||
1. Bump the versions by running `./make-realease.sh` while on a fresh pull of main
|
#### 1. Bump the versions by running `./make-release.sh` and create a Cut Release PR
|
||||||
|
|
||||||
That will create the branch with the updated json files for you.
|
That will create the branch with the updated json files for you:
|
||||||
run `./make-release.sh` for a patch update
|
- run `./make-release.sh` or `./make-release.sh patch` for a patch update;
|
||||||
run `./make-release.sh "minor"` for minor
|
- run `./make-release.sh minor` for minor; or
|
||||||
run `./make-release.sh "major"` for major
|
- run `./make-release.sh major` for major.
|
||||||
|
|
||||||
After it runs you should just need to push the push the branch and open a PR (it will suggest a changelog for you too, delete any that are not user facing)
|
After it runs you should just need the push the branch and open a PR.
|
||||||
|
|
||||||
The PR may serve as a place to discuss the human-readable changelog and extra QA.
|
**Important:** It needs to be prefixed with `Cut release v` to build in release mode and a few other things to test in the best context possible, the intent would be for instance to have `Cut release v1.2.3` for the `v1.2.3` release candidate.
|
||||||
|
|
||||||
2. Smoke test the artifact from the above PR
|
The PR may then serve as a place to discuss the human-readable changelog and extra QA. The `make-release.sh` tool suggests a changelog for you too to be used as PR description, just make sure to delete lines that are not user facing.
|
||||||
We don't have a strict process, but click around and check for anything obvious
|
|
||||||
One of the artifacts is called updater-test, because we don't have a way to test this fully automated, we have a semi-automated process.
|
|
||||||
|
|
||||||
Download updater-test zip file, install the app, run it, expect an updater prompt to v0.99.99, install it and check that the app comes back at that version (on both macOS and Windows).
|
#### 2. Smoke test artifacts from the Cut Release PR
|
||||||
|
|
||||||
3. Merge the PR
|
The release builds can be find under the `artifact` zip, at the very bottom of the `ci` action page for each commit on this branch.
|
||||||
|
|
||||||
|
We don't have a strict process, but click around and check for anything obvious, posting results as comments in the Cut Release PR.
|
||||||
|
|
||||||
|
The other `ci` output in Cut Release PRs is `updater-test`, because we don't have a way to test this fully automated, we have a semi-automated process. Download updater-test zip file, install the app, run it, expect an updater prompt to a dummy v0.99.99, install it and check that the app comes back at that version (on both macOS and Windows).
|
||||||
|
|
||||||
|
#### 3. Merge the Cut Release PR
|
||||||
|
|
||||||
|
This will kick the `create-release` action, that creates a _Draft_ release out of this Cut Release PR merge after less than a minute, with the new version as title and Cut Release PR as description.
|
||||||
|
|
||||||
|
|
||||||
4. Profit (A new Action kicks in at https://github.com/KittyCAD/modeling-app/actions if the PR was correctly named)
|
#### 4. Publish the release
|
||||||
|
|
||||||
|
Head over to https://github.com/KittyCAD/modeling-app/releases, the draft release corresponding to the merged Cut Release PR should show up at the top as _Draft_. Click on it, verify the content, and hit _Publish_.
|
||||||
|
|
||||||
|
#### 5. Profit
|
||||||
|
|
||||||
|
A new Action kicks in at https://github.com/KittyCAD/modeling-app/actions, which can be found under `release` event filter.
|
||||||
|
|
||||||
|
|
||||||
## Fuzzing the parser
|
## Fuzzing the parser
|
||||||
|
@ -22,7 +22,7 @@ const exampleSketch = startSketchOn('XZ')
|
|||||||
|> lineTo([0, 20], %)
|
|> lineTo([0, 20], %)
|
||||||
|> angledLineThatIntersects({
|
|> angledLineThatIntersects({
|
||||||
angle: 80,
|
angle: 80,
|
||||||
intersectTag: 'lineToIntersect',
|
intersectTag: lineToIntersect,
|
||||||
offset: 10
|
offset: 10
|
||||||
}, %)
|
}, %)
|
||||||
|> close(%)
|
|> close(%)
|
||||||
@ -41,6 +41,92 @@ const example = extrude(10, exampleSketch)
|
|||||||
angle: number,
|
angle: number,
|
||||||
// The tag of the line to intersect with.
|
// The tag of the line to intersect with.
|
||||||
intersectTag: {
|
intersectTag: {
|
||||||
|
// Engine information for a tag.
|
||||||
|
info: {
|
||||||
|
// The id of the tagged object.
|
||||||
|
id: uuid,
|
||||||
|
// The path the tag is on.
|
||||||
|
path: {
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
},
|
||||||
|
// The sketch group the tag is on.
|
||||||
|
sketchGroup: uuid,
|
||||||
|
// The surface information for the tag.
|
||||||
|
surface: {
|
||||||
|
// The face id for the extrude plane.
|
||||||
|
faceId: uuid,
|
||||||
|
// The id of the geometry.
|
||||||
|
id: uuid,
|
||||||
|
// The source range.
|
||||||
|
sourceRange: [number, number],
|
||||||
|
// The tag.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
type: "extrudePlane",
|
||||||
|
} |
|
||||||
|
{
|
||||||
|
// The face id for the extrude plane.
|
||||||
|
faceId: uuid,
|
||||||
|
// The id of the geometry.
|
||||||
|
id: uuid,
|
||||||
|
// The source range.
|
||||||
|
sourceRange: [number, number],
|
||||||
|
// The tag.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
type: "extrudeArc",
|
||||||
|
} |
|
||||||
|
{
|
||||||
|
// The id for the chamfer surface.
|
||||||
|
faceId: uuid,
|
||||||
|
// The id of the geometry.
|
||||||
|
id: uuid,
|
||||||
|
// The source range.
|
||||||
|
sourceRange: [number, number],
|
||||||
|
// The tag.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
type: "chamfer",
|
||||||
|
} |
|
||||||
|
{
|
||||||
|
// The id for the fillet surface.
|
||||||
|
faceId: uuid,
|
||||||
|
// The id of the geometry.
|
||||||
|
id: uuid,
|
||||||
|
// The source range.
|
||||||
|
sourceRange: [number, number],
|
||||||
|
// The tag.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
type: "fillet",
|
||||||
|
},
|
||||||
|
},
|
||||||
value: string,
|
value: string,
|
||||||
},
|
},
|
||||||
// The offset from the intersecting line.
|
// The offset from the intersecting line.
|
||||||
@ -50,7 +136,7 @@ const example = extrude(10, exampleSketch)
|
|||||||
* `sketch_group`: `SketchGroup` - A sketch group is a collection of paths. (REQUIRED)
|
* `sketch_group`: `SketchGroup` - A sketch group is a collection of paths. (REQUIRED)
|
||||||
```js
|
```js
|
||||||
{
|
{
|
||||||
// The id of the sketch group.
|
// The id of the sketch group (this will change when the engine's reference to it changes.
|
||||||
id: uuid,
|
id: uuid,
|
||||||
// What the sketch is on (can be a plane or a face).
|
// What the sketch is on (can be a plane or a face).
|
||||||
on: {
|
on: {
|
||||||
@ -92,15 +178,21 @@ const example = extrude(10, exampleSketch)
|
|||||||
// Chamfers or fillets on this extrude group.
|
// Chamfers or fillets on this extrude group.
|
||||||
filletOrChamfers: [{
|
filletOrChamfers: [{
|
||||||
// The engine id of the edge to fillet.
|
// The engine id of the edge to fillet.
|
||||||
edge_id: uuid,
|
edgeId: uuid,
|
||||||
// The id of the engine command that called this fillet.
|
// The id of the engine command that called this fillet.
|
||||||
id: uuid,
|
id: uuid,
|
||||||
radius: number,
|
radius: number,
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
type: "fillet",
|
type: "fillet",
|
||||||
} |
|
} |
|
||||||
{
|
{
|
||||||
// The engine id of the edge to chamfer.
|
// The engine id of the edge to chamfer.
|
||||||
edge_id: uuid,
|
edgeId: uuid,
|
||||||
// The id of the engine command that called this chamfer.
|
// The id of the engine command that called this chamfer.
|
||||||
id: uuid,
|
id: uuid,
|
||||||
length: number,
|
length: number,
|
||||||
@ -118,7 +210,7 @@ const example = extrude(10, exampleSketch)
|
|||||||
id: uuid,
|
id: uuid,
|
||||||
// The sketch group.
|
// The sketch group.
|
||||||
sketchGroup: {
|
sketchGroup: {
|
||||||
// The id of the sketch group.
|
// The id of the sketch group (this will change when the engine's reference to it changes.
|
||||||
id: uuid,
|
id: uuid,
|
||||||
// What the sketch is on (can be a plane or a face).
|
// What the sketch is on (can be a plane or a face).
|
||||||
on: SketchSurface,
|
on: SketchSurface,
|
||||||
@ -269,6 +361,38 @@ const example = extrude(10, exampleSketch)
|
|||||||
value: string,
|
value: string,
|
||||||
},
|
},
|
||||||
type: "extrudeArc",
|
type: "extrudeArc",
|
||||||
|
} |
|
||||||
|
{
|
||||||
|
// The id for the chamfer surface.
|
||||||
|
faceId: uuid,
|
||||||
|
// The id of the geometry.
|
||||||
|
id: uuid,
|
||||||
|
// The source range.
|
||||||
|
sourceRange: [number, number],
|
||||||
|
// The tag.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
type: "chamfer",
|
||||||
|
} |
|
||||||
|
{
|
||||||
|
// The id for the fillet surface.
|
||||||
|
faceId: uuid,
|
||||||
|
// The id of the geometry.
|
||||||
|
id: uuid,
|
||||||
|
// The source range.
|
||||||
|
sourceRange: [number, number],
|
||||||
|
// The tag.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
type: "fillet",
|
||||||
}],
|
}],
|
||||||
},
|
},
|
||||||
// The id of the face.
|
// The id of the face.
|
||||||
@ -424,7 +548,7 @@ const example = extrude(10, exampleSketch)
|
|||||||
`SketchGroup` - A sketch group is a collection of paths.
|
`SketchGroup` - A sketch group is a collection of paths.
|
||||||
```js
|
```js
|
||||||
{
|
{
|
||||||
// The id of the sketch group.
|
// The id of the sketch group (this will change when the engine's reference to it changes.
|
||||||
id: uuid,
|
id: uuid,
|
||||||
// What the sketch is on (can be a plane or a face).
|
// What the sketch is on (can be a plane or a face).
|
||||||
on: {
|
on: {
|
||||||
@ -466,15 +590,21 @@ const example = extrude(10, exampleSketch)
|
|||||||
// Chamfers or fillets on this extrude group.
|
// Chamfers or fillets on this extrude group.
|
||||||
filletOrChamfers: [{
|
filletOrChamfers: [{
|
||||||
// The engine id of the edge to fillet.
|
// The engine id of the edge to fillet.
|
||||||
edge_id: uuid,
|
edgeId: uuid,
|
||||||
// The id of the engine command that called this fillet.
|
// The id of the engine command that called this fillet.
|
||||||
id: uuid,
|
id: uuid,
|
||||||
radius: number,
|
radius: number,
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
type: "fillet",
|
type: "fillet",
|
||||||
} |
|
} |
|
||||||
{
|
{
|
||||||
// The engine id of the edge to chamfer.
|
// The engine id of the edge to chamfer.
|
||||||
edge_id: uuid,
|
edgeId: uuid,
|
||||||
// The id of the engine command that called this chamfer.
|
// The id of the engine command that called this chamfer.
|
||||||
id: uuid,
|
id: uuid,
|
||||||
length: number,
|
length: number,
|
||||||
@ -492,7 +622,7 @@ const example = extrude(10, exampleSketch)
|
|||||||
id: uuid,
|
id: uuid,
|
||||||
// The sketch group.
|
// The sketch group.
|
||||||
sketchGroup: {
|
sketchGroup: {
|
||||||
// The id of the sketch group.
|
// The id of the sketch group (this will change when the engine's reference to it changes.
|
||||||
id: uuid,
|
id: uuid,
|
||||||
// What the sketch is on (can be a plane or a face).
|
// What the sketch is on (can be a plane or a face).
|
||||||
on: SketchSurface,
|
on: SketchSurface,
|
||||||
@ -643,6 +773,38 @@ const example = extrude(10, exampleSketch)
|
|||||||
value: string,
|
value: string,
|
||||||
},
|
},
|
||||||
type: "extrudeArc",
|
type: "extrudeArc",
|
||||||
|
} |
|
||||||
|
{
|
||||||
|
// The id for the chamfer surface.
|
||||||
|
faceId: uuid,
|
||||||
|
// The id of the geometry.
|
||||||
|
id: uuid,
|
||||||
|
// The source range.
|
||||||
|
sourceRange: [number, number],
|
||||||
|
// The tag.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
type: "chamfer",
|
||||||
|
} |
|
||||||
|
{
|
||||||
|
// The id for the fillet surface.
|
||||||
|
faceId: uuid,
|
||||||
|
// The id of the geometry.
|
||||||
|
id: uuid,
|
||||||
|
// The source range.
|
||||||
|
sourceRange: [number, number],
|
||||||
|
// The tag.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
type: "fillet",
|
||||||
}],
|
}],
|
||||||
},
|
},
|
||||||
// The id of the face.
|
// The id of the face.
|
||||||
|
@ -41,7 +41,7 @@ const example = extrude(10, exampleSketch)
|
|||||||
* `sketch_group`: `SketchGroup` - A sketch group is a collection of paths. (REQUIRED)
|
* `sketch_group`: `SketchGroup` - A sketch group is a collection of paths. (REQUIRED)
|
||||||
```js
|
```js
|
||||||
{
|
{
|
||||||
// The id of the sketch group.
|
// The id of the sketch group (this will change when the engine's reference to it changes.
|
||||||
id: uuid,
|
id: uuid,
|
||||||
// What the sketch is on (can be a plane or a face).
|
// What the sketch is on (can be a plane or a face).
|
||||||
on: {
|
on: {
|
||||||
@ -83,15 +83,21 @@ const example = extrude(10, exampleSketch)
|
|||||||
// Chamfers or fillets on this extrude group.
|
// Chamfers or fillets on this extrude group.
|
||||||
filletOrChamfers: [{
|
filletOrChamfers: [{
|
||||||
// The engine id of the edge to fillet.
|
// The engine id of the edge to fillet.
|
||||||
edge_id: uuid,
|
edgeId: uuid,
|
||||||
// The id of the engine command that called this fillet.
|
// The id of the engine command that called this fillet.
|
||||||
id: uuid,
|
id: uuid,
|
||||||
radius: number,
|
radius: number,
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
type: "fillet",
|
type: "fillet",
|
||||||
} |
|
} |
|
||||||
{
|
{
|
||||||
// The engine id of the edge to chamfer.
|
// The engine id of the edge to chamfer.
|
||||||
edge_id: uuid,
|
edgeId: uuid,
|
||||||
// The id of the engine command that called this chamfer.
|
// The id of the engine command that called this chamfer.
|
||||||
id: uuid,
|
id: uuid,
|
||||||
length: number,
|
length: number,
|
||||||
@ -109,7 +115,7 @@ const example = extrude(10, exampleSketch)
|
|||||||
id: uuid,
|
id: uuid,
|
||||||
// The sketch group.
|
// The sketch group.
|
||||||
sketchGroup: {
|
sketchGroup: {
|
||||||
// The id of the sketch group.
|
// The id of the sketch group (this will change when the engine's reference to it changes.
|
||||||
id: uuid,
|
id: uuid,
|
||||||
// What the sketch is on (can be a plane or a face).
|
// What the sketch is on (can be a plane or a face).
|
||||||
on: SketchSurface,
|
on: SketchSurface,
|
||||||
@ -260,6 +266,38 @@ const example = extrude(10, exampleSketch)
|
|||||||
value: string,
|
value: string,
|
||||||
},
|
},
|
||||||
type: "extrudeArc",
|
type: "extrudeArc",
|
||||||
|
} |
|
||||||
|
{
|
||||||
|
// The id for the chamfer surface.
|
||||||
|
faceId: uuid,
|
||||||
|
// The id of the geometry.
|
||||||
|
id: uuid,
|
||||||
|
// The source range.
|
||||||
|
sourceRange: [number, number],
|
||||||
|
// The tag.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
type: "chamfer",
|
||||||
|
} |
|
||||||
|
{
|
||||||
|
// The id for the fillet surface.
|
||||||
|
faceId: uuid,
|
||||||
|
// The id of the geometry.
|
||||||
|
id: uuid,
|
||||||
|
// The source range.
|
||||||
|
sourceRange: [number, number],
|
||||||
|
// The tag.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
type: "fillet",
|
||||||
}],
|
}],
|
||||||
},
|
},
|
||||||
// The id of the face.
|
// The id of the face.
|
||||||
@ -415,7 +453,7 @@ const example = extrude(10, exampleSketch)
|
|||||||
`SketchGroup` - A sketch group is a collection of paths.
|
`SketchGroup` - A sketch group is a collection of paths.
|
||||||
```js
|
```js
|
||||||
{
|
{
|
||||||
// The id of the sketch group.
|
// The id of the sketch group (this will change when the engine's reference to it changes.
|
||||||
id: uuid,
|
id: uuid,
|
||||||
// What the sketch is on (can be a plane or a face).
|
// What the sketch is on (can be a plane or a face).
|
||||||
on: {
|
on: {
|
||||||
@ -457,15 +495,21 @@ const example = extrude(10, exampleSketch)
|
|||||||
// Chamfers or fillets on this extrude group.
|
// Chamfers or fillets on this extrude group.
|
||||||
filletOrChamfers: [{
|
filletOrChamfers: [{
|
||||||
// The engine id of the edge to fillet.
|
// The engine id of the edge to fillet.
|
||||||
edge_id: uuid,
|
edgeId: uuid,
|
||||||
// The id of the engine command that called this fillet.
|
// The id of the engine command that called this fillet.
|
||||||
id: uuid,
|
id: uuid,
|
||||||
radius: number,
|
radius: number,
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
type: "fillet",
|
type: "fillet",
|
||||||
} |
|
} |
|
||||||
{
|
{
|
||||||
// The engine id of the edge to chamfer.
|
// The engine id of the edge to chamfer.
|
||||||
edge_id: uuid,
|
edgeId: uuid,
|
||||||
// The id of the engine command that called this chamfer.
|
// The id of the engine command that called this chamfer.
|
||||||
id: uuid,
|
id: uuid,
|
||||||
length: number,
|
length: number,
|
||||||
@ -483,7 +527,7 @@ const example = extrude(10, exampleSketch)
|
|||||||
id: uuid,
|
id: uuid,
|
||||||
// The sketch group.
|
// The sketch group.
|
||||||
sketchGroup: {
|
sketchGroup: {
|
||||||
// The id of the sketch group.
|
// The id of the sketch group (this will change when the engine's reference to it changes.
|
||||||
id: uuid,
|
id: uuid,
|
||||||
// What the sketch is on (can be a plane or a face).
|
// What the sketch is on (can be a plane or a face).
|
||||||
on: SketchSurface,
|
on: SketchSurface,
|
||||||
@ -634,6 +678,38 @@ const example = extrude(10, exampleSketch)
|
|||||||
value: string,
|
value: string,
|
||||||
},
|
},
|
||||||
type: "extrudeArc",
|
type: "extrudeArc",
|
||||||
|
} |
|
||||||
|
{
|
||||||
|
// The id for the chamfer surface.
|
||||||
|
faceId: uuid,
|
||||||
|
// The id of the geometry.
|
||||||
|
id: uuid,
|
||||||
|
// The source range.
|
||||||
|
sourceRange: [number, number],
|
||||||
|
// The tag.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
type: "chamfer",
|
||||||
|
} |
|
||||||
|
{
|
||||||
|
// The id for the fillet surface.
|
||||||
|
faceId: uuid,
|
||||||
|
// The id of the geometry.
|
||||||
|
id: uuid,
|
||||||
|
// The source range.
|
||||||
|
sourceRange: [number, number],
|
||||||
|
// The tag.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
type: "fillet",
|
||||||
}],
|
}],
|
||||||
},
|
},
|
||||||
// The id of the face.
|
// The id of the face.
|
||||||
|
102
docs/kcl/arc.md
34
docs/kcl/assert.md
Normal file
34
docs/kcl/assertGreaterThan.md
Normal file
35
docs/kcl/assertGreaterThanOrEq.md
Normal file
34
docs/kcl/assertLessThan.md
Normal file
35
docs/kcl/assertLessThanOrEq.md
Normal file
@ -19,8 +19,8 @@ const example = startSketchOn('XZ')
|
|||||||
|> startProfileAt([0, 0], %)
|
|> startProfileAt([0, 0], %)
|
||||||
|> line([10, 0], %)
|
|> line([10, 0], %)
|
||||||
|> arc({
|
|> arc({
|
||||||
angle_end: 0,
|
angleStart: 120,
|
||||||
angle_start: 120,
|
angleEnd: 0,
|
||||||
radius: 5
|
radius: 5
|
||||||
}, %)
|
}, %)
|
||||||
|> line([5, 0], %)
|
|> line([5, 0], %)
|
||||||
@ -41,8 +41,8 @@ const example = startSketchOn('XZ')
|
|||||||
const exampleSketch = startSketchOn('XZ')
|
const exampleSketch = startSketchOn('XZ')
|
||||||
|> startProfileAt([-10, 0], %)
|
|> startProfileAt([-10, 0], %)
|
||||||
|> arc({
|
|> arc({
|
||||||
angle_end: -60,
|
angleStart: 120,
|
||||||
angle_start: 120,
|
angleEnd: -60,
|
||||||
radius: 5
|
radius: 5
|
||||||
}, %)
|
}, %)
|
||||||
|> line([10, 0], %)
|
|> line([10, 0], %)
|
||||||
@ -67,7 +67,7 @@ const example = extrude(10, exampleSketch)
|
|||||||
* `sketch_group_set`: `SketchGroupSet` - A sketch group or a group of sketch groups. (REQUIRED)
|
* `sketch_group_set`: `SketchGroupSet` - A sketch group or a group of sketch groups. (REQUIRED)
|
||||||
```js
|
```js
|
||||||
{
|
{
|
||||||
// The id of the sketch group.
|
// The id of the sketch group (this will change when the engine's reference to it changes.
|
||||||
id: uuid,
|
id: uuid,
|
||||||
// What the sketch is on (can be a plane or a face).
|
// What the sketch is on (can be a plane or a face).
|
||||||
on: {
|
on: {
|
||||||
@ -109,15 +109,21 @@ const example = extrude(10, exampleSketch)
|
|||||||
// Chamfers or fillets on this extrude group.
|
// Chamfers or fillets on this extrude group.
|
||||||
filletOrChamfers: [{
|
filletOrChamfers: [{
|
||||||
// The engine id of the edge to fillet.
|
// The engine id of the edge to fillet.
|
||||||
edge_id: uuid,
|
edgeId: uuid,
|
||||||
// The id of the engine command that called this fillet.
|
// The id of the engine command that called this fillet.
|
||||||
id: uuid,
|
id: uuid,
|
||||||
radius: number,
|
radius: number,
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
type: "fillet",
|
type: "fillet",
|
||||||
} |
|
} |
|
||||||
{
|
{
|
||||||
// The engine id of the edge to chamfer.
|
// The engine id of the edge to chamfer.
|
||||||
edge_id: uuid,
|
edgeId: uuid,
|
||||||
// The id of the engine command that called this chamfer.
|
// The id of the engine command that called this chamfer.
|
||||||
id: uuid,
|
id: uuid,
|
||||||
length: number,
|
length: number,
|
||||||
@ -135,7 +141,7 @@ const example = extrude(10, exampleSketch)
|
|||||||
id: uuid,
|
id: uuid,
|
||||||
// The sketch group.
|
// The sketch group.
|
||||||
sketchGroup: {
|
sketchGroup: {
|
||||||
// The id of the sketch group.
|
// The id of the sketch group (this will change when the engine's reference to it changes.
|
||||||
id: uuid,
|
id: uuid,
|
||||||
// What the sketch is on (can be a plane or a face).
|
// What the sketch is on (can be a plane or a face).
|
||||||
on: SketchSurface,
|
on: SketchSurface,
|
||||||
@ -286,6 +292,38 @@ const example = extrude(10, exampleSketch)
|
|||||||
value: string,
|
value: string,
|
||||||
},
|
},
|
||||||
type: "extrudeArc",
|
type: "extrudeArc",
|
||||||
|
} |
|
||||||
|
{
|
||||||
|
// The id for the chamfer surface.
|
||||||
|
faceId: uuid,
|
||||||
|
// The id of the geometry.
|
||||||
|
id: uuid,
|
||||||
|
// The source range.
|
||||||
|
sourceRange: [number, number],
|
||||||
|
// The tag.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
type: "chamfer",
|
||||||
|
} |
|
||||||
|
{
|
||||||
|
// The id for the fillet surface.
|
||||||
|
faceId: uuid,
|
||||||
|
// The id of the geometry.
|
||||||
|
id: uuid,
|
||||||
|
// The source range.
|
||||||
|
sourceRange: [number, number],
|
||||||
|
// The tag.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
type: "fillet",
|
||||||
}],
|
}],
|
||||||
},
|
},
|
||||||
// The id of the face.
|
// The id of the face.
|
||||||
@ -441,15 +479,21 @@ const example = extrude(10, exampleSketch)
|
|||||||
// Chamfers or fillets on this extrude group.
|
// Chamfers or fillets on this extrude group.
|
||||||
filletOrChamfers: [{
|
filletOrChamfers: [{
|
||||||
// The engine id of the edge to fillet.
|
// The engine id of the edge to fillet.
|
||||||
edge_id: uuid,
|
edgeId: uuid,
|
||||||
// The id of the engine command that called this fillet.
|
// The id of the engine command that called this fillet.
|
||||||
id: uuid,
|
id: uuid,
|
||||||
radius: number,
|
radius: number,
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
type: "fillet",
|
type: "fillet",
|
||||||
} |
|
} |
|
||||||
{
|
{
|
||||||
// The engine id of the edge to chamfer.
|
// The engine id of the edge to chamfer.
|
||||||
edge_id: uuid,
|
edgeId: uuid,
|
||||||
// The id of the engine command that called this chamfer.
|
// The id of the engine command that called this chamfer.
|
||||||
id: uuid,
|
id: uuid,
|
||||||
length: number,
|
length: number,
|
||||||
@ -467,7 +511,7 @@ const example = extrude(10, exampleSketch)
|
|||||||
id: uuid,
|
id: uuid,
|
||||||
// The sketch group.
|
// The sketch group.
|
||||||
sketchGroup: {
|
sketchGroup: {
|
||||||
// The id of the sketch group.
|
// The id of the sketch group (this will change when the engine's reference to it changes.
|
||||||
id: uuid,
|
id: uuid,
|
||||||
// What the sketch is on (can be a plane or a face).
|
// What the sketch is on (can be a plane or a face).
|
||||||
on: {
|
on: {
|
||||||
@ -509,15 +553,21 @@ const example = extrude(10, exampleSketch)
|
|||||||
// Chamfers or fillets on this extrude group.
|
// Chamfers or fillets on this extrude group.
|
||||||
filletOrChamfers: [{
|
filletOrChamfers: [{
|
||||||
// The engine id of the edge to fillet.
|
// The engine id of the edge to fillet.
|
||||||
edge_id: uuid,
|
edgeId: uuid,
|
||||||
// The id of the engine command that called this fillet.
|
// The id of the engine command that called this fillet.
|
||||||
id: uuid,
|
id: uuid,
|
||||||
radius: number,
|
radius: number,
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
type: "fillet",
|
type: "fillet",
|
||||||
} |
|
} |
|
||||||
{
|
{
|
||||||
// The engine id of the edge to chamfer.
|
// The engine id of the edge to chamfer.
|
||||||
edge_id: uuid,
|
edgeId: uuid,
|
||||||
// The id of the engine command that called this chamfer.
|
// The id of the engine command that called this chamfer.
|
||||||
id: uuid,
|
id: uuid,
|
||||||
length: number,
|
length: number,
|
||||||
@ -569,6 +619,38 @@ const example = extrude(10, exampleSketch)
|
|||||||
value: string,
|
value: string,
|
||||||
},
|
},
|
||||||
type: "extrudeArc",
|
type: "extrudeArc",
|
||||||
|
} |
|
||||||
|
{
|
||||||
|
// The id for the chamfer surface.
|
||||||
|
faceId: uuid,
|
||||||
|
// The id of the geometry.
|
||||||
|
id: uuid,
|
||||||
|
// The source range.
|
||||||
|
sourceRange: [number, number],
|
||||||
|
// The tag.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
type: "chamfer",
|
||||||
|
} |
|
||||||
|
{
|
||||||
|
// The id for the fillet surface.
|
||||||
|
faceId: uuid,
|
||||||
|
// The id of the geometry.
|
||||||
|
id: uuid,
|
||||||
|
// The source range.
|
||||||
|
sourceRange: [number, number],
|
||||||
|
// The tag.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
type: "fillet",
|
||||||
}],
|
}],
|
||||||
},
|
},
|
||||||
// The id of the face.
|
// The id of the face.
|
||||||
@ -743,6 +825,38 @@ const example = extrude(10, exampleSketch)
|
|||||||
value: string,
|
value: string,
|
||||||
},
|
},
|
||||||
type: "extrudeArc",
|
type: "extrudeArc",
|
||||||
|
} |
|
||||||
|
{
|
||||||
|
// The id for the chamfer surface.
|
||||||
|
faceId: uuid,
|
||||||
|
// The id of the geometry.
|
||||||
|
id: uuid,
|
||||||
|
// The source range.
|
||||||
|
sourceRange: [number, number],
|
||||||
|
// The tag.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
type: "chamfer",
|
||||||
|
} |
|
||||||
|
{
|
||||||
|
// The id for the fillet surface.
|
||||||
|
faceId: uuid,
|
||||||
|
// The id of the geometry.
|
||||||
|
id: uuid,
|
||||||
|
// The source range.
|
||||||
|
sourceRange: [number, number],
|
||||||
|
// The tag.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
type: "fillet",
|
||||||
}],
|
}],
|
||||||
} |
|
} |
|
||||||
{
|
{
|
||||||
|
142
docs/kcl/hole.md
@ -20,6 +20,11 @@ layout: manual
|
|||||||
* [`angledLineToY`](kcl/angledLineToY)
|
* [`angledLineToY`](kcl/angledLineToY)
|
||||||
* [`arc`](kcl/arc)
|
* [`arc`](kcl/arc)
|
||||||
* [`asin`](kcl/asin)
|
* [`asin`](kcl/asin)
|
||||||
|
* [`assert`](kcl/assert)
|
||||||
|
* [`assertGreaterThan`](kcl/assertGreaterThan)
|
||||||
|
* [`assertGreaterThanOrEq`](kcl/assertGreaterThanOrEq)
|
||||||
|
* [`assertLessThan`](kcl/assertLessThan)
|
||||||
|
* [`assertLessThanOrEq`](kcl/assertLessThanOrEq)
|
||||||
* [`atan`](kcl/atan)
|
* [`atan`](kcl/atan)
|
||||||
* [`bezierCurve`](kcl/bezierCurve)
|
* [`bezierCurve`](kcl/bezierCurve)
|
||||||
* [`ceil`](kcl/ceil)
|
* [`ceil`](kcl/ceil)
|
||||||
@ -31,13 +36,13 @@ layout: manual
|
|||||||
* [`extrude`](kcl/extrude)
|
* [`extrude`](kcl/extrude)
|
||||||
* [`fillet`](kcl/fillet)
|
* [`fillet`](kcl/fillet)
|
||||||
* [`floor`](kcl/floor)
|
* [`floor`](kcl/floor)
|
||||||
* [`getEdge`](kcl/getEdge)
|
|
||||||
* [`getNextAdjacentEdge`](kcl/getNextAdjacentEdge)
|
* [`getNextAdjacentEdge`](kcl/getNextAdjacentEdge)
|
||||||
* [`getOppositeEdge`](kcl/getOppositeEdge)
|
* [`getOppositeEdge`](kcl/getOppositeEdge)
|
||||||
* [`getPreviousAdjacentEdge`](kcl/getPreviousAdjacentEdge)
|
* [`getPreviousAdjacentEdge`](kcl/getPreviousAdjacentEdge)
|
||||||
* [`helix`](kcl/helix)
|
* [`helix`](kcl/helix)
|
||||||
* [`hole`](kcl/hole)
|
* [`hole`](kcl/hole)
|
||||||
* [`import`](kcl/import)
|
* [`import`](kcl/import)
|
||||||
|
* [`int`](kcl/int)
|
||||||
* [`lastSegX`](kcl/lastSegX)
|
* [`lastSegX`](kcl/lastSegX)
|
||||||
* [`lastSegY`](kcl/lastSegY)
|
* [`lastSegY`](kcl/lastSegY)
|
||||||
* [`legAngX`](kcl/legAngX)
|
* [`legAngX`](kcl/legAngX)
|
||||||
@ -57,6 +62,7 @@ layout: manual
|
|||||||
* [`patternLinear3d`](kcl/patternLinear3d)
|
* [`patternLinear3d`](kcl/patternLinear3d)
|
||||||
* [`patternTransform`](kcl/patternTransform)
|
* [`patternTransform`](kcl/patternTransform)
|
||||||
* [`pi`](kcl/pi)
|
* [`pi`](kcl/pi)
|
||||||
|
* [`polar`](kcl/polar)
|
||||||
* [`pow`](kcl/pow)
|
* [`pow`](kcl/pow)
|
||||||
* [`profileStart`](kcl/profileStart)
|
* [`profileStart`](kcl/profileStart)
|
||||||
* [`profileStartX`](kcl/profileStartX)
|
* [`profileStartX`](kcl/profileStartX)
|
||||||
|
43
docs/kcl/int.md
Normal file
48
docs/kcl/polar.md
Normal file
@ -29,7 +29,7 @@ const sketch001 = startSketchOn('XY')
|
|||||||
* `sketch_group`: `SketchGroup` - A sketch group is a collection of paths. (REQUIRED)
|
* `sketch_group`: `SketchGroup` - A sketch group is a collection of paths. (REQUIRED)
|
||||||
```js
|
```js
|
||||||
{
|
{
|
||||||
// The id of the sketch group.
|
// The id of the sketch group (this will change when the engine's reference to it changes.
|
||||||
id: uuid,
|
id: uuid,
|
||||||
// What the sketch is on (can be a plane or a face).
|
// What the sketch is on (can be a plane or a face).
|
||||||
on: {
|
on: {
|
||||||
@ -71,15 +71,21 @@ const sketch001 = startSketchOn('XY')
|
|||||||
// Chamfers or fillets on this extrude group.
|
// Chamfers or fillets on this extrude group.
|
||||||
filletOrChamfers: [{
|
filletOrChamfers: [{
|
||||||
// The engine id of the edge to fillet.
|
// The engine id of the edge to fillet.
|
||||||
edge_id: uuid,
|
edgeId: uuid,
|
||||||
// The id of the engine command that called this fillet.
|
// The id of the engine command that called this fillet.
|
||||||
id: uuid,
|
id: uuid,
|
||||||
radius: number,
|
radius: number,
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
type: "fillet",
|
type: "fillet",
|
||||||
} |
|
} |
|
||||||
{
|
{
|
||||||
// The engine id of the edge to chamfer.
|
// The engine id of the edge to chamfer.
|
||||||
edge_id: uuid,
|
edgeId: uuid,
|
||||||
// The id of the engine command that called this chamfer.
|
// The id of the engine command that called this chamfer.
|
||||||
id: uuid,
|
id: uuid,
|
||||||
length: number,
|
length: number,
|
||||||
@ -97,7 +103,7 @@ const sketch001 = startSketchOn('XY')
|
|||||||
id: uuid,
|
id: uuid,
|
||||||
// The sketch group.
|
// The sketch group.
|
||||||
sketchGroup: {
|
sketchGroup: {
|
||||||
// The id of the sketch group.
|
// The id of the sketch group (this will change when the engine's reference to it changes.
|
||||||
id: uuid,
|
id: uuid,
|
||||||
// What the sketch is on (can be a plane or a face).
|
// What the sketch is on (can be a plane or a face).
|
||||||
on: SketchSurface,
|
on: SketchSurface,
|
||||||
@ -248,6 +254,38 @@ const sketch001 = startSketchOn('XY')
|
|||||||
value: string,
|
value: string,
|
||||||
},
|
},
|
||||||
type: "extrudeArc",
|
type: "extrudeArc",
|
||||||
|
} |
|
||||||
|
{
|
||||||
|
// The id for the chamfer surface.
|
||||||
|
faceId: uuid,
|
||||||
|
// The id of the geometry.
|
||||||
|
id: uuid,
|
||||||
|
// The source range.
|
||||||
|
sourceRange: [number, number],
|
||||||
|
// The tag.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
type: "chamfer",
|
||||||
|
} |
|
||||||
|
{
|
||||||
|
// The id for the fillet surface.
|
||||||
|
faceId: uuid,
|
||||||
|
// The id of the geometry.
|
||||||
|
id: uuid,
|
||||||
|
// The source range.
|
||||||
|
sourceRange: [number, number],
|
||||||
|
// The tag.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
type: "fillet",
|
||||||
}],
|
}],
|
||||||
},
|
},
|
||||||
// The id of the face.
|
// The id of the face.
|
||||||
|
@ -28,7 +28,7 @@ const sketch001 = startSketchOn('XY')
|
|||||||
* `sketch_group`: `SketchGroup` - A sketch group is a collection of paths. (REQUIRED)
|
* `sketch_group`: `SketchGroup` - A sketch group is a collection of paths. (REQUIRED)
|
||||||
```js
|
```js
|
||||||
{
|
{
|
||||||
// The id of the sketch group.
|
// The id of the sketch group (this will change when the engine's reference to it changes.
|
||||||
id: uuid,
|
id: uuid,
|
||||||
// What the sketch is on (can be a plane or a face).
|
// What the sketch is on (can be a plane or a face).
|
||||||
on: {
|
on: {
|
||||||
@ -70,15 +70,21 @@ const sketch001 = startSketchOn('XY')
|
|||||||
// Chamfers or fillets on this extrude group.
|
// Chamfers or fillets on this extrude group.
|
||||||
filletOrChamfers: [{
|
filletOrChamfers: [{
|
||||||
// The engine id of the edge to fillet.
|
// The engine id of the edge to fillet.
|
||||||
edge_id: uuid,
|
edgeId: uuid,
|
||||||
// The id of the engine command that called this fillet.
|
// The id of the engine command that called this fillet.
|
||||||
id: uuid,
|
id: uuid,
|
||||||
radius: number,
|
radius: number,
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
type: "fillet",
|
type: "fillet",
|
||||||
} |
|
} |
|
||||||
{
|
{
|
||||||
// The engine id of the edge to chamfer.
|
// The engine id of the edge to chamfer.
|
||||||
edge_id: uuid,
|
edgeId: uuid,
|
||||||
// The id of the engine command that called this chamfer.
|
// The id of the engine command that called this chamfer.
|
||||||
id: uuid,
|
id: uuid,
|
||||||
length: number,
|
length: number,
|
||||||
@ -96,7 +102,7 @@ const sketch001 = startSketchOn('XY')
|
|||||||
id: uuid,
|
id: uuid,
|
||||||
// The sketch group.
|
// The sketch group.
|
||||||
sketchGroup: {
|
sketchGroup: {
|
||||||
// The id of the sketch group.
|
// The id of the sketch group (this will change when the engine's reference to it changes.
|
||||||
id: uuid,
|
id: uuid,
|
||||||
// What the sketch is on (can be a plane or a face).
|
// What the sketch is on (can be a plane or a face).
|
||||||
on: SketchSurface,
|
on: SketchSurface,
|
||||||
@ -247,6 +253,38 @@ const sketch001 = startSketchOn('XY')
|
|||||||
value: string,
|
value: string,
|
||||||
},
|
},
|
||||||
type: "extrudeArc",
|
type: "extrudeArc",
|
||||||
|
} |
|
||||||
|
{
|
||||||
|
// The id for the chamfer surface.
|
||||||
|
faceId: uuid,
|
||||||
|
// The id of the geometry.
|
||||||
|
id: uuid,
|
||||||
|
// The source range.
|
||||||
|
sourceRange: [number, number],
|
||||||
|
// The tag.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
type: "chamfer",
|
||||||
|
} |
|
||||||
|
{
|
||||||
|
// The id for the fillet surface.
|
||||||
|
faceId: uuid,
|
||||||
|
// The id of the geometry.
|
||||||
|
id: uuid,
|
||||||
|
// The source range.
|
||||||
|
sourceRange: [number, number],
|
||||||
|
// The tag.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
type: "fillet",
|
||||||
}],
|
}],
|
||||||
},
|
},
|
||||||
// The id of the face.
|
// The id of the face.
|
||||||
|
@ -9,7 +9,7 @@ Returns the angle of the segment.
|
|||||||
|
|
||||||
|
|
||||||
```js
|
```js
|
||||||
segAng(segment_name: TagIdentifier, sketch_group: SketchGroup) -> number
|
segAng(tag: TagIdentifier) -> number
|
||||||
```
|
```
|
||||||
|
|
||||||
### Examples
|
### Examples
|
||||||
@ -20,9 +20,9 @@ const exampleSketch = startSketchOn('XZ')
|
|||||||
|> 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)
|
||||||
@ -32,89 +32,15 @@ const example = extrude(4, exampleSketch)
|
|||||||
|
|
||||||
### Arguments
|
### Arguments
|
||||||
|
|
||||||
* `segment_name`: `TagIdentifier` (REQUIRED)
|
* `tag`: `TagIdentifier` (REQUIRED)
|
||||||
```js
|
```js
|
||||||
{
|
{
|
||||||
value: string,
|
// Engine information for a tag.
|
||||||
}
|
info: {
|
||||||
```
|
// The id of the tagged object.
|
||||||
* `sketch_group`: `SketchGroup` - A sketch group is a collection of paths. (REQUIRED)
|
|
||||||
```js
|
|
||||||
{
|
|
||||||
// The id of the sketch group.
|
|
||||||
id: uuid,
|
id: uuid,
|
||||||
// What the sketch is on (can be a plane or a face).
|
// The path the tag is on.
|
||||||
on: {
|
path: {
|
||||||
// The id of the plane.
|
|
||||||
id: uuid,
|
|
||||||
// Origin of the plane.
|
|
||||||
origin: {
|
|
||||||
x: number,
|
|
||||||
y: number,
|
|
||||||
z: number,
|
|
||||||
},
|
|
||||||
type: "plane",
|
|
||||||
// Type for a plane.
|
|
||||||
value: "XY" | "XZ" | "YZ" | "Custom",
|
|
||||||
// What should the plane’s X axis be?
|
|
||||||
xAxis: {
|
|
||||||
x: number,
|
|
||||||
y: number,
|
|
||||||
z: number,
|
|
||||||
},
|
|
||||||
// What should the plane’s Y axis be?
|
|
||||||
yAxis: {
|
|
||||||
x: number,
|
|
||||||
y: number,
|
|
||||||
z: number,
|
|
||||||
},
|
|
||||||
// The z-axis (normal).
|
|
||||||
zAxis: {
|
|
||||||
x: number,
|
|
||||||
y: number,
|
|
||||||
z: number,
|
|
||||||
},
|
|
||||||
} |
|
|
||||||
{
|
|
||||||
// The extrude group the face is on.
|
|
||||||
extrudeGroup: {
|
|
||||||
// The id of the extrusion end cap
|
|
||||||
endCapId: uuid,
|
|
||||||
// Chamfers or fillets on this extrude group.
|
|
||||||
filletOrChamfers: [{
|
|
||||||
// The engine id of the edge to fillet.
|
|
||||||
edge_id: uuid,
|
|
||||||
// The id of the engine command that called this fillet.
|
|
||||||
id: uuid,
|
|
||||||
radius: number,
|
|
||||||
type: "fillet",
|
|
||||||
} |
|
|
||||||
{
|
|
||||||
// The engine id of the edge to chamfer.
|
|
||||||
edge_id: uuid,
|
|
||||||
// The id of the engine command that called this chamfer.
|
|
||||||
id: uuid,
|
|
||||||
length: number,
|
|
||||||
tag: {
|
|
||||||
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
|
||||||
end: number,
|
|
||||||
start: number,
|
|
||||||
value: string,
|
|
||||||
},
|
|
||||||
type: "chamfer",
|
|
||||||
}],
|
|
||||||
// The height of the extrude group.
|
|
||||||
height: number,
|
|
||||||
// The id of the extrude group.
|
|
||||||
id: uuid,
|
|
||||||
// The sketch group.
|
|
||||||
sketchGroup: {
|
|
||||||
// The id of the sketch group.
|
|
||||||
id: uuid,
|
|
||||||
// What the sketch is on (can be a plane or a face).
|
|
||||||
on: SketchSurface,
|
|
||||||
// The starting path.
|
|
||||||
start: {
|
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
// The tag of the path.
|
// The tag of the path.
|
||||||
@ -127,109 +53,10 @@ const example = extrude(4, exampleSketch)
|
|||||||
// The to point.
|
// The to point.
|
||||||
to: [number, number],
|
to: [number, number],
|
||||||
},
|
},
|
||||||
// Tag identifiers that have been declared in this sketch group.
|
// The sketch group the tag is on.
|
||||||
tags: {
|
sketchGroup: uuid,
|
||||||
},
|
// The surface information for the tag.
|
||||||
// The paths in the sketch group.
|
surface: {
|
||||||
value: [{
|
|
||||||
// The from point.
|
|
||||||
from: [number, number],
|
|
||||||
// The tag of the path.
|
|
||||||
tag: {
|
|
||||||
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
|
||||||
end: number,
|
|
||||||
start: number,
|
|
||||||
value: string,
|
|
||||||
},
|
|
||||||
// The to point.
|
|
||||||
to: [number, number],
|
|
||||||
type: "ToPoint",
|
|
||||||
} |
|
|
||||||
{
|
|
||||||
// arc's direction
|
|
||||||
ccw: string,
|
|
||||||
// the arc's center
|
|
||||||
center: [number, number],
|
|
||||||
// The from point.
|
|
||||||
from: [number, number],
|
|
||||||
// The tag of the path.
|
|
||||||
tag: {
|
|
||||||
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
|
||||||
end: number,
|
|
||||||
start: number,
|
|
||||||
value: string,
|
|
||||||
},
|
|
||||||
// The to point.
|
|
||||||
to: [number, number],
|
|
||||||
type: "TangentialArcTo",
|
|
||||||
} |
|
|
||||||
{
|
|
||||||
// The from point.
|
|
||||||
from: [number, number],
|
|
||||||
// The tag of the path.
|
|
||||||
tag: {
|
|
||||||
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
|
||||||
end: number,
|
|
||||||
start: number,
|
|
||||||
value: string,
|
|
||||||
},
|
|
||||||
// The to point.
|
|
||||||
to: [number, number],
|
|
||||||
type: "TangentialArc",
|
|
||||||
} |
|
|
||||||
{
|
|
||||||
// The from point.
|
|
||||||
from: [number, number],
|
|
||||||
// The tag of the path.
|
|
||||||
tag: {
|
|
||||||
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
|
||||||
end: number,
|
|
||||||
start: number,
|
|
||||||
value: string,
|
|
||||||
},
|
|
||||||
// The to point.
|
|
||||||
to: [number, number],
|
|
||||||
type: "Horizontal",
|
|
||||||
// The x coordinate.
|
|
||||||
x: number,
|
|
||||||
} |
|
|
||||||
{
|
|
||||||
// The from point.
|
|
||||||
from: [number, number],
|
|
||||||
// The tag of the path.
|
|
||||||
tag: {
|
|
||||||
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
|
||||||
end: number,
|
|
||||||
start: number,
|
|
||||||
value: string,
|
|
||||||
},
|
|
||||||
// The to point.
|
|
||||||
to: [number, number],
|
|
||||||
type: "AngledLineTo",
|
|
||||||
// The x coordinate.
|
|
||||||
x: number,
|
|
||||||
// The y coordinate.
|
|
||||||
y: number,
|
|
||||||
} |
|
|
||||||
{
|
|
||||||
// The from point.
|
|
||||||
from: [number, number],
|
|
||||||
// The tag of the path.
|
|
||||||
tag: {
|
|
||||||
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
|
||||||
end: number,
|
|
||||||
start: number,
|
|
||||||
value: string,
|
|
||||||
},
|
|
||||||
// The to point.
|
|
||||||
to: [number, number],
|
|
||||||
type: "Base",
|
|
||||||
}],
|
|
||||||
},
|
|
||||||
// The id of the extrusion start cap
|
|
||||||
startCapId: uuid,
|
|
||||||
// The extrude surfaces.
|
|
||||||
value: [{
|
|
||||||
// The face id for the extrude plane.
|
// The face id for the extrude plane.
|
||||||
faceId: uuid,
|
faceId: uuid,
|
||||||
// The id of the geometry.
|
// The id of the geometry.
|
||||||
@ -260,144 +87,41 @@ const example = extrude(4, exampleSketch)
|
|||||||
value: string,
|
value: string,
|
||||||
},
|
},
|
||||||
type: "extrudeArc",
|
type: "extrudeArc",
|
||||||
}],
|
} |
|
||||||
},
|
{
|
||||||
// The id of the face.
|
// The id for the chamfer surface.
|
||||||
|
faceId: uuid,
|
||||||
|
// The id of the geometry.
|
||||||
id: uuid,
|
id: uuid,
|
||||||
type: "face",
|
// The source range.
|
||||||
// The tag of the face.
|
sourceRange: [number, number],
|
||||||
value: string,
|
// The tag.
|
||||||
// What should the face’s X axis be?
|
|
||||||
xAxis: {
|
|
||||||
x: number,
|
|
||||||
y: number,
|
|
||||||
z: number,
|
|
||||||
},
|
|
||||||
// What should the face’s Y axis be?
|
|
||||||
yAxis: {
|
|
||||||
x: number,
|
|
||||||
y: number,
|
|
||||||
z: number,
|
|
||||||
},
|
|
||||||
// The z-axis (normal).
|
|
||||||
zAxis: {
|
|
||||||
x: number,
|
|
||||||
y: number,
|
|
||||||
z: number,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
// The starting path.
|
|
||||||
start: {
|
|
||||||
// The from point.
|
|
||||||
from: [number, number],
|
|
||||||
// The tag of the path.
|
|
||||||
tag: {
|
tag: {
|
||||||
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
end: number,
|
end: number,
|
||||||
start: number,
|
start: number,
|
||||||
value: string,
|
value: string,
|
||||||
},
|
},
|
||||||
// The to point.
|
type: "chamfer",
|
||||||
to: [number, number],
|
|
||||||
},
|
|
||||||
// Tag identifiers that have been declared in this sketch group.
|
|
||||||
tags: {
|
|
||||||
},
|
|
||||||
// The paths in the sketch group.
|
|
||||||
value: [{
|
|
||||||
// The from point.
|
|
||||||
from: [number, number],
|
|
||||||
// The tag of the path.
|
|
||||||
tag: {
|
|
||||||
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
|
||||||
end: number,
|
|
||||||
start: number,
|
|
||||||
value: string,
|
|
||||||
},
|
|
||||||
// The to point.
|
|
||||||
to: [number, number],
|
|
||||||
type: "ToPoint",
|
|
||||||
} |
|
} |
|
||||||
{
|
{
|
||||||
// arc's direction
|
// The id for the fillet surface.
|
||||||
ccw: string,
|
faceId: uuid,
|
||||||
// the arc's center
|
// The id of the geometry.
|
||||||
center: [number, number],
|
id: uuid,
|
||||||
// The from point.
|
// The source range.
|
||||||
from: [number, number],
|
sourceRange: [number, number],
|
||||||
// The tag of the path.
|
// The tag.
|
||||||
tag: {
|
tag: {
|
||||||
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
end: number,
|
end: number,
|
||||||
start: number,
|
start: number,
|
||||||
value: string,
|
value: string,
|
||||||
},
|
},
|
||||||
// The to point.
|
type: "fillet",
|
||||||
to: [number, number],
|
|
||||||
type: "TangentialArcTo",
|
|
||||||
} |
|
|
||||||
{
|
|
||||||
// The from point.
|
|
||||||
from: [number, number],
|
|
||||||
// The tag of the path.
|
|
||||||
tag: {
|
|
||||||
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
|
||||||
end: number,
|
|
||||||
start: number,
|
|
||||||
value: string,
|
|
||||||
},
|
},
|
||||||
// The to point.
|
|
||||||
to: [number, number],
|
|
||||||
type: "TangentialArc",
|
|
||||||
} |
|
|
||||||
{
|
|
||||||
// The from point.
|
|
||||||
from: [number, number],
|
|
||||||
// The tag of the path.
|
|
||||||
tag: {
|
|
||||||
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
|
||||||
end: number,
|
|
||||||
start: number,
|
|
||||||
value: string,
|
|
||||||
},
|
},
|
||||||
// The to point.
|
|
||||||
to: [number, number],
|
|
||||||
type: "Horizontal",
|
|
||||||
// The x coordinate.
|
|
||||||
x: number,
|
|
||||||
} |
|
|
||||||
{
|
|
||||||
// The from point.
|
|
||||||
from: [number, number],
|
|
||||||
// The tag of the path.
|
|
||||||
tag: {
|
|
||||||
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
|
||||||
end: number,
|
|
||||||
start: number,
|
|
||||||
value: string,
|
value: string,
|
||||||
},
|
|
||||||
// The to point.
|
|
||||||
to: [number, number],
|
|
||||||
type: "AngledLineTo",
|
|
||||||
// The x coordinate.
|
|
||||||
x: number,
|
|
||||||
// The y coordinate.
|
|
||||||
y: number,
|
|
||||||
} |
|
|
||||||
{
|
|
||||||
// The from point.
|
|
||||||
from: [number, number],
|
|
||||||
// The tag of the path.
|
|
||||||
tag: {
|
|
||||||
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
|
||||||
end: number,
|
|
||||||
start: number,
|
|
||||||
value: string,
|
|
||||||
},
|
|
||||||
// The to point.
|
|
||||||
to: [number, number],
|
|
||||||
type: "Base",
|
|
||||||
}],
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ Returns the segment end of y.
|
|||||||
|
|
||||||
|
|
||||||
```js
|
```js
|
||||||
segEndY(segment_name: TagIdentifier, sketch_group: SketchGroup) -> number
|
segEndY(tag: TagIdentifier) -> number
|
||||||
```
|
```
|
||||||
|
|
||||||
### Examples
|
### Examples
|
||||||
@ -20,7 +20,7 @@ const exampleSketch = startSketchOn('XZ')
|
|||||||
|> 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(%)
|
||||||
|
|
||||||
@ -31,89 +31,15 @@ const example = extrude(5, exampleSketch)
|
|||||||
|
|
||||||
### Arguments
|
### Arguments
|
||||||
|
|
||||||
* `segment_name`: `TagIdentifier` (REQUIRED)
|
* `tag`: `TagIdentifier` (REQUIRED)
|
||||||
```js
|
```js
|
||||||
{
|
{
|
||||||
value: string,
|
// Engine information for a tag.
|
||||||
}
|
info: {
|
||||||
```
|
// The id of the tagged object.
|
||||||
* `sketch_group`: `SketchGroup` - A sketch group is a collection of paths. (REQUIRED)
|
|
||||||
```js
|
|
||||||
{
|
|
||||||
// The id of the sketch group.
|
|
||||||
id: uuid,
|
id: uuid,
|
||||||
// What the sketch is on (can be a plane or a face).
|
// The path the tag is on.
|
||||||
on: {
|
path: {
|
||||||
// The id of the plane.
|
|
||||||
id: uuid,
|
|
||||||
// Origin of the plane.
|
|
||||||
origin: {
|
|
||||||
x: number,
|
|
||||||
y: number,
|
|
||||||
z: number,
|
|
||||||
},
|
|
||||||
type: "plane",
|
|
||||||
// Type for a plane.
|
|
||||||
value: "XY" | "XZ" | "YZ" | "Custom",
|
|
||||||
// What should the plane’s X axis be?
|
|
||||||
xAxis: {
|
|
||||||
x: number,
|
|
||||||
y: number,
|
|
||||||
z: number,
|
|
||||||
},
|
|
||||||
// What should the plane’s Y axis be?
|
|
||||||
yAxis: {
|
|
||||||
x: number,
|
|
||||||
y: number,
|
|
||||||
z: number,
|
|
||||||
},
|
|
||||||
// The z-axis (normal).
|
|
||||||
zAxis: {
|
|
||||||
x: number,
|
|
||||||
y: number,
|
|
||||||
z: number,
|
|
||||||
},
|
|
||||||
} |
|
|
||||||
{
|
|
||||||
// The extrude group the face is on.
|
|
||||||
extrudeGroup: {
|
|
||||||
// The id of the extrusion end cap
|
|
||||||
endCapId: uuid,
|
|
||||||
// Chamfers or fillets on this extrude group.
|
|
||||||
filletOrChamfers: [{
|
|
||||||
// The engine id of the edge to fillet.
|
|
||||||
edge_id: uuid,
|
|
||||||
// The id of the engine command that called this fillet.
|
|
||||||
id: uuid,
|
|
||||||
radius: number,
|
|
||||||
type: "fillet",
|
|
||||||
} |
|
|
||||||
{
|
|
||||||
// The engine id of the edge to chamfer.
|
|
||||||
edge_id: uuid,
|
|
||||||
// The id of the engine command that called this chamfer.
|
|
||||||
id: uuid,
|
|
||||||
length: number,
|
|
||||||
tag: {
|
|
||||||
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
|
||||||
end: number,
|
|
||||||
start: number,
|
|
||||||
value: string,
|
|
||||||
},
|
|
||||||
type: "chamfer",
|
|
||||||
}],
|
|
||||||
// The height of the extrude group.
|
|
||||||
height: number,
|
|
||||||
// The id of the extrude group.
|
|
||||||
id: uuid,
|
|
||||||
// The sketch group.
|
|
||||||
sketchGroup: {
|
|
||||||
// The id of the sketch group.
|
|
||||||
id: uuid,
|
|
||||||
// What the sketch is on (can be a plane or a face).
|
|
||||||
on: SketchSurface,
|
|
||||||
// The starting path.
|
|
||||||
start: {
|
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
// The tag of the path.
|
// The tag of the path.
|
||||||
@ -126,109 +52,10 @@ const example = extrude(5, exampleSketch)
|
|||||||
// The to point.
|
// The to point.
|
||||||
to: [number, number],
|
to: [number, number],
|
||||||
},
|
},
|
||||||
// Tag identifiers that have been declared in this sketch group.
|
// The sketch group the tag is on.
|
||||||
tags: {
|
sketchGroup: uuid,
|
||||||
},
|
// The surface information for the tag.
|
||||||
// The paths in the sketch group.
|
surface: {
|
||||||
value: [{
|
|
||||||
// The from point.
|
|
||||||
from: [number, number],
|
|
||||||
// The tag of the path.
|
|
||||||
tag: {
|
|
||||||
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
|
||||||
end: number,
|
|
||||||
start: number,
|
|
||||||
value: string,
|
|
||||||
},
|
|
||||||
// The to point.
|
|
||||||
to: [number, number],
|
|
||||||
type: "ToPoint",
|
|
||||||
} |
|
|
||||||
{
|
|
||||||
// arc's direction
|
|
||||||
ccw: string,
|
|
||||||
// the arc's center
|
|
||||||
center: [number, number],
|
|
||||||
// The from point.
|
|
||||||
from: [number, number],
|
|
||||||
// The tag of the path.
|
|
||||||
tag: {
|
|
||||||
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
|
||||||
end: number,
|
|
||||||
start: number,
|
|
||||||
value: string,
|
|
||||||
},
|
|
||||||
// The to point.
|
|
||||||
to: [number, number],
|
|
||||||
type: "TangentialArcTo",
|
|
||||||
} |
|
|
||||||
{
|
|
||||||
// The from point.
|
|
||||||
from: [number, number],
|
|
||||||
// The tag of the path.
|
|
||||||
tag: {
|
|
||||||
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
|
||||||
end: number,
|
|
||||||
start: number,
|
|
||||||
value: string,
|
|
||||||
},
|
|
||||||
// The to point.
|
|
||||||
to: [number, number],
|
|
||||||
type: "TangentialArc",
|
|
||||||
} |
|
|
||||||
{
|
|
||||||
// The from point.
|
|
||||||
from: [number, number],
|
|
||||||
// The tag of the path.
|
|
||||||
tag: {
|
|
||||||
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
|
||||||
end: number,
|
|
||||||
start: number,
|
|
||||||
value: string,
|
|
||||||
},
|
|
||||||
// The to point.
|
|
||||||
to: [number, number],
|
|
||||||
type: "Horizontal",
|
|
||||||
// The x coordinate.
|
|
||||||
x: number,
|
|
||||||
} |
|
|
||||||
{
|
|
||||||
// The from point.
|
|
||||||
from: [number, number],
|
|
||||||
// The tag of the path.
|
|
||||||
tag: {
|
|
||||||
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
|
||||||
end: number,
|
|
||||||
start: number,
|
|
||||||
value: string,
|
|
||||||
},
|
|
||||||
// The to point.
|
|
||||||
to: [number, number],
|
|
||||||
type: "AngledLineTo",
|
|
||||||
// The x coordinate.
|
|
||||||
x: number,
|
|
||||||
// The y coordinate.
|
|
||||||
y: number,
|
|
||||||
} |
|
|
||||||
{
|
|
||||||
// The from point.
|
|
||||||
from: [number, number],
|
|
||||||
// The tag of the path.
|
|
||||||
tag: {
|
|
||||||
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
|
||||||
end: number,
|
|
||||||
start: number,
|
|
||||||
value: string,
|
|
||||||
},
|
|
||||||
// The to point.
|
|
||||||
to: [number, number],
|
|
||||||
type: "Base",
|
|
||||||
}],
|
|
||||||
},
|
|
||||||
// The id of the extrusion start cap
|
|
||||||
startCapId: uuid,
|
|
||||||
// The extrude surfaces.
|
|
||||||
value: [{
|
|
||||||
// The face id for the extrude plane.
|
// The face id for the extrude plane.
|
||||||
faceId: uuid,
|
faceId: uuid,
|
||||||
// The id of the geometry.
|
// The id of the geometry.
|
||||||
@ -259,144 +86,41 @@ const example = extrude(5, exampleSketch)
|
|||||||
value: string,
|
value: string,
|
||||||
},
|
},
|
||||||
type: "extrudeArc",
|
type: "extrudeArc",
|
||||||
}],
|
} |
|
||||||
},
|
{
|
||||||
// The id of the face.
|
// The id for the chamfer surface.
|
||||||
|
faceId: uuid,
|
||||||
|
// The id of the geometry.
|
||||||
id: uuid,
|
id: uuid,
|
||||||
type: "face",
|
// The source range.
|
||||||
// The tag of the face.
|
sourceRange: [number, number],
|
||||||
value: string,
|
// The tag.
|
||||||
// What should the face’s X axis be?
|
|
||||||
xAxis: {
|
|
||||||
x: number,
|
|
||||||
y: number,
|
|
||||||
z: number,
|
|
||||||
},
|
|
||||||
// What should the face’s Y axis be?
|
|
||||||
yAxis: {
|
|
||||||
x: number,
|
|
||||||
y: number,
|
|
||||||
z: number,
|
|
||||||
},
|
|
||||||
// The z-axis (normal).
|
|
||||||
zAxis: {
|
|
||||||
x: number,
|
|
||||||
y: number,
|
|
||||||
z: number,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
// The starting path.
|
|
||||||
start: {
|
|
||||||
// The from point.
|
|
||||||
from: [number, number],
|
|
||||||
// The tag of the path.
|
|
||||||
tag: {
|
tag: {
|
||||||
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
end: number,
|
end: number,
|
||||||
start: number,
|
start: number,
|
||||||
value: string,
|
value: string,
|
||||||
},
|
},
|
||||||
// The to point.
|
type: "chamfer",
|
||||||
to: [number, number],
|
|
||||||
},
|
|
||||||
// Tag identifiers that have been declared in this sketch group.
|
|
||||||
tags: {
|
|
||||||
},
|
|
||||||
// The paths in the sketch group.
|
|
||||||
value: [{
|
|
||||||
// The from point.
|
|
||||||
from: [number, number],
|
|
||||||
// The tag of the path.
|
|
||||||
tag: {
|
|
||||||
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
|
||||||
end: number,
|
|
||||||
start: number,
|
|
||||||
value: string,
|
|
||||||
},
|
|
||||||
// The to point.
|
|
||||||
to: [number, number],
|
|
||||||
type: "ToPoint",
|
|
||||||
} |
|
} |
|
||||||
{
|
{
|
||||||
// arc's direction
|
// The id for the fillet surface.
|
||||||
ccw: string,
|
faceId: uuid,
|
||||||
// the arc's center
|
// The id of the geometry.
|
||||||
center: [number, number],
|
id: uuid,
|
||||||
// The from point.
|
// The source range.
|
||||||
from: [number, number],
|
sourceRange: [number, number],
|
||||||
// The tag of the path.
|
// The tag.
|
||||||
tag: {
|
tag: {
|
||||||
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
end: number,
|
end: number,
|
||||||
start: number,
|
start: number,
|
||||||
value: string,
|
value: string,
|
||||||
},
|
},
|
||||||
// The to point.
|
type: "fillet",
|
||||||
to: [number, number],
|
|
||||||
type: "TangentialArcTo",
|
|
||||||
} |
|
|
||||||
{
|
|
||||||
// The from point.
|
|
||||||
from: [number, number],
|
|
||||||
// The tag of the path.
|
|
||||||
tag: {
|
|
||||||
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
|
||||||
end: number,
|
|
||||||
start: number,
|
|
||||||
value: string,
|
|
||||||
},
|
},
|
||||||
// The to point.
|
|
||||||
to: [number, number],
|
|
||||||
type: "TangentialArc",
|
|
||||||
} |
|
|
||||||
{
|
|
||||||
// The from point.
|
|
||||||
from: [number, number],
|
|
||||||
// The tag of the path.
|
|
||||||
tag: {
|
|
||||||
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
|
||||||
end: number,
|
|
||||||
start: number,
|
|
||||||
value: string,
|
|
||||||
},
|
},
|
||||||
// The to point.
|
|
||||||
to: [number, number],
|
|
||||||
type: "Horizontal",
|
|
||||||
// The x coordinate.
|
|
||||||
x: number,
|
|
||||||
} |
|
|
||||||
{
|
|
||||||
// The from point.
|
|
||||||
from: [number, number],
|
|
||||||
// The tag of the path.
|
|
||||||
tag: {
|
|
||||||
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
|
||||||
end: number,
|
|
||||||
start: number,
|
|
||||||
value: string,
|
value: string,
|
||||||
},
|
|
||||||
// The to point.
|
|
||||||
to: [number, number],
|
|
||||||
type: "AngledLineTo",
|
|
||||||
// The x coordinate.
|
|
||||||
x: number,
|
|
||||||
// The y coordinate.
|
|
||||||
y: number,
|
|
||||||
} |
|
|
||||||
{
|
|
||||||
// The from point.
|
|
||||||
from: [number, number],
|
|
||||||
// The tag of the path.
|
|
||||||
tag: {
|
|
||||||
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
|
||||||
end: number,
|
|
||||||
start: number,
|
|
||||||
value: string,
|
|
||||||
},
|
|
||||||
// The to point.
|
|
||||||
to: [number, number],
|
|
||||||
type: "Base",
|
|
||||||
}],
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
92895
docs/kcl/std.json
@ -26,7 +26,7 @@ import * as TOML from '@iarna/toml'
|
|||||||
import { LineInputsType } from 'lang/std/sketchcombos'
|
import { LineInputsType } from 'lang/std/sketchcombos'
|
||||||
import { Coords2d } from 'lang/std/sketch'
|
import { Coords2d } from 'lang/std/sketch'
|
||||||
import { KCL_DEFAULT_LENGTH } from 'lib/constants'
|
import { KCL_DEFAULT_LENGTH } from 'lib/constants'
|
||||||
import { EngineCommand } from 'lang/std/engineConnection'
|
import { EngineCommand } from 'lang/std/artifactMap'
|
||||||
import { onboardingPaths } from 'routes/Onboarding/paths'
|
import { onboardingPaths } from 'routes/Onboarding/paths'
|
||||||
import { bracket } from 'lib/exampleKcl'
|
import { bracket } from 'lib/exampleKcl'
|
||||||
|
|
||||||
@ -48,8 +48,6 @@ const commonPoints = {
|
|||||||
startAt: '[7.19, -9.7]',
|
startAt: '[7.19, -9.7]',
|
||||||
num1: 7.25,
|
num1: 7.25,
|
||||||
num2: 14.44,
|
num2: 14.44,
|
||||||
// num1: 9.64,
|
|
||||||
// num2: 19.19,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
test.afterEach(async ({ context, page }, testInfo) => {
|
test.afterEach(async ({ context, page }, testInfo) => {
|
||||||
@ -141,8 +139,9 @@ async function doBasicSketch(page: Page, openPanes: string[]) {
|
|||||||
await expect(u.codeLocator)
|
await expect(u.codeLocator)
|
||||||
.toHaveText(`const sketch001 = startSketchOn('XZ')
|
.toHaveText(`const sketch001 = startSketchOn('XZ')
|
||||||
|> startProfileAt(${commonPoints.startAt}, %)`)
|
|> startProfileAt(${commonPoints.startAt}, %)`)
|
||||||
}
|
} else {
|
||||||
await page.waitForTimeout(500)
|
await page.waitForTimeout(500)
|
||||||
|
}
|
||||||
|
|
||||||
await page.mouse.click(startXPx + PUR * 20, 500 - PUR * 10)
|
await page.mouse.click(startXPx + PUR * 20, 500 - PUR * 10)
|
||||||
await page.waitForTimeout(500)
|
await page.waitForTimeout(500)
|
||||||
@ -152,8 +151,9 @@ async function doBasicSketch(page: Page, openPanes: string[]) {
|
|||||||
.toHaveText(`const sketch001 = startSketchOn('XZ')
|
.toHaveText(`const sketch001 = startSketchOn('XZ')
|
||||||
|> startProfileAt(${commonPoints.startAt}, %)
|
|> startProfileAt(${commonPoints.startAt}, %)
|
||||||
|> line([${commonPoints.num1}, 0], %)`)
|
|> line([${commonPoints.num1}, 0], %)`)
|
||||||
}
|
} else {
|
||||||
await page.waitForTimeout(500)
|
await page.waitForTimeout(500)
|
||||||
|
}
|
||||||
|
|
||||||
await page.mouse.click(startXPx + PUR * 20, 500 - PUR * 20)
|
await page.mouse.click(startXPx + PUR * 20, 500 - PUR * 20)
|
||||||
if (openPanes.includes('code')) {
|
if (openPanes.includes('code')) {
|
||||||
@ -162,8 +162,9 @@ async function doBasicSketch(page: Page, openPanes: string[]) {
|
|||||||
|> startProfileAt(${commonPoints.startAt}, %)
|
|> startProfileAt(${commonPoints.startAt}, %)
|
||||||
|> line([${commonPoints.num1}, 0], %)
|
|> line([${commonPoints.num1}, 0], %)
|
||||||
|> line([0, ${commonPoints.num1 + 0.01}], %)`)
|
|> line([0, ${commonPoints.num1 + 0.01}], %)`)
|
||||||
}
|
} else {
|
||||||
await page.waitForTimeout(500)
|
await page.waitForTimeout(500)
|
||||||
|
}
|
||||||
await page.mouse.click(startXPx, 500 - PUR * 20)
|
await page.mouse.click(startXPx, 500 - PUR * 20)
|
||||||
if (openPanes.includes('code')) {
|
if (openPanes.includes('code')) {
|
||||||
await expect(u.codeLocator)
|
await expect(u.codeLocator)
|
||||||
@ -175,7 +176,7 @@ async function doBasicSketch(page: Page, openPanes: string[]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// deselect line tool
|
// deselect line tool
|
||||||
await page.getByRole('button', { name: 'Line' }).click()
|
await page.getByRole('button', { name: 'Line', exact: true }).click()
|
||||||
await page.waitForTimeout(500)
|
await page.waitForTimeout(500)
|
||||||
|
|
||||||
const line1 = await u.getSegmentBodyCoords(`[data-overlay-index="${0}"]`, 0)
|
const line1 = await u.getSegmentBodyCoords(`[data-overlay-index="${0}"]`, 0)
|
||||||
@ -203,7 +204,7 @@ async function doBasicSketch(page: Page, openPanes: string[]) {
|
|||||||
await expect(page.locator('.cm-cursor')).toHaveCount(2)
|
await expect(page.locator('.cm-cursor')).toHaveCount(2)
|
||||||
}
|
}
|
||||||
|
|
||||||
await page.getByRole('button', { name: 'Constraints' }).click()
|
await page.getByRole('button', { name: 'Length: open menu' }).click()
|
||||||
await page.getByRole('button', { name: 'Equal Length' }).click()
|
await page.getByRole('button', { name: 'Equal Length' }).click()
|
||||||
|
|
||||||
// Open the code pane.
|
// Open the code pane.
|
||||||
@ -212,7 +213,7 @@ async function doBasicSketch(page: Page, openPanes: string[]) {
|
|||||||
|> 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', () => {
|
||||||
@ -452,7 +453,7 @@ test.describe('Testing Camera Movement', () => {
|
|||||||
// await expect(u.codeLocator).toHaveText(code)
|
// await expect(u.codeLocator).toHaveText(code)
|
||||||
|
|
||||||
// click the line button
|
// click the line button
|
||||||
await page.getByRole('button', { name: 'Line' }).click()
|
await page.getByRole('button', { name: 'Line', exact: true }).click()
|
||||||
|
|
||||||
const hoverOverNothing = async () => {
|
const hoverOverNothing = async () => {
|
||||||
// await u.canvasLocator.hover({position: {x: 700, y: 325}})
|
// await u.canvasLocator.hover({position: {x: 700, y: 325}})
|
||||||
@ -924,10 +925,10 @@ test.describe('Editor tests', () => {
|
|||||||
|
|
||||||
await expect(page.locator('.cm-lint-marker-error')).toBeVisible()
|
await expect(page.locator('.cm-lint-marker-error')).toBeVisible()
|
||||||
await expect(
|
await expect(
|
||||||
page.locator('.cm-lintRange.cm-lintRange-error').first()
|
page.locator('.cm-lint-marker.cm-lint-marker-error')
|
||||||
).toBeVisible()
|
).toBeVisible()
|
||||||
|
|
||||||
await page.locator('.cm-lintRange.cm-lintRange-error').hover()
|
await page.locator('.cm-lint-marker.cm-lint-marker-error').hover()
|
||||||
await expect(page.locator('.cm-diagnosticText').first()).toBeVisible()
|
await expect(page.locator('.cm-diagnosticText').first()).toBeVisible()
|
||||||
await expect(
|
await expect(
|
||||||
page.getByText('Cannot redefine `topAng`').first()
|
page.getByText('Cannot redefine `topAng`').first()
|
||||||
@ -1015,18 +1016,18 @@ test.describe('Editor tests', () => {
|
|||||||
|> startProfileAt([0, 0], %)
|
|> startProfileAt([0, 0], %)
|
||||||
|> line([0, 10], %)
|
|> line([0, 10], %)
|
||||||
|> line([10, 0], %)
|
|> line([10, 0], %)
|
||||||
|> line([0, -10], %, 'revolveAxis')
|
|> line([0, -10], %, $revolveAxis)
|
||||||
|> close(%)
|
|> close(%)
|
||||||
|> extrude(10, %)
|
|> extrude(10, %)
|
||||||
|
|
||||||
const sketch001 = startSketchOn(box, "revolveAxis")
|
const sketch001 = startSketchOn(box, revolveAxis)
|
||||||
|> startProfileAt([5, 10], %)
|
|> startProfileAt([5, 10], %)
|
||||||
|> line([0, -10], %)
|
|> line([0, -10], %)
|
||||||
|> line([2, 0], %)
|
|> line([2, 0], %)
|
||||||
|> line([0, -10], %)
|
|> line([0, -10], %)
|
||||||
|> close(%)
|
|> close(%)
|
||||||
|> revolve({
|
|> revolve({
|
||||||
axis: getEdge('revolveAxis', box),
|
axis: revolveAxis,
|
||||||
angle: 90
|
angle: 90
|
||||||
}, %)
|
}, %)
|
||||||
`
|
`
|
||||||
@ -1044,7 +1045,7 @@ test.describe('Editor tests', () => {
|
|||||||
await page.hover('.cm-lint-marker-error')
|
await page.hover('.cm-lint-marker-error')
|
||||||
const searchText =
|
const searchText =
|
||||||
'sketch profile must lie entirely on one side of the revolution axis'
|
'sketch profile must lie entirely on one side of the revolution axis'
|
||||||
await expect(page.getByText(searchText).first()).toBeVisible()
|
await expect(page.getByText(searchText)).toBeVisible()
|
||||||
})
|
})
|
||||||
test.describe('Autocomplete works', () => {
|
test.describe('Autocomplete works', () => {
|
||||||
test('with enter/click to accept the completion', async ({ page }) => {
|
test('with enter/click to accept the completion', async ({ page }) => {
|
||||||
@ -1063,7 +1064,7 @@ test.describe('Editor tests', () => {
|
|||||||
await page.keyboard.type('const sketch001 = start')
|
await page.keyboard.type('const sketch001 = start')
|
||||||
|
|
||||||
// expect there to be six auto complete options
|
// expect there to be six auto complete options
|
||||||
await expect(page.locator('.cm-completionLabel')).toHaveCount(6)
|
await expect(page.locator('.cm-completionLabel')).toHaveCount(8)
|
||||||
// this makes sure we can accept a completion with click
|
// this makes sure we can accept a completion with click
|
||||||
await page.getByText('startSketchOn').click()
|
await page.getByText('startSketchOn').click()
|
||||||
await page.keyboard.type("'XZ'")
|
await page.keyboard.type("'XZ'")
|
||||||
@ -1462,7 +1463,9 @@ test.describe('Can create sketches on all planes and their back sides', () => {
|
|||||||
await page.mouse.click(clickCoords.x, clickCoords.y)
|
await page.mouse.click(clickCoords.x, clickCoords.y)
|
||||||
await page.waitForTimeout(300) // wait for animation
|
await page.waitForTimeout(300) // wait for animation
|
||||||
|
|
||||||
await expect(page.getByRole('button', { name: 'Line' })).toBeVisible()
|
await expect(
|
||||||
|
page.getByRole('button', { name: 'Line', exact: true })
|
||||||
|
).toBeVisible()
|
||||||
|
|
||||||
// draw a line
|
// draw a line
|
||||||
const startXPx = 600
|
const startXPx = 600
|
||||||
@ -1472,7 +1475,7 @@ test.describe('Can create sketches on all planes and their back sides', () => {
|
|||||||
|
|
||||||
await expect(page.locator('.cm-content')).toHaveText(code)
|
await expect(page.locator('.cm-content')).toHaveText(code)
|
||||||
|
|
||||||
await page.getByRole('button', { name: 'Line' }).click()
|
await page.getByRole('button', { name: 'Line', exact: true }).click()
|
||||||
await u.openAndClearDebugPanel()
|
await u.openAndClearDebugPanel()
|
||||||
await page.getByRole('button', { name: 'Exit Sketch' }).click()
|
await page.getByRole('button', { name: 'Exit Sketch' }).click()
|
||||||
await u.expectCmdLog('[data-message-type="execution-done"]')
|
await u.expectCmdLog('[data-message-type="execution-done"]')
|
||||||
@ -1511,6 +1514,8 @@ test.describe('Can create sketches on all planes and their back sides', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
test.describe('Copilot ghost text', () => {
|
test.describe('Copilot ghost text', () => {
|
||||||
|
test.skip(true, 'Needs to get covered again')
|
||||||
|
|
||||||
test('completes code in empty file', async ({ page }) => {
|
test('completes code in empty file', async ({ page }) => {
|
||||||
const u = await getUtils(page)
|
const u = await getUtils(page)
|
||||||
// const PUR = 400 / 37.5 //pixeltoUnitRatio
|
// const PUR = 400 / 37.5 //pixeltoUnitRatio
|
||||||
@ -1549,7 +1554,9 @@ test.describe('Copilot ghost text', () => {
|
|||||||
await expect(page.locator('.cm-ghostText')).not.toBeVisible()
|
await expect(page.locator('.cm-ghostText')).not.toBeVisible()
|
||||||
})
|
})
|
||||||
|
|
||||||
test('copilot disabled in sketch mode no select plane', async ({ page }) => {
|
test.skip('copilot disabled in sketch mode no select plane', async ({
|
||||||
|
page,
|
||||||
|
}) => {
|
||||||
const u = await getUtils(page)
|
const u = await getUtils(page)
|
||||||
// const PUR = 400 / 37.5 //pixeltoUnitRatio
|
// const PUR = 400 / 37.5 //pixeltoUnitRatio
|
||||||
await page.setViewportSize({ width: 1200, height: 500 })
|
await page.setViewportSize({ width: 1200, height: 500 })
|
||||||
@ -2096,7 +2103,7 @@ test.describe('Testing settings', () => {
|
|||||||
.hover()
|
.hover()
|
||||||
await page
|
await page
|
||||||
.getByRole('button', {
|
.getByRole('button', {
|
||||||
name: 'Roll back theme ; Has tooltip: Roll back to match default',
|
name: 'Roll back theme',
|
||||||
})
|
})
|
||||||
.click()
|
.click()
|
||||||
await expect(page.locator('select[name="app-theme"]')).toHaveValue('system')
|
await expect(page.locator('select[name="app-theme"]')).toHaveValue('system')
|
||||||
@ -2148,7 +2155,7 @@ test.describe('Testing settings', () => {
|
|||||||
.hover()
|
.hover()
|
||||||
await page
|
await page
|
||||||
.getByRole('button', {
|
.getByRole('button', {
|
||||||
name: 'Roll back theme ; Has tooltip: Roll back to match default',
|
name: 'Roll back theme',
|
||||||
})
|
})
|
||||||
.click()
|
.click()
|
||||||
await expect(page.locator('select[name="app-theme"]')).toHaveValue('system')
|
await expect(page.locator('select[name="app-theme"]')).toHaveValue('system')
|
||||||
@ -2258,6 +2265,50 @@ test.describe('Onboarding tests', () => {
|
|||||||
await expect(page.locator('.cm-content')).toContainText('// Shelf Bracket')
|
await expect(page.locator('.cm-content')).toContainText('// Shelf Bracket')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('Code resets after confirmation', async ({ page }) => {
|
||||||
|
const initialCode = `const sketch001 = startSketchOn('XZ')`
|
||||||
|
|
||||||
|
// Load the page up with some code so we see the confirmation warning
|
||||||
|
// when we go to replay onboarding
|
||||||
|
await page.addInitScript((code) => {
|
||||||
|
localStorage.setItem('persistCode', code)
|
||||||
|
}, initialCode)
|
||||||
|
|
||||||
|
const u = await getUtils(page)
|
||||||
|
await page.setViewportSize({ width: 1200, height: 500 })
|
||||||
|
await u.waitForAuthSkipAppStart()
|
||||||
|
|
||||||
|
// Replay the onboarding
|
||||||
|
await page.getByRole('link', { name: 'Settings' }).last().click()
|
||||||
|
const replayButton = page.getByRole('button', { name: 'Replay onboarding' })
|
||||||
|
await expect(replayButton).toBeVisible()
|
||||||
|
await replayButton.click()
|
||||||
|
|
||||||
|
// Ensure we see the warning, and that the code has not yet updated
|
||||||
|
await expect(
|
||||||
|
page.getByText('Replaying onboarding resets your code')
|
||||||
|
).toBeVisible()
|
||||||
|
await expect(page.locator('.cm-content')).toHaveText(initialCode)
|
||||||
|
|
||||||
|
const nextButton = page.getByTestId('onboarding-next')
|
||||||
|
await expect(nextButton).toBeVisible()
|
||||||
|
await nextButton.click()
|
||||||
|
|
||||||
|
// Ensure we see the introduction and that the code has been reset
|
||||||
|
await expect(page.getByText('Welcome to Modeling App!')).toBeVisible()
|
||||||
|
await expect(page.locator('.cm-content')).toContainText('// Shelf Bracket')
|
||||||
|
|
||||||
|
// Ensure we persisted the code to local storage.
|
||||||
|
// Playwright's addInitScript method unfortunately will reset
|
||||||
|
// this code if we try reloading the page as a test,
|
||||||
|
// so this is our best way to test persistence afaik.
|
||||||
|
expect(
|
||||||
|
await page.evaluate(() => {
|
||||||
|
return localStorage.getItem('persistCode')
|
||||||
|
})
|
||||||
|
).toContain('// Shelf Bracket')
|
||||||
|
})
|
||||||
|
|
||||||
test('Click through each onboarding step', async ({ page }) => {
|
test('Click through each onboarding step', async ({ page }) => {
|
||||||
const u = await getUtils(page)
|
const u = await getUtils(page)
|
||||||
|
|
||||||
@ -2562,7 +2613,7 @@ test.describe('Testing selections', () => {
|
|||||||
|> line([-${commonPoints.num2}, 0], %)`)
|
|> line([-${commonPoints.num2}, 0], %)`)
|
||||||
|
|
||||||
// deselect line tool
|
// deselect line tool
|
||||||
await page.getByRole('button', { name: 'Line' }).click()
|
await page.getByRole('button', { name: 'Line', exact: true }).click()
|
||||||
|
|
||||||
await u.closeDebugPanel()
|
await u.closeDebugPanel()
|
||||||
const selectionSequence = async () => {
|
const selectionSequence = async () => {
|
||||||
@ -2587,8 +2638,10 @@ test.describe('Testing selections', () => {
|
|||||||
// click a segment hold shift and click an axis, see that a relevant constraint is enabled
|
// click a segment hold shift and click an axis, see that a relevant constraint is enabled
|
||||||
await topHorzSegmentClick()
|
await topHorzSegmentClick()
|
||||||
await page.keyboard.down('Shift')
|
await page.keyboard.down('Shift')
|
||||||
const constrainButton = page.getByRole('button', { name: 'Constraints' })
|
const constrainButton = page.getByRole('button', {
|
||||||
const absYButton = page.getByRole('button', { name: 'ABS Y' })
|
name: 'Length: open menu',
|
||||||
|
})
|
||||||
|
const absYButton = page.getByRole('button', { name: 'Absolute Y' })
|
||||||
await constrainButton.click()
|
await constrainButton.click()
|
||||||
await expect(absYButton).toBeDisabled()
|
await expect(absYButton).toBeDisabled()
|
||||||
await page.waitForTimeout(100)
|
await page.waitForTimeout(100)
|
||||||
@ -3160,7 +3213,7 @@ const extrude001 = extrude(10, sketch001)`
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
pos: [816, 244],
|
pos: [816, 244],
|
||||||
expectedCode: 'angledLine([segAng(seg01, %), yo], %)',
|
expectedCode: 'angledLine([segAng(seg01), yo], %)',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
pos: [1107, 161],
|
pos: [1107, 161],
|
||||||
@ -3412,21 +3465,6 @@ const extrude001 = extrude(50, sketch001)
|
|||||||
await expect(
|
await expect(
|
||||||
page.getByRole('button', { name: 'Edit Sketch' })
|
page.getByRole('button', { name: 'Edit Sketch' })
|
||||||
).not.toBeVisible()
|
).not.toBeVisible()
|
||||||
|
|
||||||
// selecting an editable sketch but clicking "start sketch" should start a new sketch and not edit the existing one
|
|
||||||
await page.getByText(selectionsSnippets.extrudeAndEditAllowed).click()
|
|
||||||
await page.getByRole('button', { name: 'Start Sketch' }).click()
|
|
||||||
await page.waitForTimeout(200)
|
|
||||||
await page.getByTestId('KCL Code').click()
|
|
||||||
await page.waitForTimeout(200)
|
|
||||||
await page.mouse.click(734, 134)
|
|
||||||
await page.waitForTimeout(100)
|
|
||||||
await page.getByTestId('KCL Code').click()
|
|
||||||
// expect main content to contain `sketch005` i.e. started a new sketch
|
|
||||||
await page.waitForTimeout(300)
|
|
||||||
await expect(page.locator('.cm-content')).toHaveText(
|
|
||||||
/sketch001 = startSketchOn\('XZ'\)/
|
|
||||||
)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
test('Deselecting line tool should mean nothing happens on click', async ({
|
test('Deselecting line tool should mean nothing happens on click', async ({
|
||||||
@ -3463,7 +3501,7 @@ const extrude001 = extrude(50, sketch001)
|
|||||||
let previousCodeContent = await page.locator('.cm-content').innerText()
|
let previousCodeContent = await page.locator('.cm-content').innerText()
|
||||||
|
|
||||||
// deselect the line tool by clicking it
|
// deselect the line tool by clicking it
|
||||||
await page.getByRole('button', { name: 'Line' }).click()
|
await page.getByRole('button', { name: 'Line', exact: true }).click()
|
||||||
|
|
||||||
await page.mouse.click(700, 200)
|
await page.mouse.click(700, 200)
|
||||||
await page.waitForTimeout(100)
|
await page.waitForTimeout(100)
|
||||||
@ -3476,7 +3514,7 @@ const extrude001 = extrude(50, sketch001)
|
|||||||
await expect(page.locator('.cm-content')).toHaveText(previousCodeContent)
|
await expect(page.locator('.cm-content')).toHaveText(previousCodeContent)
|
||||||
|
|
||||||
// select line tool again
|
// select line tool again
|
||||||
await page.getByRole('button', { name: 'Line' }).click()
|
await page.getByRole('button', { name: 'Line', exact: true }).click()
|
||||||
|
|
||||||
await u.closeDebugPanel()
|
await u.closeDebugPanel()
|
||||||
|
|
||||||
@ -3809,13 +3847,24 @@ const extrude001 = extrude(distance001, sketch001)`.replace(
|
|||||||
const sketchButton = page.getByRole('button', { name: 'Start Sketch' })
|
const sketchButton = page.getByRole('button', { name: 'Start Sketch' })
|
||||||
const cmdBarButton = page.getByRole('button', { name: 'Commands' })
|
const cmdBarButton = page.getByRole('button', { name: 'Commands' })
|
||||||
const rectangleToolCommand = page.getByRole('option', {
|
const rectangleToolCommand = page.getByRole('option', {
|
||||||
name: 'Rectangle',
|
name: 'rectangle',
|
||||||
|
})
|
||||||
|
const rectangleToolButton = page.getByRole('button', {
|
||||||
|
name: 'Corner rectangle',
|
||||||
|
exact: true,
|
||||||
|
})
|
||||||
|
const lineToolCommand = page.getByRole('option', {
|
||||||
|
name: 'Line',
|
||||||
|
})
|
||||||
|
const lineToolButton = page.getByRole('button', {
|
||||||
|
name: 'Line',
|
||||||
|
exact: true,
|
||||||
})
|
})
|
||||||
const rectangleToolButton = page.getByRole('button', { name: 'Rectangle' })
|
|
||||||
const lineToolCommand = page.getByRole('option', { name: 'Line' })
|
|
||||||
const lineToolButton = page.getByRole('button', { name: 'Line' })
|
|
||||||
const arcToolCommand = page.getByRole('option', { name: 'Tangential Arc' })
|
const arcToolCommand = page.getByRole('option', { name: 'Tangential Arc' })
|
||||||
const arcToolButton = page.getByRole('button', { name: 'Tangential Arc' })
|
const arcToolButton = page.getByRole('button', {
|
||||||
|
name: 'Tangential Arc',
|
||||||
|
exact: true,
|
||||||
|
})
|
||||||
|
|
||||||
// Start a sketch
|
// Start a sketch
|
||||||
await sketchButton.click()
|
await sketchButton.click()
|
||||||
@ -3862,10 +3911,7 @@ test.describe('Regression tests', () => {
|
|||||||
await u.waitForAuthSkipAppStart()
|
await u.waitForAuthSkipAppStart()
|
||||||
|
|
||||||
// expand variables section
|
// expand variables section
|
||||||
const variablesTabButton = page.getByRole('tab', {
|
const variablesTabButton = page.getByTestId('variables-pane-button')
|
||||||
name: 'Variables',
|
|
||||||
exact: false,
|
|
||||||
})
|
|
||||||
await variablesTabButton.click()
|
await variablesTabButton.click()
|
||||||
|
|
||||||
// can find sketch001 in the variables summary (pretty-json-container, makes sure we're not looking in the code editor)
|
// can find sketch001 in the variables summary (pretty-json-container, makes sure we're not looking in the code editor)
|
||||||
@ -3890,10 +3936,7 @@ test.describe('Regression tests', () => {
|
|||||||
|
|
||||||
await u.waitForAuthSkipAppStart()
|
await u.waitForAuthSkipAppStart()
|
||||||
|
|
||||||
const variablesTabButton = page.getByRole('tab', {
|
const variablesTabButton = page.getByTestId('variables-pane-button')
|
||||||
name: 'Variables',
|
|
||||||
exact: false,
|
|
||||||
})
|
|
||||||
await variablesTabButton.click()
|
await variablesTabButton.click()
|
||||||
// expect to see "myVar:5"
|
// expect to see "myVar:5"
|
||||||
await expect(
|
await expect(
|
||||||
@ -3976,16 +4019,19 @@ test.describe('Regression tests', () => {
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
await expect(async () => {
|
||||||
await page.goto('/')
|
await page.goto('/')
|
||||||
await u.waitForPageLoad()
|
await u.waitForPageLoad()
|
||||||
|
|
||||||
// error in guter
|
// error in guter
|
||||||
await expect(page.locator('.cm-lint-marker-error')).toBeVisible()
|
await expect(page.locator('.cm-lint-marker-error')).toBeVisible({
|
||||||
|
timeout: 1_000,
|
||||||
|
})
|
||||||
await page.waitForTimeout(200)
|
await page.waitForTimeout(200)
|
||||||
// expect it still to be there (sometimes it just clears for a bit?)
|
// expect it still to be there (sometimes it just clears for a bit?)
|
||||||
await expect(page.locator('.cm-lint-marker-error')).toBeVisible({
|
await expect(page.locator('.cm-lint-marker-error')).toBeVisible({
|
||||||
timeout: 10_000,
|
timeout: 1_000,
|
||||||
})
|
})
|
||||||
|
}).toPass({ timeout: 40_000, intervals: [1_000] })
|
||||||
|
|
||||||
// error text on hover
|
// error text on hover
|
||||||
await page.hover('.cm-lint-marker-error')
|
await page.hover('.cm-lint-marker-error')
|
||||||
@ -4133,12 +4179,15 @@ test.describe('Sketch tests', () => {
|
|||||||
await page.setViewportSize({ width: 1200, height: 500 })
|
await page.setViewportSize({ width: 1200, height: 500 })
|
||||||
|
|
||||||
await u.waitForAuthSkipAppStart()
|
await u.waitForAuthSkipAppStart()
|
||||||
await page.getByText('tangentialArcTo([24.95, -5.38], %)').click()
|
|
||||||
|
|
||||||
|
await expect(async () => {
|
||||||
|
await page.mouse.click(700, 200)
|
||||||
|
await page.getByText('tangentialArcTo([24.95, -5.38], %)').click()
|
||||||
await expect(
|
await expect(
|
||||||
page.getByRole('button', { name: 'Edit Sketch' })
|
page.getByRole('button', { name: 'Edit Sketch' })
|
||||||
).toBeEnabled()
|
).toBeEnabled({ timeout: 1000 })
|
||||||
await page.getByRole('button', { name: 'Edit Sketch' }).click()
|
await page.getByRole('button', { name: 'Edit Sketch' }).click()
|
||||||
|
}).toPass({ timeout: 40_000, intervals: [1_000] })
|
||||||
|
|
||||||
await page.waitForTimeout(600) // wait for animation
|
await page.waitForTimeout(600) // wait for animation
|
||||||
|
|
||||||
@ -4154,7 +4203,7 @@ test.describe('Sketch tests', () => {
|
|||||||
await u.expectCmdLog('[data-message-type="execution-done"]', 10_000)
|
await u.expectCmdLog('[data-message-type="execution-done"]', 10_000)
|
||||||
await page.waitForTimeout(100)
|
await page.waitForTimeout(100)
|
||||||
|
|
||||||
await page.getByRole('button', { name: 'Line' }).click()
|
await page.getByRole('button', { name: 'Line', exact: true }).click()
|
||||||
await page.waitForTimeout(100)
|
await page.waitForTimeout(100)
|
||||||
|
|
||||||
await page.mouse.click(700, 200)
|
await page.mouse.click(700, 200)
|
||||||
@ -4181,9 +4230,7 @@ test.describe('Sketch tests', () => {
|
|||||||
page.getByRole('button', { name: 'Exit Sketch' })
|
page.getByRole('button', { name: 'Exit Sketch' })
|
||||||
).toBeVisible()
|
).toBeVisible()
|
||||||
|
|
||||||
await expect(
|
await expect(page.getByText('select a plane or face')).toBeVisible()
|
||||||
page.getByText('click plane or face to sketch on')
|
|
||||||
).toBeVisible()
|
|
||||||
|
|
||||||
await page.keyboard.press('Escape')
|
await page.keyboard.press('Escape')
|
||||||
await expect(
|
await expect(
|
||||||
@ -4734,7 +4781,7 @@ test.describe('Sketch tests', () => {
|
|||||||
await expect(page.locator('.cm-content')).toHaveText(code)
|
await expect(page.locator('.cm-content')).toHaveText(code)
|
||||||
// Assert the tool was unequipped
|
// Assert the tool was unequipped
|
||||||
await expect(
|
await expect(
|
||||||
page.getByRole('button', { name: 'Line' })
|
page.getByRole('button', { name: 'Line', exact: true })
|
||||||
).not.toHaveAttribute('aria-pressed', 'true')
|
).not.toHaveAttribute('aria-pressed', 'true')
|
||||||
|
|
||||||
// exit sketch
|
// exit sketch
|
||||||
@ -4896,8 +4943,7 @@ test.describe('Testing constraints', () => {
|
|||||||
await page.mouse.click(834, 244)
|
await page.mouse.click(834, 244)
|
||||||
await page.keyboard.up('Shift')
|
await page.keyboard.up('Shift')
|
||||||
|
|
||||||
await page.getByRole('button', { name: 'Constraints', exact: true }).click()
|
await page.getByRole('button', { name: 'Length', exact: true }).click()
|
||||||
await page.getByRole('button', { name: 'length', exact: true }).click()
|
|
||||||
await page.getByText('Add constraining value').click()
|
await page.getByText('Add constraining value').click()
|
||||||
|
|
||||||
await expect(page.locator('.cm-content')).toHaveText(
|
await expect(page.locator('.cm-content')).toHaveText(
|
||||||
@ -4927,13 +4973,13 @@ 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(%)], %)`
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
@ -4951,12 +4997,10 @@ const part002 = startSketchOn('XZ')
|
|||||||
await page.waitForTimeout(100) // this wait is needed for webkit - not sure why
|
await page.waitForTimeout(100) // this wait is needed for webkit - not sure why
|
||||||
await page
|
await page
|
||||||
.getByRole('button', {
|
.getByRole('button', {
|
||||||
name: 'Constraints',
|
name: 'Length: open menu',
|
||||||
})
|
})
|
||||||
.click()
|
.click()
|
||||||
await page
|
await page.getByRole('button', { name: 'remove constraints' }).click()
|
||||||
.getByRole('button', { name: 'remove constraints', exact: true })
|
|
||||||
.click()
|
|
||||||
|
|
||||||
await page.getByText('line([39.13, 68.63], %)').click()
|
await page.getByText('line([39.13, 68.63], %)').click()
|
||||||
const activeLinesContent = await page.locator('.cm-activeLine').all()
|
const activeLinesContent = await page.locator('.cm-activeLine').all()
|
||||||
@ -4987,13 +5031,13 @@ 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(%)], %)`
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
@ -5017,11 +5061,11 @@ const part002 = startSketchOn('XZ')
|
|||||||
await page.keyboard.up('Shift')
|
await page.keyboard.up('Shift')
|
||||||
await page
|
await page
|
||||||
.getByRole('button', {
|
.getByRole('button', {
|
||||||
name: 'Constraints',
|
name: 'Length: open menu',
|
||||||
})
|
})
|
||||||
.click()
|
.click()
|
||||||
await page
|
await page
|
||||||
.getByRole('button', { name: 'perpendicular distance', exact: true })
|
.getByRole('button', { name: 'Perpendicular Distance' })
|
||||||
.click()
|
.click()
|
||||||
|
|
||||||
const createNewVariableCheckbox = page.getByTestId(
|
const createNewVariableCheckbox = page.getByTestId(
|
||||||
@ -5058,22 +5102,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) {
|
||||||
@ -5092,7 +5136,7 @@ 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(%)], %)`
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
@ -5116,12 +5160,10 @@ const part002 = startSketchOn('XZ')
|
|||||||
await page.keyboard.up('Shift')
|
await page.keyboard.up('Shift')
|
||||||
await page
|
await page
|
||||||
.getByRole('button', {
|
.getByRole('button', {
|
||||||
name: 'Constraints',
|
name: 'Length: open menu',
|
||||||
})
|
})
|
||||||
.click()
|
.click()
|
||||||
await page
|
await page.getByRole('button', { name: constraint }).click()
|
||||||
.getByRole('button', { name: constraint, exact: true })
|
|
||||||
.click()
|
|
||||||
|
|
||||||
const createNewVariableCheckbox = page.getByTestId(
|
const createNewVariableCheckbox = page.getByTestId(
|
||||||
'create-new-variable-checkbox'
|
'create-new-variable-checkbox'
|
||||||
@ -5162,25 +5204,25 @@ const part002 = startSketchOn('XZ')
|
|||||||
{
|
{
|
||||||
testName: 'Add variable',
|
testName: 'Add variable',
|
||||||
addVariable: true,
|
addVariable: true,
|
||||||
constraint: 'ABS X',
|
constraint: 'Absolute X',
|
||||||
value: 'xDis001, 61.34',
|
value: 'xDis001, 61.34',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
testName: 'No variable',
|
testName: 'No variable',
|
||||||
addVariable: false,
|
addVariable: false,
|
||||||
constraint: 'ABS X',
|
constraint: 'Absolute X',
|
||||||
value: '154.9, 61.34',
|
value: '154.9, 61.34',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
testName: 'Add variable',
|
testName: 'Add variable',
|
||||||
addVariable: true,
|
addVariable: true,
|
||||||
constraint: 'ABS Y',
|
constraint: 'Absolute Y',
|
||||||
value: '154.9, yDis001',
|
value: '154.9, yDis001',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
testName: 'No variable',
|
testName: 'No variable',
|
||||||
addVariable: false,
|
addVariable: false,
|
||||||
constraint: 'ABS Y',
|
constraint: 'Absolute Y',
|
||||||
value: '154.9, 61.34',
|
value: '154.9, 61.34',
|
||||||
},
|
},
|
||||||
] as const
|
] as const
|
||||||
@ -5200,7 +5242,7 @@ 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(%)], %)`
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
@ -5216,7 +5258,7 @@ const part002 = startSketchOn('XZ')
|
|||||||
u.getSegmentBodyCoords(`[data-overlay-index="${2}"]`),
|
u.getSegmentBodyCoords(`[data-overlay-index="${2}"]`),
|
||||||
])
|
])
|
||||||
|
|
||||||
if (constraint === 'ABS X') {
|
if (constraint === 'Absolute X') {
|
||||||
await page.mouse.click(600, 130)
|
await page.mouse.click(600, 130)
|
||||||
} else {
|
} else {
|
||||||
await page.mouse.click(900, 250)
|
await page.mouse.click(900, 250)
|
||||||
@ -5227,7 +5269,7 @@ const part002 = startSketchOn('XZ')
|
|||||||
await page.keyboard.up('Shift')
|
await page.keyboard.up('Shift')
|
||||||
await page
|
await page
|
||||||
.getByRole('button', {
|
.getByRole('button', {
|
||||||
name: 'Constraints',
|
name: 'Length: open menu',
|
||||||
})
|
})
|
||||||
.click()
|
.click()
|
||||||
await page
|
await page
|
||||||
@ -5270,13 +5312,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',
|
||||||
@ -5307,7 +5349,7 @@ 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(%)], %)`
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
@ -5335,10 +5377,10 @@ const part002 = startSketchOn('XZ')
|
|||||||
await page.keyboard.up('Shift')
|
await page.keyboard.up('Shift')
|
||||||
await page
|
await page
|
||||||
.getByRole('button', {
|
.getByRole('button', {
|
||||||
name: 'Constraints',
|
name: 'Length: open menu',
|
||||||
})
|
})
|
||||||
.click()
|
.click()
|
||||||
await page.getByTestId('angle').click()
|
await page.getByTestId('dropdown-constraint-angle').click()
|
||||||
|
|
||||||
const createNewVariableCheckbox = page.getByTestId(
|
const createNewVariableCheckbox = page.getByTestId(
|
||||||
'create-new-variable-checkbox'
|
'create-new-variable-checkbox'
|
||||||
@ -5417,7 +5459,7 @@ 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(%)], %)`
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
@ -5436,10 +5478,10 @@ const part002 = startSketchOn('XZ')
|
|||||||
await page.mouse.click(line3.x, line3.y)
|
await page.mouse.click(line3.x, line3.y)
|
||||||
await page
|
await page
|
||||||
.getByRole('button', {
|
.getByRole('button', {
|
||||||
name: 'Constraints',
|
name: 'Length: open menu',
|
||||||
})
|
})
|
||||||
.click()
|
.click()
|
||||||
await page.getByTestId(constraint).click()
|
await page.getByTestId('dropdown-constraint-' + constraint).click()
|
||||||
|
|
||||||
if (!addVariable) {
|
if (!addVariable) {
|
||||||
await page.getByTestId('create-new-variable-checkbox').click()
|
await page.getByTestId('create-new-variable-checkbox').click()
|
||||||
@ -5493,7 +5535,7 @@ 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(%)], %)`
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
@ -5527,7 +5569,7 @@ const part002 = startSketchOn('XZ')
|
|||||||
await expect(activeLinesContent).toHaveLength(codeAfter.length)
|
await expect(activeLinesContent).toHaveLength(codeAfter.length)
|
||||||
|
|
||||||
const constraintMenuButton = page.getByRole('button', {
|
const constraintMenuButton = page.getByRole('button', {
|
||||||
name: 'Constraints',
|
name: 'Length: open menu',
|
||||||
})
|
})
|
||||||
const constraintButton = page
|
const constraintButton = page
|
||||||
.getByRole('button', {
|
.getByRole('button', {
|
||||||
@ -5558,19 +5600,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
|
||||||
@ -5589,7 +5631,7 @@ 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(%)], %)`
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
@ -5610,7 +5652,7 @@ const part002 = startSketchOn('XZ')
|
|||||||
await page.mouse.click(line3.x - 3, line3.y + 20)
|
await page.mouse.click(line3.x - 3, line3.y + 20)
|
||||||
await page.keyboard.up('Shift')
|
await page.keyboard.up('Shift')
|
||||||
const constraintMenuButton = page.getByRole('button', {
|
const constraintMenuButton = page.getByRole('button', {
|
||||||
name: 'Constraints',
|
name: 'Length: open menu',
|
||||||
})
|
})
|
||||||
const constraintButton = page.getByRole('button', {
|
const constraintButton = page.getByRole('button', {
|
||||||
name: constraintName,
|
name: constraintName,
|
||||||
@ -5666,7 +5708,7 @@ 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(%)], %)`
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
@ -5687,7 +5729,7 @@ const part002 = startSketchOn('XZ')
|
|||||||
await page.mouse.click(axisClick.x, axisClick.y)
|
await page.mouse.click(axisClick.x, axisClick.y)
|
||||||
await page.keyboard.up('Shift')
|
await page.keyboard.up('Shift')
|
||||||
const constraintMenuButton = page.getByRole('button', {
|
const constraintMenuButton = page.getByRole('button', {
|
||||||
name: 'Constraints',
|
name: 'Length: open menu',
|
||||||
})
|
})
|
||||||
const constraintButton = page.getByRole('button', {
|
const constraintButton = page.getByRole('button', {
|
||||||
name: constraintName,
|
name: constraintName,
|
||||||
@ -5746,10 +5788,10 @@ const part002 = startSketchOn('XZ')
|
|||||||
|
|
||||||
await page
|
await page
|
||||||
.getByRole('button', {
|
.getByRole('button', {
|
||||||
name: 'Constraints',
|
name: 'Length: open menu',
|
||||||
})
|
})
|
||||||
.click()
|
.click()
|
||||||
await page.getByRole('button', { name: 'horizontal', exact: true }).click()
|
await page.getByRole('button', { name: 'Horizontal', exact: true }).click()
|
||||||
|
|
||||||
let activeLinesContent = await page.locator('.cm-activeLine').all()
|
let activeLinesContent = await page.locator('.cm-activeLine').all()
|
||||||
await expect(activeLinesContent[0]).toHaveText(`|> xLine(3.13, %)`)
|
await expect(activeLinesContent[0]).toHaveText(`|> xLine(3.13, %)`)
|
||||||
@ -5770,13 +5812,13 @@ const part002 = startSketchOn('XZ')
|
|||||||
await page.waitForTimeout(300)
|
await page.waitForTimeout(300)
|
||||||
await page
|
await page
|
||||||
.getByRole('button', {
|
.getByRole('button', {
|
||||||
name: 'Constraints',
|
name: 'Length: open menu',
|
||||||
})
|
})
|
||||||
.click()
|
.click()
|
||||||
// await expect(page.getByRole('button', { name: 'length', exact: true })).toBeVisible()
|
// await expect(page.getByRole('button', { name: 'length', exact: true })).toBeVisible()
|
||||||
await page.waitForTimeout(200)
|
await page.waitForTimeout(200)
|
||||||
// await page.getByRole('button', { name: 'length', exact: true }).click()
|
// await page.getByRole('button', { name: 'length', exact: true }).click()
|
||||||
await page.locator('[data-testid="length"]').click()
|
await page.getByTestId('dropdown-constraint-length').click()
|
||||||
|
|
||||||
await page.getByLabel('length Value').fill('10')
|
await page.getByLabel('length Value').fill('10')
|
||||||
await page.getByRole('button', { name: 'Add constraining value' }).click()
|
await page.getByRole('button', { name: 'Add constraining value' }).click()
|
||||||
@ -6834,8 +6876,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)' : ''}`
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -6994,7 +7036,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)], %)`
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -7068,6 +7110,8 @@ test.describe('Test network and connection issues', () => {
|
|||||||
|
|
||||||
await u.waitForAuthSkipAppStart()
|
await u.waitForAuthSkipAppStart()
|
||||||
|
|
||||||
|
const networkToggle = page.getByTestId('network-toggle')
|
||||||
|
|
||||||
// This is how we wait until the stream is online
|
// This is how we wait until the stream is online
|
||||||
await expect(
|
await expect(
|
||||||
page.getByRole('button', { name: 'Start Sketch' })
|
page.getByRole('button', { name: 'Start Sketch' })
|
||||||
@ -7081,7 +7125,7 @@ test.describe('Test network and connection issues', () => {
|
|||||||
await expect(networkPopover).not.toBeVisible()
|
await expect(networkPopover).not.toBeVisible()
|
||||||
|
|
||||||
// (First check) Expect the network to be up
|
// (First check) Expect the network to be up
|
||||||
await expect(page.getByText('Network Health (Connected)')).toBeVisible()
|
await expect(networkToggle).toContainText('Connected')
|
||||||
|
|
||||||
// Click the network widget
|
// Click the network widget
|
||||||
await networkWidget.click()
|
await networkWidget.click()
|
||||||
@ -7103,7 +7147,7 @@ test.describe('Test network and connection issues', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// Expect the network to be down
|
// Expect the network to be down
|
||||||
await expect(page.getByText('Network Health (Offline)')).toBeVisible()
|
await expect(networkToggle).toContainText('Offline')
|
||||||
|
|
||||||
// Click the network widget
|
// Click the network widget
|
||||||
await networkWidget.click()
|
await networkWidget.click()
|
||||||
@ -7129,7 +7173,7 @@ test.describe('Test network and connection issues', () => {
|
|||||||
).not.toBeDisabled({ timeout: 15000 })
|
).not.toBeDisabled({ timeout: 15000 })
|
||||||
|
|
||||||
// (Second check) expect the network to be up
|
// (Second check) expect the network to be up
|
||||||
await expect(page.getByText('Network Health (Connected)')).toBeVisible()
|
await expect(networkToggle).toContainText('Connected')
|
||||||
})
|
})
|
||||||
|
|
||||||
test('Engine disconnect & reconnect in sketch mode', async ({
|
test('Engine disconnect & reconnect in sketch mode', async ({
|
||||||
@ -7141,6 +7185,8 @@ test.describe('Test network and connection issues', () => {
|
|||||||
browserName === 'webkit',
|
browserName === 'webkit',
|
||||||
'Skip on Safari until `window.tearDown` is working there'
|
'Skip on Safari until `window.tearDown` is working there'
|
||||||
)
|
)
|
||||||
|
const networkToggle = page.getByTestId('network-toggle')
|
||||||
|
|
||||||
const u = await getUtils(page)
|
const u = await getUtils(page)
|
||||||
await page.setViewportSize({ width: 1200, height: 500 })
|
await page.setViewportSize({ width: 1200, height: 500 })
|
||||||
const PUR = 400 / 37.5 //pixeltoUnitRatio
|
const PUR = 400 / 37.5 //pixeltoUnitRatio
|
||||||
@ -7183,7 +7229,7 @@ test.describe('Test network and connection issues', () => {
|
|||||||
|> line([${commonPoints.num1}, 0], %)`)
|
|> line([${commonPoints.num1}, 0], %)`)
|
||||||
|
|
||||||
// Expect the network to be up
|
// Expect the network to be up
|
||||||
await expect(page.getByText('Network Health (Connected)')).toBeVisible()
|
await expect(networkToggle).toContainText('Connected')
|
||||||
|
|
||||||
// simulate network down
|
// simulate network down
|
||||||
await u.emulateNetworkConditions({
|
await u.emulateNetworkConditions({
|
||||||
@ -7195,7 +7241,7 @@ test.describe('Test network and connection issues', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// Expect the network to be down
|
// Expect the network to be down
|
||||||
await expect(page.getByText('Network Health (Offline)')).toBeVisible()
|
await expect(networkToggle).toContainText('Offline')
|
||||||
|
|
||||||
// Ensure we are not in sketch mode
|
// Ensure we are not in sketch mode
|
||||||
await expect(
|
await expect(
|
||||||
@ -7220,7 +7266,8 @@ test.describe('Test network and connection issues', () => {
|
|||||||
).not.toBeDisabled({ timeout: 15000 })
|
).not.toBeDisabled({ timeout: 15000 })
|
||||||
|
|
||||||
// Expect the network to be up
|
// Expect the network to be up
|
||||||
await expect(page.getByText('Network Health (Connected)')).toBeVisible()
|
await expect(networkToggle).toContainText('Connected')
|
||||||
|
await expect(page.getByTestId('loading-stream')).not.toBeAttached()
|
||||||
|
|
||||||
// Click off the code pane.
|
// Click off the code pane.
|
||||||
await page.mouse.click(100, 100)
|
await page.mouse.click(100, 100)
|
||||||
@ -7236,7 +7283,7 @@ test.describe('Test network and connection issues', () => {
|
|||||||
await page.waitForTimeout(150)
|
await page.waitForTimeout(150)
|
||||||
|
|
||||||
// Click the line tool
|
// Click the line tool
|
||||||
await page.getByRole('button', { name: 'Line' }).click()
|
await page.getByRole('button', { name: 'Line', exact: true }).click()
|
||||||
|
|
||||||
await page.waitForTimeout(150)
|
await page.waitForTimeout(150)
|
||||||
|
|
||||||
@ -7246,15 +7293,15 @@ test.describe('Test network and connection issues', () => {
|
|||||||
.toHaveText(`const sketch001 = startSketchOn('XZ')
|
.toHaveText(`const sketch001 = startSketchOn('XZ')
|
||||||
|> startProfileAt(${commonPoints.startAt}, %)
|
|> startProfileAt(${commonPoints.startAt}, %)
|
||||||
|> line([${commonPoints.num1}, 0], %)
|
|> line([${commonPoints.num1}, 0], %)
|
||||||
|> line([-9.16, 8.81], %)`)
|
|> line([-8.84, 8.75], %)`)
|
||||||
await page.waitForTimeout(100)
|
await page.waitForTimeout(100)
|
||||||
await page.mouse.click(startXPx, 500 - PUR * 20)
|
await page.mouse.click(startXPx, 500 - PUR * 20)
|
||||||
await expect(page.locator('.cm-content'))
|
await expect(page.locator('.cm-content'))
|
||||||
.toHaveText(`const sketch001 = startSketchOn('XZ')
|
.toHaveText(`const sketch001 = startSketchOn('XZ')
|
||||||
|> startProfileAt(${commonPoints.startAt}, %)
|
|> startProfileAt(${commonPoints.startAt}, %)
|
||||||
|> line([${commonPoints.num1}, 0], %)
|
|> line([${commonPoints.num1}, 0], %)
|
||||||
|> line([-9.16, 8.81], %)
|
|> line([-8.84, 8.75], %)
|
||||||
|> line([-5.28, 0], %)`)
|
|> line([-5.6, 0], %)`)
|
||||||
|
|
||||||
// Unequip line tool
|
// Unequip line tool
|
||||||
await page.keyboard.press('Escape')
|
await page.keyboard.press('Escape')
|
||||||
@ -7263,7 +7310,7 @@ test.describe('Test network and connection issues', () => {
|
|||||||
page.getByRole('button', { name: 'Exit Sketch' })
|
page.getByRole('button', { name: 'Exit Sketch' })
|
||||||
).toBeVisible()
|
).toBeVisible()
|
||||||
await expect(
|
await expect(
|
||||||
page.getByRole('button', { name: 'Line' })
|
page.getByRole('button', { name: 'Line', exact: true })
|
||||||
).not.toHaveAttribute('aria-pressed', 'true')
|
).not.toHaveAttribute('aria-pressed', 'true')
|
||||||
|
|
||||||
// Exit sketch
|
// Exit sketch
|
||||||
@ -7564,19 +7611,19 @@ const part001 = startSketchOn('-XZ')
|
|||||||
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, %)`
|
||||||
@ -7668,7 +7715,7 @@ test('Keyboard shortcuts can be viewed through the help menu', async ({
|
|||||||
.waitFor({ state: 'visible' })
|
.waitFor({ state: 'visible' })
|
||||||
|
|
||||||
// Open the help menu
|
// Open the help menu
|
||||||
await page.getByRole('button', { name: 'Help', exact: false }).click()
|
await page.getByRole('button', { name: 'Help and resources' }).click()
|
||||||
|
|
||||||
// Open the keyboard shortcuts
|
// Open the keyboard shortcuts
|
||||||
await page.getByRole('button', { name: 'Keyboard Shortcuts' }).click()
|
await page.getByRole('button', { name: 'Keyboard Shortcuts' }).click()
|
||||||
@ -7692,8 +7739,11 @@ test('First escape in tool pops you out of tool, second exits sketch mode', asyn
|
|||||||
await u.expectCmdLog('[data-message-type="execution-done"]')
|
await u.expectCmdLog('[data-message-type="execution-done"]')
|
||||||
await u.closeDebugPanel()
|
await u.closeDebugPanel()
|
||||||
|
|
||||||
const lineButton = page.getByRole('button', { name: 'Line' })
|
const lineButton = page.getByRole('button', { name: 'Line', exact: true })
|
||||||
const arcButton = page.getByRole('button', { name: 'Tangential Arc' })
|
const arcButton = page.getByRole('button', {
|
||||||
|
name: 'Tangential Arc',
|
||||||
|
exact: true,
|
||||||
|
})
|
||||||
|
|
||||||
// Test these hotkeys perform actions when
|
// Test these hotkeys perform actions when
|
||||||
// focus is on the canvas
|
// focus is on the canvas
|
||||||
@ -7705,6 +7755,7 @@ test('First escape in tool pops you out of tool, second exits sketch mode', asyn
|
|||||||
await page.mouse.move(800, 300)
|
await page.mouse.move(800, 300)
|
||||||
await page.mouse.click(800, 300)
|
await page.mouse.click(800, 300)
|
||||||
await page.waitForTimeout(1000)
|
await page.waitForTimeout(1000)
|
||||||
|
await expect(lineButton).toBeVisible()
|
||||||
await expect(lineButton).toHaveAttribute('aria-pressed', 'true')
|
await expect(lineButton).toHaveAttribute('aria-pressed', 'true')
|
||||||
|
|
||||||
// Draw a line
|
// Draw a line
|
||||||
@ -7774,9 +7825,12 @@ test('Basic default modeling and sketch hotkeys work', async ({ page }) => {
|
|||||||
await u.closeDebugPanel()
|
await u.closeDebugPanel()
|
||||||
|
|
||||||
const codePane = page.getByRole('textbox').locator('div')
|
const codePane = page.getByRole('textbox').locator('div')
|
||||||
const codePaneButton = page.getByRole('tab', { name: 'KCL Code' })
|
const codePaneButton = page.getByTestId('code-pane-button')
|
||||||
const lineButton = page.getByRole('button', { name: 'Line' })
|
const lineButton = page.getByRole('button', { name: 'Line', exact: true })
|
||||||
const arcButton = page.getByRole('button', { name: 'Tangential Arc' })
|
const arcButton = page.getByRole('button', {
|
||||||
|
name: 'Tangential Arc',
|
||||||
|
exact: true,
|
||||||
|
})
|
||||||
const extrudeButton = page.getByRole('button', { name: 'Extrude' })
|
const extrudeButton = page.getByRole('button', { name: 'Extrude' })
|
||||||
|
|
||||||
// Test that the hotkeys do nothing when
|
// Test that the hotkeys do nothing when
|
||||||
@ -7797,7 +7851,7 @@ test('Basic default modeling and sketch hotkeys work', async ({ page }) => {
|
|||||||
await page.mouse.click(600, 250)
|
await page.mouse.click(600, 250)
|
||||||
|
|
||||||
// work-around: to stop "keyboard.press('s')" from typing in the editor even when it should be blurred
|
// work-around: to stop "keyboard.press('s')" from typing in the editor even when it should be blurred
|
||||||
await page.getByRole('button', { name: 'Commands ⌘K' }).click()
|
await page.getByRole('button', { name: 'Commands' }).click()
|
||||||
await page.waitForTimeout(100)
|
await page.waitForTimeout(100)
|
||||||
await page.keyboard.press('Escape')
|
await page.keyboard.press('Escape')
|
||||||
await page.waitForTimeout(100)
|
await page.waitForTimeout(100)
|
||||||
@ -8043,3 +8097,34 @@ test('Sketch on face', async ({ page }) => {
|
|||||||
const sketch002 = extrude(${[5, 5]} + 7, sketch002)`
|
const sketch002 = extrude(${[5, 5]} + 7, sketch002)`
|
||||||
await expect(page.locator('.cm-content')).toHaveText(result2.regExp)
|
await expect(page.locator('.cm-content')).toHaveText(result2.regExp)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('Typing KCL errors induces a badge on the error logs pane button', async ({
|
||||||
|
page,
|
||||||
|
}) => {
|
||||||
|
const u = await getUtils(page)
|
||||||
|
|
||||||
|
// Load the app with the working starter code
|
||||||
|
await page.addInitScript((code) => {
|
||||||
|
localStorage.setItem('persistCode', code)
|
||||||
|
}, bracket)
|
||||||
|
|
||||||
|
await page.setViewportSize({ width: 1200, height: 500 })
|
||||||
|
await u.waitForAuthSkipAppStart()
|
||||||
|
|
||||||
|
// wait for execution done
|
||||||
|
await u.openDebugPanel()
|
||||||
|
await u.expectCmdLog('[data-message-type="execution-done"]')
|
||||||
|
await u.closeDebugPanel()
|
||||||
|
|
||||||
|
// Ensure no badge is present
|
||||||
|
const errorLogsButton = page.getByRole('button', { name: 'KCL Errors pane' })
|
||||||
|
await expect(errorLogsButton).not.toContainText('notification')
|
||||||
|
|
||||||
|
// Delete a character to break the KCL
|
||||||
|
await u.openKclCodePanel()
|
||||||
|
await page.getByText('extrude(').click()
|
||||||
|
await page.keyboard.press('Backspace')
|
||||||
|
|
||||||
|
// Ensure that a badge appears on the button
|
||||||
|
await expect(errorLogsButton).toContainText('notification')
|
||||||
|
})
|
||||||
|
@ -64,27 +64,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, %)`
|
||||||
@ -431,7 +431,9 @@ test('Draft segments should look right', async ({ page, context }) => {
|
|||||||
|> line([7.25, 0], %)`
|
|> line([7.25, 0], %)`
|
||||||
await expect(page.locator('.cm-content')).toHaveText(code)
|
await expect(page.locator('.cm-content')).toHaveText(code)
|
||||||
|
|
||||||
await page.getByRole('button', { name: 'Tangential Arc' }).click()
|
await page
|
||||||
|
.getByRole('button', { name: 'Tangential Arc', exact: true })
|
||||||
|
.click()
|
||||||
|
|
||||||
await page.mouse.move(startXPx + PUR * 30, 500 - PUR * 20, { steps: 10 })
|
await page.mouse.move(startXPx + PUR * 30, 500 - PUR * 20, { steps: 10 })
|
||||||
|
|
||||||
@ -475,8 +477,10 @@ test('Draft rectangles should look right', async ({ page, context }) => {
|
|||||||
const startXPx = 600
|
const startXPx = 600
|
||||||
|
|
||||||
// Equip the rectangle tool
|
// Equip the rectangle tool
|
||||||
await page.getByRole('button', { name: 'Line' }).click()
|
await page.getByRole('button', { name: 'Line', exact: true }).click()
|
||||||
await page.getByRole('button', { name: 'Rectangle' }).click()
|
await page
|
||||||
|
.getByRole('button', { name: 'Corner rectangle', exact: true })
|
||||||
|
.click()
|
||||||
|
|
||||||
// Draw the rectangle
|
// Draw the rectangle
|
||||||
await page.mouse.click(startXPx + PUR * 20, 500 - PUR * 30)
|
await page.mouse.click(startXPx + PUR * 20, 500 - PUR * 30)
|
||||||
@ -535,7 +539,9 @@ test.describe('Client side scene scale should match engine scale', () => {
|
|||||||
|> line([7.25, 0], %)`
|
|> line([7.25, 0], %)`
|
||||||
await expect(u.codeLocator).toHaveText(code)
|
await expect(u.codeLocator).toHaveText(code)
|
||||||
|
|
||||||
await page.getByRole('button', { name: 'Tangential Arc' }).click()
|
await page
|
||||||
|
.getByRole('button', { name: 'Tangential Arc', exact: true })
|
||||||
|
.click()
|
||||||
await page.waitForTimeout(100)
|
await page.waitForTimeout(100)
|
||||||
|
|
||||||
await page.mouse.click(startXPx + PUR * 30, 500 - PUR * 20)
|
await page.mouse.click(startXPx + PUR * 30, 500 - PUR * 20)
|
||||||
@ -545,7 +551,9 @@ test.describe('Client side scene scale should match engine scale', () => {
|
|||||||
await expect(u.codeLocator).toHaveText(code)
|
await expect(u.codeLocator).toHaveText(code)
|
||||||
|
|
||||||
// click tangential arc tool again to unequip it
|
// click tangential arc tool again to unequip it
|
||||||
await page.getByRole('button', { name: 'Tangential Arc' }).click()
|
await page
|
||||||
|
.getByRole('button', { name: 'Tangential Arc', exact: true })
|
||||||
|
.click()
|
||||||
await page.waitForTimeout(100)
|
await page.waitForTimeout(100)
|
||||||
|
|
||||||
// screen shot should show the sketch
|
// screen shot should show the sketch
|
||||||
@ -634,7 +642,9 @@ test.describe('Client side scene scale should match engine scale', () => {
|
|||||||
|> line([184.3, 0], %)`
|
|> line([184.3, 0], %)`
|
||||||
await expect(u.codeLocator).toHaveText(code)
|
await expect(u.codeLocator).toHaveText(code)
|
||||||
|
|
||||||
await page.getByRole('button', { name: 'Tangential Arc' }).click()
|
await page
|
||||||
|
.getByRole('button', { name: 'Tangential Arc', exact: true })
|
||||||
|
.click()
|
||||||
await page.waitForTimeout(100)
|
await page.waitForTimeout(100)
|
||||||
|
|
||||||
await page.mouse.click(startXPx + PUR * 30, 500 - PUR * 20)
|
await page.mouse.click(startXPx + PUR * 30, 500 - PUR * 20)
|
||||||
@ -643,7 +653,9 @@ test.describe('Client side scene scale should match engine scale', () => {
|
|||||||
|> tangentialArcTo([551.2, -62.01], %)`
|
|> tangentialArcTo([551.2, -62.01], %)`
|
||||||
await expect(u.codeLocator).toHaveText(code)
|
await expect(u.codeLocator).toHaveText(code)
|
||||||
|
|
||||||
await page.getByRole('button', { name: 'Tangential Arc' }).click()
|
await page
|
||||||
|
.getByRole('button', { name: 'Tangential Arc', exact: true })
|
||||||
|
.click()
|
||||||
await page.waitForTimeout(100)
|
await page.waitForTimeout(100)
|
||||||
|
|
||||||
// screen shot should show the sketch
|
// screen shot should show the sketch
|
||||||
|
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 48 KiB |
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 47 KiB |
Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 54 KiB |
Before Width: | Height: | Size: 45 KiB After Width: | Height: | Size: 48 KiB |
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 39 KiB |
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 36 KiB |
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 39 KiB |
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 34 KiB |
Before Width: | Height: | Size: 71 KiB After Width: | Height: | Size: 72 KiB |
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 46 KiB |
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 62 KiB |
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 32 KiB |
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 35 KiB |
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 34 KiB |
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 34 KiB |
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 37 KiB |
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 31 KiB |
@ -71,7 +71,7 @@ export const TEST_CODE_GIZMO = `const part001 = startSketchOn('XZ')
|
|||||||
|> 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 }, %)
|
||||||
@ -79,7 +79,7 @@ export const TEST_CODE_GIZMO = `const part001 = startSketchOn('XZ')
|
|||||||
|> 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], %)
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { test, expect, Page, Download } from '@playwright/test'
|
import { expect, Page, Download } from '@playwright/test'
|
||||||
import { EngineCommand } from '../../src/lang/std/engineConnection'
|
import { EngineCommand } from 'lang/std/artifactMap'
|
||||||
import os from 'os'
|
import os from 'os'
|
||||||
import fsp from 'fs/promises'
|
import fsp from 'fs/promises'
|
||||||
import pixelMatch from 'pixelmatch'
|
import pixelMatch from 'pixelmatch'
|
||||||
@ -16,14 +16,14 @@ export const TEST_COLORS = {
|
|||||||
} as const
|
} as const
|
||||||
|
|
||||||
async function waitForPageLoad(page: Page) {
|
async function waitForPageLoad(page: Page) {
|
||||||
// wait for 'Loading stream...' spinner
|
|
||||||
await page.getByTestId('loading-stream').waitFor()
|
|
||||||
// wait for all spinners to be gone
|
// wait for all spinners to be gone
|
||||||
await page
|
await expect(page.getByTestId('loading')).not.toBeAttached({
|
||||||
.getByTestId('loading')
|
timeout: 20_000,
|
||||||
.waitFor({ state: 'detached', timeout: 20_000 })
|
})
|
||||||
|
|
||||||
await page.getByTestId('start-sketch').waitFor()
|
await expect(page.getByRole('button', { name: 'Start Sketch' })).toBeEnabled({
|
||||||
|
timeout: 20_000,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async function removeCurrentCode(page: Page) {
|
async function removeCurrentCode(page: Page) {
|
||||||
@ -58,44 +58,45 @@ async function waitForDefaultPlanesToBeVisible(page: Page) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function openKclCodePanel(page: Page) {
|
async function openKclCodePanel(page: Page) {
|
||||||
const paneLocator = page.getByRole('tab', { name: 'KCL Code', exact: false })
|
const paneLocator = page.getByTestId('code-pane-button')
|
||||||
const isOpen = (await paneLocator?.getAttribute('aria-selected')) === 'true'
|
const ariaSelected = await paneLocator?.getAttribute('aria-pressed')
|
||||||
|
const isOpen = ariaSelected === 'true'
|
||||||
|
|
||||||
if (!isOpen) {
|
if (!isOpen) {
|
||||||
await paneLocator.click()
|
await paneLocator.click()
|
||||||
await paneLocator.and(page.locator('[aria-selected="true"]')).waitFor()
|
await expect(paneLocator).toHaveAttribute('aria-pressed', 'true')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function closeKclCodePanel(page: Page) {
|
async function closeKclCodePanel(page: Page) {
|
||||||
const paneLocator = page.getByRole('tab', { name: 'KCL Code', exact: false })
|
const paneLocator = page.getByTestId('code-pane-button')
|
||||||
const isOpen = (await paneLocator?.getAttribute('aria-selected')) === 'true'
|
const ariaSelected = await paneLocator?.getAttribute('aria-pressed')
|
||||||
|
const isOpen = ariaSelected === 'true'
|
||||||
|
|
||||||
if (isOpen) {
|
if (isOpen) {
|
||||||
await paneLocator.click()
|
await paneLocator.click()
|
||||||
await paneLocator
|
await expect(paneLocator).not.toHaveAttribute('aria-pressed', 'true')
|
||||||
.and(page.locator(':not([aria-selected="true"])'))
|
|
||||||
.waitFor()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function openDebugPanel(page: Page) {
|
async function openDebugPanel(page: Page) {
|
||||||
const debugLocator = page.getByRole('tab', { name: 'Debug', exact: false })
|
const debugLocator = page.getByTestId('debug-pane-button')
|
||||||
const isOpen = (await debugLocator?.getAttribute('aria-selected')) === 'true'
|
await expect(debugLocator).toBeVisible()
|
||||||
|
const isOpen = (await debugLocator?.getAttribute('aria-pressed')) === 'true'
|
||||||
|
|
||||||
if (!isOpen) {
|
if (!isOpen) {
|
||||||
await debugLocator.click()
|
await debugLocator.click()
|
||||||
await debugLocator.and(page.locator('[aria-selected="true"]')).waitFor()
|
await expect(debugLocator).toHaveAttribute('aria-pressed', 'true')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function closeDebugPanel(page: Page) {
|
async function closeDebugPanel(page: Page) {
|
||||||
const debugLocator = page.getByRole('tab', { name: 'Debug', exact: false })
|
const debugLocator = page.getByTestId('debug-pane-button')
|
||||||
const isOpen = (await debugLocator?.getAttribute('aria-selected')) === 'true'
|
await expect(debugLocator).toBeVisible()
|
||||||
|
const isOpen = (await debugLocator?.getAttribute('aria-pressed')) === 'true'
|
||||||
if (isOpen) {
|
if (isOpen) {
|
||||||
await debugLocator.click()
|
await debugLocator.click()
|
||||||
await debugLocator
|
await expect(debugLocator).not.toHaveAttribute('aria-pressed', 'true')
|
||||||
.and(page.locator(':not([aria-selected="true"])'))
|
|
||||||
.waitFor()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -265,7 +266,7 @@ export async function getUtils(page: Page) {
|
|||||||
getSegmentBodyCoords: async (locator: string, px = 30) => {
|
getSegmentBodyCoords: async (locator: string, px = 30) => {
|
||||||
const overlay = page.locator(locator)
|
const overlay = page.locator(locator)
|
||||||
const bbox = await overlay
|
const bbox = await overlay
|
||||||
.boundingBox()
|
.boundingBox({ timeout: 5000 })
|
||||||
.then((box) => ({ ...box, x: box?.x || 0, y: box?.y || 0 }))
|
.then((box) => ({ ...box, x: box?.x || 0, y: box?.y || 0 }))
|
||||||
const angle = Number(await overlay.getAttribute('data-overlay-angle'))
|
const angle = Number(await overlay.getAttribute('data-overlay-angle'))
|
||||||
const angleXOffset = Math.cos(((angle - 180) * Math.PI) / 180) * px
|
const angleXOffset = Math.cos(((angle - 180) * Math.PI) / 180) * px
|
||||||
@ -471,8 +472,11 @@ export const doExport = async (
|
|||||||
page: Page
|
page: Page
|
||||||
): Promise<Paths> => {
|
): Promise<Paths> => {
|
||||||
await page.getByRole('button', { name: APP_NAME }).click()
|
await page.getByRole('button', { name: APP_NAME }).click()
|
||||||
await expect(page.getByRole('button', { name: 'Export Part' })).toBeVisible()
|
const exportMenuButton = page.getByRole('button', {
|
||||||
await page.getByRole('button', { name: 'Export Part' }).click()
|
name: 'Export current part',
|
||||||
|
})
|
||||||
|
await expect(exportMenuButton).toBeVisible()
|
||||||
|
await exportMenuButton.click()
|
||||||
await expect(page.getByTestId('command-bar')).toBeVisible()
|
await expect(page.getByTestId('command-bar')).toBeVisible()
|
||||||
|
|
||||||
// Go through export via command bar
|
// Go through export via command bar
|
||||||
|
@ -77,7 +77,7 @@ describe('ZMA authorized user flows', () => {
|
|||||||
const menuButton = await $('[data-testid="user-sidebar-toggle"]')
|
const menuButton = await $('[data-testid="user-sidebar-toggle"]')
|
||||||
await click(menuButton)
|
await click(menuButton)
|
||||||
|
|
||||||
const settingsButton = await $('[data-testid="settings-button"]')
|
const settingsButton = await $('[data-testid="user-settings"]')
|
||||||
await click(settingsButton)
|
await click(settingsButton)
|
||||||
|
|
||||||
const projectDirInput = await $('[data-testid="project-directory-input"]')
|
const projectDirInput = await $('[data-testid="project-directory-input"]')
|
||||||
|
340
openapi/machine-api.json
Normal file
@ -0,0 +1,340 @@
|
|||||||
|
{
|
||||||
|
"components": {
|
||||||
|
"responses": {
|
||||||
|
"Error": {
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/Error"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"description": "Error"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"schemas": {
|
||||||
|
"Error": {
|
||||||
|
"description": "Error information from a response.",
|
||||||
|
"properties": {
|
||||||
|
"error_code": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"message": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"request_id": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"message",
|
||||||
|
"request_id"
|
||||||
|
],
|
||||||
|
"type": "object"
|
||||||
|
},
|
||||||
|
"Machine": {
|
||||||
|
"description": "Details for a 3d printer connected over USB.",
|
||||||
|
"oneOf": [
|
||||||
|
{
|
||||||
|
"description": "Details for a 3d printer connected over USB.",
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"manufacturer": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"model": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"port": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"enum": [
|
||||||
|
"UsbPrinter"
|
||||||
|
],
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"id",
|
||||||
|
"manufacturer",
|
||||||
|
"model",
|
||||||
|
"port",
|
||||||
|
"type"
|
||||||
|
],
|
||||||
|
"type": "object"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Details for a 3d printer connected over USB.",
|
||||||
|
"properties": {
|
||||||
|
"hostname": {
|
||||||
|
"description": "The hostname of the printer.",
|
||||||
|
"nullable": true,
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"ip": {
|
||||||
|
"description": "The IP address of the printer.",
|
||||||
|
"format": "ip",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"manufacturer": {
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/components/schemas/NetworkPrinterManufacturer"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "The manufacturer of the printer."
|
||||||
|
},
|
||||||
|
"model": {
|
||||||
|
"description": "The model of the printer.",
|
||||||
|
"nullable": true,
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"port": {
|
||||||
|
"description": "The port of the printer.",
|
||||||
|
"format": "uint16",
|
||||||
|
"minimum": 0,
|
||||||
|
"nullable": true,
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"serial": {
|
||||||
|
"description": "The serial number of the printer.",
|
||||||
|
"nullable": true,
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"enum": [
|
||||||
|
"NetworkPrinter"
|
||||||
|
],
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"ip",
|
||||||
|
"manufacturer",
|
||||||
|
"type"
|
||||||
|
],
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"NetworkPrinterManufacturer": {
|
||||||
|
"description": "Network printer manufacturer.",
|
||||||
|
"oneOf": [
|
||||||
|
{
|
||||||
|
"description": "Bambu.",
|
||||||
|
"enum": [
|
||||||
|
"Bambu"
|
||||||
|
],
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Formlabs.",
|
||||||
|
"enum": [
|
||||||
|
"Formlabs"
|
||||||
|
],
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"Pong": {
|
||||||
|
"description": "The response from the `/ping` endpoint.",
|
||||||
|
"properties": {
|
||||||
|
"message": {
|
||||||
|
"description": "The pong response.",
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"message"
|
||||||
|
],
|
||||||
|
"type": "object"
|
||||||
|
},
|
||||||
|
"PrintJobResponse": {
|
||||||
|
"description": "The response from the `/print` endpoint.",
|
||||||
|
"properties": {
|
||||||
|
"job_id": {
|
||||||
|
"description": "The job id used for this print.",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"parameters": {
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/components/schemas/PrintParameters"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "The parameters used for this print."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"job_id",
|
||||||
|
"parameters"
|
||||||
|
],
|
||||||
|
"type": "object"
|
||||||
|
},
|
||||||
|
"PrintParameters": {
|
||||||
|
"description": "Parameters for printing.",
|
||||||
|
"properties": {
|
||||||
|
"machine_id": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"machine_id"
|
||||||
|
],
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"info": {
|
||||||
|
"contact": {
|
||||||
|
"email": "machine-api@zoo.dev",
|
||||||
|
"url": "https://zoo.dev"
|
||||||
|
},
|
||||||
|
"description": "",
|
||||||
|
"title": "machine-api",
|
||||||
|
"version": "0.1.0"
|
||||||
|
},
|
||||||
|
"openapi": "3.0.3",
|
||||||
|
"paths": {
|
||||||
|
"/": {
|
||||||
|
"get": {
|
||||||
|
"operationId": "api_get_schema",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"description": "successful operation"
|
||||||
|
},
|
||||||
|
"4XX": {
|
||||||
|
"$ref": "#/components/responses/Error"
|
||||||
|
},
|
||||||
|
"5XX": {
|
||||||
|
"$ref": "#/components/responses/Error"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"summary": "Return the OpenAPI schema in JSON format.",
|
||||||
|
"tags": [
|
||||||
|
"meta"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/machines": {
|
||||||
|
"get": {
|
||||||
|
"operationId": "get_machines",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"additionalProperties": {
|
||||||
|
"$ref": "#/components/schemas/Machine"
|
||||||
|
},
|
||||||
|
"title": "Map_of_Machine",
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"description": "successful operation"
|
||||||
|
},
|
||||||
|
"4XX": {
|
||||||
|
"$ref": "#/components/responses/Error"
|
||||||
|
},
|
||||||
|
"5XX": {
|
||||||
|
"$ref": "#/components/responses/Error"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"summary": "List available machines and their statuses",
|
||||||
|
"tags": [
|
||||||
|
"print"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/ping": {
|
||||||
|
"get": {
|
||||||
|
"operationId": "ping",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/Pong"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"description": "successful operation"
|
||||||
|
},
|
||||||
|
"4XX": {
|
||||||
|
"$ref": "#/components/responses/Error"
|
||||||
|
},
|
||||||
|
"5XX": {
|
||||||
|
"$ref": "#/components/responses/Error"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"summary": "Return pong.",
|
||||||
|
"tags": [
|
||||||
|
"meta"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/print": {
|
||||||
|
"post": {
|
||||||
|
"operationId": "print_file",
|
||||||
|
"requestBody": {
|
||||||
|
"content": {
|
||||||
|
"multipart/form-data": {
|
||||||
|
"schema": {
|
||||||
|
"format": "binary",
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/PrintJobResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"description": "successful operation"
|
||||||
|
},
|
||||||
|
"4XX": {
|
||||||
|
"$ref": "#/components/responses/Error"
|
||||||
|
},
|
||||||
|
"5XX": {
|
||||||
|
"$ref": "#/components/responses/Error"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"summary": "Print a given file. File must be a sliceable 3D model.",
|
||||||
|
"tags": [
|
||||||
|
"print"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"tags": [
|
||||||
|
{
|
||||||
|
"description": "Meta information about the API.",
|
||||||
|
"externalDocs": {
|
||||||
|
"url": "https://docs.zoo.dev/api/meta"
|
||||||
|
},
|
||||||
|
"name": "meta"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Utilities for printing and discovering printers.",
|
||||||
|
"externalDocs": {
|
||||||
|
"url": "https://docs.zoo.dev/api/print"
|
||||||
|
},
|
||||||
|
"name": "print"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|