get overlays working for circle three point

This commit is contained in:
Kurt Hutten Irev-Dev
2025-02-03 17:53:08 +11:00
parent 5a5138a703
commit 84d17454e9
9 changed files with 138 additions and 60 deletions

View File

@ -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 (
<Overlay
overlay={overlay}
key={pathToNodeString}
key={pathToNodeString + String(index)}
pathToNodeString={pathToNodeString}
overlayIndex={index}
/>
@ -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 (
<div className={`absolute w-0 h-0`}>
<div
@ -307,7 +310,8 @@ const Overlay = ({
this will likely change soon when we implement multi-profile so we'll leave it for now
issue: https://github.com/KittyCAD/modeling-app/issues/3910
*/}
{callExpression?.callee?.name !== 'circle' && (
{callExpression?.callee?.name !== 'circle' &&
callExpression?.callee?.name !== 'circleThreePoint' && (
<SegmentMenu
verticalPosition={
overlay.windowCoords[1] > window.innerHeight / 2

View File

@ -71,7 +71,6 @@ import {
SegmentUtils,
segmentUtils,
} from './segments'
import { CircleThreePoint } from './circleThreePoint'
import {
addCallExpressionsToPipe,
addCloseToPipe,

View File

@ -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: {
seg: [
{
windowCoords: [x, y],
angle: _angle,
group,
pathToNode: group.userData.pathToNode,
visible: isHandlesVisible,
hasThreeDotMenu,
},
],
}
}
return null

View File

@ -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,
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: Math.PI / 4,
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
}
}
}

View File

@ -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,

View File

@ -27,6 +27,7 @@ export type ToolTip =
| 'angledLineThatIntersects'
| 'tangentialArcTo'
| 'circle'
| 'circleThreePoint'
export const toolTips: Array<ToolTip> = [
'line',

View File

@ -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<CallExpression>,
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
)
}

View File

@ -250,6 +250,7 @@ export interface SketchLineHelper {
getConstraintInfo: (
callExp: Node<CallExpression>,
code: string,
pathToNode: PathToNode
pathToNode: PathToNode,
filterValue?: string
) => ConstrainInfo[]
}

View File

@ -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
}