number of stability fixes
This commit is contained in:
@ -12,6 +12,8 @@ import {
|
|||||||
Path,
|
Path,
|
||||||
Rotation,
|
Rotation,
|
||||||
Position,
|
Position,
|
||||||
|
PathToNode,
|
||||||
|
SourceRange,
|
||||||
} from '../lang/executor'
|
} from '../lang/executor'
|
||||||
import { BufferGeometry } from 'three'
|
import { BufferGeometry } from 'three'
|
||||||
import { useStore } from '../useStore'
|
import { useStore } from '../useStore'
|
||||||
@ -191,9 +193,10 @@ export function RenderViewerArtifacts({
|
|||||||
}: {
|
}: {
|
||||||
artifacts: (ExtrudeGroup | SketchGroup)[]
|
artifacts: (ExtrudeGroup | SketchGroup)[]
|
||||||
}) {
|
}) {
|
||||||
|
useSetAppModeFromCursorLocation(artifacts)
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{artifacts.map((artifact, i) => (
|
{artifacts?.map((artifact, i) => (
|
||||||
<RenderViewerArtifact key={i} artifact={artifact} />
|
<RenderViewerArtifact key={i} artifact={artifact} />
|
||||||
))}
|
))}
|
||||||
</>
|
</>
|
||||||
@ -205,59 +208,22 @@ function RenderViewerArtifact({
|
|||||||
}: {
|
}: {
|
||||||
artifact: ExtrudeGroup | SketchGroup
|
artifact: ExtrudeGroup | SketchGroup
|
||||||
}) {
|
}) {
|
||||||
const { selectionRange, guiMode, ast, setGuiMode } = useStore(
|
// const { selectionRange, guiMode, ast, setGuiMode } = useStore(
|
||||||
({ selectionRange, guiMode, ast, setGuiMode }) => ({
|
// ({ selectionRange, guiMode, ast, setGuiMode }) => ({
|
||||||
selectionRange,
|
// selectionRange,
|
||||||
guiMode,
|
// guiMode,
|
||||||
ast,
|
// ast,
|
||||||
setGuiMode,
|
// setGuiMode,
|
||||||
})
|
// })
|
||||||
)
|
// )
|
||||||
const [editorCursor, setEditorCursor] = useState(false)
|
// const [editorCursor, setEditorCursor] = useState(false)
|
||||||
useEffect(() => {
|
// useEffect(() => {
|
||||||
const shouldHighlight = isOverlapping(
|
// const shouldHighlight = isOverlapping(
|
||||||
artifact.__meta[0].sourceRange,
|
// artifact.__meta.slice(-1)[0].sourceRange,
|
||||||
selectionRange
|
// selectionRange
|
||||||
)
|
// )
|
||||||
setEditorCursor(shouldHighlight)
|
// setEditorCursor(shouldHighlight)
|
||||||
}, [selectionRange, artifact.__meta])
|
// }, [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])
|
|
||||||
|
|
||||||
if (artifact.type === 'sketchGroup') {
|
if (artifact.type === 'sketchGroup') {
|
||||||
return (
|
return (
|
||||||
@ -266,7 +232,7 @@ function RenderViewerArtifact({
|
|||||||
<PathRender
|
<PathRender
|
||||||
geoInfo={geoInfo}
|
geoInfo={geoInfo}
|
||||||
key={key}
|
key={key}
|
||||||
forceHighlight={editorCursor}
|
forceHighlight={false}
|
||||||
rotation={artifact.rotation}
|
rotation={artifact.rotation}
|
||||||
position={artifact.position}
|
position={artifact.position}
|
||||||
/>
|
/>
|
||||||
@ -281,7 +247,7 @@ function RenderViewerArtifact({
|
|||||||
<WallRender
|
<WallRender
|
||||||
geoInfo={geoInfo}
|
geoInfo={geoInfo}
|
||||||
key={key}
|
key={key}
|
||||||
forceHighlight={editorCursor}
|
forceHighlight={false}
|
||||||
rotation={artifact.rotation}
|
rotation={artifact.rotation}
|
||||||
position={artifact.position}
|
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(
|
export function getNodeFromPath(
|
||||||
node: Program,
|
node: Program,
|
||||||
path: (string | number)[],
|
path: (string | number)[],
|
||||||
stopAt: string = ''
|
stopAt: string = '',
|
||||||
|
returnEarly = false
|
||||||
) {
|
) {
|
||||||
let currentNode = node as any
|
let currentNode = node as any
|
||||||
let stopAtNode = null
|
let stopAtNode = null
|
||||||
@ -1363,6 +1364,9 @@ export function getNodeFromPath(
|
|||||||
// it will match the deepest node of the type
|
// it will match the deepest node of the type
|
||||||
// instead of returning at the first match
|
// instead of returning at the first match
|
||||||
stopAtNode = currentNode
|
stopAtNode = currentNode
|
||||||
|
if (returnEarly) {
|
||||||
|
return stopAtNode
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
|
@ -74,6 +74,19 @@ show(mySketch001)`
|
|||||||
{
|
{
|
||||||
type: 'extrudeGroup',
|
type: 'extrudeGroup',
|
||||||
value: [
|
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',
|
type: 'extrudePlane',
|
||||||
position: [
|
position: [
|
||||||
@ -137,6 +150,19 @@ show(theExtrude, sk2)`
|
|||||||
{
|
{
|
||||||
type: 'extrudeGroup',
|
type: 'extrudeGroup',
|
||||||
value: [
|
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',
|
type: 'extrudePlane',
|
||||||
position: [
|
position: [
|
||||||
@ -189,6 +215,21 @@ show(theExtrude, sk2)`
|
|||||||
{
|
{
|
||||||
type: 'extrudeGroup',
|
type: 'extrudeGroup',
|
||||||
value: [
|
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',
|
type: 'extrudePlane',
|
||||||
position: [
|
position: [
|
||||||
|
@ -98,10 +98,12 @@ export function extrudeGeo({
|
|||||||
from,
|
from,
|
||||||
to,
|
to,
|
||||||
length,
|
length,
|
||||||
|
extrusionDirection = 1,
|
||||||
}: {
|
}: {
|
||||||
from: [number, number, number]
|
from: [number, number, number]
|
||||||
to: [number, number, number]
|
to: [number, number, number]
|
||||||
length: number
|
length: number
|
||||||
|
extrusionDirection?: number
|
||||||
}): {
|
}): {
|
||||||
geo: BufferGeometry
|
geo: BufferGeometry
|
||||||
position: Position
|
position: Position
|
||||||
@ -124,7 +126,13 @@ export function extrudeGeo({
|
|||||||
face.translate(to[0], to[1], to[2])
|
face.translate(to[0], to[1], to[2])
|
||||||
|
|
||||||
const quat = new Quaternion()
|
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)
|
quat.setFromEuler(euler)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -385,8 +385,12 @@ export function sketchOnExtrudedFace(
|
|||||||
const _node = { ...node }
|
const _node = { ...node }
|
||||||
const dumbyStartend = { start: 0, end: 0 }
|
const dumbyStartend = { start: 0, end: 0 }
|
||||||
const newSketchName = findUniqueName(node, 'part')
|
const newSketchName = findUniqueName(node, 'part')
|
||||||
const oldSketchName = getNodeFromPath(_node, pathToNode, 'VariableDeclarator')
|
const oldSketchName = getNodeFromPath(
|
||||||
.id.name
|
_node,
|
||||||
|
pathToNode,
|
||||||
|
'VariableDeclarator',
|
||||||
|
true
|
||||||
|
).id.name
|
||||||
const expression = getNodeFromPath(_node, pathToNode, 'CallExpression') as
|
const expression = getNodeFromPath(_node, pathToNode, 'CallExpression') as
|
||||||
| VariableDeclarator
|
| VariableDeclarator
|
||||||
| CallExpression
|
| CallExpression
|
||||||
|
@ -173,13 +173,12 @@ export const sketchFns = {
|
|||||||
const { position, rotation } = sketchVal
|
const { position, rotation } = sketchVal
|
||||||
|
|
||||||
const extrudeSurfaces: ExtrudeSurface[] = []
|
const extrudeSurfaces: ExtrudeSurface[] = []
|
||||||
|
const extrusionDirection = clockwiseSign(
|
||||||
|
sketch.value.map((line) => line.to)
|
||||||
|
)
|
||||||
sketch.value.map((line, index) => {
|
sketch.value.map((line, index) => {
|
||||||
if (line.type === 'toPoint' && index !== 0) {
|
if (line.type === 'toPoint') {
|
||||||
const lastPoint = sketch.value[index - 1]
|
let from: [number, number] = line.from
|
||||||
let from: [number, number] = [0, 0]
|
|
||||||
if (lastPoint.type === 'toPoint') {
|
|
||||||
from = lastPoint.to
|
|
||||||
}
|
|
||||||
const to = line.to
|
const to = line.to
|
||||||
const {
|
const {
|
||||||
geo,
|
geo,
|
||||||
@ -189,6 +188,7 @@ export const sketchFns = {
|
|||||||
from: [from[0], from[1], 0],
|
from: [from[0], from[1], 0],
|
||||||
to: [to[0], to[1], 0],
|
to: [to[0], to[1], 0],
|
||||||
length,
|
length,
|
||||||
|
extrusionDirection,
|
||||||
})
|
})
|
||||||
const groupQuaternion = new Quaternion(...rotation)
|
const groupQuaternion = new Quaternion(...rotation)
|
||||||
const currentWallQuat = new Quaternion(...faceRotation)
|
const currentWallQuat = new Quaternion(...faceRotation)
|
||||||
@ -344,3 +344,13 @@ function getExtrudeWallTransform(
|
|||||||
quaternion: path.rotation,
|
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