Compare commits
	
		
			6 Commits
		
	
	
		
			lf94/fix-r
			...
			jtran/fix-
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 1953ca0607 | |||
| cb9fa71645 | |||
| a7f0a5607d | |||
| eb28ed6cbf | |||
| 3c84ef8592 | |||
| 9b966de7f0 | 
| @ -84,7 +84,11 @@ import { | |||||||
|   createPipeSubstitution, |   createPipeSubstitution, | ||||||
|   findUniqueName, |   findUniqueName, | ||||||
| } from 'lang/modifyAst' | } from 'lang/modifyAst' | ||||||
| import { Selections, getEventForSegmentSelection } from 'lib/selections' | import { | ||||||
|  |   Selection, | ||||||
|  |   Selections, | ||||||
|  |   getEventForSegmentSelection, | ||||||
|  | } from 'lib/selections' | ||||||
| import { getTangentPointFromPreviousArc } from 'lib/utils2d' | import { getTangentPointFromPreviousArc } from 'lib/utils2d' | ||||||
| import { createGridHelper, orthoScale, perspScale } from './helpers' | import { createGridHelper, orthoScale, perspScale } from './helpers' | ||||||
| import { Models } from '@kittycad/lib' | import { Models } from '@kittycad/lib' | ||||||
| @ -98,6 +102,11 @@ import { | |||||||
| import { getThemeColorForThreeJs } from 'lib/theme' | import { getThemeColorForThreeJs } from 'lib/theme' | ||||||
| import { err, trap } from 'lib/trap' | import { err, trap } from 'lib/trap' | ||||||
| import { CSS2DObject } from 'three/examples/jsm/renderers/CSS2DRenderer' | import { CSS2DObject } from 'three/examples/jsm/renderers/CSS2DRenderer' | ||||||
|  | import { | ||||||
|  |   ArtifactGraph, | ||||||
|  |   ArtifactId, | ||||||
|  |   getPlaneOrFaceFromSelection, | ||||||
|  | } from 'lang/std/artifactGraph' | ||||||
|  |  | ||||||
| type DraftSegment = 'line' | 'tangentialArcTo' | type DraftSegment = 'line' | 'tangentialArcTo' | ||||||
|  |  | ||||||
| @ -582,15 +591,20 @@ export class SceneEntities { | |||||||
|     const _node1 = getNodeFromPath<VariableDeclaration>( |     const _node1 = getNodeFromPath<VariableDeclaration>( | ||||||
|       _ast, |       _ast, | ||||||
|       sketchPathToNode || [], |       sketchPathToNode || [], | ||||||
|       'VariableDeclaration' |       ['VariableDeclaration', 'ExpressionStatement'] | ||||||
|     ) |     ) as { node: { type: string } } | Error | ||||||
|     if (trap(_node1)) return Promise.reject(_node1) |     if (trap(_node1)) return Promise.reject(_node1) | ||||||
|     const variableDeclarationName = |     const variableDeclarationName = (_node1.node.type === 'VariableDeclaration') ? | ||||||
|       _node1.node?.declarations?.[0]?.id?.name || '' |       (_node1.node as VariableDeclaration).declarations[0]?.id?.name || '' : | ||||||
|  |       '' | ||||||
|  |  | ||||||
|     const sg = kclManager.programMemory.get( |     const sgMemItem = kclManager.programMemory.get( | ||||||
|       variableDeclarationName |       variableDeclarationName | ||||||
|     ) as SketchGroup |     ) | ||||||
|  |     if (sgMemItem?.type !== 'SketchGroup') { | ||||||
|  |       return Promise.reject(new Error('SketchGroup not found in programMemory')) | ||||||
|  |     } | ||||||
|  |     const sg: SketchGroup = sgMemItem | ||||||
|     const lastSeg = sg.value.slice(-1)[0] || sg.start |     const lastSeg = sg.value.slice(-1)[0] || sg.start | ||||||
|  |  | ||||||
|     const index = sg.value.length // because we've added a new segment that's not in the memory yet, no need for `-1` |     const index = sg.value.length // because we've added a new segment that's not in the memory yet, no need for `-1` | ||||||
| @ -1762,6 +1776,33 @@ export function getParentGroup( | |||||||
|   return null |   return null | ||||||
| } | } | ||||||
|  |  | ||||||
|  | export async function planeOrFaceFromSelection({ | ||||||
|  |   artifactGraph, | ||||||
|  |   selection, | ||||||
|  | }: { | ||||||
|  |   artifactGraph: ArtifactGraph | ||||||
|  |   selection: Selection | ||||||
|  | }): Promise<{ | ||||||
|  |   id: ArtifactId | ||||||
|  |   faceDetails: Models['GetSketchModePlane_type'] | ||||||
|  | } | null> { | ||||||
|  |   // If the selection doesn't have an artifactId associated with it, we can't | ||||||
|  |   // do it. | ||||||
|  |   if (!selection.artifactId) return null | ||||||
|  |  | ||||||
|  |   const planeOrFace = getPlaneOrFaceFromSelection( | ||||||
|  |     selection.artifactId, | ||||||
|  |     artifactGraph | ||||||
|  |   ) | ||||||
|  |   if (!planeOrFace) return null | ||||||
|  |   if (planeOrFace?.type === 'plane') { | ||||||
|  |     const faceDetails = await getFaceDetails(planeOrFace.id) | ||||||
|  |     return { id: planeOrFace.id, faceDetails } | ||||||
|  |   } | ||||||
|  |   // TODO: Handle wall or cap artifact. | ||||||
|  |   return null | ||||||
|  | } | ||||||
|  |  | ||||||
| export function sketchGroupFromPathToNode({ | export function sketchGroupFromPathToNode({ | ||||||
|   pathToNode, |   pathToNode, | ||||||
|   ast, |   ast, | ||||||
| @ -1827,11 +1868,51 @@ export function getSketchQuaternion( | |||||||
|   return getQuaternionFromZAxis(massageFormats(zAxis)) |   return getQuaternionFromZAxis(massageFormats(zAxis)) | ||||||
| } | } | ||||||
| export async function getSketchOrientationDetails( | export async function getSketchOrientationDetails( | ||||||
|  |   artifactGraph: ArtifactGraph, | ||||||
|  |   selection: Selection, | ||||||
|   sketchPathToNode: PathToNode |   sketchPathToNode: PathToNode | ||||||
| ): Promise<{ | ): Promise<{ | ||||||
|   quat: Quaternion |   sketchDetails: { | ||||||
|   sketchDetails: SketchDetails & { faceId?: string } |     zAxis: [number, number, number] | ||||||
|  |     yAxis: [number, number, number] | ||||||
|  |     origin: [number, number, number] | ||||||
|  |     faceId: string | ||||||
|  |   } | ||||||
| }> { | }> { | ||||||
|  |   const plane = await planeOrFaceFromSelection({ | ||||||
|  |     artifactGraph, | ||||||
|  |     selection, | ||||||
|  |   }) | ||||||
|  |   if (plane) { | ||||||
|  |     const details = plane.faceDetails | ||||||
|  |     console.warn('Found plane', plane) | ||||||
|  |     const zAxis: [number, number, number] = [ | ||||||
|  |       details.z_axis.x, | ||||||
|  |       details.z_axis.y, | ||||||
|  |       details.z_axis.z, | ||||||
|  |     ] | ||||||
|  |     const yAxis: [number, number, number] = [ | ||||||
|  |       details.y_axis.x, | ||||||
|  |       details.y_axis.y, | ||||||
|  |       details.y_axis.z, | ||||||
|  |     ] | ||||||
|  |     const origin: [number, number, number] = [ | ||||||
|  |       details.origin.x, | ||||||
|  |       details.origin.y, | ||||||
|  |       details.origin.z, | ||||||
|  |     ] | ||||||
|  |     return { | ||||||
|  |       sketchDetails: { | ||||||
|  |         zAxis, | ||||||
|  |         yAxis, | ||||||
|  |         origin, | ||||||
|  |         faceId: plane.id, | ||||||
|  |       }, | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   // We couldn't find the plane or face, so try to look at the AST, and find it | ||||||
|  |   // through there. | ||||||
|   const sketchGroup = sketchGroupFromPathToNode({ |   const sketchGroup = sketchGroupFromPathToNode({ | ||||||
|     pathToNode: sketchPathToNode, |     pathToNode: sketchPathToNode, | ||||||
|     ast: kclManager.ast, |     ast: kclManager.ast, | ||||||
| @ -1843,9 +1924,7 @@ export async function getSketchOrientationDetails( | |||||||
|   if (sketchGroup.on.type === 'plane') { |   if (sketchGroup.on.type === 'plane') { | ||||||
|     const zAxis = sketchGroup?.on.zAxis |     const zAxis = sketchGroup?.on.zAxis | ||||||
|     return { |     return { | ||||||
|       quat: getQuaternionFromZAxis(massageFormats(zAxis)), |  | ||||||
|       sketchDetails: { |       sketchDetails: { | ||||||
|         sketchPathToNode, |  | ||||||
|         zAxis: [zAxis.x, zAxis.y, zAxis.z], |         zAxis: [zAxis.x, zAxis.y, zAxis.z], | ||||||
|         yAxis: [ |         yAxis: [ | ||||||
|           sketchGroup.on.yAxis.x, |           sketchGroup.on.yAxis.x, | ||||||
| @ -1864,14 +1943,8 @@ export async function getSketchOrientationDetails( | |||||||
|     if (!faceInfo?.origin || !faceInfo?.z_axis || !faceInfo?.y_axis) |     if (!faceInfo?.origin || !faceInfo?.z_axis || !faceInfo?.y_axis) | ||||||
|       return Promise.reject('face info') |       return Promise.reject('face info') | ||||||
|     const { z_axis, y_axis, origin } = 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 { |     return { | ||||||
|       quat: quaternion, |  | ||||||
|       sketchDetails: { |       sketchDetails: { | ||||||
|         sketchPathToNode, |  | ||||||
|         zAxis: [z_axis.x, z_axis.y, z_axis.z], |         zAxis: [z_axis.x, z_axis.y, z_axis.z], | ||||||
|         yAxis: [y_axis.x, y_axis.y, y_axis.z], |         yAxis: [y_axis.x, y_axis.y, y_axis.z], | ||||||
|         origin: [origin.x, origin.y, origin.z], |         origin: [origin.x, origin.y, origin.z], | ||||||
|  | |||||||
| @ -589,12 +589,17 @@ export const ModelingMachineProvider = ({ | |||||||
|           } |           } | ||||||
|         }, |         }, | ||||||
|         'animate-to-sketch': async ({ selectionRanges }) => { |         'animate-to-sketch': async ({ selectionRanges }) => { | ||||||
|           const sourceRange = selectionRanges.codeBasedSelections[0].range |           const selection = selectionRanges.codeBasedSelections[0] | ||||||
|  |           const sourceRange = selection.range | ||||||
|           const sketchPathToNode = getNodePathFromSourceRange( |           const sketchPathToNode = getNodePathFromSourceRange( | ||||||
|             kclManager.ast, |             kclManager.ast, | ||||||
|             sourceRange |             sourceRange | ||||||
|           ) |           ) | ||||||
|           const info = await getSketchOrientationDetails(sketchPathToNode || []) |           const info = await getSketchOrientationDetails( | ||||||
|  |             engineCommandManager.artifactGraph, | ||||||
|  |             selection, | ||||||
|  |             sketchPathToNode || [] | ||||||
|  |           ) | ||||||
|           await letEngineAnimateAndSyncCamAfter( |           await letEngineAnimateAndSyncCamAfter( | ||||||
|             engineCommandManager, |             engineCommandManager, | ||||||
|             info?.sketchDetails?.faceId || '' |             info?.sketchDetails?.faceId || '' | ||||||
|  | |||||||
| @ -18,6 +18,7 @@ import { | |||||||
|   ProgramMemory, |   ProgramMemory, | ||||||
|   SourceRange, |   SourceRange, | ||||||
|   SketchGroup, |   SketchGroup, | ||||||
|  |   ExpressionStatement, | ||||||
| } from './wasm' | } from './wasm' | ||||||
| import { | import { | ||||||
|   isNodeSafeToReplacePath, |   isNodeSafeToReplacePath, | ||||||
| @ -82,15 +83,22 @@ export function addStartProfileAt( | |||||||
|   const _node1 = getNodeFromPath<VariableDeclaration>( |   const _node1 = getNodeFromPath<VariableDeclaration>( | ||||||
|     node, |     node, | ||||||
|     pathToNode, |     pathToNode, | ||||||
|     'VariableDeclaration' |     ['VariableDeclaration', 'ExpressionStatement'] | ||||||
|   ) |   ) as { node: { type: string } } | Error | ||||||
|   if (err(_node1)) return _node1 |   if (err(_node1)) return _node1 | ||||||
|   const variableDeclaration = _node1.node |  | ||||||
|   if (variableDeclaration.type !== 'VariableDeclaration') { |  | ||||||
|     return new Error('variableDeclaration.init.type !== PipeExpression') |  | ||||||
|   } |  | ||||||
|   const _node = { ...node } |   const _node = { ...node } | ||||||
|   const init = variableDeclaration.declarations[0].init |   let expr: Value | ||||||
|  |   let variableDeclaration: VariableDeclaration | undefined | ||||||
|  |   if (_node1.node.type === 'VariableDeclaration') { | ||||||
|  |     const node: VariableDeclaration = _node1.node as VariableDeclaration | ||||||
|  |     variableDeclaration = node | ||||||
|  |     expr = node.declarations[0].init | ||||||
|  |   } else if (_node1.node.type === 'ExpressionStatement') { | ||||||
|  |     const node: ExpressionStatement = _node1.node as ExpressionStatement | ||||||
|  |     expr = node.expression | ||||||
|  |   } else { | ||||||
|  |     return new Error(`Unrecognized node type ${_node1.node.type}`) | ||||||
|  |   } | ||||||
|   const startProfileAt = createCallExpressionStdLib('startProfileAt', [ |   const startProfileAt = createCallExpressionStdLib('startProfileAt', [ | ||||||
|     createArrayExpression([ |     createArrayExpression([ | ||||||
|       createLiteral(roundOff(at[0])), |       createLiteral(roundOff(at[0])), | ||||||
| @ -98,11 +106,11 @@ export function addStartProfileAt( | |||||||
|     ]), |     ]), | ||||||
|     createPipeSubstitution(), |     createPipeSubstitution(), | ||||||
|   ]) |   ]) | ||||||
|   if (init.type === 'PipeExpression') { |   if (expr.type === 'PipeExpression') { | ||||||
|     init.body.splice(1, 0, startProfileAt) |     expr.body.splice(1, 0, startProfileAt) | ||||||
|   } else { |   } else if (variableDeclaration) { | ||||||
|     variableDeclaration.declarations[0].init = createPipeExpression([ |     variableDeclaration.declarations[0].init = createPipeExpression([ | ||||||
|       init, |       expr, | ||||||
|       startProfileAt, |       startProfileAt, | ||||||
|     ]) |     ]) | ||||||
|   } |   } | ||||||
|  | |||||||
| @ -791,7 +791,7 @@ export function isSingleCursorInPipe( | |||||||
|   const pathToNode = getNodePathFromSourceRange(ast, selection.range) |   const pathToNode = getNodePathFromSourceRange(ast, selection.range) | ||||||
|   const nodeTypes = pathToNode.map(([, type]) => type) |   const nodeTypes = pathToNode.map(([, type]) => type) | ||||||
|   if (nodeTypes.includes('FunctionExpression')) return false |   if (nodeTypes.includes('FunctionExpression')) return false | ||||||
|   if (!nodeTypes.includes('VariableDeclaration')) return false |   // if (!nodeTypes.includes('VariableDeclaration')) return false | ||||||
|   if (nodeTypes.includes('PipeExpression')) return true |   if (nodeTypes.includes('PipeExpression')) return true | ||||||
|   return false |   return false | ||||||
| } | } | ||||||
|  | |||||||
| @ -3,6 +3,8 @@ import { Models } from '@kittycad/lib' | |||||||
| import { getNodePathFromSourceRange } from 'lang/queryAst' | import { getNodePathFromSourceRange } from 'lang/queryAst' | ||||||
| import { err } from 'lib/trap' | import { err } from 'lib/trap' | ||||||
|  |  | ||||||
|  | export type ArtifactId = string | ||||||
|  |  | ||||||
| interface CommonCommandProperties { | interface CommonCommandProperties { | ||||||
|   range: SourceRange |   range: SourceRange | ||||||
|   pathToNode: PathToNode |   pathToNode: PathToNode | ||||||
| @ -10,17 +12,20 @@ interface CommonCommandProperties { | |||||||
|  |  | ||||||
| export interface PlaneArtifact { | export interface PlaneArtifact { | ||||||
|   type: 'plane' |   type: 'plane' | ||||||
|  |   id: ArtifactId | ||||||
|   pathIds: Array<string> |   pathIds: Array<string> | ||||||
|   codeRef: CommonCommandProperties |   codeRef: CommonCommandProperties | ||||||
| } | } | ||||||
| export interface PlaneArtifactRich { | export interface PlaneArtifactRich { | ||||||
|   type: 'plane' |   type: 'plane' | ||||||
|  |   id: ArtifactId | ||||||
|   paths: Array<PathArtifact> |   paths: Array<PathArtifact> | ||||||
|   codeRef: CommonCommandProperties |   codeRef: CommonCommandProperties | ||||||
| } | } | ||||||
|  |  | ||||||
| export interface PathArtifact { | export interface PathArtifact { | ||||||
|   type: 'path' |   type: 'path' | ||||||
|  |   id: ArtifactId | ||||||
|   planeId: string |   planeId: string | ||||||
|   segIds: Array<string> |   segIds: Array<string> | ||||||
|   extrusionId: string |   extrusionId: string | ||||||
| @ -30,10 +35,12 @@ export interface PathArtifact { | |||||||
|  |  | ||||||
| interface solid2D { | interface solid2D { | ||||||
|   type: 'solid2D' |   type: 'solid2D' | ||||||
|  |   id: ArtifactId | ||||||
|   pathId: string |   pathId: string | ||||||
| } | } | ||||||
| export interface PathArtifactRich { | export interface PathArtifactRich { | ||||||
|   type: 'path' |   type: 'path' | ||||||
|  |   id: ArtifactId | ||||||
|   plane: PlaneArtifact | WallArtifact |   plane: PlaneArtifact | WallArtifact | ||||||
|   segments: Array<SegmentArtifact> |   segments: Array<SegmentArtifact> | ||||||
|   extrusion: ExtrusionArtifact |   extrusion: ExtrusionArtifact | ||||||
| @ -42,6 +49,7 @@ export interface PathArtifactRich { | |||||||
|  |  | ||||||
| interface SegmentArtifact { | interface SegmentArtifact { | ||||||
|   type: 'segment' |   type: 'segment' | ||||||
|  |   id: ArtifactId | ||||||
|   pathId: string |   pathId: string | ||||||
|   surfaceId: string |   surfaceId: string | ||||||
|   edgeIds: Array<string> |   edgeIds: Array<string> | ||||||
| @ -50,6 +58,7 @@ interface SegmentArtifact { | |||||||
| } | } | ||||||
| interface SegmentArtifactRich { | interface SegmentArtifactRich { | ||||||
|   type: 'segment' |   type: 'segment' | ||||||
|  |   id: ArtifactId | ||||||
|   path: PathArtifact |   path: PathArtifact | ||||||
|   surf: WallArtifact |   surf: WallArtifact | ||||||
|   edges: Array<ExtrudeEdge> |   edges: Array<ExtrudeEdge> | ||||||
| @ -59,6 +68,7 @@ interface SegmentArtifactRich { | |||||||
|  |  | ||||||
| interface ExtrusionArtifact { | interface ExtrusionArtifact { | ||||||
|   type: 'extrusion' |   type: 'extrusion' | ||||||
|  |   id: ArtifactId | ||||||
|   pathId: string |   pathId: string | ||||||
|   surfaceIds: Array<string> |   surfaceIds: Array<string> | ||||||
|   edgeIds: Array<string> |   edgeIds: Array<string> | ||||||
| @ -66,6 +76,7 @@ interface ExtrusionArtifact { | |||||||
| } | } | ||||||
| interface ExtrusionArtifactRich { | interface ExtrusionArtifactRich { | ||||||
|   type: 'extrusion' |   type: 'extrusion' | ||||||
|  |   id: ArtifactId | ||||||
|   path: PathArtifact |   path: PathArtifact | ||||||
|   surfaces: Array<WallArtifact | CapArtifact> |   surfaces: Array<WallArtifact | CapArtifact> | ||||||
|   edges: Array<ExtrudeEdge> |   edges: Array<ExtrudeEdge> | ||||||
| @ -74,6 +85,7 @@ interface ExtrusionArtifactRich { | |||||||
|  |  | ||||||
| interface WallArtifact { | interface WallArtifact { | ||||||
|   type: 'wall' |   type: 'wall' | ||||||
|  |   id: ArtifactId | ||||||
|   segId: string |   segId: string | ||||||
|   edgeCutEdgeIds: Array<string> |   edgeCutEdgeIds: Array<string> | ||||||
|   extrusionId: string |   extrusionId: string | ||||||
| @ -81,6 +93,7 @@ interface WallArtifact { | |||||||
| } | } | ||||||
| interface CapArtifact { | interface CapArtifact { | ||||||
|   type: 'cap' |   type: 'cap' | ||||||
|  |   id: ArtifactId | ||||||
|   subType: 'start' | 'end' |   subType: 'start' | 'end' | ||||||
|   edgeCutEdgeIds: Array<string> |   edgeCutEdgeIds: Array<string> | ||||||
|   extrusionId: string |   extrusionId: string | ||||||
| @ -89,6 +102,7 @@ interface CapArtifact { | |||||||
|  |  | ||||||
| interface ExtrudeEdge { | interface ExtrudeEdge { | ||||||
|   type: 'extrudeEdge' |   type: 'extrudeEdge' | ||||||
|  |   id: ArtifactId | ||||||
|   segId: string |   segId: string | ||||||
|   extrusionId: string |   extrusionId: string | ||||||
|   edgeId: string |   edgeId: string | ||||||
| @ -97,6 +111,7 @@ interface ExtrudeEdge { | |||||||
| /** A edgeCut is a more generic term for both fillet or chamfer */ | /** A edgeCut is a more generic term for both fillet or chamfer */ | ||||||
| interface EdgeCut { | interface EdgeCut { | ||||||
|   type: 'edgeCut' |   type: 'edgeCut' | ||||||
|  |   id: ArtifactId | ||||||
|   subType: 'fillet' | 'chamfer' |   subType: 'fillet' | 'chamfer' | ||||||
|   consumedEdgeId: string |   consumedEdgeId: string | ||||||
|   edgeIds: Array<string> |   edgeIds: Array<string> | ||||||
| @ -106,6 +121,7 @@ interface EdgeCut { | |||||||
|  |  | ||||||
| interface EdgeCutEdge { | interface EdgeCutEdge { | ||||||
|   type: 'edgeCutEdge' |   type: 'edgeCutEdge' | ||||||
|  |   id: ArtifactId | ||||||
|   edgeCutId: string |   edgeCutId: string | ||||||
|   surfaceId: string |   surfaceId: string | ||||||
| } | } | ||||||
| @ -122,7 +138,7 @@ export type Artifact = | |||||||
|   | EdgeCutEdge |   | EdgeCutEdge | ||||||
|   | solid2D |   | solid2D | ||||||
|  |  | ||||||
| export type ArtifactGraph = Map<string, Artifact> | export type ArtifactGraph = Map<ArtifactId, Artifact> | ||||||
|  |  | ||||||
| export type EngineCommand = Models['WebSocketRequest_type'] | export type EngineCommand = Models['WebSocketRequest_type'] | ||||||
|  |  | ||||||
| @ -149,7 +165,7 @@ export function createArtifactGraph({ | |||||||
|   responseMap: ResponseMap |   responseMap: ResponseMap | ||||||
|   ast: Program |   ast: Program | ||||||
| }) { | }) { | ||||||
|   const myMap = new Map<string, Artifact>() |   const myMap = new Map<ArtifactId, Artifact>() | ||||||
|  |  | ||||||
|   /** see docstring for {@link getArtifactsToUpdate} as to why this is needed */ |   /** see docstring for {@link getArtifactsToUpdate} as to why this is needed */ | ||||||
|   let currentPlaneId = '' |   let currentPlaneId = '' | ||||||
| @ -166,7 +182,7 @@ export function createArtifactGraph({ | |||||||
|     const artifactsToUpdate = getArtifactsToUpdate({ |     const artifactsToUpdate = getArtifactsToUpdate({ | ||||||
|       orderedCommand, |       orderedCommand, | ||||||
|       responseMap, |       responseMap, | ||||||
|       getArtifact: (id: string) => myMap.get(id), |       getArtifact: (id: ArtifactId) => myMap.get(id), | ||||||
|       currentPlaneId, |       currentPlaneId, | ||||||
|       ast, |       ast, | ||||||
|     }) |     }) | ||||||
| @ -210,7 +226,7 @@ function mergeArtifacts( | |||||||
|  * It does not mutate the map directly, but returns an array of artifacts to update |  * It does not mutate the map directly, but returns an array of artifacts to update | ||||||
|  * |  * | ||||||
|  * @param currentPlaneId is only needed for `start_path` commands because this command does not have a pathId |  * @param currentPlaneId is only needed for `start_path` commands because this command does not have a pathId | ||||||
|  * instead it relies on the id used with the `enable_sketch_mode` command, so this much be kept track of |  * instead it relies on the id used with the `enable_sketch_mode` command, so this must be kept track of | ||||||
|  * outside of this function. It would be good to update the `start_path` command to include the planeId so we |  * outside of this function. It would be good to update the `start_path` command to include the planeId so we | ||||||
|  * can remove this. |  * can remove this. | ||||||
|  */ |  */ | ||||||
| @ -224,11 +240,11 @@ export function getArtifactsToUpdate({ | |||||||
|   orderedCommand: OrderedCommand |   orderedCommand: OrderedCommand | ||||||
|   responseMap: ResponseMap |   responseMap: ResponseMap | ||||||
|   /** Passing in a getter because we don't wan this function to update the map directly */ |   /** Passing in a getter because we don't wan this function to update the map directly */ | ||||||
|   getArtifact: (id: string) => Artifact | undefined |   getArtifact: (id: ArtifactId) => Artifact | undefined | ||||||
|   currentPlaneId: string |   currentPlaneId: string | ||||||
|   ast: Program |   ast: Program | ||||||
| }): Array<{ | }): Array<{ | ||||||
|   id: string |   id: ArtifactId | ||||||
|   artifact: Artifact |   artifact: Artifact | ||||||
| }> { | }> { | ||||||
|   const pathToNode = getNodePathFromSourceRange(ast, range) |   const pathToNode = getNodePathFromSourceRange(ast, range) | ||||||
| @ -253,6 +269,7 @@ export function getArtifactsToUpdate({ | |||||||
|           id: currentPlaneId, |           id: currentPlaneId, | ||||||
|           artifact: { |           artifact: { | ||||||
|             type: 'wall', |             type: 'wall', | ||||||
|  |             id: currentPlaneId, | ||||||
|             segId: existingPlane.segId, |             segId: existingPlane.segId, | ||||||
|             edgeCutEdgeIds: existingPlane.edgeCutEdgeIds, |             edgeCutEdgeIds: existingPlane.edgeCutEdgeIds, | ||||||
|             extrusionId: existingPlane.extrusionId, |             extrusionId: existingPlane.extrusionId, | ||||||
| @ -262,7 +279,10 @@ export function getArtifactsToUpdate({ | |||||||
|       ] |       ] | ||||||
|     } else { |     } else { | ||||||
|       return [ |       return [ | ||||||
|         { id: currentPlaneId, artifact: { type: 'plane', pathIds, codeRef } }, |         { | ||||||
|  |           id: currentPlaneId, | ||||||
|  |           artifact: { type: 'plane', id: currentPlaneId, pathIds, codeRef }, | ||||||
|  |         }, | ||||||
|       ] |       ] | ||||||
|     } |     } | ||||||
|   } else if (cmd.type === 'start_path') { |   } else if (cmd.type === 'start_path') { | ||||||
| @ -270,6 +290,7 @@ export function getArtifactsToUpdate({ | |||||||
|       id, |       id, | ||||||
|       artifact: { |       artifact: { | ||||||
|         type: 'path', |         type: 'path', | ||||||
|  |         id, | ||||||
|         segIds: [], |         segIds: [], | ||||||
|         planeId: currentPlaneId, |         planeId: currentPlaneId, | ||||||
|         extrusionId: '', |         extrusionId: '', | ||||||
| @ -282,7 +303,7 @@ export function getArtifactsToUpdate({ | |||||||
|     if (plane?.type === 'plane') { |     if (plane?.type === 'plane') { | ||||||
|       returnArr.push({ |       returnArr.push({ | ||||||
|         id: currentPlaneId, |         id: currentPlaneId, | ||||||
|         artifact: { type: 'plane', pathIds: [id], codeRef }, |         artifact: { type: 'plane', id: currentPlaneId, pathIds: [id], codeRef }, | ||||||
|       }) |       }) | ||||||
|     } |     } | ||||||
|     if (plane?.type === 'wall') { |     if (plane?.type === 'wall') { | ||||||
| @ -290,6 +311,7 @@ export function getArtifactsToUpdate({ | |||||||
|         id: currentPlaneId, |         id: currentPlaneId, | ||||||
|         artifact: { |         artifact: { | ||||||
|           type: 'wall', |           type: 'wall', | ||||||
|  |           id: currentPlaneId, | ||||||
|           segId: plane.segId, |           segId: plane.segId, | ||||||
|           edgeCutEdgeIds: plane.edgeCutEdgeIds, |           edgeCutEdgeIds: plane.edgeCutEdgeIds, | ||||||
|           extrusionId: plane.extrusionId, |           extrusionId: plane.extrusionId, | ||||||
| @ -304,6 +326,7 @@ export function getArtifactsToUpdate({ | |||||||
|       id, |       id, | ||||||
|       artifact: { |       artifact: { | ||||||
|         type: 'segment', |         type: 'segment', | ||||||
|  |         id, | ||||||
|         pathId, |         pathId, | ||||||
|         surfaceId: '', |         surfaceId: '', | ||||||
|         edgeIds: [], |         edgeIds: [], | ||||||
| @ -313,21 +336,22 @@ export function getArtifactsToUpdate({ | |||||||
|     const path = getArtifact(pathId) |     const path = getArtifact(pathId) | ||||||
|     if (path?.type === 'path') |     if (path?.type === 'path') | ||||||
|       returnArr.push({ |       returnArr.push({ | ||||||
|         id: pathId, |         id: path.id, | ||||||
|         artifact: { ...path, segIds: [id] }, |         artifact: { ...path, segIds: [id] }, | ||||||
|       }) |       }) | ||||||
|     if ( |     if ( | ||||||
|       response?.type === 'modeling' && |       response?.type === 'modeling' && | ||||||
|       response.data.modeling_response.type === 'close_path' |       response.data.modeling_response.type === 'close_path' | ||||||
|     ) { |     ) { | ||||||
|  |       const id = response.data.modeling_response.data.face_id | ||||||
|       returnArr.push({ |       returnArr.push({ | ||||||
|         id: response.data.modeling_response.data.face_id, |         id, | ||||||
|         artifact: { type: 'solid2D', pathId }, |         artifact: { type: 'solid2D', id, pathId }, | ||||||
|       }) |       }) | ||||||
|       const path = getArtifact(pathId) |       const path = getArtifact(pathId) | ||||||
|       if (path?.type === 'path') |       if (path?.type === 'path') | ||||||
|         returnArr.push({ |         returnArr.push({ | ||||||
|           id: pathId, |           id: path.id, | ||||||
|           artifact: { |           artifact: { | ||||||
|             ...path, |             ...path, | ||||||
|             solid2dId: response.data.modeling_response.data.face_id, |             solid2dId: response.data.modeling_response.data.face_id, | ||||||
| @ -340,6 +364,7 @@ export function getArtifactsToUpdate({ | |||||||
|       id, |       id, | ||||||
|       artifact: { |       artifact: { | ||||||
|         type: 'extrusion', |         type: 'extrusion', | ||||||
|  |         id, | ||||||
|         pathId: cmd.target, |         pathId: cmd.target, | ||||||
|         surfaceIds: [], |         surfaceIds: [], | ||||||
|         edgeIds: [], |         edgeIds: [], | ||||||
| @ -349,7 +374,7 @@ export function getArtifactsToUpdate({ | |||||||
|     const path = getArtifact(cmd.target) |     const path = getArtifact(cmd.target) | ||||||
|     if (path?.type === 'path') |     if (path?.type === 'path') | ||||||
|       returnArr.push({ |       returnArr.push({ | ||||||
|         id: cmd.target, |         id: path.id, | ||||||
|         artifact: { ...path, extrusionId: id }, |         artifact: { ...path, extrusionId: id }, | ||||||
|       }) |       }) | ||||||
|     return returnArr |     return returnArr | ||||||
| @ -371,6 +396,7 @@ export function getArtifactsToUpdate({ | |||||||
|               id: face_id, |               id: face_id, | ||||||
|               artifact: { |               artifact: { | ||||||
|                 type: 'wall', |                 type: 'wall', | ||||||
|  |                 id: face_id, | ||||||
|                 segId: curve_id, |                 segId: curve_id, | ||||||
|                 edgeCutEdgeIds: [], |                 edgeCutEdgeIds: [], | ||||||
|                 extrusionId: path.extrusionId, |                 extrusionId: path.extrusionId, | ||||||
| @ -378,7 +404,7 @@ export function getArtifactsToUpdate({ | |||||||
|               }, |               }, | ||||||
|             }) |             }) | ||||||
|             returnArr.push({ |             returnArr.push({ | ||||||
|               id: curve_id, |               id: seg.id, | ||||||
|               artifact: { ...seg, surfaceId: face_id }, |               artifact: { ...seg, surfaceId: face_id }, | ||||||
|             }) |             }) | ||||||
|             const extrusion = getArtifact(path.extrusionId) |             const extrusion = getArtifact(path.extrusionId) | ||||||
| @ -403,6 +429,7 @@ export function getArtifactsToUpdate({ | |||||||
|             id: face_id, |             id: face_id, | ||||||
|             artifact: { |             artifact: { | ||||||
|               type: 'cap', |               type: 'cap', | ||||||
|  |               id: face_id, | ||||||
|               subType: cap === 'bottom' ? 'start' : 'end', |               subType: cap === 'bottom' ? 'start' : 'end', | ||||||
|               edgeCutEdgeIds: [], |               edgeCutEdgeIds: [], | ||||||
|               extrusionId: path.extrusionId, |               extrusionId: path.extrusionId, | ||||||
| @ -412,7 +439,7 @@ export function getArtifactsToUpdate({ | |||||||
|           const extrusion = getArtifact(path.extrusionId) |           const extrusion = getArtifact(path.extrusionId) | ||||||
|           if (extrusion?.type !== 'extrusion') return |           if (extrusion?.type !== 'extrusion') return | ||||||
|           returnArr.push({ |           returnArr.push({ | ||||||
|             id: path.extrusionId, |             id: extrusion.id, | ||||||
|             artifact: { |             artifact: { | ||||||
|               ...extrusion, |               ...extrusion, | ||||||
|               surfaceIds: [face_id], |               surfaceIds: [face_id], | ||||||
| @ -427,6 +454,7 @@ export function getArtifactsToUpdate({ | |||||||
|       id, |       id, | ||||||
|       artifact: { |       artifact: { | ||||||
|         type: 'edgeCut', |         type: 'edgeCut', | ||||||
|  |         id, | ||||||
|         subType: cmd.cut_type, |         subType: cmd.cut_type, | ||||||
|         consumedEdgeId: cmd.edge_id, |         consumedEdgeId: cmd.edge_id, | ||||||
|         edgeIds: [], |         edgeIds: [], | ||||||
| @ -437,7 +465,7 @@ export function getArtifactsToUpdate({ | |||||||
|     const consumedEdge = getArtifact(cmd.edge_id) |     const consumedEdge = getArtifact(cmd.edge_id) | ||||||
|     if (consumedEdge?.type === 'segment') { |     if (consumedEdge?.type === 'segment') { | ||||||
|       returnArr.push({ |       returnArr.push({ | ||||||
|         id: cmd.edge_id, |         id: consumedEdge.id, | ||||||
|         artifact: { ...consumedEdge, edgeCutId: id }, |         artifact: { ...consumedEdge, edgeCutId: id }, | ||||||
|       }) |       }) | ||||||
|     } |     } | ||||||
| @ -464,7 +492,7 @@ export function filterArtifacts<T extends Artifact['type'][]>( | |||||||
|         (!predicate || |         (!predicate || | ||||||
|           predicate(value as Extract<Artifact, { type: T[number] }>)) |           predicate(value as Extract<Artifact, { type: T[number] }>)) | ||||||
|     ) |     ) | ||||||
|   ) as Map<string, Extract<Artifact, { type: T[number] }>> |   ) as Map<ArtifactId, Extract<Artifact, { type: T[number] }>> | ||||||
| } | } | ||||||
|  |  | ||||||
| export function getArtifactsOfTypes<T extends Artifact['type'][]>( | export function getArtifactsOfTypes<T extends Artifact['type'][]>( | ||||||
| @ -478,7 +506,7 @@ export function getArtifactsOfTypes<T extends Artifact['type'][]>( | |||||||
|     predicate?: (value: Extract<Artifact, { type: T[number] }>) => boolean |     predicate?: (value: Extract<Artifact, { type: T[number] }>) => boolean | ||||||
|   }, |   }, | ||||||
|   map: ArtifactGraph |   map: ArtifactGraph | ||||||
| ): Map<string, Extract<Artifact, { type: T[number] }>> { | ): Map<ArtifactId, Extract<Artifact, { type: T[number] }>> { | ||||||
|   return new Map( |   return new Map( | ||||||
|     [...map].filter( |     [...map].filter( | ||||||
|       ([key, value]) => |       ([key, value]) => | ||||||
| @ -487,7 +515,7 @@ export function getArtifactsOfTypes<T extends Artifact['type'][]>( | |||||||
|         (!predicate || |         (!predicate || | ||||||
|           predicate(value as Extract<Artifact, { type: T[number] }>)) |           predicate(value as Extract<Artifact, { type: T[number] }>)) | ||||||
|     ) |     ) | ||||||
|   ) as Map<string, Extract<Artifact, { type: T[number] }>> |   ) as Map<ArtifactId, Extract<Artifact, { type: T[number] }>> | ||||||
| } | } | ||||||
|  |  | ||||||
| export function getArtifactOfTypes<T extends Artifact['type'][]>( | export function getArtifactOfTypes<T extends Artifact['type'][]>( | ||||||
| @ -495,7 +523,7 @@ export function getArtifactOfTypes<T extends Artifact['type'][]>( | |||||||
|     key, |     key, | ||||||
|     types, |     types, | ||||||
|   }: { |   }: { | ||||||
|     key: string |     key: ArtifactId | ||||||
|     types: T |     types: T | ||||||
|   }, |   }, | ||||||
|   map: ArtifactGraph |   map: ArtifactGraph | ||||||
| @ -517,6 +545,7 @@ export function expandPlane( | |||||||
|   ) |   ) | ||||||
|   return { |   return { | ||||||
|     type: 'plane', |     type: 'plane', | ||||||
|  |     id: plane.id, | ||||||
|     paths: Array.from(paths.values()), |     paths: Array.from(paths.values()), | ||||||
|     codeRef: plane.codeRef, |     codeRef: plane.codeRef, | ||||||
|   } |   } | ||||||
| @ -545,6 +574,7 @@ export function expandPath( | |||||||
|   if (err(plane)) return plane |   if (err(plane)) return plane | ||||||
|   return { |   return { | ||||||
|     type: 'path', |     type: 'path', | ||||||
|  |     id: path.id, | ||||||
|     segments: Array.from(segs.values()), |     segments: Array.from(segs.values()), | ||||||
|     extrusion, |     extrusion, | ||||||
|     plane, |     plane, | ||||||
| @ -571,6 +601,7 @@ export function expandExtrusion( | |||||||
|   if (err(path)) return path |   if (err(path)) return path | ||||||
|   return { |   return { | ||||||
|     type: 'extrusion', |     type: 'extrusion', | ||||||
|  |     id: extrusion.id, | ||||||
|     surfaces: Array.from(surfs.values()), |     surfaces: Array.from(surfs.values()), | ||||||
|     edges: Array.from(edges.values()), |     edges: Array.from(edges.values()), | ||||||
|     path, |     path, | ||||||
| @ -606,6 +637,7 @@ export function expandSegment( | |||||||
|  |  | ||||||
|   return { |   return { | ||||||
|     type: 'segment', |     type: 'segment', | ||||||
|  |     id: segment.id, | ||||||
|     path, |     path, | ||||||
|     surf, |     surf, | ||||||
|     edges: Array.from(edges.values()), |     edges: Array.from(edges.values()), | ||||||
| @ -656,7 +688,7 @@ export function getWallCodeRef( | |||||||
| } | } | ||||||
|  |  | ||||||
| export function getExtrusionFromSuspectedExtrudeSurface( | export function getExtrusionFromSuspectedExtrudeSurface( | ||||||
|   id: string, |   id: ArtifactId, | ||||||
|   artifactGraph: ArtifactGraph |   artifactGraph: ArtifactGraph | ||||||
| ): ExtrusionArtifact | Error { | ): ExtrusionArtifact | Error { | ||||||
|   const artifact = getArtifactOfTypes( |   const artifact = getArtifactOfTypes( | ||||||
| @ -671,7 +703,7 @@ export function getExtrusionFromSuspectedExtrudeSurface( | |||||||
| } | } | ||||||
|  |  | ||||||
| export function getExtrusionFromSuspectedPath( | export function getExtrusionFromSuspectedPath( | ||||||
|   id: string, |   id: ArtifactId, | ||||||
|   artifactGraph: ArtifactGraph |   artifactGraph: ArtifactGraph | ||||||
| ): ExtrusionArtifact | Error { | ): ExtrusionArtifact | Error { | ||||||
|   const path = getArtifactOfTypes({ key: id, types: ['path'] }, artifactGraph) |   const path = getArtifactOfTypes({ key: id, types: ['path'] }, artifactGraph) | ||||||
| @ -681,3 +713,33 @@ export function getExtrusionFromSuspectedPath( | |||||||
|     artifactGraph |     artifactGraph | ||||||
|   ) |   ) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Get the plane or face from a selection. | ||||||
|  |  * | ||||||
|  |  * TODO: Handle sketch on face. | ||||||
|  |  */ | ||||||
|  | export function getPlaneOrFaceFromSelection( | ||||||
|  |   id: ArtifactId, | ||||||
|  |   artifactGraph: ArtifactGraph | ||||||
|  | ): PlaneArtifactRich | null { | ||||||
|  |   const selection = artifactGraph.get(id) | ||||||
|  |   if (!selection) return null | ||||||
|  |   if (selection.type === 'solid2D') { | ||||||
|  |     const path = artifactGraph.get(selection.pathId) | ||||||
|  |     if (path?.type !== 'path') return null | ||||||
|  |     const plane = artifactGraph.get(path.planeId) | ||||||
|  |     if (plane?.type !== 'plane') return null | ||||||
|  |     return expandPlane(plane, artifactGraph) | ||||||
|  |   } else if (selection.type === 'wall' || selection.type === 'cap') { | ||||||
|  |     const extrusion = artifactGraph.get(selection.extrusionId) | ||||||
|  |     if (extrusion?.type !== 'extrusion') return null | ||||||
|  |     const path = artifactGraph.get(extrusion.pathId) | ||||||
|  |     if (path?.type !== 'path') return null | ||||||
|  |     const plane = artifactGraph.get(path.planeId) | ||||||
|  |     // TODO: For sketch on face, this won't be a plane. | ||||||
|  |     if (plane?.type !== 'plane') return null | ||||||
|  |     return expandPlane(plane, artifactGraph) | ||||||
|  |   } | ||||||
|  |   return null | ||||||
|  | } | ||||||
|  | |||||||
| @ -30,6 +30,7 @@ import { AXIS_GROUP, X_AXIS } from 'clientSideScene/sceneInfra' | |||||||
| import { PathToNodeMap } from 'lang/std/sketchcombos' | import { PathToNodeMap } from 'lang/std/sketchcombos' | ||||||
| import { err } from 'lib/trap' | import { err } from 'lib/trap' | ||||||
| import { | import { | ||||||
|  |   ArtifactId, | ||||||
|   getArtifactOfTypes, |   getArtifactOfTypes, | ||||||
|   getArtifactsOfTypes, |   getArtifactsOfTypes, | ||||||
|   getCapCodeRef, |   getCapCodeRef, | ||||||
| @ -56,6 +57,7 @@ export type Selection = { | |||||||
|     | 'line' |     | 'line' | ||||||
|     | 'arc' |     | 'arc' | ||||||
|     | 'all' |     | 'all' | ||||||
|  |   artifactId?: ArtifactId | ||||||
|   range: SourceRange |   range: SourceRange | ||||||
| } | } | ||||||
| export type Selections = { | export type Selections = { | ||||||
| @ -100,7 +102,11 @@ export async function getEventForSelectWithPoint({ | |||||||
|       type: 'Set selection', |       type: 'Set selection', | ||||||
|       data: { |       data: { | ||||||
|         selectionType: 'singleCodeCursor', |         selectionType: 'singleCodeCursor', | ||||||
|         selection: { range: codeRef.range, type: 'solid2D' }, |         selection: { | ||||||
|  |           artifactId: data.entity_id, | ||||||
|  |           range: codeRef.range, | ||||||
|  |           type: 'solid2D', | ||||||
|  |         }, | ||||||
|       }, |       }, | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| @ -112,6 +118,7 @@ export async function getEventForSelectWithPoint({ | |||||||
|       data: { |       data: { | ||||||
|         selectionType: 'singleCodeCursor', |         selectionType: 'singleCodeCursor', | ||||||
|         selection: { |         selection: { | ||||||
|  |           artifactId: data.entity_id, | ||||||
|           range: codeRef.range, |           range: codeRef.range, | ||||||
|           type: _artifact?.subType === 'end' ? 'end-cap' : 'start-cap', |           type: _artifact?.subType === 'end' ? 'end-cap' : 'start-cap', | ||||||
|         }, |         }, | ||||||
| @ -128,7 +135,11 @@ export async function getEventForSelectWithPoint({ | |||||||
|       type: 'Set selection', |       type: 'Set selection', | ||||||
|       data: { |       data: { | ||||||
|         selectionType: 'singleCodeCursor', |         selectionType: 'singleCodeCursor', | ||||||
|         selection: { range: codeRef.range, type: 'extrude-wall' }, |         selection: { | ||||||
|  |           artifactId: data.entity_id, | ||||||
|  |           range: codeRef.range, | ||||||
|  |           type: 'extrude-wall', | ||||||
|  |         }, | ||||||
|       }, |       }, | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| @ -137,7 +148,11 @@ export async function getEventForSelectWithPoint({ | |||||||
|       type: 'Set selection', |       type: 'Set selection', | ||||||
|       data: { |       data: { | ||||||
|         selectionType: 'singleCodeCursor', |         selectionType: 'singleCodeCursor', | ||||||
|         selection: { range: _artifact.codeRef.range, type: 'default' }, |         selection: { | ||||||
|  |           artifactId: data.entity_id, | ||||||
|  |           range: _artifact.codeRef.range, | ||||||
|  |           type: 'default', | ||||||
|  |         }, | ||||||
|       }, |       }, | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| @ -642,9 +657,12 @@ export function updateSelections( | |||||||
|       const nodeMeta = getNodeFromPath<Value>(ast, pathToNode) |       const nodeMeta = getNodeFromPath<Value>(ast, pathToNode) | ||||||
|       if (err(nodeMeta)) return undefined |       if (err(nodeMeta)) return undefined | ||||||
|       const node = nodeMeta.node |       const node = nodeMeta.node | ||||||
|  |       const prevCodeBasedSelection = | ||||||
|  |         prevSelectionRanges.codeBasedSelections[Number(index)] | ||||||
|       return { |       return { | ||||||
|  |         artifactId: prevCodeBasedSelection?.artifactId, | ||||||
|         range: [node.start, node.end], |         range: [node.start, node.end], | ||||||
|         type: prevSelectionRanges.codeBasedSelections[Number(index)]?.type, |         type: prevCodeBasedSelection?.type, | ||||||
|       } |       } | ||||||
|     }) |     }) | ||||||
|     .filter((x?: Selection) => x !== undefined) as Selection[] |     .filter((x?: Selection) => x !== undefined) as Selection[] | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user
	