Compare commits
6 Commits
kurt-delet
...
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