Compare commits
8 Commits
lf94/prope
...
callbacks-
| Author | SHA1 | Date | |
|---|---|---|---|
| cf068f325e | |||
| d60d2292f3 | |||
| 7d564cc2ac | |||
| 05a84213dd | |||
| a85c1a9375 | |||
| 5701616f3e | |||
| 846acaba2f | |||
| 0a524d42f6 |
@ -121,6 +121,9 @@ const extrusion = extrude(5, sketch001)
|
|||||||
},
|
},
|
||||||
// The to point.
|
// The to point.
|
||||||
to: [number, number],
|
to: [number, number],
|
||||||
|
},
|
||||||
|
// Tag identifiers that have been declared in this sketch group.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
@ -282,6 +285,9 @@ const extrusion = extrude(5, sketch001)
|
|||||||
},
|
},
|
||||||
// The to point.
|
// The to point.
|
||||||
to: [number, number],
|
to: [number, number],
|
||||||
|
},
|
||||||
|
// Tag identifiers that have been declared in this sketch group.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
|
|||||||
@ -125,6 +125,9 @@ const extrusion = extrude(5, sketch001)
|
|||||||
},
|
},
|
||||||
// The to point.
|
// The to point.
|
||||||
to: [number, number],
|
to: [number, number],
|
||||||
|
},
|
||||||
|
// Tag identifiers that have been declared in this sketch group.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
@ -286,6 +289,9 @@ const extrusion = extrude(5, sketch001)
|
|||||||
},
|
},
|
||||||
// The to point.
|
// The to point.
|
||||||
to: [number, number],
|
to: [number, number],
|
||||||
|
},
|
||||||
|
// Tag identifiers that have been declared in this sketch group.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
|
|||||||
@ -126,6 +126,9 @@ const example = extrude(10, exampleSketch)
|
|||||||
},
|
},
|
||||||
// The to point.
|
// The to point.
|
||||||
to: [number, number],
|
to: [number, number],
|
||||||
|
},
|
||||||
|
// Tag identifiers that have been declared in this sketch group.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
@ -287,6 +290,9 @@ const example = extrude(10, exampleSketch)
|
|||||||
},
|
},
|
||||||
// The to point.
|
// The to point.
|
||||||
to: [number, number],
|
to: [number, number],
|
||||||
|
},
|
||||||
|
// Tag identifiers that have been declared in this sketch group.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
@ -476,6 +482,9 @@ const example = extrude(10, exampleSketch)
|
|||||||
},
|
},
|
||||||
// The to point.
|
// The to point.
|
||||||
to: [number, number],
|
to: [number, number],
|
||||||
|
},
|
||||||
|
// Tag identifiers that have been declared in this sketch group.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
@ -637,6 +646,9 @@ const example = extrude(10, exampleSketch)
|
|||||||
},
|
},
|
||||||
// The to point.
|
// The to point.
|
||||||
to: [number, number],
|
to: [number, number],
|
||||||
|
},
|
||||||
|
// Tag identifiers that have been declared in this sketch group.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
|
|||||||
@ -125,6 +125,9 @@ const extrusion = extrude(10, sketch001)
|
|||||||
},
|
},
|
||||||
// The to point.
|
// The to point.
|
||||||
to: [number, number],
|
to: [number, number],
|
||||||
|
},
|
||||||
|
// Tag identifiers that have been declared in this sketch group.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
@ -286,6 +289,9 @@ const extrusion = extrude(10, sketch001)
|
|||||||
},
|
},
|
||||||
// The to point.
|
// The to point.
|
||||||
to: [number, number],
|
to: [number, number],
|
||||||
|
},
|
||||||
|
// Tag identifiers that have been declared in this sketch group.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
@ -475,6 +481,9 @@ const extrusion = extrude(10, sketch001)
|
|||||||
},
|
},
|
||||||
// The to point.
|
// The to point.
|
||||||
to: [number, number],
|
to: [number, number],
|
||||||
|
},
|
||||||
|
// Tag identifiers that have been declared in this sketch group.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
@ -636,6 +645,9 @@ const extrusion = extrude(10, sketch001)
|
|||||||
},
|
},
|
||||||
// The to point.
|
// The to point.
|
||||||
to: [number, number],
|
to: [number, number],
|
||||||
|
},
|
||||||
|
// Tag identifiers that have been declared in this sketch group.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
|
|||||||
@ -133,6 +133,9 @@ const example = extrude(10, exampleSketch)
|
|||||||
},
|
},
|
||||||
// The to point.
|
// The to point.
|
||||||
to: [number, number],
|
to: [number, number],
|
||||||
|
},
|
||||||
|
// Tag identifiers that have been declared in this sketch group.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
@ -294,6 +297,9 @@ const example = extrude(10, exampleSketch)
|
|||||||
},
|
},
|
||||||
// The to point.
|
// The to point.
|
||||||
to: [number, number],
|
to: [number, number],
|
||||||
|
},
|
||||||
|
// Tag identifiers that have been declared in this sketch group.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
@ -483,6 +489,9 @@ const example = extrude(10, exampleSketch)
|
|||||||
},
|
},
|
||||||
// The to point.
|
// The to point.
|
||||||
to: [number, number],
|
to: [number, number],
|
||||||
|
},
|
||||||
|
// Tag identifiers that have been declared in this sketch group.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
@ -644,6 +653,9 @@ const example = extrude(10, exampleSketch)
|
|||||||
},
|
},
|
||||||
// The to point.
|
// The to point.
|
||||||
to: [number, number],
|
to: [number, number],
|
||||||
|
},
|
||||||
|
// Tag identifiers that have been declared in this sketch group.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
|
|||||||
@ -124,6 +124,9 @@ const example = extrude(10, exampleSketch)
|
|||||||
},
|
},
|
||||||
// The to point.
|
// The to point.
|
||||||
to: [number, number],
|
to: [number, number],
|
||||||
|
},
|
||||||
|
// Tag identifiers that have been declared in this sketch group.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
@ -285,6 +288,9 @@ const example = extrude(10, exampleSketch)
|
|||||||
},
|
},
|
||||||
// The to point.
|
// The to point.
|
||||||
to: [number, number],
|
to: [number, number],
|
||||||
|
},
|
||||||
|
// Tag identifiers that have been declared in this sketch group.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
@ -474,6 +480,9 @@ const example = extrude(10, exampleSketch)
|
|||||||
},
|
},
|
||||||
// The to point.
|
// The to point.
|
||||||
to: [number, number],
|
to: [number, number],
|
||||||
|
},
|
||||||
|
// Tag identifiers that have been declared in this sketch group.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
@ -635,6 +644,9 @@ const example = extrude(10, exampleSketch)
|
|||||||
},
|
},
|
||||||
// The to point.
|
// The to point.
|
||||||
to: [number, number],
|
to: [number, number],
|
||||||
|
},
|
||||||
|
// Tag identifiers that have been declared in this sketch group.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
|
|||||||
@ -124,6 +124,9 @@ const example = extrude(10, exampleSketch)
|
|||||||
},
|
},
|
||||||
// The to point.
|
// The to point.
|
||||||
to: [number, number],
|
to: [number, number],
|
||||||
|
},
|
||||||
|
// Tag identifiers that have been declared in this sketch group.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
@ -285,6 +288,9 @@ const example = extrude(10, exampleSketch)
|
|||||||
},
|
},
|
||||||
// The to point.
|
// The to point.
|
||||||
to: [number, number],
|
to: [number, number],
|
||||||
|
},
|
||||||
|
// Tag identifiers that have been declared in this sketch group.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
@ -474,6 +480,9 @@ const example = extrude(10, exampleSketch)
|
|||||||
},
|
},
|
||||||
// The to point.
|
// The to point.
|
||||||
to: [number, number],
|
to: [number, number],
|
||||||
|
},
|
||||||
|
// Tag identifiers that have been declared in this sketch group.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
@ -635,6 +644,9 @@ const example = extrude(10, exampleSketch)
|
|||||||
},
|
},
|
||||||
// The to point.
|
// The to point.
|
||||||
to: [number, number],
|
to: [number, number],
|
||||||
|
},
|
||||||
|
// Tag identifiers that have been declared in this sketch group.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
|
|||||||
@ -135,6 +135,9 @@ const exampleSketch = startSketchOn('XZ')
|
|||||||
},
|
},
|
||||||
// The to point.
|
// The to point.
|
||||||
to: [number, number],
|
to: [number, number],
|
||||||
|
},
|
||||||
|
// Tag identifiers that have been declared in this sketch group.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
@ -296,6 +299,9 @@ const exampleSketch = startSketchOn('XZ')
|
|||||||
},
|
},
|
||||||
// The to point.
|
// The to point.
|
||||||
to: [number, number],
|
to: [number, number],
|
||||||
|
},
|
||||||
|
// Tag identifiers that have been declared in this sketch group.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
@ -485,6 +491,9 @@ const exampleSketch = startSketchOn('XZ')
|
|||||||
},
|
},
|
||||||
// The to point.
|
// The to point.
|
||||||
to: [number, number],
|
to: [number, number],
|
||||||
|
},
|
||||||
|
// Tag identifiers that have been declared in this sketch group.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
@ -646,6 +655,9 @@ const exampleSketch = startSketchOn('XZ')
|
|||||||
},
|
},
|
||||||
// The to point.
|
// The to point.
|
||||||
to: [number, number],
|
to: [number, number],
|
||||||
|
},
|
||||||
|
// Tag identifiers that have been declared in this sketch group.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
|
|||||||
@ -130,6 +130,9 @@ const example = extrude(10, exampleSketch)
|
|||||||
},
|
},
|
||||||
// The to point.
|
// The to point.
|
||||||
to: [number, number],
|
to: [number, number],
|
||||||
|
},
|
||||||
|
// Tag identifiers that have been declared in this sketch group.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
@ -291,6 +294,9 @@ const example = extrude(10, exampleSketch)
|
|||||||
},
|
},
|
||||||
// The to point.
|
// The to point.
|
||||||
to: [number, number],
|
to: [number, number],
|
||||||
|
},
|
||||||
|
// Tag identifiers that have been declared in this sketch group.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
@ -480,6 +486,9 @@ const example = extrude(10, exampleSketch)
|
|||||||
},
|
},
|
||||||
// The to point.
|
// The to point.
|
||||||
to: [number, number],
|
to: [number, number],
|
||||||
|
},
|
||||||
|
// Tag identifiers that have been declared in this sketch group.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
@ -641,6 +650,9 @@ const example = extrude(10, exampleSketch)
|
|||||||
},
|
},
|
||||||
// The to point.
|
// The to point.
|
||||||
to: [number, number],
|
to: [number, number],
|
||||||
|
},
|
||||||
|
// Tag identifiers that have been declared in this sketch group.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
|
|||||||
@ -225,6 +225,9 @@ const mountingPlate = extrude(thickness, mountingPlateSketch)
|
|||||||
},
|
},
|
||||||
// The to point.
|
// The to point.
|
||||||
to: [number, number],
|
to: [number, number],
|
||||||
|
},
|
||||||
|
// Tag identifiers that have been declared in this sketch group.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
@ -532,6 +535,9 @@ const mountingPlate = extrude(thickness, mountingPlateSketch)
|
|||||||
},
|
},
|
||||||
// The to point.
|
// The to point.
|
||||||
to: [number, number],
|
to: [number, number],
|
||||||
|
},
|
||||||
|
// Tag identifiers that have been declared in this sketch group.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
|
|||||||
@ -123,6 +123,9 @@ 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.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
@ -410,6 +413,9 @@ 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.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
@ -599,6 +605,9 @@ 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.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
@ -760,6 +769,9 @@ 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.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
|
|||||||
@ -125,6 +125,9 @@ const example = extrude(10, exampleSketch)
|
|||||||
},
|
},
|
||||||
// The to point.
|
// The to point.
|
||||||
to: [number, number],
|
to: [number, number],
|
||||||
|
},
|
||||||
|
// Tag identifiers that have been declared in this sketch group.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
@ -286,6 +289,9 @@ const example = extrude(10, exampleSketch)
|
|||||||
},
|
},
|
||||||
// The to point.
|
// The to point.
|
||||||
to: [number, number],
|
to: [number, number],
|
||||||
|
},
|
||||||
|
// Tag identifiers that have been declared in this sketch group.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
@ -475,6 +481,9 @@ const example = extrude(10, exampleSketch)
|
|||||||
},
|
},
|
||||||
// The to point.
|
// The to point.
|
||||||
to: [number, number],
|
to: [number, number],
|
||||||
|
},
|
||||||
|
// Tag identifiers that have been declared in this sketch group.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
@ -636,6 +645,9 @@ const example = extrude(10, exampleSketch)
|
|||||||
},
|
},
|
||||||
// The to point.
|
// The to point.
|
||||||
to: [number, number],
|
to: [number, number],
|
||||||
|
},
|
||||||
|
// Tag identifiers that have been declared in this sketch group.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
|
|||||||
@ -150,6 +150,9 @@ const example = extrude(10, exampleSketch)
|
|||||||
},
|
},
|
||||||
// The to point.
|
// The to point.
|
||||||
to: [number, number],
|
to: [number, number],
|
||||||
|
},
|
||||||
|
// Tag identifiers that have been declared in this sketch group.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
@ -311,6 +314,9 @@ const example = extrude(10, exampleSketch)
|
|||||||
},
|
},
|
||||||
// The to point.
|
// The to point.
|
||||||
to: [number, number],
|
to: [number, number],
|
||||||
|
},
|
||||||
|
// Tag identifiers that have been declared in this sketch group.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
type: "sketchGroup",
|
type: "sketchGroup",
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
@ -580,6 +586,9 @@ const example = extrude(10, exampleSketch)
|
|||||||
},
|
},
|
||||||
// The to point.
|
// The to point.
|
||||||
to: [number, number],
|
to: [number, number],
|
||||||
|
},
|
||||||
|
// Tag identifiers that have been declared in this sketch group.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
|
|||||||
@ -225,6 +225,9 @@ const mountingPlate = extrude(thickness, mountingPlateSketch)
|
|||||||
},
|
},
|
||||||
// The to point.
|
// The to point.
|
||||||
to: [number, number],
|
to: [number, number],
|
||||||
|
},
|
||||||
|
// Tag identifiers that have been declared in this sketch group.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
@ -524,6 +527,9 @@ const mountingPlate = extrude(thickness, mountingPlateSketch)
|
|||||||
},
|
},
|
||||||
// The to point.
|
// The to point.
|
||||||
to: [number, number],
|
to: [number, number],
|
||||||
|
},
|
||||||
|
// Tag identifiers that have been declared in this sketch group.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
|
|||||||
@ -215,6 +215,9 @@ const revolution = startSketchOn(box, "revolveAxis")
|
|||||||
},
|
},
|
||||||
// The to point.
|
// The to point.
|
||||||
to: [number, number],
|
to: [number, number],
|
||||||
|
},
|
||||||
|
// Tag identifiers that have been declared in this sketch group.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
|
|||||||
@ -211,6 +211,9 @@ 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.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
|
|||||||
@ -211,6 +211,9 @@ 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.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
|
|||||||
@ -213,6 +213,9 @@ 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.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
|
|||||||
@ -213,6 +213,9 @@ const part001 = startSketchOn('XY')
|
|||||||
},
|
},
|
||||||
// The to point.
|
// The to point.
|
||||||
to: [number, number],
|
to: [number, number],
|
||||||
|
},
|
||||||
|
// Tag identifiers that have been declared in this sketch group.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
@ -512,6 +515,9 @@ const part001 = startSketchOn('XY')
|
|||||||
},
|
},
|
||||||
// The to point.
|
// The to point.
|
||||||
to: [number, number],
|
to: [number, number],
|
||||||
|
},
|
||||||
|
// Tag identifiers that have been declared in this sketch group.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
|
|||||||
@ -136,6 +136,9 @@ const example = extrude(1, exampleSketch)
|
|||||||
},
|
},
|
||||||
// The to point.
|
// The to point.
|
||||||
to: [number, number],
|
to: [number, number],
|
||||||
|
},
|
||||||
|
// Tag identifiers that have been declared in this sketch group.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
@ -297,6 +300,9 @@ const example = extrude(1, exampleSketch)
|
|||||||
},
|
},
|
||||||
// The to point.
|
// The to point.
|
||||||
to: [number, number],
|
to: [number, number],
|
||||||
|
},
|
||||||
|
// Tag identifiers that have been declared in this sketch group.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
type: "sketchGroup",
|
type: "sketchGroup",
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
@ -479,6 +485,9 @@ const example = extrude(1, exampleSketch)
|
|||||||
},
|
},
|
||||||
// The to point.
|
// The to point.
|
||||||
to: [number, number],
|
to: [number, number],
|
||||||
|
},
|
||||||
|
// Tag identifiers that have been declared in this sketch group.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
@ -640,6 +649,9 @@ const example = extrude(1, exampleSketch)
|
|||||||
},
|
},
|
||||||
// The to point.
|
// The to point.
|
||||||
to: [number, number],
|
to: [number, number],
|
||||||
|
},
|
||||||
|
// Tag identifiers that have been declared in this sketch group.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
@ -821,6 +833,9 @@ const example = extrude(1, exampleSketch)
|
|||||||
},
|
},
|
||||||
// The to point.
|
// The to point.
|
||||||
to: [number, number],
|
to: [number, number],
|
||||||
|
},
|
||||||
|
// Tag identifiers that have been declared in this sketch group.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
@ -982,6 +997,9 @@ const example = extrude(1, exampleSketch)
|
|||||||
},
|
},
|
||||||
// The to point.
|
// The to point.
|
||||||
to: [number, number],
|
to: [number, number],
|
||||||
|
},
|
||||||
|
// Tag identifiers that have been declared in this sketch group.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
|
|||||||
@ -116,6 +116,9 @@ 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.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
@ -277,6 +280,9 @@ 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.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
|
|||||||
@ -116,6 +116,9 @@ 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.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
@ -277,6 +280,9 @@ 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.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
|
|||||||
@ -129,6 +129,9 @@ 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.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
@ -290,6 +293,9 @@ 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.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
@ -479,6 +485,9 @@ 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.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
@ -640,6 +649,9 @@ 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.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
|
|||||||
@ -116,6 +116,9 @@ 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.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
@ -277,6 +280,9 @@ 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.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
@ -466,6 +472,9 @@ 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.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
@ -627,6 +636,9 @@ 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.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
|
|||||||
@ -134,6 +134,9 @@ const example = extrude(1, exampleSketch)
|
|||||||
},
|
},
|
||||||
// The to point.
|
// The to point.
|
||||||
to: [number, number],
|
to: [number, number],
|
||||||
|
},
|
||||||
|
// Tag identifiers that have been declared in this sketch group.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
@ -295,6 +298,9 @@ const example = extrude(1, exampleSketch)
|
|||||||
},
|
},
|
||||||
// The to point.
|
// The to point.
|
||||||
to: [number, number],
|
to: [number, number],
|
||||||
|
},
|
||||||
|
// Tag identifiers that have been declared in this sketch group.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
type: "sketchGroup",
|
type: "sketchGroup",
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
|
|||||||
@ -217,6 +217,9 @@ 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.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
|
|||||||
@ -127,6 +127,9 @@ const example = extrude(1, exampleSketch)
|
|||||||
},
|
},
|
||||||
// The to point.
|
// The to point.
|
||||||
to: [number, number],
|
to: [number, number],
|
||||||
|
},
|
||||||
|
// Tag identifiers that have been declared in this sketch group.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
@ -288,6 +291,9 @@ const example = extrude(1, exampleSketch)
|
|||||||
},
|
},
|
||||||
// The to point.
|
// The to point.
|
||||||
to: [number, number],
|
to: [number, number],
|
||||||
|
},
|
||||||
|
// Tag identifiers that have been declared in this sketch group.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
type: "sketchGroup",
|
type: "sketchGroup",
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
|
|||||||
@ -215,6 +215,9 @@ const example = extrude(1, exampleSketch)
|
|||||||
},
|
},
|
||||||
// The to point.
|
// The to point.
|
||||||
to: [number, number],
|
to: [number, number],
|
||||||
|
},
|
||||||
|
// Tag identifiers that have been declared in this sketch group.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
|
|||||||
@ -217,6 +217,9 @@ let vase = layer()
|
|||||||
},
|
},
|
||||||
// The to point.
|
// The to point.
|
||||||
to: [number, number],
|
to: [number, number],
|
||||||
|
},
|
||||||
|
// Tag identifiers that have been declared in this sketch group.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
|
|||||||
@ -117,6 +117,9 @@ const sketch001 = startSketchOn('XY')
|
|||||||
},
|
},
|
||||||
// The to point.
|
// The to point.
|
||||||
to: [number, number],
|
to: [number, number],
|
||||||
|
},
|
||||||
|
// Tag identifiers that have been declared in this sketch group.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
@ -278,6 +281,9 @@ const sketch001 = startSketchOn('XY')
|
|||||||
},
|
},
|
||||||
// The to point.
|
// The to point.
|
||||||
to: [number, number],
|
to: [number, number],
|
||||||
|
},
|
||||||
|
// Tag identifiers that have been declared in this sketch group.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
|
|||||||
@ -112,6 +112,9 @@ const sketch001 = startSketchOn('XY')
|
|||||||
},
|
},
|
||||||
// The to point.
|
// The to point.
|
||||||
to: [number, number],
|
to: [number, number],
|
||||||
|
},
|
||||||
|
// Tag identifiers that have been declared in this sketch group.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
@ -273,6 +276,9 @@ const sketch001 = startSketchOn('XY')
|
|||||||
},
|
},
|
||||||
// The to point.
|
// The to point.
|
||||||
to: [number, number],
|
to: [number, number],
|
||||||
|
},
|
||||||
|
// Tag identifiers that have been declared in this sketch group.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
|
|||||||
@ -111,6 +111,9 @@ const sketch001 = startSketchOn('XY')
|
|||||||
},
|
},
|
||||||
// The to point.
|
// The to point.
|
||||||
to: [number, number],
|
to: [number, number],
|
||||||
|
},
|
||||||
|
// Tag identifiers that have been declared in this sketch group.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
@ -272,6 +275,9 @@ const sketch001 = startSketchOn('XY')
|
|||||||
},
|
},
|
||||||
// The to point.
|
// The to point.
|
||||||
to: [number, number],
|
to: [number, number],
|
||||||
|
},
|
||||||
|
// Tag identifiers that have been declared in this sketch group.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
|
|||||||
@ -247,6 +247,9 @@ uuid |
|
|||||||
},
|
},
|
||||||
// The to point.
|
// The to point.
|
||||||
to: [number, number],
|
to: [number, number],
|
||||||
|
},
|
||||||
|
// Tag identifiers that have been declared in this sketch group.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
@ -408,6 +411,9 @@ uuid |
|
|||||||
},
|
},
|
||||||
// The to point.
|
// The to point.
|
||||||
to: [number, number],
|
to: [number, number],
|
||||||
|
},
|
||||||
|
// Tag identifiers that have been declared in this sketch group.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
@ -673,6 +679,9 @@ uuid |
|
|||||||
},
|
},
|
||||||
// The to point.
|
// The to point.
|
||||||
to: [number, number],
|
to: [number, number],
|
||||||
|
},
|
||||||
|
// Tag identifiers that have been declared in this sketch group.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
|
|||||||
@ -124,6 +124,9 @@ 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.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
@ -285,6 +288,9 @@ 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.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
|
|||||||
@ -122,6 +122,9 @@ 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.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
@ -283,6 +286,9 @@ 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.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
|
|||||||
@ -123,6 +123,9 @@ 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.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
@ -284,6 +287,9 @@ 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.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
|
|||||||
@ -121,6 +121,9 @@ 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.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
@ -282,6 +285,9 @@ 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.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
|
|||||||
@ -213,6 +213,9 @@ shell({ faces: ['end'], thickness: 0.25 }, firstSketch)
|
|||||||
},
|
},
|
||||||
// The to point.
|
// The to point.
|
||||||
to: [number, number],
|
to: [number, number],
|
||||||
|
},
|
||||||
|
// Tag identifiers that have been declared in this sketch group.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
@ -512,6 +515,9 @@ shell({ faces: ['end'], thickness: 0.25 }, firstSketch)
|
|||||||
},
|
},
|
||||||
// The to point.
|
// The to point.
|
||||||
to: [number, number],
|
to: [number, number],
|
||||||
|
},
|
||||||
|
// Tag identifiers that have been declared in this sketch group.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
|
|||||||
@ -195,6 +195,9 @@ 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.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
@ -442,6 +445,9 @@ 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.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
@ -603,6 +609,9 @@ 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.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
|
|||||||
@ -142,6 +142,9 @@ 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.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
@ -303,6 +306,9 @@ 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.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
|
|||||||
@ -264,6 +264,9 @@ const a1 = startSketchOn({
|
|||||||
},
|
},
|
||||||
// The to point.
|
// The to point.
|
||||||
to: [number, number],
|
to: [number, number],
|
||||||
|
},
|
||||||
|
// Tag identifiers that have been declared in this sketch group.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
@ -539,6 +542,9 @@ const a1 = startSketchOn({
|
|||||||
},
|
},
|
||||||
// The to point.
|
// The to point.
|
||||||
to: [number, number],
|
to: [number, number],
|
||||||
|
},
|
||||||
|
// Tag identifiers that have been declared in this sketch group.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
|
|||||||
5655
docs/kcl/std.json
@ -125,6 +125,9 @@ const example = extrude(10, exampleSketch)
|
|||||||
},
|
},
|
||||||
// The to point.
|
// The to point.
|
||||||
to: [number, number],
|
to: [number, number],
|
||||||
|
},
|
||||||
|
// Tag identifiers that have been declared in this sketch group.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
@ -286,6 +289,9 @@ const example = extrude(10, exampleSketch)
|
|||||||
},
|
},
|
||||||
// The to point.
|
// The to point.
|
||||||
to: [number, number],
|
to: [number, number],
|
||||||
|
},
|
||||||
|
// Tag identifiers that have been declared in this sketch group.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
@ -475,6 +481,9 @@ const example = extrude(10, exampleSketch)
|
|||||||
},
|
},
|
||||||
// The to point.
|
// The to point.
|
||||||
to: [number, number],
|
to: [number, number],
|
||||||
|
},
|
||||||
|
// Tag identifiers that have been declared in this sketch group.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
@ -636,6 +645,9 @@ const example = extrude(10, exampleSketch)
|
|||||||
},
|
},
|
||||||
// The to point.
|
// The to point.
|
||||||
to: [number, number],
|
to: [number, number],
|
||||||
|
},
|
||||||
|
// Tag identifiers that have been declared in this sketch group.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
|
|||||||
@ -116,6 +116,9 @@ const example = extrude(10, exampleSketch)
|
|||||||
},
|
},
|
||||||
// The to point.
|
// The to point.
|
||||||
to: [number, number],
|
to: [number, number],
|
||||||
|
},
|
||||||
|
// Tag identifiers that have been declared in this sketch group.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
@ -277,6 +280,9 @@ const example = extrude(10, exampleSketch)
|
|||||||
},
|
},
|
||||||
// The to point.
|
// The to point.
|
||||||
to: [number, number],
|
to: [number, number],
|
||||||
|
},
|
||||||
|
// Tag identifiers that have been declared in this sketch group.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
@ -466,6 +472,9 @@ const example = extrude(10, exampleSketch)
|
|||||||
},
|
},
|
||||||
// The to point.
|
// The to point.
|
||||||
to: [number, number],
|
to: [number, number],
|
||||||
|
},
|
||||||
|
// Tag identifiers that have been declared in this sketch group.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
@ -627,6 +636,9 @@ const example = extrude(10, exampleSketch)
|
|||||||
},
|
},
|
||||||
// The to point.
|
// The to point.
|
||||||
to: [number, number],
|
to: [number, number],
|
||||||
|
},
|
||||||
|
// Tag identifiers that have been declared in this sketch group.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
|
|||||||
@ -74,10 +74,107 @@ You can nest expressions in parenthesis as well:
|
|||||||
let myMathExpression = 3 + (1 * 2 / (3 - 7))
|
let myMathExpression = 3 + (1 * 2 / (3 - 7))
|
||||||
```
|
```
|
||||||
|
|
||||||
## Tag Declaration and Tag Identifiers
|
## Tags
|
||||||
|
|
||||||
The syntax for tags is now `$myTag` to declare a tag and `myTag` to then use it later.
|
Tags are used to give a name (tag) to a specific path.
|
||||||
|
|
||||||
Please if you find any issues using any of the above expressions or syntax
|
### 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
|
please file an issue with the `ast` label on the [modeling-app
|
||||||
repo](https://github.com/KittyCAD/modeling-app/issues/new).
|
repo](https://github.com/KittyCAD/modeling-app/issues/new).
|
||||||
|
|||||||
@ -119,6 +119,9 @@ const example = extrude(10, exampleSketch)
|
|||||||
},
|
},
|
||||||
// The to point.
|
// The to point.
|
||||||
to: [number, number],
|
to: [number, number],
|
||||||
|
},
|
||||||
|
// Tag identifiers that have been declared in this sketch group.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
@ -280,6 +283,9 @@ const example = extrude(10, exampleSketch)
|
|||||||
},
|
},
|
||||||
// The to point.
|
// The to point.
|
||||||
to: [number, number],
|
to: [number, number],
|
||||||
|
},
|
||||||
|
// Tag identifiers that have been declared in this sketch group.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
@ -469,6 +475,9 @@ const example = extrude(10, exampleSketch)
|
|||||||
},
|
},
|
||||||
// The to point.
|
// The to point.
|
||||||
to: [number, number],
|
to: [number, number],
|
||||||
|
},
|
||||||
|
// Tag identifiers that have been declared in this sketch group.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
@ -630,6 +639,9 @@ const example = extrude(10, exampleSketch)
|
|||||||
},
|
},
|
||||||
// The to point.
|
// The to point.
|
||||||
to: [number, number],
|
to: [number, number],
|
||||||
|
},
|
||||||
|
// Tag identifiers that have been declared in this sketch group.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
|
|||||||
@ -119,6 +119,9 @@ const example = extrude(10, exampleSketch)
|
|||||||
},
|
},
|
||||||
// The to point.
|
// The to point.
|
||||||
to: [number, number],
|
to: [number, number],
|
||||||
|
},
|
||||||
|
// Tag identifiers that have been declared in this sketch group.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
@ -280,6 +283,9 @@ const example = extrude(10, exampleSketch)
|
|||||||
},
|
},
|
||||||
// The to point.
|
// The to point.
|
||||||
to: [number, number],
|
to: [number, number],
|
||||||
|
},
|
||||||
|
// Tag identifiers that have been declared in this sketch group.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
@ -469,6 +475,9 @@ const example = extrude(10, exampleSketch)
|
|||||||
},
|
},
|
||||||
// The to point.
|
// The to point.
|
||||||
to: [number, number],
|
to: [number, number],
|
||||||
|
},
|
||||||
|
// Tag identifiers that have been declared in this sketch group.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
@ -630,6 +639,9 @@ const example = extrude(10, exampleSketch)
|
|||||||
},
|
},
|
||||||
// The to point.
|
// The to point.
|
||||||
to: [number, number],
|
to: [number, number],
|
||||||
|
},
|
||||||
|
// Tag identifiers that have been declared in this sketch group.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
|
|||||||
@ -117,6 +117,9 @@ const example = extrude(10, exampleSketch)
|
|||||||
},
|
},
|
||||||
// The to point.
|
// The to point.
|
||||||
to: [number, number],
|
to: [number, number],
|
||||||
|
},
|
||||||
|
// Tag identifiers that have been declared in this sketch group.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
@ -278,6 +281,9 @@ const example = extrude(10, exampleSketch)
|
|||||||
},
|
},
|
||||||
// The to point.
|
// The to point.
|
||||||
to: [number, number],
|
to: [number, number],
|
||||||
|
},
|
||||||
|
// Tag identifiers that have been declared in this sketch group.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
@ -467,6 +473,9 @@ const example = extrude(10, exampleSketch)
|
|||||||
},
|
},
|
||||||
// The to point.
|
// The to point.
|
||||||
to: [number, number],
|
to: [number, number],
|
||||||
|
},
|
||||||
|
// Tag identifiers that have been declared in this sketch group.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
@ -628,6 +637,9 @@ const example = extrude(10, exampleSketch)
|
|||||||
},
|
},
|
||||||
// The to point.
|
// The to point.
|
||||||
to: [number, number],
|
to: [number, number],
|
||||||
|
},
|
||||||
|
// Tag identifiers that have been declared in this sketch group.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
|
|||||||
@ -115,6 +115,9 @@ 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.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
@ -276,6 +279,9 @@ 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.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
@ -465,6 +471,9 @@ 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.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
@ -626,6 +635,9 @@ 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.
|
||||||
|
tags: {
|
||||||
},
|
},
|
||||||
// The paths in the sketch group.
|
// The paths in the sketch group.
|
||||||
value: [{
|
value: [{
|
||||||
|
|||||||
@ -52,24 +52,7 @@ const commonPoints = {
|
|||||||
// num2: 19.19,
|
// num2: 19.19,
|
||||||
}
|
}
|
||||||
|
|
||||||
test.afterEach(async ({ context, page }, testInfo) => {
|
// Utilities for writing tests that depend on test values
|
||||||
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 }) => {
|
test.beforeEach(async ({ context, page }) => {
|
||||||
// wait for Vite preview server to be up
|
// wait for Vite preview server to be up
|
||||||
@ -95,7 +78,7 @@ test.beforeEach(async ({ context, page }) => {
|
|||||||
await page.emulateMedia({ reducedMotion: 'reduce' })
|
await page.emulateMedia({ reducedMotion: 'reduce' })
|
||||||
})
|
})
|
||||||
|
|
||||||
test.setTimeout(120000)
|
test.setTimeout(60000)
|
||||||
|
|
||||||
async function doBasicSketch(page: Page, openPanes: string[]) {
|
async function doBasicSketch(page: Page, openPanes: string[]) {
|
||||||
const u = await getUtils(page)
|
const u = await getUtils(page)
|
||||||
@ -7151,6 +7134,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 }) => {
|
test('Successful export shows a success toast', async ({ page }) => {
|
||||||
// FYI this test doesn't work with only engine running locally
|
// FYI this test doesn't work with only engine running locally
|
||||||
// And you will need to have the KittyCAD CLI installed
|
// And you will need to have the KittyCAD CLI installed
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 42 KiB |
|
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 43 KiB |
|
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 49 KiB |
|
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 44 KiB |
|
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 35 KiB |
|
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 70 KiB After Width: | Height: | Size: 71 KiB |
|
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 43 KiB |
|
Before Width: | Height: | Size: 60 KiB After Width: | Height: | Size: 61 KiB |
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 31 KiB |
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 35 KiB |
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 29 KiB |
@ -312,9 +312,9 @@ export async function getUtils(page: Page) {
|
|||||||
fullPage: true,
|
fullPage: true,
|
||||||
})
|
})
|
||||||
const screenshot = await PNG.sync.read(buffer)
|
const screenshot = await PNG.sync.read(buffer)
|
||||||
const pixMultiplier: number = await page.evaluate(
|
// most likely related to pixel density but the screenshots for webkit are 2x the size
|
||||||
'window.devicePixelRatio'
|
// there might be a more robust way of doing this.
|
||||||
)
|
const pixMultiplier = browserType === 'webkit' ? 2 : 1
|
||||||
const index =
|
const index =
|
||||||
(screenshot.width * coords.y * pixMultiplier +
|
(screenshot.width * coords.y * pixMultiplier +
|
||||||
coords.x * pixMultiplier) *
|
coords.x * pixMultiplier) *
|
||||||
@ -377,10 +377,11 @@ export async function getUtils(page: Page) {
|
|||||||
emulateNetworkConditions: async (
|
emulateNetworkConditions: async (
|
||||||
networkOptions: Protocol.Network.emulateNetworkConditionsParameters
|
networkOptions: Protocol.Network.emulateNetworkConditionsParameters
|
||||||
) => {
|
) => {
|
||||||
if (cdpSession === null) {
|
// Skip on non-Chromium browsers, since we need to use the CDP.
|
||||||
// Use a fail safe if we can't simulate disconnect (on Safari)
|
test.skip(
|
||||||
return page.evaluate('window.tearDown()')
|
cdpSession === null,
|
||||||
}
|
'Network emulation is only supported in Chromium'
|
||||||
|
)
|
||||||
|
|
||||||
cdpSession?.send('Network.emulateNetworkConditions', networkOptions)
|
cdpSession?.send('Network.emulateNetworkConditions', networkOptions)
|
||||||
},
|
},
|
||||||
|
|||||||
6
src-tauri/Cargo.lock
generated
@ -2571,7 +2571,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "kcl-lib"
|
name = "kcl-lib"
|
||||||
version = "0.1.69"
|
version = "0.1.70"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"approx",
|
"approx",
|
||||||
@ -2628,9 +2628,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "kittycad"
|
name = "kittycad"
|
||||||
version = "0.3.6"
|
version = "0.3.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "af3de9bb4b1441f198689a9f64a8163a518377e30b348a784680e738985b95eb"
|
checksum = "e1777b503442fa4666564cc3ab237d456df853a09648a4b2bb09622d25d021a5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
|
|||||||
@ -16,7 +16,7 @@ tauri-build = { version = "2.0.0-beta.18", features = [] }
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow = "1"
|
anyhow = "1"
|
||||||
kcl-lib = { version = "0.1.53", path = "../src/wasm-lib/kcl" }
|
kcl-lib = { version = "0.1.53", path = "../src/wasm-lib/kcl" }
|
||||||
kittycad = "0.3.5"
|
kittycad = "0.3.7"
|
||||||
log = "0.4.21"
|
log = "0.4.21"
|
||||||
oauth2 = "4.4.2"
|
oauth2 = "4.4.2"
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
|
|||||||
@ -25,6 +25,7 @@ import ModalContainer from 'react-modal-promise'
|
|||||||
import useHotkeyWrapper from 'lib/hotkeyWrapper'
|
import useHotkeyWrapper from 'lib/hotkeyWrapper'
|
||||||
import Gizmo from 'components/Gizmo'
|
import Gizmo from 'components/Gizmo'
|
||||||
import { CoreDumpManager } from 'lib/coredump'
|
import { CoreDumpManager } from 'lib/coredump'
|
||||||
|
import { UnitsMenu } from 'components/UnitsMenu'
|
||||||
|
|
||||||
export function App() {
|
export function App() {
|
||||||
useRefreshSettings(paths.FILE + 'SETTINGS')
|
useRefreshSettings(paths.FILE + 'SETTINGS')
|
||||||
@ -127,6 +128,7 @@ export function App() {
|
|||||||
<Stream />
|
<Stream />
|
||||||
{/* <CamToggle /> */}
|
{/* <CamToggle /> */}
|
||||||
<LowerRightControls coreDumpManager={coreDumpManager}>
|
<LowerRightControls coreDumpManager={coreDumpManager}>
|
||||||
|
<UnitsMenu />
|
||||||
<Gizmo />
|
<Gizmo />
|
||||||
</LowerRightControls>
|
</LowerRightControls>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -19,7 +19,10 @@ import {
|
|||||||
PROFILE_START,
|
PROFILE_START,
|
||||||
getParentGroup,
|
getParentGroup,
|
||||||
} from './sceneEntities'
|
} from './sceneEntities'
|
||||||
import { SegmentOverlay, SketchDetails } from 'machines/modelingMachine'
|
import {
|
||||||
|
SegmentOverlay,
|
||||||
|
ModelingMachineContext as ModelingContextType,
|
||||||
|
} from 'machines/modelingMachine'
|
||||||
import { findUsesOfTagInPipe, getNodeFromPath } from 'lang/queryAst'
|
import { findUsesOfTagInPipe, getNodeFromPath } from 'lang/queryAst'
|
||||||
import {
|
import {
|
||||||
CallExpression,
|
CallExpression,
|
||||||
@ -353,11 +356,12 @@ export const confirmModal = create<ConfirmModalProps, boolean, boolean>(
|
|||||||
|
|
||||||
export async function deleteSegment({
|
export async function deleteSegment({
|
||||||
pathToNode,
|
pathToNode,
|
||||||
sketchDetails,
|
context,
|
||||||
}: {
|
}: {
|
||||||
pathToNode: PathToNode
|
pathToNode: PathToNode
|
||||||
sketchDetails: SketchDetails | null
|
context: ModelingContextType
|
||||||
}) {
|
}) {
|
||||||
|
const { sketchDetails } = context
|
||||||
let modifiedAst: Program | Error = kclManager.ast
|
let modifiedAst: Program | Error = kclManager.ast
|
||||||
const dependentRanges = findUsesOfTagInPipe(modifiedAst, pathToNode)
|
const dependentRanges = findUsesOfTagInPipe(modifiedAst, pathToNode)
|
||||||
|
|
||||||
@ -394,13 +398,7 @@ export async function deleteSegment({
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!sketchDetails) return
|
if (!sketchDetails) return
|
||||||
await sceneEntitiesManager.updateAstAndRejigSketch(
|
await sceneEntitiesManager.updateAstAndRejigSketch(modifiedAst, context)
|
||||||
pathToNode,
|
|
||||||
modifiedAst,
|
|
||||||
sketchDetails.zAxis,
|
|
||||||
sketchDetails.yAxis,
|
|
||||||
sketchDetails.origin
|
|
||||||
)
|
|
||||||
|
|
||||||
// Now 'Set sketchDetails' is called with the modified pathToNode
|
// Now 'Set sketchDetails' is called with the modified pathToNode
|
||||||
}
|
}
|
||||||
|
|||||||
362
src/clientSideScene/sceneCallbacks.ts
Normal file
@ -0,0 +1,362 @@
|
|||||||
|
import { getEventForSegmentSelection } from 'lib/selections'
|
||||||
|
import {
|
||||||
|
editorManager,
|
||||||
|
kclManager,
|
||||||
|
sceneEntitiesManager,
|
||||||
|
sceneInfra,
|
||||||
|
} from 'lib/singletons'
|
||||||
|
import {
|
||||||
|
Intersection,
|
||||||
|
Mesh,
|
||||||
|
MeshBasicMaterial,
|
||||||
|
Object3D,
|
||||||
|
Object3DEventMap,
|
||||||
|
OrthographicCamera,
|
||||||
|
Points,
|
||||||
|
Vector2,
|
||||||
|
Vector3,
|
||||||
|
} from 'three'
|
||||||
|
import {
|
||||||
|
EXTRA_SEGMENT_HANDLE,
|
||||||
|
PROFILE_START,
|
||||||
|
STRAIGHT_SEGMENT,
|
||||||
|
TANGENTIAL_ARC_TO_SEGMENT,
|
||||||
|
getParentGroup,
|
||||||
|
sketchGroupFromPathToNode,
|
||||||
|
} from './sceneEntities'
|
||||||
|
import { trap } from 'lib/trap'
|
||||||
|
import { addNewSketchLn } from 'lang/std/sketch'
|
||||||
|
import { CallExpression, PathToNode, parse, recast } from 'lang/wasm'
|
||||||
|
import { ARROWHEAD, X_AXIS, Y_AXIS } from './sceneInfra'
|
||||||
|
import { getNodeFromPath } from 'lang/queryAst'
|
||||||
|
import { getThemeColorForThreeJs } from 'lib/theme'
|
||||||
|
import { orthoScale, perspScale, quaternionFromUpNForward } from './helpers'
|
||||||
|
import { ModelingMachineContext } from 'machines/modelingMachine'
|
||||||
|
import { addStartProfileAt } from 'lang/modifyAst'
|
||||||
|
|
||||||
|
export interface OnMouseEnterLeaveArgs {
|
||||||
|
selected: Object3D<Object3DEventMap>
|
||||||
|
dragSelected?: Object3D<Object3DEventMap>
|
||||||
|
mouseEvent: MouseEvent
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface OnDragCallbackArgs extends OnMouseEnterLeaveArgs {
|
||||||
|
intersectionPoint: {
|
||||||
|
twoD: Vector2
|
||||||
|
threeD: Vector3
|
||||||
|
}
|
||||||
|
intersects: Intersection<Object3D<Object3DEventMap>>[]
|
||||||
|
}
|
||||||
|
export interface OnClickCallbackArgs {
|
||||||
|
mouseEvent: MouseEvent
|
||||||
|
intersectionPoint?: {
|
||||||
|
twoD: Vector2
|
||||||
|
threeD: Vector3
|
||||||
|
}
|
||||||
|
intersects: Intersection<Object3D<Object3DEventMap>>[]
|
||||||
|
selected?: Object3D<Object3DEventMap>
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface OnMoveCallbackArgs {
|
||||||
|
mouseEvent: MouseEvent
|
||||||
|
intersectionPoint: {
|
||||||
|
twoD: Vector2
|
||||||
|
threeD: Vector3
|
||||||
|
}
|
||||||
|
intersects: Intersection<Object3D<Object3DEventMap>>[]
|
||||||
|
selected?: Object3D<Object3DEventMap>
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Callbacks {
|
||||||
|
onDragStart: (arg: OnDragCallbackArgs) => void
|
||||||
|
onDragEnd: (arg: OnDragCallbackArgs) => void
|
||||||
|
onDrag: (arg: OnDragCallbackArgs) => void
|
||||||
|
onMove: (arg: OnMoveCallbackArgs) => void
|
||||||
|
onClick: (arg: OnClickCallbackArgs) => void
|
||||||
|
onMouseEnter: (arg: OnMouseEnterLeaveArgs) => void
|
||||||
|
onMouseLeave: (arg: OnMouseEnterLeaveArgs) => void
|
||||||
|
}
|
||||||
|
|
||||||
|
type SetCallbacksWithCtx = (context: ModelingMachineContext) => Callbacks
|
||||||
|
|
||||||
|
const dummyListenersAll: Callbacks = {
|
||||||
|
onDragStart: () => {},
|
||||||
|
onDragEnd: () => {},
|
||||||
|
onDrag: () => {},
|
||||||
|
onMove: () => {},
|
||||||
|
onClick: () => {},
|
||||||
|
onMouseEnter: () => {},
|
||||||
|
onMouseLeave: () => {},
|
||||||
|
}
|
||||||
|
|
||||||
|
const onMousEnterLeaveCallbacks = {
|
||||||
|
onMouseEnter: ({ selected, dragSelected }: OnMouseEnterLeaveArgs) => {
|
||||||
|
if ([X_AXIS, Y_AXIS].includes(selected?.userData?.type)) {
|
||||||
|
const obj = selected as Mesh
|
||||||
|
const mat = obj.material as MeshBasicMaterial
|
||||||
|
mat.color.set(obj.userData.baseColor)
|
||||||
|
mat.color.offsetHSL(0, 0, 0.5)
|
||||||
|
}
|
||||||
|
const parent = getParentGroup(selected, [
|
||||||
|
STRAIGHT_SEGMENT,
|
||||||
|
TANGENTIAL_ARC_TO_SEGMENT,
|
||||||
|
PROFILE_START,
|
||||||
|
])
|
||||||
|
if (parent?.userData?.pathToNode) {
|
||||||
|
const updatedAst = parse(recast(kclManager.ast))
|
||||||
|
if (trap(updatedAst)) return
|
||||||
|
const _node = getNodeFromPath<CallExpression>(
|
||||||
|
updatedAst,
|
||||||
|
parent.userData.pathToNode,
|
||||||
|
'CallExpression'
|
||||||
|
)
|
||||||
|
if (trap(_node, { suppress: true })) return
|
||||||
|
const node = _node.node
|
||||||
|
editorManager.setHighlightRange([node.start, node.end])
|
||||||
|
const yellow = 0xffff00
|
||||||
|
colorSegment(selected, yellow)
|
||||||
|
const extraSegmentGroup = parent.getObjectByName(EXTRA_SEGMENT_HANDLE)
|
||||||
|
if (extraSegmentGroup) {
|
||||||
|
extraSegmentGroup.traverse((child) => {
|
||||||
|
if (child instanceof Points || child instanceof Mesh) {
|
||||||
|
child.material.opacity = dragSelected ? 0 : 1
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
const orthoFactor = orthoScale(sceneInfra.camControls.camera)
|
||||||
|
|
||||||
|
const factor =
|
||||||
|
(sceneInfra.camControls.camera instanceof OrthographicCamera
|
||||||
|
? orthoFactor
|
||||||
|
: perspScale(sceneInfra.camControls.camera, parent)) /
|
||||||
|
sceneInfra._baseUnitMultiplier
|
||||||
|
if (parent.name === STRAIGHT_SEGMENT) {
|
||||||
|
sceneEntitiesManager.updateStraightSegment({
|
||||||
|
from: parent.userData.from,
|
||||||
|
to: parent.userData.to,
|
||||||
|
group: parent,
|
||||||
|
scale: factor,
|
||||||
|
})
|
||||||
|
} else if (parent.name === TANGENTIAL_ARC_TO_SEGMENT) {
|
||||||
|
sceneEntitiesManager.updateTangentialArcToSegment({
|
||||||
|
prevSegment: parent.userData.prevSegment,
|
||||||
|
from: parent.userData.from,
|
||||||
|
to: parent.userData.to,
|
||||||
|
group: parent,
|
||||||
|
scale: factor,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
editorManager.setHighlightRange([0, 0])
|
||||||
|
},
|
||||||
|
onMouseLeave: ({ selected, ...rest }: OnMouseEnterLeaveArgs) => {
|
||||||
|
editorManager.setHighlightRange([0, 0])
|
||||||
|
const parent = getParentGroup(selected, [
|
||||||
|
STRAIGHT_SEGMENT,
|
||||||
|
TANGENTIAL_ARC_TO_SEGMENT,
|
||||||
|
PROFILE_START,
|
||||||
|
])
|
||||||
|
if (parent) {
|
||||||
|
const orthoFactor = orthoScale(sceneInfra.camControls.camera)
|
||||||
|
|
||||||
|
const factor =
|
||||||
|
(sceneInfra.camControls.camera instanceof OrthographicCamera
|
||||||
|
? orthoFactor
|
||||||
|
: perspScale(sceneInfra.camControls.camera, parent)) /
|
||||||
|
sceneInfra._baseUnitMultiplier
|
||||||
|
if (parent.name === STRAIGHT_SEGMENT) {
|
||||||
|
sceneEntitiesManager.updateStraightSegment({
|
||||||
|
from: parent.userData.from,
|
||||||
|
to: parent.userData.to,
|
||||||
|
group: parent,
|
||||||
|
scale: factor,
|
||||||
|
})
|
||||||
|
} else if (parent.name === TANGENTIAL_ARC_TO_SEGMENT) {
|
||||||
|
sceneEntitiesManager.updateTangentialArcToSegment({
|
||||||
|
prevSegment: parent.userData.prevSegment,
|
||||||
|
from: parent.userData.from,
|
||||||
|
to: parent.userData.to,
|
||||||
|
group: parent,
|
||||||
|
scale: factor,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const isSelected = parent?.userData?.isSelected
|
||||||
|
colorSegment(
|
||||||
|
selected,
|
||||||
|
isSelected
|
||||||
|
? 0x0000ff
|
||||||
|
: parent?.userData?.baseColor ||
|
||||||
|
getThemeColorForThreeJs(sceneInfra._theme)
|
||||||
|
)
|
||||||
|
const extraSegmentGroup = parent?.getObjectByName(EXTRA_SEGMENT_HANDLE)
|
||||||
|
if (extraSegmentGroup) {
|
||||||
|
extraSegmentGroup.traverse((child) => {
|
||||||
|
if (child instanceof Points || child instanceof Mesh) {
|
||||||
|
child.material.opacity = 0
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if ([X_AXIS, Y_AXIS].includes(selected?.userData?.type)) {
|
||||||
|
const obj = selected as Mesh
|
||||||
|
const mat = obj.material as MeshBasicMaterial
|
||||||
|
mat.color.set(obj.userData.baseColor)
|
||||||
|
if (obj.userData.isSelected) mat.color.offsetHSL(0, 0, 0.2)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
} as const
|
||||||
|
|
||||||
|
export const idleCallbacks: SetCallbacksWithCtx = (context) => {
|
||||||
|
let addingNewSegmentStatus: 'nothing' | 'pending' | 'added' = 'nothing'
|
||||||
|
return {
|
||||||
|
onDragStart: () => {},
|
||||||
|
onDragEnd: () => {},
|
||||||
|
onMove: () => {},
|
||||||
|
...onMousEnterLeaveCallbacks,
|
||||||
|
onClick: (args) => {
|
||||||
|
if (args?.mouseEvent.which !== 1) return
|
||||||
|
if (!args || !args.selected) {
|
||||||
|
sceneInfra.modelingSend({
|
||||||
|
type: 'Set selection',
|
||||||
|
data: {
|
||||||
|
selectionType: 'singleCodeCursor',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const { selected } = args
|
||||||
|
const event = getEventForSegmentSelection(selected)
|
||||||
|
if (!event) return
|
||||||
|
sceneInfra.modelingSend(event)
|
||||||
|
},
|
||||||
|
onDrag: async ({ selected, intersectionPoint, mouseEvent, intersects }) => {
|
||||||
|
if (mouseEvent.which !== 1) return
|
||||||
|
|
||||||
|
const group = getParentGroup(selected, [EXTRA_SEGMENT_HANDLE])
|
||||||
|
if (group?.name === EXTRA_SEGMENT_HANDLE) {
|
||||||
|
const segGroup = getParentGroup(selected)
|
||||||
|
const pathToNode: PathToNode = segGroup?.userData?.pathToNode
|
||||||
|
const pathToNodeIndex = pathToNode.findIndex(
|
||||||
|
(x) => x[1] === 'PipeExpression'
|
||||||
|
)
|
||||||
|
|
||||||
|
const sketchGroup = sketchGroupFromPathToNode({
|
||||||
|
pathToNode,
|
||||||
|
ast: kclManager.ast,
|
||||||
|
programMemory: kclManager.programMemory,
|
||||||
|
})
|
||||||
|
if (trap(sketchGroup)) return
|
||||||
|
|
||||||
|
const pipeIndex = pathToNode[pathToNodeIndex + 1][0] as number
|
||||||
|
if (addingNewSegmentStatus === 'nothing') {
|
||||||
|
const prevSegment = sketchGroup.value[pipeIndex - 2]
|
||||||
|
const mod = addNewSketchLn({
|
||||||
|
node: kclManager.ast,
|
||||||
|
programMemory: kclManager.programMemory,
|
||||||
|
to: [intersectionPoint.twoD.x, intersectionPoint.twoD.y],
|
||||||
|
from: [prevSegment.from[0], prevSegment.from[1]],
|
||||||
|
// TODO assuming it's always a straight segments being added
|
||||||
|
// as this is easiest, and we'll need to add "tabbing" behavior
|
||||||
|
// to support other segment types
|
||||||
|
fnName: 'line',
|
||||||
|
pathToNode: pathToNode,
|
||||||
|
spliceBetween: true,
|
||||||
|
})
|
||||||
|
addingNewSegmentStatus = 'pending'
|
||||||
|
if (trap(mod)) return
|
||||||
|
|
||||||
|
await kclManager.executeAstMock(mod.modifiedAst)
|
||||||
|
await sceneEntitiesManager.tearDownSketch({ removeAxis: false })
|
||||||
|
sceneEntitiesManager.setupSketch({
|
||||||
|
sketchPathToNode: pathToNode,
|
||||||
|
maybeModdedAst: kclManager.ast,
|
||||||
|
up: context.sketchDetails?.yAxis || [0, 1, 0],
|
||||||
|
forward: context.sketchDetails?.zAxis || [0, 0, 1],
|
||||||
|
position: context.sketchDetails?.origin || [0, 0, 0],
|
||||||
|
})
|
||||||
|
addingNewSegmentStatus = 'added'
|
||||||
|
} else if (addingNewSegmentStatus === 'added') {
|
||||||
|
const pathToNodeForNewSegment = pathToNode.slice(0, pathToNodeIndex)
|
||||||
|
pathToNodeForNewSegment.push([pipeIndex - 2, 'index'])
|
||||||
|
sceneEntitiesManager.onDragSegment({
|
||||||
|
sketchPathToNode: pathToNodeForNewSegment,
|
||||||
|
object: selected,
|
||||||
|
intersection2d: intersectionPoint.twoD,
|
||||||
|
intersects,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
sceneEntitiesManager.onDragSegment({
|
||||||
|
object: selected,
|
||||||
|
intersection2d: intersectionPoint.twoD,
|
||||||
|
intersects,
|
||||||
|
sketchPathToNode: context.sketchDetails?.sketchPathToNode || [],
|
||||||
|
})
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const Sketch_LineTool_NoPoints: SetCallbacksWithCtx = ({
|
||||||
|
sketchDetails,
|
||||||
|
}) => {
|
||||||
|
if (!sketchDetails) return dummyListenersAll
|
||||||
|
sceneEntitiesManager.createIntersectionPlane()
|
||||||
|
const quaternion = quaternionFromUpNForward(
|
||||||
|
new Vector3(...sketchDetails.yAxis),
|
||||||
|
new Vector3(...sketchDetails.zAxis)
|
||||||
|
)
|
||||||
|
sceneEntitiesManager.intersectionPlane &&
|
||||||
|
sceneEntitiesManager.intersectionPlane.setRotationFromQuaternion(quaternion)
|
||||||
|
sceneEntitiesManager.intersectionPlane &&
|
||||||
|
sceneEntitiesManager.intersectionPlane.position.copy(
|
||||||
|
new Vector3(...(sketchDetails?.origin || [0, 0, 0]))
|
||||||
|
)
|
||||||
|
return {
|
||||||
|
...dummyListenersAll,
|
||||||
|
onClick: async (args) => {
|
||||||
|
if (!args) return
|
||||||
|
if (args.mouseEvent.which !== 1) return
|
||||||
|
const { intersectionPoint } = args
|
||||||
|
if (!intersectionPoint?.twoD || !sketchDetails?.sketchPathToNode) return
|
||||||
|
const addStartProfileAtRes = addStartProfileAt(
|
||||||
|
kclManager.ast,
|
||||||
|
sketchDetails.sketchPathToNode,
|
||||||
|
[intersectionPoint.twoD.x, intersectionPoint.twoD.y]
|
||||||
|
)
|
||||||
|
|
||||||
|
if (trap(addStartProfileAtRes)) return
|
||||||
|
const { modifiedAst } = addStartProfileAtRes
|
||||||
|
|
||||||
|
await kclManager.updateAst(modifiedAst, false)
|
||||||
|
sceneEntitiesManager.removeIntersectionPlane()
|
||||||
|
sceneInfra.modelingSend('Add start point')
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function colorSegment(object: any, color: number) {
|
||||||
|
const segmentHead = getParentGroup(object, [ARROWHEAD, PROFILE_START])
|
||||||
|
if (segmentHead) {
|
||||||
|
segmentHead.traverse((child) => {
|
||||||
|
if (child instanceof Mesh) {
|
||||||
|
child.material.color.set(color)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const straightSegmentBody = getParentGroup(object, [
|
||||||
|
STRAIGHT_SEGMENT,
|
||||||
|
TANGENTIAL_ARC_TO_SEGMENT,
|
||||||
|
])
|
||||||
|
if (straightSegmentBody) {
|
||||||
|
straightSegmentBody.traverse((child) => {
|
||||||
|
if (child instanceof Mesh && !child.userData.ignoreColorChange) {
|
||||||
|
child.material.color.set(color)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -22,12 +22,8 @@ import {
|
|||||||
import {
|
import {
|
||||||
ARROWHEAD,
|
ARROWHEAD,
|
||||||
AXIS_GROUP,
|
AXIS_GROUP,
|
||||||
DEFAULT_PLANES,
|
|
||||||
DefaultPlane,
|
|
||||||
defaultPlaneColor,
|
|
||||||
getSceneScale,
|
getSceneScale,
|
||||||
INTERSECTION_PLANE_LAYER,
|
INTERSECTION_PLANE_LAYER,
|
||||||
OnMouseEnterLeaveArgs,
|
|
||||||
RAYCASTABLE_PLANE,
|
RAYCASTABLE_PLANE,
|
||||||
SKETCH_GROUP_SEGMENTS,
|
SKETCH_GROUP_SEGMENTS,
|
||||||
SKETCH_LAYER,
|
SKETCH_LAYER,
|
||||||
@ -82,16 +78,16 @@ import {
|
|||||||
createPipeSubstitution,
|
createPipeSubstitution,
|
||||||
findUniqueName,
|
findUniqueName,
|
||||||
} from 'lang/modifyAst'
|
} from 'lang/modifyAst'
|
||||||
import {
|
import { Selections, sendSelectEventToEngine } from 'lib/selections'
|
||||||
Selections,
|
|
||||||
getEventForSegmentSelection,
|
|
||||||
sendSelectEventToEngine,
|
|
||||||
} from 'lib/selections'
|
|
||||||
import { getTangentPointFromPreviousArc } from 'lib/utils2d'
|
import { getTangentPointFromPreviousArc } from 'lib/utils2d'
|
||||||
import { createGridHelper, orthoScale, perspScale } from './helpers'
|
import { createGridHelper, orthoScale, perspScale } from './helpers'
|
||||||
import { Models } from '@kittycad/lib'
|
import { Models } from '@kittycad/lib'
|
||||||
import { uuidv4 } from 'lib/utils'
|
import { uuidv4 } from 'lib/utils'
|
||||||
import { SegmentOverlayPayload, SketchDetails } from 'machines/modelingMachine'
|
import {
|
||||||
|
SegmentOverlayPayload,
|
||||||
|
SketchDetails,
|
||||||
|
ModelingMachineContext,
|
||||||
|
} from 'machines/modelingMachine'
|
||||||
import {
|
import {
|
||||||
ArtifactMapCommand,
|
ArtifactMapCommand,
|
||||||
EngineCommandManager,
|
EngineCommandManager,
|
||||||
@ -102,6 +98,7 @@ import {
|
|||||||
} from 'lib/rectangleTool'
|
} from 'lib/rectangleTool'
|
||||||
import { getThemeColorForThreeJs } from 'lib/theme'
|
import { getThemeColorForThreeJs } from 'lib/theme'
|
||||||
import { err, trap } from 'lib/trap'
|
import { err, trap } from 'lib/trap'
|
||||||
|
import { OnMouseEnterLeaveArgs, idleCallbacks } from './sceneCallbacks'
|
||||||
|
|
||||||
type DraftSegment = 'line' | 'tangentialArcTo'
|
type DraftSegment = 'line' | 'tangentialArcTo'
|
||||||
|
|
||||||
@ -499,31 +496,23 @@ export class SceneEntities {
|
|||||||
variableDeclarationName,
|
variableDeclarationName,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
updateAstAndRejigSketch = async (
|
updateAstAndRejigSketch: (
|
||||||
sketchPathToNode: PathToNode,
|
|
||||||
modifiedAst: Program | Error,
|
modifiedAst: Program | Error,
|
||||||
forward: [number, number, number],
|
context: ModelingMachineContext
|
||||||
up: [number, number, number],
|
) => Promise<any> = async (modifiedAst, context) => {
|
||||||
origin: [number, number, number]
|
|
||||||
) => {
|
|
||||||
if (err(modifiedAst)) return modifiedAst
|
if (err(modifiedAst)) return modifiedAst
|
||||||
|
|
||||||
const nextAst = await kclManager.updateAst(modifiedAst, false)
|
const nextAst = await kclManager.updateAst(modifiedAst, false)
|
||||||
await this.tearDownSketch({ removeAxis: false })
|
await this.tearDownSketch({ removeAxis: false })
|
||||||
sceneInfra.resetMouseListeners()
|
sceneInfra.resetMouseListeners()
|
||||||
await this.setupSketch({
|
await this.setupSketch({
|
||||||
sketchPathToNode,
|
sketchPathToNode: context.sketchDetails?.sketchPathToNode || [],
|
||||||
forward,
|
forward: context.sketchDetails?.zAxis || [0, 0, 1],
|
||||||
up,
|
up: context.sketchDetails?.yAxis || [0, 1, 0],
|
||||||
position: origin,
|
position: context.sketchDetails?.origin || [0, 0, 0],
|
||||||
maybeModdedAst: nextAst.newAst,
|
maybeModdedAst: nextAst.newAst,
|
||||||
})
|
})
|
||||||
this.setupSketchIdleCallbacks({
|
this.setupSketchIdleCallbacks(context)
|
||||||
forward,
|
|
||||||
up,
|
|
||||||
position: origin,
|
|
||||||
pathToNode: sketchPathToNode,
|
|
||||||
})
|
|
||||||
return nextAst
|
return nextAst
|
||||||
}
|
}
|
||||||
setUpDraftSegment = async (
|
setUpDraftSegment = async (
|
||||||
@ -838,128 +827,8 @@ export class SceneEntities {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
setupSketchIdleCallbacks = ({
|
setupSketchIdleCallbacks = (context: ModelingMachineContext) => {
|
||||||
pathToNode,
|
sceneInfra.setCallbacks(idleCallbacks(context))
|
||||||
up,
|
|
||||||
forward,
|
|
||||||
position,
|
|
||||||
}: {
|
|
||||||
pathToNode: PathToNode
|
|
||||||
forward: [number, number, number]
|
|
||||||
up: [number, number, number]
|
|
||||||
position?: [number, number, number]
|
|
||||||
}) => {
|
|
||||||
let addingNewSegmentStatus: 'nothing' | 'pending' | 'added' = 'nothing'
|
|
||||||
sceneInfra.setCallbacks({
|
|
||||||
onDragEnd: async () => {
|
|
||||||
if (addingNewSegmentStatus !== 'nothing') {
|
|
||||||
await this.tearDownSketch({ removeAxis: false })
|
|
||||||
this.setupSketch({
|
|
||||||
sketchPathToNode: pathToNode,
|
|
||||||
maybeModdedAst: kclManager.ast,
|
|
||||||
up,
|
|
||||||
forward,
|
|
||||||
position,
|
|
||||||
})
|
|
||||||
// setting up the callbacks again resets value in closures
|
|
||||||
this.setupSketchIdleCallbacks({
|
|
||||||
pathToNode,
|
|
||||||
up,
|
|
||||||
forward,
|
|
||||||
position,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onDrag: async ({
|
|
||||||
selected,
|
|
||||||
intersectionPoint,
|
|
||||||
mouseEvent,
|
|
||||||
intersects,
|
|
||||||
}) => {
|
|
||||||
if (mouseEvent.which !== 1) return
|
|
||||||
|
|
||||||
const group = getParentGroup(selected, [EXTRA_SEGMENT_HANDLE])
|
|
||||||
if (group?.name === EXTRA_SEGMENT_HANDLE) {
|
|
||||||
const segGroup = getParentGroup(selected)
|
|
||||||
const pathToNode: PathToNode = segGroup?.userData?.pathToNode
|
|
||||||
const pathToNodeIndex = pathToNode.findIndex(
|
|
||||||
(x) => x[1] === 'PipeExpression'
|
|
||||||
)
|
|
||||||
|
|
||||||
const sketchGroup = sketchGroupFromPathToNode({
|
|
||||||
pathToNode,
|
|
||||||
ast: kclManager.ast,
|
|
||||||
programMemory: kclManager.programMemory,
|
|
||||||
})
|
|
||||||
if (trap(sketchGroup)) return
|
|
||||||
|
|
||||||
const pipeIndex = pathToNode[pathToNodeIndex + 1][0] as number
|
|
||||||
if (addingNewSegmentStatus === 'nothing') {
|
|
||||||
const prevSegment = sketchGroup.value[pipeIndex - 2]
|
|
||||||
const mod = addNewSketchLn({
|
|
||||||
node: kclManager.ast,
|
|
||||||
programMemory: kclManager.programMemory,
|
|
||||||
to: [intersectionPoint.twoD.x, intersectionPoint.twoD.y],
|
|
||||||
from: [prevSegment.from[0], prevSegment.from[1]],
|
|
||||||
// TODO assuming it's always a straight segments being added
|
|
||||||
// as this is easiest, and we'll need to add "tabbing" behavior
|
|
||||||
// to support other segment types
|
|
||||||
fnName: 'line',
|
|
||||||
pathToNode: pathToNode,
|
|
||||||
spliceBetween: true,
|
|
||||||
})
|
|
||||||
addingNewSegmentStatus = 'pending'
|
|
||||||
if (trap(mod)) return
|
|
||||||
|
|
||||||
await kclManager.executeAstMock(mod.modifiedAst)
|
|
||||||
await this.tearDownSketch({ removeAxis: false })
|
|
||||||
this.setupSketch({
|
|
||||||
sketchPathToNode: pathToNode,
|
|
||||||
maybeModdedAst: kclManager.ast,
|
|
||||||
up,
|
|
||||||
forward,
|
|
||||||
position,
|
|
||||||
})
|
|
||||||
addingNewSegmentStatus = 'added'
|
|
||||||
} else if (addingNewSegmentStatus === 'added') {
|
|
||||||
const pathToNodeForNewSegment = pathToNode.slice(0, pathToNodeIndex)
|
|
||||||
pathToNodeForNewSegment.push([pipeIndex - 2, 'index'])
|
|
||||||
this.onDragSegment({
|
|
||||||
sketchPathToNode: pathToNodeForNewSegment,
|
|
||||||
object: selected,
|
|
||||||
intersection2d: intersectionPoint.twoD,
|
|
||||||
intersects,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
this.onDragSegment({
|
|
||||||
object: selected,
|
|
||||||
intersection2d: intersectionPoint.twoD,
|
|
||||||
intersects,
|
|
||||||
sketchPathToNode: pathToNode,
|
|
||||||
})
|
|
||||||
},
|
|
||||||
onMove: () => {},
|
|
||||||
onClick: (args) => {
|
|
||||||
if (args?.mouseEvent.which !== 1) return
|
|
||||||
if (!args || !args.selected) {
|
|
||||||
sceneInfra.modelingSend({
|
|
||||||
type: 'Set selection',
|
|
||||||
data: {
|
|
||||||
selectionType: 'singleCodeCursor',
|
|
||||||
},
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
const { selected } = args
|
|
||||||
const event = getEventForSegmentSelection(selected)
|
|
||||||
if (!event) return
|
|
||||||
sceneInfra.modelingSend(event)
|
|
||||||
},
|
|
||||||
...this.mouseEnterLeaveCallbacks(),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
prepareTruncatedMemoryAndAst = (
|
prepareTruncatedMemoryAndAst = (
|
||||||
sketchPathToNode: PathToNode,
|
sketchPathToNode: PathToNode,
|
||||||
@ -1429,150 +1298,6 @@ export class SceneEntities {
|
|||||||
this._tearDownSketch(0, resolve, reject, { removeAxis })
|
this._tearDownSketch(0, resolve, reject, { removeAxis })
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
setupDefaultPlaneHover() {
|
|
||||||
sceneInfra.setCallbacks({
|
|
||||||
onMouseEnter: ({ selected }) => {
|
|
||||||
if (!(selected instanceof Mesh && selected.parent)) return
|
|
||||||
if (selected.parent.userData.type !== DEFAULT_PLANES) return
|
|
||||||
const type: DefaultPlane = selected.userData.type
|
|
||||||
selected.material.color = defaultPlaneColor(type, 0.5, 1)
|
|
||||||
},
|
|
||||||
onMouseLeave: ({ selected }) => {
|
|
||||||
if (!(selected instanceof Mesh && selected.parent)) return
|
|
||||||
if (selected.parent.userData.type !== DEFAULT_PLANES) return
|
|
||||||
const type: DefaultPlane = selected.userData.type
|
|
||||||
selected.material.color = defaultPlaneColor(type)
|
|
||||||
},
|
|
||||||
onClick: async (args) => {
|
|
||||||
const { entity_id } = await sendSelectEventToEngine(
|
|
||||||
args?.mouseEvent,
|
|
||||||
document.getElementById('video-stream') as HTMLVideoElement,
|
|
||||||
sceneInfra._streamDimensions
|
|
||||||
)
|
|
||||||
|
|
||||||
let _entity_id = entity_id
|
|
||||||
if (!_entity_id) return
|
|
||||||
if (
|
|
||||||
engineCommandManager.defaultPlanes?.xy === _entity_id ||
|
|
||||||
engineCommandManager.defaultPlanes?.xz === _entity_id ||
|
|
||||||
engineCommandManager.defaultPlanes?.yz === _entity_id ||
|
|
||||||
engineCommandManager.defaultPlanes?.negXy === _entity_id ||
|
|
||||||
engineCommandManager.defaultPlanes?.negXz === _entity_id ||
|
|
||||||
engineCommandManager.defaultPlanes?.negYz === _entity_id
|
|
||||||
) {
|
|
||||||
const defaultPlaneStrMap: Record<string, DefaultPlaneStr> = {
|
|
||||||
[engineCommandManager.defaultPlanes.xy]: 'XY',
|
|
||||||
[engineCommandManager.defaultPlanes.xz]: 'XZ',
|
|
||||||
[engineCommandManager.defaultPlanes.yz]: 'YZ',
|
|
||||||
[engineCommandManager.defaultPlanes.negXy]: '-XY',
|
|
||||||
[engineCommandManager.defaultPlanes.negXz]: '-XZ',
|
|
||||||
[engineCommandManager.defaultPlanes.negYz]: '-YZ',
|
|
||||||
}
|
|
||||||
// TODO can we get this information from rust land when it creates the default planes?
|
|
||||||
// maybe returned from make_default_planes (src/wasm-lib/src/wasm.rs)
|
|
||||||
let zAxis: [number, number, number] = [0, 0, 1]
|
|
||||||
let yAxis: [number, number, number] = [0, 1, 0]
|
|
||||||
|
|
||||||
// get unit vector from camera position to target
|
|
||||||
const camVector = sceneInfra.camControls.camera.position
|
|
||||||
.clone()
|
|
||||||
.sub(sceneInfra.camControls.target)
|
|
||||||
|
|
||||||
if (engineCommandManager.defaultPlanes?.xy === _entity_id) {
|
|
||||||
zAxis = [0, 0, 1]
|
|
||||||
yAxis = [0, 1, 0]
|
|
||||||
if (camVector.z < 0) {
|
|
||||||
zAxis = [0, 0, -1]
|
|
||||||
_entity_id = engineCommandManager.defaultPlanes?.negXy || ''
|
|
||||||
}
|
|
||||||
} else if (engineCommandManager.defaultPlanes?.yz === _entity_id) {
|
|
||||||
zAxis = [1, 0, 0]
|
|
||||||
yAxis = [0, 0, 1]
|
|
||||||
if (camVector.x < 0) {
|
|
||||||
zAxis = [-1, 0, 0]
|
|
||||||
_entity_id = engineCommandManager.defaultPlanes?.negYz || ''
|
|
||||||
}
|
|
||||||
} else if (engineCommandManager.defaultPlanes?.xz === _entity_id) {
|
|
||||||
zAxis = [0, 1, 0]
|
|
||||||
yAxis = [0, 0, 1]
|
|
||||||
_entity_id = engineCommandManager.defaultPlanes?.negXz || ''
|
|
||||||
if (camVector.y < 0) {
|
|
||||||
zAxis = [0, -1, 0]
|
|
||||||
_entity_id = engineCommandManager.defaultPlanes?.xz || ''
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sceneInfra.modelingSend({
|
|
||||||
type: 'Select default plane',
|
|
||||||
data: {
|
|
||||||
type: 'defaultPlane',
|
|
||||||
planeId: _entity_id,
|
|
||||||
plane: defaultPlaneStrMap[_entity_id],
|
|
||||||
zAxis,
|
|
||||||
yAxis,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
const artifact = this.engineCommandManager.artifactMap[_entity_id]
|
|
||||||
// If we clicked on an extrude wall, we climb up the parent Id
|
|
||||||
// to get the sketch profile's face ID. If we clicked on an endcap,
|
|
||||||
// we already have it.
|
|
||||||
const targetId =
|
|
||||||
'additionalData' in artifact &&
|
|
||||||
artifact.additionalData?.type === 'cap'
|
|
||||||
? _entity_id
|
|
||||||
: artifact.parentId
|
|
||||||
|
|
||||||
// tsc cannot infer that target can have extrusions
|
|
||||||
// from the commandType (why?) so we need to cast it
|
|
||||||
const target = this.engineCommandManager.artifactMap?.[
|
|
||||||
targetId || ''
|
|
||||||
] as ArtifactMapCommand & { extrusions?: string[] }
|
|
||||||
|
|
||||||
// TODO: We get the first extrusion command ID,
|
|
||||||
// which is fine while backend systems only support one extrusion.
|
|
||||||
// but we need to more robustly handle resolving to the correct extrusion
|
|
||||||
// if there are multiple.
|
|
||||||
const extrusions =
|
|
||||||
this.engineCommandManager.artifactMap?.[target?.extrusions?.[0] || '']
|
|
||||||
|
|
||||||
if (artifact?.commandType !== 'solid3d_get_extrusion_face_info') return
|
|
||||||
|
|
||||||
const faceInfo = await getFaceDetails(_entity_id)
|
|
||||||
if (!faceInfo?.origin || !faceInfo?.z_axis || !faceInfo?.y_axis) return
|
|
||||||
const { z_axis, y_axis, origin } = faceInfo
|
|
||||||
const sketchPathToNode = getNodePathFromSourceRange(
|
|
||||||
kclManager.ast,
|
|
||||||
artifact.range
|
|
||||||
)
|
|
||||||
|
|
||||||
const extrudePathToNode = extrusions?.range
|
|
||||||
? getNodePathFromSourceRange(kclManager.ast, extrusions.range)
|
|
||||||
: []
|
|
||||||
|
|
||||||
sceneInfra.modelingSend({
|
|
||||||
type: 'Select default plane',
|
|
||||||
data: {
|
|
||||||
type: 'extrudeFace',
|
|
||||||
zAxis: [z_axis.x, z_axis.y, z_axis.z],
|
|
||||||
yAxis: [y_axis.x, y_axis.y, y_axis.z],
|
|
||||||
position: [origin.x, origin.y, origin.z].map(
|
|
||||||
(num) => num / sceneInfra._baseUnitMultiplier
|
|
||||||
) as [number, number, number],
|
|
||||||
sketchPathToNode,
|
|
||||||
extrudePathToNode,
|
|
||||||
cap:
|
|
||||||
artifact?.additionalData?.type === 'cap'
|
|
||||||
? artifact.additionalData.info
|
|
||||||
: 'none',
|
|
||||||
faceId: _entity_id,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
return
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
mouseEnterLeaveCallbacks() {
|
mouseEnterLeaveCallbacks() {
|
||||||
return {
|
return {
|
||||||
onMouseEnter: ({ selected, dragSelected }: OnMouseEnterLeaveArgs) => {
|
onMouseEnter: ({ selected, dragSelected }: OnMouseEnterLeaveArgs) => {
|
||||||
@ -1863,6 +1588,7 @@ export function sketchGroupFromPathToNode({
|
|||||||
return result as SketchGroup
|
return result as SketchGroup
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO delete
|
||||||
function colorSegment(object: any, color: number) {
|
function colorSegment(object: any, color: number) {
|
||||||
const segmentHead = getParentGroup(object, [ARROWHEAD, PROFILE_START])
|
const segmentHead = getParentGroup(object, [ARROWHEAD, PROFILE_START])
|
||||||
if (segmentHead) {
|
if (segmentHead) {
|
||||||
|
|||||||
@ -1,25 +1,25 @@
|
|||||||
import {
|
import {
|
||||||
AmbientLight,
|
AmbientLight,
|
||||||
Color,
|
Color,
|
||||||
GridHelper,
|
|
||||||
LineBasicMaterial,
|
|
||||||
OrthographicCamera,
|
|
||||||
PerspectiveCamera,
|
|
||||||
Scene,
|
|
||||||
Vector3,
|
|
||||||
WebGLRenderer,
|
|
||||||
Raycaster,
|
|
||||||
Vector2,
|
|
||||||
Group,
|
|
||||||
PlaneGeometry,
|
|
||||||
MeshBasicMaterial,
|
|
||||||
Mesh,
|
|
||||||
DoubleSide,
|
DoubleSide,
|
||||||
|
GridHelper,
|
||||||
|
Group,
|
||||||
Intersection,
|
Intersection,
|
||||||
|
LineBasicMaterial,
|
||||||
|
Mesh,
|
||||||
|
MeshBasicMaterial,
|
||||||
Object3D,
|
Object3D,
|
||||||
Object3DEventMap,
|
Object3DEventMap,
|
||||||
TextureLoader,
|
OrthographicCamera,
|
||||||
|
PerspectiveCamera,
|
||||||
|
PlaneGeometry,
|
||||||
|
Raycaster,
|
||||||
|
Scene,
|
||||||
Texture,
|
Texture,
|
||||||
|
TextureLoader,
|
||||||
|
Vector2,
|
||||||
|
Vector3,
|
||||||
|
WebGLRenderer,
|
||||||
} from 'three'
|
} from 'three'
|
||||||
import { Coords2d, compareVec2Epsilon2 } from 'lang/std/sketch'
|
import { Coords2d, compareVec2Epsilon2 } from 'lang/std/sketch'
|
||||||
import { useModelingContext } from 'hooks/useModelingContext'
|
import { useModelingContext } from 'hooks/useModelingContext'
|
||||||
@ -31,6 +31,12 @@ import { EngineCommandManager } from 'lang/std/engineConnection'
|
|||||||
import { MouseState, SegmentOverlayPayload } from 'machines/modelingMachine'
|
import { MouseState, SegmentOverlayPayload } from 'machines/modelingMachine'
|
||||||
import { getAngle, throttle } from 'lib/utils'
|
import { getAngle, throttle } from 'lib/utils'
|
||||||
import { Themes } from 'lib/theme'
|
import { Themes } from 'lib/theme'
|
||||||
|
import {
|
||||||
|
OnClickCallbackArgs,
|
||||||
|
OnDragCallbackArgs,
|
||||||
|
OnMouseEnterLeaveArgs,
|
||||||
|
OnMoveCallbackArgs,
|
||||||
|
} from './sceneCallbacks'
|
||||||
|
|
||||||
type SendType = ReturnType<typeof useModelingContext>['send']
|
type SendType = ReturnType<typeof useModelingContext>['send']
|
||||||
|
|
||||||
@ -55,39 +61,6 @@ export const AXIS_GROUP = 'axisGroup'
|
|||||||
export const SKETCH_GROUP_SEGMENTS = 'sketch-group-segments'
|
export const SKETCH_GROUP_SEGMENTS = 'sketch-group-segments'
|
||||||
export const ARROWHEAD = 'arrowhead'
|
export const ARROWHEAD = 'arrowhead'
|
||||||
|
|
||||||
export interface OnMouseEnterLeaveArgs {
|
|
||||||
selected: Object3D<Object3DEventMap>
|
|
||||||
dragSelected?: Object3D<Object3DEventMap>
|
|
||||||
mouseEvent: MouseEvent
|
|
||||||
}
|
|
||||||
|
|
||||||
interface OnDragCallbackArgs extends OnMouseEnterLeaveArgs {
|
|
||||||
intersectionPoint: {
|
|
||||||
twoD: Vector2
|
|
||||||
threeD: Vector3
|
|
||||||
}
|
|
||||||
intersects: Intersection<Object3D<Object3DEventMap>>[]
|
|
||||||
}
|
|
||||||
interface OnClickCallbackArgs {
|
|
||||||
mouseEvent: MouseEvent
|
|
||||||
intersectionPoint?: {
|
|
||||||
twoD: Vector2
|
|
||||||
threeD: Vector3
|
|
||||||
}
|
|
||||||
intersects: Intersection<Object3D<Object3DEventMap>>[]
|
|
||||||
selected?: Object3D<Object3DEventMap>
|
|
||||||
}
|
|
||||||
|
|
||||||
interface OnMoveCallbackArgs {
|
|
||||||
mouseEvent: MouseEvent
|
|
||||||
intersectionPoint: {
|
|
||||||
twoD: Vector2
|
|
||||||
threeD: Vector3
|
|
||||||
}
|
|
||||||
intersects: Intersection<Object3D<Object3DEventMap>>[]
|
|
||||||
selected?: Object3D<Object3DEventMap>
|
|
||||||
}
|
|
||||||
|
|
||||||
// This singleton class is responsible for all of the under the hood setup for the client side scene.
|
// This singleton class is responsible for all of the under the hood setup for the client side scene.
|
||||||
// That is the cameras and switching between them, raycasters for click mouse events and their abstractions (onClick etc), setting up controls.
|
// That is the cameras and switching between them, raycasters for click mouse events and their abstractions (onClick etc), setting up controls.
|
||||||
// Anything that added the the scene for the user to interact with is probably in SceneEntities.ts
|
// Anything that added the the scene for the user to interact with is probably in SceneEntities.ts
|
||||||
@ -618,59 +591,6 @@ export class SceneInfra {
|
|||||||
this.onClickCallback({ mouseEvent, intersects })
|
this.onClickCallback({ mouseEvent, intersects })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
showDefaultPlanes() {
|
|
||||||
const addPlane = (
|
|
||||||
rotation: { x: number; y: number; z: number }, //
|
|
||||||
type: DefaultPlane
|
|
||||||
): Mesh => {
|
|
||||||
const planeGeometry = new PlaneGeometry(100, 100)
|
|
||||||
const planeMaterial = new MeshBasicMaterial({
|
|
||||||
color: defaultPlaneColor(type),
|
|
||||||
transparent: true,
|
|
||||||
opacity: 0.0,
|
|
||||||
side: DoubleSide,
|
|
||||||
depthTest: false, // needed to avoid transparency issues
|
|
||||||
})
|
|
||||||
const plane = new Mesh(planeGeometry, planeMaterial)
|
|
||||||
plane.rotation.x = rotation.x
|
|
||||||
plane.rotation.y = rotation.y
|
|
||||||
plane.rotation.z = rotation.z
|
|
||||||
plane.userData.type = type
|
|
||||||
plane.name = type
|
|
||||||
return plane
|
|
||||||
}
|
|
||||||
const planes = [
|
|
||||||
addPlane({ x: 0, y: Math.PI / 2, z: 0 }, YZ_PLANE),
|
|
||||||
addPlane({ x: 0, y: 0, z: 0 }, XY_PLANE),
|
|
||||||
addPlane({ x: -Math.PI / 2, y: 0, z: 0 }, XZ_PLANE),
|
|
||||||
]
|
|
||||||
const planesGroup = new Group()
|
|
||||||
planesGroup.userData.type = DEFAULT_PLANES
|
|
||||||
planesGroup.name = DEFAULT_PLANES
|
|
||||||
planesGroup.add(...planes)
|
|
||||||
planesGroup.traverse((child) => {
|
|
||||||
if (child instanceof Mesh) {
|
|
||||||
child.layers.enable(SKETCH_LAYER)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
planesGroup.layers.enable(SKETCH_LAYER)
|
|
||||||
const sceneScale = getSceneScale(
|
|
||||||
this.camControls.camera,
|
|
||||||
this.camControls.target
|
|
||||||
)
|
|
||||||
planesGroup.scale.set(
|
|
||||||
sceneScale / this._baseUnitMultiplier,
|
|
||||||
sceneScale / this._baseUnitMultiplier,
|
|
||||||
sceneScale / this._baseUnitMultiplier
|
|
||||||
)
|
|
||||||
this.scene.add(planesGroup)
|
|
||||||
}
|
|
||||||
removeDefaultPlanes() {
|
|
||||||
const planesGroup = this.scene.children.find(
|
|
||||||
({ userData }) => userData.type === DEFAULT_PLANES
|
|
||||||
)
|
|
||||||
if (planesGroup) this.scene.remove(planesGroup)
|
|
||||||
}
|
|
||||||
updateOtherSelectionColors = (otherSelections: Axis[]) => {
|
updateOtherSelectionColors = (otherSelections: Axis[]) => {
|
||||||
const axisGroup = this.scene.children.find(
|
const axisGroup = this.scene.children.find(
|
||||||
({ userData }) => userData?.type === AXIS_GROUP
|
({ userData }) => userData?.type === AXIS_GROUP
|
||||||
@ -728,28 +648,3 @@ function baseUnitTomm(baseUnit: BaseUnit) {
|
|||||||
return 914.4
|
return 914.4
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export type DefaultPlane =
|
|
||||||
| 'xy-default-plane'
|
|
||||||
| 'xz-default-plane'
|
|
||||||
| 'yz-default-plane'
|
|
||||||
|
|
||||||
export const XY_PLANE: DefaultPlane = 'xy-default-plane'
|
|
||||||
export const XZ_PLANE: DefaultPlane = 'xz-default-plane'
|
|
||||||
export const YZ_PLANE: DefaultPlane = 'yz-default-plane'
|
|
||||||
|
|
||||||
export function defaultPlaneColor(
|
|
||||||
plane: DefaultPlane,
|
|
||||||
lowCh = 0.1,
|
|
||||||
highCh = 0.7
|
|
||||||
): Color {
|
|
||||||
switch (plane) {
|
|
||||||
case XY_PLANE:
|
|
||||||
return new Color(highCh, lowCh, lowCh)
|
|
||||||
case XZ_PLANE:
|
|
||||||
return new Color(lowCh, lowCh, highCh)
|
|
||||||
case YZ_PLANE:
|
|
||||||
return new Color(lowCh, highCh, lowCh)
|
|
||||||
}
|
|
||||||
return new Color(lowCh, lowCh, lowCh)
|
|
||||||
}
|
|
||||||
|
|||||||
@ -119,7 +119,7 @@ export default function Gizmo() {
|
|||||||
<div
|
<div
|
||||||
ref={wrapperRef}
|
ref={wrapperRef}
|
||||||
aria-label="View orientation gizmo"
|
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} />
|
<canvas ref={canvasRef} />
|
||||||
<ContextMenu
|
<ContextMenu
|
||||||
|
|||||||
@ -53,9 +53,8 @@ import {
|
|||||||
sketchOnExtrudedFace,
|
sketchOnExtrudedFace,
|
||||||
startSketchOnDefault,
|
startSketchOnDefault,
|
||||||
} from 'lang/modifyAst'
|
} from 'lang/modifyAst'
|
||||||
import { Program, VariableDeclaration, parse, recast } from 'lang/wasm'
|
import { Program, parse, recast } from 'lang/wasm'
|
||||||
import {
|
import {
|
||||||
getNodeFromPath,
|
|
||||||
getNodePathFromSourceRange,
|
getNodePathFromSourceRange,
|
||||||
hasExtrudableGeometry,
|
hasExtrudableGeometry,
|
||||||
isSingleCursorInPipe,
|
isSingleCursorInPipe,
|
||||||
@ -550,10 +549,8 @@ export const ModelingMachineProvider = ({
|
|||||||
) as [number, number, number],
|
) as [number, number, number],
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
'Get horizontal info': async ({
|
'Get horizontal info': async (context): Promise<SetSelections> => {
|
||||||
selectionRanges,
|
const { selectionRanges, sketchDetails } = context
|
||||||
sketchDetails,
|
|
||||||
}): Promise<SetSelections> => {
|
|
||||||
const { modifiedAst, pathToNodeMap } =
|
const { modifiedAst, pathToNodeMap } =
|
||||||
await applyConstraintHorzVertDistance({
|
await applyConstraintHorzVertDistance({
|
||||||
constraint: 'setHorzDistance',
|
constraint: 'setHorzDistance',
|
||||||
@ -567,11 +564,8 @@ export const ModelingMachineProvider = ({
|
|||||||
pathToNodeMap
|
pathToNodeMap
|
||||||
)
|
)
|
||||||
const updatedAst = await sceneEntitiesManager.updateAstAndRejigSketch(
|
const updatedAst = await sceneEntitiesManager.updateAstAndRejigSketch(
|
||||||
updatedPathToNode,
|
|
||||||
_modifiedAst,
|
_modifiedAst,
|
||||||
sketchDetails.zAxis,
|
context
|
||||||
sketchDetails.yAxis,
|
|
||||||
sketchDetails.origin
|
|
||||||
)
|
)
|
||||||
if (err(updatedAst)) return Promise.reject(updatedAst)
|
if (err(updatedAst)) return Promise.reject(updatedAst)
|
||||||
const selection = updateSelections(
|
const selection = updateSelections(
|
||||||
@ -586,10 +580,8 @@ export const ModelingMachineProvider = ({
|
|||||||
updatedPathToNode,
|
updatedPathToNode,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
'Get vertical info': async ({
|
'Get vertical info': async (context): Promise<SetSelections> => {
|
||||||
selectionRanges,
|
const { selectionRanges, sketchDetails } = context
|
||||||
sketchDetails,
|
|
||||||
}): Promise<SetSelections> => {
|
|
||||||
const { modifiedAst, pathToNodeMap } =
|
const { modifiedAst, pathToNodeMap } =
|
||||||
await applyConstraintHorzVertDistance({
|
await applyConstraintHorzVertDistance({
|
||||||
constraint: 'setVertDistance',
|
constraint: 'setVertDistance',
|
||||||
@ -603,11 +595,8 @@ export const ModelingMachineProvider = ({
|
|||||||
pathToNodeMap
|
pathToNodeMap
|
||||||
)
|
)
|
||||||
const updatedAst = await sceneEntitiesManager.updateAstAndRejigSketch(
|
const updatedAst = await sceneEntitiesManager.updateAstAndRejigSketch(
|
||||||
updatedPathToNode,
|
|
||||||
_modifiedAst,
|
_modifiedAst,
|
||||||
sketchDetails.zAxis,
|
context
|
||||||
sketchDetails.yAxis,
|
|
||||||
sketchDetails.origin
|
|
||||||
)
|
)
|
||||||
if (err(updatedAst)) return Promise.reject(updatedAst)
|
if (err(updatedAst)) return Promise.reject(updatedAst)
|
||||||
const selection = updateSelections(
|
const selection = updateSelections(
|
||||||
@ -622,10 +611,8 @@ export const ModelingMachineProvider = ({
|
|||||||
updatedPathToNode,
|
updatedPathToNode,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
'Get angle info': async ({
|
'Get angle info': async (context): Promise<SetSelections> => {
|
||||||
selectionRanges,
|
const { selectionRanges, sketchDetails } = context
|
||||||
sketchDetails,
|
|
||||||
}): Promise<SetSelections> => {
|
|
||||||
const info = angleBetweenInfo({
|
const info = angleBetweenInfo({
|
||||||
selectionRanges,
|
selectionRanges,
|
||||||
})
|
})
|
||||||
@ -648,11 +635,8 @@ export const ModelingMachineProvider = ({
|
|||||||
pathToNodeMap
|
pathToNodeMap
|
||||||
)
|
)
|
||||||
const updatedAst = await sceneEntitiesManager.updateAstAndRejigSketch(
|
const updatedAst = await sceneEntitiesManager.updateAstAndRejigSketch(
|
||||||
updatedPathToNode,
|
|
||||||
_modifiedAst,
|
_modifiedAst,
|
||||||
sketchDetails.zAxis,
|
context
|
||||||
sketchDetails.yAxis,
|
|
||||||
sketchDetails.origin
|
|
||||||
)
|
)
|
||||||
if (err(updatedAst)) return Promise.reject(updatedAst)
|
if (err(updatedAst)) return Promise.reject(updatedAst)
|
||||||
const selection = updateSelections(
|
const selection = updateSelections(
|
||||||
@ -667,10 +651,8 @@ export const ModelingMachineProvider = ({
|
|||||||
updatedPathToNode,
|
updatedPathToNode,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
'Get length info': async ({
|
'Get length info': async (context): Promise<SetSelections> => {
|
||||||
selectionRanges,
|
const { selectionRanges, sketchDetails } = context
|
||||||
sketchDetails,
|
|
||||||
}): Promise<SetSelections> => {
|
|
||||||
const { modifiedAst, pathToNodeMap } =
|
const { modifiedAst, pathToNodeMap } =
|
||||||
await applyConstraintAngleLength({ selectionRanges })
|
await applyConstraintAngleLength({ selectionRanges })
|
||||||
const _modifiedAst = parse(recast(modifiedAst))
|
const _modifiedAst = parse(recast(modifiedAst))
|
||||||
@ -681,11 +663,8 @@ export const ModelingMachineProvider = ({
|
|||||||
pathToNodeMap
|
pathToNodeMap
|
||||||
)
|
)
|
||||||
const updatedAst = await sceneEntitiesManager.updateAstAndRejigSketch(
|
const updatedAst = await sceneEntitiesManager.updateAstAndRejigSketch(
|
||||||
updatedPathToNode,
|
|
||||||
_modifiedAst,
|
_modifiedAst,
|
||||||
sketchDetails.zAxis,
|
context
|
||||||
sketchDetails.yAxis,
|
|
||||||
sketchDetails.origin
|
|
||||||
)
|
)
|
||||||
if (err(updatedAst)) return Promise.reject(updatedAst)
|
if (err(updatedAst)) return Promise.reject(updatedAst)
|
||||||
const selection = updateSelections(
|
const selection = updateSelections(
|
||||||
@ -700,10 +679,10 @@ export const ModelingMachineProvider = ({
|
|||||||
updatedPathToNode,
|
updatedPathToNode,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
'Get perpendicular distance info': async ({
|
'Get perpendicular distance info': async (
|
||||||
selectionRanges,
|
context
|
||||||
sketchDetails,
|
): Promise<SetSelections> => {
|
||||||
}): Promise<SetSelections> => {
|
const { selectionRanges, sketchDetails } = context
|
||||||
const { modifiedAst, pathToNodeMap } = await applyConstraintIntersect(
|
const { modifiedAst, pathToNodeMap } = await applyConstraintIntersect(
|
||||||
{
|
{
|
||||||
selectionRanges,
|
selectionRanges,
|
||||||
@ -717,11 +696,8 @@ export const ModelingMachineProvider = ({
|
|||||||
pathToNodeMap
|
pathToNodeMap
|
||||||
)
|
)
|
||||||
const updatedAst = await sceneEntitiesManager.updateAstAndRejigSketch(
|
const updatedAst = await sceneEntitiesManager.updateAstAndRejigSketch(
|
||||||
updatedPathToNode,
|
|
||||||
_modifiedAst,
|
_modifiedAst,
|
||||||
sketchDetails.zAxis,
|
context
|
||||||
sketchDetails.yAxis,
|
|
||||||
sketchDetails.origin
|
|
||||||
)
|
)
|
||||||
if (err(updatedAst)) return Promise.reject(updatedAst)
|
if (err(updatedAst)) return Promise.reject(updatedAst)
|
||||||
const selection = updateSelections(
|
const selection = updateSelections(
|
||||||
@ -736,10 +712,8 @@ export const ModelingMachineProvider = ({
|
|||||||
updatedPathToNode,
|
updatedPathToNode,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
'Get ABS X info': async ({
|
'Get ABS X info': async (context): Promise<SetSelections> => {
|
||||||
selectionRanges,
|
const { selectionRanges, sketchDetails } = context
|
||||||
sketchDetails,
|
|
||||||
}): Promise<SetSelections> => {
|
|
||||||
const { modifiedAst, pathToNodeMap } =
|
const { modifiedAst, pathToNodeMap } =
|
||||||
await applyConstraintAbsDistance({
|
await applyConstraintAbsDistance({
|
||||||
constraint: 'xAbs',
|
constraint: 'xAbs',
|
||||||
@ -753,11 +727,8 @@ export const ModelingMachineProvider = ({
|
|||||||
pathToNodeMap
|
pathToNodeMap
|
||||||
)
|
)
|
||||||
const updatedAst = await sceneEntitiesManager.updateAstAndRejigSketch(
|
const updatedAst = await sceneEntitiesManager.updateAstAndRejigSketch(
|
||||||
updatedPathToNode,
|
|
||||||
_modifiedAst,
|
_modifiedAst,
|
||||||
sketchDetails.zAxis,
|
context
|
||||||
sketchDetails.yAxis,
|
|
||||||
sketchDetails.origin
|
|
||||||
)
|
)
|
||||||
if (err(updatedAst)) return Promise.reject(updatedAst)
|
if (err(updatedAst)) return Promise.reject(updatedAst)
|
||||||
const selection = updateSelections(
|
const selection = updateSelections(
|
||||||
@ -772,10 +743,8 @@ export const ModelingMachineProvider = ({
|
|||||||
updatedPathToNode,
|
updatedPathToNode,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
'Get ABS Y info': async ({
|
'Get ABS Y info': async (context): Promise<SetSelections> => {
|
||||||
selectionRanges,
|
const { selectionRanges, sketchDetails } = context
|
||||||
sketchDetails,
|
|
||||||
}): Promise<SetSelections> => {
|
|
||||||
const { modifiedAst, pathToNodeMap } =
|
const { modifiedAst, pathToNodeMap } =
|
||||||
await applyConstraintAbsDistance({
|
await applyConstraintAbsDistance({
|
||||||
constraint: 'yAbs',
|
constraint: 'yAbs',
|
||||||
@ -789,11 +758,8 @@ export const ModelingMachineProvider = ({
|
|||||||
pathToNodeMap
|
pathToNodeMap
|
||||||
)
|
)
|
||||||
const updatedAst = await sceneEntitiesManager.updateAstAndRejigSketch(
|
const updatedAst = await sceneEntitiesManager.updateAstAndRejigSketch(
|
||||||
updatedPathToNode,
|
|
||||||
_modifiedAst,
|
_modifiedAst,
|
||||||
sketchDetails.zAxis,
|
context
|
||||||
sketchDetails.yAxis,
|
|
||||||
sketchDetails.origin
|
|
||||||
)
|
)
|
||||||
if (err(updatedAst)) return Promise.reject(updatedAst)
|
if (err(updatedAst)) return Promise.reject(updatedAst)
|
||||||
const selection = updateSelections(
|
const selection = updateSelections(
|
||||||
@ -809,9 +775,10 @@ export const ModelingMachineProvider = ({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
'Get convert to variable info': async (
|
'Get convert to variable info': async (
|
||||||
{ sketchDetails, selectionRanges },
|
context,
|
||||||
{ data }
|
{ data }
|
||||||
): Promise<SetSelections> => {
|
): Promise<SetSelections> => {
|
||||||
|
const { selectionRanges, sketchDetails } = context
|
||||||
if (!sketchDetails)
|
if (!sketchDetails)
|
||||||
return Promise.reject(new Error('No sketch details'))
|
return Promise.reject(new Error('No sketch details'))
|
||||||
const { variableName } = await getVarNameModal({
|
const { variableName } = await getVarNameModal({
|
||||||
@ -835,11 +802,8 @@ export const ModelingMachineProvider = ({
|
|||||||
return Promise.reject(new Error('No path to replaced node'))
|
return Promise.reject(new Error('No path to replaced node'))
|
||||||
|
|
||||||
const updatedAst = await sceneEntitiesManager.updateAstAndRejigSketch(
|
const updatedAst = await sceneEntitiesManager.updateAstAndRejigSketch(
|
||||||
pathToReplacedNode || [],
|
|
||||||
parsed,
|
parsed,
|
||||||
sketchDetails.zAxis,
|
context
|
||||||
sketchDetails.yAxis,
|
|
||||||
sketchDetails.origin
|
|
||||||
)
|
)
|
||||||
if (err(updatedAst)) return Promise.reject(updatedAst)
|
if (err(updatedAst)) return Promise.reject(updatedAst)
|
||||||
const selection = updateSelections(
|
const selection = updateSelections(
|
||||||
|
|||||||
@ -109,7 +109,6 @@ export const Stream = () => {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
if (state.matches('Sketch')) return
|
if (state.matches('Sketch')) return
|
||||||
if (state.matches('Sketch no face')) return
|
|
||||||
|
|
||||||
if (!context.store?.didDragInStream && butName(e).left) {
|
if (!context.store?.didDragInStream && butName(e).left) {
|
||||||
sendSelectEventToEngine(
|
sendSelectEventToEngine(
|
||||||
|
|||||||
54
src/components/UnitsMenu.tsx
Normal 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: </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>
|
||||||
|
)
|
||||||
|
}
|
||||||
@ -4,7 +4,7 @@ import { useModelingContext } from './useModelingContext'
|
|||||||
import { getEventForSelectWithPoint } from 'lib/selections'
|
import { getEventForSelectWithPoint } from 'lib/selections'
|
||||||
|
|
||||||
export function useEngineConnectionSubscriptions() {
|
export function useEngineConnectionSubscriptions() {
|
||||||
const { send, context } = useModelingContext()
|
const { send, state } = useModelingContext()
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!engineCommandManager) return
|
if (!engineCommandManager) return
|
||||||
@ -29,9 +29,7 @@ export function useEngineConnectionSubscriptions() {
|
|||||||
const unSubClick = engineCommandManager.subscribeTo({
|
const unSubClick = engineCommandManager.subscribeTo({
|
||||||
event: 'select_with_point',
|
event: 'select_with_point',
|
||||||
callback: async (engineEvent) => {
|
callback: async (engineEvent) => {
|
||||||
const event = await getEventForSelectWithPoint(engineEvent, {
|
const event = await getEventForSelectWithPoint(engineEvent, state)
|
||||||
sketchEnginePathId: context.sketchEnginePathId,
|
|
||||||
})
|
|
||||||
event && send(event)
|
event && send(event)
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
@ -39,5 +37,5 @@ export function useEngineConnectionSubscriptions() {
|
|||||||
unSubHover()
|
unSubHover()
|
||||||
unSubClick()
|
unSubClick()
|
||||||
}
|
}
|
||||||
}, [engineCommandManager, context?.sketchEnginePathId])
|
}, [engineCommandManager, state])
|
||||||
}
|
}
|
||||||
|
|||||||
@ -185,6 +185,17 @@ const sk2 = startSketchOn('XY')
|
|||||||
on: expect.any(Object),
|
on: expect.any(Object),
|
||||||
start: expect.any(Object),
|
start: expect.any(Object),
|
||||||
type: 'SketchGroup',
|
type: 'SketchGroup',
|
||||||
|
tags: {
|
||||||
|
p: {
|
||||||
|
__meta: [
|
||||||
|
{
|
||||||
|
sourceRange: [114, 116],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
type: 'TagIdentifier',
|
||||||
|
value: 'p',
|
||||||
|
},
|
||||||
|
},
|
||||||
value: [
|
value: [
|
||||||
{
|
{
|
||||||
type: 'ToPoint',
|
type: 'ToPoint',
|
||||||
@ -265,6 +276,17 @@ const sk2 = startSketchOn('XY')
|
|||||||
on: expect.any(Object),
|
on: expect.any(Object),
|
||||||
start: expect.any(Object),
|
start: expect.any(Object),
|
||||||
type: 'SketchGroup',
|
type: 'SketchGroup',
|
||||||
|
tags: {
|
||||||
|
o: {
|
||||||
|
__meta: [
|
||||||
|
{
|
||||||
|
sourceRange: [417, 419],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
type: 'TagIdentifier',
|
||||||
|
value: 'o',
|
||||||
|
},
|
||||||
|
},
|
||||||
value: [
|
value: [
|
||||||
{
|
{
|
||||||
type: 'ToPoint',
|
type: 'ToPoint',
|
||||||
|
|||||||
@ -155,6 +155,17 @@ const newVar = myVar + 1`
|
|||||||
sourceRange: [39, 63],
|
sourceRange: [39, 63],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
tags: {
|
||||||
|
myPath: {
|
||||||
|
__meta: [
|
||||||
|
{
|
||||||
|
sourceRange: [109, 117],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
type: 'TagIdentifier',
|
||||||
|
value: 'myPath',
|
||||||
|
},
|
||||||
|
},
|
||||||
value: [
|
value: [
|
||||||
{
|
{
|
||||||
type: 'ToPoint',
|
type: 'ToPoint',
|
||||||
|
|||||||
@ -1200,15 +1200,6 @@ export class EngineCommandManager extends EventTarget {
|
|||||||
token,
|
token,
|
||||||
})
|
})
|
||||||
|
|
||||||
// Teardown everything if we go hidden or reconnect
|
|
||||||
document.onvisibilitychange = () => {
|
|
||||||
if (document.visibilityState === 'hidden') {
|
|
||||||
this.engineConnection?.tearDown()
|
|
||||||
} else {
|
|
||||||
this.engineConnection?.connect(true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.dispatchEvent(
|
this.dispatchEvent(
|
||||||
new CustomEvent(EngineCommandManagerEvents.EngineAvailable, {
|
new CustomEvent(EngineCommandManagerEvents.EngineAvailable, {
|
||||||
detail: this.engineConnection,
|
detail: this.engineConnection,
|
||||||
@ -1628,15 +1619,7 @@ export class EngineCommandManager extends EventTarget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
tearDown() {
|
tearDown() {
|
||||||
if (this.engineConnection) {
|
this.engineConnection?.tearDown()
|
||||||
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() {
|
async startNewSession() {
|
||||||
this.lastArtifactMap = this.artifactMap
|
this.lastArtifactMap = this.artifactMap
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import {
|
|||||||
engineCommandManager,
|
engineCommandManager,
|
||||||
kclManager,
|
kclManager,
|
||||||
sceneEntitiesManager,
|
sceneEntitiesManager,
|
||||||
|
sceneInfra,
|
||||||
} from 'lib/singletons'
|
} from 'lib/singletons'
|
||||||
import { CallExpression, SourceRange, Value, parse, recast } from 'lang/wasm'
|
import { CallExpression, SourceRange, Value, parse, recast } from 'lang/wasm'
|
||||||
import { ModelingMachineEvent } from 'machines/modelingMachine'
|
import { ModelingMachineEvent } from 'machines/modelingMachine'
|
||||||
@ -15,6 +16,7 @@ import { Program } from 'lang/wasm'
|
|||||||
import {
|
import {
|
||||||
doesPipeHaveCallExp,
|
doesPipeHaveCallExp,
|
||||||
getNodeFromPath,
|
getNodeFromPath,
|
||||||
|
getNodePathFromSourceRange,
|
||||||
hasSketchPipeBeenExtruded,
|
hasSketchPipeBeenExtruded,
|
||||||
isSingleCursorInPipe,
|
isSingleCursorInPipe,
|
||||||
} from 'lang/queryAst'
|
} from 'lang/queryAst'
|
||||||
@ -24,11 +26,15 @@ import {
|
|||||||
TANGENTIAL_ARC_TO_SEGMENT,
|
TANGENTIAL_ARC_TO_SEGMENT,
|
||||||
getParentGroup,
|
getParentGroup,
|
||||||
PROFILE_START,
|
PROFILE_START,
|
||||||
|
getFaceDetails,
|
||||||
|
DefaultPlaneStr,
|
||||||
} from 'clientSideScene/sceneEntities'
|
} from 'clientSideScene/sceneEntities'
|
||||||
import { Mesh, Object3D, Object3DEventMap } from 'three'
|
import { Mesh, Object3D, Object3DEventMap } from 'three'
|
||||||
import { AXIS_GROUP, X_AXIS } from 'clientSideScene/sceneInfra'
|
import { AXIS_GROUP, X_AXIS } from 'clientSideScene/sceneInfra'
|
||||||
import { PathToNodeMap } from 'lang/std/sketchcombos'
|
import { PathToNodeMap } from 'lang/std/sketchcombos'
|
||||||
import { err } from 'lib/trap'
|
import { err } from 'lib/trap'
|
||||||
|
import { useModelingContext } from 'hooks/useModelingContext'
|
||||||
|
import { ArtifactMapCommand } from 'lang/std/engineConnection'
|
||||||
|
|
||||||
export const X_AXIS_UUID = 'ad792545-7fd3-482a-a602-a93924e3055b'
|
export const X_AXIS_UUID = 'ad792545-7fd3-482a-a602-a93924e3055b'
|
||||||
export const Y_AXIS_UUID = '680fd157-266f-4b8a-984f-cdf46b8bdf01'
|
export const Y_AXIS_UUID = '680fd157-266f-4b8a-984f-cdf46b8bdf01'
|
||||||
@ -62,8 +68,12 @@ export async function getEventForSelectWithPoint(
|
|||||||
Models['OkModelingCmdResponse_type'],
|
Models['OkModelingCmdResponse_type'],
|
||||||
{ type: 'select_with_point' }
|
{ type: 'select_with_point' }
|
||||||
>,
|
>,
|
||||||
{ sketchEnginePathId }: { sketchEnginePathId?: string }
|
state: ReturnType<typeof useModelingContext>['state']
|
||||||
): Promise<ModelingMachineEvent | null> {
|
): Promise<ModelingMachineEvent | null> {
|
||||||
|
if (state.matches('Sketch no face'))
|
||||||
|
return handleSelectionInSketchNoFace(data?.entity_id || '')
|
||||||
|
|
||||||
|
// assumes XState state is `idle` from this point
|
||||||
if (!data?.entity_id) {
|
if (!data?.entity_id) {
|
||||||
return {
|
return {
|
||||||
type: 'Set selection',
|
type: 'Set selection',
|
||||||
@ -143,6 +153,128 @@ export async function getEventForSelectWithPoint(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function handleSelectionInSketchNoFace(
|
||||||
|
entity_id: string
|
||||||
|
): Promise<ModelingMachineEvent | null> {
|
||||||
|
let _entity_id = entity_id
|
||||||
|
if (!_entity_id) return Promise.resolve(null)
|
||||||
|
if (
|
||||||
|
engineCommandManager.defaultPlanes?.xy === _entity_id ||
|
||||||
|
engineCommandManager.defaultPlanes?.xz === _entity_id ||
|
||||||
|
engineCommandManager.defaultPlanes?.yz === _entity_id ||
|
||||||
|
engineCommandManager.defaultPlanes?.negXy === _entity_id ||
|
||||||
|
engineCommandManager.defaultPlanes?.negXz === _entity_id ||
|
||||||
|
engineCommandManager.defaultPlanes?.negYz === _entity_id
|
||||||
|
) {
|
||||||
|
const defaultPlaneStrMap: Record<string, DefaultPlaneStr> = {
|
||||||
|
[engineCommandManager.defaultPlanes.xy]: 'XY',
|
||||||
|
[engineCommandManager.defaultPlanes.xz]: 'XZ',
|
||||||
|
[engineCommandManager.defaultPlanes.yz]: 'YZ',
|
||||||
|
[engineCommandManager.defaultPlanes.negXy]: '-XY',
|
||||||
|
[engineCommandManager.defaultPlanes.negXz]: '-XZ',
|
||||||
|
[engineCommandManager.defaultPlanes.negYz]: '-YZ',
|
||||||
|
}
|
||||||
|
// TODO can we get this information from rust land when it creates the default planes?
|
||||||
|
// maybe returned from make_default_planes (src/wasm-lib/src/wasm.rs)
|
||||||
|
let zAxis: [number, number, number] = [0, 0, 1]
|
||||||
|
let yAxis: [number, number, number] = [0, 1, 0]
|
||||||
|
|
||||||
|
// get unit vector from camera position to target
|
||||||
|
const camVector = sceneInfra.camControls.camera.position
|
||||||
|
.clone()
|
||||||
|
.sub(sceneInfra.camControls.target)
|
||||||
|
|
||||||
|
if (engineCommandManager.defaultPlanes?.xy === _entity_id) {
|
||||||
|
zAxis = [0, 0, 1]
|
||||||
|
yAxis = [0, 1, 0]
|
||||||
|
if (camVector.z < 0) {
|
||||||
|
zAxis = [0, 0, -1]
|
||||||
|
_entity_id = engineCommandManager.defaultPlanes?.negXy || ''
|
||||||
|
}
|
||||||
|
} else if (engineCommandManager.defaultPlanes?.yz === _entity_id) {
|
||||||
|
zAxis = [1, 0, 0]
|
||||||
|
yAxis = [0, 0, 1]
|
||||||
|
if (camVector.x < 0) {
|
||||||
|
zAxis = [-1, 0, 0]
|
||||||
|
_entity_id = engineCommandManager.defaultPlanes?.negYz || ''
|
||||||
|
}
|
||||||
|
} else if (engineCommandManager.defaultPlanes?.xz === _entity_id) {
|
||||||
|
zAxis = [0, 1, 0]
|
||||||
|
yAxis = [0, 0, 1]
|
||||||
|
_entity_id = engineCommandManager.defaultPlanes?.negXz || ''
|
||||||
|
if (camVector.y < 0) {
|
||||||
|
zAxis = [0, -1, 0]
|
||||||
|
_entity_id = engineCommandManager.defaultPlanes?.xz || ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
type: 'Select default plane',
|
||||||
|
data: {
|
||||||
|
type: 'defaultPlane',
|
||||||
|
planeId: _entity_id,
|
||||||
|
plane: defaultPlaneStrMap[_entity_id],
|
||||||
|
zAxis,
|
||||||
|
yAxis,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const artifact = engineCommandManager.artifactMap[_entity_id]
|
||||||
|
// If we clicked on an extrude wall, we climb up the parent Id
|
||||||
|
// to get the sketch profile's face ID. If we clicked on an endcap,
|
||||||
|
// we already have it.
|
||||||
|
const targetId =
|
||||||
|
'additionalData' in artifact && artifact.additionalData?.type === 'cap'
|
||||||
|
? _entity_id
|
||||||
|
: artifact.parentId
|
||||||
|
|
||||||
|
// tsc cannot infer that target can have extrusions
|
||||||
|
// from the commandType (why?) so we need to cast it
|
||||||
|
const target = engineCommandManager.artifactMap?.[
|
||||||
|
targetId || ''
|
||||||
|
] as ArtifactMapCommand & { extrusions?: string[] }
|
||||||
|
|
||||||
|
// TODO: We get the first extrusion command ID,
|
||||||
|
// which is fine while backend systems only support one extrusion.
|
||||||
|
// but we need to more robustly handle resolving to the correct extrusion
|
||||||
|
// if there are multiple.
|
||||||
|
const extrusions =
|
||||||
|
engineCommandManager.artifactMap?.[target?.extrusions?.[0] || '']
|
||||||
|
|
||||||
|
if (artifact?.commandType !== 'solid3d_get_extrusion_face_info') return null
|
||||||
|
|
||||||
|
const faceInfo = await getFaceDetails(_entity_id)
|
||||||
|
if (!faceInfo?.origin || !faceInfo?.z_axis || !faceInfo?.y_axis) return null
|
||||||
|
const { z_axis, y_axis, origin } = faceInfo
|
||||||
|
const sketchPathToNode = getNodePathFromSourceRange(
|
||||||
|
kclManager.ast,
|
||||||
|
artifact.range
|
||||||
|
)
|
||||||
|
|
||||||
|
const extrudePathToNode = extrusions?.range
|
||||||
|
? getNodePathFromSourceRange(kclManager.ast, extrusions.range)
|
||||||
|
: []
|
||||||
|
|
||||||
|
return {
|
||||||
|
type: 'Select default plane',
|
||||||
|
data: {
|
||||||
|
type: 'extrudeFace',
|
||||||
|
zAxis: [z_axis.x, z_axis.y, z_axis.z],
|
||||||
|
yAxis: [y_axis.x, y_axis.y, y_axis.z],
|
||||||
|
position: [origin.x, origin.y, origin.z].map(
|
||||||
|
(num) => num / sceneInfra._baseUnitMultiplier
|
||||||
|
) as [number, number, number],
|
||||||
|
sketchPathToNode,
|
||||||
|
extrudePathToNode,
|
||||||
|
cap:
|
||||||
|
artifact?.additionalData?.type === 'cap'
|
||||||
|
? artifact.additionalData.info
|
||||||
|
: 'none',
|
||||||
|
faceId: _entity_id,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export function getEventForSegmentSelection(
|
export function getEventForSegmentSelection(
|
||||||
obj: Object3D<Object3DEventMap>
|
obj: Object3D<Object3DEventMap>
|
||||||
): ModelingMachineEvent | null {
|
): ModelingMachineEvent | null {
|
||||||
|
|||||||
@ -16,6 +16,14 @@ export const baseUnits = {
|
|||||||
export type BaseUnit = Models['UnitLength_type']
|
export type BaseUnit = Models['UnitLength_type']
|
||||||
|
|
||||||
export const baseUnitsUnion = Object.values(baseUnits).flatMap((v) => v)
|
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 type Toggle = 'On' | 'Off'
|
||||||
export const toggleAsArray = ['On', 'Off'] as const
|
export const toggleAsArray = ['On', 'Off'] as const
|
||||||
|
|||||||
@ -9,10 +9,6 @@ export const codeManager = new CodeManager()
|
|||||||
|
|
||||||
export const engineCommandManager = new EngineCommandManager()
|
export const engineCommandManager = new EngineCommandManager()
|
||||||
|
|
||||||
// Accessible for tests mostly
|
|
||||||
// @ts-ignore
|
|
||||||
window.tearDown = engineCommandManager.tearDown
|
|
||||||
|
|
||||||
// This needs to be after codeManager is created.
|
// This needs to be after codeManager is created.
|
||||||
export const kclManager = new KclManager(engineCommandManager)
|
export const kclManager = new KclManager(engineCommandManager)
|
||||||
kclManager.isFirstRender = true
|
kclManager.isFirstRender = true
|
||||||
|
|||||||
8
src/wasm-lib/Cargo.lock
generated
@ -1385,7 +1385,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "kcl-lib"
|
name = "kcl-lib"
|
||||||
version = "0.1.69"
|
version = "0.1.71"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"approx",
|
"approx",
|
||||||
@ -1453,7 +1453,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "kcl-test-server"
|
name = "kcl-test-server"
|
||||||
version = "0.1.1"
|
version = "0.1.2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"hyper",
|
"hyper",
|
||||||
@ -1466,9 +1466,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "kittycad"
|
name = "kittycad"
|
||||||
version = "0.3.6"
|
version = "0.3.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "af3de9bb4b1441f198689a9f64a8163a518377e30b348a784680e738985b95eb"
|
checksum = "e1777b503442fa4666564cc3ab237d456df853a09648a4b2bb09622d25d021a5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
|
|||||||
@ -69,7 +69,7 @@ members = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[workspace.dependencies]
|
[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"
|
kittycad-modeling-session = "0.1.4"
|
||||||
|
|
||||||
[[test]]
|
[[test]]
|
||||||
|
|||||||
@ -1,14 +1,14 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "kcl-test-server"
|
name = "kcl-test-server"
|
||||||
description = "A test server for KCL"
|
description = "A test server for KCL"
|
||||||
version = "0.1.1"
|
version = "0.1.2"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow = "1.0.86"
|
anyhow = "1.0.86"
|
||||||
hyper = { version = "0.14.29", features = ["server"] }
|
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"
|
pico-args = "0.5.0"
|
||||||
serde = { version = "1.0.203", features = ["derive"] }
|
serde = { version = "1.0.203", features = ["derive"] }
|
||||||
serde_json = "1.0.120"
|
serde_json = "1.0.120"
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "kcl-lib"
|
name = "kcl-lib"
|
||||||
description = "KittyCAD Language implementation and tools"
|
description = "KittyCAD Language implementation and tools"
|
||||||
version = "0.1.69"
|
version = "0.1.71"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
repository = "https://github.com/KittyCAD/modeling-app"
|
repository = "https://github.com/KittyCAD/modeling-app"
|
||||||
|
|||||||
@ -1238,11 +1238,10 @@ impl CallExpression {
|
|||||||
}
|
}
|
||||||
FunctionKind::UserDefined => {
|
FunctionKind::UserDefined => {
|
||||||
let func = memory.get(&fn_name, self.into())?;
|
let func = memory.get(&fn_name, self.into())?;
|
||||||
let (result, global_memory_items) =
|
let result = func.call_fn(fn_args, memory.clone(), ctx.clone()).await.map_err(|e| {
|
||||||
func.call_fn(fn_args, memory.clone(), ctx.clone()).await.map_err(|e| {
|
// Add the call expression to the source ranges.
|
||||||
// Add the call expression to the source ranges.
|
e.add_source_ranges(vec![self.into()])
|
||||||
e.add_source_ranges(vec![self.into()])
|
})?;
|
||||||
})?;
|
|
||||||
|
|
||||||
let result = result.ok_or_else(|| {
|
let result = result.ok_or_else(|| {
|
||||||
KclError::UndefinedValue(KclErrorDetails {
|
KclError::UndefinedValue(KclErrorDetails {
|
||||||
@ -1252,14 +1251,6 @@ impl CallExpression {
|
|||||||
})?;
|
})?;
|
||||||
let result = result.get_value()?;
|
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)
|
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 {
|
impl From<&TagDeclarator> for CompletionItem {
|
||||||
fn from(tag: &TagDeclarator) -> Self {
|
fn from(tag: &TagDeclarator) -> Self {
|
||||||
CompletionItem {
|
CompletionItem {
|
||||||
|
|||||||
@ -537,17 +537,14 @@ impl std::hash::Hash for TagIdentifier {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type MemoryFunction = fn(
|
pub type MemoryFunction =
|
||||||
s: Vec<MemoryItem>,
|
fn(
|
||||||
memory: ProgramMemory,
|
s: Vec<MemoryItem>,
|
||||||
expression: Box<FunctionExpression>,
|
memory: ProgramMemory,
|
||||||
metadata: Vec<Metadata>,
|
expression: Box<FunctionExpression>,
|
||||||
ctx: ExecutorContext,
|
metadata: Vec<Metadata>,
|
||||||
) -> std::pin::Pin<
|
ctx: ExecutorContext,
|
||||||
Box<
|
) -> std::pin::Pin<Box<dyn std::future::Future<Output = Result<Option<ProgramReturn>, KclError>> + Send>>;
|
||||||
dyn std::future::Future<Output = Result<(Option<ProgramReturn>, HashMap<String, MemoryItem>), KclError>> + Send,
|
|
||||||
>,
|
|
||||||
>;
|
|
||||||
|
|
||||||
fn force_memory_function<
|
fn force_memory_function<
|
||||||
F: Fn(
|
F: Fn(
|
||||||
@ -556,12 +553,7 @@ fn force_memory_function<
|
|||||||
Box<FunctionExpression>,
|
Box<FunctionExpression>,
|
||||||
Vec<Metadata>,
|
Vec<Metadata>,
|
||||||
ExecutorContext,
|
ExecutorContext,
|
||||||
) -> std::pin::Pin<
|
) -> std::pin::Pin<Box<dyn std::future::Future<Output = Result<Option<ProgramReturn>, KclError>> + Send>>,
|
||||||
Box<
|
|
||||||
dyn std::future::Future<Output = Result<(Option<ProgramReturn>, HashMap<String, MemoryItem>), KclError>>
|
|
||||||
+ Send,
|
|
||||||
>,
|
|
||||||
>,
|
|
||||||
>(
|
>(
|
||||||
f: F,
|
f: F,
|
||||||
) -> F {
|
) -> F {
|
||||||
@ -691,11 +683,15 @@ impl MemoryItem {
|
|||||||
match self {
|
match self {
|
||||||
MemoryItem::TagIdentifier(t) => Ok(*t.clone()),
|
MemoryItem::TagIdentifier(t) => Ok(*t.clone()),
|
||||||
MemoryItem::UserVal(u) => {
|
MemoryItem::UserVal(u) => {
|
||||||
let name: String = self.get_json()?;
|
if let Some(identifier) = self.get_json_opt::<TagIdentifier>()? {
|
||||||
Ok(TagIdentifier {
|
Ok(identifier)
|
||||||
value: name,
|
} else {
|
||||||
meta: u.meta.clone(),
|
let name: String = self.get_json()?;
|
||||||
})
|
Ok(TagIdentifier {
|
||||||
|
value: name,
|
||||||
|
meta: u.meta.clone(),
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_ => Err(KclError::Semantic(KclErrorDetails {
|
_ => Err(KclError::Semantic(KclErrorDetails {
|
||||||
message: format!("Not a tag identifier: {:?}", self),
|
message: format!("Not a tag identifier: {:?}", self),
|
||||||
@ -752,7 +748,7 @@ impl MemoryItem {
|
|||||||
args: Vec<MemoryItem>,
|
args: Vec<MemoryItem>,
|
||||||
memory: ProgramMemory,
|
memory: ProgramMemory,
|
||||||
ctx: ExecutorContext,
|
ctx: ExecutorContext,
|
||||||
) -> Result<(Option<ProgramReturn>, HashMap<String, MemoryItem>), KclError> {
|
) -> Result<Option<ProgramReturn>, KclError> {
|
||||||
let MemoryItem::Function { func, expression, meta } = &self else {
|
let MemoryItem::Function { func, expression, meta } = &self else {
|
||||||
return Err(KclError::Semantic(KclErrorDetails {
|
return Err(KclError::Semantic(KclErrorDetails {
|
||||||
message: "not a in memory function".to_string(),
|
message: "not a in memory function".to_string(),
|
||||||
@ -782,6 +778,9 @@ pub struct SketchGroup {
|
|||||||
pub on: SketchSurface,
|
pub on: SketchSurface,
|
||||||
/// The starting path.
|
/// The starting path.
|
||||||
pub start: BasePath,
|
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.
|
/// Metadata.
|
||||||
#[serde(rename = "__meta")]
|
#[serde(rename = "__meta")]
|
||||||
pub meta: Vec<Metadata>,
|
pub meta: Vec<Metadata>,
|
||||||
@ -1359,6 +1358,8 @@ pub struct ExecutorSettings {
|
|||||||
pub highlight_edges: bool,
|
pub highlight_edges: bool,
|
||||||
/// Whether or not Screen Space Ambient Occlusion (SSAO) is enabled.
|
/// Whether or not Screen Space Ambient Occlusion (SSAO) is enabled.
|
||||||
pub enable_ssao: bool,
|
pub enable_ssao: bool,
|
||||||
|
// Show grid?
|
||||||
|
pub show_grid: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for ExecutorSettings {
|
impl Default for ExecutorSettings {
|
||||||
@ -1367,6 +1368,7 @@ impl Default for ExecutorSettings {
|
|||||||
units: Default::default(),
|
units: Default::default(),
|
||||||
highlight_edges: true,
|
highlight_edges: true,
|
||||||
enable_ssao: false,
|
enable_ssao: false,
|
||||||
|
show_grid: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1377,6 +1379,7 @@ impl From<crate::settings::types::Configuration> for ExecutorSettings {
|
|||||||
units: config.settings.modeling.base_unit,
|
units: config.settings.modeling.base_unit,
|
||||||
highlight_edges: config.settings.modeling.highlight_edges.into(),
|
highlight_edges: config.settings.modeling.highlight_edges.into(),
|
||||||
enable_ssao: config.settings.modeling.enable_ssao.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,
|
units: config.settings.modeling.base_unit,
|
||||||
highlight_edges: config.settings.modeling.highlight_edges.into(),
|
highlight_edges: config.settings.modeling.highlight_edges.into(),
|
||||||
enable_ssao: config.settings.modeling.enable_ssao.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,
|
units: modeling.base_unit,
|
||||||
highlight_edges: modeling.highlight_edges.into(),
|
highlight_edges: modeling.highlight_edges.into(),
|
||||||
enable_ssao: modeling.enable_ssao.into(),
|
enable_ssao: modeling.enable_ssao.into(),
|
||||||
|
show_grid: modeling.show_scale_grid,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1415,6 +1420,7 @@ impl ExecutorContext {
|
|||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
},
|
},
|
||||||
|
if settings.show_grid { Some(true) } else { None },
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
@ -1478,6 +1484,7 @@ impl ExecutorContext {
|
|||||||
units,
|
units,
|
||||||
highlight_edges: true,
|
highlight_edges: true,
|
||||||
enable_ssao: false,
|
enable_ssao: false,
|
||||||
|
show_grid: false,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
@ -1564,16 +1571,7 @@ impl ExecutorContext {
|
|||||||
}
|
}
|
||||||
FunctionKind::UserDefined => {
|
FunctionKind::UserDefined => {
|
||||||
if let Some(func) = memory.clone().root.get(&fn_name) {
|
if let Some(func) = memory.clone().root.get(&fn_name) {
|
||||||
let (result, global_memory_items) =
|
let result = func.call_fn(args.clone(), memory.clone(), self.clone()).await?;
|
||||||
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();
|
|
||||||
}
|
|
||||||
|
|
||||||
memory.return_ = result;
|
memory.return_ = result;
|
||||||
} else {
|
} else {
|
||||||
@ -1698,7 +1696,7 @@ impl ExecutorContext {
|
|||||||
.inner_execute(&function_expression.body, &mut fn_memory, BodyType::Block)
|
.inner_execute(&function_expression.body, &mut fn_memory, BodyType::Block)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
Ok((result.return_, fn_memory.get_tags()))
|
Ok(result.return_)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|||||||
@ -1,5 +1,3 @@
|
|||||||
use std::collections::HashMap;
|
|
||||||
|
|
||||||
use schemars::JsonSchema;
|
use schemars::JsonSchema;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
@ -18,10 +16,7 @@ pub struct FunctionParam<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> FunctionParam<'a> {
|
impl<'a> FunctionParam<'a> {
|
||||||
pub async fn call(
|
pub async fn call(&self, args: Vec<MemoryItem>) -> Result<Option<ProgramReturn>, KclError> {
|
||||||
&self,
|
|
||||||
args: Vec<MemoryItem>,
|
|
||||||
) -> Result<(Option<ProgramReturn>, HashMap<String, MemoryItem>), KclError> {
|
|
||||||
(self.inner)(
|
(self.inner)(
|
||||||
args,
|
args,
|
||||||
self.memory.clone(),
|
self.memory.clone(),
|
||||||
|
|||||||
@ -1542,6 +1542,7 @@ fn fn_call(i: TokenSlice) -> PResult<CallExpression> {
|
|||||||
// Replace the literal with the tag.
|
// Replace the literal with the tag.
|
||||||
args[i] = Value::Identifier(Box::new(tag));
|
args[i] = Value::Identifier(Box::new(tag));
|
||||||
}
|
}
|
||||||
|
Value::MemberExpression(_) => {}
|
||||||
e => {
|
e => {
|
||||||
return Err(ErrMode::Cut(
|
return Err(ErrMode::Cut(
|
||||||
KclError::Syntax(KclErrorDetails {
|
KclError::Syntax(KclErrorDetails {
|
||||||
|
|||||||
@ -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 sketch_groups: Vec<Box<SketchGroup>> = sketch_group_set.into();
|
||||||
let mut extrude_groups = Vec::new();
|
let mut extrude_groups = Vec::new();
|
||||||
for sketch_group in &sketch_groups {
|
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(
|
args.send_modeling_cmd(
|
||||||
id,
|
id,
|
||||||
kittycad::types::ModelingCmd::Extrude {
|
kittycad::types::ModelingCmd::Extrude {
|
||||||
|
|||||||
@ -207,7 +207,7 @@ async fn make_transform<'a>(
|
|||||||
meta: vec![source_range.into()],
|
meta: vec![source_range.into()],
|
||||||
});
|
});
|
||||||
let transform_fn_args = vec![repetition_num];
|
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.
|
// Unpack the returned transform object.
|
||||||
let source_ranges = vec![source_range];
|
let source_ranges = vec![source_range];
|
||||||
|
|||||||
@ -1,5 +1,7 @@
|
|||||||
//! Functions related to sketching.
|
//! Functions related to sketching.
|
||||||
|
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use derive_docs::stdlib;
|
use derive_docs::stdlib;
|
||||||
use kittycad::types::{Angle, ModelingCmd, Point3D};
|
use kittycad::types::{Angle, ModelingCmd, Point3D};
|
||||||
@ -127,6 +129,11 @@ async fn inner_line_to(
|
|||||||
)
|
)
|
||||||
.await?;
|
.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 {
|
let current_path = Path::ToPoint {
|
||||||
base: BasePath {
|
base: BasePath {
|
||||||
from: from.into(),
|
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);
|
new_sketch_group.value.push(current_path);
|
||||||
|
|
||||||
Ok(new_sketch_group)
|
Ok(new_sketch_group)
|
||||||
@ -291,6 +297,11 @@ async fn inner_line(
|
|||||||
)
|
)
|
||||||
.await?;
|
.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 {
|
let current_path = Path::ToPoint {
|
||||||
base: BasePath {
|
base: BasePath {
|
||||||
from: from.into(),
|
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);
|
new_sketch_group.value.push(current_path);
|
||||||
|
|
||||||
Ok(new_sketch_group)
|
Ok(new_sketch_group)
|
||||||
@ -455,18 +465,6 @@ async fn inner_angled_line(
|
|||||||
|
|
||||||
let id = uuid::Uuid::new_v4();
|
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(
|
args.batch_modeling_cmd(
|
||||||
id,
|
id,
|
||||||
ModelingCmd::ExtendPath {
|
ModelingCmd::ExtendPath {
|
||||||
@ -484,6 +482,22 @@ async fn inner_angled_line(
|
|||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
let mut new_sketch_group = sketch_group.clone();
|
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);
|
new_sketch_group.value.push(current_path);
|
||||||
Ok(new_sketch_group)
|
Ok(new_sketch_group)
|
||||||
}
|
}
|
||||||
@ -1206,7 +1220,7 @@ pub(crate) async fn inner_start_profile_at(
|
|||||||
let current_path = BasePath {
|
let current_path = BasePath {
|
||||||
from: to,
|
from: to,
|
||||||
to,
|
to,
|
||||||
tag,
|
tag: tag.clone(),
|
||||||
geo_meta: GeoMeta {
|
geo_meta: GeoMeta {
|
||||||
id,
|
id,
|
||||||
metadata: args.source_range.into(),
|
metadata: args.source_range.into(),
|
||||||
@ -1219,6 +1233,11 @@ pub(crate) async fn inner_start_profile_at(
|
|||||||
value: vec![],
|
value: vec![],
|
||||||
start: current_path,
|
start: current_path,
|
||||||
meta: vec![args.source_range.into()],
|
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))
|
Ok(Box::new(sketch_group))
|
||||||
}
|
}
|
||||||
@ -1353,6 +1372,9 @@ pub(crate) async fn inner_close(
|
|||||||
}
|
}
|
||||||
|
|
||||||
let mut new_sketch_group = sketch_group.clone();
|
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 {
|
new_sketch_group.value.push(Path::ToPoint {
|
||||||
base: BasePath {
|
base: BasePath {
|
||||||
from: from.into(),
|
from: from.into(),
|
||||||
@ -1461,6 +1483,11 @@ pub(crate) async fn inner_arc(
|
|||||||
)
|
)
|
||||||
.await?;
|
.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 {
|
let current_path = Path::ToPoint {
|
||||||
base: BasePath {
|
base: BasePath {
|
||||||
from: from.into(),
|
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);
|
new_sketch_group.value.push(current_path);
|
||||||
|
|
||||||
Ok(new_sketch_group)
|
Ok(new_sketch_group)
|
||||||
@ -1567,6 +1593,11 @@ async fn inner_tangential_arc(
|
|||||||
|
|
||||||
let to = [from.x + to[0], from.y + to[1]];
|
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 {
|
let current_path = Path::TangentialArc {
|
||||||
base: BasePath {
|
base: BasePath {
|
||||||
from: from.into(),
|
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);
|
new_sketch_group.value.push(current_path);
|
||||||
|
|
||||||
Ok(new_sketch_group)
|
Ok(new_sketch_group)
|
||||||
@ -1671,6 +1701,11 @@ async fn inner_tangential_arc_to(
|
|||||||
let id = uuid::Uuid::new_v4();
|
let id = uuid::Uuid::new_v4();
|
||||||
args.batch_modeling_cmd(id, tan_arc_to(&sketch_group, &delta)).await?;
|
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 {
|
let current_path = Path::TangentialArcTo {
|
||||||
base: BasePath {
|
base: BasePath {
|
||||||
from: from.into(),
|
from: from.into(),
|
||||||
@ -1685,7 +1720,6 @@ async fn inner_tangential_arc_to(
|
|||||||
ccw: result.ccw > 0,
|
ccw: result.ccw > 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut new_sketch_group = sketch_group.clone();
|
|
||||||
new_sketch_group.value.push(current_path);
|
new_sketch_group.value.push(current_path);
|
||||||
|
|
||||||
Ok(new_sketch_group)
|
Ok(new_sketch_group)
|
||||||
@ -1772,6 +1806,11 @@ async fn inner_bezier_curve(
|
|||||||
)
|
)
|
||||||
.await?;
|
.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 {
|
let current_path = Path::ToPoint {
|
||||||
base: BasePath {
|
base: BasePath {
|
||||||
from: from.into(),
|
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);
|
new_sketch_group.value.push(current_path);
|
||||||
|
|
||||||
Ok(new_sketch_group)
|
Ok(new_sketch_group)
|
||||||
|
|||||||