From 84d17454e9d5892882dd0f9f6b356c2b11f49d2e Mon Sep 17 00:00:00 2001 From: Kurt Hutten Irev-Dev Date: Mon, 3 Feb 2025 17:53:08 +1100 Subject: [PATCH] get overlays working for circle three point --- src/clientSideScene/ClientSideSceneComp.tsx | 36 ++++++------ src/clientSideScene/sceneEntities.ts | 1 - src/clientSideScene/sceneInfra.ts | 31 +++++++---- src/clientSideScene/segments.ts | 62 ++++++++++++++++----- src/components/ModelingMachineProvider.tsx | 6 +- src/lang/langHelpers.ts | 1 + src/lang/std/sketch.ts | 49 ++++++++++++---- src/lang/std/stdTypes.ts | 3 +- src/machines/modelingMachine.ts | 9 +-- 9 files changed, 138 insertions(+), 60 deletions(-) diff --git a/src/clientSideScene/ClientSideSceneComp.tsx b/src/clientSideScene/ClientSideSceneComp.tsx index 2f81c3ceb..10d45f2a5 100644 --- a/src/clientSideScene/ClientSideSceneComp.tsx +++ b/src/clientSideScene/ClientSideSceneComp.tsx @@ -182,12 +182,15 @@ const Overlays = () => { style={{ zIndex: '99999999' }} > {Object.entries(context.segmentOverlays) - .filter((a) => a[1].visible) - .map(([pathToNodeString, overlay], index) => { + .flatMap((a) => + a[1].map((b) => ({ pathToNodeString: a[0], overlay: b })) + ) + .filter((a) => a.overlay.visible) + .map(({ pathToNodeString, overlay }, index) => { return ( @@ -229,7 +232,8 @@ const Overlay = ({ const constraints = getConstraintInfo( callExpression, codeManager.code, - overlay.pathToNode + overlay.pathToNode, + overlay.filterValue ) const offset = 20 // px @@ -249,7 +253,6 @@ const Overlay = ({ state.matches({ Sketch: 'Tangential arc to' }) || state.matches({ Sketch: 'Rectangle tool' }) ) - return (
window.innerHeight / 2 - ? 'top' - : 'bottom' - } - pathToNode={overlay.pathToNode} - stdLibFnName={constraints[0]?.stdLibFnName} - /> - )} + {callExpression?.callee?.name !== 'circle' && + callExpression?.callee?.name !== 'circleThreePoint' && ( + window.innerHeight / 2 + ? 'top' + : 'bottom' + } + pathToNode={overlay.pathToNode} + stdLibFnName={constraints[0]?.stdLibFnName} + /> + )}
)}
diff --git a/src/clientSideScene/sceneEntities.ts b/src/clientSideScene/sceneEntities.ts index 12b22df0b..8f46550d5 100644 --- a/src/clientSideScene/sceneEntities.ts +++ b/src/clientSideScene/sceneEntities.ts @@ -71,7 +71,6 @@ import { SegmentUtils, segmentUtils, } from './segments' -import { CircleThreePoint } from './circleThreePoint' import { addCallExpressionsToPipe, addCloseToPipe, diff --git a/src/clientSideScene/sceneInfra.ts b/src/clientSideScene/sceneInfra.ts index d7fadb26b..ffc21ef4f 100644 --- a/src/clientSideScene/sceneInfra.ts +++ b/src/clientSideScene/sceneInfra.ts @@ -182,13 +182,15 @@ export class SceneInfra { callbacks: (() => SegmentOverlayPayload | null)[] = [] _overlayCallbacks(callbacks: (() => SegmentOverlayPayload | null)[]) { const segmentOverlayPayload: SegmentOverlayPayload = { - type: 'set-many', + type: 'add-many', overlays: {}, } callbacks.forEach((cb) => { const overlay = cb() if (overlay?.type === 'set-one') { segmentOverlayPayload.overlays[overlay.pathToNodeString] = overlay.seg + } else if (overlay?.type === 'add-many') { + Object.assign(segmentOverlayPayload.overlays, overlay.overlays) } }) this.modelingSend({ @@ -213,25 +215,27 @@ export class SceneInfra { overlayThrottleMap: { [pathToNodeString: string]: number } = {} updateOverlayDetails({ - arrowGroup, + handle, group, isHandlesVisible, from, to, angle, + hasThreeDotMenu, }: { - arrowGroup: Group + handle: Group group: Group isHandlesVisible: boolean from: Coords2d to: Coords2d + hasThreeDotMenu: boolean angle?: number }): SegmentOverlayPayload | null { - if (!group.userData.draft && group.userData.pathToNode && arrowGroup) { + if (!group.userData.draft && group.userData.pathToNode && handle) { const vector = new Vector3(0, 0, 0) // Get the position of the object3D in world space - arrowGroup.getWorldPosition(vector) + handle.getWorldPosition(vector) // Project that position to screen space vector.project(this.camControls.camera) @@ -244,13 +248,16 @@ export class SceneInfra { return { type: 'set-one', pathToNodeString, - seg: { - windowCoords: [x, y], - angle: _angle, - group, - pathToNode: group.userData.pathToNode, - visible: isHandlesVisible, - }, + seg: [ + { + windowCoords: [x, y], + angle: _angle, + group, + pathToNode: group.userData.pathToNode, + visible: isHandlesVisible, + hasThreeDotMenu, + }, + ], } } return null diff --git a/src/clientSideScene/segments.ts b/src/clientSideScene/segments.ts index 950e164e7..22c7d77ba 100644 --- a/src/clientSideScene/segments.ts +++ b/src/clientSideScene/segments.ts @@ -64,7 +64,11 @@ import { } from './sceneInfra' import { Themes, getThemeColorForThreeJs } from 'lib/theme' import { normaliseAngle, roundOff } from 'lib/utils' -import { SegmentOverlayPayload } from 'machines/modelingMachine' +import { + SegmentOverlay, + SegmentOverlayPayload, + SegmentOverlays, +} from 'machines/modelingMachine' import { SegmentInputs } from 'lang/std/stdTypes' import { err } from 'lib/trap' import { editorManager, sceneInfra } from 'lib/singletons' @@ -315,11 +319,12 @@ class StraightSegment implements SegmentUtils { } return () => sceneInfra.updateOverlayDetails({ - arrowGroup, + handle: arrowGroup, group, isHandlesVisible, from, to, + hasThreeDotMenu: true, }) } } @@ -491,12 +496,13 @@ class TangentialArcToSegment implements SegmentUtils { ) return () => sceneInfra.updateOverlayDetails({ - arrowGroup, + handle: arrowGroup, group, isHandlesVisible, from, to, angle, + hasThreeDotMenu: true, }) } } @@ -692,12 +698,13 @@ class CircleSegment implements SegmentUtils { } return () => sceneInfra.updateOverlayDetails({ - arrowGroup, + handle: arrowGroup, group, isHandlesVisible, from: from, to: [center[0], center[1]], angle: Math.PI / 4, + hasThreeDotMenu: true, }) } } @@ -826,7 +833,6 @@ class CircleThreePointSegment implements SegmentUtils { ].map((handle) => group.getObjectByName(handle) as Group) handles.forEach((handle, i) => { const point = points[i] - console.log('point', point, handle) if (handle && point) { handle.position.set(point[0], point[1], 0) handle.scale.set(scale, scale, scale) @@ -878,15 +884,45 @@ class CircleThreePointSegment implements SegmentUtils { scale, }) } - return () => - sceneInfra.updateOverlayDetails({ - arrowGroup: {} as any, - group, - isHandlesVisible, - from: [0, 0], - to: [center[0], center[1]], - angle: Math.PI / 4, + return () => { + const overlays: SegmentOverlays = {} + const points = [p1, p2, p3] + const overlayDetails = handles.map((handle, index) => { + const currentPoint = points[index] + const angle = Math.atan2( + currentPoint[1] - center[1], + currentPoint[0] - center[0] + ) + return sceneInfra.updateOverlayDetails({ + handle, + group, + isHandlesVisible, + from: [0, 0], + to: [center[0], center[1]], + angle: angle, + hasThreeDotMenu: index === 0, + }) }) + const segmentOverlays: SegmentOverlay[] = [] + overlayDetails.forEach((payload, index) => { + if (payload?.type === 'set-one') { + overlays[payload.pathToNodeString] = payload.seg + segmentOverlays.push({ + ...payload.seg[0], + filterValue: index === 0 ? 'p1' : index === 1 ? 'p2' : 'p3', + }) + } + }) + const segmentOverlayPayload: SegmentOverlayPayload = { + type: 'set-one', + pathToNodeString: + overlayDetails[0]?.type === 'set-one' + ? overlayDetails[0].pathToNodeString + : '', + seg: segmentOverlays, + } + return segmentOverlayPayload + } } } diff --git a/src/components/ModelingMachineProvider.tsx b/src/components/ModelingMachineProvider.tsx index 75b059772..2cb1c3ecf 100644 --- a/src/components/ModelingMachineProvider.tsx +++ b/src/components/ModelingMachineProvider.tsx @@ -281,7 +281,11 @@ export const ModelingMachineProvider = ({ 'Set Segment Overlays': assign({ segmentOverlays: ({ context: { segmentOverlays }, event }) => { if (event.type !== 'Set Segment Overlays') return {} - if (event.data.type === 'set-many') return event.data.overlays + if (event.data.type === 'add-many') + return { + ...segmentOverlays, + ...event.data.overlays, + } if (event.data.type === 'set-one') return { ...segmentOverlays, diff --git a/src/lang/langHelpers.ts b/src/lang/langHelpers.ts index d8f12f1ad..ba9a3c90b 100644 --- a/src/lang/langHelpers.ts +++ b/src/lang/langHelpers.ts @@ -27,6 +27,7 @@ export type ToolTip = | 'angledLineThatIntersects' | 'tangentialArcTo' | 'circle' + | 'circleThreePoint' export const toolTips: Array = [ 'line', diff --git a/src/lang/std/sketch.ts b/src/lang/std/sketch.ts index 30a7faea4..d3203ffd9 100644 --- a/src/lang/std/sketch.ts +++ b/src/lang/std/sketch.ts @@ -161,7 +161,8 @@ const commonConstraintInfoHelper = ( } ], code: string, - pathToNode: PathToNode + pathToNode: PathToNode, + filterValue?: string ) => { if (callExp.type !== 'CallExpression') return [] const firstArg = callExp.arguments?.[0] @@ -251,7 +252,8 @@ const horzVertConstraintInfoHelper = ( stdLibFnName: ConstrainInfo['stdLibFnName'], abbreviatedInput: AbbreviatedInput, code: string, - pathToNode: PathToNode + pathToNode: PathToNode, + filterValue?: string ) => { if (callExp.type !== 'CallExpression') return [] const firstArg = callExp.arguments?.[0] @@ -1240,7 +1242,12 @@ export const circleThreePoint: SketchLineHelper = { }, getTag: getTag(), addTag: addTag(), - getConstraintInfo: (callExp: CallExpression, code, pathToNode) => { + getConstraintInfo: ( + callExp: CallExpression, + code, + pathToNode, + filterValue + ) => { if (callExp.type !== 'CallExpression') return [] const firstArg = callExp.arguments?.[0] if (firstArg.type !== 'ObjectExpression') return [] @@ -1290,9 +1297,9 @@ export const circleThreePoint: SketchLineHelper = { const pathToP3XArg: PathToNode = [...pathToP3ArrayExpression, [0, 'index']] const pathToP3YArg: PathToNode = [...pathToP3ArrayExpression, [1, 'index']] - return [ + const constraints: (ConstrainInfo & { filterValue: string })[] = [ { - stdLibFnName: 'circle', + stdLibFnName: 'circleThreePoint', type: 'xAbsolute', isConstrained: isNotLiteralArrayOrStatic(p1Details.expr.elements[0]), sourceRange: [ @@ -1310,9 +1317,10 @@ export const circleThreePoint: SketchLineHelper = { index: 0, key: 'p1', }, + filterValue: 'p1', }, { - stdLibFnName: 'circle', + stdLibFnName: 'circleThreePoint', type: 'yAbsolute', isConstrained: isNotLiteralArrayOrStatic(p1Details.expr.elements[1]), sourceRange: [ @@ -1330,9 +1338,10 @@ export const circleThreePoint: SketchLineHelper = { index: 1, key: 'p1', }, + filterValue: 'p1', }, { - stdLibFnName: 'circle', + stdLibFnName: 'circleThreePoint', type: 'xAbsolute', isConstrained: isNotLiteralArrayOrStatic(p2Details.expr.elements[0]), sourceRange: [ @@ -1350,9 +1359,10 @@ export const circleThreePoint: SketchLineHelper = { index: 0, key: 'p2', }, + filterValue: 'p2', }, { - stdLibFnName: 'circle', + stdLibFnName: 'circleThreePoint', type: 'yAbsolute', isConstrained: isNotLiteralArrayOrStatic(p2Details.expr.elements[1]), sourceRange: [ @@ -1370,9 +1380,10 @@ export const circleThreePoint: SketchLineHelper = { index: 1, key: 'p2', }, + filterValue: 'p2', }, { - stdLibFnName: 'circle', + stdLibFnName: 'circleThreePoint', type: 'xAbsolute', isConstrained: isNotLiteralArrayOrStatic(p3Details.expr.elements[0]), sourceRange: [ @@ -1390,9 +1401,10 @@ export const circleThreePoint: SketchLineHelper = { index: 0, key: 'p3', }, + filterValue: 'p3', }, { - stdLibFnName: 'circle', + stdLibFnName: 'circleThreePoint', type: 'yAbsolute', isConstrained: isNotLiteralArrayOrStatic(p3Details.expr.elements[1]), sourceRange: [ @@ -1410,8 +1422,19 @@ export const circleThreePoint: SketchLineHelper = { index: 1, key: 'p3', }, + filterValue: 'p3', }, ] + const finalConstraints: ConstrainInfo[] = [] + constraints.forEach((constraint) => { + if (!filterValue) { + finalConstraints.push(constraint) + } + if (filterValue && constraint.filterValue === filterValue) { + finalConstraints.push(constraint) + } + }) + return finalConstraints }, } export const angledLine: SketchLineHelper = { @@ -2229,14 +2252,16 @@ export function changeSketchArguments( export function getConstraintInfo( callExpression: Node, code: string, - pathToNode: PathToNode + pathToNode: PathToNode, + filterValue?: string ): ConstrainInfo[] { const fnName = callExpression?.callee?.name || '' if (!(fnName in sketchLineHelperMap)) return [] return sketchLineHelperMap[fnName].getConstraintInfo( callExpression, code, - pathToNode + pathToNode, + filterValue ) } diff --git a/src/lang/std/stdTypes.ts b/src/lang/std/stdTypes.ts index cb861c081..6182bd4d1 100644 --- a/src/lang/std/stdTypes.ts +++ b/src/lang/std/stdTypes.ts @@ -250,6 +250,7 @@ export interface SketchLineHelper { getConstraintInfo: ( callExp: Node, code: string, - pathToNode: PathToNode + pathToNode: PathToNode, + filterValue?: string ) => ConstrainInfo[] } diff --git a/src/machines/modelingMachine.ts b/src/machines/modelingMachine.ts index e8b1dc7cd..a06c33d85 100644 --- a/src/machines/modelingMachine.ts +++ b/src/machines/modelingMachine.ts @@ -85,7 +85,6 @@ import { MachineManager } from 'components/MachineManagerProvider' import { addShell } from 'lang/modifyAst/addShell' import { KclCommandValue } from 'lib/commandTypes' import { getPathsFromPlaneArtifact } from 'lang/std/artifactGraph' -import { CircleThreePoint } from '../clientSideScene/circleThreePoint' export const MODELING_PERSIST_KEY = 'MODELING_PERSIST_KEY' @@ -153,10 +152,12 @@ export interface SegmentOverlay { group: any pathToNode: PathToNode visible: boolean + hasThreeDotMenu: boolean + filterValue?: string } export interface SegmentOverlays { - [pathToNodeString: string]: SegmentOverlay + [pathToNodeString: string]: SegmentOverlay[] } export interface EdgeCutInfo { @@ -207,7 +208,7 @@ export type SegmentOverlayPayload = | { type: 'set-one' pathToNodeString: string - seg: SegmentOverlay + seg: SegmentOverlay[] } | { type: 'delete-one' @@ -215,7 +216,7 @@ export type SegmentOverlayPayload = } | { type: 'clear' } | { - type: 'set-many' + type: 'add-many' overlays: SegmentOverlays }