Compare commits
1 Commits
v0.25.4
...
kurt-add-s
Author | SHA1 | Date | |
---|---|---|---|
3e0c44e689 |
@ -13,6 +13,7 @@ import {
|
|||||||
Quaternion,
|
Quaternion,
|
||||||
Scene,
|
Scene,
|
||||||
Shape,
|
Shape,
|
||||||
|
SphereGeometry,
|
||||||
Vector2,
|
Vector2,
|
||||||
Vector3,
|
Vector3,
|
||||||
} from 'three'
|
} from 'three'
|
||||||
@ -85,6 +86,7 @@ export const TANGENTIAL_ARC_TO_SEGMENT = 'tangential-arc-to-segment'
|
|||||||
export const TANGENTIAL_ARC_TO_SEGMENT_BODY = 'tangential-arc-to-segment-body'
|
export const TANGENTIAL_ARC_TO_SEGMENT_BODY = 'tangential-arc-to-segment-body'
|
||||||
export const TANGENTIAL_ARC_TO__SEGMENT_DASH =
|
export const TANGENTIAL_ARC_TO__SEGMENT_DASH =
|
||||||
'tangential-arc-to-segment-body-dashed'
|
'tangential-arc-to-segment-body-dashed'
|
||||||
|
export const EXTRA_SEGMENT_HANDLE = 'extraSegmentHandle'
|
||||||
|
|
||||||
// This singleton Class is responsible for all of the things the user sees and interacts with.
|
// This singleton Class is responsible for all of the things the user sees and interacts with.
|
||||||
// That mostly mean sketch elements.
|
// That mostly mean sketch elements.
|
||||||
@ -239,12 +241,16 @@ class SceneEntities {
|
|||||||
ast,
|
ast,
|
||||||
// is draft line assumes the last segment is a draft line, and mods it as the user moves the mouse
|
// is draft line assumes the last segment is a draft line, and mods it as the user moves the mouse
|
||||||
draftSegment,
|
draftSegment,
|
||||||
|
skipListeners,
|
||||||
}: {
|
}: {
|
||||||
sketchPathToNode: PathToNode
|
sketchPathToNode: PathToNode
|
||||||
ast?: Program
|
ast?: Program
|
||||||
draftSegment?: DraftSegment
|
draftSegment?: DraftSegment
|
||||||
|
skipListeners?: boolean
|
||||||
}) {
|
}) {
|
||||||
sceneInfra.resetMouseListeners()
|
if (!skipListeners) {
|
||||||
|
sceneInfra.resetMouseListeners()
|
||||||
|
}
|
||||||
this.createIntersectionPlane()
|
this.createIntersectionPlane()
|
||||||
|
|
||||||
const { truncatedAst, programMemoryOverride, variableDeclarationName } =
|
const { truncatedAst, programMemoryOverride, variableDeclarationName } =
|
||||||
@ -326,11 +332,60 @@ class SceneEntities {
|
|||||||
this.currentSketchQuaternion
|
this.currentSketchQuaternion
|
||||||
)
|
)
|
||||||
|
|
||||||
|
let addingNewSegmentStatus: 'nothing' | 'pending' | 'added' = 'nothing'
|
||||||
|
|
||||||
this.scene.add(group)
|
this.scene.add(group)
|
||||||
if (!draftSegment) {
|
if (!draftSegment && !skipListeners) {
|
||||||
sceneInfra.setCallbacks({
|
sceneInfra.setCallbacks({
|
||||||
onDrag: (args) => {
|
onDragEnd: async () => {
|
||||||
|
if (addingNewSegmentStatus !== 'nothing') {
|
||||||
|
await this.tearDownSketch({ removeAxis: false })
|
||||||
|
this.setupSketch({ sketchPathToNode })
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onDrag: async (args) => {
|
||||||
if (args.event.which !== 1) return
|
if (args.event.which !== 1) return
|
||||||
|
const group = getParentGroup(args.object, [EXTRA_SEGMENT_HANDLE])
|
||||||
|
if (group?.name === EXTRA_SEGMENT_HANDLE) {
|
||||||
|
const segGroup = getParentGroup(args.object)
|
||||||
|
const pathToNode: PathToNode = segGroup?.userData?.pathToNode
|
||||||
|
const pathToNodeIndex = pathToNode.findIndex(
|
||||||
|
(x) => x[1] === 'PipeExpression'
|
||||||
|
)
|
||||||
|
const pipeIndex = pathToNode[pathToNodeIndex + 1][0] as number
|
||||||
|
if (addingNewSegmentStatus === 'nothing') {
|
||||||
|
const prevSegment = sketchGroup.value[pipeIndex - 2]
|
||||||
|
const yo = addNewSketchLn({
|
||||||
|
node: kclManager.ast,
|
||||||
|
programMemory: kclManager.programMemory,
|
||||||
|
to: [args.intersection2d.x, args.intersection2d.y],
|
||||||
|
from: [prevSegment.from[0], prevSegment.from[1]],
|
||||||
|
fnName:
|
||||||
|
prevSegment.type === 'TangentialArcTo'
|
||||||
|
? 'tangentialArcTo'
|
||||||
|
: 'line',
|
||||||
|
pathToNode: pathToNode,
|
||||||
|
})
|
||||||
|
addingNewSegmentStatus = 'pending'
|
||||||
|
await kclManager.executeAstMock(yo.modifiedAst, {
|
||||||
|
updates: 'code',
|
||||||
|
})
|
||||||
|
await this.tearDownSketch({ removeAxis: false })
|
||||||
|
this.setupSketch({ sketchPathToNode, skipListeners: true })
|
||||||
|
addingNewSegmentStatus = 'added'
|
||||||
|
} else if (addingNewSegmentStatus === 'added') {
|
||||||
|
const pathToNodeForNewSegment = pathToNode.slice(
|
||||||
|
0,
|
||||||
|
pathToNodeIndex
|
||||||
|
)
|
||||||
|
pathToNodeForNewSegment.push([pipeIndex - 2, 'index'])
|
||||||
|
this.onDragSegment({
|
||||||
|
...args,
|
||||||
|
sketchPathToNode: pathToNodeForNewSegment,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
this.onDragSegment({
|
this.onDragSegment({
|
||||||
...args,
|
...args,
|
||||||
sketchPathToNode,
|
sketchPathToNode,
|
||||||
@ -391,7 +446,7 @@ class SceneEntities {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
} else {
|
} else if (draftSegment && !skipListeners) {
|
||||||
sceneInfra.setCallbacks({
|
sceneInfra.setCallbacks({
|
||||||
onDrag: () => {},
|
onDrag: () => {},
|
||||||
onClick: async (args) => {
|
onClick: async (args) => {
|
||||||
@ -500,6 +555,7 @@ class SceneEntities {
|
|||||||
variableDeclarationName: string
|
variableDeclarationName: string
|
||||||
}
|
}
|
||||||
}) {
|
}) {
|
||||||
|
if (object.name === STRAIGHT_SEGMENT_BODY) return
|
||||||
const group = getParentGroup(object)
|
const group = getParentGroup(object)
|
||||||
if (!group) return
|
if (!group) return
|
||||||
const pathToNode: PathToNode = JSON.parse(
|
const pathToNode: PathToNode = JSON.parse(
|
||||||
@ -606,9 +662,7 @@ class SceneEntities {
|
|||||||
group.userData.from = from
|
group.userData.from = from
|
||||||
group.userData.to = to
|
group.userData.to = to
|
||||||
group.userData.prevSegment = prevSegment
|
group.userData.prevSegment = prevSegment
|
||||||
const arrowGroup = group.children.find(
|
const arrowGroup = group.getObjectByName(ARROWHEAD) as Group
|
||||||
(child) => child.userData.type === ARROWHEAD
|
|
||||||
) as Group
|
|
||||||
|
|
||||||
arrowGroup.position.set(to[0], to[1], 0)
|
arrowGroup.position.set(to[0], to[1], 0)
|
||||||
|
|
||||||
@ -683,9 +737,7 @@ class SceneEntities {
|
|||||||
const shape = new Shape()
|
const shape = new Shape()
|
||||||
shape.moveTo(0, -0.08 * scale)
|
shape.moveTo(0, -0.08 * scale)
|
||||||
shape.lineTo(0, 0.08 * scale) // The width of the line
|
shape.lineTo(0, 0.08 * scale) // The width of the line
|
||||||
const arrowGroup = group.children.find(
|
const arrowGroup = group.getObjectByName(ARROWHEAD) as Group
|
||||||
(child) => child.userData.type === ARROWHEAD
|
|
||||||
) as Group
|
|
||||||
|
|
||||||
arrowGroup.position.set(to[0], to[1], 0)
|
arrowGroup.position.set(to[0], to[1], 0)
|
||||||
|
|
||||||
@ -698,6 +750,32 @@ class SceneEntities {
|
|||||||
arrowGroup.quaternion.setFromUnitVectors(new Vector3(0, 1, 0), dir)
|
arrowGroup.quaternion.setFromUnitVectors(new Vector3(0, 1, 0), dir)
|
||||||
arrowGroup.scale.set(scale, scale, scale)
|
arrowGroup.scale.set(scale, scale, scale)
|
||||||
|
|
||||||
|
// TODO this should be created in setupSketch, not updateStraightSegment
|
||||||
|
// it should only be updated here
|
||||||
|
const extraSegmentHandle = (group.getObjectByName(EXTRA_SEGMENT_HANDLE) ||
|
||||||
|
(() => {
|
||||||
|
const mat = new MeshBasicMaterial({ color: 0xffffff })
|
||||||
|
const sphereMesh = new Mesh(new SphereGeometry(0.6, 12, 12), mat)
|
||||||
|
|
||||||
|
const handleGroup = new Group()
|
||||||
|
handleGroup.userData.type = EXTRA_SEGMENT_HANDLE
|
||||||
|
handleGroup.name = EXTRA_SEGMENT_HANDLE
|
||||||
|
handleGroup.add(sphereMesh)
|
||||||
|
handleGroup.layers.set(SKETCH_LAYER)
|
||||||
|
handleGroup.traverse((child) => {
|
||||||
|
child.layers.set(SKETCH_LAYER)
|
||||||
|
})
|
||||||
|
return handleGroup
|
||||||
|
})()) as Group
|
||||||
|
|
||||||
|
extraSegmentHandle.position.set(
|
||||||
|
from[0] + 0.08 * (to[0] - from[0]),
|
||||||
|
from[1] + 0.08 * (to[1] - from[1]),
|
||||||
|
0
|
||||||
|
)
|
||||||
|
extraSegmentHandle.scale.set(scale, scale, scale)
|
||||||
|
group.add(extraSegmentHandle)
|
||||||
|
|
||||||
const straightSegmentBody = group.children.find(
|
const straightSegmentBody = group.children.find(
|
||||||
(child) => child.userData.type === STRAIGHT_SEGMENT_BODY
|
(child) => child.userData.type === STRAIGHT_SEGMENT_BODY
|
||||||
) as Mesh
|
) as Mesh
|
||||||
|
@ -88,18 +88,25 @@ class SceneInfra {
|
|||||||
fov = 45
|
fov = 45
|
||||||
fovBeforeAnimate = 45
|
fovBeforeAnimate = 45
|
||||||
isFovAnimationInProgress = false
|
isFovAnimationInProgress = false
|
||||||
|
onDragStartCallback: (arg: OnDragCallbackArgs) => void = () => {}
|
||||||
|
onDragEndCallback: (arg: OnDragCallbackArgs) => void = () => {}
|
||||||
onDragCallback: (arg: OnDragCallbackArgs) => void = () => {}
|
onDragCallback: (arg: OnDragCallbackArgs) => void = () => {}
|
||||||
onMoveCallback: (arg: onMoveCallbackArgs) => void = () => {}
|
onMoveCallback: (arg: onMoveCallbackArgs) => void = () => {}
|
||||||
onClickCallback: (arg?: OnClickCallbackArgs) => void = () => {}
|
onClickCallback: (arg?: OnClickCallbackArgs) => void = () => {}
|
||||||
onMouseEnter: (arg: BaseCallbackArgs2) => void = () => {}
|
onMouseEnter: (arg: BaseCallbackArgs2) => void = () => {}
|
||||||
onMouseLeave: (arg: BaseCallbackArgs2) => void = () => {}
|
onMouseLeave: (arg: BaseCallbackArgs2) => void = () => {}
|
||||||
setCallbacks = (callbacks: {
|
setCallbacks = (callbacks: {
|
||||||
|
onDragStart?: (arg: OnDragCallbackArgs) => void
|
||||||
|
onDragEnd?: (arg: OnDragCallbackArgs) => void
|
||||||
onDrag?: (arg: OnDragCallbackArgs) => void
|
onDrag?: (arg: OnDragCallbackArgs) => void
|
||||||
onMove?: (arg: onMoveCallbackArgs) => void
|
onMove?: (arg: onMoveCallbackArgs) => void
|
||||||
onClick?: (arg?: OnClickCallbackArgs) => void
|
onClick?: (arg?: OnClickCallbackArgs) => void
|
||||||
onMouseEnter?: (arg: BaseCallbackArgs2) => void
|
onMouseEnter?: (arg: BaseCallbackArgs2) => void
|
||||||
onMouseLeave?: (arg: BaseCallbackArgs2) => void
|
onMouseLeave?: (arg: BaseCallbackArgs2) => void
|
||||||
}) => {
|
}) => {
|
||||||
|
console.trace('setting callbacks')
|
||||||
|
this.onDragStartCallback = callbacks.onDragStart || this.onDragStartCallback
|
||||||
|
this.onDragEndCallback = callbacks.onDragEnd || this.onDragEndCallback
|
||||||
this.onDragCallback = callbacks.onDrag || this.onDragCallback
|
this.onDragCallback = callbacks.onDrag || this.onDragCallback
|
||||||
this.onMoveCallback = callbacks.onMove || this.onMoveCallback
|
this.onMoveCallback = callbacks.onMove || this.onMoveCallback
|
||||||
this.onClickCallback = callbacks.onClick || this.onClickCallback
|
this.onClickCallback = callbacks.onClick || this.onClickCallback
|
||||||
@ -109,6 +116,8 @@ class SceneInfra {
|
|||||||
}
|
}
|
||||||
resetMouseListeners = () => {
|
resetMouseListeners = () => {
|
||||||
sceneInfra.setCallbacks({
|
sceneInfra.setCallbacks({
|
||||||
|
onDragStart: () => {},
|
||||||
|
onDragEnd: () => {},
|
||||||
onDrag: () => {},
|
onDrag: () => {},
|
||||||
onMove: () => {},
|
onMove: () => {},
|
||||||
onClick: () => {},
|
onClick: () => {},
|
||||||
@ -420,8 +429,13 @@ class SceneInfra {
|
|||||||
|
|
||||||
if (this.selected) {
|
if (this.selected) {
|
||||||
if (this.selected.hasBeenDragged) {
|
if (this.selected.hasBeenDragged) {
|
||||||
// this is where we could fire a onDragEnd event
|
// TODO do the types properly here
|
||||||
// console.log('onDragEnd', this.selected)
|
this.onDragEndCallback({
|
||||||
|
object: this.selected.object,
|
||||||
|
event,
|
||||||
|
intersection2d: planeIntersectPoint?.intersection2d,
|
||||||
|
...planeIntersectPoint,
|
||||||
|
} as any)
|
||||||
} else if (planeIntersectPoint) {
|
} else if (planeIntersectPoint) {
|
||||||
// fire onClick event as there was no drags
|
// fire onClick event as there was no drags
|
||||||
this.onClickCallback({
|
this.onClickCallback({
|
||||||
|
@ -81,6 +81,7 @@ export function straightSegment({
|
|||||||
pathToNode,
|
pathToNode,
|
||||||
isSelected: false,
|
isSelected: false,
|
||||||
}
|
}
|
||||||
|
group.name = STRAIGHT_SEGMENT
|
||||||
|
|
||||||
const arrowGroup = createArrowhead(scale)
|
const arrowGroup = createArrowhead(scale)
|
||||||
arrowGroup.position.set(to[0], to[1], 0)
|
arrowGroup.position.set(to[0], to[1], 0)
|
||||||
@ -169,6 +170,7 @@ export function tangentialArcToSegment({
|
|||||||
pathToNode,
|
pathToNode,
|
||||||
isSelected: false,
|
isSelected: false,
|
||||||
}
|
}
|
||||||
|
group.name = TANGENTIAL_ARC_TO_SEGMENT
|
||||||
|
|
||||||
const arrowGroup = createArrowhead(scale)
|
const arrowGroup = createArrowhead(scale)
|
||||||
arrowGroup.position.set(to[0], to[1], 0)
|
arrowGroup.position.set(to[0], to[1], 0)
|
||||||
|
@ -181,6 +181,10 @@ export const line: SketchLineHelper = {
|
|||||||
pathToNode,
|
pathToNode,
|
||||||
'PipeExpression'
|
'PipeExpression'
|
||||||
)
|
)
|
||||||
|
const { node: callExpression } = getNodeFromPath<
|
||||||
|
PipeExpression | CallExpression
|
||||||
|
>(_node, pathToNode, 'CallExpression')
|
||||||
|
|
||||||
const { node: varDec } = getNodeFromPath<VariableDeclarator>(
|
const { node: varDec } = getNodeFromPath<VariableDeclarator>(
|
||||||
_node,
|
_node,
|
||||||
pathToNode,
|
pathToNode,
|
||||||
@ -190,6 +194,38 @@ export const line: SketchLineHelper = {
|
|||||||
const newXVal = createLiteral(roundOff(to[0] - from[0], 2))
|
const newXVal = createLiteral(roundOff(to[0] - from[0], 2))
|
||||||
const newYVal = createLiteral(roundOff(to[1] - from[1], 2))
|
const newYVal = createLiteral(roundOff(to[1] - from[1], 2))
|
||||||
|
|
||||||
|
const isAddingSegmentBetween =
|
||||||
|
callExpression.type === 'CallExpression' &&
|
||||||
|
callExpression.start >= pipe.start &&
|
||||||
|
callExpression.end <= pipe.end
|
||||||
|
if (
|
||||||
|
isAddingSegmentBetween &&
|
||||||
|
!createCallback &&
|
||||||
|
pipe.type === 'PipeExpression'
|
||||||
|
) {
|
||||||
|
const callExp = createCallExpression('line', [
|
||||||
|
createArrayExpression([newXVal, newYVal]),
|
||||||
|
createPipeSubstitution(),
|
||||||
|
])
|
||||||
|
const pathToNodeIndex = pathToNode.findIndex(
|
||||||
|
(x) => x[1] === 'PipeExpression'
|
||||||
|
)
|
||||||
|
const pipeIndex = pathToNode[pathToNodeIndex + 1][0]
|
||||||
|
if (typeof pipeIndex === 'undefined' || typeof pipeIndex === 'string') {
|
||||||
|
console.warn('pipeIndex is undefined')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
pipe.body = [
|
||||||
|
...pipe.body.slice(0, pipeIndex),
|
||||||
|
callExp,
|
||||||
|
...pipe.body.slice(pipeIndex),
|
||||||
|
]
|
||||||
|
return {
|
||||||
|
modifiedAst: _node,
|
||||||
|
pathToNode,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (replaceExisting && createCallback && pipe.type !== 'CallExpression') {
|
if (replaceExisting && createCallback && pipe.type !== 'CallExpression') {
|
||||||
const { index: callIndex } = splitPathAtPipeExpression(pathToNode)
|
const { index: callIndex } = splitPathAtPipeExpression(pathToNode)
|
||||||
const { callExp, valueUsedInTransform } = createCallback(
|
const { callExp, valueUsedInTransform } = createCallback(
|
||||||
@ -1011,15 +1047,6 @@ export function changeSketchArguments(
|
|||||||
throw new Error(`not a sketch line helper: ${callExpression?.callee?.name}`)
|
throw new Error(`not a sketch line helper: ${callExpression?.callee?.name}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
interface CreateLineFnCallArgs {
|
|
||||||
node: Program
|
|
||||||
programMemory: ProgramMemory
|
|
||||||
to: [number, number]
|
|
||||||
from: [number, number]
|
|
||||||
fnName: ToolTip
|
|
||||||
pathToNode: PathToNode
|
|
||||||
}
|
|
||||||
|
|
||||||
export function compareVec2Epsilon(
|
export function compareVec2Epsilon(
|
||||||
vec1: [number, number],
|
vec1: [number, number],
|
||||||
vec2: [number, number],
|
vec2: [number, number],
|
||||||
@ -1044,6 +1071,15 @@ export function compareVec2Epsilon2(
|
|||||||
return distance < compareEpsilon
|
return distance < compareEpsilon
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface CreateLineFnCallArgs {
|
||||||
|
node: Program
|
||||||
|
programMemory: ProgramMemory
|
||||||
|
to: [number, number]
|
||||||
|
from: [number, number]
|
||||||
|
fnName: ToolTip
|
||||||
|
pathToNode: PathToNode
|
||||||
|
}
|
||||||
|
|
||||||
export function addNewSketchLn({
|
export function addNewSketchLn({
|
||||||
node: _node,
|
node: _node,
|
||||||
programMemory: previousProgramMemory,
|
programMemory: previousProgramMemory,
|
||||||
|
Reference in New Issue
Block a user