@ -56,6 +56,7 @@ import { engineCommandManager } from 'lang/std/engineConnection'
|
|||||||
import {
|
import {
|
||||||
createArcGeometry,
|
createArcGeometry,
|
||||||
dashedStraight,
|
dashedStraight,
|
||||||
|
profileStart,
|
||||||
straightSegment,
|
straightSegment,
|
||||||
tangentialArcToSegment,
|
tangentialArcToSegment,
|
||||||
} from './segments'
|
} from './segments'
|
||||||
@ -64,6 +65,7 @@ import {
|
|||||||
addNewSketchLn,
|
addNewSketchLn,
|
||||||
changeSketchArguments,
|
changeSketchArguments,
|
||||||
compareVec2Epsilon2,
|
compareVec2Epsilon2,
|
||||||
|
updateStartProfileAtArgs,
|
||||||
} from 'lang/std/sketch'
|
} from 'lang/std/sketch'
|
||||||
import { isReducedMotion, throttle } from 'lib/utils'
|
import { isReducedMotion, throttle } from 'lib/utils'
|
||||||
import {
|
import {
|
||||||
@ -85,6 +87,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 PROFILE_START = 'profile-start'
|
||||||
|
|
||||||
// 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.
|
||||||
@ -137,6 +140,9 @@ class SceneEntities {
|
|||||||
scale: factor,
|
scale: factor,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
if (segment.name === PROFILE_START) {
|
||||||
|
segment.scale.set(factor, factor, factor)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
if (this.axisGroup) {
|
if (this.axisGroup) {
|
||||||
const factor =
|
const factor =
|
||||||
@ -293,6 +299,24 @@ class SceneEntities {
|
|||||||
? orthoFactor
|
? orthoFactor
|
||||||
: perspScale(sceneInfra.camControls.camera, dummy)) /
|
: perspScale(sceneInfra.camControls.camera, dummy)) /
|
||||||
sceneInfra._baseUnitMultiplier
|
sceneInfra._baseUnitMultiplier
|
||||||
|
|
||||||
|
let segPathToNode = getNodePathFromSourceRange(
|
||||||
|
draftSegment ? truncatedAst : kclManager.ast,
|
||||||
|
sketchGroup.start.__geoMeta.sourceRange
|
||||||
|
)
|
||||||
|
const _profileStart = profileStart({
|
||||||
|
from: sketchGroup.start.from,
|
||||||
|
id: sketchGroup.start.__geoMeta.id,
|
||||||
|
pathToNode: segPathToNode,
|
||||||
|
scale: factor,
|
||||||
|
})
|
||||||
|
_profileStart.layers.set(SKETCH_LAYER)
|
||||||
|
_profileStart.traverse((child) => {
|
||||||
|
child.layers.set(SKETCH_LAYER)
|
||||||
|
})
|
||||||
|
group.add(_profileStart)
|
||||||
|
this.activeSegments[JSON.stringify(segPathToNode)] = _profileStart
|
||||||
|
|
||||||
sketchGroup.value.forEach((segment, index) => {
|
sketchGroup.value.forEach((segment, index) => {
|
||||||
let segPathToNode = getNodePathFromSourceRange(
|
let segPathToNode = getNodePathFromSourceRange(
|
||||||
draftSegment ? truncatedAst : kclManager.ast,
|
draftSegment ? truncatedAst : kclManager.ast,
|
||||||
@ -374,7 +398,11 @@ class SceneEntities {
|
|||||||
mat.color.set(obj.userData.baseColor)
|
mat.color.set(obj.userData.baseColor)
|
||||||
mat.color.offsetHSL(0, 0, 0.5)
|
mat.color.offsetHSL(0, 0, 0.5)
|
||||||
}
|
}
|
||||||
const parent = getParentGroup(object)
|
const parent = getParentGroup(object, [
|
||||||
|
STRAIGHT_SEGMENT,
|
||||||
|
TANGENTIAL_ARC_TO_SEGMENT,
|
||||||
|
PROFILE_START,
|
||||||
|
])
|
||||||
if (parent?.userData?.pathToNode) {
|
if (parent?.userData?.pathToNode) {
|
||||||
const updatedAst = parse(recast(kclManager.ast))
|
const updatedAst = parse(recast(kclManager.ast))
|
||||||
const node = getNodeFromPath<CallExpression>(
|
const node = getNodeFromPath<CallExpression>(
|
||||||
@ -511,7 +539,11 @@ class SceneEntities {
|
|||||||
variableDeclarationName: string
|
variableDeclarationName: string
|
||||||
}
|
}
|
||||||
}) {
|
}) {
|
||||||
const group = getParentGroup(object)
|
const group = getParentGroup(object, [
|
||||||
|
STRAIGHT_SEGMENT,
|
||||||
|
TANGENTIAL_ARC_TO_SEGMENT,
|
||||||
|
PROFILE_START,
|
||||||
|
])
|
||||||
if (!group) return
|
if (!group) return
|
||||||
const pathToNode: PathToNode = JSON.parse(
|
const pathToNode: PathToNode = JSON.parse(
|
||||||
JSON.stringify(group.userData.pathToNode)
|
JSON.stringify(group.userData.pathToNode)
|
||||||
@ -535,13 +567,28 @@ class SceneEntities {
|
|||||||
).node
|
).node
|
||||||
if (node.type !== 'CallExpression') return
|
if (node.type !== 'CallExpression') return
|
||||||
|
|
||||||
const modded = changeSketchArguments(
|
let modded: {
|
||||||
modifiedAst,
|
modifiedAst: Program
|
||||||
kclManager.programMemory,
|
pathToNode: PathToNode
|
||||||
[node.start, node.end],
|
}
|
||||||
to,
|
if (group.name === PROFILE_START) {
|
||||||
from
|
modded = updateStartProfileAtArgs({
|
||||||
)
|
node: modifiedAst,
|
||||||
|
pathToNode,
|
||||||
|
to,
|
||||||
|
from,
|
||||||
|
previousProgramMemory: kclManager.programMemory,
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
modded = changeSketchArguments(
|
||||||
|
modifiedAst,
|
||||||
|
kclManager.programMemory,
|
||||||
|
[node.start, node.end],
|
||||||
|
to,
|
||||||
|
from
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
modifiedAst = modded.modifiedAst
|
modifiedAst = modded.modifiedAst
|
||||||
const { truncatedAst, programMemoryOverride, variableDeclarationName } =
|
const { truncatedAst, programMemoryOverride, variableDeclarationName } =
|
||||||
draftInfo
|
draftInfo
|
||||||
@ -560,10 +607,16 @@ class SceneEntities {
|
|||||||
programMemoryOverride,
|
programMemoryOverride,
|
||||||
})
|
})
|
||||||
this.sceneProgramMemory = programMemory
|
this.sceneProgramMemory = programMemory
|
||||||
const sketchGroup = programMemory.root[variableDeclarationName]
|
const sketchGroup = programMemory.root[
|
||||||
.value as Path[]
|
variableDeclarationName
|
||||||
|
] as SketchGroup
|
||||||
|
const sgPaths = sketchGroup.value
|
||||||
const orthoFactor = orthoScale(sceneInfra.camControls.camera)
|
const orthoFactor = orthoScale(sceneInfra.camControls.camera)
|
||||||
sketchGroup.forEach((segment, index) => {
|
|
||||||
|
const updateSegment = (
|
||||||
|
segment: Path | SketchGroup['start'],
|
||||||
|
index: number
|
||||||
|
) => {
|
||||||
const segPathToNode = getNodePathFromSourceRange(
|
const segPathToNode = getNodePathFromSourceRange(
|
||||||
modifiedAst,
|
modifiedAst,
|
||||||
segment.__geoMeta.sourceRange
|
segment.__geoMeta.sourceRange
|
||||||
@ -584,7 +637,7 @@ class SceneEntities {
|
|||||||
sceneInfra._baseUnitMultiplier
|
sceneInfra._baseUnitMultiplier
|
||||||
if (type === TANGENTIAL_ARC_TO_SEGMENT) {
|
if (type === TANGENTIAL_ARC_TO_SEGMENT) {
|
||||||
this.updateTangentialArcToSegment({
|
this.updateTangentialArcToSegment({
|
||||||
prevSegment: sketchGroup[index - 1],
|
prevSegment: sgPaths[index - 1],
|
||||||
from: segment.from,
|
from: segment.from,
|
||||||
to: segment.to,
|
to: segment.to,
|
||||||
group: group,
|
group: group,
|
||||||
@ -597,8 +650,13 @@ class SceneEntities {
|
|||||||
group: group,
|
group: group,
|
||||||
scale: factor,
|
scale: factor,
|
||||||
})
|
})
|
||||||
|
} else if (type === PROFILE_START) {
|
||||||
|
group.position.set(segment.from[0], segment.from[1], 0)
|
||||||
|
group.scale.set(factor, factor, factor)
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
updateSegment(sketchGroup.start, 0)
|
||||||
|
sgPaths.forEach(updateSegment)
|
||||||
})()
|
})()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -618,9 +676,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)
|
||||||
|
|
||||||
@ -695,9 +751,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)
|
||||||
|
|
||||||
@ -980,9 +1034,9 @@ export function quaternionFromSketchGroup(
|
|||||||
}
|
}
|
||||||
|
|
||||||
function colorSegment(object: any, color: number) {
|
function colorSegment(object: any, color: number) {
|
||||||
const arrowHead = getParentGroup(object, [ARROWHEAD])
|
const segmentHead = getParentGroup(object, [ARROWHEAD, PROFILE_START])
|
||||||
if (arrowHead) {
|
if (segmentHead) {
|
||||||
arrowHead.traverse((child) => {
|
segmentHead.traverse((child) => {
|
||||||
if (child instanceof Mesh) {
|
if (child instanceof Mesh) {
|
||||||
child.material.color.set(color)
|
child.material.color.set(color)
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { Coords2d } from 'lang/std/sketch'
|
import { Coords2d } from 'lang/std/sketch'
|
||||||
import {
|
import {
|
||||||
|
BoxGeometry,
|
||||||
BufferGeometry,
|
BufferGeometry,
|
||||||
CatmullRomCurve3,
|
CatmullRomCurve3,
|
||||||
ConeGeometry,
|
ConeGeometry,
|
||||||
@ -19,6 +20,7 @@ import {
|
|||||||
import { mergeGeometries } from 'three/examples/jsm/utils/BufferGeometryUtils.js'
|
import { mergeGeometries } from 'three/examples/jsm/utils/BufferGeometryUtils.js'
|
||||||
import { PathToNode, SketchGroup, getTangentialArcToInfo } from 'lang/wasm'
|
import { PathToNode, SketchGroup, getTangentialArcToInfo } from 'lang/wasm'
|
||||||
import {
|
import {
|
||||||
|
PROFILE_START,
|
||||||
STRAIGHT_SEGMENT,
|
STRAIGHT_SEGMENT,
|
||||||
STRAIGHT_SEGMENT_BODY,
|
STRAIGHT_SEGMENT_BODY,
|
||||||
STRAIGHT_SEGMENT_DASH,
|
STRAIGHT_SEGMENT_DASH,
|
||||||
@ -29,6 +31,38 @@ import {
|
|||||||
import { getTangentPointFromPreviousArc } from 'lib/utils2d'
|
import { getTangentPointFromPreviousArc } from 'lib/utils2d'
|
||||||
import { ARROWHEAD } from './sceneInfra'
|
import { ARROWHEAD } from './sceneInfra'
|
||||||
|
|
||||||
|
export function profileStart({
|
||||||
|
from,
|
||||||
|
id,
|
||||||
|
pathToNode,
|
||||||
|
scale = 1,
|
||||||
|
}: {
|
||||||
|
from: Coords2d
|
||||||
|
id: string
|
||||||
|
pathToNode: PathToNode
|
||||||
|
scale?: number
|
||||||
|
}) {
|
||||||
|
const group = new Group()
|
||||||
|
|
||||||
|
const geometry = new BoxGeometry(0.8, 0.8, 0.8)
|
||||||
|
const body = new MeshBasicMaterial({ color: 0xffffff })
|
||||||
|
const mesh = new Mesh(geometry, body)
|
||||||
|
|
||||||
|
group.add(mesh)
|
||||||
|
|
||||||
|
group.userData = {
|
||||||
|
type: PROFILE_START,
|
||||||
|
id,
|
||||||
|
from,
|
||||||
|
pathToNode,
|
||||||
|
isSelected: false,
|
||||||
|
}
|
||||||
|
group.name = PROFILE_START
|
||||||
|
group.position.set(from[0], from[1], 0)
|
||||||
|
group.scale.set(scale, scale, scale)
|
||||||
|
return group
|
||||||
|
}
|
||||||
|
|
||||||
export function straightSegment({
|
export function straightSegment({
|
||||||
from,
|
from,
|
||||||
to,
|
to,
|
||||||
|
@ -91,12 +91,6 @@ export function createFirstArg(
|
|||||||
throw new Error('all sketch line types should have been covered')
|
throw new Error('all sketch line types should have been covered')
|
||||||
}
|
}
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
||||||
type LineData = {
|
|
||||||
from: [number, number, number]
|
|
||||||
to: [number, number, number]
|
|
||||||
}
|
|
||||||
|
|
||||||
export const lineTo: SketchLineHelper = {
|
export const lineTo: SketchLineHelper = {
|
||||||
add: ({
|
add: ({
|
||||||
node,
|
node,
|
||||||
@ -966,6 +960,30 @@ export const angledLineThatIntersects: SketchLineHelper = {
|
|||||||
addTag: addTagWithTo('angleTo'), // TODO might be wrong
|
addTag: addTagWithTo('angleTo'), // TODO might be wrong
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const updateStartProfileAtArgs: SketchLineHelper['updateArgs'] = ({
|
||||||
|
node,
|
||||||
|
pathToNode,
|
||||||
|
to,
|
||||||
|
}) => {
|
||||||
|
const _node = { ...node }
|
||||||
|
const { node: callExpression } = getNodeFromPath<CallExpression>(
|
||||||
|
_node,
|
||||||
|
pathToNode
|
||||||
|
)
|
||||||
|
|
||||||
|
const toArrExp = createArrayExpression([
|
||||||
|
createLiteral(roundOff(to[0])),
|
||||||
|
createLiteral(roundOff(to[1])),
|
||||||
|
])
|
||||||
|
|
||||||
|
mutateArrExp(callExpression.arguments?.[0], toArrExp) ||
|
||||||
|
mutateObjExpProp(callExpression.arguments?.[0], toArrExp, 'to')
|
||||||
|
return {
|
||||||
|
modifiedAst: _node,
|
||||||
|
pathToNode,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export const sketchLineHelperMap: { [key: string]: SketchLineHelper } = {
|
export const sketchLineHelperMap: { [key: string]: SketchLineHelper } = {
|
||||||
line,
|
line,
|
||||||
lineTo,
|
lineTo,
|
||||||
|
Reference in New Issue
Block a user