number of stability fixes
This commit is contained in:
@ -12,6 +12,8 @@ import {
|
||||
Path,
|
||||
Rotation,
|
||||
Position,
|
||||
PathToNode,
|
||||
SourceRange,
|
||||
} from '../lang/executor'
|
||||
import { BufferGeometry } from 'three'
|
||||
import { useStore } from '../useStore'
|
||||
@ -191,9 +193,10 @@ export function RenderViewerArtifacts({
|
||||
}: {
|
||||
artifacts: (ExtrudeGroup | SketchGroup)[]
|
||||
}) {
|
||||
useSetAppModeFromCursorLocation(artifacts)
|
||||
return (
|
||||
<>
|
||||
{artifacts.map((artifact, i) => (
|
||||
{artifacts?.map((artifact, i) => (
|
||||
<RenderViewerArtifact key={i} artifact={artifact} />
|
||||
))}
|
||||
</>
|
||||
@ -205,59 +208,22 @@ function RenderViewerArtifact({
|
||||
}: {
|
||||
artifact: ExtrudeGroup | SketchGroup
|
||||
}) {
|
||||
const { selectionRange, guiMode, ast, setGuiMode } = useStore(
|
||||
({ selectionRange, guiMode, ast, setGuiMode }) => ({
|
||||
selectionRange,
|
||||
guiMode,
|
||||
ast,
|
||||
setGuiMode,
|
||||
})
|
||||
)
|
||||
const [editorCursor, setEditorCursor] = useState(false)
|
||||
useEffect(() => {
|
||||
const shouldHighlight = isOverlapping(
|
||||
artifact.__meta[0].sourceRange,
|
||||
selectionRange
|
||||
)
|
||||
setEditorCursor(shouldHighlight)
|
||||
}, [selectionRange, artifact.__meta])
|
||||
|
||||
useEffect(() => {
|
||||
const shouldHighlight = artifact.__meta.some((aMeta) =>
|
||||
isOverlapping(aMeta.sourceRange, selectionRange)
|
||||
)
|
||||
if (
|
||||
shouldHighlight &&
|
||||
(guiMode.mode === 'default' || guiMode.mode === 'canEditSketch') &&
|
||||
ast &&
|
||||
artifact.type === 'sketchGroup'
|
||||
) {
|
||||
const pathToNode = getNodePathFromSourceRange(
|
||||
ast,
|
||||
artifact.__meta[0].sourceRange
|
||||
)
|
||||
const { rotation, position } = artifact
|
||||
setGuiMode({ mode: 'canEditSketch', pathToNode, rotation, position })
|
||||
} else if (
|
||||
shouldHighlight &&
|
||||
(guiMode.mode === 'default' || guiMode.mode === 'canEditSketch') &&
|
||||
ast &&
|
||||
artifact.type === 'extrudeGroup'
|
||||
) {
|
||||
const pathToNode = getNodePathFromSourceRange(
|
||||
ast,
|
||||
artifact.__meta[0].sourceRange
|
||||
)
|
||||
const { rotation, position } = artifact
|
||||
setGuiMode({ mode: 'canEditExtrude', pathToNode, rotation, position })
|
||||
} else if (
|
||||
!shouldHighlight &&
|
||||
(guiMode.mode === 'canEditSketch' || guiMode.mode === 'canEditExtrude') &&
|
||||
(artifact.type === 'sketchGroup' || artifact.type === 'extrudeGroup')
|
||||
) {
|
||||
setGuiMode({ mode: 'default' })
|
||||
}
|
||||
}, [selectionRange, artifact, ast, guiMode.mode, setGuiMode])
|
||||
// const { selectionRange, guiMode, ast, setGuiMode } = useStore(
|
||||
// ({ selectionRange, guiMode, ast, setGuiMode }) => ({
|
||||
// selectionRange,
|
||||
// guiMode,
|
||||
// ast,
|
||||
// setGuiMode,
|
||||
// })
|
||||
// )
|
||||
// const [editorCursor, setEditorCursor] = useState(false)
|
||||
// useEffect(() => {
|
||||
// const shouldHighlight = isOverlapping(
|
||||
// artifact.__meta.slice(-1)[0].sourceRange,
|
||||
// selectionRange
|
||||
// )
|
||||
// setEditorCursor(shouldHighlight)
|
||||
// }, [selectionRange, artifact.__meta])
|
||||
|
||||
if (artifact.type === 'sketchGroup') {
|
||||
return (
|
||||
@ -266,7 +232,7 @@ function RenderViewerArtifact({
|
||||
<PathRender
|
||||
geoInfo={geoInfo}
|
||||
key={key}
|
||||
forceHighlight={editorCursor}
|
||||
forceHighlight={false}
|
||||
rotation={artifact.rotation}
|
||||
position={artifact.position}
|
||||
/>
|
||||
@ -281,7 +247,7 @@ function RenderViewerArtifact({
|
||||
<WallRender
|
||||
geoInfo={geoInfo}
|
||||
key={key}
|
||||
forceHighlight={editorCursor}
|
||||
forceHighlight={false}
|
||||
rotation={artifact.rotation}
|
||||
position={artifact.position}
|
||||
/>
|
||||
@ -454,3 +420,91 @@ function LineRender({
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
type Boop = ExtrudeGroup | SketchGroup
|
||||
|
||||
function useSetAppModeFromCursorLocation(artifacts: Boop[]) {
|
||||
const { selectionRange, guiMode, setGuiMode, ast } = useStore(
|
||||
({ selectionRange, guiMode, setGuiMode, ast }) => ({
|
||||
selectionRange,
|
||||
guiMode,
|
||||
setGuiMode,
|
||||
ast,
|
||||
})
|
||||
)
|
||||
useEffect(() => {
|
||||
const artifactsWithinCursorRange: (
|
||||
| {
|
||||
parentType: Boop['type']
|
||||
isParent: true
|
||||
pathToNode: PathToNode
|
||||
sourceRange: SourceRange
|
||||
rotation: Rotation
|
||||
position: Position
|
||||
}
|
||||
| {
|
||||
parentType: Boop['type']
|
||||
isParent: false
|
||||
pathToNode: PathToNode
|
||||
sourceRange: SourceRange
|
||||
}
|
||||
)[] = []
|
||||
artifacts.forEach((artifact) => {
|
||||
artifact.value.forEach((geo) => {
|
||||
if (isOverlapping(geo.__geoMeta.sourceRange, selectionRange)) {
|
||||
artifactsWithinCursorRange.push({
|
||||
parentType: artifact.type,
|
||||
isParent: false,
|
||||
pathToNode: geo.__geoMeta.pathToNode,
|
||||
sourceRange: geo.__geoMeta.sourceRange,
|
||||
})
|
||||
}
|
||||
})
|
||||
artifact.__meta.forEach((meta) => {
|
||||
if (isOverlapping(meta.sourceRange, selectionRange)) {
|
||||
artifactsWithinCursorRange.push({
|
||||
parentType: artifact.type,
|
||||
isParent: true,
|
||||
pathToNode: meta.pathToNode,
|
||||
sourceRange: meta.sourceRange,
|
||||
rotation: artifact.rotation,
|
||||
position: artifact.position,
|
||||
})
|
||||
}
|
||||
})
|
||||
})
|
||||
const parentArtifacts = artifactsWithinCursorRange.filter((a) => a.isParent)
|
||||
if (parentArtifacts.length > 1) {
|
||||
console.log('multiple parents, might be an issue?', parentArtifacts)
|
||||
}
|
||||
const artifact = parentArtifacts[0]
|
||||
const shouldHighlight = !!artifact
|
||||
if (
|
||||
shouldHighlight &&
|
||||
(guiMode.mode === 'default' || guiMode.mode === 'canEditSketch') &&
|
||||
ast &&
|
||||
artifact.parentType === 'sketchGroup' &&
|
||||
artifact.isParent
|
||||
) {
|
||||
const pathToNode = getNodePathFromSourceRange(ast, artifact.sourceRange)
|
||||
const { rotation, position } = artifact
|
||||
setGuiMode({ mode: 'canEditSketch', pathToNode, rotation, position })
|
||||
} else if (
|
||||
shouldHighlight &&
|
||||
(guiMode.mode === 'default' || guiMode.mode === 'canEditSketch') &&
|
||||
ast &&
|
||||
artifact.parentType === 'extrudeGroup' &&
|
||||
artifact.isParent
|
||||
) {
|
||||
const pathToNode = getNodePathFromSourceRange(ast, artifact.sourceRange)
|
||||
const { rotation, position } = artifact
|
||||
setGuiMode({ mode: 'canEditExtrude', pathToNode, rotation, position })
|
||||
} else if (
|
||||
!shouldHighlight &&
|
||||
(guiMode.mode === 'canEditSketch' || guiMode.mode === 'canEditExtrude')
|
||||
// (artifact.parentType === 'extrudeGroup' || artifact.type === 'extrudeGroup')
|
||||
) {
|
||||
setGuiMode({ mode: 'default' })
|
||||
}
|
||||
}, [artifacts, selectionRange])
|
||||
}
|
||||
|
@ -1348,7 +1348,8 @@ function debuggerr(tokens: Token[], indexes: number[], msg = ''): string {
|
||||
export function getNodeFromPath(
|
||||
node: Program,
|
||||
path: (string | number)[],
|
||||
stopAt: string = ''
|
||||
stopAt: string = '',
|
||||
returnEarly = false
|
||||
) {
|
||||
let currentNode = node as any
|
||||
let stopAtNode = null
|
||||
@ -1363,6 +1364,9 @@ export function getNodeFromPath(
|
||||
// it will match the deepest node of the type
|
||||
// instead of returning at the first match
|
||||
stopAtNode = currentNode
|
||||
if (returnEarly) {
|
||||
return stopAtNode
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
throw new Error(
|
||||
|
@ -74,6 +74,19 @@ show(mySketch001)`
|
||||
{
|
||||
type: 'extrudeGroup',
|
||||
value: [
|
||||
{
|
||||
type: 'extrudePlane',
|
||||
position: [-0.795, -0.5444722215136415, -0.5444722215136416],
|
||||
rotation: [
|
||||
0.35471170441873584, 0.3467252481708758, -0.14361830020955396,
|
||||
0.8563498075401887,
|
||||
],
|
||||
__geoMeta: {
|
||||
geo: 'PlaneGeometry',
|
||||
sourceRange: [24, 44],
|
||||
pathToNode: [],
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'extrudePlane',
|
||||
position: [
|
||||
@ -137,6 +150,19 @@ show(theExtrude, sk2)`
|
||||
{
|
||||
type: 'extrudeGroup',
|
||||
value: [
|
||||
{
|
||||
type: 'extrudePlane',
|
||||
position: [-0.1618929317752782, 0, 1.01798363377866],
|
||||
rotation: [
|
||||
0.3823192025331841, -0.04029905920751535, -0.016692416874629204,
|
||||
0.9230002039112793,
|
||||
],
|
||||
__geoMeta: {
|
||||
geo: 'PlaneGeometry',
|
||||
sourceRange: [16, 31],
|
||||
pathToNode: [],
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'extrudePlane',
|
||||
position: [
|
||||
@ -189,6 +215,21 @@ show(theExtrude, sk2)`
|
||||
{
|
||||
type: 'extrudeGroup',
|
||||
value: [
|
||||
{
|
||||
type: 'extrudePlane',
|
||||
position: [
|
||||
0.5230004643466108, 4.393026831645281, 5.367870706359959,
|
||||
],
|
||||
rotation: [
|
||||
-0.5548685410139091, 0.7377864971619333, 0.3261466075583827,
|
||||
-0.20351996751370383,
|
||||
],
|
||||
__geoMeta: {
|
||||
geo: 'PlaneGeometry',
|
||||
sourceRange: [241, 256],
|
||||
pathToNode: [],
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'extrudePlane',
|
||||
position: [
|
||||
|
@ -98,10 +98,12 @@ export function extrudeGeo({
|
||||
from,
|
||||
to,
|
||||
length,
|
||||
extrusionDirection = 1,
|
||||
}: {
|
||||
from: [number, number, number]
|
||||
to: [number, number, number]
|
||||
length: number
|
||||
extrusionDirection?: number
|
||||
}): {
|
||||
geo: BufferGeometry
|
||||
position: Position
|
||||
@ -124,7 +126,13 @@ export function extrudeGeo({
|
||||
face.translate(to[0], to[1], to[2])
|
||||
|
||||
const quat = new Quaternion()
|
||||
const euler = new Euler(-Math.PI / 2, ry, rz * sign, 'XYZ')
|
||||
const otherSign = ry === 0 ? 1 : -1 // don't ask questions, it works okay
|
||||
const euler = new Euler(
|
||||
(Math.PI * otherSign * extrusionDirection) / 2,
|
||||
ry,
|
||||
rz * sign * -otherSign,
|
||||
'XYZ'
|
||||
)
|
||||
quat.setFromEuler(euler)
|
||||
|
||||
return {
|
||||
|
@ -385,8 +385,12 @@ export function sketchOnExtrudedFace(
|
||||
const _node = { ...node }
|
||||
const dumbyStartend = { start: 0, end: 0 }
|
||||
const newSketchName = findUniqueName(node, 'part')
|
||||
const oldSketchName = getNodeFromPath(_node, pathToNode, 'VariableDeclarator')
|
||||
.id.name
|
||||
const oldSketchName = getNodeFromPath(
|
||||
_node,
|
||||
pathToNode,
|
||||
'VariableDeclarator',
|
||||
true
|
||||
).id.name
|
||||
const expression = getNodeFromPath(_node, pathToNode, 'CallExpression') as
|
||||
| VariableDeclarator
|
||||
| CallExpression
|
||||
|
@ -173,13 +173,12 @@ export const sketchFns = {
|
||||
const { position, rotation } = sketchVal
|
||||
|
||||
const extrudeSurfaces: ExtrudeSurface[] = []
|
||||
const extrusionDirection = clockwiseSign(
|
||||
sketch.value.map((line) => line.to)
|
||||
)
|
||||
sketch.value.map((line, index) => {
|
||||
if (line.type === 'toPoint' && index !== 0) {
|
||||
const lastPoint = sketch.value[index - 1]
|
||||
let from: [number, number] = [0, 0]
|
||||
if (lastPoint.type === 'toPoint') {
|
||||
from = lastPoint.to
|
||||
}
|
||||
if (line.type === 'toPoint') {
|
||||
let from: [number, number] = line.from
|
||||
const to = line.to
|
||||
const {
|
||||
geo,
|
||||
@ -189,6 +188,7 @@ export const sketchFns = {
|
||||
from: [from[0], from[1], 0],
|
||||
to: [to[0], to[1], 0],
|
||||
length,
|
||||
extrusionDirection,
|
||||
})
|
||||
const groupQuaternion = new Quaternion(...rotation)
|
||||
const currentWallQuat = new Quaternion(...faceRotation)
|
||||
@ -344,3 +344,13 @@ function getExtrudeWallTransform(
|
||||
quaternion: path.rotation,
|
||||
}
|
||||
}
|
||||
|
||||
function clockwiseSign(points: [number, number][]): number {
|
||||
let sum = 0
|
||||
for (let i = 0; i < points.length; i++) {
|
||||
const currentPoint = points[i]
|
||||
const nextPoint = points[(i + 1) % points.length]
|
||||
sum += (nextPoint[0] - currentPoint[0]) * (nextPoint[1] + currentPoint[1])
|
||||
}
|
||||
return sum >= 0 ? 1 : -1
|
||||
}
|
||||
|
Reference in New Issue
Block a user