Grid axis should be able to be selected for angles (#99)
This commit is contained in:
@ -1,19 +1,32 @@
|
|||||||
import { useStore } from '../useStore'
|
import { useState } from 'react'
|
||||||
|
import { Selections, useStore } from '../useStore'
|
||||||
import { DoubleSide, Vector3, Quaternion } from 'three'
|
import { DoubleSide, Vector3, Quaternion } from 'three'
|
||||||
import { Program } from '../lang/abstractSyntaxTree'
|
import { Program } from '../lang/abstractSyntaxTree'
|
||||||
import { addNewSketchLn } from '../lang/std/sketch'
|
import { addNewSketchLn } from '../lang/std/sketch'
|
||||||
import { roundOff } from '../lib/utils'
|
import { roundOff } from '../lib/utils'
|
||||||
|
|
||||||
export const SketchPlane = () => {
|
export const SketchPlane = () => {
|
||||||
const { ast, guiMode, updateAst, programMemory, updateAstAsync } = useStore(
|
const {
|
||||||
(s) => ({
|
ast,
|
||||||
guiMode: s.guiMode,
|
guiMode,
|
||||||
ast: s.ast,
|
programMemory,
|
||||||
updateAst: s.updateAst,
|
updateAstAsync,
|
||||||
updateAstAsync: s.updateAstAsync,
|
setSelectionRanges,
|
||||||
programMemory: s.programMemory,
|
selectionRanges,
|
||||||
})
|
isShiftDown,
|
||||||
)
|
setCursor,
|
||||||
|
} = useStore((s) => ({
|
||||||
|
guiMode: s.guiMode,
|
||||||
|
ast: s.ast,
|
||||||
|
updateAstAsync: s.updateAstAsync,
|
||||||
|
programMemory: s.programMemory,
|
||||||
|
setSelectionRanges: s.setSelectionRanges,
|
||||||
|
selectionRanges: s.selectionRanges,
|
||||||
|
isShiftDown: s.isShiftDown,
|
||||||
|
setCursor: s.setCursor,
|
||||||
|
}))
|
||||||
|
const [xHover, setXHover] = useState(false)
|
||||||
|
const [yHover, setYHover] = useState(false)
|
||||||
if (guiMode.mode !== 'sketch') {
|
if (guiMode.mode !== 'sketch') {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
@ -35,6 +48,32 @@ export const SketchPlane = () => {
|
|||||||
temp
|
temp
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const onAxisClick = (name: 'y-axis' | 'x-axis') => () => {
|
||||||
|
const _selectionRanges: Selections = isShiftDown
|
||||||
|
? selectionRanges
|
||||||
|
: {
|
||||||
|
codeBasedSelections: [
|
||||||
|
{
|
||||||
|
range: [0, 0],
|
||||||
|
type: 'default',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
otherSelections: [],
|
||||||
|
}
|
||||||
|
if (!isShiftDown) {
|
||||||
|
setCursor({
|
||||||
|
..._selectionRanges,
|
||||||
|
otherSelections: [name],
|
||||||
|
})
|
||||||
|
}
|
||||||
|
setTimeout(() => {
|
||||||
|
setSelectionRanges({
|
||||||
|
..._selectionRanges,
|
||||||
|
otherSelections: [name],
|
||||||
|
})
|
||||||
|
}, 100)
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<mesh
|
<mesh
|
||||||
@ -86,10 +125,49 @@ export const SketchPlane = () => {
|
|||||||
/>
|
/>
|
||||||
</mesh>
|
</mesh>
|
||||||
<gridHelper
|
<gridHelper
|
||||||
args={[30, 40, 'blue', 'hotpink']}
|
args={[50, 50, 'blue', 'hotpink']}
|
||||||
quaternion={gridQuaternion}
|
quaternion={gridQuaternion}
|
||||||
position={position}
|
position={position}
|
||||||
|
onClick={() =>
|
||||||
|
!isShiftDown &&
|
||||||
|
setSelectionRanges({
|
||||||
|
...selectionRanges,
|
||||||
|
otherSelections: [],
|
||||||
|
})
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
|
<mesh
|
||||||
|
onPointerOver={() => setXHover(true)}
|
||||||
|
onPointerOut={() => setXHover(false)}
|
||||||
|
onClick={onAxisClick('x-axis')}
|
||||||
|
>
|
||||||
|
<boxGeometry args={[50, 0.2, 0.05]} />
|
||||||
|
<meshStandardMaterial
|
||||||
|
color={
|
||||||
|
selectionRanges.otherSelections.includes('x-axis')
|
||||||
|
? 'skyblue'
|
||||||
|
: xHover
|
||||||
|
? '#FF5555'
|
||||||
|
: '#FF1111'
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</mesh>
|
||||||
|
<mesh
|
||||||
|
onPointerOver={() => setYHover(true)}
|
||||||
|
onPointerOut={() => setYHover(false)}
|
||||||
|
onClick={onAxisClick('y-axis')}
|
||||||
|
>
|
||||||
|
<boxGeometry args={[0.2, 50, 0.05]} />
|
||||||
|
<meshStandardMaterial
|
||||||
|
color={
|
||||||
|
selectionRanges.otherSelections.includes('y-axis')
|
||||||
|
? 'skyblue'
|
||||||
|
: yHover
|
||||||
|
? '#5555FF'
|
||||||
|
: '#1111FF'
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</mesh>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@ export const ConvertToVariable = () => {
|
|||||||
|
|
||||||
const { isSafe, value } = isNodeSafeToReplace(
|
const { isSafe, value } = isNodeSafeToReplace(
|
||||||
ast,
|
ast,
|
||||||
selectionRanges.codeBasedSelections[0].range
|
selectionRanges.codeBasedSelections?.[0]?.range || []
|
||||||
)
|
)
|
||||||
const canReplace = isSafe && value.type !== 'Identifier'
|
const canReplace = isSafe && value.type !== 'Identifier'
|
||||||
const isOnlyOneSelection = selectionRanges.codeBasedSelections.length === 1
|
const isOnlyOneSelection = selectionRanges.codeBasedSelections.length === 1
|
||||||
|
@ -12,8 +12,13 @@ import {
|
|||||||
transformAstSketchLines,
|
transformAstSketchLines,
|
||||||
} from '../../lang/std/sketchcombos'
|
} from '../../lang/std/sketchcombos'
|
||||||
import { SetAngleLengthModal } from '../SetAngleLengthModal'
|
import { SetAngleLengthModal } from '../SetAngleLengthModal'
|
||||||
import { createVariableDeclaration } from '../../lang/modifyAst'
|
import {
|
||||||
|
createBinaryExpressionWithUnary,
|
||||||
|
createIdentifier,
|
||||||
|
createVariableDeclaration,
|
||||||
|
} from '../../lang/modifyAst'
|
||||||
import { removeDoubleNegatives } from '../AvailableVarsHelpers'
|
import { removeDoubleNegatives } from '../AvailableVarsHelpers'
|
||||||
|
import { normaliseAngle } from '../../lib/utils'
|
||||||
|
|
||||||
const getModalInfo = create(SetAngleLengthModal as any)
|
const getModalInfo = create(SetAngleLengthModal as any)
|
||||||
|
|
||||||
@ -68,16 +73,47 @@ export const SetAngleLength = ({
|
|||||||
referenceSegName: '',
|
referenceSegName: '',
|
||||||
})
|
})
|
||||||
try {
|
try {
|
||||||
|
const isReferencingYAxis =
|
||||||
|
selectionRanges.otherSelections.length === 1 &&
|
||||||
|
selectionRanges.otherSelections[0] === 'y-axis'
|
||||||
|
const isReferencingYAxisAngle =
|
||||||
|
isReferencingYAxis && angleOrLength === 'setAngle'
|
||||||
|
|
||||||
|
const isReferencingXAxis =
|
||||||
|
selectionRanges.otherSelections.length === 1 &&
|
||||||
|
selectionRanges.otherSelections[0] === 'x-axis'
|
||||||
|
const isReferencingXAxisAngle =
|
||||||
|
isReferencingXAxis && angleOrLength === 'setAngle'
|
||||||
|
|
||||||
|
let forceVal = valueUsedInTransform || 0
|
||||||
|
let calcIdentifier = createIdentifier('_0')
|
||||||
|
if (isReferencingYAxisAngle) {
|
||||||
|
calcIdentifier = createIdentifier(forceVal < 0 ? '_270' : '_90')
|
||||||
|
forceVal = normaliseAngle(forceVal + (forceVal < 0 ? 90 : -90))
|
||||||
|
} else if (isReferencingXAxisAngle) {
|
||||||
|
calcIdentifier = createIdentifier(
|
||||||
|
Math.abs(forceVal) > 90 ? '_180' : '_0'
|
||||||
|
)
|
||||||
|
forceVal =
|
||||||
|
Math.abs(forceVal) > 90
|
||||||
|
? normaliseAngle(forceVal - 180)
|
||||||
|
: forceVal
|
||||||
|
}
|
||||||
const { valueNode, variableName, newVariableInsertIndex, sign } =
|
const { valueNode, variableName, newVariableInsertIndex, sign } =
|
||||||
await getModalInfo({
|
await getModalInfo({
|
||||||
value: valueUsedInTransform,
|
value: forceVal,
|
||||||
valueName: angleOrLength === 'setAngle' ? 'angle' : 'length',
|
valueName: angleOrLength === 'setAngle' ? 'angle' : 'length',
|
||||||
} as any)
|
} as any)
|
||||||
const finalValue = removeDoubleNegatives(
|
let finalValue = removeDoubleNegatives(valueNode, sign, variableName)
|
||||||
valueNode,
|
if (
|
||||||
sign,
|
isReferencingYAxisAngle ||
|
||||||
variableName
|
(isReferencingXAxisAngle && calcIdentifier.name !== '_0')
|
||||||
)
|
) {
|
||||||
|
finalValue = createBinaryExpressionWithUnary([
|
||||||
|
calcIdentifier,
|
||||||
|
finalValue,
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
const { modifiedAst: _modifiedAst } = transformAstSketchLines({
|
const { modifiedAst: _modifiedAst } = transformAstSketchLines({
|
||||||
ast: JSON.parse(JSON.stringify(ast)),
|
ast: JSON.parse(JSON.stringify(ast)),
|
||||||
|
@ -20,6 +20,10 @@ export function getLength(a: [number, number], b: [number, number]): number {
|
|||||||
export function getAngle(a: [number, number], b: [number, number]): number {
|
export function getAngle(a: [number, number], b: [number, number]): number {
|
||||||
const x = b[0] - a[0]
|
const x = b[0] - a[0]
|
||||||
const y = b[1] - a[1]
|
const y = b[1] - a[1]
|
||||||
const result = ((Math.atan2(y, x) * 180) / Math.PI + 360) % 360
|
return normaliseAngle((Math.atan2(y, x) * 180) / Math.PI)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function normaliseAngle(angle: number): number {
|
||||||
|
const result = ((angle % 360) + 360) % 360
|
||||||
return result > 180 ? result - 360 : result
|
return result > 180 ? result - 360 : result
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user