move idleCallbacks
This commit is contained in:
@ -19,7 +19,10 @@ import {
|
||||
PROFILE_START,
|
||||
getParentGroup,
|
||||
} from './sceneEntities'
|
||||
import { SegmentOverlay, SketchDetails } from 'machines/modelingMachine'
|
||||
import {
|
||||
SegmentOverlay,
|
||||
ModelingMachineContext as ModelingContextType,
|
||||
} from 'machines/modelingMachine'
|
||||
import { findUsesOfTagInPipe, getNodeFromPath } from 'lang/queryAst'
|
||||
import {
|
||||
CallExpression,
|
||||
@ -353,11 +356,12 @@ export const confirmModal = create<ConfirmModalProps, boolean, boolean>(
|
||||
|
||||
export async function deleteSegment({
|
||||
pathToNode,
|
||||
sketchDetails,
|
||||
context,
|
||||
}: {
|
||||
pathToNode: PathToNode
|
||||
sketchDetails: SketchDetails | null
|
||||
context: ModelingContextType
|
||||
}) {
|
||||
const { sketchDetails } = context
|
||||
let modifiedAst: Program | Error = kclManager.ast
|
||||
const dependentRanges = findUsesOfTagInPipe(modifiedAst, pathToNode)
|
||||
|
||||
@ -394,13 +398,7 @@ export async function deleteSegment({
|
||||
}
|
||||
|
||||
if (!sketchDetails) return
|
||||
await sceneEntitiesManager.updateAstAndRejigSketch(
|
||||
pathToNode,
|
||||
modifiedAst,
|
||||
sketchDetails.zAxis,
|
||||
sketchDetails.yAxis,
|
||||
sketchDetails.origin
|
||||
)
|
||||
await sceneEntitiesManager.updateAstAndRejigSketch(modifiedAst, context)
|
||||
|
||||
// Now 'Set sketchDetails' is called with the modified pathToNode
|
||||
}
|
||||
|
313
src/clientSideScene/sceneCallbacks.ts
Normal file
313
src/clientSideScene/sceneCallbacks.ts
Normal file
@ -0,0 +1,313 @@
|
||||
import { getEventForSegmentSelection } from 'lib/selections'
|
||||
import {
|
||||
editorManager,
|
||||
kclManager,
|
||||
sceneEntitiesManager,
|
||||
sceneInfra,
|
||||
} from 'lib/singletons'
|
||||
import {
|
||||
Intersection,
|
||||
Mesh,
|
||||
MeshBasicMaterial,
|
||||
Object3D,
|
||||
Object3DEventMap,
|
||||
OrthographicCamera,
|
||||
Points,
|
||||
Vector2,
|
||||
Vector3,
|
||||
} from 'three'
|
||||
import {
|
||||
EXTRA_SEGMENT_HANDLE,
|
||||
PROFILE_START,
|
||||
STRAIGHT_SEGMENT,
|
||||
TANGENTIAL_ARC_TO_SEGMENT,
|
||||
getParentGroup,
|
||||
sketchGroupFromPathToNode,
|
||||
} from './sceneEntities'
|
||||
import { trap } from 'lib/trap'
|
||||
import { addNewSketchLn } from 'lang/std/sketch'
|
||||
import { CallExpression, PathToNode, parse, recast } from 'lang/wasm'
|
||||
import { ARROWHEAD, X_AXIS, Y_AXIS } from './sceneInfra'
|
||||
import { getNodeFromPath } from 'lang/queryAst'
|
||||
import { getThemeColorForThreeJs } from 'lib/theme'
|
||||
import { orthoScale, perspScale } from './helpers'
|
||||
import { ModelingMachineContext } from 'machines/modelingMachine'
|
||||
|
||||
export interface OnMouseEnterLeaveArgs {
|
||||
selected: Object3D<Object3DEventMap>
|
||||
dragSelected?: Object3D<Object3DEventMap>
|
||||
mouseEvent: MouseEvent
|
||||
}
|
||||
|
||||
export interface OnDragCallbackArgs extends OnMouseEnterLeaveArgs {
|
||||
intersectionPoint: {
|
||||
twoD: Vector2
|
||||
threeD: Vector3
|
||||
}
|
||||
intersects: Intersection<Object3D<Object3DEventMap>>[]
|
||||
}
|
||||
export interface OnClickCallbackArgs {
|
||||
mouseEvent: MouseEvent
|
||||
intersectionPoint?: {
|
||||
twoD: Vector2
|
||||
threeD: Vector3
|
||||
}
|
||||
intersects: Intersection<Object3D<Object3DEventMap>>[]
|
||||
selected?: Object3D<Object3DEventMap>
|
||||
}
|
||||
|
||||
export interface OnMoveCallbackArgs {
|
||||
mouseEvent: MouseEvent
|
||||
intersectionPoint: {
|
||||
twoD: Vector2
|
||||
threeD: Vector3
|
||||
}
|
||||
intersects: Intersection<Object3D<Object3DEventMap>>[]
|
||||
selected?: Object3D<Object3DEventMap>
|
||||
}
|
||||
|
||||
interface Callbacks {
|
||||
onDragStart: (arg: OnDragCallbackArgs) => void
|
||||
onDragEnd: (arg: OnDragCallbackArgs) => void
|
||||
onDrag: (arg: OnDragCallbackArgs) => void
|
||||
onMove: (arg: OnMoveCallbackArgs) => void
|
||||
onClick: (arg: OnClickCallbackArgs) => void
|
||||
onMouseEnter: (arg: OnMouseEnterLeaveArgs) => void
|
||||
onMouseLeave: (arg: OnMouseEnterLeaveArgs) => void
|
||||
}
|
||||
|
||||
type SetCallbacksWithCtx = (context: ModelingMachineContext) => Callbacks
|
||||
|
||||
const onMousEnterLeaveCallbacks = {
|
||||
onMouseEnter: ({ selected, dragSelected }: OnMouseEnterLeaveArgs) => {
|
||||
if ([X_AXIS, Y_AXIS].includes(selected?.userData?.type)) {
|
||||
const obj = selected as Mesh
|
||||
const mat = obj.material as MeshBasicMaterial
|
||||
mat.color.set(obj.userData.baseColor)
|
||||
mat.color.offsetHSL(0, 0, 0.5)
|
||||
}
|
||||
const parent = getParentGroup(selected, [
|
||||
STRAIGHT_SEGMENT,
|
||||
TANGENTIAL_ARC_TO_SEGMENT,
|
||||
PROFILE_START,
|
||||
])
|
||||
if (parent?.userData?.pathToNode) {
|
||||
const updatedAst = parse(recast(kclManager.ast))
|
||||
if (trap(updatedAst)) return
|
||||
const _node = getNodeFromPath<CallExpression>(
|
||||
updatedAst,
|
||||
parent.userData.pathToNode,
|
||||
'CallExpression'
|
||||
)
|
||||
if (trap(_node, { suppress: true })) return
|
||||
const node = _node.node
|
||||
editorManager.setHighlightRange([node.start, node.end])
|
||||
const yellow = 0xffff00
|
||||
colorSegment(selected, yellow)
|
||||
const extraSegmentGroup = parent.getObjectByName(EXTRA_SEGMENT_HANDLE)
|
||||
if (extraSegmentGroup) {
|
||||
extraSegmentGroup.traverse((child) => {
|
||||
if (child instanceof Points || child instanceof Mesh) {
|
||||
child.material.opacity = dragSelected ? 0 : 1
|
||||
}
|
||||
})
|
||||
}
|
||||
const orthoFactor = orthoScale(sceneInfra.camControls.camera)
|
||||
|
||||
const factor =
|
||||
(sceneInfra.camControls.camera instanceof OrthographicCamera
|
||||
? orthoFactor
|
||||
: perspScale(sceneInfra.camControls.camera, parent)) /
|
||||
sceneInfra._baseUnitMultiplier
|
||||
if (parent.name === STRAIGHT_SEGMENT) {
|
||||
sceneEntitiesManager.updateStraightSegment({
|
||||
from: parent.userData.from,
|
||||
to: parent.userData.to,
|
||||
group: parent,
|
||||
scale: factor,
|
||||
})
|
||||
} else if (parent.name === TANGENTIAL_ARC_TO_SEGMENT) {
|
||||
sceneEntitiesManager.updateTangentialArcToSegment({
|
||||
prevSegment: parent.userData.prevSegment,
|
||||
from: parent.userData.from,
|
||||
to: parent.userData.to,
|
||||
group: parent,
|
||||
scale: factor,
|
||||
})
|
||||
}
|
||||
return
|
||||
}
|
||||
editorManager.setHighlightRange([0, 0])
|
||||
},
|
||||
onMouseLeave: ({ selected, ...rest }: OnMouseEnterLeaveArgs) => {
|
||||
editorManager.setHighlightRange([0, 0])
|
||||
const parent = getParentGroup(selected, [
|
||||
STRAIGHT_SEGMENT,
|
||||
TANGENTIAL_ARC_TO_SEGMENT,
|
||||
PROFILE_START,
|
||||
])
|
||||
if (parent) {
|
||||
const orthoFactor = orthoScale(sceneInfra.camControls.camera)
|
||||
|
||||
const factor =
|
||||
(sceneInfra.camControls.camera instanceof OrthographicCamera
|
||||
? orthoFactor
|
||||
: perspScale(sceneInfra.camControls.camera, parent)) /
|
||||
sceneInfra._baseUnitMultiplier
|
||||
if (parent.name === STRAIGHT_SEGMENT) {
|
||||
sceneEntitiesManager.updateStraightSegment({
|
||||
from: parent.userData.from,
|
||||
to: parent.userData.to,
|
||||
group: parent,
|
||||
scale: factor,
|
||||
})
|
||||
} else if (parent.name === TANGENTIAL_ARC_TO_SEGMENT) {
|
||||
sceneEntitiesManager.updateTangentialArcToSegment({
|
||||
prevSegment: parent.userData.prevSegment,
|
||||
from: parent.userData.from,
|
||||
to: parent.userData.to,
|
||||
group: parent,
|
||||
scale: factor,
|
||||
})
|
||||
}
|
||||
}
|
||||
const isSelected = parent?.userData?.isSelected
|
||||
colorSegment(
|
||||
selected,
|
||||
isSelected
|
||||
? 0x0000ff
|
||||
: parent?.userData?.baseColor ||
|
||||
getThemeColorForThreeJs(sceneInfra._theme)
|
||||
)
|
||||
const extraSegmentGroup = parent?.getObjectByName(EXTRA_SEGMENT_HANDLE)
|
||||
if (extraSegmentGroup) {
|
||||
extraSegmentGroup.traverse((child) => {
|
||||
if (child instanceof Points || child instanceof Mesh) {
|
||||
child.material.opacity = 0
|
||||
}
|
||||
})
|
||||
}
|
||||
if ([X_AXIS, Y_AXIS].includes(selected?.userData?.type)) {
|
||||
const obj = selected as Mesh
|
||||
const mat = obj.material as MeshBasicMaterial
|
||||
mat.color.set(obj.userData.baseColor)
|
||||
if (obj.userData.isSelected) mat.color.offsetHSL(0, 0, 0.2)
|
||||
}
|
||||
},
|
||||
} as const
|
||||
|
||||
export const idleCallbacks: SetCallbacksWithCtx = (context) => {
|
||||
let addingNewSegmentStatus: 'nothing' | 'pending' | 'added' = 'nothing'
|
||||
return {
|
||||
onDragStart: () => {},
|
||||
onDragEnd: () => {},
|
||||
onMove: () => {},
|
||||
...onMousEnterLeaveCallbacks,
|
||||
onClick: (args) => {
|
||||
if (args?.mouseEvent.which !== 1) return
|
||||
if (!args || !args.selected) {
|
||||
sceneInfra.modelingSend({
|
||||
type: 'Set selection',
|
||||
data: {
|
||||
selectionType: 'singleCodeCursor',
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
const { selected } = args
|
||||
const event = getEventForSegmentSelection(selected)
|
||||
if (!event) return
|
||||
sceneInfra.modelingSend(event)
|
||||
},
|
||||
onDrag: async ({ selected, intersectionPoint, mouseEvent, intersects }) => {
|
||||
if (mouseEvent.which !== 1) return
|
||||
|
||||
const group = getParentGroup(selected, [EXTRA_SEGMENT_HANDLE])
|
||||
if (group?.name === EXTRA_SEGMENT_HANDLE) {
|
||||
const segGroup = getParentGroup(selected)
|
||||
const pathToNode: PathToNode = segGroup?.userData?.pathToNode
|
||||
const pathToNodeIndex = pathToNode.findIndex(
|
||||
(x) => x[1] === 'PipeExpression'
|
||||
)
|
||||
|
||||
const sketchGroup = sketchGroupFromPathToNode({
|
||||
pathToNode,
|
||||
ast: kclManager.ast,
|
||||
programMemory: kclManager.programMemory,
|
||||
})
|
||||
if (trap(sketchGroup)) return
|
||||
|
||||
const pipeIndex = pathToNode[pathToNodeIndex + 1][0] as number
|
||||
if (addingNewSegmentStatus === 'nothing') {
|
||||
const prevSegment = sketchGroup.value[pipeIndex - 2]
|
||||
const mod = addNewSketchLn({
|
||||
node: kclManager.ast,
|
||||
programMemory: kclManager.programMemory,
|
||||
to: [intersectionPoint.twoD.x, intersectionPoint.twoD.y],
|
||||
from: [prevSegment.from[0], prevSegment.from[1]],
|
||||
// TODO assuming it's always a straight segments being added
|
||||
// as this is easiest, and we'll need to add "tabbing" behavior
|
||||
// to support other segment types
|
||||
fnName: 'line',
|
||||
pathToNode: pathToNode,
|
||||
spliceBetween: true,
|
||||
})
|
||||
addingNewSegmentStatus = 'pending'
|
||||
if (trap(mod)) return
|
||||
|
||||
await kclManager.executeAstMock(mod.modifiedAst)
|
||||
await sceneEntitiesManager.tearDownSketch({ removeAxis: false })
|
||||
sceneEntitiesManager.setupSketch({
|
||||
sketchPathToNode: pathToNode,
|
||||
maybeModdedAst: kclManager.ast,
|
||||
up: context.sketchDetails?.yAxis || [0, 1, 0],
|
||||
forward: context.sketchDetails?.zAxis || [0, 0, 1],
|
||||
position: context.sketchDetails?.origin || [0, 0, 0],
|
||||
})
|
||||
addingNewSegmentStatus = 'added'
|
||||
} else if (addingNewSegmentStatus === 'added') {
|
||||
const pathToNodeForNewSegment = pathToNode.slice(0, pathToNodeIndex)
|
||||
pathToNodeForNewSegment.push([pipeIndex - 2, 'index'])
|
||||
sceneEntitiesManager.onDragSegment({
|
||||
sketchPathToNode: pathToNodeForNewSegment,
|
||||
object: selected,
|
||||
intersection2d: intersectionPoint.twoD,
|
||||
intersects,
|
||||
})
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
sceneEntitiesManager.onDragSegment({
|
||||
object: selected,
|
||||
intersection2d: intersectionPoint.twoD,
|
||||
intersects,
|
||||
sketchPathToNode: context.sketchDetails?.sketchPathToNode || [],
|
||||
})
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
function colorSegment(object: any, color: number) {
|
||||
const segmentHead = getParentGroup(object, [ARROWHEAD, PROFILE_START])
|
||||
if (segmentHead) {
|
||||
segmentHead.traverse((child) => {
|
||||
if (child instanceof Mesh) {
|
||||
child.material.color.set(color)
|
||||
}
|
||||
})
|
||||
return
|
||||
}
|
||||
const straightSegmentBody = getParentGroup(object, [
|
||||
STRAIGHT_SEGMENT,
|
||||
TANGENTIAL_ARC_TO_SEGMENT,
|
||||
])
|
||||
if (straightSegmentBody) {
|
||||
straightSegmentBody.traverse((child) => {
|
||||
if (child instanceof Mesh && !child.userData.ignoreColorChange) {
|
||||
child.material.color.set(color)
|
||||
}
|
||||
})
|
||||
return
|
||||
}
|
||||
}
|
@ -27,7 +27,6 @@ import {
|
||||
defaultPlaneColor,
|
||||
getSceneScale,
|
||||
INTERSECTION_PLANE_LAYER,
|
||||
OnMouseEnterLeaveArgs,
|
||||
RAYCASTABLE_PLANE,
|
||||
SKETCH_GROUP_SEGMENTS,
|
||||
SKETCH_LAYER,
|
||||
@ -82,16 +81,16 @@ import {
|
||||
createPipeSubstitution,
|
||||
findUniqueName,
|
||||
} from 'lang/modifyAst'
|
||||
import {
|
||||
Selections,
|
||||
getEventForSegmentSelection,
|
||||
sendSelectEventToEngine,
|
||||
} from 'lib/selections'
|
||||
import { Selections, sendSelectEventToEngine } from 'lib/selections'
|
||||
import { getTangentPointFromPreviousArc } from 'lib/utils2d'
|
||||
import { createGridHelper, orthoScale, perspScale } from './helpers'
|
||||
import { Models } from '@kittycad/lib'
|
||||
import { uuidv4 } from 'lib/utils'
|
||||
import { SegmentOverlayPayload, SketchDetails } from 'machines/modelingMachine'
|
||||
import {
|
||||
SegmentOverlayPayload,
|
||||
SketchDetails,
|
||||
ModelingMachineContext,
|
||||
} from 'machines/modelingMachine'
|
||||
import {
|
||||
ArtifactMapCommand,
|
||||
EngineCommandManager,
|
||||
@ -102,6 +101,7 @@ import {
|
||||
} from 'lib/rectangleTool'
|
||||
import { getThemeColorForThreeJs } from 'lib/theme'
|
||||
import { err, trap } from 'lib/trap'
|
||||
import { OnMouseEnterLeaveArgs, idleCallbacks } from './sceneCallbacks'
|
||||
|
||||
type DraftSegment = 'line' | 'tangentialArcTo'
|
||||
|
||||
@ -499,31 +499,23 @@ export class SceneEntities {
|
||||
variableDeclarationName,
|
||||
}
|
||||
}
|
||||
updateAstAndRejigSketch = async (
|
||||
sketchPathToNode: PathToNode,
|
||||
updateAstAndRejigSketch: (
|
||||
modifiedAst: Program | Error,
|
||||
forward: [number, number, number],
|
||||
up: [number, number, number],
|
||||
origin: [number, number, number]
|
||||
) => {
|
||||
context: ModelingMachineContext
|
||||
) => Promise<any> = async (modifiedAst, context) => {
|
||||
if (err(modifiedAst)) return modifiedAst
|
||||
|
||||
const nextAst = await kclManager.updateAst(modifiedAst, false)
|
||||
await this.tearDownSketch({ removeAxis: false })
|
||||
sceneInfra.resetMouseListeners()
|
||||
await this.setupSketch({
|
||||
sketchPathToNode,
|
||||
forward,
|
||||
up,
|
||||
position: origin,
|
||||
sketchPathToNode: context.sketchDetails?.sketchPathToNode || [],
|
||||
forward: context.sketchDetails?.zAxis || [0, 0, 1],
|
||||
up: context.sketchDetails?.yAxis || [0, 1, 0],
|
||||
position: context.sketchDetails?.origin || [0, 0, 0],
|
||||
maybeModdedAst: nextAst.newAst,
|
||||
})
|
||||
this.setupSketchIdleCallbacks({
|
||||
forward,
|
||||
up,
|
||||
position: origin,
|
||||
pathToNode: sketchPathToNode,
|
||||
})
|
||||
this.setupSketchIdleCallbacks(context)
|
||||
return nextAst
|
||||
}
|
||||
setUpDraftSegment = async (
|
||||
@ -838,128 +830,8 @@ export class SceneEntities {
|
||||
},
|
||||
})
|
||||
}
|
||||
setupSketchIdleCallbacks = ({
|
||||
pathToNode,
|
||||
up,
|
||||
forward,
|
||||
position,
|
||||
}: {
|
||||
pathToNode: PathToNode
|
||||
forward: [number, number, number]
|
||||
up: [number, number, number]
|
||||
position?: [number, number, number]
|
||||
}) => {
|
||||
let addingNewSegmentStatus: 'nothing' | 'pending' | 'added' = 'nothing'
|
||||
sceneInfra.setCallbacks({
|
||||
onDragEnd: async () => {
|
||||
if (addingNewSegmentStatus !== 'nothing') {
|
||||
await this.tearDownSketch({ removeAxis: false })
|
||||
this.setupSketch({
|
||||
sketchPathToNode: pathToNode,
|
||||
maybeModdedAst: kclManager.ast,
|
||||
up,
|
||||
forward,
|
||||
position,
|
||||
})
|
||||
// setting up the callbacks again resets value in closures
|
||||
this.setupSketchIdleCallbacks({
|
||||
pathToNode,
|
||||
up,
|
||||
forward,
|
||||
position,
|
||||
})
|
||||
}
|
||||
},
|
||||
onDrag: async ({
|
||||
selected,
|
||||
intersectionPoint,
|
||||
mouseEvent,
|
||||
intersects,
|
||||
}) => {
|
||||
if (mouseEvent.which !== 1) return
|
||||
|
||||
const group = getParentGroup(selected, [EXTRA_SEGMENT_HANDLE])
|
||||
if (group?.name === EXTRA_SEGMENT_HANDLE) {
|
||||
const segGroup = getParentGroup(selected)
|
||||
const pathToNode: PathToNode = segGroup?.userData?.pathToNode
|
||||
const pathToNodeIndex = pathToNode.findIndex(
|
||||
(x) => x[1] === 'PipeExpression'
|
||||
)
|
||||
|
||||
const sketchGroup = sketchGroupFromPathToNode({
|
||||
pathToNode,
|
||||
ast: kclManager.ast,
|
||||
programMemory: kclManager.programMemory,
|
||||
})
|
||||
if (trap(sketchGroup)) return
|
||||
|
||||
const pipeIndex = pathToNode[pathToNodeIndex + 1][0] as number
|
||||
if (addingNewSegmentStatus === 'nothing') {
|
||||
const prevSegment = sketchGroup.value[pipeIndex - 2]
|
||||
const mod = addNewSketchLn({
|
||||
node: kclManager.ast,
|
||||
programMemory: kclManager.programMemory,
|
||||
to: [intersectionPoint.twoD.x, intersectionPoint.twoD.y],
|
||||
from: [prevSegment.from[0], prevSegment.from[1]],
|
||||
// TODO assuming it's always a straight segments being added
|
||||
// as this is easiest, and we'll need to add "tabbing" behavior
|
||||
// to support other segment types
|
||||
fnName: 'line',
|
||||
pathToNode: pathToNode,
|
||||
spliceBetween: true,
|
||||
})
|
||||
addingNewSegmentStatus = 'pending'
|
||||
if (trap(mod)) return
|
||||
|
||||
await kclManager.executeAstMock(mod.modifiedAst)
|
||||
await this.tearDownSketch({ removeAxis: false })
|
||||
this.setupSketch({
|
||||
sketchPathToNode: pathToNode,
|
||||
maybeModdedAst: kclManager.ast,
|
||||
up,
|
||||
forward,
|
||||
position,
|
||||
})
|
||||
addingNewSegmentStatus = 'added'
|
||||
} else if (addingNewSegmentStatus === 'added') {
|
||||
const pathToNodeForNewSegment = pathToNode.slice(0, pathToNodeIndex)
|
||||
pathToNodeForNewSegment.push([pipeIndex - 2, 'index'])
|
||||
this.onDragSegment({
|
||||
sketchPathToNode: pathToNodeForNewSegment,
|
||||
object: selected,
|
||||
intersection2d: intersectionPoint.twoD,
|
||||
intersects,
|
||||
})
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
this.onDragSegment({
|
||||
object: selected,
|
||||
intersection2d: intersectionPoint.twoD,
|
||||
intersects,
|
||||
sketchPathToNode: pathToNode,
|
||||
})
|
||||
},
|
||||
onMove: () => {},
|
||||
onClick: (args) => {
|
||||
if (args?.mouseEvent.which !== 1) return
|
||||
if (!args || !args.selected) {
|
||||
sceneInfra.modelingSend({
|
||||
type: 'Set selection',
|
||||
data: {
|
||||
selectionType: 'singleCodeCursor',
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
const { selected } = args
|
||||
const event = getEventForSegmentSelection(selected)
|
||||
if (!event) return
|
||||
sceneInfra.modelingSend(event)
|
||||
},
|
||||
...this.mouseEnterLeaveCallbacks(),
|
||||
})
|
||||
setupSketchIdleCallbacks = (context: ModelingMachineContext) => {
|
||||
sceneInfra.setCallbacks(idleCallbacks(context))
|
||||
}
|
||||
prepareTruncatedMemoryAndAst = (
|
||||
sketchPathToNode: PathToNode,
|
||||
@ -1863,6 +1735,7 @@ export function sketchGroupFromPathToNode({
|
||||
return result as SketchGroup
|
||||
}
|
||||
|
||||
// TODO delete
|
||||
function colorSegment(object: any, color: number) {
|
||||
const segmentHead = getParentGroup(object, [ARROWHEAD, PROFILE_START])
|
||||
if (segmentHead) {
|
||||
|
@ -1,25 +1,25 @@
|
||||
import {
|
||||
AmbientLight,
|
||||
Color,
|
||||
GridHelper,
|
||||
LineBasicMaterial,
|
||||
OrthographicCamera,
|
||||
PerspectiveCamera,
|
||||
Scene,
|
||||
Vector3,
|
||||
WebGLRenderer,
|
||||
Raycaster,
|
||||
Vector2,
|
||||
Group,
|
||||
PlaneGeometry,
|
||||
MeshBasicMaterial,
|
||||
Mesh,
|
||||
DoubleSide,
|
||||
GridHelper,
|
||||
Group,
|
||||
Intersection,
|
||||
LineBasicMaterial,
|
||||
Mesh,
|
||||
MeshBasicMaterial,
|
||||
Object3D,
|
||||
Object3DEventMap,
|
||||
TextureLoader,
|
||||
OrthographicCamera,
|
||||
PerspectiveCamera,
|
||||
PlaneGeometry,
|
||||
Raycaster,
|
||||
Scene,
|
||||
Texture,
|
||||
TextureLoader,
|
||||
Vector2,
|
||||
Vector3,
|
||||
WebGLRenderer,
|
||||
} from 'three'
|
||||
import { Coords2d, compareVec2Epsilon2 } from 'lang/std/sketch'
|
||||
import { useModelingContext } from 'hooks/useModelingContext'
|
||||
@ -31,6 +31,12 @@ import { EngineCommandManager } from 'lang/std/engineConnection'
|
||||
import { MouseState, SegmentOverlayPayload } from 'machines/modelingMachine'
|
||||
import { getAngle, throttle } from 'lib/utils'
|
||||
import { Themes } from 'lib/theme'
|
||||
import {
|
||||
OnClickCallbackArgs,
|
||||
OnDragCallbackArgs,
|
||||
OnMouseEnterLeaveArgs,
|
||||
OnMoveCallbackArgs,
|
||||
} from './sceneCallbacks'
|
||||
|
||||
type SendType = ReturnType<typeof useModelingContext>['send']
|
||||
|
||||
@ -55,39 +61,6 @@ export const AXIS_GROUP = 'axisGroup'
|
||||
export const SKETCH_GROUP_SEGMENTS = 'sketch-group-segments'
|
||||
export const ARROWHEAD = 'arrowhead'
|
||||
|
||||
export interface OnMouseEnterLeaveArgs {
|
||||
selected: Object3D<Object3DEventMap>
|
||||
dragSelected?: Object3D<Object3DEventMap>
|
||||
mouseEvent: MouseEvent
|
||||
}
|
||||
|
||||
interface OnDragCallbackArgs extends OnMouseEnterLeaveArgs {
|
||||
intersectionPoint: {
|
||||
twoD: Vector2
|
||||
threeD: Vector3
|
||||
}
|
||||
intersects: Intersection<Object3D<Object3DEventMap>>[]
|
||||
}
|
||||
interface OnClickCallbackArgs {
|
||||
mouseEvent: MouseEvent
|
||||
intersectionPoint?: {
|
||||
twoD: Vector2
|
||||
threeD: Vector3
|
||||
}
|
||||
intersects: Intersection<Object3D<Object3DEventMap>>[]
|
||||
selected?: Object3D<Object3DEventMap>
|
||||
}
|
||||
|
||||
interface OnMoveCallbackArgs {
|
||||
mouseEvent: MouseEvent
|
||||
intersectionPoint: {
|
||||
twoD: Vector2
|
||||
threeD: Vector3
|
||||
}
|
||||
intersects: Intersection<Object3D<Object3DEventMap>>[]
|
||||
selected?: Object3D<Object3DEventMap>
|
||||
}
|
||||
|
||||
// This singleton class is responsible for all of the under the hood setup for the client side scene.
|
||||
// That is the cameras and switching between them, raycasters for click mouse events and their abstractions (onClick etc), setting up controls.
|
||||
// Anything that added the the scene for the user to interact with is probably in SceneEntities.ts
|
||||
|
@ -549,10 +549,8 @@ export const ModelingMachineProvider = ({
|
||||
) as [number, number, number],
|
||||
}
|
||||
},
|
||||
'Get horizontal info': async ({
|
||||
selectionRanges,
|
||||
sketchDetails,
|
||||
}): Promise<SetSelections> => {
|
||||
'Get horizontal info': async (context): Promise<SetSelections> => {
|
||||
const { selectionRanges, sketchDetails } = context
|
||||
const { modifiedAst, pathToNodeMap } =
|
||||
await applyConstraintHorzVertDistance({
|
||||
constraint: 'setHorzDistance',
|
||||
@ -566,11 +564,8 @@ export const ModelingMachineProvider = ({
|
||||
pathToNodeMap
|
||||
)
|
||||
const updatedAst = await sceneEntitiesManager.updateAstAndRejigSketch(
|
||||
updatedPathToNode,
|
||||
_modifiedAst,
|
||||
sketchDetails.zAxis,
|
||||
sketchDetails.yAxis,
|
||||
sketchDetails.origin
|
||||
context
|
||||
)
|
||||
if (err(updatedAst)) return Promise.reject(updatedAst)
|
||||
const selection = updateSelections(
|
||||
@ -585,10 +580,8 @@ export const ModelingMachineProvider = ({
|
||||
updatedPathToNode,
|
||||
}
|
||||
},
|
||||
'Get vertical info': async ({
|
||||
selectionRanges,
|
||||
sketchDetails,
|
||||
}): Promise<SetSelections> => {
|
||||
'Get vertical info': async (context): Promise<SetSelections> => {
|
||||
const { selectionRanges, sketchDetails } = context
|
||||
const { modifiedAst, pathToNodeMap } =
|
||||
await applyConstraintHorzVertDistance({
|
||||
constraint: 'setVertDistance',
|
||||
@ -602,11 +595,8 @@ export const ModelingMachineProvider = ({
|
||||
pathToNodeMap
|
||||
)
|
||||
const updatedAst = await sceneEntitiesManager.updateAstAndRejigSketch(
|
||||
updatedPathToNode,
|
||||
_modifiedAst,
|
||||
sketchDetails.zAxis,
|
||||
sketchDetails.yAxis,
|
||||
sketchDetails.origin
|
||||
context
|
||||
)
|
||||
if (err(updatedAst)) return Promise.reject(updatedAst)
|
||||
const selection = updateSelections(
|
||||
@ -621,10 +611,8 @@ export const ModelingMachineProvider = ({
|
||||
updatedPathToNode,
|
||||
}
|
||||
},
|
||||
'Get angle info': async ({
|
||||
selectionRanges,
|
||||
sketchDetails,
|
||||
}): Promise<SetSelections> => {
|
||||
'Get angle info': async (context): Promise<SetSelections> => {
|
||||
const { selectionRanges, sketchDetails } = context
|
||||
const info = angleBetweenInfo({
|
||||
selectionRanges,
|
||||
})
|
||||
@ -647,11 +635,8 @@ export const ModelingMachineProvider = ({
|
||||
pathToNodeMap
|
||||
)
|
||||
const updatedAst = await sceneEntitiesManager.updateAstAndRejigSketch(
|
||||
updatedPathToNode,
|
||||
_modifiedAst,
|
||||
sketchDetails.zAxis,
|
||||
sketchDetails.yAxis,
|
||||
sketchDetails.origin
|
||||
context
|
||||
)
|
||||
if (err(updatedAst)) return Promise.reject(updatedAst)
|
||||
const selection = updateSelections(
|
||||
@ -666,10 +651,8 @@ export const ModelingMachineProvider = ({
|
||||
updatedPathToNode,
|
||||
}
|
||||
},
|
||||
'Get length info': async ({
|
||||
selectionRanges,
|
||||
sketchDetails,
|
||||
}): Promise<SetSelections> => {
|
||||
'Get length info': async (context): Promise<SetSelections> => {
|
||||
const { selectionRanges, sketchDetails } = context
|
||||
const { modifiedAst, pathToNodeMap } =
|
||||
await applyConstraintAngleLength({ selectionRanges })
|
||||
const _modifiedAst = parse(recast(modifiedAst))
|
||||
@ -680,11 +663,8 @@ export const ModelingMachineProvider = ({
|
||||
pathToNodeMap
|
||||
)
|
||||
const updatedAst = await sceneEntitiesManager.updateAstAndRejigSketch(
|
||||
updatedPathToNode,
|
||||
_modifiedAst,
|
||||
sketchDetails.zAxis,
|
||||
sketchDetails.yAxis,
|
||||
sketchDetails.origin
|
||||
context
|
||||
)
|
||||
if (err(updatedAst)) return Promise.reject(updatedAst)
|
||||
const selection = updateSelections(
|
||||
@ -699,10 +679,10 @@ export const ModelingMachineProvider = ({
|
||||
updatedPathToNode,
|
||||
}
|
||||
},
|
||||
'Get perpendicular distance info': async ({
|
||||
selectionRanges,
|
||||
sketchDetails,
|
||||
}): Promise<SetSelections> => {
|
||||
'Get perpendicular distance info': async (
|
||||
context
|
||||
): Promise<SetSelections> => {
|
||||
const { selectionRanges, sketchDetails } = context
|
||||
const { modifiedAst, pathToNodeMap } = await applyConstraintIntersect(
|
||||
{
|
||||
selectionRanges,
|
||||
@ -716,11 +696,8 @@ export const ModelingMachineProvider = ({
|
||||
pathToNodeMap
|
||||
)
|
||||
const updatedAst = await sceneEntitiesManager.updateAstAndRejigSketch(
|
||||
updatedPathToNode,
|
||||
_modifiedAst,
|
||||
sketchDetails.zAxis,
|
||||
sketchDetails.yAxis,
|
||||
sketchDetails.origin
|
||||
context
|
||||
)
|
||||
if (err(updatedAst)) return Promise.reject(updatedAst)
|
||||
const selection = updateSelections(
|
||||
@ -735,10 +712,8 @@ export const ModelingMachineProvider = ({
|
||||
updatedPathToNode,
|
||||
}
|
||||
},
|
||||
'Get ABS X info': async ({
|
||||
selectionRanges,
|
||||
sketchDetails,
|
||||
}): Promise<SetSelections> => {
|
||||
'Get ABS X info': async (context): Promise<SetSelections> => {
|
||||
const { selectionRanges, sketchDetails } = context
|
||||
const { modifiedAst, pathToNodeMap } =
|
||||
await applyConstraintAbsDistance({
|
||||
constraint: 'xAbs',
|
||||
@ -752,11 +727,8 @@ export const ModelingMachineProvider = ({
|
||||
pathToNodeMap
|
||||
)
|
||||
const updatedAst = await sceneEntitiesManager.updateAstAndRejigSketch(
|
||||
updatedPathToNode,
|
||||
_modifiedAst,
|
||||
sketchDetails.zAxis,
|
||||
sketchDetails.yAxis,
|
||||
sketchDetails.origin
|
||||
context
|
||||
)
|
||||
if (err(updatedAst)) return Promise.reject(updatedAst)
|
||||
const selection = updateSelections(
|
||||
@ -771,10 +743,8 @@ export const ModelingMachineProvider = ({
|
||||
updatedPathToNode,
|
||||
}
|
||||
},
|
||||
'Get ABS Y info': async ({
|
||||
selectionRanges,
|
||||
sketchDetails,
|
||||
}): Promise<SetSelections> => {
|
||||
'Get ABS Y info': async (context): Promise<SetSelections> => {
|
||||
const { selectionRanges, sketchDetails } = context
|
||||
const { modifiedAst, pathToNodeMap } =
|
||||
await applyConstraintAbsDistance({
|
||||
constraint: 'yAbs',
|
||||
@ -788,11 +758,8 @@ export const ModelingMachineProvider = ({
|
||||
pathToNodeMap
|
||||
)
|
||||
const updatedAst = await sceneEntitiesManager.updateAstAndRejigSketch(
|
||||
updatedPathToNode,
|
||||
_modifiedAst,
|
||||
sketchDetails.zAxis,
|
||||
sketchDetails.yAxis,
|
||||
sketchDetails.origin
|
||||
context
|
||||
)
|
||||
if (err(updatedAst)) return Promise.reject(updatedAst)
|
||||
const selection = updateSelections(
|
||||
@ -808,9 +775,10 @@ export const ModelingMachineProvider = ({
|
||||
}
|
||||
},
|
||||
'Get convert to variable info': async (
|
||||
{ sketchDetails, selectionRanges },
|
||||
context,
|
||||
{ data }
|
||||
): Promise<SetSelections> => {
|
||||
const { selectionRanges, sketchDetails } = context
|
||||
if (!sketchDetails)
|
||||
return Promise.reject(new Error('No sketch details'))
|
||||
const { variableName } = await getVarNameModal({
|
||||
@ -834,11 +802,8 @@ export const ModelingMachineProvider = ({
|
||||
return Promise.reject(new Error('No path to replaced node'))
|
||||
|
||||
const updatedAst = await sceneEntitiesManager.updateAstAndRejigSketch(
|
||||
pathToReplacedNode || [],
|
||||
parsed,
|
||||
sketchDetails.zAxis,
|
||||
sketchDetails.yAxis,
|
||||
sketchDetails.origin
|
||||
context
|
||||
)
|
||||
if (err(updatedAst)) return Promise.reject(updatedAst)
|
||||
const selection = updateSelections(
|
||||
|
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user