Compare commits

...

7 Commits

Author SHA1 Message Date
0d7049d90f skip network tests mac 2024-07-08 21:28:07 +10:00
8ebe78c664 Lf94/eco mode save the planet (#2940)
* Trigger shutdown operations after each test

* Idle mode states

* Don't show the reconnect when coming back from tab
2024-07-07 10:10:52 -07:00
a85c1a9375 Scoped tags (#2941)
* start of scoped tags

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

* add the tags to the sketch group context

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

* scoped tags

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

* update docs

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

* fix tests

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

* updates

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

* updates

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

* scoped

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

* updates

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

* fix;

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

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
2024-07-05 16:53:13 -07:00
5701616f3e Add a current default unit indicator with menu to switch (#2937)
* Add a units indicator with a menu to switch default units

* Add a playwright test, add a SR label

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

* Re-run CI

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

* Re-run CI

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-07-05 18:40:43 -04:00
846acaba2f fix bug with order of operations (#2938)
* fix bug with order of operations

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

* fix

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

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
2024-07-05 15:37:30 -07:00
0a524d42f6 Bump kittycad.rs (#2936)
* update kittycad.rs

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

* tauri bump

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

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
2024-07-05 12:39:58 -07:00
fe28527ef9 update docs (#2933)
Signed-off-by: Jess Frazelle <github@jessfraz.com>
2024-07-05 10:44:29 -07:00
103 changed files with 6704 additions and 143 deletions

View File

@ -121,6 +121,9 @@ const extrusion = extrude(5, sketch001)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{
@ -282,6 +285,9 @@ const extrusion = extrude(5, sketch001)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{

View File

@ -125,6 +125,9 @@ const extrusion = extrude(5, sketch001)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{
@ -286,6 +289,9 @@ const extrusion = extrude(5, sketch001)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{

View File

@ -126,6 +126,9 @@ const example = extrude(10, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{
@ -287,6 +290,9 @@ const example = extrude(10, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{
@ -476,6 +482,9 @@ const example = extrude(10, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{
@ -637,6 +646,9 @@ const example = extrude(10, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{

View File

@ -125,6 +125,9 @@ const extrusion = extrude(10, sketch001)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{
@ -286,6 +289,9 @@ const extrusion = extrude(10, sketch001)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{
@ -475,6 +481,9 @@ const extrusion = extrude(10, sketch001)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{
@ -636,6 +645,9 @@ const extrusion = extrude(10, sketch001)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{

File diff suppressed because one or more lines are too long

View File

@ -133,6 +133,9 @@ const example = extrude(10, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{
@ -294,6 +297,9 @@ const example = extrude(10, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{
@ -483,6 +489,9 @@ const example = extrude(10, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{
@ -644,6 +653,9 @@ const example = extrude(10, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{

View File

@ -124,6 +124,9 @@ const example = extrude(10, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{
@ -285,6 +288,9 @@ const example = extrude(10, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{
@ -474,6 +480,9 @@ const example = extrude(10, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{
@ -635,6 +644,9 @@ const example = extrude(10, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{

View File

@ -124,6 +124,9 @@ const example = extrude(10, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{
@ -285,6 +288,9 @@ const example = extrude(10, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{
@ -474,6 +480,9 @@ const example = extrude(10, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{
@ -635,6 +644,9 @@ const example = extrude(10, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{

View File

@ -135,6 +135,9 @@ const exampleSketch = startSketchOn('XZ')
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{
@ -296,6 +299,9 @@ const exampleSketch = startSketchOn('XZ')
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{
@ -485,6 +491,9 @@ const exampleSketch = startSketchOn('XZ')
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{
@ -646,6 +655,9 @@ const exampleSketch = startSketchOn('XZ')
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{

View File

@ -130,6 +130,9 @@ const example = extrude(10, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{
@ -291,6 +294,9 @@ const example = extrude(10, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{
@ -480,6 +486,9 @@ const example = extrude(10, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{
@ -641,6 +650,9 @@ const example = extrude(10, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{

View File

@ -225,6 +225,9 @@ const mountingPlate = extrude(thickness, mountingPlateSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{
@ -532,6 +535,9 @@ const mountingPlate = extrude(thickness, mountingPlateSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{

View File

@ -123,6 +123,9 @@ const example = extrude(5, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{
@ -410,6 +413,9 @@ const example = extrude(5, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{
@ -599,6 +605,9 @@ const example = extrude(5, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{
@ -760,6 +769,9 @@ const example = extrude(5, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{

View File

@ -125,6 +125,9 @@ const example = extrude(10, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{
@ -286,6 +289,9 @@ const example = extrude(10, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{
@ -475,6 +481,9 @@ const example = extrude(10, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{
@ -636,6 +645,9 @@ const example = extrude(10, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{

View File

@ -150,6 +150,9 @@ const example = extrude(10, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{
@ -311,6 +314,9 @@ const example = extrude(10, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
type: "sketchGroup",
// The paths in the sketch group.
@ -580,6 +586,9 @@ const example = extrude(10, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{

View File

@ -225,6 +225,9 @@ const mountingPlate = extrude(thickness, mountingPlateSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{
@ -524,6 +527,9 @@ const mountingPlate = extrude(thickness, mountingPlateSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{

View File

@ -215,6 +215,9 @@ const revolution = startSketchOn(box, "revolveAxis")
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{

View File

@ -211,6 +211,9 @@ const example = extrude(5, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{

View File

@ -211,6 +211,9 @@ const example = extrude(5, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{

View File

@ -213,6 +213,9 @@ const example = extrude(5, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{

View File

@ -213,6 +213,9 @@ const part001 = startSketchOn('XY')
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{
@ -512,6 +515,9 @@ const part001 = startSketchOn('XY')
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{

View File

@ -136,6 +136,9 @@ const example = extrude(1, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{
@ -297,6 +300,9 @@ const example = extrude(1, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
type: "sketchGroup",
// The paths in the sketch group.
@ -479,6 +485,9 @@ const example = extrude(1, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{
@ -640,6 +649,9 @@ const example = extrude(1, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{
@ -821,6 +833,9 @@ const example = extrude(1, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{
@ -982,6 +997,9 @@ const example = extrude(1, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{

View File

@ -116,6 +116,9 @@ const example = extrude(5, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{
@ -277,6 +280,9 @@ const example = extrude(5, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{

View File

@ -116,6 +116,9 @@ const example = extrude(5, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{
@ -277,6 +280,9 @@ const example = extrude(5, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{

View File

@ -129,6 +129,9 @@ const example = extrude(5, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{
@ -290,6 +293,9 @@ const example = extrude(5, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{
@ -479,6 +485,9 @@ const example = extrude(5, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{
@ -640,6 +649,9 @@ const example = extrude(5, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{

View File

@ -116,6 +116,9 @@ const example = extrude(5, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{
@ -277,6 +280,9 @@ const example = extrude(5, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{
@ -466,6 +472,9 @@ const example = extrude(5, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{
@ -627,6 +636,9 @@ const example = extrude(5, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{

View File

@ -134,6 +134,9 @@ const example = extrude(1, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{
@ -295,6 +298,9 @@ const example = extrude(1, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
type: "sketchGroup",
// The paths in the sketch group.

View File

@ -217,6 +217,9 @@ const example = extrude(-5, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{

View File

@ -127,6 +127,9 @@ const example = extrude(1, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{
@ -288,6 +291,9 @@ const example = extrude(1, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
type: "sketchGroup",
// The paths in the sketch group.

View File

@ -215,6 +215,9 @@ const example = extrude(1, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{

View File

@ -217,6 +217,9 @@ let vase = layer()
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{

View File

@ -117,6 +117,9 @@ const sketch001 = startSketchOn('XY')
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{
@ -278,6 +281,9 @@ const sketch001 = startSketchOn('XY')
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{

View File

@ -112,6 +112,9 @@ const sketch001 = startSketchOn('XY')
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{
@ -273,6 +276,9 @@ const sketch001 = startSketchOn('XY')
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{

View File

@ -111,6 +111,9 @@ const sketch001 = startSketchOn('XY')
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{
@ -272,6 +275,9 @@ const sketch001 = startSketchOn('XY')
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{

View File

@ -247,6 +247,9 @@ uuid |
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{
@ -408,6 +411,9 @@ uuid |
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{
@ -673,6 +679,9 @@ uuid |
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{

View File

@ -124,6 +124,9 @@ const example = extrude(4, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{
@ -285,6 +288,9 @@ const example = extrude(4, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{

View File

@ -122,6 +122,9 @@ const example = extrude(5, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{
@ -283,6 +286,9 @@ const example = extrude(5, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{

View File

@ -123,6 +123,9 @@ const example = extrude(5, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{
@ -284,6 +287,9 @@ const example = extrude(5, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{

View File

@ -121,6 +121,9 @@ const example = extrude(5, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{
@ -282,6 +285,9 @@ const example = extrude(5, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{

View File

@ -213,6 +213,9 @@ shell({ faces: ['end'], thickness: 0.25 }, firstSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{
@ -512,6 +515,9 @@ shell({ faces: ['end'], thickness: 0.25 }, firstSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{

View File

@ -195,6 +195,9 @@ const example = extrude(5, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{
@ -442,6 +445,9 @@ const example = extrude(5, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{
@ -603,6 +609,9 @@ const example = extrude(5, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{

View File

@ -142,6 +142,9 @@ const example = extrude(5, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{
@ -303,6 +306,9 @@ const example = extrude(5, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{

View File

@ -264,6 +264,9 @@ const a1 = startSketchOn({
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{
@ -539,6 +542,9 @@ const a1 = startSketchOn({
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{

File diff suppressed because it is too large Load Diff

View File

@ -125,6 +125,9 @@ const example = extrude(10, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{
@ -286,6 +289,9 @@ const example = extrude(10, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{
@ -475,6 +481,9 @@ const example = extrude(10, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{
@ -636,6 +645,9 @@ const example = extrude(10, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{

View File

@ -116,6 +116,9 @@ const example = extrude(10, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{
@ -277,6 +280,9 @@ const example = extrude(10, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{
@ -466,6 +472,9 @@ const example = extrude(10, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{
@ -627,6 +636,9 @@ const example = extrude(10, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{

View File

@ -74,6 +74,107 @@ You can nest expressions in parenthesis as well:
let myMathExpression = 3 + (1 * 2 / (3 - 7))
```
Please if you find any issues using any of the above expressions or syntax
## Tags
Tags are used to give a name (tag) to a specific path.
### Tag Declaration
The syntax for declaring a tag is `$myTag` you would use it in the following
way:
```
startSketchOn('XZ')
|> startProfileAt(origin, %)
|> angledLine([0, 191.26], %, $rectangleSegmentA001)
|> angledLine([
segAng(rectangleSegmentA001, %) - 90,
196.99
], %, $rectangleSegmentB001)
|> angledLine([
segAng(rectangleSegmentA001, %),
-segLen(rectangleSegmentA001, %)
], %, $rectangleSegmentC001)
|> lineTo([profileStartX(%), profileStartY(%)], %)
|> close(%)
```
### Tag Identifier
As per the example above you can use the tag identifier to get a reference to the
tagged object. The syntax for this is `myTag`.
In the example above we use the tag identifier to get the angle of the segment
`segAng(rectangleSegmentA001, %)`.
### Tag Scope
Tags are scoped globally if in the root context meaning in this example you can
use the tag `rectangleSegmentA001` in any function or expression in the file.
However if the code was written like this:
```
fn rect = (origin) => {
return startSketchOn('XZ')
|> startProfileAt(origin, %)
|> angledLine([0, 191.26], %, $rectangleSegmentA001)
|> angledLine([
segAng(rectangleSegmentA001, %) - 90,
196.99
], %, $rectangleSegmentB001)
|> angledLine([
segAng(rectangleSegmentA001, %),
-segLen(rectangleSegmentA001, %)
], %, $rectangleSegmentC001)
|> lineTo([profileStartX(%), profileStartY(%)], %)
|> close(%)
}
rect([0, 0])
rect([20, 0])
```
Those tags would only be available in the `rect` function and not globally.
However you likely want to use those tags somewhere outside the `rect` function.
Tags are accessible through the sketch group they are declared in.
For example the following code works.
```
fn rect = (origin) => {
return startSketchOn('XZ')
|> startProfileAt(origin, %)
|> angledLine([0, 191.26], %, $rectangleSegmentA001)
|> angledLine([
segAng(rectangleSegmentA001, %) - 90,
196.99
], %, $rectangleSegmentB001)
|> angledLine([
segAng(rectangleSegmentA001, %),
-segLen(rectangleSegmentA001, %)
], %, $rectangleSegmentC001)
|> lineTo([profileStartX(%), profileStartY(%)], %)
|> close(%)
}
rect([0, 0])
const myRect = rect([20, 0])
myRect
|> extrude(10, %)
|> fillet({radius: 0.5, tags: [myRect.tags.rectangleSegmentA001]}, %)
```
See how we use the tag `rectangleSegmentA001` in the `fillet` function outside
the `rect` function. This is because the `rect` function is returning the
sketch group that contains the tags.
---
If you find any issues using any of the above expressions or syntax,
please file an issue with the `ast` label on the [modeling-app
repo](https://github.com/KittyCAD/modeling-app/issues/new).

View File

@ -119,6 +119,9 @@ const example = extrude(10, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{
@ -280,6 +283,9 @@ const example = extrude(10, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{
@ -469,6 +475,9 @@ const example = extrude(10, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{
@ -630,6 +639,9 @@ const example = extrude(10, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{

View File

@ -119,6 +119,9 @@ const example = extrude(10, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{
@ -280,6 +283,9 @@ const example = extrude(10, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{
@ -469,6 +475,9 @@ const example = extrude(10, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{
@ -630,6 +639,9 @@ const example = extrude(10, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{

View File

@ -117,6 +117,9 @@ const example = extrude(10, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{
@ -278,6 +281,9 @@ const example = extrude(10, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{
@ -467,6 +473,9 @@ const example = extrude(10, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{
@ -628,6 +637,9 @@ const example = extrude(10, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{

View File

@ -115,6 +115,9 @@ const example = extrude(5, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{
@ -276,6 +279,9 @@ const example = extrude(5, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{
@ -465,6 +471,9 @@ const example = extrude(5, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{
@ -626,6 +635,9 @@ const example = extrude(5, exampleSketch)
},
// The to point.
to: [number, number],
},
// Tag identifiers that have been declared in this sketch group.
tags: {
},
// The paths in the sketch group.
value: [{

View File

@ -52,7 +52,24 @@ const commonPoints = {
// num2: 19.19,
}
// Utilities for writing tests that depend on test values
test.afterEach(async ({ context, page }, testInfo) => {
if (testInfo.status === 'skipped') return
if (testInfo.status === 'failed') return
const u = await getUtils(page)
// Kill the network so shutdown happens properly
await u.emulateNetworkConditions({
offline: true,
// values of 0 remove any active throttling. crbug.com/456324#c9
latency: 0,
downloadThroughput: -1,
uploadThroughput: -1,
})
// It seems it's best to give the browser about 3s to close things
// It's not super reliable but we have no real other choice for now
await page.waitForTimeout(3000)
})
test.beforeEach(async ({ context, page }) => {
// wait for Vite preview server to be up
@ -78,7 +95,7 @@ test.beforeEach(async ({ context, page }) => {
await page.emulateMedia({ reducedMotion: 'reduce' })
})
test.setTimeout(60000)
test.setTimeout(120000)
async function doBasicSketch(page: Page, openPanes: string[]) {
const u = await getUtils(page)
@ -6705,6 +6722,11 @@ ${extraLine ? 'const myVar = segLen(seg01, part001)' : ''}`
test.describe('Test network and connection issues', () => {
test('simulate network down and network little widget', async ({ page }) => {
const browserType = page.context().browser()?.browserType().name()
test.skip(
browserType !== 'chromium',
'emulateNetworkConditions only works in chromium'
)
const u = await getUtils(page)
await page.setViewportSize({ width: 1200, height: 500 })
@ -6775,6 +6797,11 @@ test.describe('Test network and connection issues', () => {
})
test('Engine disconnect & reconnect in sketch mode', async ({ page }) => {
const browserType = page.context().browser()?.browserType().name()
test.skip(
browserType !== 'chromium',
'emulateNetworkConditions only works in chromium'
)
const u = await getUtils(page)
await page.setViewportSize({ width: 1200, height: 500 })
const PUR = 400 / 37.5 //pixeltoUnitRatio
@ -7134,6 +7161,40 @@ test.describe('Testing Gizmo', () => {
})
})
test('Units menu', async ({ page }) => {
const u = await getUtils(page)
await page.setViewportSize({ width: 1200, height: 500 })
await page.goto('/')
await page.waitForURL('**/file/**', { waitUntil: 'domcontentloaded' })
await u.waitForAuthSkipAppStart()
const unitsMenuButton = page.getByRole('button', {
name: 'Current Units',
exact: false,
})
await expect(unitsMenuButton).toBeVisible()
await expect(unitsMenuButton).toContainText('in')
await unitsMenuButton.click()
const millimetersButton = page.getByRole('button', { name: 'Millimeters' })
await expect(millimetersButton).toBeVisible()
await millimetersButton.click()
// Look out for the toast message
const toastMessage = page.getByText(
`Set default unit to "mm" for this project`
)
await expect(toastMessage).toBeVisible()
// Verify that the popover has closed
await expect(millimetersButton).not.toBeAttached()
// Verify that the button label has updated
await expect(unitsMenuButton).toContainText('mm')
})
test('Successful export shows a success toast', async ({ page }) => {
// FYI this test doesn't work with only engine running locally
// And you will need to have the KittyCAD CLI installed

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 70 KiB

After

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 29 KiB

View File

@ -312,9 +312,9 @@ export async function getUtils(page: Page) {
fullPage: true,
})
const screenshot = await PNG.sync.read(buffer)
// most likely related to pixel density but the screenshots for webkit are 2x the size
// there might be a more robust way of doing this.
const pixMultiplier = browserType === 'webkit' ? 2 : 1
const pixMultiplier: number = await page.evaluate(
'window.devicePixelRatio'
)
const index =
(screenshot.width * coords.y * pixMultiplier +
coords.x * pixMultiplier) *
@ -377,11 +377,13 @@ export async function getUtils(page: Page) {
emulateNetworkConditions: async (
networkOptions: Protocol.Network.emulateNetworkConditionsParameters
) => {
// Skip on non-Chromium browsers, since we need to use the CDP.
test.skip(
cdpSession === null,
'Network emulation is only supported in Chromium'
)
if (browserType !== 'chromium') {
console.warn('emulateNetworkConditions will not work on this browser')
}
if (cdpSession === null) {
// Use a fail safe if we can't simulate disconnect (on Safari)
return page.evaluate('window.tearDown()')
}
cdpSession?.send('Network.emulateNetworkConditions', networkOptions)
},

6
src-tauri/Cargo.lock generated
View File

@ -2571,7 +2571,7 @@ dependencies = [
[[package]]
name = "kcl-lib"
version = "0.1.69"
version = "0.1.70"
dependencies = [
"anyhow",
"approx",
@ -2628,9 +2628,9 @@ dependencies = [
[[package]]
name = "kittycad"
version = "0.3.6"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af3de9bb4b1441f198689a9f64a8163a518377e30b348a784680e738985b95eb"
checksum = "e1777b503442fa4666564cc3ab237d456df853a09648a4b2bb09622d25d021a5"
dependencies = [
"anyhow",
"async-trait",

View File

@ -16,7 +16,7 @@ tauri-build = { version = "2.0.0-beta.18", features = [] }
[dependencies]
anyhow = "1"
kcl-lib = { version = "0.1.53", path = "../src/wasm-lib/kcl" }
kittycad = "0.3.5"
kittycad = "0.3.7"
log = "0.4.21"
oauth2 = "4.4.2"
serde_json = "1.0"

View File

@ -25,6 +25,7 @@ import ModalContainer from 'react-modal-promise'
import useHotkeyWrapper from 'lib/hotkeyWrapper'
import Gizmo from 'components/Gizmo'
import { CoreDumpManager } from 'lib/coredump'
import { UnitsMenu } from 'components/UnitsMenu'
export function App() {
useRefreshSettings(paths.FILE + 'SETTINGS')
@ -127,6 +128,7 @@ export function App() {
<Stream />
{/* <CamToggle /> */}
<LowerRightControls coreDumpManager={coreDumpManager}>
<UnitsMenu />
<Gizmo />
</LowerRightControls>
</div>

View File

@ -119,7 +119,7 @@ export default function Gizmo() {
<div
ref={wrapperRef}
aria-label="View orientation gizmo"
className="grid place-content-center rounded-full overflow-hidden border border-solid border-primary/50 pointer-events-auto"
className="grid place-content-center rounded-full overflow-hidden border border-solid border-primary/50 pointer-events-auto bg-chalkboard-10/70 dark:bg-chalkboard-100/80 backdrop-blur-sm"
>
<canvas ref={canvasRef} />
<ContextMenu

View File

@ -53,9 +53,8 @@ import {
sketchOnExtrudedFace,
startSketchOnDefault,
} from 'lang/modifyAst'
import { Program, VariableDeclaration, parse, recast } from 'lang/wasm'
import { Program, parse, recast } from 'lang/wasm'
import {
getNodeFromPath,
getNodePathFromSourceRange,
hasExtrudableGeometry,
isSingleCursorInPipe,
@ -164,6 +163,8 @@ export const ModelingMachineProvider = ({
store.videoElement?.pause()
kclManager.executeCode(true).then(() => {
if (engineCommandManager.engineConnection?.freezeFrame) return
store.videoElement?.play()
})
})()

View File

@ -8,7 +8,7 @@ import { NetworkHealthState } from 'hooks/useNetworkStatus'
import { ClientSideScene } from 'clientSideScene/ClientSideSceneComp'
import { butName } from 'lib/cameraControls'
import { sendSelectEventToEngine } from 'lib/selections'
import { kclManager } from 'lib/singletons'
import { kclManager, engineCommandManager } from 'lib/singletons'
export const Stream = () => {
const [isLoading, setIsLoading] = useState(true)
@ -18,6 +18,7 @@ export const Stream = () => {
const { settings } = useSettingsAuthContext()
const { state, send, context } = useModelingContext()
const { overallState } = useNetworkContext()
const [isFreezeFrame, setIsFreezeFrame] = useState(false)
const isNetworkOkay =
overallState === NetworkHealthState.Ok ||
@ -49,14 +50,69 @@ export const Stream = () => {
globalThis?.window?.document?.addEventListener('paste', handlePaste, {
capture: true,
})
return () =>
// Teardown everything if we go hidden or reconnect
if (globalThis?.window?.document) {
globalThis.window.document.onvisibilitychange = () => {
if (globalThis.window.document.visibilityState === 'hidden') {
videoRef.current?.pause()
setIsFreezeFrame(true)
window.requestAnimationFrame(() => {
engineCommandManager.engineConnection?.tearDown({ freeze: true })
})
} else {
engineCommandManager.engineConnection?.connect(true)
}
}
}
const IDLE_TIME_MS = 1000 * 20
let timeoutIdIdle: ReturnType<typeof setTimeout> | undefined = undefined
const onIdle = () => {
videoRef.current?.pause()
setIsFreezeFrame(true)
kclManager.isFirstRender = true
setIsFirstRender(true)
// Give video time to pause
window.requestAnimationFrame(() => {
engineCommandManager.engineConnection?.tearDown({ freeze: true })
})
}
const onAnyInput = () => {
if (!engineCommandManager.engineConnection?.isReady()) {
engineCommandManager.engineConnection?.connect(true)
}
clearTimeout(timeoutIdIdle)
timeoutIdIdle = setTimeout(onIdle, IDLE_TIME_MS)
}
globalThis?.window?.document?.addEventListener('keydown', onAnyInput)
globalThis?.window?.document?.addEventListener('mousemove', onAnyInput)
globalThis?.window?.document?.addEventListener('mousedown', onAnyInput)
globalThis?.window?.document?.addEventListener('scroll', onAnyInput)
globalThis?.window?.document?.addEventListener('touchstart', onAnyInput)
timeoutIdIdle = setTimeout(onIdle, IDLE_TIME_MS)
return () => {
globalThis?.window?.document?.removeEventListener('paste', handlePaste, {
capture: true,
})
globalThis?.window?.document?.removeEventListener('keydown', onAnyInput)
globalThis?.window?.document?.removeEventListener('mousemove', onAnyInput)
globalThis?.window?.document?.removeEventListener('mousedown', onAnyInput)
globalThis?.window?.document?.removeEventListener('scroll', onAnyInput)
globalThis?.window?.document?.removeEventListener(
'touchstart',
onAnyInput
)
}
}, [])
useEffect(() => {
setIsFirstRender(kclManager.isFirstRender)
if (!kclManager.isFirstRender) videoRef.current?.play()
}, [kclManager.isFirstRender])
useEffect(() => {
@ -67,7 +123,10 @@ export const Stream = () => {
return
if (!videoRef.current) return
if (!context.store?.mediaStream) return
// Do not immediately play the stream!
videoRef.current.srcObject = context.store.mediaStream
videoRef.current.pause()
send({
type: 'Set context',
@ -172,17 +231,12 @@ export const Stream = () => {
<ClientSideScene
cameraControls={settings.context.modeling.mouseControls.current}
/>
{!isNetworkOkay && !isLoading && (
{(!isNetworkOkay || isLoading || isFirstRender) && !isFreezeFrame && (
<div className="text-center absolute inset-0">
<Loading>
<span data-testid="loading-stream">Stream disconnected...</span>
</Loading>
</div>
)}
{(isLoading || isFirstRender) && (
<div className="text-center absolute inset-0">
<Loading>
{!isLoading && isFirstRender ? (
{!isNetworkOkay && !isLoading ? (
<span data-testid="loading-stream">Stream disconnected...</span>
) : !isLoading && isFirstRender ? (
<span data-testid="loading-stream">Building scene...</span>
) : (
<span data-testid="loading-stream">Loading stream...</span>

View File

@ -0,0 +1,54 @@
import { Popover } from '@headlessui/react'
import { useSettingsAuthContext } from 'hooks/useSettingsAuthContext'
import { baseUnitLabels, baseUnitsUnion } from 'lib/settings/settingsTypes'
export function UnitsMenu() {
const { settings } = useSettingsAuthContext()
return (
<Popover className="relative pointer-events-auto">
{({ close }) => (
<>
<Popover.Button
className={`flex items-center gap-2 px-3 py-1
text-xs text-primary bg-chalkboard-10/70 dark:bg-chalkboard-100/80 backdrop-blur-sm
border !border-primary/50 rounded-full`}
>
<div className="w-4 h-[1px] bg-primary relative">
<div className="absolute w-[1px] h-[1em] bg-primary left-0 top-1/2 -translate-y-1/2"></div>
<div className="absolute w-[1px] h-[1em] bg-primary right-0 top-1/2 -translate-y-1/2"></div>
</div>
<span className="sr-only">Current units are:&nbsp;</span>
{settings.context.modeling.defaultUnit.current}
</Popover.Button>
<Popover.Panel
className={`absolute bottom-full right-0 mb-2 w-48 bg-chalkboard-10 dark:bg-chalkboard-90
border border-solid border-chalkboard-10 dark:border-chalkboard-90 rounded
shadow-lg`}
>
<ul className="relative flex flex-col gap-0.5 items-stretch content-stretch">
{baseUnitsUnion.map((unit) => (
<li key={unit} className="contents">
<button
className="flex items-center gap-2 py-1 px-2 cursor-pointer hover:bg-chalkboard-20 dark:hover:bg-chalkboard-80 border-none text-left"
onClick={() => {
settings.send({
type: 'set.modeling.defaultUnit',
data: {
level: 'project',
value: unit,
},
})
close()
}}
>
{baseUnitLabels[unit]}
</button>
</li>
))}
</ul>
</Popover.Panel>
</>
)}
</Popover>
)
}

View File

@ -185,6 +185,17 @@ const sk2 = startSketchOn('XY')
on: expect.any(Object),
start: expect.any(Object),
type: 'SketchGroup',
tags: {
p: {
__meta: [
{
sourceRange: [114, 116],
},
],
type: 'TagIdentifier',
value: 'p',
},
},
value: [
{
type: 'ToPoint',
@ -265,6 +276,17 @@ const sk2 = startSketchOn('XY')
on: expect.any(Object),
start: expect.any(Object),
type: 'SketchGroup',
tags: {
o: {
__meta: [
{
sourceRange: [417, 419],
},
],
type: 'TagIdentifier',
value: 'o',
},
},
value: [
{
type: 'ToPoint',

View File

@ -155,6 +155,17 @@ const newVar = myVar + 1`
sourceRange: [39, 63],
},
},
tags: {
myPath: {
__meta: [
{
sourceRange: [109, 117],
},
],
type: 'TagIdentifier',
value: 'myPath',
},
},
value: [
{
type: 'ToPoint',

View File

@ -300,6 +300,7 @@ class EngineConnection extends EventTarget {
pc?: RTCPeerConnection
unreliableDataChannel?: RTCDataChannel
mediaStream?: MediaStream
freezeFrame: boolean = false
private _state: EngineConnectionState = {
type: EngineConnectionStateType.Fresh,
@ -365,7 +366,11 @@ class EngineConnection extends EventTarget {
this.pingPongSpan = { ping: undefined, pong: undefined }
// Without an interval ping, our connection will timeout.
// If this.freezeFrame is true we skip this logic so only reconnect
// happens on mouse move
setInterval(() => {
if (this.freezeFrame) return
switch (this.state.type as EngineConnectionStateType) {
case EngineConnectionStateType.ConnectionEstablished:
// If there was no reply to the last ping, report a timeout.
@ -426,7 +431,8 @@ class EngineConnection extends EventTarget {
return this.state.type === EngineConnectionStateType.ConnectionEstablished
}
tearDown() {
tearDown(opts?: { freeze: boolean }) {
this.freezeFrame = opts?.freeze ?? false
this.disconnectAll()
this.state = {
type: EngineConnectionStateType.Disconnecting,
@ -996,6 +1002,9 @@ class EngineConnection extends EventTarget {
this.pc?.connectionState === 'closed' &&
this.unreliableDataChannel?.readyState === 'closed'
if (allClosed) {
// Do not notify the rest of the program that we have cut off anything.
if (this.freezeFrame) return
this.state = { type: EngineConnectionStateType.Disconnected }
}
}
@ -1619,7 +1628,15 @@ export class EngineCommandManager extends EventTarget {
}
}
tearDown() {
this.engineConnection?.tearDown()
if (this.engineConnection) {
this.engineConnection?.tearDown()
// Our window.tearDown assignment causes this case to happen which is
// only really for tests.
// @ts-ignore
} else if (this.engineCommandManager?.engineConnection) {
// @ts-ignore
this.engineCommandManager?.engineConnection?.tearDown()
}
}
async startNewSession() {
this.lastArtifactMap = this.artifactMap

View File

@ -16,6 +16,14 @@ export const baseUnits = {
export type BaseUnit = Models['UnitLength_type']
export const baseUnitsUnion = Object.values(baseUnits).flatMap((v) => v)
export const baseUnitLabels = {
in: 'Inches',
ft: 'Feet',
yd: 'Yards',
mm: 'Millimeters',
cm: 'Centimeters',
m: 'Meters',
} as const
export type Toggle = 'On' | 'Off'
export const toggleAsArray = ['On', 'Off'] as const

View File

@ -9,6 +9,10 @@ export const codeManager = new CodeManager()
export const engineCommandManager = new EngineCommandManager()
// Accessible for tests mostly
// @ts-ignore
window.tearDown = engineCommandManager.tearDown
// This needs to be after codeManager is created.
export const kclManager = new KclManager(engineCommandManager)
kclManager.isFirstRender = true

View File

@ -1051,7 +1051,9 @@ export const modelingMachine = createMachine(
type: 'start_path',
},
})
store.videoElement?.play()
if (!engineCommandManager.engineConnection?.freezeFrame) {
store.videoElement?.play()
}
if (updatedAst?.selections) {
editorManager.selectRange(updatedAst?.selections)
}

View File

@ -1385,7 +1385,7 @@ dependencies = [
[[package]]
name = "kcl-lib"
version = "0.1.69"
version = "0.1.71"
dependencies = [
"anyhow",
"approx",
@ -1453,7 +1453,7 @@ dependencies = [
[[package]]
name = "kcl-test-server"
version = "0.1.1"
version = "0.1.2"
dependencies = [
"anyhow",
"hyper",
@ -1466,9 +1466,9 @@ dependencies = [
[[package]]
name = "kittycad"
version = "0.3.6"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af3de9bb4b1441f198689a9f64a8163a518377e30b348a784680e738985b95eb"
checksum = "e1777b503442fa4666564cc3ab237d456df853a09648a4b2bb09622d25d021a5"
dependencies = [
"anyhow",
"async-trait",

View File

@ -69,7 +69,7 @@ members = [
]
[workspace.dependencies]
kittycad = { version = "0.3.6", default-features = false, features = ["js", "requests"] }
kittycad = { version = "0.3.7", default-features = false, features = ["js", "requests"] }
kittycad-modeling-session = "0.1.4"
[[test]]

View File

@ -1,14 +1,14 @@
[package]
name = "kcl-test-server"
description = "A test server for KCL"
version = "0.1.1"
version = "0.1.2"
edition = "2021"
license = "MIT"
[dependencies]
anyhow = "1.0.86"
hyper = { version = "0.14.29", features = ["server"] }
kcl-lib = { version = "0.1.62", path = "../kcl" }
kcl-lib = { version = "0.1.70", path = "../kcl" }
pico-args = "0.5.0"
serde = { version = "1.0.203", features = ["derive"] }
serde_json = "1.0.120"

View File

@ -1,7 +1,7 @@
[package]
name = "kcl-lib"
description = "KittyCAD Language implementation and tools"
version = "0.1.69"
version = "0.1.71"
edition = "2021"
license = "MIT"
repository = "https://github.com/KittyCAD/modeling-app"

View File

@ -1238,11 +1238,10 @@ impl CallExpression {
}
FunctionKind::UserDefined => {
let func = memory.get(&fn_name, self.into())?;
let (result, global_memory_items) =
func.call_fn(fn_args, memory.clone(), ctx.clone()).await.map_err(|e| {
// Add the call expression to the source ranges.
e.add_source_ranges(vec![self.into()])
})?;
let result = func.call_fn(fn_args, memory.clone(), ctx.clone()).await.map_err(|e| {
// Add the call expression to the source ranges.
e.add_source_ranges(vec![self.into()])
})?;
let result = result.ok_or_else(|| {
KclError::UndefinedValue(KclErrorDetails {
@ -1252,14 +1251,6 @@ impl CallExpression {
})?;
let result = result.get_value()?;
// Add the global memory items to the memory.
for (key, item) in global_memory_items {
// We don't care about errors here because any collisions
// would happened in the function call itself and already
// errored out.
memory.add(&key, item, self.into()).unwrap_or_default();
}
Ok(result)
}
}
@ -1787,6 +1778,17 @@ impl From<&TagDeclarator> for MemoryItem {
}
}
impl From<&TagDeclarator> for TagIdentifier {
fn from(tag: &TagDeclarator) -> Self {
TagIdentifier {
value: tag.name.clone(),
meta: vec![Metadata {
source_range: tag.into(),
}],
}
}
}
impl From<&TagDeclarator> for CompletionItem {
fn from(tag: &TagDeclarator) -> Self {
CompletionItem {

View File

@ -537,17 +537,14 @@ impl std::hash::Hash for TagIdentifier {
}
}
pub type MemoryFunction = fn(
s: Vec<MemoryItem>,
memory: ProgramMemory,
expression: Box<FunctionExpression>,
metadata: Vec<Metadata>,
ctx: ExecutorContext,
) -> std::pin::Pin<
Box<
dyn std::future::Future<Output = Result<(Option<ProgramReturn>, HashMap<String, MemoryItem>), KclError>> + Send,
>,
>;
pub type MemoryFunction =
fn(
s: Vec<MemoryItem>,
memory: ProgramMemory,
expression: Box<FunctionExpression>,
metadata: Vec<Metadata>,
ctx: ExecutorContext,
) -> std::pin::Pin<Box<dyn std::future::Future<Output = Result<Option<ProgramReturn>, KclError>> + Send>>;
fn force_memory_function<
F: Fn(
@ -556,12 +553,7 @@ fn force_memory_function<
Box<FunctionExpression>,
Vec<Metadata>,
ExecutorContext,
) -> std::pin::Pin<
Box<
dyn std::future::Future<Output = Result<(Option<ProgramReturn>, HashMap<String, MemoryItem>), KclError>>
+ Send,
>,
>,
) -> std::pin::Pin<Box<dyn std::future::Future<Output = Result<Option<ProgramReturn>, KclError>> + Send>>,
>(
f: F,
) -> F {
@ -691,11 +683,15 @@ impl MemoryItem {
match self {
MemoryItem::TagIdentifier(t) => Ok(*t.clone()),
MemoryItem::UserVal(u) => {
let name: String = self.get_json()?;
Ok(TagIdentifier {
value: name,
meta: u.meta.clone(),
})
if let Some(identifier) = self.get_json_opt::<TagIdentifier>()? {
Ok(identifier)
} else {
let name: String = self.get_json()?;
Ok(TagIdentifier {
value: name,
meta: u.meta.clone(),
})
}
}
_ => Err(KclError::Semantic(KclErrorDetails {
message: format!("Not a tag identifier: {:?}", self),
@ -752,7 +748,7 @@ impl MemoryItem {
args: Vec<MemoryItem>,
memory: ProgramMemory,
ctx: ExecutorContext,
) -> Result<(Option<ProgramReturn>, HashMap<String, MemoryItem>), KclError> {
) -> Result<Option<ProgramReturn>, KclError> {
let MemoryItem::Function { func, expression, meta } = &self else {
return Err(KclError::Semantic(KclErrorDetails {
message: "not a in memory function".to_string(),
@ -782,6 +778,9 @@ pub struct SketchGroup {
pub on: SketchSurface,
/// The starting path.
pub start: BasePath,
/// Tag identifiers that have been declared in this sketch group.
#[serde(default, skip_serializing_if = "HashMap::is_empty")]
pub tags: HashMap<String, TagIdentifier>,
/// Metadata.
#[serde(rename = "__meta")]
pub meta: Vec<Metadata>,
@ -1359,6 +1358,8 @@ pub struct ExecutorSettings {
pub highlight_edges: bool,
/// Whether or not Screen Space Ambient Occlusion (SSAO) is enabled.
pub enable_ssao: bool,
// Show grid?
pub show_grid: bool,
}
impl Default for ExecutorSettings {
@ -1367,6 +1368,7 @@ impl Default for ExecutorSettings {
units: Default::default(),
highlight_edges: true,
enable_ssao: false,
show_grid: false,
}
}
}
@ -1377,6 +1379,7 @@ impl From<crate::settings::types::Configuration> for ExecutorSettings {
units: config.settings.modeling.base_unit,
highlight_edges: config.settings.modeling.highlight_edges.into(),
enable_ssao: config.settings.modeling.enable_ssao.into(),
show_grid: config.settings.modeling.show_scale_grid,
}
}
}
@ -1387,6 +1390,7 @@ impl From<crate::settings::types::project::ProjectConfiguration> for ExecutorSet
units: config.settings.modeling.base_unit,
highlight_edges: config.settings.modeling.highlight_edges.into(),
enable_ssao: config.settings.modeling.enable_ssao.into(),
show_grid: config.settings.modeling.show_scale_grid,
}
}
}
@ -1397,6 +1401,7 @@ impl From<crate::settings::types::ModelingSettings> for ExecutorSettings {
units: modeling.base_unit,
highlight_edges: modeling.highlight_edges.into(),
enable_ssao: modeling.enable_ssao.into(),
show_grid: modeling.show_scale_grid,
}
}
}
@ -1415,6 +1420,7 @@ impl ExecutorContext {
} else {
None
},
if settings.show_grid { Some(true) } else { None },
None,
None,
None,
@ -1478,6 +1484,7 @@ impl ExecutorContext {
units,
highlight_edges: true,
enable_ssao: false,
show_grid: false,
},
)
.await?;
@ -1564,16 +1571,7 @@ impl ExecutorContext {
}
FunctionKind::UserDefined => {
if let Some(func) = memory.clone().root.get(&fn_name) {
let (result, global_memory_items) =
func.call_fn(args.clone(), memory.clone(), self.clone()).await?;
// Add the global memory items to the memory.
for (key, item) in global_memory_items {
// We don't care about errors here because any collisions
// would happened in the function call itself and already
// errored out.
memory.add(&key, item, call_expr.into()).unwrap_or_default();
}
let result = func.call_fn(args.clone(), memory.clone(), self.clone()).await?;
memory.return_ = result;
} else {
@ -1698,7 +1696,7 @@ impl ExecutorContext {
.inner_execute(&function_expression.body, &mut fn_memory, BodyType::Block)
.await?;
Ok((result.return_, fn_memory.get_tags()))
Ok(result.return_)
})
},
);

View File

@ -1,5 +1,3 @@
use std::collections::HashMap;
use schemars::JsonSchema;
use crate::{
@ -18,10 +16,7 @@ pub struct FunctionParam<'a> {
}
impl<'a> FunctionParam<'a> {
pub async fn call(
&self,
args: Vec<MemoryItem>,
) -> Result<(Option<ProgramReturn>, HashMap<String, MemoryItem>), KclError> {
pub async fn call(&self, args: Vec<MemoryItem>) -> Result<Option<ProgramReturn>, KclError> {
(self.inner)(
args,
self.memory.clone(),

View File

@ -1542,6 +1542,7 @@ fn fn_call(i: TokenSlice) -> PResult<CallExpression> {
// Replace the literal with the tag.
args[i] = Value::Identifier(Box::new(tag));
}
Value::MemberExpression(_) => {}
e => {
return Err(ErrMode::Cut(
KclError::Syntax(KclErrorDetails {

View File

@ -77,6 +77,15 @@ async fn inner_extrude(length: f64, sketch_group_set: SketchGroupSet, args: Args
let sketch_groups: Vec<Box<SketchGroup>> = sketch_group_set.into();
let mut extrude_groups = Vec::new();
for sketch_group in &sketch_groups {
// Make sure we exited sketch mode if sketching on a plane.
if let SketchSurface::Plane(_) = sketch_group.on {
// Disable the sketch mode.
// This is necessary for when people don't close the sketch explicitly.
// The sketch mode will mess up the extrude direction if still active.
args.batch_modeling_cmd(uuid::Uuid::new_v4(), kittycad::types::ModelingCmd::SketchModeDisable {})
.await?;
}
args.send_modeling_cmd(
id,
kittycad::types::ModelingCmd::Extrude {

View File

@ -207,7 +207,7 @@ async fn make_transform<'a>(
meta: vec![source_range.into()],
});
let transform_fn_args = vec![repetition_num];
let transform_fn_return = transform_function.call(transform_fn_args).await?.0;
let transform_fn_return = transform_function.call(transform_fn_args).await?;
// Unpack the returned transform object.
let source_ranges = vec![source_range];

View File

@ -1,5 +1,7 @@
//! Functions related to sketching.
use std::collections::HashMap;
use anyhow::Result;
use derive_docs::stdlib;
use kittycad::types::{Angle, ModelingCmd, Point3D};
@ -127,6 +129,11 @@ async fn inner_line_to(
)
.await?;
let mut new_sketch_group = sketch_group.clone();
if let Some(tag) = &tag {
new_sketch_group.tags.insert(tag.name.to_string(), tag.into());
}
let current_path = Path::ToPoint {
base: BasePath {
from: from.into(),
@ -139,7 +146,6 @@ async fn inner_line_to(
},
};
let mut new_sketch_group = sketch_group.clone();
new_sketch_group.value.push(current_path);
Ok(new_sketch_group)
@ -291,6 +297,11 @@ async fn inner_line(
)
.await?;
let mut new_sketch_group = sketch_group.clone();
if let Some(tag) = &tag {
new_sketch_group.tags.insert(tag.name.to_string(), tag.into());
}
let current_path = Path::ToPoint {
base: BasePath {
from: from.into(),
@ -303,7 +314,6 @@ async fn inner_line(
},
};
let mut new_sketch_group = sketch_group.clone();
new_sketch_group.value.push(current_path);
Ok(new_sketch_group)
@ -455,18 +465,6 @@ async fn inner_angled_line(
let id = uuid::Uuid::new_v4();
let current_path = Path::ToPoint {
base: BasePath {
from: from.into(),
to,
tag,
geo_meta: GeoMeta {
id,
metadata: args.source_range.into(),
},
},
};
args.batch_modeling_cmd(
id,
ModelingCmd::ExtendPath {
@ -484,6 +482,22 @@ async fn inner_angled_line(
.await?;
let mut new_sketch_group = sketch_group.clone();
if let Some(tag) = &tag {
new_sketch_group.tags.insert(tag.name.to_string(), tag.into());
}
let current_path = Path::ToPoint {
base: BasePath {
from: from.into(),
to,
tag,
geo_meta: GeoMeta {
id,
metadata: args.source_range.into(),
},
},
};
new_sketch_group.value.push(current_path);
Ok(new_sketch_group)
}
@ -1206,7 +1220,7 @@ pub(crate) async fn inner_start_profile_at(
let current_path = BasePath {
from: to,
to,
tag,
tag: tag.clone(),
geo_meta: GeoMeta {
id,
metadata: args.source_range.into(),
@ -1219,6 +1233,11 @@ pub(crate) async fn inner_start_profile_at(
value: vec![],
start: current_path,
meta: vec![args.source_range.into()],
tags: if let Some(tag) = &tag {
HashMap::from([(tag.name.to_string(), tag.into())])
} else {
Default::default()
},
};
Ok(Box::new(sketch_group))
}
@ -1353,6 +1372,9 @@ pub(crate) async fn inner_close(
}
let mut new_sketch_group = sketch_group.clone();
if let Some(ref tag) = tag {
new_sketch_group.tags.insert(tag.name.to_string(), tag.into());
}
new_sketch_group.value.push(Path::ToPoint {
base: BasePath {
from: from.into(),
@ -1461,6 +1483,11 @@ pub(crate) async fn inner_arc(
)
.await?;
let mut new_sketch_group = sketch_group.clone();
if let Some(tag) = &tag {
new_sketch_group.tags.insert(tag.name.to_string(), tag.into());
}
let current_path = Path::ToPoint {
base: BasePath {
from: from.into(),
@ -1473,7 +1500,6 @@ pub(crate) async fn inner_arc(
},
};
let mut new_sketch_group = sketch_group.clone();
new_sketch_group.value.push(current_path);
Ok(new_sketch_group)
@ -1567,6 +1593,11 @@ async fn inner_tangential_arc(
let to = [from.x + to[0], from.y + to[1]];
let mut new_sketch_group = sketch_group.clone();
if let Some(tag) = &tag {
new_sketch_group.tags.insert(tag.name.to_string(), tag.into());
}
let current_path = Path::TangentialArc {
base: BasePath {
from: from.into(),
@ -1579,7 +1610,6 @@ async fn inner_tangential_arc(
},
};
let mut new_sketch_group = sketch_group.clone();
new_sketch_group.value.push(current_path);
Ok(new_sketch_group)
@ -1671,6 +1701,11 @@ async fn inner_tangential_arc_to(
let id = uuid::Uuid::new_v4();
args.batch_modeling_cmd(id, tan_arc_to(&sketch_group, &delta)).await?;
let mut new_sketch_group = sketch_group.clone();
if let Some(tag) = &tag {
new_sketch_group.tags.insert(tag.name.to_string(), tag.into());
}
let current_path = Path::TangentialArcTo {
base: BasePath {
from: from.into(),
@ -1685,7 +1720,6 @@ async fn inner_tangential_arc_to(
ccw: result.ccw > 0,
};
let mut new_sketch_group = sketch_group.clone();
new_sketch_group.value.push(current_path);
Ok(new_sketch_group)
@ -1772,6 +1806,11 @@ async fn inner_bezier_curve(
)
.await?;
let mut new_sketch_group = sketch_group.clone();
if let Some(tag) = &tag {
new_sketch_group.tags.insert(tag.name.to_string(), tag.into());
}
let current_path = Path::ToPoint {
base: BasePath {
from: from.into(),
@ -1784,7 +1823,6 @@ async fn inner_bezier_curve(
},
};
let mut new_sketch_group = sketch_group.clone();
new_sketch_group.value.push(current_path);
Ok(new_sketch_group)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 134 KiB

After

Width:  |  Height:  |  Size: 114 KiB

View File

@ -1,6 +1,7 @@
// A mounting bracket for the Focusrite Scarlett Solo audio interface
// This is a bracket that holds an audio device underneath a desk or shelf. The audio device has dimensions of 144mm wide, 80mm length and 45mm depth with fillets of 6mm. This mounting bracket is designed to be 3D printed with PLA material
// define constants in mm
const radius = 6.0
const width = 144.0
@ -16,10 +17,10 @@ const tabThk = 4
fn rectShape = (pos, w, l) => {
const rr = startSketchOn('xy')
|> startProfileAt([pos[0] - (w / 2), pos[1] - (l / 2)], %)
|> lineTo([pos[0] + w / 2, pos[1] - (l / 2)], %, "edge01")
|> lineTo([pos[0] + w / 2, pos[1] + l / 2], %, "edge02")
|> lineTo([pos[0] - (w / 2), pos[1] + l / 2], %, "edge03")
|> close(%, "edge04")
|> lineTo([pos[0] + w / 2, pos[1] - (l / 2)], %, $edge01)
|> lineTo([pos[0] + w / 2, pos[1] + l / 2], %, $edge02)
|> lineTo([pos[0] - (w / 2), pos[1] + l / 2], %, $edge03)
|> close(%, $edge04)
return rr
}
@ -37,27 +38,28 @@ const bracketPlane = {
fn bracketSketch = (w, d, t) => {
const s = startSketchOn(bracketPlane)
|> startProfileAt([-w / 2 - t, d + t], %)
|> lineTo([-w / 2 - t, -t], %, "edge1")
|> lineTo([w / 2 + t, -t], %, "edge2")
|> lineTo([w / 2 + t, d + t], %, "edge3")
|> lineTo([w / 2, d + t], %, "edge4")
|> lineTo([w / 2, 0], %, "edge5")
|> lineTo([-w / 2, 0], %, "edge6")
|> lineTo([-w / 2, d + t], %, "edge7")
|> close(%, "edge8")
|> lineTo([-w / 2 - t, -t], %, $edge1)
|> lineTo([w / 2 + t, -t], %, $edge2)
|> lineTo([w / 2 + t, d + t], %, $edge3)
|> lineTo([w / 2, d + t], %, $edge4)
|> lineTo([w / 2, 0], %, $edge5)
|> lineTo([-w / 2, 0], %, $edge6)
|> lineTo([-w / 2, d + t], %, $edge7)
|> close(%, $edge8)
return s
}
// build the body of the bracket
const bracketBody = bracketSketch(width, depth, thk)
const bs = bracketSketch(width, depth, thk)
const bracketBody = bs
|> extrude(length + 2 * thk, %)
|> fillet({
radius: radius,
tags: [
getNextAdjacentEdge("edge7", %),
getNextAdjacentEdge("edge2", %),
getNextAdjacentEdge("edge3", %),
getNextAdjacentEdge("edge6", %)
getNextAdjacentEdge(bs.tags.edge7, %),
getNextAdjacentEdge(bs.tags.edge2, %),
getNextAdjacentEdge(bs.tags.edge3, %),
getNextAdjacentEdge(bs.tags.edge6, %)
]
}, %)
@ -74,10 +76,10 @@ const tabPlane = {
// build the tabs of the mounting bracket (right side)
const tabsR = startSketchOn(tabPlane)
|> startProfileAt([width / 2 + thk, length / 2 + thk], %)
|> line([tabWidth, -tabLength / 3], %, "edge11")
|> line([0, -tabLength / 3 * 2], %, "edge12")
|> line([-tabWidth, -tabLength / 3], %, "edge13")
|> close(%, "edge14")
|> line([tabWidth, -tabLength / 3], %, $edge11)
|> line([0, -tabLength / 3 * 2], %, $edge12)
|> line([-tabWidth, -tabLength / 3], %, $edge13)
|> close(%, $edge14)
|> hole(circle([
width / 2 + thk + tabWidth / 2,
length / 2 + thk - (tabLength / (3 / 2))
@ -86,8 +88,8 @@ const tabsR = startSketchOn(tabPlane)
|> fillet({
radius: holeDiam / 2,
tags: [
getNextAdjacentEdge("edge12", %),
getNextAdjacentEdge("edge13", %)
getNextAdjacentEdge(edge12, %),
getNextAdjacentEdge(edge13, %)
]
}, %)
|> patternLinear3d({
@ -99,10 +101,10 @@ const tabsR = startSketchOn(tabPlane)
// build the tabs of the mounting bracket (left side)
const tabsL = startSketchOn(tabPlane)
|> startProfileAt([-width / 2 - thk, length / 2 + thk], %)
|> line([-tabWidth, -tabLength / 3], %, "edge21")
|> line([0, -tabLength / 3 * 2], %, "edge22")
|> line([tabWidth, -tabLength / 3], %, "edge23")
|> close(%, "edge24")
|> line([-tabWidth, -tabLength / 3], %, $edge21)
|> line([0, -tabLength / 3 * 2], %, $edge22)
|> line([tabWidth, -tabLength / 3], %, $edge23)
|> close(%, $edge24)
|> hole(circle([
-width / 2 - thk - (tabWidth / 2),
length / 2 + thk - (tabLength / (3 / 2))
@ -111,8 +113,8 @@ const tabsL = startSketchOn(tabPlane)
|> fillet({
radius: holeDiam / 2,
tags: [
getNextAdjacentEdge("edge21", %),
getNextAdjacentEdge("edge22", %)
getNextAdjacentEdge(edge21, %),
getNextAdjacentEdge(edge22, %)
]
}, %)
|> patternLinear3d({

View File

@ -0,0 +1,39 @@
// define a plane with UID 94894440791888
const plane94894440791888 = {
plane: {
origin: [0.005000000000000001, 0.01, -0.005],
x_axis: [
0.9285064634886234,
0.37131623619207604,
0.0
],
y_axis: [-0.0, 0.0, 1.0],
z_axis: [
0.37131623619207604,
-0.9285064634886234,
0.0
]
}
}
// create a sketch with UID 94894440902176
const sketch94894440902176 = startSketchOn('-XZ')
|> startProfileAt([-0.005, -0.005], %)
|> line([0.01, 0.0], %, $line94894439494384)
|> line([0.0, 0.01], %, $line94894439429616)
|> line([-0.01, 0.0], %, $line94894439638160)
|> line([0.0, -0.01], %, $line94894439971808)
// create an extrusion with UID 94894439487136
const extrude94894439487136 = extrude(0.01, sketch94894440902176)
// create a sketch with UID 94894439448464
const sketch94894439448464 = startSketchOn(plane94894440791888)
|> startProfileAt([
0.00074557205559017,
0.00306415853984399
], %)
|> line([0.004999999999999999, 0.0], %, $line94894440230336)
|> line([0.0, -0.005], %, $line94894439497168)
|> line([-0.004999999999999999, 0.0], %, $line94894439496768)
|> line([0.0, 0.005], %, $line94894440231952)

View File

@ -0,0 +1,39 @@
// define a plane with UID 94894440791888
const plane94894440791888 = {
plane: {
origin: [0.005000000000000001, 0.01, -0.005],
x_axis: [
0.9285064634886234,
0.37131623619207604,
0.0
],
y_axis: [-0.0, 0.0, 1.0],
z_axis: [
0.37131623619207604,
-0.9285064634886234,
0.0
]
}
}
// create a sketch with UID 94894440902176
const sketch94894440902176 = startSketchOn('-XZ')
|> startProfileAt([-0.005, -0.005], %)
|> line([0.01, 0.0], %, $line94894439494384)
|> line([0.0, 0.01], %, $line94894439429616)
|> line([-0.01, 0.0], %, $line94894439638160)
|> line([0.0, -0.01], %, $line94894439971808)
// create a sketch with UID 94894439448464
const sketch94894439448464 = startSketchOn(plane94894440791888)
|> startProfileAt([
0.00074557205559017,
0.00306415853984399
], %)
|> line([0.004999999999999999, 0.0], %, $line94894440230336)
|> line([0.0, -0.005], %, $line94894439497168)
|> line([-0.004999999999999999, 0.0], %, $line94894439496768)
|> line([0.0, 0.005], %, $line94894440231952)
// create an extrusion with UID 94894439487136
const extrude94894439487136 = extrude(0.01, sketch94894440902176)

View File

@ -0,0 +1,18 @@
fn rect = (origin) => {
return startSketchOn('XZ')
|> startProfileAt(origin, %)
|> angledLine([0, 191.26], %, $rectangleSegmentA001)
|> angledLine([
segAng(rectangleSegmentA001, %) - 90,
196.99
], %, $rectangleSegmentB001)
|> angledLine([
segAng(rectangleSegmentA001, %),
-segLen(rectangleSegmentA001, %)
], %, $rectangleSegmentC001)
|> lineTo([profileStartX(%), profileStartY(%)], %)
|> close(%)
}
rect([0, 0])
rect([20, 0])

View File

@ -37,6 +37,7 @@ async fn new_context(units: UnitLength) -> Result<ExecutorContext> {
units,
highlight_edges: true,
enable_ssao: false,
show_grid: false,
},
)
.await?;
@ -2471,3 +2472,32 @@ async fn serial_test_pattern_vase() {
let result = execute_and_snapshot(code, UnitLength::Mm).await.unwrap();
twenty_twenty::assert_image("tests/executor/outputs/pattern_vase.png", &result, 0.999);
}
#[tokio::test(flavor = "multi_thread")]
async fn serial_test_scoped_tags() {
let code = include_str!("inputs/scoped-tags.kcl");
let result = execute_and_snapshot(code, UnitLength::Mm).await.unwrap();
twenty_twenty::assert_image("tests/executor/outputs/scoped_tags.png", &result, 0.999);
}
#[tokio::test(flavor = "multi_thread")]
async fn serial_test_order_sketch_extrude_in_order() {
let code = include_str!("inputs/order-sketch-extrude-in-order.kcl");
let result = execute_and_snapshot(code, UnitLength::Mm).await.unwrap();
twenty_twenty::assert_image(
"tests/executor/outputs/order-sketch-extrude-in-order.png",
&result,
0.999,
);
}
#[tokio::test(flavor = "multi_thread")]
async fn serial_test_order_sketch_extrude_out_of_order() {
let code = include_str!("inputs/order-sketch-extrude-out-of-order.kcl");
let result = execute_and_snapshot(code, UnitLength::Mm).await.unwrap();
twenty_twenty::assert_image(
"tests/executor/outputs/order-sketch-extrude-out-of-order.png",
&result,
0.999,
);
}

Some files were not shown because too many files have changed in this diff Show More