From 0e916cfd5b7bdca7c5931b28c5438d1f1f7a87d9 Mon Sep 17 00:00:00 2001 From: Kurt Hutten Date: Fri, 22 Mar 2024 10:23:04 +1100 Subject: [PATCH] SketchOnFace UI (#1664) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * always enter edit mode * initial blocking of extra code-mirror updates * dry out code * rejig selections * A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu) * clean up * stream clean up * update export * sketch mode can be entered and exited for extrude faces But has bugs * startSketchOn working in some cases, editsketch animation working but not orientation of instersection plane etc * Revert "A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)" This reverts commit 406fca4c553681fbad882167a9c1ab380af52899. * A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu) * remove comment * add sketch on face e2e test * tweenCamToNegYAxis should respect reduced motion * initial sketch on face working with test * remove temporary toolbar button and xState flow * un-used vars * snapshot test tweak * A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu) * type tidy up * Revert "A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)" This reverts commit c39b8ebf954fa63556e21da081031b8acd77c909. * Revert "A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)" This reverts commit fecf6f490af6ced34959653984108958fb504f82. * A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu) * rename * sketch on sketch on sketch * A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu) * typo * startSketchOn Endcaps end works, start is weird still * clear selections for entity_ids that are not recognised * fix sketch on end cap of second order extrustion * tiny clean up * fix sketch on close segment/face * clean up 'lastCodeMirrorSelectionUpdatedFromScene' * add code mode test for sketchOnExtrudedFace * make end cap selection more robust * update js artifacts for extrudes * update kcl docs * clean up --------- Co-authored-by: github-actions[bot] --- docs/kcl/angleToMatchLengthX.md | 2 + docs/kcl/angleToMatchLengthY.md | 2 + docs/kcl/angledLine.md | 4 + docs/kcl/angledLineOfXLength.md | 4 + docs/kcl/angledLineOfYLength.md | 4 + docs/kcl/angledLineThatIntersects.md | 4 + docs/kcl/angledLineToX.md | 4 + docs/kcl/angledLineToY.md | 4 + docs/kcl/arc.md | 4 + docs/kcl/bezierCurve.md | 4 + docs/kcl/circle.md | 6 + docs/kcl/close.md | 4 + docs/kcl/extrude.md | 2 + docs/kcl/hole.md | 6 + docs/kcl/lastSegX.md | 2 + docs/kcl/lastSegY.md | 2 + docs/kcl/line.md | 4 + docs/kcl/lineTo.md | 4 + docs/kcl/patternCircular2d.md | 2 + docs/kcl/patternLinear2d.md | 2 + docs/kcl/segAng.md | 2 + docs/kcl/segEndX.md | 2 + docs/kcl/segEndY.md | 2 + docs/kcl/segLen.md | 2 + docs/kcl/startProfileAt.md | 4 + docs/kcl/startSketchAt.md | 2 + docs/kcl/startSketchOn.md | 2 + docs/kcl/std.json | 348 ++++++++++++++++ docs/kcl/tangentialArc.md | 4 + docs/kcl/tangentialArcTo.md | 4 + docs/kcl/xLine.md | 4 + docs/kcl/xLineTo.md | 4 + docs/kcl/yLine.md | 4 + docs/kcl/yLineTo.md | 4 + e2e/playwright/flow-tests.spec.ts | 147 ++++++- e2e/playwright/snapshot-tests.spec.ts | 51 ++- ...ngine-scale-inch-2-Google-Chrome-linux.png | Bin 45117 -> 53789 bytes ...-engine-scale-mm-2-Google-Chrome-linux.png | Bin 46172 -> 54840 bytes ...e-with-none-z-up-1-Google-Chrome-linux.png | Bin 0 -> 76817 bytes src/clientSideScene/CameraControls.ts | 134 ++++--- src/clientSideScene/helpers.ts | 9 + src/clientSideScene/sceneEntities.ts | 248 +++++++++--- src/clientSideScene/sceneInfra.ts | 31 +- src/components/MemoryPanel.test.tsx | 21 +- src/components/ModelingMachineProvider.tsx | 241 ++++++----- src/components/Stream.tsx | 48 +-- src/components/TextEditor.tsx | 25 +- src/lang/KclSingleton.tsx | 21 +- src/lang/artifact.test.ts | 183 ++++++++- src/lang/modifyAst.test.ts | 88 ++++ src/lang/modifyAst.ts | 72 ++-- src/lang/recast.test.ts | 4 +- src/lang/std/engineConnection.ts | 55 ++- src/lang/std/sketch.ts | 11 +- src/lang/wasm.ts | 1 + src/lib/cameraControls.ts | 2 +- .../modelingCommandConfig.ts | 2 +- src/lib/selections.ts | 375 ++++++++---------- src/machines/modelingMachine.ts | 315 ++++++++------- src/useStore.ts | 5 + src/wasm-lib/kcl/src/executor.rs | 2 + src/wasm-lib/kcl/src/std/extrude.rs | 18 +- src/wasm-lib/kcl/src/std/sketch.rs | 1 + 63 files changed, 1854 insertions(+), 714 deletions(-) create mode 100644 e2e/playwright/snapshot-tests.spec.ts-snapshots/Sketch-on-face-with-none-z-up-1-Google-Chrome-linux.png diff --git a/docs/kcl/angleToMatchLengthX.md b/docs/kcl/angleToMatchLengthX.md index 8757a9bdfc..4b01e052a0 100644 --- a/docs/kcl/angleToMatchLengthX.md +++ b/docs/kcl/angleToMatchLengthX.md @@ -69,6 +69,8 @@ const part001 = startSketchOn('XY') }, } | { + // the face id the sketch is on + faceId: uuid, // The id of the face. id: uuid, // The original sketch group id of the object we are sketching on. diff --git a/docs/kcl/angleToMatchLengthY.md b/docs/kcl/angleToMatchLengthY.md index 1d4972e9e3..f1f369a8a2 100644 --- a/docs/kcl/angleToMatchLengthY.md +++ b/docs/kcl/angleToMatchLengthY.md @@ -69,6 +69,8 @@ const part001 = startSketchOn('XY') }, } | { + // the face id the sketch is on + faceId: uuid, // The id of the face. id: uuid, // The original sketch group id of the object we are sketching on. diff --git a/docs/kcl/angledLine.md b/docs/kcl/angledLine.md index 827e7b1bf4..576b8e39c3 100644 --- a/docs/kcl/angledLine.md +++ b/docs/kcl/angledLine.md @@ -76,6 +76,8 @@ startSketchOn('XY') }, } | { + // the face id the sketch is on + faceId: uuid, // The id of the face. id: uuid, // The original sketch group id of the object we are sketching on. @@ -244,6 +246,8 @@ startSketchOn('XY') }, } | { + // the face id the sketch is on + faceId: uuid, // The id of the face. id: uuid, // The original sketch group id of the object we are sketching on. diff --git a/docs/kcl/angledLineOfXLength.md b/docs/kcl/angledLineOfXLength.md index a909a12fab..494a2b860e 100644 --- a/docs/kcl/angledLineOfXLength.md +++ b/docs/kcl/angledLineOfXLength.md @@ -76,6 +76,8 @@ startSketchOn('XZ') }, } | { + // the face id the sketch is on + faceId: uuid, // The id of the face. id: uuid, // The original sketch group id of the object we are sketching on. @@ -244,6 +246,8 @@ startSketchOn('XZ') }, } | { + // the face id the sketch is on + faceId: uuid, // The id of the face. id: uuid, // The original sketch group id of the object we are sketching on. diff --git a/docs/kcl/angledLineOfYLength.md b/docs/kcl/angledLineOfYLength.md index 6f21a65ed7..6ecb934323 100644 --- a/docs/kcl/angledLineOfYLength.md +++ b/docs/kcl/angledLineOfYLength.md @@ -77,6 +77,8 @@ startSketchOn('YZ') }, } | { + // the face id the sketch is on + faceId: uuid, // The id of the face. id: uuid, // The original sketch group id of the object we are sketching on. @@ -245,6 +247,8 @@ startSketchOn('YZ') }, } | { + // the face id the sketch is on + faceId: uuid, // The id of the face. id: uuid, // The original sketch group id of the object we are sketching on. diff --git a/docs/kcl/angledLineThatIntersects.md b/docs/kcl/angledLineThatIntersects.md index ecbae1c0e3..7f833df091 100644 --- a/docs/kcl/angledLineThatIntersects.md +++ b/docs/kcl/angledLineThatIntersects.md @@ -82,6 +82,8 @@ const part001 = startSketchOn('XY') }, } | { + // the face id the sketch is on + faceId: uuid, // The id of the face. id: uuid, // The original sketch group id of the object we are sketching on. @@ -250,6 +252,8 @@ const part001 = startSketchOn('XY') }, } | { + // the face id the sketch is on + faceId: uuid, // The id of the face. id: uuid, // The original sketch group id of the object we are sketching on. diff --git a/docs/kcl/angledLineToX.md b/docs/kcl/angledLineToX.md index ea470eac49..2c5790b244 100644 --- a/docs/kcl/angledLineToX.md +++ b/docs/kcl/angledLineToX.md @@ -76,6 +76,8 @@ startSketchOn('XY') }, } | { + // the face id the sketch is on + faceId: uuid, // The id of the face. id: uuid, // The original sketch group id of the object we are sketching on. @@ -244,6 +246,8 @@ startSketchOn('XY') }, } | { + // the face id the sketch is on + faceId: uuid, // The id of the face. id: uuid, // The original sketch group id of the object we are sketching on. diff --git a/docs/kcl/angledLineToY.md b/docs/kcl/angledLineToY.md index a4f865f7d9..d28ed4e276 100644 --- a/docs/kcl/angledLineToY.md +++ b/docs/kcl/angledLineToY.md @@ -75,6 +75,8 @@ startSketchOn('XY') }, } | { + // the face id the sketch is on + faceId: uuid, // The id of the face. id: uuid, // The original sketch group id of the object we are sketching on. @@ -243,6 +245,8 @@ startSketchOn('XY') }, } | { + // the face id the sketch is on + faceId: uuid, // The id of the face. id: uuid, // The original sketch group id of the object we are sketching on. diff --git a/docs/kcl/arc.md b/docs/kcl/arc.md index d8ef4d2cef..1e8836dc01 100644 --- a/docs/kcl/arc.md +++ b/docs/kcl/arc.md @@ -86,6 +86,8 @@ startSketchOn('-YZ') }, } | { + // the face id the sketch is on + faceId: uuid, // The id of the face. id: uuid, // The original sketch group id of the object we are sketching on. @@ -254,6 +256,8 @@ startSketchOn('-YZ') }, } | { + // the face id the sketch is on + faceId: uuid, // The id of the face. id: uuid, // The original sketch group id of the object we are sketching on. diff --git a/docs/kcl/bezierCurve.md b/docs/kcl/bezierCurve.md index aa4a52d48f..12adab14c0 100644 --- a/docs/kcl/bezierCurve.md +++ b/docs/kcl/bezierCurve.md @@ -79,6 +79,8 @@ startSketchOn('XY') }, } | { + // the face id the sketch is on + faceId: uuid, // The id of the face. id: uuid, // The original sketch group id of the object we are sketching on. @@ -247,6 +249,8 @@ startSketchOn('XY') }, } | { + // the face id the sketch is on + faceId: uuid, // The id of the face. id: uuid, // The original sketch group id of the object we are sketching on. diff --git a/docs/kcl/circle.md b/docs/kcl/circle.md index 88b5d907d1..395d3cd6f1 100644 --- a/docs/kcl/circle.md +++ b/docs/kcl/circle.md @@ -71,6 +71,8 @@ const rectangle = startSketchOn('XY') }, } | { + // the face id the sketch is on + faceId: uuid, // The id of the face. id: uuid, // The original sketch group id of the object we are sketching on. @@ -135,6 +137,8 @@ const rectangle = startSketchOn('XY') }, } | { + // the face id the sketch is on + faceId: uuid, // The id of the face. id: uuid, // The original sketch group id of the object we are sketching on. @@ -302,6 +306,8 @@ const rectangle = startSketchOn('XY') }, } | { + // the face id the sketch is on + faceId: uuid, // The id of the face. id: uuid, // The original sketch group id of the object we are sketching on. diff --git a/docs/kcl/close.md b/docs/kcl/close.md index 596513613a..cd5d6aea1f 100644 --- a/docs/kcl/close.md +++ b/docs/kcl/close.md @@ -72,6 +72,8 @@ startSketchOn('YZ') }, } | { + // the face id the sketch is on + faceId: uuid, // The id of the face. id: uuid, // The original sketch group id of the object we are sketching on. @@ -240,6 +242,8 @@ startSketchOn('YZ') }, } | { + // the face id the sketch is on + faceId: uuid, // The id of the face. id: uuid, // The original sketch group id of the object we are sketching on. diff --git a/docs/kcl/extrude.md b/docs/kcl/extrude.md index 8e26f582f7..4eb330ab7a 100644 --- a/docs/kcl/extrude.md +++ b/docs/kcl/extrude.md @@ -67,6 +67,8 @@ startSketchOn('XY') }, } | { + // the face id the sketch is on + faceId: uuid, // The id of the face. id: uuid, // The original sketch group id of the object we are sketching on. diff --git a/docs/kcl/hole.md b/docs/kcl/hole.md index 1d043d8f07..7b85f95286 100644 --- a/docs/kcl/hole.md +++ b/docs/kcl/hole.md @@ -68,6 +68,8 @@ const square = startSketchOn('XY') }, } | { + // the face id the sketch is on + faceId: uuid, // The id of the face. id: uuid, // The original sketch group id of the object we are sketching on. @@ -236,6 +238,8 @@ const square = startSketchOn('XY') }, } | { + // the face id the sketch is on + faceId: uuid, // The id of the face. id: uuid, // The original sketch group id of the object we are sketching on. @@ -403,6 +407,8 @@ const square = startSketchOn('XY') }, } | { + // the face id the sketch is on + faceId: uuid, // The id of the face. id: uuid, // The original sketch group id of the object we are sketching on. diff --git a/docs/kcl/lastSegX.md b/docs/kcl/lastSegX.md index 6714035da3..088af85582 100644 --- a/docs/kcl/lastSegX.md +++ b/docs/kcl/lastSegX.md @@ -66,6 +66,8 @@ startSketchOn("YZ") }, } | { + // the face id the sketch is on + faceId: uuid, // The id of the face. id: uuid, // The original sketch group id of the object we are sketching on. diff --git a/docs/kcl/lastSegY.md b/docs/kcl/lastSegY.md index 57bf61e47e..ca5ab03233 100644 --- a/docs/kcl/lastSegY.md +++ b/docs/kcl/lastSegY.md @@ -66,6 +66,8 @@ startSketchOn("YZ") }, } | { + // the face id the sketch is on + faceId: uuid, // The id of the face. id: uuid, // The original sketch group id of the object we are sketching on. diff --git a/docs/kcl/line.md b/docs/kcl/line.md index 423a4aed85..fe12775fad 100644 --- a/docs/kcl/line.md +++ b/docs/kcl/line.md @@ -66,6 +66,8 @@ startSketchOn('-XY') }, } | { + // the face id the sketch is on + faceId: uuid, // The id of the face. id: uuid, // The original sketch group id of the object we are sketching on. @@ -234,6 +236,8 @@ startSketchOn('-XY') }, } | { + // the face id the sketch is on + faceId: uuid, // The id of the face. id: uuid, // The original sketch group id of the object we are sketching on. diff --git a/docs/kcl/lineTo.md b/docs/kcl/lineTo.md index 7f0453efa2..005d932c74 100644 --- a/docs/kcl/lineTo.md +++ b/docs/kcl/lineTo.md @@ -72,6 +72,8 @@ const part = rectShape([0, 0], 20, 20) }, } | { + // the face id the sketch is on + faceId: uuid, // The id of the face. id: uuid, // The original sketch group id of the object we are sketching on. @@ -240,6 +242,8 @@ const part = rectShape([0, 0], 20, 20) }, } | { + // the face id the sketch is on + faceId: uuid, // The id of the face. id: uuid, // The original sketch group id of the object we are sketching on. diff --git a/docs/kcl/patternCircular2d.md b/docs/kcl/patternCircular2d.md index 7b2cebbc38..52ae998921 100644 --- a/docs/kcl/patternCircular2d.md +++ b/docs/kcl/patternCircular2d.md @@ -80,6 +80,8 @@ const part = startSketchOn('XY') }, } | { + // the face id the sketch is on + faceId: uuid, // The id of the face. id: uuid, // The original sketch group id of the object we are sketching on. diff --git a/docs/kcl/patternLinear2d.md b/docs/kcl/patternLinear2d.md index 3c1702eabb..2034b66880 100644 --- a/docs/kcl/patternLinear2d.md +++ b/docs/kcl/patternLinear2d.md @@ -77,6 +77,8 @@ const part = startSketchOn('XY') }, } | { + // the face id the sketch is on + faceId: uuid, // The id of the face. id: uuid, // The original sketch group id of the object we are sketching on. diff --git a/docs/kcl/segAng.md b/docs/kcl/segAng.md index fddb2ee9cd..f8aa586424 100644 --- a/docs/kcl/segAng.md +++ b/docs/kcl/segAng.md @@ -69,6 +69,8 @@ const part001 = startSketchOn('XY') }, } | { + // the face id the sketch is on + faceId: uuid, // The id of the face. id: uuid, // The original sketch group id of the object we are sketching on. diff --git a/docs/kcl/segEndX.md b/docs/kcl/segEndX.md index 3df6b9bac7..c1ab1372f7 100644 --- a/docs/kcl/segEndX.md +++ b/docs/kcl/segEndX.md @@ -67,6 +67,8 @@ startSketchOn("YZ") }, } | { + // the face id the sketch is on + faceId: uuid, // The id of the face. id: uuid, // The original sketch group id of the object we are sketching on. diff --git a/docs/kcl/segEndY.md b/docs/kcl/segEndY.md index c165b07967..c2dd9e3554 100644 --- a/docs/kcl/segEndY.md +++ b/docs/kcl/segEndY.md @@ -67,6 +67,8 @@ startSketchOn("YZ") }, } | { + // the face id the sketch is on + faceId: uuid, // The id of the face. id: uuid, // The original sketch group id of the object we are sketching on. diff --git a/docs/kcl/segLen.md b/docs/kcl/segLen.md index 97f40fa54b..ae5f5271e5 100644 --- a/docs/kcl/segLen.md +++ b/docs/kcl/segLen.md @@ -67,6 +67,8 @@ startSketchOn("YZ") }, } | { + // the face id the sketch is on + faceId: uuid, // The id of the face. id: uuid, // The original sketch group id of the object we are sketching on. diff --git a/docs/kcl/startProfileAt.md b/docs/kcl/startProfileAt.md index 2c62fa3b81..0d6bb01eb1 100644 --- a/docs/kcl/startProfileAt.md +++ b/docs/kcl/startProfileAt.md @@ -57,6 +57,8 @@ startSketchOn('XY') }, } | { + // the face id the sketch is on + faceId: uuid, // The id of the face. id: uuid, // The original sketch group id of the object we are sketching on. @@ -128,6 +130,8 @@ startSketchOn('XY') }, } | { + // the face id the sketch is on + faceId: uuid, // The id of the face. id: uuid, // The original sketch group id of the object we are sketching on. diff --git a/docs/kcl/startSketchAt.md b/docs/kcl/startSketchAt.md index c537753666..52c7ea3d64 100644 --- a/docs/kcl/startSketchAt.md +++ b/docs/kcl/startSketchAt.md @@ -65,6 +65,8 @@ startSketchAt([0, 0]) }, } | { + // the face id the sketch is on + faceId: uuid, // The id of the face. id: uuid, // The original sketch group id of the object we are sketching on. diff --git a/docs/kcl/startSketchOn.md b/docs/kcl/startSketchOn.md index db64bad887..658d5a690c 100644 --- a/docs/kcl/startSketchOn.md +++ b/docs/kcl/startSketchOn.md @@ -254,6 +254,8 @@ string }, } | { + // the face id the sketch is on + faceId: uuid, // The id of the face. id: uuid, // The original sketch group id of the object we are sketching on. diff --git a/docs/kcl/std.json b/docs/kcl/std.json index 205d7c7e76..575d5c2442 100644 --- a/docs/kcl/std.json +++ b/docs/kcl/std.json @@ -308,6 +308,7 @@ "type": "object", "required": [ "__meta", + "faceId", "id", "sketchGroupId", "type", @@ -340,6 +341,11 @@ } } }, + "faceId": { + "description": "the face id the sketch is on", + "type": "string", + "format": "uuid" + }, "id": { "description": "The id of the face.", "type": "string", @@ -1308,6 +1314,7 @@ "type": "object", "required": [ "__meta", + "faceId", "id", "sketchGroupId", "type", @@ -1340,6 +1347,11 @@ } } }, + "faceId": { + "description": "the face id the sketch is on", + "type": "string", + "format": "uuid" + }, "id": { "description": "The id of the face.", "type": "string", @@ -2331,6 +2343,7 @@ "type": "object", "required": [ "__meta", + "faceId", "id", "sketchGroupId", "type", @@ -2363,6 +2376,11 @@ } } }, + "faceId": { + "description": "the face id the sketch is on", + "type": "string", + "format": "uuid" + }, "id": { "description": "The id of the face.", "type": "string", @@ -3302,6 +3320,7 @@ "type": "object", "required": [ "__meta", + "faceId", "id", "sketchGroupId", "type", @@ -3334,6 +3353,11 @@ } } }, + "faceId": { + "description": "the face id the sketch is on", + "type": "string", + "format": "uuid" + }, "id": { "description": "The id of the face.", "type": "string", @@ -4315,6 +4339,7 @@ "type": "object", "required": [ "__meta", + "faceId", "id", "sketchGroupId", "type", @@ -4347,6 +4372,11 @@ } } }, + "faceId": { + "description": "the face id the sketch is on", + "type": "string", + "format": "uuid" + }, "id": { "description": "The id of the face.", "type": "string", @@ -5286,6 +5316,7 @@ "type": "object", "required": [ "__meta", + "faceId", "id", "sketchGroupId", "type", @@ -5318,6 +5349,11 @@ } } }, + "faceId": { + "description": "the face id the sketch is on", + "type": "string", + "format": "uuid" + }, "id": { "description": "The id of the face.", "type": "string", @@ -6299,6 +6335,7 @@ "type": "object", "required": [ "__meta", + "faceId", "id", "sketchGroupId", "type", @@ -6331,6 +6368,11 @@ } } }, + "faceId": { + "description": "the face id the sketch is on", + "type": "string", + "format": "uuid" + }, "id": { "description": "The id of the face.", "type": "string", @@ -7270,6 +7312,7 @@ "type": "object", "required": [ "__meta", + "faceId", "id", "sketchGroupId", "type", @@ -7302,6 +7345,11 @@ } } }, + "faceId": { + "description": "the face id the sketch is on", + "type": "string", + "format": "uuid" + }, "id": { "description": "The id of the face.", "type": "string", @@ -8273,6 +8321,7 @@ "type": "object", "required": [ "__meta", + "faceId", "id", "sketchGroupId", "type", @@ -8305,6 +8354,11 @@ } } }, + "faceId": { + "description": "the face id the sketch is on", + "type": "string", + "format": "uuid" + }, "id": { "description": "The id of the face.", "type": "string", @@ -9244,6 +9298,7 @@ "type": "object", "required": [ "__meta", + "faceId", "id", "sketchGroupId", "type", @@ -9276,6 +9331,11 @@ } } }, + "faceId": { + "description": "the face id the sketch is on", + "type": "string", + "format": "uuid" + }, "id": { "description": "The id of the face.", "type": "string", @@ -10242,6 +10302,7 @@ "type": "object", "required": [ "__meta", + "faceId", "id", "sketchGroupId", "type", @@ -10274,6 +10335,11 @@ } } }, + "faceId": { + "description": "the face id the sketch is on", + "type": "string", + "format": "uuid" + }, "id": { "description": "The id of the face.", "type": "string", @@ -11213,6 +11279,7 @@ "type": "object", "required": [ "__meta", + "faceId", "id", "sketchGroupId", "type", @@ -11245,6 +11312,11 @@ } } }, + "faceId": { + "description": "the face id the sketch is on", + "type": "string", + "format": "uuid" + }, "id": { "description": "The id of the face.", "type": "string", @@ -12211,6 +12283,7 @@ "type": "object", "required": [ "__meta", + "faceId", "id", "sketchGroupId", "type", @@ -12243,6 +12316,11 @@ } } }, + "faceId": { + "description": "the face id the sketch is on", + "type": "string", + "format": "uuid" + }, "id": { "description": "The id of the face.", "type": "string", @@ -13182,6 +13260,7 @@ "type": "object", "required": [ "__meta", + "faceId", "id", "sketchGroupId", "type", @@ -13214,6 +13293,11 @@ } } }, + "faceId": { + "description": "the face id the sketch is on", + "type": "string", + "format": "uuid" + }, "id": { "description": "The id of the face.", "type": "string", @@ -14227,6 +14311,7 @@ "type": "object", "required": [ "__meta", + "faceId", "id", "sketchGroupId", "type", @@ -14259,6 +14344,11 @@ } } }, + "faceId": { + "description": "the face id the sketch is on", + "type": "string", + "format": "uuid" + }, "id": { "description": "The id of the face.", "type": "string", @@ -15198,6 +15288,7 @@ "type": "object", "required": [ "__meta", + "faceId", "id", "sketchGroupId", "type", @@ -15230,6 +15321,11 @@ } } }, + "faceId": { + "description": "the face id the sketch is on", + "type": "string", + "format": "uuid" + }, "id": { "description": "The id of the face.", "type": "string", @@ -16279,6 +16375,7 @@ "type": "object", "required": [ "__meta", + "faceId", "id", "sketchGroupId", "type", @@ -16311,6 +16408,11 @@ } } }, + "faceId": { + "description": "the face id the sketch is on", + "type": "string", + "format": "uuid" + }, "id": { "description": "The id of the face.", "type": "string", @@ -17250,6 +17352,7 @@ "type": "object", "required": [ "__meta", + "faceId", "id", "sketchGroupId", "type", @@ -17282,6 +17385,11 @@ } } }, + "faceId": { + "description": "the face id the sketch is on", + "type": "string", + "format": "uuid" + }, "id": { "description": "The id of the face.", "type": "string", @@ -18238,6 +18346,7 @@ "type": "object", "required": [ "__meta", + "faceId", "id", "sketchGroupId", "type", @@ -18270,6 +18379,11 @@ } } }, + "faceId": { + "description": "the face id the sketch is on", + "type": "string", + "format": "uuid" + }, "id": { "description": "The id of the face.", "type": "string", @@ -18584,6 +18698,7 @@ "type": "object", "required": [ "__meta", + "faceId", "id", "sketchGroupId", "type", @@ -18616,6 +18731,11 @@ } } }, + "faceId": { + "description": "the face id the sketch is on", + "type": "string", + "format": "uuid" + }, "id": { "description": "The id of the face.", "type": "string", @@ -19548,6 +19668,7 @@ "type": "object", "required": [ "__meta", + "faceId", "id", "sketchGroupId", "type", @@ -19580,6 +19701,11 @@ } } }, + "faceId": { + "description": "the face id the sketch is on", + "type": "string", + "format": "uuid" + }, "id": { "description": "The id of the face.", "type": "string", @@ -20521,6 +20647,7 @@ "type": "object", "required": [ "__meta", + "faceId", "id", "sketchGroupId", "type", @@ -20553,6 +20680,11 @@ } } }, + "faceId": { + "description": "the face id the sketch is on", + "type": "string", + "format": "uuid" + }, "id": { "description": "The id of the face.", "type": "string", @@ -21492,6 +21624,7 @@ "type": "object", "required": [ "__meta", + "faceId", "id", "sketchGroupId", "type", @@ -21524,6 +21657,11 @@ } } }, + "faceId": { + "description": "the face id the sketch is on", + "type": "string", + "format": "uuid" + }, "id": { "description": "The id of the face.", "type": "string", @@ -22527,6 +22665,7 @@ "type": "object", "required": [ "__meta", + "faceId", "id", "sketchGroupId", "type", @@ -22559,6 +22698,11 @@ } } }, + "faceId": { + "description": "the face id the sketch is on", + "type": "string", + "format": "uuid" + }, "id": { "description": "The id of the face.", "type": "string", @@ -29046,6 +29190,7 @@ "type": "object", "required": [ "__meta", + "faceId", "id", "sketchGroupId", "type", @@ -29078,6 +29223,11 @@ } } }, + "faceId": { + "description": "the face id the sketch is on", + "type": "string", + "format": "uuid" + }, "id": { "description": "The id of the face.", "type": "string", @@ -30013,6 +30163,7 @@ "type": "object", "required": [ "__meta", + "faceId", "id", "sketchGroupId", "type", @@ -30045,6 +30196,11 @@ } } }, + "faceId": { + "description": "the face id the sketch is on", + "type": "string", + "format": "uuid" + }, "id": { "description": "The id of the face.", "type": "string", @@ -30988,6 +31144,7 @@ "type": "object", "required": [ "__meta", + "faceId", "id", "sketchGroupId", "type", @@ -31020,6 +31177,11 @@ } } }, + "faceId": { + "description": "the face id the sketch is on", + "type": "string", + "format": "uuid" + }, "id": { "description": "The id of the face.", "type": "string", @@ -31950,6 +32112,7 @@ "type": "object", "required": [ "__meta", + "faceId", "id", "sketchGroupId", "type", @@ -31982,6 +32145,11 @@ } } }, + "faceId": { + "description": "the face id the sketch is on", + "type": "string", + "format": "uuid" + }, "id": { "description": "The id of the face.", "type": "string", @@ -33580,6 +33748,7 @@ "type": "object", "required": [ "__meta", + "faceId", "id", "sketchGroupId", "type", @@ -33612,6 +33781,11 @@ } } }, + "faceId": { + "description": "the face id the sketch is on", + "type": "string", + "format": "uuid" + }, "id": { "description": "The id of the face.", "type": "string", @@ -34563,6 +34737,7 @@ "type": "object", "required": [ "__meta", + "faceId", "id", "sketchGroupId", "type", @@ -34595,6 +34770,11 @@ } } }, + "faceId": { + "description": "the face id the sketch is on", + "type": "string", + "format": "uuid" + }, "id": { "description": "The id of the face.", "type": "string", @@ -35680,6 +35860,7 @@ "type": "object", "required": [ "__meta", + "faceId", "id", "sketchGroupId", "type", @@ -35712,6 +35893,11 @@ } } }, + "faceId": { + "description": "the face id the sketch is on", + "type": "string", + "format": "uuid" + }, "id": { "description": "The id of the face.", "type": "string", @@ -36651,6 +36837,7 @@ "type": "object", "required": [ "__meta", + "faceId", "id", "sketchGroupId", "type", @@ -36683,6 +36870,11 @@ } } }, + "faceId": { + "description": "the face id the sketch is on", + "type": "string", + "format": "uuid" + }, "id": { "description": "The id of the face.", "type": "string", @@ -37638,6 +37830,7 @@ "type": "object", "required": [ "__meta", + "faceId", "id", "sketchGroupId", "type", @@ -37670,6 +37863,11 @@ } } }, + "faceId": { + "description": "the face id the sketch is on", + "type": "string", + "format": "uuid" + }, "id": { "description": "The id of the face.", "type": "string", @@ -38609,6 +38807,7 @@ "type": "object", "required": [ "__meta", + "faceId", "id", "sketchGroupId", "type", @@ -38641,6 +38840,11 @@ } } }, + "faceId": { + "description": "the face id the sketch is on", + "type": "string", + "format": "uuid" + }, "id": { "description": "The id of the face.", "type": "string", @@ -39825,6 +40029,7 @@ "type": "object", "required": [ "__meta", + "faceId", "id", "sketchGroupId", "type", @@ -39857,6 +40062,11 @@ } } }, + "faceId": { + "description": "the face id the sketch is on", + "type": "string", + "format": "uuid" + }, "id": { "description": "The id of the face.", "type": "string", @@ -40789,6 +40999,7 @@ "type": "object", "required": [ "__meta", + "faceId", "id", "sketchGroupId", "type", @@ -40821,6 +41032,11 @@ } } }, + "faceId": { + "description": "the face id the sketch is on", + "type": "string", + "format": "uuid" + }, "id": { "description": "The id of the face.", "type": "string", @@ -43381,6 +43597,7 @@ "type": "object", "required": [ "__meta", + "faceId", "id", "sketchGroupId", "type", @@ -43413,6 +43630,11 @@ } } }, + "faceId": { + "description": "the face id the sketch is on", + "type": "string", + "format": "uuid" + }, "id": { "description": "The id of the face.", "type": "string", @@ -44345,6 +44567,7 @@ "type": "object", "required": [ "__meta", + "faceId", "id", "sketchGroupId", "type", @@ -44377,6 +44600,11 @@ } } }, + "faceId": { + "description": "the face id the sketch is on", + "type": "string", + "format": "uuid" + }, "id": { "description": "The id of the face.", "type": "string", @@ -46953,6 +47181,7 @@ "type": "object", "required": [ "__meta", + "faceId", "id", "sketchGroupId", "type", @@ -46985,6 +47214,11 @@ } } }, + "faceId": { + "description": "the face id the sketch is on", + "type": "string", + "format": "uuid" + }, "id": { "description": "The id of the face.", "type": "string", @@ -47944,6 +48178,7 @@ "type": "object", "required": [ "__meta", + "faceId", "id", "sketchGroupId", "type", @@ -47976,6 +48211,11 @@ } } }, + "faceId": { + "description": "the face id the sketch is on", + "type": "string", + "format": "uuid" + }, "id": { "description": "The id of the face.", "type": "string", @@ -48935,6 +49175,7 @@ "type": "object", "required": [ "__meta", + "faceId", "id", "sketchGroupId", "type", @@ -48967,6 +49208,11 @@ } } }, + "faceId": { + "description": "the face id the sketch is on", + "type": "string", + "format": "uuid" + }, "id": { "description": "The id of the face.", "type": "string", @@ -49926,6 +50172,7 @@ "type": "object", "required": [ "__meta", + "faceId", "id", "sketchGroupId", "type", @@ -49958,6 +50205,11 @@ } } }, + "faceId": { + "description": "the face id the sketch is on", + "type": "string", + "format": "uuid" + }, "id": { "description": "The id of the face.", "type": "string", @@ -50934,6 +51186,7 @@ "type": "object", "required": [ "__meta", + "faceId", "id", "sketchGroupId", "type", @@ -50966,6 +51219,11 @@ } } }, + "faceId": { + "description": "the face id the sketch is on", + "type": "string", + "format": "uuid" + }, "id": { "description": "The id of the face.", "type": "string", @@ -51295,6 +51553,7 @@ "type": "object", "required": [ "__meta", + "faceId", "id", "sketchGroupId", "type", @@ -51327,6 +51586,11 @@ } } }, + "faceId": { + "description": "the face id the sketch is on", + "type": "string", + "format": "uuid" + }, "id": { "description": "The id of the face.", "type": "string", @@ -52283,6 +52547,7 @@ "type": "object", "required": [ "__meta", + "faceId", "id", "sketchGroupId", "type", @@ -52315,6 +52580,11 @@ } } }, + "faceId": { + "description": "the face id the sketch is on", + "type": "string", + "format": "uuid" + }, "id": { "description": "The id of the face.", "type": "string", @@ -54160,6 +54430,7 @@ "type": "object", "required": [ "__meta", + "faceId", "id", "sketchGroupId", "type", @@ -54192,6 +54463,11 @@ } } }, + "faceId": { + "description": "the face id the sketch is on", + "type": "string", + "format": "uuid" + }, "id": { "description": "The id of the face.", "type": "string", @@ -54594,6 +54870,7 @@ "type": "object", "required": [ "__meta", + "faceId", "id", "sketchGroupId", "type", @@ -54626,6 +54903,11 @@ } } }, + "faceId": { + "description": "the face id the sketch is on", + "type": "string", + "format": "uuid" + }, "id": { "description": "The id of the face.", "type": "string", @@ -55565,6 +55847,7 @@ "type": "object", "required": [ "__meta", + "faceId", "id", "sketchGroupId", "type", @@ -55597,6 +55880,11 @@ } } }, + "faceId": { + "description": "the face id the sketch is on", + "type": "string", + "format": "uuid" + }, "id": { "description": "The id of the face.", "type": "string", @@ -56552,6 +56840,7 @@ "type": "object", "required": [ "__meta", + "faceId", "id", "sketchGroupId", "type", @@ -56584,6 +56873,11 @@ } } }, + "faceId": { + "description": "the face id the sketch is on", + "type": "string", + "format": "uuid" + }, "id": { "description": "The id of the face.", "type": "string", @@ -57523,6 +57817,7 @@ "type": "object", "required": [ "__meta", + "faceId", "id", "sketchGroupId", "type", @@ -57555,6 +57850,11 @@ } } }, + "faceId": { + "description": "the face id the sketch is on", + "type": "string", + "format": "uuid" + }, "id": { "description": "The id of the face.", "type": "string", @@ -58588,6 +58888,7 @@ "type": "object", "required": [ "__meta", + "faceId", "id", "sketchGroupId", "type", @@ -58620,6 +58921,11 @@ } } }, + "faceId": { + "description": "the face id the sketch is on", + "type": "string", + "format": "uuid" + }, "id": { "description": "The id of the face.", "type": "string", @@ -59559,6 +59865,7 @@ "type": "object", "required": [ "__meta", + "faceId", "id", "sketchGroupId", "type", @@ -59591,6 +59898,11 @@ } } }, + "faceId": { + "description": "the face id the sketch is on", + "type": "string", + "format": "uuid" + }, "id": { "description": "The id of the face.", "type": "string", @@ -60541,6 +60853,7 @@ "type": "object", "required": [ "__meta", + "faceId", "id", "sketchGroupId", "type", @@ -60573,6 +60886,11 @@ } } }, + "faceId": { + "description": "the face id the sketch is on", + "type": "string", + "format": "uuid" + }, "id": { "description": "The id of the face.", "type": "string", @@ -61512,6 +61830,7 @@ "type": "object", "required": [ "__meta", + "faceId", "id", "sketchGroupId", "type", @@ -61544,6 +61863,11 @@ } } }, + "faceId": { + "description": "the face id the sketch is on", + "type": "string", + "format": "uuid" + }, "id": { "description": "The id of the face.", "type": "string", @@ -62494,6 +62818,7 @@ "type": "object", "required": [ "__meta", + "faceId", "id", "sketchGroupId", "type", @@ -62526,6 +62851,11 @@ } } }, + "faceId": { + "description": "the face id the sketch is on", + "type": "string", + "format": "uuid" + }, "id": { "description": "The id of the face.", "type": "string", @@ -63465,6 +63795,7 @@ "type": "object", "required": [ "__meta", + "faceId", "id", "sketchGroupId", "type", @@ -63497,6 +63828,11 @@ } } }, + "faceId": { + "description": "the face id the sketch is on", + "type": "string", + "format": "uuid" + }, "id": { "description": "The id of the face.", "type": "string", @@ -64447,6 +64783,7 @@ "type": "object", "required": [ "__meta", + "faceId", "id", "sketchGroupId", "type", @@ -64479,6 +64816,11 @@ } } }, + "faceId": { + "description": "the face id the sketch is on", + "type": "string", + "format": "uuid" + }, "id": { "description": "The id of the face.", "type": "string", @@ -65418,6 +65760,7 @@ "type": "object", "required": [ "__meta", + "faceId", "id", "sketchGroupId", "type", @@ -65450,6 +65793,11 @@ } } }, + "faceId": { + "description": "the face id the sketch is on", + "type": "string", + "format": "uuid" + }, "id": { "description": "The id of the face.", "type": "string", diff --git a/docs/kcl/tangentialArc.md b/docs/kcl/tangentialArc.md index 6856988034..385a6a2431 100644 --- a/docs/kcl/tangentialArc.md +++ b/docs/kcl/tangentialArc.md @@ -75,6 +75,8 @@ startSketchOn('-YZ') }, } | { + // the face id the sketch is on + faceId: uuid, // The id of the face. id: uuid, // The original sketch group id of the object we are sketching on. @@ -243,6 +245,8 @@ startSketchOn('-YZ') }, } | { + // the face id the sketch is on + faceId: uuid, // The id of the face. id: uuid, // The original sketch group id of the object we are sketching on. diff --git a/docs/kcl/tangentialArcTo.md b/docs/kcl/tangentialArcTo.md index 5737a93f7d..4cc56d25a1 100644 --- a/docs/kcl/tangentialArcTo.md +++ b/docs/kcl/tangentialArcTo.md @@ -65,6 +65,8 @@ startSketchOn('-YZ') }, } | { + // the face id the sketch is on + faceId: uuid, // The id of the face. id: uuid, // The original sketch group id of the object we are sketching on. @@ -233,6 +235,8 @@ startSketchOn('-YZ') }, } | { + // the face id the sketch is on + faceId: uuid, // The id of the face. id: uuid, // The original sketch group id of the object we are sketching on. diff --git a/docs/kcl/xLine.md b/docs/kcl/xLine.md index 2206a9e032..2b7a138202 100644 --- a/docs/kcl/xLine.md +++ b/docs/kcl/xLine.md @@ -66,6 +66,8 @@ startSketchOn('YZ') }, } | { + // the face id the sketch is on + faceId: uuid, // The id of the face. id: uuid, // The original sketch group id of the object we are sketching on. @@ -234,6 +236,8 @@ startSketchOn('YZ') }, } | { + // the face id the sketch is on + faceId: uuid, // The id of the face. id: uuid, // The original sketch group id of the object we are sketching on. diff --git a/docs/kcl/xLineTo.md b/docs/kcl/xLineTo.md index 13008c89ac..b522f89f34 100644 --- a/docs/kcl/xLineTo.md +++ b/docs/kcl/xLineTo.md @@ -66,6 +66,8 @@ startSketchOn('XY') }, } | { + // the face id the sketch is on + faceId: uuid, // The id of the face. id: uuid, // The original sketch group id of the object we are sketching on. @@ -234,6 +236,8 @@ startSketchOn('XY') }, } | { + // the face id the sketch is on + faceId: uuid, // The id of the face. id: uuid, // The original sketch group id of the object we are sketching on. diff --git a/docs/kcl/yLine.md b/docs/kcl/yLine.md index bc26b9d601..81863241d9 100644 --- a/docs/kcl/yLine.md +++ b/docs/kcl/yLine.md @@ -66,6 +66,8 @@ startSketchOn('XY') }, } | { + // the face id the sketch is on + faceId: uuid, // The id of the face. id: uuid, // The original sketch group id of the object we are sketching on. @@ -234,6 +236,8 @@ startSketchOn('XY') }, } | { + // the face id the sketch is on + faceId: uuid, // The id of the face. id: uuid, // The original sketch group id of the object we are sketching on. diff --git a/docs/kcl/yLineTo.md b/docs/kcl/yLineTo.md index 6ef4465cb2..46069891f1 100644 --- a/docs/kcl/yLineTo.md +++ b/docs/kcl/yLineTo.md @@ -67,6 +67,8 @@ startSketchOn('XZ') }, } | { + // the face id the sketch is on + faceId: uuid, // The id of the face. id: uuid, // The original sketch group id of the object we are sketching on. @@ -235,6 +237,8 @@ startSketchOn('XZ') }, } | { + // the face id the sketch is on + faceId: uuid, // The id of the face. id: uuid, // The original sketch group id of the object we are sketching on. diff --git a/e2e/playwright/flow-tests.spec.ts b/e2e/playwright/flow-tests.spec.ts index dc43f6b365..059888a4f5 100644 --- a/e2e/playwright/flow-tests.spec.ts +++ b/e2e/playwright/flow-tests.spec.ts @@ -20,6 +20,8 @@ const commonPoints = { startAt: '[9.06, -12.22]', num1: 9.14, num2: 18.2, + // num1: 9.64, + // num2: 19.19, } test.beforeEach(async ({ context, page }) => { @@ -76,6 +78,7 @@ test('Basic sketch', async ({ page }) => { await expect(page.locator('.cm-content')).toHaveText( `const part001 = startSketchOn('-XZ')` ) + await u.closeDebugPanel() await page.waitForTimeout(300) // TODO detect animation ending, or disable animation @@ -86,7 +89,6 @@ test('Basic sketch', async ({ page }) => { |> startProfileAt(${commonPoints.startAt}, %)`) await page.waitForTimeout(100) - await u.closeDebugPanel() await page.mouse.click(startXPx + PUR * 20, 500 - PUR * 10) await page.waitForTimeout(100) @@ -625,7 +627,7 @@ test('Selections work on fresh and edited sketch', async ({ page }) => { const emptySpaceClick = () => page.mouse.click(728, 343).then(() => page.waitForTimeout(100)) const topHorzSegmentClick = () => - page.mouse.click(709, 289).then(() => page.waitForTimeout(100)) + page.mouse.click(709, 290).then(() => page.waitForTimeout(100)) const bottomHorzSegmentClick = () => page.mouse.click(767, 396).then(() => page.waitForTimeout(100)) @@ -640,13 +642,12 @@ test('Selections work on fresh and edited sketch', async ({ page }) => { await page.waitForTimeout(700) // wait for animation const startXPx = 600 + await u.closeDebugPanel() await page.mouse.click(startXPx + PUR * 10, 500 - PUR * 10) await expect(page.locator('.cm-content')) .toHaveText(`const part001 = startSketchOn('-XZ') |> startProfileAt(${commonPoints.startAt}, %)`) - await u.closeDebugPanel() - await page.mouse.click(startXPx + PUR * 20, 500 - PUR * 10) await expect(page.locator('.cm-content')) @@ -727,13 +728,18 @@ test('Selections work on fresh and edited sketch', async ({ page }) => { await emptySpaceClick() // select segment in editor than another segment in scene and check there are two cursors - await page.getByText(` |> line([-${commonPoints.num2}, 0], %)`).click() - await page.waitForTimeout(300) - await page.keyboard.down('Shift') - await expect(page.locator('.cm-cursor')).toHaveCount(1) + // TODO change this back to shift click in the scene, not cmd click in the editor await bottomHorzSegmentClick() - await page.keyboard.up('Shift') + + await expect(page.locator('.cm-cursor')).toHaveCount(1) + + await page.keyboard.down(process.platform === 'linux' ? 'Control' : 'Meta') + await page.waitForTimeout(100) + await page.getByText(` |> line([-${commonPoints.num2}, 0], %)`).click() + await expect(page.locator('.cm-cursor')).toHaveCount(2) + await page.waitForTimeout(500) + await page.keyboard.up(process.platform === 'linux' ? 'Control' : 'Meta') // clear selection by clicking on nothing await emptySpaceClick() @@ -918,13 +924,13 @@ test('Can add multiple sketches', async ({ page }) => { await page.waitForTimeout(500) // TODO detect animation ending, or disable animation const startXPx = 600 + await u.closeDebugPanel() await page.mouse.click(startXPx + PUR * 10, 500 - PUR * 10) await expect(page.locator('.cm-content')) .toHaveText(`const part001 = startSketchOn('-XZ') |> startProfileAt(${commonPoints.startAt}, %)`) await page.waitForTimeout(100) - await u.closeDebugPanel() await page.mouse.click(startXPx + PUR * 20, 500 - PUR * 10) await page.waitForTimeout(100) @@ -1372,10 +1378,129 @@ test('Snap to close works (at any scale)', async ({ page }) => { ) => `const part001 = startSketchOn('XZ') |> startProfileAt([${roundOff(scale * 87.68)}, ${roundOff(scale * 43.84)}], %) |> line([${roundOff(scale * 175.36)}, 0], %) -|> line([0, -${roundOff(scale * 175.37) + fudge}], %) +|> line([0, -${roundOff(scale * 175.36) + fudge}], %) |> close(%)` await doSnapAtDifferentScales([0, 100, 100], codeTemplate(0.01, 0.01)) await doSnapAtDifferentScales([0, 10000, 10000], codeTemplate()) }) + +test('Sketch on face', async ({ page, context }) => { + const u = getUtils(page) + await context.addInitScript(async () => { + localStorage.setItem( + 'persistCode', + `const part001 = startSketchOn('-XZ') + |> startProfileAt([3.29, 7.86], %) + |> line([2.48, 2.44], %) + |> line([2.66, 1.17], %) + |> line([3.75, 0.46], %) + |> line([4.99, -0.46], %) + |> line([3.3, -2.12], %) + |> line([2.16, -3.33], %) + |> line([0.85, -3.08], %) + |> line([-0.18, -3.36], %) + |> line([-3.86, -2.73], %) + |> line([-17.67, 0.85], %) + |> close(%) + |> extrude(5 + 7, %)` + ) + }) + + await page.setViewportSize({ width: 1200, height: 500 }) + await page.goto('/') + await u.waitForAuthSkipAppStart() + await expect( + page.getByRole('button', { name: 'Start Sketch' }) + ).not.toBeDisabled() + + await page.getByRole('button', { name: 'Start Sketch' }).click() + + let previousCodeContent = await page.locator('.cm-content').innerText() + + await page.mouse.click(793, 133) + + const firstClickPosition = [612, 238] + const secondClickPosition = [661, 242] + const thirdClickPosition = [609, 267] + + await page.waitForTimeout(300) + + await page.mouse.click(firstClickPosition[0], firstClickPosition[1]) + await expect(page.locator('.cm-content')).not.toHaveText(previousCodeContent) + previousCodeContent = await page.locator('.cm-content').innerText() + + await page.mouse.click(secondClickPosition[0], secondClickPosition[1]) + await expect(page.locator('.cm-content')).not.toHaveText(previousCodeContent) + previousCodeContent = await page.locator('.cm-content').innerText() + + await page.mouse.click(thirdClickPosition[0], thirdClickPosition[1]) + await expect(page.locator('.cm-content')).not.toHaveText(previousCodeContent) + previousCodeContent = await page.locator('.cm-content').innerText() + + await page.mouse.click(firstClickPosition[0], firstClickPosition[1]) + await expect(page.locator('.cm-content')).not.toHaveText(previousCodeContent) + previousCodeContent = await page.locator('.cm-content').innerText() + + await expect(page.locator('.cm-content')) + .toContainText(`const part002 = startSketchOn(part001, 'seg01') + |> startProfileAt([1.03, 1.03], %) + |> line([4.18, -0.35], %) + |> line([-4.44, -2.13], %) + |> close(%)`) + + await u.openAndClearDebugPanel() + await page.getByRole('button', { name: 'Exit Sketch' }).click() + await u.expectCmdLog('[data-message-type="execution-done"]') + + await u.updateCamPosition([1049, 239, 686]) + await u.closeDebugPanel() + + await page.getByText('startProfileAt([1.03, 1.03], %)').click() + await expect(page.getByRole('button', { name: 'Edit Sketch' })).toBeVisible() + await page.getByRole('button', { name: 'Edit Sketch' }).click() + await page.waitForTimeout(200) + + const pointToDragFirst = [691, 237] + await page.mouse.move(pointToDragFirst[0], pointToDragFirst[1]) + await page.mouse.down() + await page.mouse.move(pointToDragFirst[0] - 20, pointToDragFirst[1], { + steps: 5, + }) + await page.mouse.up() + await page.waitForTimeout(100) + await expect(page.locator('.cm-content')).not.toHaveText(previousCodeContent) + previousCodeContent = await page.locator('.cm-content').innerText() + + await expect(page.locator('.cm-content')) + .toContainText(`const part002 = startSketchOn(part001, 'seg01') +|> startProfileAt([1.03, 1.03], %) +|> line([2.81, -0.33], %) +|> line([-4.44, -2.13], %) +|> close(%)`) + + // exit sketch + await u.openAndClearDebugPanel() + await page.getByRole('button', { name: 'Exit Sketch' }).click() + await u.expectCmdLog('[data-message-type="execution-done"]') + + await page.getByText('startProfileAt([1.03, 1.03], %)').click() + + await expect(page.getByRole('button', { name: 'Extrude' })).not.toBeDisabled() + await page.getByRole('button', { name: 'Extrude' }).click() + + await expect(page.getByTestId('command-bar')).toBeVisible() + + await page.keyboard.press('Enter') + await expect(page.getByText('Confirm Extrude')).toBeVisible() + await page.keyboard.press('Enter') + + await expect(page.locator('.cm-content')) + .toContainText(`const part002 = startSketchOn(part001, 'seg01') +|> startProfileAt([1.03, 1.03], %) +|> line([2.81, -0.33], %) +|> line([-4.44, -2.13], %) +|> close(%) +|> extrude(5 + 7, %)`) +}) diff --git a/e2e/playwright/snapshot-tests.spec.ts b/e2e/playwright/snapshot-tests.spec.ts index 578e11205c..571e740da3 100644 --- a/e2e/playwright/snapshot-tests.spec.ts +++ b/e2e/playwright/snapshot-tests.spec.ts @@ -612,7 +612,7 @@ test('Client side scene scale should match engine scale mm', async ({ await page.mouse.click(startXPx + PUR * 10, 500 - PUR * 10) await expect(page.locator('.cm-content')) .toHaveText(`const part001 = startSketchOn('-XZ') - |> startProfileAt([230.03, -310.33], %)`) + |> startProfileAt([230.03, -310.32], %)`) await page.waitForTimeout(100) await u.closeDebugPanel() @@ -622,7 +622,7 @@ test('Client side scene scale should match engine scale mm', async ({ await expect(page.locator('.cm-content')) .toHaveText(`const part001 = startSketchOn('-XZ') - |> startProfileAt([230.03, -310.33], %) + |> startProfileAt([230.03, -310.32], %) |> line([232.2, 0], %)`) await page.getByRole('button', { name: 'Tangential Arc' }).click() @@ -632,7 +632,7 @@ test('Client side scene scale should match engine scale mm', async ({ await expect(page.locator('.cm-content')) .toHaveText(`const part001 = startSketchOn('-XZ') - |> startProfileAt([230.03, -310.33], %) + |> startProfileAt([230.03, -310.32], %) |> line([232.2, 0], %) |> tangentialArcTo([694.43, -78.12], %)`) @@ -658,3 +658,48 @@ test('Client side scene scale should match engine scale mm', async ({ maxDiffPixels: 100, }) }) + +test('Sketch on face with none z-up', async ({ page, context }) => { + const u = getUtils(page) + await context.addInitScript(async () => { + localStorage.setItem( + 'persistCode', + `const part001 = startSketchOn('-XZ') + |> startProfileAt([1.4, 2.47], %) + |> line({ to: [9.31, 10.55], tag: 'seg01' }, %) + |> line([11.91, -10.42], %) + |> close(%) + |> extrude(5 + 7, %) +const part002 = startSketchOn(part001, 'seg01') + |> startProfileAt([-2.89, 1.82], %) + |> line([4.68, 3.05], %) + |> line({ to: [0, -7.79], tag: 'seg02' }, %) + |> close(%) + |> extrude(5 + 7, %) +` + ) + }) + + await page.setViewportSize({ width: 1200, height: 500 }) + await page.goto('/') + await u.waitForAuthSkipAppStart() + await expect( + page.getByRole('button', { name: 'Start Sketch' }) + ).not.toBeDisabled() + + await page.getByRole('button', { name: 'Start Sketch' }).click() + let previousCodeContent = await page.locator('.cm-content').innerText() + + // click at 641, 135 + await page.mouse.click(641, 135) + await expect(page.locator('.cm-content')).not.toHaveText(previousCodeContent) + previousCodeContent = await page.locator('.cm-content').innerText() + + await page.waitForTimeout(300) + + await expect(page).toHaveScreenshot({ + maxDiffPixels: 100, + }) + + await page.waitForTimeout(200) +}) diff --git a/e2e/playwright/snapshot-tests.spec.ts-snapshots/Client-side-scene-scale-should-match-engine-scale-inch-2-Google-Chrome-linux.png b/e2e/playwright/snapshot-tests.spec.ts-snapshots/Client-side-scene-scale-should-match-engine-scale-inch-2-Google-Chrome-linux.png index 65b5adbbce18e47dc8dbb22cda570b1d887ea3f1..f877bfca59876c93fe041651c33f0534d457ebb8 100644 GIT binary patch literal 53789 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 HN@xNAYUniP literal 46172 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 B4XpqG literal 0 HcmV?d00001 diff --git a/src/clientSideScene/CameraControls.ts b/src/clientSideScene/CameraControls.ts index 960353bfda..21d667d609 100644 --- a/src/clientSideScene/CameraControls.ts +++ b/src/clientSideScene/CameraControls.ts @@ -425,6 +425,7 @@ export class CameraControls { if (this.camera instanceof OrthographicCamera) return const { x: px, y: py, z: pz } = this.camera.position const { x: qx, y: qy, z: qz, w: qw } = this.camera.quaternion + const oldCamUp = this.camera.up.clone() const aspect = window.innerWidth / window.innerHeight this.lastPerspectiveFov = this.camera.fov const { z_near, z_far } = calculateNearFarFromFOV(this.lastPerspectiveFov) @@ -436,7 +437,8 @@ export class CameraControls { z_near, z_far ) - this.camera.up.set(0, 0, 1) + + this.camera.up.copy(oldCamUp) this.camera.layers.enable(SKETCH_LAYER) if (DEBUG_SHOW_INTERSECTION_PLANE) this.camera.layers.enable(INTERSECTION_PLANE_LAYER) @@ -458,13 +460,14 @@ export class CameraControls { } private createPerspectiveCamera = () => { const { z_near, z_far } = calculateNearFarFromFOV(this.lastPerspectiveFov) + const previousCamUp = this.camera.up.clone() this.camera = new PerspectiveCamera( this.lastPerspectiveFov, window.innerWidth / window.innerHeight, z_near, z_far ) - this.camera.up.set(0, 0, 1) + this.camera.up.copy(previousCamUp) this.camera.layers.enable(SKETCH_LAYER) if (DEBUG_SHOW_INTERSECTION_PLANE) this.camera.layers.enable(INTERSECTION_PLANE_LAYER) @@ -618,7 +621,7 @@ export class CameraControls { didChange = true } - this.safeLookAtTarget() + this.safeLookAtTarget(this.camera.up) // Update the camera's matrices this.camera.updateMatrixWorld() @@ -683,48 +686,48 @@ export class CameraControls { targetAngle = -Math.PI / 2, duration = 500 ): Promise { - // should tween the camera so that it has an xPosition of 0, and forcing it's yPosition to be negative - // zPosition should stay the same - const xyRadius = Math.sqrt( - (this.target.x - this.camera.position.x) ** 2 + - (this.target.y - this.camera.position.y) ** 2 - ) - const xyAngle = Math.atan2( - this.camera.position.y - this.target.y, - this.camera.position.x - this.target.x - ) - this._isCamMovingCallback(true, true) return new Promise((resolve) => { + // should tween the camera so that it has an xPosition of 0, and forcing it's yPosition to be negative + // zPosition should stay the same + const xyRadius = Math.sqrt( + (this.target.x - this.camera.position.x) ** 2 + + (this.target.y - this.camera.position.y) ** 2 + ) + const xyAngle = Math.atan2( + this.camera.position.y - this.target.y, + this.camera.position.x - this.target.x + ) + const camAtTime = (obj: { angle: number }) => { + const x = xyRadius * Math.cos(obj.angle) + const y = xyRadius * Math.sin(obj.angle) + this.camera.position.set( + this.target.x + x, + this.target.y + y, + this.camera.position.z + ) + this.update() + this.onCameraChange() + } + const onComplete = (obj: { angle: number }) => { + camAtTime(obj) + this._isCamMovingCallback(false, true) + + // resolve after a couple of frames + requestAnimationFrame(() => { + requestAnimationFrame(() => resolve()) + }) + } + this._isCamMovingCallback(true, true) + + if (isReducedMotion()) { + onComplete({ angle: targetAngle }) + return + } + new TWEEN.Tween({ angle: xyAngle }) .to({ angle: targetAngle }, duration) - .onUpdate((obj) => { - const x = xyRadius * Math.cos(obj.angle) - const y = xyRadius * Math.sin(obj.angle) - this.camera.position.set( - this.target.x + x, - this.target.y + y, - this.camera.position.z - ) - this.update() - this.onCameraChange() - }) - .onComplete((obj) => { - const x = xyRadius * Math.cos(obj.angle) - const y = xyRadius * Math.sin(obj.angle) - this.camera.position.set( - this.target.x + x, - this.target.y + y, - this.camera.position.z - ) - this.update() - this.onCameraChange() - this._isCamMovingCallback(false, true) - - // resolve after a couple of frames - requestAnimationFrame(() => { - requestAnimationFrame(() => resolve()) - }) - }) + .onUpdate(camAtTime) + .onComplete(onComplete) .start() }) } @@ -778,6 +781,8 @@ export class CameraControls { targetQuaternion, animationProgress ) + const up = new Vector3(0, 0, 1).applyQuaternion(currentQ) + this.camera.up.copy(up) const currentTarget = tempVec.lerpVectors( initialTarget, targetPosition, @@ -802,7 +807,7 @@ export class CameraControls { const onComplete = async () => { if (isReducedMotion() && toOrthographic) { - cameraAtTime(0.99) + cameraAtTime(0.9999) this.useOrthographicCamera() } else if (toOrthographic) { await this.animateToOrthographic() @@ -863,37 +868,40 @@ export class CameraControls { animateFovChange() // Start the animation }) - animateToPerspective = () => + animateToPerspective = (targetCamUp = new Vector3(0, 0, 1)) => new Promise((resolve) => { - if (this.syncDirection === 'engineToClient') + if (this.syncDirection === 'engineToClient') { console.warn( 'animate To Perspective not design to work with engineToClient syncDirection.' ) + } this.isFovAnimationInProgress = true - // Immediately set the camera to perspective with a very low FOV const targetFov = this.fovBeforeOrtho // Target FOV for perspective this.lastPerspectiveFov = 4 let currentFov = 4 - this.camera.updateProjectionMatrix() - const fovAnimationStep = (targetFov - currentFov) / FRAMES_TO_ANIMATE_IN + const initialCameraUp = this.camera.up.clone() this.usePerspectiveCamera() + const tempVec = new Vector3() - const animateFovChange = () => { - if (this.camera instanceof OrthographicCamera) return - if (this.camera.fov < targetFov) { - // Increase the FOV - currentFov = Math.min(currentFov + fovAnimationStep, targetFov) - // this.camera.fov = currentFov - this.camera.updateProjectionMatrix() - this.dollyZoom(currentFov) - requestAnimationFrame(animateFovChange) // Continue the animation - } else { - // Set the flag to false as the FOV animation is complete - this.isFovAnimationInProgress = false - resolve(true) - } + const cameraAtTime = (t: number) => { + currentFov = + this.lastPerspectiveFov + (targetFov - this.lastPerspectiveFov) * t + const currentUp = tempVec.lerpVectors(initialCameraUp, targetCamUp, t) + this.camera.up.copy(currentUp) + this.dollyZoom(currentFov) } - animateFovChange() // Start the animation + + const onComplete = () => { + this.isFovAnimationInProgress = false + resolve(true) + } + + new TWEEN.Tween({ t: 0 }) + .to({ t: 1 }, isReducedMotion() ? 50 : FRAMES_TO_ANIMATE_IN * 16) // Assuming 60fps, hence 16ms per frame + .easing(TWEEN.Easing.Quadratic.InOut) + .onUpdate(({ t }) => cameraAtTime(t)) + .onComplete(onComplete) + .start() }) reactCameraPropertiesCallback: (a: ReactCameraProperties) => void = () => {} diff --git a/src/clientSideScene/helpers.ts b/src/clientSideScene/helpers.ts index 233ff3219c..4a2e2f0270 100644 --- a/src/clientSideScene/helpers.ts +++ b/src/clientSideScene/helpers.ts @@ -40,3 +40,12 @@ export function isQuaternionVertical(q: Quaternion) { // no x or y components means it's vertical return compareVec2Epsilon2([v.x, v.y], [0, 0]) } + +export function quaternionFromUpNForward(up: Vector3, forward: Vector3) { + const dummyCam = new PerspectiveCamera() + dummyCam.up.copy(up) + dummyCam.position.copy(forward) + dummyCam.lookAt(0, 0, 0) + dummyCam.updateMatrix() + return dummyCam.quaternion.clone() +} diff --git a/src/clientSideScene/sceneEntities.ts b/src/clientSideScene/sceneEntities.ts index cdee9ffd77..cdc33bfd18 100644 --- a/src/clientSideScene/sceneEntities.ts +++ b/src/clientSideScene/sceneEntities.ts @@ -5,7 +5,6 @@ import { Group, Intersection, LineCurve3, - Matrix4, Mesh, MeshBasicMaterial, Object3D, @@ -37,7 +36,7 @@ import { Y_AXIS, YZ_PLANE, } from './sceneInfra' -import { isQuaternionVertical } from './helpers' +import { isQuaternionVertical, quaternionFromUpNForward } from './helpers' import { CallExpression, getTangentialArcToInfo, @@ -55,7 +54,7 @@ import { } from 'lang/wasm' import { kclManager } from 'lang/KclSingleton' import { getNodeFromPath, getNodePathFromSourceRange } from 'lang/queryAst' -import { executeAst } from 'useStore' +import { executeAst, useStore } from 'useStore' import { engineCommandManager } from 'lang/std/engineConnection' import { createArcGeometry, @@ -70,16 +69,22 @@ import { changeSketchArguments, updateStartProfileAtArgs, } from 'lang/std/sketch' -import { isReducedMotion, throttle } from 'lib/utils' +import { throttle } from 'lib/utils' import { createArrayExpression, createCallExpressionStdLib, createLiteral, createPipeSubstitution, } from 'lang/modifyAst' -import { getEventForSegmentSelection } from 'lib/selections' +import { + getEventForSegmentSelection, + sendSelectEventToEngine, +} from 'lib/selections' import { getTangentPointFromPreviousArc } from 'lib/utils2d' import { createGridHelper, orthoScale, perspScale } from './helpers' +import { Models } from '@kittycad/lib' +import { v4 as uuidv4 } from 'uuid' +import { SketchDetails } from 'machines/modelingMachine' type DraftSegment = 'line' | 'tangentialArcTo' @@ -164,7 +169,7 @@ class SceneEntities { console.warn('createIntersectionPlane called when it already exists') return } - const hundredM = 1000000 + const hundredM = 100_0000 const planeGeometry = new PlaneGeometry(hundredM, hundredM) const planeMaterial = new MeshBasicMaterial({ color: 0xff0000, @@ -178,7 +183,12 @@ class SceneEntities { this.intersectionPlane.layers.set(INTERSECTION_PLANE_LAYER) this.scene.add(this.intersectionPlane) } - createSketchAxis(sketchPathToNode: PathToNode) { + createSketchAxis( + sketchPathToNode: PathToNode, + forward: [number, number, number], + up: [number, number, number], + sketchPosition?: [number, number, number] + ) { const orthoFactor = orthoScale(sceneInfra.camControls.camera) const baseXColor = 0x000055 const baseYColor = 0x550000 @@ -238,14 +248,12 @@ class SceneEntities { child.layers.set(SKETCH_LAYER) }) - const quat = quaternionFromSketchGroup( - sketchGroupFromPathToNode({ - pathToNode: sketchPathToNode, - ast: kclManager.ast, - programMemory: kclManager.programMemory, - }) + const quat = quaternionFromUpNForward( + new Vector3(...up), + new Vector3(...forward) ) this.axisGroup.setRotationFromQuaternion(quat) + sketchPosition && this.axisGroup.position.set(...sketchPosition) this.scene.add(this.axisGroup) } removeIntersectionPlane() { @@ -258,10 +266,16 @@ class SceneEntities { ast, // is draft line assumes the last segment is a draft line, and mods it as the user moves the mouse draftSegment, + forward, + up, + position, }: { sketchPathToNode: PathToNode ast?: Program draftSegment?: DraftSegment + forward: [number, number, number] + up: [number, number, number] + position?: [number, number, number] }) { sceneInfra.resetMouseListeners() this.createIntersectionPlane() @@ -286,6 +300,7 @@ class SceneEntities { if (!Array.isArray(sketchGroup?.value)) return this.sceneProgramMemory = programMemory const group = new Group() + position && group.position.set(...position) group.userData = { type: SKETCH_GROUP_SEGMENTS, pathToNode: sketchPathToNode, @@ -377,13 +392,18 @@ class SceneEntities { this.activeSegments[JSON.stringify(segPathToNode)] = seg }) - this.currentSketchQuaternion = quaternionFromSketchGroup(sketchGroup) + this.currentSketchQuaternion = quaternionFromUpNForward( + new Vector3(...up), + new Vector3(...forward) + ) group.setRotationFromQuaternion(this.currentSketchQuaternion) this.intersectionPlane && this.intersectionPlane.setRotationFromQuaternion( this.currentSketchQuaternion ) - + this.intersectionPlane && + position && + this.intersectionPlane.position.set(...position) this.scene.add(group) if (!draftSegment) { sceneInfra.setCallbacks({ @@ -453,7 +473,13 @@ class SceneEntities { kclManager.executeAstMock(modifiedAst, { updates: 'code' }) await this.tearDownSketch({ removeAxis: false }) - this.setupSketch({ sketchPathToNode, draftSegment }) + this.setupSketch({ + sketchPathToNode, + draftSegment, + forward, + up, + position, + }) }, onMove: (args) => { this.onDragSegment({ @@ -476,21 +502,37 @@ class SceneEntities { } updateAstAndRejigSketch = async ( sketchPathToNode: PathToNode, - modifiedAst: Program + modifiedAst: Program, + forward: [number, number, number], + up: [number, number, number], + origin: [number, number, number] ) => { await kclManager.updateAst(modifiedAst, false) await this.tearDownSketch({ removeAxis: false }) - this.setupSketch({ sketchPathToNode }) + this.setupSketch({ sketchPathToNode, forward, up, position: origin }) } - setUpDraftArc = async (sketchPathToNode: PathToNode) => { + setUpDraftArc = async ( + sketchPathToNode: PathToNode, + forward: [number, number, number], + up: [number, number, number] + ) => { await this.tearDownSketch({ removeAxis: false }) await new Promise((resolve) => setTimeout(resolve, 100)) - this.setupSketch({ sketchPathToNode, draftSegment: 'tangentialArcTo' }) + this.setupSketch({ + sketchPathToNode, + draftSegment: 'tangentialArcTo', + forward, + up, + }) } - setUpDraftLine = async (sketchPathToNode: PathToNode) => { + setUpDraftLine = async ( + sketchPathToNode: PathToNode, + forward: [number, number, number], + up: [number, number, number] + ) => { await this.tearDownSketch({ removeAxis: false }) await new Promise((resolve) => setTimeout(resolve, 100)) - this.setupSketch({ sketchPathToNode, draftSegment: 'line' }) + this.setupSketch({ sketchPathToNode, draftSegment: 'line', forward, up }) } onDraftLineMouseMove = () => {} prepareTruncatedMemoryAndAst = ( @@ -785,10 +827,10 @@ class SceneEntities { } } async animateAfterSketch() { - if (isReducedMotion()) { - sceneInfra.camControls.usePerspectiveCamera() - return - } + // if (isReducedMotion()) { + // sceneInfra.camControls.usePerspectiveCamera() + // return + // } await sceneInfra.camControls.animateToPerspective() } removeSketchGrid() { @@ -853,26 +895,81 @@ class SceneEntities { const type: DefaultPlane = selected.userData.type selected.material.color = defaultPlaneColor(type) }, - onClick: (args) => { + onClick: async (args) => { + const checkExtrudeFaceClick = async (): Promise => { + const { streamDimensions } = useStore.getState() + const { entity_id } = await sendSelectEventToEngine( + args?.mouseEvent, + document.getElementById('video-stream') as HTMLVideoElement, + streamDimensions + ) + if (!entity_id) return false + const artifact = engineCommandManager.artifactMap[entity_id] + if (artifact?.commandType !== 'solid3d_get_extrusion_face_info') + return false + const faceInfo: Models['FaceIsPlanar_type'] = ( + await engineCommandManager.sendSceneCommand({ + type: 'modeling_cmd_req', + cmd_id: uuidv4(), + cmd: { + type: 'face_is_planar', + object_id: entity_id, + }, + }) + )?.data?.data + if (!faceInfo?.origin || !faceInfo?.z_axis || !faceInfo?.y_axis) + return false + const { z_axis, origin, y_axis } = faceInfo + const pathToNode = getNodePathFromSourceRange( + kclManager.ast, + artifact.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], + extrudeSegmentPathToNode: pathToNode, + cap: + artifact?.additionalData?.type === 'cap' + ? artifact.additionalData.info + : 'none', + }, + }) + return true + } + + if (await checkExtrudeFaceClick()) return + if (!args || !args.intersects?.[0]) return if (args.mouseEvent.which !== 1) return const { intersects } = args const type = intersects?.[0].object.name || '' const posNorm = Number(intersects?.[0]?.normal?.z) > 0 let planeString: DefaultPlaneStr = posNorm ? 'XY' : '-XY' - let normal: [number, number, number] = posNorm ? [0, 0, 1] : [0, 0, -1] + let zAxis: [number, number, number] = posNorm ? [0, 0, 1] : [0, 0, -1] + let yAxis: [number, number, number] = [0, 1, 0] if (type === YZ_PLANE) { planeString = posNorm ? 'YZ' : '-YZ' - normal = posNorm ? [1, 0, 0] : [-1, 0, 0] + zAxis = posNorm ? [1, 0, 0] : [-1, 0, 0] + yAxis = [0, 0, 1] } else if (type === XZ_PLANE) { planeString = posNorm ? 'XZ' : '-XZ' - normal = posNorm ? [0, 1, 0] : [0, -1, 0] + zAxis = posNorm ? [0, 1, 0] : [0, -1, 0] + yAxis = [0, 0, 1] } sceneInfra.modelingSend({ type: 'Select default plane', data: { + type: 'defaultPlane', plane: planeString, - normal, + zAxis, + yAxis, }, }) }, @@ -1002,33 +1099,10 @@ export function sketchGroupFromPathToNode({ pathToNode, 'VariableDeclarator' ).node + // console.trace('where from?') return programMemory.root[varDec?.id?.name || ''] as SketchGroup } -export function quaternionFromSketchGroup( - sketchGroup: SketchGroup -): Quaternion { - // TODO figure what is happening in the executor that it's some times returning - // [x,y,z] and sometimes {x,y,z} - if (!sketchGroup?.zAxis) { - // sometimes sketchGroup is undefined, - // I don't quiet understand the circumstances yet - // and it's very intermittent so leaving this here for now - console.log('no zAxis', sketchGroup) - console.trace('no zAxis') - } - const zAxisVec = massageFormats(sketchGroup?.zAxis) - const yAxisVec = massageFormats(sketchGroup?.yAxis) - const xAxisVec = new Vector3().crossVectors(yAxisVec, zAxisVec).normalize() - - let yAxisVecNormalized = yAxisVec.clone().normalize() - let zAxisVecNormalized = zAxisVec.clone().normalize() - - let rotationMatrix = new Matrix4() - rotationMatrix.makeBasis(xAxisVec, yAxisVecNormalized, zAxisVecNormalized) - return new Quaternion().setFromRotationMatrix(rotationMatrix) -} - function colorSegment(object: any, color: number) { const segmentHead = getParentGroup(object, [ARROWHEAD, PROFILE_START]) if (segmentHead) { @@ -1063,10 +1137,68 @@ export function getSketchQuaternion( programMemory: kclManager.programMemory, }) const zAxis = sketchGroup?.zAxis || sketchNormalBackUp + return getQuaternionFromZAxis(massageFormats(zAxis)) +} +export async function getSketchOrientationDetails( + sketchPathToNode: PathToNode +): Promise<{ + quat: Quaternion + sketchDetails: SketchDetails +}> { + const sketchGroup = sketchGroupFromPathToNode({ + pathToNode: sketchPathToNode, + ast: kclManager.ast, + programMemory: kclManager.programMemory, + }) + if (sketchGroup.on.type === 'plane') { + const zAxis = sketchGroup?.zAxis + return { + quat: getQuaternionFromZAxis(massageFormats(zAxis)), + sketchDetails: { + sketchPathToNode, + zAxis: [zAxis.x, zAxis.y, zAxis.z], + yAxis: [sketchGroup.yAxis.x, sketchGroup.yAxis.y, sketchGroup.yAxis.z], + origin: [0, 0, 0], + }, + } + } + if (sketchGroup.on.type === 'face') { + const faceInfo: Models['FaceIsPlanar_type'] = ( + await engineCommandManager.sendSceneCommand({ + type: 'modeling_cmd_req', + cmd_id: uuidv4(), + cmd: { + type: 'face_is_planar', + object_id: sketchGroup.on.faceId, + }, + }) + )?.data?.data + if (!faceInfo?.origin || !faceInfo?.z_axis || !faceInfo?.y_axis) + throw new Error('faceInfo') + const { z_axis, y_axis, origin } = faceInfo + const quaternion = quaternionFromUpNForward( + new Vector3(y_axis.x, y_axis.y, y_axis.z), + new Vector3(z_axis.x, z_axis.y, z_axis.z) + ) + return { + quat: quaternion, + sketchDetails: { + sketchPathToNode, + zAxis: [z_axis.x, z_axis.y, z_axis.z], + yAxis: [y_axis.x, y_axis.y, y_axis.z], + origin: [origin.x, origin.y, origin.z], + }, + } + } + throw new Error( + 'sketchGroup.on.type not recognized, has a new type been added?' + ) +} + +export function getQuaternionFromZAxis(zAxis: Vector3): Quaternion { const dummyCam = new PerspectiveCamera() dummyCam.up.set(0, 0, 1) - const _zAxis = massageFormats(zAxis) - dummyCam.position.copy(_zAxis) + dummyCam.position.copy(zAxis) dummyCam.lookAt(0, 0, 0) dummyCam.updateMatrix() const quaternion = dummyCam.quaternion.clone() @@ -1075,7 +1207,7 @@ export function getSketchQuaternion( // because vertical quaternions are a gimbal lock, for the orbit controls // it's best to set them explicitly to the vertical position with a known good camera up - if (isVert && _zAxis.z < 0) { + if (isVert && zAxis.z < 0) { quaternion.set(0, 1, 0, 0) } else if (isVert) { quaternion.set(0, 0, 0, 1) diff --git a/src/clientSideScene/sceneInfra.ts b/src/clientSideScene/sceneInfra.ts index 4a65623fc8..cf8a3bea11 100644 --- a/src/clientSideScene/sceneInfra.ts +++ b/src/clientSideScene/sceneInfra.ts @@ -37,8 +37,10 @@ export const ZOOM_MAGIC_NUMBER = 63.5 export const INTERSECTION_PLANE_LAYER = 1 export const SKETCH_LAYER = 2 -export const DEBUG_SHOW_INTERSECTION_PLANE = false -export const DEBUG_SHOW_BOTH_SCENES = false + +// redundant types so that it can be changed temporarily but CI will catch the wrong type +export const DEBUG_SHOW_INTERSECTION_PLANE: false = false +export const DEBUG_SHOW_BOTH_SCENES: false = false export const RAYCASTABLE_PLANE = 'raycastable-plane' export const DEFAULT_PLANES = 'default-planes' @@ -97,13 +99,13 @@ class SceneInfra { _baseUnitMultiplier = 1 onDragCallback: (arg: OnDragCallbackArgs) => void = () => {} onMoveCallback: (arg: OnMoveCallbackArgs) => void = () => {} - onClickCallback: (arg?: OnClickCallbackArgs) => void = () => {} + onClickCallback: (arg: OnClickCallbackArgs) => void = () => {} onMouseEnter: (arg: OnMouseEnterLeaveArgs) => void = () => {} onMouseLeave: (arg: OnMouseEnterLeaveArgs) => void = () => {} setCallbacks = (callbacks: { onDrag?: (arg: OnDragCallbackArgs) => void onMove?: (arg: OnMoveCallbackArgs) => void - onClick?: (arg?: OnClickCallbackArgs) => void + onClick?: (arg: OnClickCallbackArgs) => void onMouseEnter?: (arg: OnMouseEnterLeaveArgs) => void onMouseLeave?: (arg: OnMouseEnterLeaveArgs) => void }) => { @@ -272,16 +274,19 @@ class SceneInfra { let transformedPoint = intersectPoint.clone() if (transformedPoint) { transformedPoint.applyQuaternion(inversePlaneQuaternion) - transformedPoint?.sub( - new Vector3(...planePosition).applyQuaternion(inversePlaneQuaternion) - ) } + const twoD = new Vector2( + // I think the intersection plane doesn't get scale when nearly everything else does, maybe that should change + transformedPoint.x / this._baseUnitMultiplier, + transformedPoint.y / this._baseUnitMultiplier + ) // z should be 0 + const planePositionCorrected = new Vector3( + ...planePosition + ).applyQuaternion(inversePlaneQuaternion) + twoD.sub(new Vector2(...planePositionCorrected)) return { - twoD: new Vector2( - transformedPoint.x / this._baseUnitMultiplier, - transformedPoint.y / this._baseUnitMultiplier - ), // z should be 0 + twoD, threeD: intersectPoint.divideScalar(this._baseUnitMultiplier), intersection: planeIntersects[0], } @@ -464,7 +469,7 @@ class SceneInfra { intersects, }) } else { - this.onClickCallback() + this.onClickCallback({ mouseEvent, intersects }) } // Clear the selected state whether it was dragged or not this.selected = null @@ -478,7 +483,7 @@ class SceneInfra { intersects, }) } else { - this.onClickCallback() + this.onClickCallback({ mouseEvent, intersects }) } } showDefaultPlanes() { diff --git a/src/components/MemoryPanel.test.tsx b/src/components/MemoryPanel.test.tsx index 7e971dfdd9..8bfffd4ca6 100644 --- a/src/components/MemoryPanel.test.tsx +++ b/src/components/MemoryPanel.test.tsx @@ -38,7 +38,26 @@ describe('processMemory', () => { myVar: 5, myFn: undefined, otherVar: 3, - theExtrude: [], + theExtrude: [ + { + type: 'extrudePlane', + position: [0, 0, 0], + rotation: [0, 0, 0, 1], + faceId: expect.any(String), + name: '', + id: expect.any(String), + sourceRange: [170, 194], + }, + { + type: 'extrudePlane', + position: [0, 0, 0], + rotation: [0, 0, 0, 1], + faceId: expect.any(String), + name: '', + id: expect.any(String), + sourceRange: [202, 230], + }, + ], theSketch: [ { type: 'ToPoint', to: [-3.35, 0.17], from: [0, 0], name: '' }, { type: 'ToPoint', to: [0.98, 5.16], from: [-3.35, 0.17], name: '' }, diff --git a/src/components/ModelingMachineProvider.tsx b/src/components/ModelingMachineProvider.tsx index 119bdba24a..774bdfde98 100644 --- a/src/components/ModelingMachineProvider.tsx +++ b/src/components/ModelingMachineProvider.tsx @@ -23,9 +23,9 @@ import { applyConstraintAngleLength } from './Toolbar/setAngleLength' import { pathMapToSelections } from 'lang/util' import { useStore } from 'useStore' import { + Selections, canExtrudeSelection, handleSelectionBatch, - handleSelectionWithShift, isSelectionLastLine, isSketchPipe, } from 'lib/selections' @@ -34,14 +34,20 @@ import { applyConstraintAbsDistance } from './Toolbar/SetAbsDistance' import useStateMachineCommands from 'hooks/useStateMachineCommands' import { modelingMachineConfig } from 'lib/commandBarConfigs/modelingCommandConfig' import { sceneInfra } from 'clientSideScene/sceneInfra' -import { getSketchQuaternion } from 'clientSideScene/sceneEntities' -import { startSketchOnDefault } from 'lang/modifyAst' -import { Program } from 'lang/wasm' -import { isSingleCursorInPipe } from 'lang/queryAst' +import { + getSketchQuaternion, + getSketchOrientationDetails, +} from 'clientSideScene/sceneEntities' +import { sketchOnExtrudedFace, startSketchOnDefault } from 'lang/modifyAst' +import { Program, parse } from 'lang/wasm' +import { getNodePathFromSourceRange, isSingleCursorInPipe } from 'lang/queryAst' import { TEST } from 'env' import { exportFromEngine } from 'lib/exportFromEngine' import { Models } from '@kittycad/lib/dist/types/src' import toast from 'react-hot-toast' +import { EditorSelection } from '@uiw/react-codemirror' +import { Vector3 } from 'three' +import { quaternionFromUpNForward } from 'clientSideScene/helpers' type MachineContext = { state: StateFrom @@ -69,9 +75,15 @@ export const ModelingMachineProvider = ({ const streamRef = useRef(null) useSetupEngineManager(streamRef, token) - const { isShiftDown, editorView } = useStore((s) => ({ + const { + isShiftDown, + editorView, + setLastCodeMirrorSelectionUpdatedFromScene, + } = useStore((s) => ({ isShiftDown: s.isShiftDown, editorView: s.editorView, + setLastCodeMirrorSelectionUpdatedFromScene: + s.setLastCodeMirrorSelectionUpdatedFromScene, })) // Settings machine setup @@ -92,92 +104,98 @@ export const ModelingMachineProvider = ({ { actions: { 'sketch exit execute': () => { - kclManager.executeAst() + try { + kclManager.executeAst(parse(kclManager.code)) + } catch (e) { + kclManager.executeAst() + } }, 'Set selection': assign(({ selectionRanges }, event) => { if (event.type !== 'Set selection') return {} // this was needed for ts after adding 'Set selection' action to on done modal events const setSelections = event.data if (!editorView) return {} - if (setSelections.selectionType === 'mirrorCodeMirrorSelections') - return { selectionRanges: setSelections.selection } - else if (setSelections.selectionType === 'otherSelection') { + const dispatchSelection = (selection?: EditorSelection) => { + if (!selection) return // TODO less of hack for the below please + setLastCodeMirrorSelectionUpdatedFromScene(Date.now()) + setTimeout(() => editorView.dispatch({ selection })) + } + let selections: Selections = { + codeBasedSelections: [], + otherSelections: [], + } + if (setSelections.selectionType === 'singleCodeCursor') { + if (!setSelections.selection && isShiftDown) { + } else if (!setSelections.selection && !isShiftDown) { + selections = { + codeBasedSelections: [], + otherSelections: [], + } + } else if (setSelections.selection && !isShiftDown) { + selections = { + codeBasedSelections: [setSelections.selection], + otherSelections: [], + } + } else if (setSelections.selection && isShiftDown) { + selections = { + codeBasedSelections: [ + ...selectionRanges.codeBasedSelections, + setSelections.selection, + ], + otherSelections: selectionRanges.otherSelections, + } + } + const { + engineEvents, codeMirrorSelection, - selectionRangeTypeMap, - otherSelections, - } = handleSelectionWithShift({ - otherSelection: setSelections.selection, - currentSelections: selectionRanges, - isShiftDown, - }) - setTimeout(() => { - editorView.dispatch({ - selection: codeMirrorSelection, - }) + updateSceneObjectColors, + } = handleSelectionBatch({ + selections, }) + codeMirrorSelection && dispatchSelection(codeMirrorSelection) + engineEvents && + engineEvents.forEach((event) => + engineCommandManager.sendSceneCommand(event) + ) + updateSceneObjectColors() return { - selectionRangeTypeMap, - selectionRanges: { - codeBasedSelections: selectionRanges.codeBasedSelections, - otherSelections, - }, + selectionRanges: selections, } - } else if (setSelections.selectionType === 'singleCodeCursor') { - // This DOES NOT set the `selectionRanges` in xstate context - // instead it updates/dispatches to the editor, which in turn updates the xstate context - // I've found this the best way to deal with the editor without causing an infinite loop - // and really we want the editor to be in charge of cursor positions and for `selectionRanges` mirror it - // because we want to respect the user manually placing the cursor too. - - // for more details on how selections see `src/lib/selections.ts`. + } - const { - codeMirrorSelection, - selectionRangeTypeMap, - otherSelections, - } = handleSelectionWithShift({ - codeSelection: setSelections.selection, - currentSelections: selectionRanges, - isShiftDown, - }) - if (codeMirrorSelection) { - setTimeout(() => { - editorView.dispatch({ - selection: codeMirrorSelection, - }) - }) + if (setSelections.selectionType === 'mirrorCodeMirrorSelections') { + return { + selectionRanges: setSelections.selection, } - if (!setSelections.selection) { - return { - selectionRangeTypeMap, - selectionRanges: { - codeBasedSelections: selectionRanges.codeBasedSelections, - otherSelections, - }, + } + + if (setSelections.selectionType === 'otherSelection') { + if (isShiftDown) { + selections = { + codeBasedSelections: selectionRanges.codeBasedSelections, + otherSelections: [setSelections.selection], + } + } else { + selections = { + codeBasedSelections: [], + otherSelections: [setSelections.selection], } } + const { engineEvents, updateSceneObjectColors } = + handleSelectionBatch({ + selections, + }) + engineEvents && + engineEvents.forEach((event) => + engineCommandManager.sendSceneCommand(event) + ) + updateSceneObjectColors() return { - selectionRangeTypeMap, - selectionRanges: { - codeBasedSelections: selectionRanges.codeBasedSelections, - otherSelections, - }, + selectionRanges: selections, } } - // This DOES NOT set the `selectionRanges` in xstate context - // same as comment above - const { codeMirrorSelection, selectionRangeTypeMap } = - handleSelectionBatch({ - selections: setSelections.selection, - }) - if (codeMirrorSelection) { - setTimeout(() => { - editorView.dispatch({ - selection: codeMirrorSelection, - }) - }) - } - return { selectionRangeTypeMap } + + return {} }), 'Engine export': (_, event) => { if (event.type !== 'Export' || TEST) return @@ -255,10 +273,10 @@ export const ModelingMachineProvider = ({ kclManager.kclErrors.length === 0 && kclManager.ast.body.length > 0, }, services: { - 'AST-undo-startSketchOn': async ({ sketchPathToNode }) => { - if (!sketchPathToNode) return + 'AST-undo-startSketchOn': async ({ sketchDetails }) => { + if (!sketchDetails) return const newAst: Program = JSON.parse(JSON.stringify(kclManager.ast)) - const varDecIndex = sketchPathToNode[1][0] + const varDecIndex = sketchDetails.sketchPathToNode[1][0] // remove body item at varDecIndex newAst.body = newAst.body.filter((_, i) => i !== varDecIndex) await kclManager.executeAstMock(newAst, { updates: 'code' }) @@ -267,28 +285,69 @@ export const ModelingMachineProvider = ({ onDrag: () => {}, }) }, - 'animate-to-face': async (_, { data: { plane, normal } }) => { + 'animate-to-face': async (_, { data }) => { + if (data.type === 'extrudeFace') { + const { modifiedAst, pathToNode: pathToNewSketchNode } = + sketchOnExtrudedFace( + kclManager.ast, + data.extrudeSegmentPathToNode, + kclManager.programMemory, + data.cap + ) + await kclManager.executeAstMock(modifiedAst, { updates: 'code' }) + + const forward = new Vector3(...data.zAxis) + const up = new Vector3(...data.yAxis) + + let target = new Vector3(...data.position).multiplyScalar( + sceneInfra._baseUnitMultiplier + ) + const quaternion = quaternionFromUpNForward(up, forward) + await sceneInfra.camControls.tweenCameraToQuaternion( + quaternion, + target + ) + + return { + sketchPathToNode: pathToNewSketchNode, + zAxis: data.zAxis, + yAxis: data.yAxis, + origin: data.position, + } + } const { modifiedAst, pathToNode } = startSketchOnDefault( kclManager.ast, - plane + data.plane ) await kclManager.updateAst(modifiedAst, false) - const quaternion = getSketchQuaternion(pathToNode, normal) - await sceneInfra.camControls.tweenCameraToQuaternion(quaternion) + const quat = await getSketchQuaternion(pathToNode, data.zAxis) + await sceneInfra.camControls.tweenCameraToQuaternion(quat) return { sketchPathToNode: pathToNode, - sketchNormalBackUp: normal, + zAxis: data.zAxis, + yAxis: data.yAxis, + origin: [0, 0, 0], } }, - 'animate-to-sketch': async ({ - sketchPathToNode, - sketchNormalBackUp, - }) => { - const quaternion = getSketchQuaternion( - sketchPathToNode || [], - sketchNormalBackUp + 'animate-to-sketch': async ({ selectionRanges }) => { + const sourceRange = selectionRanges.codeBasedSelections[0].range + const sketchPathToNode = getNodePathFromSourceRange( + kclManager.ast, + sourceRange + ) + const info = await getSketchOrientationDetails(sketchPathToNode || []) + await sceneInfra.camControls.tweenCameraToQuaternion( + info.quat, + new Vector3(...info.sketchDetails.origin) ) - await sceneInfra.camControls.tweenCameraToQuaternion(quaternion) + return { + sketchPathToNode: sketchPathToNode || [], + zAxis: info.sketchDetails.zAxis || null, + yAxis: info.sketchDetails.yAxis || null, + origin: info.sketchDetails.origin.map( + (a) => a / sceneInfra._baseUnitMultiplier + ) as [number, number, number], + } }, 'Get horizontal info': async ({ selectionRanges, diff --git a/src/components/Stream.tsx b/src/components/Stream.tsx index e7108db842..41120f19be 100644 --- a/src/components/Stream.tsx +++ b/src/components/Stream.tsx @@ -1,15 +1,14 @@ import { MouseEventHandler, useEffect, useRef, useState } from 'react' -import { v4 as uuidv4 } from 'uuid' import { useStore } from '../useStore' import { getNormalisedCoordinates } from '../lib/utils' import Loading from './Loading' import { useSettingsAuthContext } from 'hooks/useSettingsAuthContext' -import { Models } from '@kittycad/lib' -import { engineCommandManager } from '../lang/std/engineConnection' import { useModelingContext } from 'hooks/useModelingContext' import { useKclContext } from 'lang/KclSingleton' import { ClientSideScene } from 'clientSideScene/ClientSideSceneComp' import { NetworkHealthState, useNetworkStatus } from './NetworkHealthIndicator' +import { butName } from 'lib/cameraControls' +import { sendSelectEventToEngine } from 'lib/selections' export const Stream = ({ className = '' }: { className?: string }) => { const [isLoading, setIsLoading] = useState(true) @@ -60,50 +59,14 @@ export const Stream = ({ className = '' }: { className?: string }) => { setClickCoords({ x, y }) } - const handleMouseUp: MouseEventHandler = ({ - clientX, - clientY, - ctrlKey, - }) => { + const handleMouseUp: MouseEventHandler = (e) => { if (!videoRef.current) return setButtonDownInStream(undefined) if (state.matches('Sketch')) return if (state.matches('Sketch no face')) return - const { x, y } = getNormalisedCoordinates({ - clientX, - clientY, - el: videoRef.current, - ...streamDimensions, - }) - - const newCmdId = uuidv4() - const interaction = ctrlKey ? 'pan' : 'rotate' - - const command: Models['WebSocketRequest_type'] = { - type: 'modeling_cmd_req', - cmd: { - type: 'camera_drag_end', - interaction, - window: { x, y }, - }, - cmd_id: newCmdId, - } - if (!didDragInStream) { - command.cmd = { - type: 'select_with_point', - selected_at_window: { x, y }, - selection_type: 'add', - } - engineCommandManager.sendSceneCommand(command) - } else if (didDragInStream) { - command.cmd = { - type: 'handle_mouse_drag_end', - window: { x, y }, - } - void engineCommandManager.sendSceneCommand(command) - } else { - engineCommandManager.sendSceneCommand(command) + if (!didDragInStream && butName(e).left) { + sendSelectEventToEngine(e, videoRef.current, streamDimensions) } setDidDragInStream(false) @@ -143,6 +106,7 @@ export const Stream = ({ className = '' }: { className?: string }) => { className={`w-full cursor-pointer h-full ${isExecuting && 'blur-md'}`} disablePictureInPicture style={{ transitionDuration: '200ms', transitionProperty: 'filter' }} + id="video-stream" /> {!isNetworkOkay && !isLoading && ( diff --git a/src/components/TextEditor.tsx b/src/components/TextEditor.tsx index b668edb1a1..e11e24a17c 100644 --- a/src/components/TextEditor.tsx +++ b/src/components/TextEditor.tsx @@ -3,6 +3,7 @@ import ReactCodeMirror, { Extension, ViewUpdate, keymap, + SelectionRange, } from '@uiw/react-codemirror' import { TEST } from 'env' import { useCommandsContext } from 'hooks/useCommandsContext' @@ -75,7 +76,7 @@ export const TextEditor = ({ }) const { - context: { selectionRanges, selectionRangeTypeMap }, + context: { selectionRanges }, send, state, } = useModelingContext() @@ -91,10 +92,27 @@ export const TextEditor = ({ if (isNetworkOkay) kclManager.setCodeAndExecute(newCode) else kclManager.setCode(newCode) } //, []); + const lastSelection = useRef('') const onUpdate = (viewUpdate: ViewUpdate) => { if (!editorView) { setEditorView(viewUpdate.view) } + const selString = stringifyRanges( + viewUpdate?.state?.selection?.ranges || [] + ) + if (selString === lastSelection.current) { + // onUpdate is noisy and is fired a lot by extensions + // since we're only interested in selections changes we can ignore most of these. + return + } + lastSelection.current = selString + + if ( + // TODO find a less lazy way of getting the last + Date.now() - useStore.getState().lastCodeMirrorSelectionUpdatedFromScene < + 150 + ) + return // update triggered by scene selection if (sceneInfra.selected) return // mid drag const ignoreEvents: ModelingMachineEvent['type'][] = [ 'Equip Line tool', @@ -104,7 +122,6 @@ export const TextEditor = ({ const eventInfo = processCodeMirrorRanges({ codeMirrorRanges: viewUpdate.state.selection.ranges, selectionRanges, - selectionRangeTypeMap, isShiftDown, }) if (!eventInfo) return @@ -226,3 +243,7 @@ export const TextEditor = ({ ) } + +function stringifyRanges(ranges: readonly SelectionRange[]): string { + return ranges.map(({ to, from }) => `${to}->${from}`).join('&') +} diff --git a/src/lang/KclSingleton.tsx b/src/lang/KclSingleton.tsx index dadb04d1a4..3f46409676 100644 --- a/src/lang/KclSingleton.tsx +++ b/src/lang/KclSingleton.tsx @@ -1,6 +1,7 @@ import { executeAst, executeCode } from 'useStore' import { Selections } from 'lib/selections' import { KCLError } from './errors' +import { v4 as uuidv4 } from 'uuid' import { EngineCommandManager, engineCommandManager, @@ -14,6 +15,8 @@ import { Program, ProgramMemory, recast, + SketchGroup, + ExtrudeGroup, } from 'lang/wasm' import { bracket } from 'lib/exampleKcl' import { createContext, useContext, useEffect, useState } from 'react' @@ -235,7 +238,6 @@ class KclManager { updateCode = false, executionId?: number ) { - console.trace('executeAst') const currentExecutionId = executionId || Date.now() this._cancelTokens.set(currentExecutionId, false) @@ -245,6 +247,7 @@ class KclManager { ast, engineCommandManager: this.engineCommandManager, }) + enterEditMode(programMemory) this.isExecuting = false // Check the cancellation token for this execution before applying side effects if (this._cancelTokens.get(currentExecutionId)) { @@ -333,6 +336,7 @@ class KclManager { } if (!result.isChange) return const { logs, errors, programMemory, ast } = result + enterEditMode(programMemory) this.logs = logs this.kclErrors = errors this.programMemory = programMemory @@ -520,3 +524,18 @@ function safteLSSetItem(key: string, value: string) { if (typeof window === 'undefined') return localStorage?.setItem(key, value) } + +function enterEditMode(programMemory: ProgramMemory) { + const firstSketchOrExtrudeGroup = Object.values(programMemory.root).find( + (node) => node.type === 'ExtrudeGroup' || node.type === 'SketchGroup' + ) as SketchGroup | ExtrudeGroup + firstSketchOrExtrudeGroup && + engineCommandManager.sendSceneCommand({ + type: 'modeling_cmd_req', + cmd_id: uuidv4(), + cmd: { + type: 'edit_mode_enter', + target: firstSketchOrExtrudeGroup.id, + }, + }) +} diff --git a/src/lang/artifact.test.ts b/src/lang/artifact.test.ts index 26882a55bb..f4fbe2937e 100644 --- a/src/lang/artifact.test.ts +++ b/src/lang/artifact.test.ts @@ -74,16 +74,56 @@ const mySketch001 = startSketchOn('XY') expect(sketch001).toEqual({ type: 'ExtrudeGroup', id: expect.any(String), - value: [], + value: [ + { + type: 'extrudePlane', + position: [0, 0, 0], + rotation: [0, 0, 0, 1], + faceId: expect.any(String), + name: '', + id: expect.any(String), + sourceRange: [77, 102], + }, + { + type: 'extrudePlane', + position: [0, 0, 0], + rotation: [0, 0, 0, 1], + faceId: expect.any(String), + name: '', + id: expect.any(String), + sourceRange: [108, 132], + }, + ], + sketchGroupValues: [ + { + type: 'ToPoint', + from: [0, 0], + to: [-1.59, -1.54], + name: '', + __geoMeta: { + id: expect.any(String), + sourceRange: [77, 102], + }, + }, + { + type: 'ToPoint', + from: [-1.59, -1.54], + to: [0.46, -5.82], + name: '', + __geoMeta: { + id: expect.any(String), + sourceRange: [108, 132], + }, + }, + ], height: 2, position: [0, 0, 0], rotation: [0, 0, 0, 1], - endCapId: null, - startCapId: null, - sketchGroupValues: expect.any(Array), xAxis: { x: 1, y: 0, z: 0 }, yAxis: { x: 0, y: 1, z: 0 }, zAxis: { x: 0, y: 0, z: 1 }, + startCapId: expect.any(String), + endCapId: expect.any(String), __meta: [{ sourceRange: [46, 71] }], }) }) @@ -117,32 +157,149 @@ const sk2 = startSketchOn('XY') { type: 'ExtrudeGroup', id: expect.any(String), - value: [], + value: [ + { + type: 'extrudePlane', + position: [0, 0, 0], + rotation: [0, 0, 0, 1], + faceId: expect.any(String), + name: '', + id: expect.any(String), + sourceRange: [69, 89], + }, + { + type: 'extrudePlane', + position: [0, 0, 0], + rotation: [0, 0, 0, 1], + faceId: expect.any(String), + name: 'p', + id: expect.any(String), + sourceRange: [95, 118], + }, + { + type: 'extrudePlane', + position: [0, 0, 0], + rotation: [0, 0, 0, 1], + faceId: expect.any(String), + name: '', + id: expect.any(String), + sourceRange: [124, 143], + }, + ], + sketchGroupValues: [ + { + type: 'ToPoint', + from: [0, 0], + to: [-2.5, 0], + name: '', + __geoMeta: { + id: expect.any(String), + sourceRange: [69, 89], + }, + }, + { + type: 'ToPoint', + from: [-2.5, 0], + to: [0, 10], + name: 'p', + __geoMeta: { + id: expect.any(String), + sourceRange: [95, 118], + }, + }, + { + type: 'ToPoint', + from: [0, 10], + to: [2.5, 0], + name: '', + __geoMeta: { + id: expect.any(String), + sourceRange: [124, 143], + }, + }, + ], height: 2, position: [0, 0, 0], rotation: [0, 0, 0, 1], - endCapId: null, - startCapId: null, - sketchGroupValues: expect.any(Array), xAxis: { x: 1, y: 0, z: 0 }, yAxis: { x: 0, y: 1, z: 0 }, zAxis: { x: 0, y: 0, z: 1 }, + startCapId: expect.any(String), + endCapId: expect.any(String), __meta: [{ sourceRange: [38, 63] }], }, { type: 'ExtrudeGroup', id: expect.any(String), - value: [], + value: [ + { + type: 'extrudePlane', + position: [0, 0, 0], + rotation: [0, 0, 0, 1], + faceId: expect.any(String), + name: '', + id: expect.any(String), + sourceRange: [374, 394], + }, + { + type: 'extrudePlane', + position: [0, 0, 0], + rotation: [0, 0, 0, 1], + faceId: expect.any(String), + name: 'p', + id: expect.any(String), + sourceRange: [400, 422], + }, + { + type: 'extrudePlane', + position: [0, 0, 0], + rotation: [0, 0, 0, 1], + faceId: expect.any(String), + name: '', + id: expect.any(String), + sourceRange: [428, 447], + }, + ], + sketchGroupValues: [ + { + type: 'ToPoint', + from: [0, 0], + to: [-2.5, 0], + name: '', + __geoMeta: { + id: expect.any(String), + sourceRange: [374, 394], + }, + }, + { + type: 'ToPoint', + from: [-2.5, 0], + to: [0, 3], + name: 'p', + __geoMeta: { + id: expect.any(String), + sourceRange: [400, 422], + }, + }, + { + type: 'ToPoint', + from: [0, 3], + to: [2.5, 0], + name: '', + __geoMeta: { + id: expect.any(String), + sourceRange: [428, 447], + }, + }, + ], height: 2, position: [0, 0, 0], rotation: [0, 0, 0, 1], - - endCapId: null, - startCapId: null, - sketchGroupValues: expect.any(Array), xAxis: { x: 1, y: 0, z: 0 }, yAxis: { x: 0, y: 1, z: 0 }, zAxis: { x: 0, y: 0, z: 1 }, + startCapId: expect.any(String), + endCapId: expect.any(String), __meta: [{ sourceRange: [343, 368] }], }, ]) diff --git a/src/lang/modifyAst.test.ts b/src/lang/modifyAst.test.ts index 314e3b1bd6..59e42a64fe 100644 --- a/src/lang/modifyAst.test.ts +++ b/src/lang/modifyAst.test.ts @@ -12,8 +12,10 @@ import { addSketchTo, giveSketchFnCallTag, moveValueIntoNewVariable, + sketchOnExtrudedFace, } from './modifyAst' import { enginelessExecutor } from '../lib/testHelpers' +import { getNodePathFromSourceRange } from './queryAst' beforeAll(() => initPromise) @@ -274,3 +276,89 @@ const yo2 = hmm([identifierGuy + 5])` expect(newCode).toContain(`const yo2 = hmm([newVar])`) }) }) + +describe('testing sketchOnExtrudedFace', () => { + test('it should be able to extrude on regular segments', async () => { + const code = `const part001 = startSketchOn('-XZ') + |> startProfileAt([3.58, 2.06], %) + |> line([9.7, 9.19], %) + |> line([8.62, -9.57], %) + |> close(%) + |> extrude(5 + 7, %)` + const ast = parse(code) + const programMemory = await enginelessExecutor(ast) + const snippet = `line([9.7, 9.19], %)` + const range: [number, number] = [ + code.indexOf(snippet), + code.indexOf(snippet) + snippet.length, + ] + const pathToNode = getNodePathFromSourceRange(ast, range) + + const { modifiedAst } = sketchOnExtrudedFace(ast, pathToNode, programMemory) + const newCode = recast(modifiedAst) + expect(newCode).toContain(`const part001 = startSketchOn('-XZ') + |> startProfileAt([3.58, 2.06], %) + |> line([9.7, 9.19], %, 'seg01') + |> line([8.62, -9.57], %) + |> close(%) + |> extrude(5 + 7, %) +const part002 = startSketchOn(part001, 'seg01')`) + }) + test('it should be able to extrude on close segments', async () => { + const code = `const part001 = startSketchOn('-XZ') + |> startProfileAt([3.58, 2.06], %) + |> line([9.7, 9.19], %) + |> line([8.62, -9.57], %) + |> close(%) + |> extrude(5 + 7, %)` + const ast = parse(code) + const programMemory = await enginelessExecutor(ast) + const snippet = `close(%)` + const range: [number, number] = [ + code.indexOf(snippet), + code.indexOf(snippet) + snippet.length, + ] + const pathToNode = getNodePathFromSourceRange(ast, range) + + const { modifiedAst } = sketchOnExtrudedFace(ast, pathToNode, programMemory) + const newCode = recast(modifiedAst) + expect(newCode).toContain(`const part001 = startSketchOn('-XZ') + |> startProfileAt([3.58, 2.06], %) + |> line([9.7, 9.19], %) + |> line([8.62, -9.57], %) + |> close(%, 'seg01') + |> extrude(5 + 7, %) +const part002 = startSketchOn(part001, 'seg01')`) + }) + test('it should be able to extrude on start-end caps', async () => { + const code = `const part001 = startSketchOn('-XZ') + |> startProfileAt([3.58, 2.06], %) + |> line([9.7, 9.19], %) + |> line([8.62, -9.57], %) + |> close(%) + |> extrude(5 + 7, %)` + const ast = parse(code) + const programMemory = await enginelessExecutor(ast) + const snippet = `startProfileAt([3.58, 2.06], %)` + const range: [number, number] = [ + code.indexOf(snippet), + code.indexOf(snippet) + snippet.length, + ] + const pathToNode = getNodePathFromSourceRange(ast, range) + + const { modifiedAst } = sketchOnExtrudedFace( + ast, + pathToNode, + programMemory, + 'end' + ) + const newCode = recast(modifiedAst) + expect(newCode).toContain(`const part001 = startSketchOn('-XZ') + |> startProfileAt([3.58, 2.06], %) + |> line([9.7, 9.19], %) + |> line([8.62, -9.57], %) + |> close(%) + |> extrude(5 + 7, %) +const part002 = startSketchOn(part001, 'END')`) + }) +}) diff --git a/src/lang/modifyAst.ts b/src/lang/modifyAst.ts index 88f3004743..8bef7c2794 100644 --- a/src/lang/modifyAst.ts +++ b/src/lang/modifyAst.ts @@ -1,4 +1,3 @@ -import { ToolTip } from '../useStore' import { Selection } from 'lib/selections' import { Program, @@ -64,7 +63,6 @@ export function addStartProfileAt( pathToNode: PathToNode, at: [number, number] ): { modifiedAst: Program; pathToNode: PathToNode } { - console.log('addStartProfileAt called') const variableDeclaration = getNodeFromPath( node, pathToNode, @@ -317,17 +315,17 @@ export function extrudeSketch( export function sketchOnExtrudedFace( node: Program, pathToNode: PathToNode, - programMemory: ProgramMemory + programMemory: ProgramMemory, + cap: 'none' | 'start' | 'end' = 'none' ): { modifiedAst: Program; pathToNode: PathToNode } { let _node = { ...node } const newSketchName = findUniqueName(node, 'part') - const { node: oldSketchNode, shallowPath: pathToOldSketch } = - getNodeFromPath( - _node, - pathToNode, - 'VariableDeclarator', - true - ) + const { node: oldSketchNode } = getNodeFromPath( + _node, + pathToNode, + 'VariableDeclarator', + true + ) const oldSketchName = oldSketchNode.id.name const { node: expression } = getNodeFromPath( _node, @@ -335,42 +333,44 @@ export function sketchOnExtrudedFace( 'CallExpression' ) - const { modifiedAst, tag } = addTagForSketchOnFace( - { - previousProgramMemory: programMemory, - pathToNode, - node: _node, - }, - expression.callee.name - ) - _node = modifiedAst + let _tag = '' + if (cap === 'none') { + const { modifiedAst, tag } = addTagForSketchOnFace( + { + previousProgramMemory: programMemory, + pathToNode, + node: _node, + }, + expression.callee.name + ) + _tag = tag + _node = modifiedAst + } else { + _tag = cap.toUpperCase() + } const newSketch = createVariableDeclaration( newSketchName, - createPipeExpression([ - createCallExpressionStdLib('startSketchAt', [ - createArrayExpression([createLiteral(0), createLiteral(0)]), - ]), - createCallExpressionStdLib('lineTo', [ - createArrayExpression([createLiteral(1), createLiteral(1)]), - createPipeSubstitution(), - ]), - createCallExpression('transform', [ - createCallExpressionStdLib('getExtrudeWallTransform', [ - createLiteral(tag), - createIdentifier(oldSketchName), - ]), - createPipeSubstitution(), - ]), + createCallExpressionStdLib('startSketchOn', [ + createIdentifier(oldSketchName), + createLiteral(_tag), ]), 'const' ) - const expressionIndex = getLastIndex(pathToOldSketch) + + const expressionIndex = pathToNode[1][0] as number _node.body.splice(expressionIndex + 1, 0, newSketch) + const newpathToNode: PathToNode = [ + ['body', ''], + [expressionIndex + 1, 'index'], + ['declarations', 'VariableDeclaration'], + [0, 'index'], + ['init', 'VariableDeclarator'], + ] return { modifiedAst: _node, - pathToNode: [...pathToNode.slice(0, -1), [expressionIndex, 'index']], + pathToNode: newpathToNode, } } diff --git a/src/lang/recast.test.ts b/src/lang/recast.test.ts index c924de64f6..7985d41b24 100644 --- a/src/lang/recast.test.ts +++ b/src/lang/recast.test.ts @@ -150,7 +150,7 @@ log(5, myVar) const recasted = recast(ast) expect(recasted.trim()).toBe(code.trim()) }) - it('recast long object exectution', () => { + it('recast long object execution', () => { const code = `const three = 3 const yo = { aStr: 'str', @@ -163,7 +163,7 @@ const yo = { const recasted = recast(ast) expect(recasted).toBe(code) }) - it('recast short object exectution', () => { + it('recast short object execution', () => { const code = `const yo = { key: 'val' } ` const { ast } = code2ast(code) diff --git a/src/lang/std/engineConnection.ts b/src/lang/std/engineConnection.ts index df1572b1e4..3af7af86a5 100644 --- a/src/lang/std/engineConnection.ts +++ b/src/lang/std/engineConnection.ts @@ -13,6 +13,10 @@ interface CommandInfo { range: SourceRange pathToNode: PathToNode parentId?: string + additionalData?: { + type: 'cap' + info: 'start' | 'end' + } } type WebSocketResponse = Models['OkWebSocketResponseData_type'] @@ -1069,14 +1073,42 @@ export class EngineCommandManager { } as const this.artifactMap[id] = artifact if ( - command.commandType === 'entity_linear_pattern' || - command.commandType === 'entity_circular_pattern' + (command.commandType === 'entity_linear_pattern' && + modelingResponse.type === 'entity_linear_pattern') || + (command.commandType === 'entity_circular_pattern' && + modelingResponse.type === 'entity_circular_pattern') ) { - const entities = (modelingResponse as any)?.data?.entity_ids + const entities = modelingResponse.data.entity_ids entities?.forEach((entity: string) => { this.artifactMap[entity] = artifact }) } + if ( + command?.commandType === 'solid3d_get_extrusion_face_info' && + modelingResponse.type === 'solid3d_get_extrusion_face_info' + ) { + console.log('modelingResposne', modelingResponse) + const parent = this.artifactMap[command?.parentId || ''] + modelingResponse.data.faces.forEach((face) => { + if (face.cap !== 'none' && face.face_id && parent) { + this.artifactMap[face.face_id] = { + ...parent, + commandType: 'solid3d_get_extrusion_face_info', + additionalData: { + type: 'cap', + info: face.cap === 'bottom' ? 'start' : 'end', + }, + } + } + const curveArtifact = this.artifactMap[face?.curve_id || ''] + if (curveArtifact && face?.face_id) { + this.artifactMap[face.face_id] = { + ...curveArtifact, + commandType: 'solid3d_get_extrusion_face_info', + } + } + }) + } resolve({ id, commandType: command.commandType, @@ -1388,12 +1420,6 @@ export class EngineCommandManager { const promise = new Promise((_resolve, reject) => { resolve = _resolve }) - const getParentId = (): string | undefined => { - if (command.type === 'extend_path') { - return command.path - } - // TODO handle other commands that have a parent - } const pathToNode = ast ? getNodePathFromSourceRange(ast, range || [0, 0]) : [] @@ -1402,7 +1428,6 @@ export class EngineCommandManager { pathToNode, type: 'pending', commandType: command.type, - parentId: getParentId(), promise, resolve, } @@ -1419,10 +1444,14 @@ export class EngineCommandManager { resolve = _resolve }) const getParentId = (): string | undefined => { - if (command.type === 'extend_path') { - return command.path + if (command.type === 'extend_path') return command.path + if (command.type === 'solid3d_get_extrusion_face_info') { + const edgeArtifact = this.artifactMap[command.edge_id] + // edges's parent id is to the original "start_path" artifact + if (edgeArtifact?.parentId) return edgeArtifact.parentId } - // TODO handle other commands that have a parent + if (command.type === 'close_path') return command.path_id + // handle other commands that have a parent here } const pathToNode = ast ? getNodePathFromSourceRange(ast, range || [0, 0]) diff --git a/src/lang/std/sketch.ts b/src/lang/std/sketch.ts index db1d0a4fa2..cc5c1768e5 100644 --- a/src/lang/std/sketch.ts +++ b/src/lang/std/sketch.ts @@ -1155,11 +1155,14 @@ export function addTagForSketchOnFace( a: ModifyAstBase, expressionName: string ) { + if (expressionName === 'close') { + return addTag(1)(a) + } if (expressionName in sketchLineHelperMap) { const { addTag } = sketchLineHelperMap[expressionName] return addTag(a) } - throw new Error('not a sketch line helper') + throw new Error(`"${expressionName}" is not a sketch line helper`) } function isAngleLiteral(lineArugement: Value): boolean { @@ -1174,7 +1177,7 @@ function isAngleLiteral(lineArugement: Value): boolean { type addTagFn = (a: ModifyAstBase) => { modifiedAst: Program; tag: string } -function addTag(): addTagFn { +function addTag(tagIndex = 2): addTagFn { return ({ node, pathToNode }) => { const _node = { ...node } const { node: primaryCallExp } = getNodeFromPath( @@ -1184,12 +1187,12 @@ function addTag(): addTagFn { ) // Tag is always 3rd expression now, using arg index feels brittle // but we can come up with a better way to identify tag later. - const thirdArg = primaryCallExp.arguments?.[2] + const thirdArg = primaryCallExp.arguments?.[tagIndex] const tagLiteral = thirdArg || (createLiteral(findUniqueName(_node, 'seg', 2)) as Literal) const isTagExisting = !!thirdArg if (!isTagExisting) { - primaryCallExp.arguments[2] = tagLiteral + primaryCallExp.arguments[tagIndex] = tagLiteral } if ('value' in tagLiteral) { // Now TypeScript knows tagLiteral has a value property diff --git a/src/lang/wasm.ts b/src/lang/wasm.ts index 64845ede66..3895027cfd 100644 --- a/src/lang/wasm.ts +++ b/src/lang/wasm.ts @@ -66,6 +66,7 @@ export type { Position } from '../wasm-lib/kcl/bindings/Position' export type { Rotation } from '../wasm-lib/kcl/bindings/Rotation' export type { Path } from '../wasm-lib/kcl/bindings/Path' export type { SketchGroup } from '../wasm-lib/kcl/bindings/SketchGroup' +export type { ExtrudeGroup } from '../wasm-lib/kcl/bindings/ExtrudeGroup' export type { MemoryItem } from '../wasm-lib/kcl/bindings/MemoryItem' export type { ExtrudeSurface } from '../wasm-lib/kcl/bindings/ExtrudeSurface' diff --git a/src/lib/cameraControls.ts b/src/lib/cameraControls.ts index a447b5b4ed..4d867866ed 100644 --- a/src/lib/cameraControls.ts +++ b/src/lib/cameraControls.ts @@ -39,7 +39,7 @@ export interface MouseGuard { rotate: MouseGuardHandler } -const butName = (e: React.MouseEvent) => ({ +export const butName = (e: React.MouseEvent) => ({ middle: !!(e.buttons & 4) || e.button === 1, right: !!(e.buttons & 2) || e.button === 2, left: !!(e.buttons & 1) || e.button === 0, diff --git a/src/lib/commandBarConfigs/modelingCommandConfig.ts b/src/lib/commandBarConfigs/modelingCommandConfig.ts index 45c88cf2a1..c0cec93622 100644 --- a/src/lib/commandBarConfigs/modelingCommandConfig.ts +++ b/src/lib/commandBarConfigs/modelingCommandConfig.ts @@ -117,7 +117,7 @@ export const modelingMachineConfig: CommandSetConfig< args: { selection: { inputType: 'selection', - selectionTypes: ['face'], + selectionTypes: ['extrude-wall', 'start-cap', 'end-cap'], multiple: false, // TODO: multiple selection required: true, skip: true, diff --git a/src/lib/selections.ts b/src/lib/selections.ts index 1f8287d5c9..3edde54f8a 100644 --- a/src/lib/selections.ts +++ b/src/lib/selections.ts @@ -6,7 +6,7 @@ import { v4 as uuidv4 } from 'uuid' import { EditorSelection } from '@codemirror/state' import { kclManager } from 'lang/KclSingleton' import { SelectionRange } from '@uiw/react-codemirror' -import { isOverlap } from 'lib/utils' +import { getNormalisedCoordinates, isOverlap } from 'lib/utils' import { isCursorInSketchCommandRange } from 'lang/util' import { Program } from 'lang/wasm' import { @@ -22,70 +22,12 @@ import { getParentGroup, PROFILE_START, } from 'clientSideScene/sceneEntities' -import { Mesh } from 'three' +import { Mesh, Object3D, Object3DEventMap } from 'three' import { AXIS_GROUP, X_AXIS } from 'clientSideScene/sceneInfra' export const X_AXIS_UUID = 'ad792545-7fd3-482a-a602-a93924e3055b' export const Y_AXIS_UUID = '680fd157-266f-4b8a-984f-cdf46b8bdf01' -/* -How selections work is complex due to the nature that we rely on the engine -to tell what has been selected after we send a click command. But than the -app needs these selections to be based on cursors, therefore the app must -be in control of selections. On top of that because we need to set cursor -positions in code-mirror for selections, both from app logic, and still -allow the user to add multiple cursors like a normal editor, it's best to -let code mirror control cursor positions and associate those source ranges -with entity ids from code-mirror events later. - -So it's a lot of back and forth. conceptually the back and forth is: - -1) we send a click command to the engine -2) the engine sends back ids of entities that were clicked -3) we associate that source ranges with those ids -4) we set the codemirror selection based on those source ranges (taking - into account if the user is holding shift to add to current selections - or not). we also create and remember a SelectionRangeTypeMap -5) Code mirror fires a an event that cursors have changed, we loop through - these ranges and associate them with entity ids again with the ArtifactMap, - but also we can pick up selection types using the SelectionRangeTypeMap -6) we clear all previous selections in the engine and set the new ones - -The above is less likely to get stale but below is some more details, -because this wonders all over the code-base, I've tried to centeralise it -by putting relevant utils in this file. All of the functions below are -pure with the exception of getEventForSelectWithPoint which makes a call -to the engine, but it's a query call (not mutation) so I'm okay with this. -Actual side effects that change cursors or tell the engine what's selected -are still done throughout the in their relevant parts in the codebase. - -In detail: - -1) Click commands are mostly sent in stream.tsx search for - "select_with_point" -2) The handler for when the engine sends back entity ids calls - getEventForSelectWithPoint, it fires an XState event to update our - selections is xstate context -3 and 4) The XState handler for the above uses handleSelectionBatch and - handleSelectionWithShift to update the selections in xstate context as - well as returning our SelectionRangeTypeMap and a codeMirror specific - event to be dispatched. -5) The codeMirror handler for changes to the cursor uses - processCodeMirrorRanges to associate the ranges back with their original - types and the entity ids (the id can vary depending on the type, as - there's only one source range for a given segment, but depending on if - the user selected the segment directly or the vertex, the id will be - different) -6) We take all of the ids and create events for the engine with - resetAndSetEngineEntitySelectionCmds - -An important note is that if a user changes the cursor directly themselves -then they skip directly to step 5, And these selections get a type of -"default". - -There are a few more nuances than this, but best to find them in the code. -*/ - export type Axis = 'y-axis' | 'x-axis' | 'z-axis' export type Selection = { @@ -93,7 +35,9 @@ export type Selection = { | 'default' | 'line-end' | 'line-mid' - | 'face' + | 'extrude-wall' + | 'start-cap' + | 'end-cap' | 'point' | 'edge' | 'line' @@ -106,15 +50,6 @@ export type Selections = { codeBasedSelections: Selection[] } -export interface SelectionRangeTypeMap { - [key: number]: Selection['type'] -} - -interface RangeAndId { - id: string - range: SourceRange -} - export async function getEventForSelectWithPoint( { data, @@ -139,8 +74,32 @@ export async function getEventForSelectWithPoint( }, } } - const sourceRange = engineCommandManager.artifactMap[data.entity_id]?.range - if (engineCommandManager.artifactMap[data.entity_id]) { + const _artifact = engineCommandManager.artifactMap[data.entity_id] + const sourceRange = _artifact?.range + if (_artifact) { + if (_artifact.commandType === 'solid3d_get_extrusion_face_info') { + if (_artifact?.additionalData) + return { + type: 'Set selection', + data: { + selectionType: 'singleCodeCursor', + selection: { + range: sourceRange, + type: + _artifact?.additionalData.info === 'end' + ? 'end-cap' + : 'start-cap', + }, + }, + } + return { + type: 'Set selection', + data: { + selectionType: 'singleCodeCursor', + selection: { range: sourceRange, type: 'extrude-wall' }, + }, + } + } return { type: 'Set selection', data: { @@ -148,46 +107,17 @@ export async function getEventForSelectWithPoint( selection: { range: sourceRange, type: 'default' }, }, } - } - if (!sketchEnginePathId) return null - // selected a vertex - const res = await engineCommandManager.sendSceneCommand({ - type: 'modeling_cmd_req', - cmd_id: uuidv4(), - cmd: { - type: 'path_get_curve_uuids_for_vertices', - vertex_ids: [data.entity_id], - path_id: sketchEnginePathId, - }, - }) - const curveIds = res?.data?.data?.curve_ids - const ranges: RangeAndId[] = curveIds - .map( - (id: string): RangeAndId => ({ - id, - range: engineCommandManager.artifactMap[id].range, - }) - ) - .sort((a: RangeAndId, b: RangeAndId) => a.range[0] - b.range[0]) - // default to the head of the curve selected - const _sourceRange = ranges?.[0].range - const artifact = engineCommandManager.artifactMap[ranges?.[0]?.id] - if (artifact.type === 'result') { - artifact.headVertexId = data.entity_id - } - return { - type: 'Set selection', - data: { - selectionType: 'singleCodeCursor', - // line-end is used to indicate that headVertexId should be sent to the engine as "selected" - // not the whole curve - selection: { range: _sourceRange, type: 'line-end' }, - }, + } else { + // if we don't recognise the entity, select nothing + return { + type: 'Set selection', + data: { selectionType: 'singleCodeCursor' }, + } } } export function getEventForSegmentSelection( - obj: any + obj: Object3D ): ModelingMachineEvent | null { const group = getParentGroup(obj, [ STRAIGHT_SEGMENT, @@ -231,107 +161,54 @@ export function handleSelectionBatch({ }: { selections: Selections }): { - selectionRangeTypeMap: SelectionRangeTypeMap - codeMirrorSelection?: EditorSelection + engineEvents: Models['WebSocketRequest_type'][] + codeMirrorSelection: EditorSelection otherSelections: Axis[] + updateSceneObjectColors: () => void } { const ranges: ReturnType[] = [] - const selectionRangeTypeMap: SelectionRangeTypeMap = {} + const engineEvents: Models['WebSocketRequest_type'][] = + resetAndSetEngineEntitySelectionCmds( + codeToIdSelections(selections.codeBasedSelections) + ) selections.codeBasedSelections.forEach(({ range, type }) => { if (range?.[1]) { ranges.push(EditorSelection.cursor(range[1])) - selectionRangeTypeMap[range[1]] = type } }) if (ranges.length) return { - selectionRangeTypeMap, + engineEvents, codeMirrorSelection: EditorSelection.create( ranges, selections.codeBasedSelections.length - 1 ), otherSelections: selections.otherSelections, + updateSceneObjectColors: () => + updateSceneObjectColors(selections.codeBasedSelections), } return { - selectionRangeTypeMap, + codeMirrorSelection: EditorSelection.create( + [EditorSelection.cursor(kclManager.code.length)], + 0 + ), + engineEvents, otherSelections: selections.otherSelections, + updateSceneObjectColors: () => + updateSceneObjectColors(selections.codeBasedSelections), } } -export function handleSelectionWithShift({ - codeSelection, - otherSelection, - currentSelections, - isShiftDown, -}: { - codeSelection?: Selection - otherSelection?: Axis - currentSelections: Selections - isShiftDown: boolean -}): { - selectionRangeTypeMap: SelectionRangeTypeMap - otherSelections: Axis[] - codeMirrorSelection?: EditorSelection -} { - const code = kclManager.code - if (codeSelection && otherSelection) { - throw new Error('cannot have both code and other selection') - } - if (!codeSelection && !otherSelection) { - return handleSelectionBatch({ - selections: { - otherSelections: [], - codeBasedSelections: [ - { - range: [0, code.length ? code.length : 0], - type: 'default', - }, - ], - }, - }) - } - if (otherSelection) { - return handleSelectionBatch({ - selections: { - codeBasedSelections: isShiftDown - ? currentSelections.codeBasedSelections - : [ - { - range: [0, code.length ? code.length : 0], - type: 'default', - }, - ], - otherSelections: [otherSelection], - }, - }) - } - const isEndOfFileDumbySelection = - currentSelections.codeBasedSelections.length === 1 && - currentSelections.codeBasedSelections[0].range[0] === kclManager.code.length - const newCodeBasedSelections = !isShiftDown - ? [codeSelection!] - : isEndOfFileDumbySelection - ? [codeSelection!] - : [...currentSelections.codeBasedSelections, codeSelection!] - const selections: Selections = { - otherSelections: isShiftDown ? currentSelections.otherSelections : [], - codeBasedSelections: newCodeBasedSelections, - } - return handleSelectionBatch({ selections }) -} - type SelectionToEngine = { type: Selection['type']; id: string } export function processCodeMirrorRanges({ codeMirrorRanges, selectionRanges, - selectionRangeTypeMap, isShiftDown, }: { codeMirrorRanges: readonly SelectionRange[] selectionRanges: Selections - selectionRangeTypeMap: SelectionRangeTypeMap isShiftDown: boolean }): null | { modelingEvent: ModelingMachineEvent @@ -349,41 +226,13 @@ export function processCodeMirrorRanges({ if (!isChange) return null const codeBasedSelections: Selections['codeBasedSelections'] = codeMirrorRanges.map(({ from, to }) => { - if (selectionRangeTypeMap[to]) { - return { - type: selectionRangeTypeMap[to], - range: [from, to], - } - } return { type: 'default', range: [from, to], } }) - const idBasedSelections: SelectionToEngine[] = codeBasedSelections - .flatMap(({ type, range }): null | SelectionToEngine[] => { - // TODO #868: loops over all artifacts will become inefficient at a large scale - const entriesWithOverlap = Object.entries( - engineCommandManager.artifactMap || {} - ).filter(([_, artifact]) => { - return artifact.range && isOverlap(artifact.range, range) - ? artifact - : false - }) - if (entriesWithOverlap.length) { - return entriesWithOverlap.map(([id, artifact]) => ({ - type, - id: - type === 'line-end' && - artifact.type === 'result' && - artifact.headVertexId - ? artifact.headVertexId - : id, - })) - } - return null - }) - .filter(Boolean) as any + const idBasedSelections: SelectionToEngine[] = + codeToIdSelections(codeBasedSelections) if (!selectionRanges) return null updateSceneObjectColors(codeBasedSelections) @@ -486,24 +335,21 @@ export type CommonASTNode = { ast: Program } -export function buildCommonNodeFromSelection( - selectionRanges: Selections, - i: number -) { +function buildCommonNodeFromSelection(selectionRanges: Selections, i: number) { return { selection: selectionRanges.codeBasedSelections[i], ast: kclManager.ast, } } -export function nodeHasExtrude(node: CommonASTNode) { +function nodeHasExtrude(node: CommonASTNode) { return doesPipeHaveCallExp({ calleeName: 'extrude', ...node, }) } -export function nodeHasClose(node: CommonASTNode) { +function nodeHasClose(node: CommonASTNode) { return doesPipeHaveCallExp({ calleeName: 'close', ...node, @@ -521,7 +367,7 @@ export function canExtrudeSelection(selection: Selections) { ) } -export function canExtrudeSelectionItem(selection: Selections, i: number) { +function canExtrudeSelectionItem(selection: Selections, i: number) { const commonNode = buildCommonNodeFromSelection(selection, i) return ( @@ -547,7 +393,7 @@ export function getSelectionType( return selection.codeBasedSelections .map((s, i) => { if (canExtrudeSelectionItem(selection, i)) { - return ['face', 1] as ResolvedSelectionType // This is implicitly determining what a face is, which is bad + return ['extrude-wall', 1] as ResolvedSelectionType // This is implicitly determining what a face is, which is bad } else { return ['other', 1] as ResolvedSelectionType } @@ -590,3 +436,100 @@ export function canSubmitSelectionArg( }) ) } + +function codeToIdSelections( + codeBasedSelections: Selection[] +): SelectionToEngine[] { + return codeBasedSelections + .flatMap(({ type, range, ...rest }): null | SelectionToEngine[] => { + // TODO #868: loops over all artifacts will become inefficient at a large scale + const entriesWithOverlap = Object.entries( + engineCommandManager.artifactMap || {} + ) + .map(([id, artifact]) => { + return artifact.range && isOverlap(artifact.range, range) + ? { + artifact, + selection: { type, range, ...rest }, + id, + } + : false + }) + .filter(Boolean) + let bestCandidate + entriesWithOverlap.forEach((entry) => { + if (!entry) return + if ( + type === 'default' && + entry.artifact.commandType === 'extend_path' + ) { + bestCandidate = entry + return + } + if ( + type === 'start-cap' && + entry.artifact.commandType === 'solid3d_get_extrusion_face_info' && + entry?.artifact?.additionalData?.info === 'start' + ) { + bestCandidate = entry + return + } + if ( + type === 'end-cap' && + entry.artifact.commandType === 'solid3d_get_extrusion_face_info' && + entry?.artifact?.additionalData?.info === 'end' + ) { + bestCandidate = entry + return + } + if ( + type === 'extrude-wall' && + entry.artifact.commandType === 'solid3d_get_extrusion_face_info' + ) { + bestCandidate = entry + return + } + }) + + if (bestCandidate) { + const _bestCandidate = bestCandidate as { + artifact: any + selection: any + id: string + } + return [ + { + type, + id: _bestCandidate.id, + }, + ] + } + return null + }) + .filter(Boolean) as any +} + +export function sendSelectEventToEngine( + e: MouseEvent | React.MouseEvent, + el: HTMLVideoElement, + streamDimensions: { streamWidth: number; streamHeight: number } +) { + const { x, y } = getNormalisedCoordinates({ + clientX: e.clientX, + clientY: e.clientY, + el, + ...streamDimensions, + }) + const result: Promise = engineCommandManager + .sendSceneCommand({ + type: 'modeling_cmd_req', + cmd: { + type: 'select_with_point', + selected_at_window: { x, y }, + selection_type: 'add', + }, + cmd_id: uuidv4(), + }) + .then((res) => res.data.data) + return result +} diff --git a/src/machines/modelingMachine.ts b/src/machines/modelingMachine.ts index 0b320497b4..a199fec673 100644 --- a/src/machines/modelingMachine.ts +++ b/src/machines/modelingMachine.ts @@ -1,13 +1,6 @@ import { PathToNode, VariableDeclarator } from 'lang/wasm' -import { engineCommandManager } from 'lang/std/engineConnection' -import { - Axis, - Selection, - SelectionRangeTypeMap, - Selections, -} from 'lib/selections' +import { Axis, Selection, Selections } from 'lib/selections' import { assign, createMachine } from 'xstate' -import { isCursorInSketchCommandRange } from 'lang/util' import { getNodePathFromSourceRange } from 'lang/queryAst' import { kclManager } from 'lang/KclSingleton' import { @@ -26,7 +19,6 @@ import { } from 'components/Toolbar/EqualLength' import { addStartProfileAt, extrudeSketch } from 'lang/modifyAst' import { getNodeFromPath } from '../lang/queryAst' -import { CallExpression, PipeExpression } from '../lang/wasm' import { applyConstraintEqualAngle, equalAngleInfo, @@ -45,10 +37,10 @@ import { ModelingCommandSchema } from 'lib/commandBarConfigs/modelingCommandConf import { DefaultPlaneStr, sceneEntitiesManager, - quaternionFromSketchGroup, - sketchGroupFromPathToNode, } from 'clientSideScene/sceneEntities' import { sceneInfra } from 'clientSideScene/sceneInfra' +import { Vector3 } from 'three' +import { quaternionFromUpNForward } from 'clientSideScene/helpers' export const MODELING_PERSIST_KEY = 'MODELING_PERSIST_KEY' @@ -70,6 +62,13 @@ export type SetSelections = selection: Selections } +export interface SketchDetails { + sketchPathToNode: PathToNode + zAxis: [number, number, number] + yAxis: [number, number, number] + origin: [number, number, number] +} + export type ModelingMachineEvent = | { type: 'Enter sketch' @@ -77,9 +76,24 @@ export type ModelingMachineEvent = forceNewSketch?: boolean } } + | { type: 'Sketch On Face' } | { type: 'Select default plane' - data: { plane: DefaultPlaneStr; normal: [number, number, number] } + data: { + zAxis: [number, number, number] + yAxis: [number, number, number] + } & ( + | { + type: 'defaultPlane' + plane: DefaultPlaneStr + } + | { + type: 'extrudeFace' + position: [number, number, number] + extrudeSegmentPathToNode: PathToNode + cap: 'start' | 'end' | 'none' + } + ) } | { type: 'Set selection'; data: SetSelections } | { type: 'Sketch no face' } @@ -109,18 +123,15 @@ export type ModelingMachineEvent = | { type: 'Equip Line tool' } | { type: 'Equip tangential arc to' } | { - type: 'done.invoke.animate-to-face' - data: { - sketchPathToNode: PathToNode - sketchNormalBackUp: [number, number, number] | null - } + type: 'done.invoke.animate-to-face' | 'done.invoke.animate-to-sketch' + data: SketchDetails } export type MoveDesc = { line: number; snippet: string } export const modelingMachine = createMachine( { - /** @xstate-layout N4IgpgJg5mDOIC5QFkD2EwBsCWA7KAxAMICGuAxlgNoAMAuoqAA6qzYAu2qujIAHogC0AdgCsAZgB04gEyjhADnEA2GgoUAWJQBoQAT0QBGGuICckmoZkbTM42YWKAvk91oMOfAQDKYdgAJYLDByTm5aBiQQFjYwniiBBFtpGhlxDRphGg1ZURlhXQMEcRLDSVF5UwV84XEK8Rc3dCw8KElsCEwwHz9A4NCuXAjeGI5B3kTBLWFJDWV5hVSZZTrlBUKjS1FZiUrDeWVDasaQdxb8ds7ugFFcdjAAJ0CAaz9yAAthqNG4iaF07bCNLiRYlGiZUyZDbFYQzfIaLSQ5Sw0TGZQnM6eNodLoEW73J6wV7sD5UQyRZisMbcP4IQRrGiSdRmfIqUxrCrQlbKcoQ4RHDTWUx5DHNLGXXHXPjsB4AVwwX0psXGCSEFThkNEymFGlECkM0MM+0ZMgUa1MwuypgRhlFHlaEpufBYD3YiuiVN+qrpdg0klMwkFaU0ermwuhwlUkiBhxUyKUazt5za3mJH2IZEomFTb0+9BGnpVoESRrNkmMga0ahMplkhqOZVL+sM4ksCj1SfFOZJ70k3Y+AEkrj0AkEugNwvnvoWad7DIGyuqOe2rPNDRCLIKaKJa6JBXrRJ2Hf3eyeh7jkCRXn0oABbMB3fwAN0enHIJEw7p+Rf4RhkpkbapNEjTRUgKfQjA0FsUnBOQJHyJQNCPC4Tz7NN3nPbpL2vII7wfAJ3lQB5sAAL24dgPy-Gd4mLP9A0kVQzW3I18mRGRDXEI1yl1LJDBWYwKhkZCU3QtDc0w4huFgGUSDwfxCOIsi7g-fwIGwaTMzAKjlVnWiECsPdNzSGgqnSAD1GhNJ2QsCpRHBXUAJbYSxJ7FzB2HIgpJkuSX1dbB30wVT1IoigtKnJVqRo399OWBR-TyFdlCgtRBUs1lymsAVYRjPdnNQs8PK8h5ZNwfwAEEACFvH8AANbTItpKx21mcQxEMGxOP-NJLJ1eL41gndagaVxTjFY9RIK3FPNwaTirkyrqoATXqr09Ka7ZrDsZQ5H2ZQtXYiDijUOKgVsvi1ErPKJvQiTptmkr-DIKAuhWn8S3SKQQRBU15H1YRTEsuy4QPbKtX+gMrtzNyMMKmbvNKrp8HYPMKQ9HSove1rpD21QANkTjREsw4Tu1KD-oRBNhEh1zJu6O74f8JhHiZ3A1PIWVMBIJ41I00LXt06KrFNWYLU6jIjlUZRLP1P1+SqAMgQRDQxGpj5oduoqHoU0jyI-TA9EenAoCGcK0YaudlhkJlQ3bAEMhWQ1UR5f9Q1hfItRKVXTxu2H7p819-L1g2P2wY3+YxujzByU1-qdsxUUNbbtj1AMqjWf9HGGpp7RQ67xN9hnYFwEgmH8dhUFq8PGs4qRlhBNQA2qMxLOyK2ZDkeZ5m3Rx2699WC7m0qi5LsuK+W03vwF97oMyfjYVa4wNEs9qZj3Hud3nOYcj72nJLhwf-DAABHWUVMRqBkari3a3KFf-qyPIJHAop51bFqTHBbccdMHefamzW5JMC5nragE9qLV3yBYdu-EdzpE3oaWsMwTCcUOBaTIahDwjUxONKGu96YHweGAW8qAXz+HIAAu4sAr5rWsHFQ41h9qaH2DoQ6RxOIWD4rYbIYIzRCSwWNXOuC-7dAAEpgEEGAPgIRZT3GoYLOoUgWyGFrKkdIYgE6HXUFbdIqRkSdwTLafhOcRJCPzpKE+2BS4ABk8BgFHqgT8YD0aNQUNZCQKgbDCnSBZTRdReSK3bnuPaRpf5mJuBY0uIUYB3GwCpLm5BR5yMSFtOKIIPZ8V+go+slhoxrFUJkhESU+5lQAO6yQIkRHWylAo8xCpQfweAABmqACAQG4GAdouAnyoFeJIGA7BBDayUhRTAggmmoCSYgYyfpCkZADGYBW4hLJQXMO2U0aROEdypkY5M0NJClPKfJSpwyVK1M0g03AzSCCPAeERSQTBObsGaQ8W8fS-CDOObrUZ4zJkIGMtsI0NoWy6lNAGSy31Nw0FUCYPIkZDHZ12ahA5HBnwBwCkFXm9TxmtPaZ07pvT+mCF8m+D8YzLkTKcebPSGyrYtkUPYZEyj8hpSUEyMQcg7ClCBMUspKLiWBxqcFc52Kbl3IeSQJ5RFXmEv5QFMlzTfk0qZNuMQAExCaDSoKcsONVFaOZDyw5C1aoXKuW03AHS8D4o6YSkgAAjWAgg+DyopajSeEc-koNyTIWCcg6jrEOv+ba5YMhQSSrIbatQDUoqNTVE1LTRUPHuY8550r3l2odU6n5lLVrRQ2TMHIIIlA7m3FoHqfFpB6j2pxbIgYf47K7KJZFAQjWLTjTi81eKenWrTfawQehnWKs9XUeQFRbCIN1NCVsyIRauLsnqVsuV604Nck28qVV-CtpFQ8W5ibxWSpeW8gZ6a+0DuzW9KZnEkGsVassFYobJ18T9FC9k20do3qjQEJ6XQ21motV0rth7BBfvEVm114DvR5pSEaOocgLQaKKHBHkKi7JGgqGaWEH7Hr4G-VundSaJUpsA8B09YHnEQc4idbITUrAN3nIDec5YWzyFSHO5Y2yEUNqhqu8+yMf24stQBwlPH3gkYLGR6lBMWpWTJluZlAaOQWBWJelQ84rCYeE22hN+H92poGcJ0T05xO5s9cYGF+o1jKwOghpKVt5i0OtGIFE6Il2CJXbygITMHgszZhzLmGK6l2Oxb+ztBL3mee8-5XzDxBBnNCgZiKObkmW3ikoawr706EwDdUbYC85h7Tg76zD4WHw+c5tzIVoVNPbrFcmqVgHius0i2VmLFXKDxbNolqZyXhSpbmNA7LllsrSH5HlncwpCsuZMa5Gx5r7GYBHH0cccRFXeqjjRo4mQjh5CWQGgM5YesmVoYxPhHHl1qxm3Y8uDi8QRLLk9fCsTArxMSWeqeUzYR+n2GYcE6h5ZS0OgrFqrVHBZHZH3C7c3JADlwBwAgK2VBMjSRt60sGuT6kkMGWskJWr-TSOD2xkPoew7JKRqlub8hWzsqaR9NHtQRn+rMFYEhbBakhNufHs2ruYEkLgKVH4FtjhCMt177rrC1GkKafUvCMhan+0UJKMwFzKz1O1KCnEOeXdQA4yQAA5CuAAFVAeB2CwAIGVCAEBAgUVdIzI3dxFXzD9JqfLgpFhJS5NqFqqcsiKCUAoDXkO9f+EN8b03pBQqONJ51-SmhzAmGDKtrQep-VFF4iLVBpRTQrD7kT9gcOReNUsDyJPWQVDbkT4aYEjPIzLChboqCOeYd55J2JsnJZmJMkhJCOYshwTtUrwBaMts5irg6s507rm1YABV7sxLiQ8BJ5cBf9GF1H89fztrmG1EoLxh3-yV6gkyR93rLC6g7JNvZM-8APfn4vlp1xbsQ65w7hE79FA7jsttaE1oeRuzSMxqFOYdjUaYxPZWUVmCuDSV0E8AAeVwHbT-StX2W8Cn0EHALaUECgPYFgJNjXze30nxkZxMF1BMkyEWGfkQB3DihXDQzpU8UwQnymw+H8F538EaRIEoB6CW1UjAHYI5g805nNV+UEHanMDSRhSNEDAkGUS5DkH9BsEODmEsDgmAOwQuDIGwFvAlVaFHkZkEO6GCwE16Q0K0PuEEHLkEHYMoF+QqEAjIOyB9ShEOm2lSSsDBFBUDHUGchMO0PwF0PFXNWXyW0GEVSBEYw5R3EYkDGhDXnLFWDsHBBWBqG8Jh1MJ0PLkPj4GCh0KJFzAQJCw6R8LMIsNyJ7BsL2gYisFqAtHbjSFhGhCghywSkAN9BcKQhOF5wwHgCiDUKgFb2j0EEWDKFyEUDL3UC0B2yKEGJNC1EsFqCFGMDNGchxDAH6PX3pC0HKGRHmRDGAmhHUEXFbH1GkOMmUS9jWPwPZDihLxMHyQr0OiQQWGtEGlsHmAwwv3ymEQuPdRbAtAxySn1GB19UyxfiZTiNalSGqAAmhMwyGS+X82FXJW+JcTWFmDmUUH5BqFSHBWSABFbChW1HyHhRAMRUbXc1RT8nRViyxSRMMzbyMC0W1T7wUU3wNADTkEZFSCghlnmFsMwxjTjWRLnFcSkDUE6lrG2lMwBl23YV1HjFUHOj1BOxJM4zc0NXXU3VpIS3XyOGSAShyA21SkOinQ2jghHSqChMw2A0FLpOj11O2BWHshKCqDyFrEBjUCZGDAqFUBrzqHUwfAvneBtO1PwN1MZAyFWBVwlLXHkwR3+mUUcG2LlKzhVLO17FXQa1Kz82pMCy1I6x1PbF-3ZDslAgUJKEG3RzlnbAAnVDBw+NEify10wCFOpXsAsCGnbBsHUDWBiKjG5MEmQVtnH1TMn17EbO11zxbNzX2DKEyBKE7ItJ7OcOSD4jvR72721ADy5x5z52bNtPXyFHzXnn-GrFkCs0QDTwUOUUzzNFkC3KbN1wNztxNynOSV1FriUHan1HjxUEmIvKDWp2gyOEjC0GJN6L2UnP3NDO3C311EFAjJ3371YQbEYwOJbDbHP0YMv1n04Fv1HlfKmVDGjBjBUB+nBnXDyH+LNA5AfgMj7nQMgOt2wPQjgIIv0nNHKDqCTyZ1S2lKKCCUZyZTP3jC1C9hYIrisNWKgvdSmDkIkBWVUDqH+i-2cLkKgnsDnQmNNBSM0N8KgH8P0LYr4ikADG1CtHkFp1kJ5BMHUEjDXiONUIETaCKPSIrkkWyL8NKI+CMscAx1hCYlanZE5UnUjF5HsHIMswAnaKwpcr8IyICLsQAApyEmA9AABKNikQCQCXTJRiTQFhIoHhRTF9QJOlZU8C2K-S+K-Q-wZK1AVKtK2qlK9KzKsQT6OQUYvKiYydBESnHcawA0muYUFwFwIAA */ + /** @xstate-layout N4IgpgJg5mDOIC5QFkD2EwBsCWA7KAxAMICGuAxlgNoAMAuoqAA6qzYAu2qujIAHogC0AdgCsAZgB04gEyjhADnEA2GgoUAWJQBoQAT0QBGGuICckmoZkbTM42YWKAvk91oMOfAQDKYdgAJYLDByTm5aBiQQFjYwniiBBFtpGhlxDRphGg1ZURlhXQMEcRLDSVF5UwV84XEK8Rc3dCw8KElsCEwwHz9A4NCuXAjeGI5B3kTBLWFJDWV5hVSZZTrlBUKjS1FZiUrDeWVDasaQdxb8ds7ugFFcdjAAJ0CAaz9yAAthqNG4iaFlmZWZSmZRaKyGQzKYQaDYIGSmDSzdKyDSGcQ0KrAk5nTxtDpdAi3e5PWCvdgfKiGSLMVhjbh-BCCaw0WaQrZqdGLAr6RAZGSSWzCZSiIEKNFi5TY5q4y4E658dgPACuGC+NNi4wSQgqM3hNFEwNEGlEYthENELJkCjWplMFpsGlRUo8rVlNz4LAe7DV0Vpvy1jKtCkkVuZMjsDpNsOEwjKUIkcxNqWhomd5za3jJH2IZEomEzb0+9BGfs1oESEOtkmM0K0ahMplkZqOZUrYrRlgUJrTMoL5Pekj7HwAklcegEgl0BuFi99S-SA4ZoWUdWsTSLlsozZlzNkZPrG0a5F2e66hwPz6OCcgSK8+lAALZgO7+ABuj045BImB9PzL-CMeFW2qTQhU0ZMzVRKR0RoVJ6nyJQNFPC5z0HLN3ivbobzvIJH2fAJ3lQB5sAAL24dhv1-ed4nLQDoUkVRrX1CF8ihGQzXECFymNLJIU4-U8mQjN0LQwtMOIbhYEVEg8H8QjiLIu5v38CBsCk3MwCojUF1ohArCNCwNDSDFENMI51h5OEzGUCwKgtbJRDMtEhNE-tXJHMciEk6TZPfL1sC-TAVLUiiKE02d1TpGiAL05ZgztK0RVBYxNHYyzw1qcprCODQY2EZYjRc1DL087yHhk3B-AAQQAIW8fwAA0tKihkrC7JExEMGxOPhNJYXhAy7ShRY4NMWoGlcU5pTPESSoJLzcCk8rZNq+qAE1mv9XS2u2aw7GUOR9mFA7YU5YN8rstlHEdIrZvQ8SFqWir-DIKAuk2-8K2RaQlBA+QxWEUx+otXV1zyg1AbG27C3cjDSsWnzKq6fB2CLalfW06KvvEGYVANDE0TSfZ+sOc7gVRQHHSUKFobcubukexH-CYR4WdwVTyCVTASCeVT1LCj6dJiqwrVmW0eoyI5VC3dKxURWMqjG-LHVy1NJpxGaYfpiSEeWyr5NI8jv0wPQXpwKAhgijGWsXZZ+S7TQu3SI0aBWM0kpDO1QPysQVgmpoXRQu6xPhp7fI-ALjdN79sAtwWsbo8wcitQGkrMEUzQO7YTTGzFqiqWpaY+WGHrK57YFwEgmH8dhUEa+PWs4qRlnERYFDG6ozH6vcQzkeZ5n1RxwyLi97tDpmK6rmu642q2-yFr60QsIVOJjHHjBhdKupmI0h8cpc5hyEeS-HvX-DAABHJVlORqBUYb23G3KbfAayPIJG5Iol3RJETFg-VjqmGPtrRmZ8mA82NtQOe1FG75AsOGFY+xGwU03l-RsMwTCcUOLaTIag1YB3TLDE+80y6yQeGAB8qB3z+HIKQu4sAH7bWsMGQ41gDRWlRCacQZolBlEsMCfcOROQHWAWPAkAAlMAggwB8BCEqe4jDhZ1CkGiVQ+kdQGlhCCGyjk14misGZbIoiQ5yivtgauAAZPAYBp6oB-NAzGrV246JKKCW0CZ1CwiUNnTIe05CJghMY-s4lrhmOrqFGAdxsDKR5uQaeijEj7WDK3A0WD-rKObJYSQYFVDpMdKCY+VUADuMkCJEUNkpIKfNQqUH8HgAAZqgAgEBuBgHaLgV8qBXiSBgOwQQBtFIUUwIIBpqAEmIGMoifJGQxpmCVtw9KqJzBdlDFg2wENCklI4HJcpgzlLVI0nU3AjSCCPAeERSQTBubsEaQ8B8PS-D9N2UbYZozxlWX1NWLqqI0TGitGNfqrd+TZFdrBOorFDCbNKW+COgVgr81qaM5prT2mdO6b0wQflPzfhGccsZDiba6SJvyNEih7BQkMIKfqVopCOHfnYUo+UoXbKxZHKpIVDlIrORcq5JAblEXuRi1lgVcWNPecSyQix5D7zEJoalRlqzHVSK3ECShmUBFWo1I5JyWm4DaXgNFbSMUkAAEawEEHwUV+L0bzwTlZSE2SDqwXDLsCyRR4QHWrBkVEoJZAHULuraaQcYbFOhZqhq2qmncoeJc65tzBWPNNeay1byCVbRikTGYQj1B1FMPqLQ-UzI2TqNaCQG9oRAMDYHYSIatkarqv4NakbkV6tRV0o1iazWCD0Fa8VWDpAaMcvCHGxpTquyzYrC0XD83quqg2ptXKHjnJjby-ldyHl9KTd23tabPoTNXvAle+V5jpEhKdSEiJXbaJdaSmQs7XpdGbbq-VHT20bsEA+qRqabUwIDJmlIEJwWOTtIYYGBoBTogtOaE0UJhD3vwI+xdy7Y18vje+z9O6f2OL-Zxc62Q2pWDUGZT+EyRSAjRPIOC+oASztvqjJ9KKDVvoxXR94mGSzYaJZxbYyczAoP3PkEm7VXaMpUEuKwtHnx33eM26NKG10Jr6ax9jc5OMZv7cYEw+i1i5TSu60E-J5jMIRGIGMBpZ0sweGzDmXMebwpqTYpFz623oseZZ6zAVbMPEEAcsKKnIrpsSXbAUXDrAHTinIfq1RtjrzmMKdxch-ZTWrUQ0N2z3PPhs9zXmHKwqyaXTyuNAr30ZfZp57LPncuUH89bQLEzgtexROFtYkX0p5WkLGOLwH35JY1sGtyVi9W2MwOOPoU44jiv3EnQjRxMhHDyAs91Y1qxewxMwxid6q2ENQoNmxtc7GEjCTXV6+FolBVifE3dC8JkxkRPsMwsF1CKxlkUJWSIcaOCyCCY+u3huSGHLgDgBBJsqElSk2bCI5BA0smsMoaR24PZxoDNIP3rF-YB0DykWHCUZvyPyC0VoL2EeBNGQGswVgSHWcCWC+DkvbZEr9-bmBJC4AFd+Ubk4QgTau3a6wmVZDqClsyA0L3ECghmMuVWcsoKQq272BnaOmeSAAHJ1wAAqoDwOwWABAqoQAgIECiXpmaa7uOK+YiI80GkckZRYoJYTzCTmYV+mQc0KFR0NpXqv-Aa61zr0gYV7HY7q3pTQu5ZBAoxFoE0brEC8TFtg0oVoVjHwx+wYHPPWr8NmF2LIKhqNR7NGkKQcwhTLFBcsJ0cvNZuTT8DqkHGccVmYpKvNea5iyFgl1IvZlslOzmECbqkpq-9eLgAFRO1EmJDw4m1w5-0bnwe91wgOuYYESg7TolsPCIvqJJUXv3JYY03YR81rchP-Ap3p+z6aaEpU5j-CM9QHY83jpf6KEchaE6lkEQ2RjOGOoLIV2UvY+JUdmOudSL0c8AAeVwBbRfUNUkCqm8DH0EDAJaUEEgPYBgMtiX2uz0hKGDDyFqCckdDqDUFhCTAFGwTUFylbhKDg1P1hn8FZ38HqRIEoB6HGxUjAHYK5gCF5T1XeSZC4iOARCRy0ChBsFEAd2WH3zSByEhiFBsBHhYLrnYM4N8AnAX0GHeSFC+R0wkDmWyEOFhAdAgxKDsCUAGhXhcjIGwAfD5VaGnmZm5j1XgJczaXsMcPuEEFrkEA0PCjwLtQqGAldxBSWEyFkOSSsBKFSHbmhHUDsMBx8OcNrlcLIG6C0LGy510Mzz-Xyi+TkCh0YmhEoK0GrFWDsFghWBqGSIcKcPwBcJkRCmcNJELA8KY26W8L5SkX8PaP7HeSzngX9SqH2EUL00QFwwYihFbhBCe1yndxOFZwwHgCiD6ygEbxD0EEWDKFyEUHz3UC0EWyEEWElT3ByE03UCyCQiYPxDAC2OX0EFBCIKhFmU0BNFyi8TFHKE5Hu1iMsErQIXl0LEePwPmJz0o3zzyELxhwYjtDAnZBXm+yYOKjEQeNUybyMAyGbjGlylsA+MBljz0kpTu1RGMj9jz16yDTP2LjSzKQUheXs05TxTBLtSlmDEdAxEUFjBqFSEBWSGdhgkd3yFl2BJrzpLrRhX8jhV80RVZMxJD3MhJVUEsGUVX1A3SjkBZFSFRDlnmFCNnXDUjTZKcSfg5AMRUGqIxELU4h2GGjUVyWOFRJEnpLnXWhNMVOXzEPxw4Vwz3DHWFF7jsjECqHzngzekcwVIC29Pbm2BWFgiESqDyEbGBjUElXhwqFUDLzqEkxRhk1GVNMXHbhZBxOtzFEbH7hJlB0BkpUcDeONBTxdNrWhVKyyzszlKjMaSLO2i7D-xBAtHAhsD9n6jJWyTrP3h1BRPFNHwHCfzsR7IzXsGXkIKNDDLWEoNUBDFREPnX0dGnLpxBIG0V2f2ZzT0XMSX2D4XGi7BsHUA3Jh2SEhBWHyQezmCBMPIlLnJPLsRZzZ0wAvImRsCzTXj1EWFkEmIQHj2HMpST2tFkA9z21PJV3V1N210ArhGNGbl4TBBMDSDdksjLxDHbDRCOGULFFT0B3YAwuMEcgYmNCMhxI3270skrFbHMkA07BPxnNpIHAv0iU4Gv2ngwuPHlmPStNz1tG3DyBDDWAWEow3Fpw2KIXQIgKN2wPQlgJoptF+N3lSVC2hyKCNBsgH1sGP2GnM2bP7DULYI4IxJjPwKZBKAYhNAEyMgM35MsjoJDHYRBBqBWEbHqNSKaPSMEPstq29JWAFCFHbwROJ1kJshMGuOFGOLUEYJ4skB6M4BCrrhaKkjaPQhouW19mFCyAjE4lsCixZAHhLOZGtCtBcBcCAA */ id: 'Modeling', tsTypes: {} as import('./modelingMachine.typegen').Typegen0, @@ -135,11 +146,14 @@ export const modelingMachine = createMachine( otherSelections: [], codeBasedSelections: [], } as Selections, - selectionRangeTypeMap: {} as SelectionRangeTypeMap, - sketchPathToNode: null as PathToNode | null, // maybe too specific, and we should have a generic pathToNode, but being specific seems less risky when I'm not sure - sketchEnginePathId: '' as string, + sketchDetails: { + sketchPathToNode: [], + zAxis: [0, 0, 1], + yAxis: [0, 1, 0], + origin: [0, 0, 0], + } as null | SketchDetails, sketchPlaneId: '' as string, - sketchNormalBackUp: null as null | [number, number, number], + sketchEnginePathId: '' as string, moveDescs: [] as MoveDesc[], }, @@ -160,7 +174,6 @@ export const modelingMachine = createMachine( { target: 'animating to existing sketch', cond: 'Selection is on face', - actions: ['set sketch metadata'], }, 'Sketch no face', ], @@ -504,6 +517,11 @@ export const modelingMachine = createMachine( target: 'animating to plane', actions: ['reset sketch metadata'], }, + + 'Set selection': { + target: 'Sketch no face', + internal: true, + }, }, }, @@ -532,15 +550,15 @@ export const modelingMachine = createMachine( { src: 'animate-to-sketch', id: 'animate-to-sketch', - onDone: 'Sketch', + onDone: { + target: 'Sketch', + actions: 'set new sketch metadata', + }, }, ], entry: 'clientToEngine cam sync direction', }, - - 'animating to plane (copy)': {}, - 'animating to plane (copy) (copy)': {}, }, initial: 'idle', @@ -562,13 +580,13 @@ export const modelingMachine = createMachine( }, { guards: { - 'is editing existing sketch': ({ sketchPathToNode }) => { + 'is editing existing sketch': ({ sketchDetails }) => { // should check that the variable declaration is a pipeExpression // and that the pipeExpression contains a "startProfileAt" callExpression - if (!sketchPathToNode) return false + if (!sketchDetails?.sketchPathToNode) return false const variableDeclaration = getNodeFromPath( kclManager.ast, - sketchPathToNode, + sketchDetails.sketchPathToNode, 'VariableDeclarator' ).node if (variableDeclaration.type !== 'VariableDeclarator') return false @@ -621,128 +639,154 @@ export const modelingMachine = createMachine( }, // end guards actions: { - 'set sketchMetadata from pathToNode': assign(({ sketchPathToNode }) => { - if (!sketchPathToNode) return {} - return getSketchMetadataFromPathToNode(sketchPathToNode) + 'set sketchMetadata from pathToNode': assign(({ sketchDetails }) => { + if (!sketchDetails?.sketchPathToNode || !sketchDetails) return {} + return { + sketchDetails: { + ...sketchDetails, + sketchPathToNode: sketchDetails.sketchPathToNode, + }, + } }), 'hide default planes': () => { sceneInfra.removeDefaultPlanes() kclManager.hidePlanes() }, 'reset sketch metadata': assign({ - sketchPathToNode: null, + sketchDetails: null, sketchEnginePathId: '', sketchPlaneId: '', }), - 'set sketch metadata': assign(({ selectionRanges }) => { - const sourceRange = selectionRanges.codeBasedSelections[0].range - const sketchPathToNode = getNodePathFromSourceRange( - kclManager.ast, - sourceRange - ) - return getSketchMetadataFromPathToNode( - sketchPathToNode, - selectionRanges - ) - }), - 'set new sketch metadata': assign((_, { data }) => data), + 'set new sketch metadata': assign((_, { data }) => ({ + sketchDetails: data, + })), // TODO implement source ranges for all of these constraints // need to make the async like the modal constraints - 'Make selection horizontal': ({ selectionRanges, sketchPathToNode }) => { + 'Make selection horizontal': ({ selectionRanges, sketchDetails }) => { const { modifiedAst } = applyConstraintHorzVert( selectionRanges, 'horizontal', kclManager.ast, kclManager.programMemory ) + if (!sketchDetails) return sceneEntitiesManager.updateAstAndRejigSketch( - sketchPathToNode || [], - modifiedAst + sketchDetails.sketchPathToNode, + modifiedAst, + sketchDetails.zAxis, + sketchDetails.yAxis, + sketchDetails.origin ) }, - 'Make selection vertical': ({ selectionRanges, sketchPathToNode }) => { + 'Make selection vertical': ({ selectionRanges, sketchDetails }) => { const { modifiedAst } = applyConstraintHorzVert( selectionRanges, 'vertical', kclManager.ast, kclManager.programMemory ) + if (!sketchDetails) return sceneEntitiesManager.updateAstAndRejigSketch( - sketchPathToNode || [], - modifiedAst + sketchDetails.sketchPathToNode || [], + modifiedAst, + sketchDetails.zAxis, + sketchDetails.yAxis, + sketchDetails.origin ) }, - 'Constrain horizontally align': ({ - selectionRanges, - sketchPathToNode, - }) => { + 'Constrain horizontally align': ({ selectionRanges, sketchDetails }) => { const { modifiedAst } = applyConstraintHorzVertAlign({ selectionRanges, constraint: 'setVertDistance', }) + if (!sketchDetails) return sceneEntitiesManager.updateAstAndRejigSketch( - sketchPathToNode || [], - modifiedAst + sketchDetails?.sketchPathToNode || [], + modifiedAst, + sketchDetails.zAxis, + sketchDetails.yAxis, + sketchDetails.origin ) }, - 'Constrain vertically align': ({ selectionRanges, sketchPathToNode }) => { + 'Constrain vertically align': ({ selectionRanges, sketchDetails }) => { const { modifiedAst } = applyConstraintHorzVertAlign({ selectionRanges, constraint: 'setHorzDistance', }) + if (!sketchDetails) return sceneEntitiesManager.updateAstAndRejigSketch( - sketchPathToNode || [], - modifiedAst + sketchDetails?.sketchPathToNode || [], + modifiedAst, + sketchDetails.zAxis, + sketchDetails.yAxis, + sketchDetails.origin ) }, - 'Constrain snap to X': ({ selectionRanges, sketchPathToNode }) => { + 'Constrain snap to X': ({ selectionRanges, sketchDetails }) => { const { modifiedAst } = applyConstraintAxisAlign({ selectionRanges, constraint: 'snapToXAxis', }) + if (!sketchDetails) return sceneEntitiesManager.updateAstAndRejigSketch( - sketchPathToNode || [], - modifiedAst + sketchDetails?.sketchPathToNode || [], + modifiedAst, + sketchDetails.zAxis, + sketchDetails.yAxis, + sketchDetails.origin ) }, - 'Constrain snap to Y': ({ selectionRanges, sketchPathToNode }) => { + 'Constrain snap to Y': ({ selectionRanges, sketchDetails }) => { const { modifiedAst } = applyConstraintAxisAlign({ selectionRanges, constraint: 'snapToYAxis', }) + if (!sketchDetails) return sceneEntitiesManager.updateAstAndRejigSketch( - sketchPathToNode || [], - modifiedAst + sketchDetails?.sketchPathToNode || [], + modifiedAst, + sketchDetails.zAxis, + sketchDetails.yAxis, + sketchDetails.origin ) }, - 'Constrain equal length': ({ selectionRanges, sketchPathToNode }) => { + 'Constrain equal length': ({ selectionRanges, sketchDetails }) => { const { modifiedAst } = applyConstraintEqualLength({ selectionRanges, }) + if (!sketchDetails) return sceneEntitiesManager.updateAstAndRejigSketch( - sketchPathToNode || [], - modifiedAst + sketchDetails?.sketchPathToNode || [], + modifiedAst, + sketchDetails.zAxis, + sketchDetails.yAxis, + sketchDetails.origin ) }, - 'Constrain parallel': ({ selectionRanges, sketchPathToNode }) => { + 'Constrain parallel': ({ selectionRanges, sketchDetails }) => { const { modifiedAst } = applyConstraintEqualAngle({ selectionRanges, }) + if (!sketchDetails) return sceneEntitiesManager.updateAstAndRejigSketch( - sketchPathToNode || [], - modifiedAst + sketchDetails?.sketchPathToNode || [], + modifiedAst, + sketchDetails.zAxis, + sketchDetails.yAxis, + sketchDetails.origin ) }, - 'Constrain remove constraints': ({ - selectionRanges, - sketchPathToNode, - }) => { + 'Constrain remove constraints': ({ selectionRanges, sketchDetails }) => { const { modifiedAst } = applyRemoveConstrainingValues({ selectionRanges, }) + if (!sketchDetails) return sceneEntitiesManager.updateAstAndRejigSketch( - sketchPathToNode || [], - modifiedAst + sketchDetails?.sketchPathToNode || [], + modifiedAst, + sketchDetails.zAxis, + sketchDetails.yAxis, + sketchDetails.origin ) }, 'AST extrude': (_, event) => { @@ -754,7 +798,6 @@ export const modelingMachine = createMachine( distance.variableName && distance.insertIndex !== undefined ) { - console.log('adding variable!', distance) const newBody = [...ast.body] newBody.splice( distance.insertIndex, @@ -785,18 +828,25 @@ export const modelingMachine = createMachine( sceneInfra.modelingSend('Equip Line tool') } }, - 'setup client side sketch segments': ({ sketchPathToNode }, { type }) => { + 'setup client side sketch segments': ({ sketchDetails }) => { + if (!sketchDetails) return if (Object.keys(sceneEntitiesManager.activeSegments).length > 0) { sceneEntitiesManager .tearDownSketch({ removeAxis: false }) .then(() => { sceneEntitiesManager.setupSketch({ - sketchPathToNode: sketchPathToNode || [], + sketchPathToNode: sketchDetails?.sketchPathToNode || [], + forward: sketchDetails.zAxis, + up: sketchDetails.yAxis, + position: sketchDetails.origin, }) }) } else { sceneEntitiesManager.setupSketch({ - sketchPathToNode: sketchPathToNode || [], + sketchPathToNode: sketchDetails?.sketchPathToNode || [], + forward: sketchDetails.zAxis, + up: sketchDetails.yAxis, + position: sketchDetails.origin, }) } }, @@ -809,43 +859,60 @@ export const modelingMachine = createMachine( } }, 'remove sketch grid': () => sceneEntitiesManager.removeSketchGrid(), - 'set up draft line': ({ sketchPathToNode }) => { - sceneEntitiesManager.setUpDraftLine(sketchPathToNode || []) + 'set up draft line': ({ sketchDetails }) => { + if (!sketchDetails) return + sceneEntitiesManager.setUpDraftLine( + sketchDetails.sketchPathToNode, + sketchDetails.zAxis, + sketchDetails.yAxis + ) }, - 'set up draft arc': ({ sketchPathToNode }) => { - sceneEntitiesManager.setUpDraftArc(sketchPathToNode || []) + 'set up draft arc': ({ sketchDetails }) => { + if (!sketchDetails) return + sceneEntitiesManager.setUpDraftArc( + sketchDetails.sketchPathToNode, + sketchDetails.zAxis, + sketchDetails.yAxis + ) }, - 'set up draft line without teardown': ({ sketchPathToNode }) => + 'set up draft line without teardown': ({ sketchDetails }) => sceneEntitiesManager.setupSketch({ - sketchPathToNode: sketchPathToNode || [], + sketchPathToNode: sketchDetails?.sketchPathToNode || [], draftSegment: 'line', + forward: sketchDetails?.zAxis || [0, 1, 0], + up: sketchDetails?.yAxis || [0, 0, 1], + position: sketchDetails?.origin, }), 'show default planes': () => { sceneInfra.showDefaultPlanes() sceneEntitiesManager.setupDefaultPlaneHover() kclManager.showPlanes() }, - 'setup noPoints onClick listener': ({ sketchPathToNode }) => { + 'setup noPoints onClick listener': ({ sketchDetails }) => { + if (!sketchDetails) return sceneEntitiesManager.createIntersectionPlane() - const sketchGroup = sketchGroupFromPathToNode({ - pathToNode: sketchPathToNode || [], - ast: kclManager.ast, - programMemory: kclManager.programMemory, - }) - const quaternion = quaternionFromSketchGroup(sketchGroup) + 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])) + ) sceneInfra.setCallbacks({ onClick: async (args) => { if (!args) return if (args.mouseEvent.which !== 1) return const { intersectionPoint } = args - if (!intersectionPoint?.twoD || !sketchPathToNode) return + if (!intersectionPoint?.twoD || !sketchDetails?.sketchPathToNode) + return const { modifiedAst } = addStartProfileAt( kclManager.ast, - sketchPathToNode, + sketchDetails.sketchPathToNode, [intersectionPoint.twoD.x, intersectionPoint.twoD.y] ) await kclManager.updateAst(modifiedAst, false) @@ -854,8 +921,15 @@ export const modelingMachine = createMachine( }, }) }, - 'add axis n grid': ({ sketchPathToNode }) => - sceneEntitiesManager.createSketchAxis(sketchPathToNode || []), + 'add axis n grid': ({ sketchDetails }) => { + if (!sketchDetails) return + sceneEntitiesManager.createSketchAxis( + sketchDetails.sketchPathToNode || [], + sketchDetails.zAxis, + sketchDetails.yAxis, + sketchDetails.origin + ) + }, 'reset client scene mouse handlers': () => { // when not in sketch mode we don't need any mouse listeners // (note the orbit controls are always active though) @@ -871,44 +945,3 @@ export const modelingMachine = createMachine( // end actions } ) - -function getSketchMetadataFromPathToNode( - pathToNode: PathToNode, - selectionRanges?: Selections -) { - const pipeExpression = getNodeFromPath( - kclManager.ast, - pathToNode, - 'PipeExpression' - ).node - if (pipeExpression.type !== 'PipeExpression') return {} - const sketchCallExpression = pipeExpression.body.find( - (e) => e.type === 'CallExpression' && e.callee.name === 'startSketchOn' - ) as CallExpression - if (!sketchCallExpression) return {} - - let sketchEnginePathId: string - if (selectionRanges) { - sketchEnginePathId = - isCursorInSketchCommandRange( - engineCommandManager.artifactMap, - selectionRanges - ) || '' - } else { - const _selectionRanges: Selections = { - otherSelections: [], - codeBasedSelections: [ - { range: [pipeExpression.start, pipeExpression.end], type: 'default' }, - ], - } - sketchEnginePathId = - isCursorInSketchCommandRange( - engineCommandManager.artifactMap, - _selectionRanges - ) || '' - } - return { - sketchPathToNode: pathToNode, - sketchEnginePathId, - } -} diff --git a/src/useStore.ts b/src/useStore.ts index e3ed2d1200..2a6ce03087 100644 --- a/src/useStore.ts +++ b/src/useStore.ts @@ -93,6 +93,8 @@ export interface StoreState { path: string }[] setHomeMenuItems: (items: { name: string; path: string }[]) => void + lastCodeMirrorSelectionUpdatedFromScene: number + setLastCodeMirrorSelectionUpdatedFromScene: (time: number) => void } export const useStore = create()( @@ -156,6 +158,9 @@ export const useStore = create()( setHomeShowMenu: (showHomeMenu) => set({ showHomeMenu }), homeMenuItems: [], setHomeMenuItems: (homeMenuItems) => set({ homeMenuItems }), + lastCodeMirrorSelectionUpdatedFromScene: Date.now(), + setLastCodeMirrorSelectionUpdatedFromScene: (time) => + set({ lastCodeMirrorSelectionUpdatedFromScene: time }), } }, { diff --git a/src/wasm-lib/kcl/src/executor.rs b/src/wasm-lib/kcl/src/executor.rs index e0d4c94932..11ddb4c7ba 100644 --- a/src/wasm-lib/kcl/src/executor.rs +++ b/src/wasm-lib/kcl/src/executor.rs @@ -242,6 +242,8 @@ pub struct Face { pub y_axis: Point3d, /// The z-axis (normal). pub z_axis: Point3d, + /// the face id the sketch is on + pub face_id: uuid::Uuid, #[serde(rename = "__meta")] pub meta: Vec, } diff --git a/src/wasm-lib/kcl/src/std/extrude.rs b/src/wasm-lib/kcl/src/std/extrude.rs index d2c19e7035..0817d2d584 100644 --- a/src/wasm-lib/kcl/src/std/extrude.rs +++ b/src/wasm-lib/kcl/src/std/extrude.rs @@ -3,6 +3,7 @@ use anyhow::Result; use derive_docs::stdlib; use schemars::JsonSchema; +use uuid::Uuid; use crate::{ errors::{KclError, KclErrorDetails}, @@ -113,8 +114,9 @@ async fn inner_extrude(length: f64, sketch_group: Box, args: Args) // Create a hashmap for quick id lookup let mut face_id_map = std::collections::HashMap::new(); - let mut start_cap_id = None; - let mut end_cap_id = None; + // creating fake ids for start and end caps is to make extrudes mock-execute safe + let mut start_cap_id = Some(Uuid::new_v4()); + let mut end_cap_id = Some(Uuid::new_v4()); for face_info in face_infos { match face_info.cap { @@ -160,6 +162,18 @@ async fn inner_extrude(length: f64, sketch_group: Box, args: Args) new_value.push(extrude_surface); } } + } else { + new_value.push(ExtrudeSurface::ExtrudePlane(crate::executor::ExtrudePlane { + position: sketch_group.position, // TODO should be for the extrude surface + rotation: sketch_group.rotation, // TODO should be for the extrude surface + // pushing this values with a fake face_id to make extrudes mock-execute safe + face_id: Uuid::new_v4(), + name: path.get_base().name.clone(), + geo_meta: GeoMeta { + id: path.get_base().geo_meta.id, + metadata: path.get_base().geo_meta.metadata.clone(), + }, + })); } } diff --git a/src/wasm-lib/kcl/src/std/sketch.rs b/src/wasm-lib/kcl/src/std/sketch.rs index 52f766db7d..64118dc7d8 100644 --- a/src/wasm-lib/kcl/src/std/sketch.rs +++ b/src/wasm-lib/kcl/src/std/sketch.rs @@ -955,6 +955,7 @@ async fn start_sketch_on_face( y_axis: extrude_group.y_axis, z_axis: extrude_group.z_axis, meta: vec![args.source_range.into()], + face_id: extrude_plane_id, })) }