From d73e5ca7c0e8121ca1c1d2e027c1299704b13e96 Mon Sep 17 00:00:00 2001 From: Kurt Hutten Irev-Dev Date: Thu, 8 Aug 2024 21:53:31 +1000 Subject: [PATCH] add edges to artifact graph --- src/hooks/useEngineConnectionSubscriptions.ts | 8 + .../__snapshots__/artifactGraph.test.ts.snap | 163 +++++++++++++++--- src/lang/std/artifactGraph.test.ts | 22 +-- src/lang/std/artifactGraph.ts | 62 ++++++- src/lib/selections.ts | 17 ++ src/lib/singletons.ts | 35 ++++ src/wasm-lib/kcl/src/std/extrude.rs | 42 +++++ 7 files changed, 316 insertions(+), 33 deletions(-) diff --git a/src/hooks/useEngineConnectionSubscriptions.ts b/src/hooks/useEngineConnectionSubscriptions.ts index b9888901c..6be7d2f61 100644 --- a/src/hooks/useEngineConnectionSubscriptions.ts +++ b/src/hooks/useEngineConnectionSubscriptions.ts @@ -9,6 +9,7 @@ import { useModelingContext } from './useModelingContext' import { getEventForSelectWithPoint } from 'lib/selections' import { getCapCodeRef, + getExtrudeEdgeCodeRef, getExtrusionFromSuspectedExtrudeSurface, getSolid2dCodeRef, getWallCodeRef, @@ -60,6 +61,13 @@ export function useEngineConnectionSubscriptions() { ? [codeRef.range] : [codeRef.range, extrusion.codeRef.range] ) + } else if (artifact?.type === 'extrudeEdge') { + const codeRef = getExtrudeEdgeCodeRef( + artifact, + engineCommandManager.artifactGraph + ) + if (err(codeRef)) return + editorManager.setHighlightRange([codeRef.range]) } else if (artifact?.type === 'segment') { editorManager.setHighlightRange([ artifact?.codeRef?.range || [0, 0], diff --git a/src/lang/std/__snapshots__/artifactGraph.test.ts.snap b/src/lang/std/__snapshots__/artifactGraph.test.ts.snap index ad00a31fd..cd896d1d5 100644 --- a/src/lang/std/__snapshots__/artifactGraph.test.ts.snap +++ b/src/lang/std/__snapshots__/artifactGraph.test.ts.snap @@ -58,7 +58,10 @@ Map { 92, ], }, - "edgeIds": [], + "edgeIds": [ + "UUID", + "UUID", + ], "pathId": "UUID", "surfaceId": "UUID", "type": "segment", @@ -77,7 +80,10 @@ Map { ], }, "edgeCutId": "UUID", - "edgeIds": [], + "edgeIds": [ + "UUID", + "UUID", + ], "pathId": "UUID", "surfaceId": "UUID", "type": "segment", @@ -95,7 +101,10 @@ Map { 156, ], }, - "edgeIds": [], + "edgeIds": [ + "UUID", + "UUID", + ], "pathId": "UUID", "surfaceId": "UUID", "type": "segment", @@ -113,7 +122,10 @@ Map { 209, ], }, - "edgeIds": [], + "edgeIds": [ + "UUID", + "UUID", + ], "pathId": "UUID", "surfaceId": "UUID", "type": "segment", @@ -152,7 +164,16 @@ Map { 266, ], }, - "edgeIds": [], + "edgeIds": [ + "UUID", + "UUID", + "UUID", + "UUID", + "UUID", + "UUID", + "UUID", + "UUID", + ], "pathId": "UUID", "surfaceIds": [ "UUID", @@ -209,6 +230,54 @@ Map { "type": "cap", }, "UUID-15" => { + "extrusionId": "UUID", + "segId": "UUID", + "subType": "adjacent", + "type": "extrudeEdge", + }, + "UUID-16" => { + "extrusionId": "UUID", + "segId": "UUID", + "subType": "opposite", + "type": "extrudeEdge", + }, + "UUID-17" => { + "extrusionId": "UUID", + "segId": "UUID", + "subType": "adjacent", + "type": "extrudeEdge", + }, + "UUID-18" => { + "extrusionId": "UUID", + "segId": "UUID", + "subType": "opposite", + "type": "extrudeEdge", + }, + "UUID-19" => { + "extrusionId": "UUID", + "segId": "UUID", + "subType": "adjacent", + "type": "extrudeEdge", + }, + "UUID-20" => { + "extrusionId": "UUID", + "segId": "UUID", + "subType": "opposite", + "type": "extrudeEdge", + }, + "UUID-21" => { + "extrusionId": "UUID", + "segId": "UUID", + "subType": "adjacent", + "type": "extrudeEdge", + }, + "UUID-22" => { + "extrusionId": "UUID", + "segId": "UUID", + "subType": "opposite", + "type": "extrudeEdge", + }, + "UUID-23" => { "codeRef": { "pathToNode": [ [ @@ -226,7 +295,7 @@ Map { "subType": "fillet", "type": "edgeCut", }, - "UUID-16" => { + "UUID-24" => { "codeRef": { "pathToNode": [ [ @@ -250,7 +319,7 @@ Map { "solid2dId": "UUID", "type": "path", }, - "UUID-17" => { + "UUID-25" => { "codeRef": { "pathToNode": [ [ @@ -263,12 +332,15 @@ Map { 416, ], }, - "edgeIds": [], + "edgeIds": [ + "UUID", + "UUID", + ], "pathId": "UUID", "surfaceId": "UUID", "type": "segment", }, - "UUID-18" => { + "UUID-26" => { "codeRef": { "pathToNode": [ [ @@ -281,12 +353,15 @@ Map { 438, ], }, - "edgeIds": [], + "edgeIds": [ + "UUID", + "UUID", + ], "pathId": "UUID", "surfaceId": "UUID", "type": "segment", }, - "UUID-19" => { + "UUID-27" => { "codeRef": { "pathToNode": [ [ @@ -299,12 +374,15 @@ Map { 491, ], }, - "edgeIds": [], + "edgeIds": [ + "UUID", + "UUID", + ], "pathId": "UUID", "surfaceId": "UUID", "type": "segment", }, - "UUID-20" => { + "UUID-28" => { "codeRef": { "pathToNode": [ [ @@ -321,11 +399,11 @@ Map { "pathId": "UUID", "type": "segment", }, - "UUID-21" => { + "UUID-29" => { "pathId": "UUID", "type": "solid2D", }, - "UUID-22" => { + "UUID-30" => { "codeRef": { "pathToNode": [ [ @@ -338,7 +416,14 @@ Map { 546, ], }, - "edgeIds": [], + "edgeIds": [ + "UUID", + "UUID", + "UUID", + "UUID", + "UUID", + "UUID", + ], "pathId": "UUID", "surfaceIds": [ "UUID", @@ -349,40 +434,76 @@ Map { ], "type": "extrusion", }, - "UUID-23" => { + "UUID-31" => { "edgeCutEdgeIds": [], "extrusionId": "UUID", "pathIds": [], "segId": "UUID", "type": "wall", }, - "UUID-24" => { + "UUID-32" => { "edgeCutEdgeIds": [], "extrusionId": "UUID", "pathIds": [], "segId": "UUID", "type": "wall", }, - "UUID-25" => { + "UUID-33" => { "edgeCutEdgeIds": [], "extrusionId": "UUID", "pathIds": [], "segId": "UUID", "type": "wall", }, - "UUID-26" => { + "UUID-34" => { "edgeCutEdgeIds": [], "extrusionId": "UUID", "pathIds": [], "subType": "start", "type": "cap", }, - "UUID-27" => { + "UUID-35" => { "edgeCutEdgeIds": [], "extrusionId": "UUID", "pathIds": [], "subType": "end", "type": "cap", }, + "UUID-36" => { + "extrusionId": "UUID", + "segId": "UUID", + "subType": "adjacent", + "type": "extrudeEdge", + }, + "UUID-37" => { + "extrusionId": "UUID", + "segId": "UUID", + "subType": "opposite", + "type": "extrudeEdge", + }, + "UUID-38" => { + "extrusionId": "UUID", + "segId": "UUID", + "subType": "adjacent", + "type": "extrudeEdge", + }, + "UUID-39" => { + "extrusionId": "UUID", + "segId": "UUID", + "subType": "opposite", + "type": "extrudeEdge", + }, + "UUID-40" => { + "extrusionId": "UUID", + "segId": "UUID", + "subType": "adjacent", + "type": "extrudeEdge", + }, + "UUID-41" => { + "extrusionId": "UUID", + "segId": "UUID", + "subType": "opposite", + "type": "extrudeEdge", + }, } `; diff --git a/src/lang/std/artifactGraph.test.ts b/src/lang/std/artifactGraph.test.ts index 8e261251d..a02c46009 100644 --- a/src/lang/std/artifactGraph.test.ts +++ b/src/lang/std/artifactGraph.test.ts @@ -607,7 +607,7 @@ describe('testing getArtifactsToUpdate', () => { type: 'segment', pathId: expect.any(String), surfaceId: expect.any(String), - edgeIds: [], + edgeIds: expect.any(Array), codeRef: { range: [98, 125], pathToNode: [['body', '']], @@ -627,7 +627,7 @@ describe('testing getArtifactsToUpdate', () => { type: 'segment', pathId: expect.any(String), surfaceId: expect.any(String), - edgeIds: [], + edgeIds: expect.any(Array), codeRef: { range: [162, 209], pathToNode: [['body', '']], @@ -637,7 +637,7 @@ describe('testing getArtifactsToUpdate', () => { type: 'extrusion', pathId: expect.any(String), surfaceIds: expect.any(Array), - edgeIds: [], + edgeIds: expect.any(Array), codeRef: { range: [243, 266], pathToNode: [['body', '']], @@ -654,7 +654,7 @@ describe('testing getArtifactsToUpdate', () => { type: 'segment', pathId: expect.any(String), surfaceId: expect.any(String), - edgeIds: [], + edgeIds: expect.any(Array), codeRef: { range: [131, 156], pathToNode: [['body', '']], @@ -664,7 +664,7 @@ describe('testing getArtifactsToUpdate', () => { type: 'extrusion', pathId: expect.any(String), surfaceIds: expect.any(Array), - edgeIds: [], + edgeIds: expect.any(Array), codeRef: { range: [243, 266], pathToNode: [['body', '']], @@ -681,7 +681,7 @@ describe('testing getArtifactsToUpdate', () => { type: 'segment', pathId: expect.any(String), surfaceId: expect.any(String), - edgeIds: [], + edgeIds: expect.any(Array), codeRef: { range: [98, 125], pathToNode: [['body', '']], @@ -692,7 +692,7 @@ describe('testing getArtifactsToUpdate', () => { type: 'extrusion', pathId: expect.any(String), surfaceIds: expect.any(Array), - edgeIds: [], + edgeIds: expect.any(Array), codeRef: { range: [243, 266], pathToNode: [['body', '']], @@ -709,7 +709,7 @@ describe('testing getArtifactsToUpdate', () => { type: 'segment', pathId: expect.any(String), surfaceId: expect.any(String), - edgeIds: [], + edgeIds: expect.any(Array), codeRef: { range: [76, 92], pathToNode: [['body', '']], @@ -719,7 +719,7 @@ describe('testing getArtifactsToUpdate', () => { type: 'extrusion', pathId: expect.any(String), surfaceIds: expect.any(Array), - edgeIds: [], + edgeIds: expect.any(Array), codeRef: { range: [243, 266], pathToNode: [['body', '']], @@ -736,7 +736,7 @@ describe('testing getArtifactsToUpdate', () => { type: 'extrusion', pathId: expect.any(String), surfaceIds: expect.any(Array), - edgeIds: [], + edgeIds: expect.any(Array), codeRef: { range: [243, 266], pathToNode: [['body', '']], @@ -753,7 +753,7 @@ describe('testing getArtifactsToUpdate', () => { type: 'extrusion', pathId: expect.any(String), surfaceIds: expect.any(Array), - edgeIds: [], + edgeIds: expect.any(Array), codeRef: { range: [243, 266], pathToNode: [['body', '']], diff --git a/src/lang/std/artifactGraph.ts b/src/lang/std/artifactGraph.ts index 9ab950230..39f3a0f15 100644 --- a/src/lang/std/artifactGraph.ts +++ b/src/lang/std/artifactGraph.ts @@ -91,7 +91,7 @@ interface ExtrudeEdge { type: 'extrudeEdge' segId: string extrusionId: string - edgeId: string + subType: 'opposite' | 'adjacent' } /** A edgeCut is a more generic term for both fillet or chamfer */ @@ -422,6 +422,54 @@ export function getArtifactsToUpdate({ } }) return returnArr + } else if ( + (cmd.type === 'solid3d_get_opposite_edge' && + response.type === 'modeling' && + response.data.modeling_response.type === 'solid3d_get_opposite_edge' && + response.data.modeling_response.data.edge) || + (cmd.type === 'solid3d_get_prev_adjacent_edge' && + response.type === 'modeling' && + response.data.modeling_response.type === + 'solid3d_get_prev_adjacent_edge' && + response.data.modeling_response.data.edge) + ) { + const wall = getArtifact(cmd.face_id) + if (wall?.type !== 'wall') return returnArr + const extrusion = getArtifact(wall.extrusionId) + if (extrusion?.type !== 'extrusion') return returnArr + const path = getArtifact(extrusion.pathId) + if (path?.type !== 'path') return returnArr + const segment = getArtifact(cmd.edge_id) + if (segment?.type !== 'segment') return returnArr + + return [ + { + id: response.data.modeling_response.data.edge, + artifact: { + type: 'extrudeEdge', + subType: + cmd.type === 'solid3d_get_prev_adjacent_edge' + ? 'opposite' + : 'adjacent', + segId: cmd.edge_id, + extrusionId: path.extrusionId, + }, + }, + { + id: cmd.edge_id, + artifact: { + ...segment, + edgeIds: [response.data.modeling_response.data.edge], + }, + }, + { + id: path.extrusionId, + artifact: { + ...extrusion, + edgeIds: [response.data.modeling_response.data.edge], + }, + }, + ] } else if (cmd.type === 'solid3d_fillet_edge') { returnArr.push({ id, @@ -655,6 +703,18 @@ export function getWallCodeRef( return seg.codeRef } +export function getExtrudeEdgeCodeRef( + edge: ExtrudeEdge, + artifactGraph: ArtifactGraph +): CommonCommandProperties | Error { + const seg = getArtifactOfTypes( + { key: edge.segId, types: ['segment'] }, + artifactGraph + ) + if (err(seg)) return seg + return seg.codeRef +} + export function getExtrusionFromSuspectedExtrudeSurface( id: string, artifactGraph: ArtifactGraph diff --git a/src/lib/selections.ts b/src/lib/selections.ts index 790df7f64..1303e37dd 100644 --- a/src/lib/selections.ts +++ b/src/lib/selections.ts @@ -33,6 +33,7 @@ import { getArtifactOfTypes, getArtifactsOfTypes, getCapCodeRef, + getExtrudeEdgeCodeRef, getSolid2dCodeRef, getWallCodeRef, } from 'lang/std/artifactGraph' @@ -85,6 +86,7 @@ export async function getEventForSelectWithPoint({ } } let _artifact = engineCommandManager.artifactGraph.get(data.entity_id) + console.log('entity id', data.entity_id) if (!_artifact) return { type: 'Set selection', @@ -141,6 +143,21 @@ export async function getEventForSelectWithPoint({ }, } } + if (_artifact.type === 'extrudeEdge') { + const codeRef = getExtrudeEdgeCodeRef( + _artifact, + engineCommandManager.artifactGraph + ) + console.log('codeRef', codeRef) + if (err(codeRef)) return null + return { + type: 'Set selection', + data: { + selectionType: 'singleCodeCursor', + selection: { range: codeRef.range, type: 'edge' }, + }, + } + } return null } diff --git a/src/lib/singletons.ts b/src/lib/singletons.ts index 17e5cf25e..ffb25f3ef 100644 --- a/src/lib/singletons.ts +++ b/src/lib/singletons.ts @@ -51,4 +51,39 @@ if (typeof window !== 'undefined') { padding: 0.2, // padding around the objects }, }) + ;(window as any).getEdgesForAndAskEngineForType = async (faceId: string) => { + // Kurt - Debugging tool used help to show edges aren't stable after further 3d operations + // if this was added more than a few months ago, it probably can be removed. + const face = engineCommandManager.artifactGraph.get(faceId) + if (face?.type !== 'wall') { + console.log('was expecting a wall, you gave me a ', face?.type) + return + } + const extrusion = engineCommandManager.artifactGraph.get(face.extrusionId) + if (extrusion?.type !== 'extrusion') { + console.log('was expecting an extrusion, but got ', extrusion?.type) + return + } + extrusion.edgeIds.forEach(async (edgeId) => { + const result = await engineCommandManager + .sendSceneCommand({ + type: 'modeling_cmd_req', + cmd_id: uuidv4(), + cmd: { + type: 'get_entity_type', + entity_id: edgeId, + }, + }) + .catch((a) => console.log('error:', a)) + if (!result?.success) return + if (result.resp.type !== 'modeling') return + if (result.resp.data.modeling_response.type !== 'get_entity_type') return + console.log( + 'result edge is: ', + result.resp.data.modeling_response.data.entity_type, + ' id: ', + edgeId + ) + }) + } } diff --git a/src/wasm-lib/kcl/src/std/extrude.rs b/src/wasm-lib/kcl/src/std/extrude.rs index 9b5ff556a..2b3d055c0 100644 --- a/src/wasm-lib/kcl/src/std/extrude.rs +++ b/src/wasm-lib/kcl/src/std/extrude.rs @@ -181,6 +181,48 @@ pub(crate) async fn do_post_extrude( vec![] }; + for face_info in face_infos.iter() { + if face_info.cap == kittycad::types::ExtrusionFaceCapType::None + && face_info.face_id.is_some() + && face_info.curve_id.is_some() + { + match args + .batch_modeling_cmd( + uuid::Uuid::new_v4(), + kittycad::types::ModelingCmd::Solid3DGetOppositeEdge { + edge_id: face_info.curve_id.unwrap(), + object_id: sketch_group.id, + face_id: face_info.face_id.unwrap_or_default(), + }, + ) + .await + { + Ok(info) => info, + Err(e) => { + eprintln!("Error fetching opposite edge: {:?}", e); + continue; + } + }; + match args + .batch_modeling_cmd( + uuid::Uuid::new_v4(), + kittycad::types::ModelingCmd::Solid3DGetPrevAdjacentEdge { + edge_id: face_info.curve_id.unwrap(), + object_id: sketch_group.id, + face_id: face_info.face_id.unwrap(), + }, + ) + .await + { + Ok(info) => info, + Err(e) => { + eprintln!("Error fetching adjacent edge: {:?}", e); + continue; + } + }; + } + } + // Create a hashmap for quick id lookup let mut face_id_map = std::collections::HashMap::new(); // creating fake ids for start and end caps is to make extrudes mock-execute safe