Add sketch on extrude face functionality
This commit is contained in:
@ -84,7 +84,6 @@ function MovingSphere({
|
||||
let theNewPoints: [number, number] = [x, y]
|
||||
const { modifiedAst } = changeArguments(ast, thePath, theNewPoints)
|
||||
updateAst(modifiedAst)
|
||||
console.log('reset position')
|
||||
ref.current.position.set(...position)
|
||||
}
|
||||
setIsMouseDown(false)
|
||||
|
@ -199,6 +199,23 @@ function makeArguments(
|
||||
expression,
|
||||
])
|
||||
}
|
||||
if (
|
||||
argumentToken.token.type === 'brace' &&
|
||||
argumentToken.token.value === '{'
|
||||
) {
|
||||
const { expression, lastIndex } = makeObjectExpression(
|
||||
tokens,
|
||||
argumentToken.index
|
||||
)
|
||||
const nextCommarOrBraceTokenIndex = nextMeaningfulToken(
|
||||
tokens,
|
||||
lastIndex
|
||||
).index
|
||||
return makeArguments(tokens, nextCommarOrBraceTokenIndex, [
|
||||
...previousArgs,
|
||||
expression,
|
||||
])
|
||||
}
|
||||
if (!isIdentifierOrLiteral) {
|
||||
const { expression, lastIndex } = makeBinaryExpression(tokens, index)
|
||||
return makeArguments(tokens, lastIndex, [...previousArgs, expression])
|
||||
@ -217,6 +234,25 @@ function makeArguments(
|
||||
value,
|
||||
])
|
||||
}
|
||||
|
||||
if (
|
||||
argumentToken.token.type === 'word' &&
|
||||
nextBraceOrCommaToken.token.type === 'brace' &&
|
||||
nextBraceOrCommaToken.token.value === '('
|
||||
) {
|
||||
const { expression, lastIndex } = makeCallExpression(
|
||||
tokens,
|
||||
argumentToken.index
|
||||
)
|
||||
const nextCommarOrBraceTokenIndex = nextMeaningfulToken(
|
||||
tokens,
|
||||
lastIndex
|
||||
).index
|
||||
return makeArguments(tokens, nextCommarOrBraceTokenIndex, [
|
||||
...previousArgs,
|
||||
expression,
|
||||
])
|
||||
}
|
||||
if (argumentToken.token.type === 'word') {
|
||||
const identifier = makeIdentifier(tokens, argumentToken.index)
|
||||
return makeArguments(tokens, nextBraceOrCommaToken.index, [
|
||||
|
@ -76,8 +76,13 @@ show(mySketch001)`
|
||||
value: [
|
||||
{
|
||||
type: 'extrudePlane',
|
||||
position: [0, 0, 0],
|
||||
rotation: [0.3826834323650898, 0, 0, 0.9238795325112867],
|
||||
position: [
|
||||
-0.5650000000000001, -2.602152954766495, -2.602152954766495,
|
||||
],
|
||||
rotation: [
|
||||
0.20394238048109659, 0.7817509623502217, -0.3238118510036805,
|
||||
0.4923604609001174,
|
||||
],
|
||||
__geoMeta: {
|
||||
geo: 'PlaneGeometry',
|
||||
sourceRange: [47, 66],
|
||||
@ -97,6 +102,132 @@ show(mySketch001)`
|
||||
},
|
||||
])
|
||||
})
|
||||
test('sketch extrude and sketch on one of the faces', () => {
|
||||
const code = `
|
||||
sketch sk1 {
|
||||
lineTo(-2.5, 0)
|
||||
path p = lineTo(0, 10)
|
||||
lineTo(2.5, 0)
|
||||
}
|
||||
|> rx(45, %)
|
||||
|> translate([1,0,1], %)
|
||||
|> ry(5, %)
|
||||
const theExtrude = extrude(2, sk1)
|
||||
const theTransf = getExtrudeWallTransform('p', theExtrude)
|
||||
sketch sk2 {
|
||||
lineTo(-2.5, 0)
|
||||
path p = lineTo(0, 3)
|
||||
lineTo(2.5, 0)
|
||||
}
|
||||
|> transform(theTransf, %)
|
||||
|> extrude(2, %)
|
||||
|
||||
|
||||
show(theExtrude, sk2)`
|
||||
const programMemory = executor(abstractSyntaxTree(lexer(code)))
|
||||
const geos = programMemory?.return?.map(
|
||||
(a) => programMemory?.root?.[a.name]
|
||||
)
|
||||
const artifactsWithoutGeos = removeGeo(geos as any)
|
||||
expect(artifactsWithoutGeos).toEqual([
|
||||
{
|
||||
type: 'extrudeGroup',
|
||||
value: [
|
||||
{
|
||||
type: 'extrudePlane',
|
||||
position: [
|
||||
0.14624915180581843, 3.5355339059327373, 4.540063765792454,
|
||||
],
|
||||
rotation: [
|
||||
-0.24844095888221532, 0.7523143130765927, -0.2910733573455524,
|
||||
-0.5362616571538269,
|
||||
],
|
||||
__geoMeta: {
|
||||
geo: 'PlaneGeometry',
|
||||
sourceRange: [39, 56],
|
||||
pathToNode: [],
|
||||
},
|
||||
name: 'p',
|
||||
},
|
||||
{
|
||||
type: 'extrudePlane',
|
||||
position: [
|
||||
2.636735897035183, 3.5355339059327386, 4.322174408923308,
|
||||
],
|
||||
rotation: [
|
||||
0.22212685137378593, 0.7027132469491032, -0.3116187916437232,
|
||||
0.5997895323824204,
|
||||
],
|
||||
__geoMeta: {
|
||||
geo: 'PlaneGeometry',
|
||||
sourceRange: [59, 73],
|
||||
pathToNode: [],
|
||||
},
|
||||
},
|
||||
],
|
||||
height: 2,
|
||||
position: [1.083350440839404, 0, 0.9090389553440874],
|
||||
rotation: [
|
||||
0.38231920253318413, 0.04029905920751535, -0.01669241687462921,
|
||||
0.9230002039112792,
|
||||
],
|
||||
__meta: [
|
||||
{
|
||||
sourceRange: [138, 166],
|
||||
pathToNode: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'extrudeGroup',
|
||||
value: [
|
||||
{
|
||||
type: 'extrudePlane',
|
||||
position: [
|
||||
0.43055783927228125, 5.453687003425103, 4.311246666755821,
|
||||
],
|
||||
rotation: [
|
||||
0.5307054034531232, -0.4972416536396126, 0.3641462373475848,
|
||||
-0.5818075544860157,
|
||||
],
|
||||
__geoMeta: {
|
||||
geo: 'PlaneGeometry',
|
||||
sourceRange: [264, 280],
|
||||
pathToNode: [],
|
||||
},
|
||||
name: 'p',
|
||||
},
|
||||
{
|
||||
type: 'extrudePlane',
|
||||
position: [
|
||||
-0.3229447858093035, 3.7387011520000146, 2.6556327856208117,
|
||||
],
|
||||
rotation: [
|
||||
0.06000443169260189, 0.12863059446321826, 0.6408199244764428,
|
||||
-0.7544557394170275,
|
||||
],
|
||||
__geoMeta: {
|
||||
geo: 'PlaneGeometry',
|
||||
sourceRange: [283, 297],
|
||||
pathToNode: [],
|
||||
},
|
||||
},
|
||||
],
|
||||
height: 2,
|
||||
position: [0.14624915180581843, 3.5355339059327373, 4.540063765792454],
|
||||
rotation: [
|
||||
0.24844095888221532, -0.7523143130765927, 0.2910733573455524,
|
||||
-0.5362616571538269,
|
||||
],
|
||||
__meta: [
|
||||
{
|
||||
sourceRange: [334, 347],
|
||||
pathToNode: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
])
|
||||
})
|
||||
})
|
||||
|
||||
function removeGeo(arts: (SketchGroup | ExtrudeGroup)[]): any {
|
||||
|
@ -3,7 +3,10 @@ import {
|
||||
SphereGeometry,
|
||||
BufferGeometry,
|
||||
PlaneGeometry,
|
||||
Quaternion,
|
||||
Euler,
|
||||
} from 'three'
|
||||
import { Rotation, Position } from './executor'
|
||||
|
||||
export function baseGeo({ from }: { from: [number, number, number] }) {
|
||||
const baseSphere = new SphereGeometry(0.25)
|
||||
@ -99,9 +102,13 @@ export function extrudeGeo({
|
||||
from: [number, number, number]
|
||||
to: [number, number, number]
|
||||
length: number
|
||||
}): BufferGeometry {
|
||||
}): {
|
||||
geo: BufferGeometry
|
||||
position: Position
|
||||
rotation: Rotation
|
||||
} {
|
||||
const {
|
||||
// centre,
|
||||
centre,
|
||||
Hypotenuse: Hypotenuse3d,
|
||||
ry,
|
||||
rz,
|
||||
@ -116,5 +123,13 @@ export function extrudeGeo({
|
||||
face.rotateZ(rz)
|
||||
face.translate(to[0], to[1], to[2])
|
||||
|
||||
return face
|
||||
const quat = new Quaternion()
|
||||
const euler = new Euler(-Math.PI / 2, ry, rz * sign, 'XYZ')
|
||||
quat.setFromEuler(euler)
|
||||
|
||||
return {
|
||||
geo: face,
|
||||
position: [centre[0], centre[1], centre[2]],
|
||||
rotation: quat.toArray() as Rotation,
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ import {
|
||||
ObjectExpression,
|
||||
MemberExpression,
|
||||
Identifier,
|
||||
CallExpression,
|
||||
} from './abstractSyntaxTree'
|
||||
import { sketchFns } from './sketch'
|
||||
import { BufferGeometry } from 'three'
|
||||
@ -71,6 +72,7 @@ interface ExtrudePlane {
|
||||
type: 'extrudePlane'
|
||||
position: Position
|
||||
rotation: Rotation
|
||||
name?: string
|
||||
}
|
||||
|
||||
export type ExtrudeSurface = GeoMeta &
|
||||
@ -272,13 +274,19 @@ export const executor = (
|
||||
__meta,
|
||||
}
|
||||
} else if (declaration.init.type === 'CallExpression') {
|
||||
// TODO: use executeCallExpression here instead
|
||||
const functionName = declaration.init.callee.name
|
||||
const fnArgs = declaration.init.arguments.map((arg) => {
|
||||
if (arg.type === 'Literal') {
|
||||
return arg.value
|
||||
} else if (arg.type === 'Identifier') {
|
||||
return _programMemory.root[arg.name].value
|
||||
} else if (arg.type === 'ObjectExpression') {
|
||||
return executeObjectExpression(_programMemory, arg)
|
||||
}
|
||||
throw new Error(
|
||||
`Unexpected argument type ${arg.type} in function call`
|
||||
)
|
||||
})
|
||||
if (
|
||||
'lineTo' === functionName ||
|
||||
@ -331,7 +339,10 @@ export const executor = (
|
||||
sketchVal as any // todo memory redo
|
||||
)
|
||||
_programMemory.root[variableName] = result as any // todo memory redo
|
||||
} else if (functionName === 'translate') {
|
||||
} else if (
|
||||
functionName === 'translate' ||
|
||||
functionName === 'transform'
|
||||
) {
|
||||
const sketch = declaration.init.arguments[1]
|
||||
if (sketch.type !== 'Identifier')
|
||||
throw new Error('rx must be called with an identifier')
|
||||
@ -343,6 +354,22 @@ export const executor = (
|
||||
sketchVal as any // todo memory redo
|
||||
)
|
||||
_programMemory.root[variableName] = result as any // todo memory redo
|
||||
} else if (functionName === 'getExtrudeWallTransform') {
|
||||
const extrude = declaration.init.arguments[1]
|
||||
if (extrude.type !== 'Identifier')
|
||||
throw new Error('rx must be called with an identifier')
|
||||
const sketchVal = _programMemory.root[extrude.name]
|
||||
const value = sketchFns[functionName](
|
||||
_programMemory,
|
||||
[declaration.start, declaration.end],
|
||||
fnArgs[0],
|
||||
sketchVal as any // todo memory redo
|
||||
)
|
||||
_programMemory.root[variableName] = {
|
||||
type: 'userVal',
|
||||
value,
|
||||
__meta,
|
||||
}
|
||||
} else {
|
||||
_programMemory.root[variableName] = {
|
||||
type: 'userVal',
|
||||
@ -472,85 +499,16 @@ function executePipeBody(
|
||||
[...previousResults, result]
|
||||
)
|
||||
} else if (expression.type === 'CallExpression') {
|
||||
const functionName = expression.callee.name
|
||||
const fnArgs = expression.arguments.map((arg) => {
|
||||
if (arg.type === 'Literal') {
|
||||
return arg.value
|
||||
} else if (arg.type === 'Identifier') {
|
||||
return programMemory.root[arg.name]
|
||||
} else if (arg.type === 'PipeSubstitution') {
|
||||
return previousResults[expressionIndex - 1]
|
||||
} else if (arg.type === 'ArrayExpression') {
|
||||
return arg.elements.map((el) => {
|
||||
if (el.type === 'Literal') {
|
||||
return el.value
|
||||
} else if (el.type === 'Identifier') {
|
||||
return programMemory.root[el.name]
|
||||
} else if (el.type === 'BinaryExpression') {
|
||||
return getBinaryExpressionResult(el, programMemory)
|
||||
}
|
||||
throw new Error('Invalid argument type')
|
||||
})
|
||||
}
|
||||
throw new Error('Invalid argument type')
|
||||
})
|
||||
if (
|
||||
'rx' === functionName ||
|
||||
'ry' === functionName ||
|
||||
'rz' === functionName
|
||||
) {
|
||||
const result = sketchFns[functionName](
|
||||
programMemory,
|
||||
[expression.start, expression.end],
|
||||
fnArgs[0],
|
||||
fnArgs[1]
|
||||
)
|
||||
return executePipeBody(
|
||||
body,
|
||||
return executeCallExpression(
|
||||
programMemory,
|
||||
expression,
|
||||
previousPathToNode,
|
||||
expressionIndex + 1,
|
||||
[...previousResults, result]
|
||||
)
|
||||
}
|
||||
if (functionName === 'extrude') {
|
||||
const result = sketchFns[functionName](
|
||||
programMemory,
|
||||
'yo',
|
||||
[expression.start, expression.end],
|
||||
fnArgs[0],
|
||||
fnArgs[1]
|
||||
)
|
||||
return executePipeBody(
|
||||
{
|
||||
isInPipe: true,
|
||||
previousResults,
|
||||
expressionIndex,
|
||||
body,
|
||||
programMemory,
|
||||
previousPathToNode,
|
||||
expressionIndex + 1,
|
||||
[...previousResults, result]
|
||||
)
|
||||
}
|
||||
if (functionName === 'translate') {
|
||||
const result = sketchFns[functionName](
|
||||
programMemory,
|
||||
[expression.start, expression.end],
|
||||
fnArgs[0],
|
||||
fnArgs[1]
|
||||
)
|
||||
return executePipeBody(
|
||||
body,
|
||||
programMemory,
|
||||
previousPathToNode,
|
||||
expressionIndex + 1,
|
||||
[...previousResults, result]
|
||||
)
|
||||
}
|
||||
const result = programMemory.root[functionName].value(...fnArgs)
|
||||
return executePipeBody(
|
||||
body,
|
||||
programMemory,
|
||||
previousPathToNode,
|
||||
expressionIndex + 1,
|
||||
[...previousResults, result]
|
||||
)
|
||||
} else if (expression.type === 'SketchExpression') {
|
||||
const sketchBody = expression.body
|
||||
@ -613,6 +571,19 @@ function executeObjectExpression(
|
||||
_programMemory,
|
||||
property.value
|
||||
)
|
||||
} else if (property.value.type === 'ArrayExpression') {
|
||||
obj[property.key.name] = property.value.elements.map((el) => {
|
||||
if (el.type === 'Literal') {
|
||||
return el.value
|
||||
} else if (el.type === 'Identifier') {
|
||||
return _programMemory.root[el.name].value
|
||||
} else if (el.type === 'BinaryExpression') {
|
||||
return getBinaryExpressionResult(el, _programMemory)
|
||||
} else if (el.type === 'ObjectExpression') {
|
||||
return executeObjectExpression(_programMemory, el)
|
||||
}
|
||||
throw new Error('Invalid argument type')
|
||||
})
|
||||
} else {
|
||||
throw new Error(
|
||||
`Unexpected property type ${property.value.type} in object expression`
|
||||
@ -626,3 +597,131 @@ function executeObjectExpression(
|
||||
})
|
||||
return obj
|
||||
}
|
||||
|
||||
function executeCallExpression(
|
||||
programMemory: ProgramMemory,
|
||||
expression: CallExpression,
|
||||
previousPathToNode: PathToNode = [],
|
||||
pipeInfo: {
|
||||
isInPipe: boolean
|
||||
previousResults: any[]
|
||||
expressionIndex: number
|
||||
body: PipeExpression['body']
|
||||
} = {
|
||||
isInPipe: false,
|
||||
previousResults: [],
|
||||
expressionIndex: 0,
|
||||
body: [],
|
||||
}
|
||||
) {
|
||||
const { isInPipe, previousResults, expressionIndex, body } = pipeInfo
|
||||
const functionName = expression.callee.name
|
||||
const fnArgs = expression.arguments.map((arg) => {
|
||||
if (arg.type === 'Literal') {
|
||||
return arg.value
|
||||
} else if (arg.type === 'Identifier') {
|
||||
const temp = programMemory.root[arg.name]
|
||||
return temp?.type === 'userVal' ? temp.value : temp
|
||||
} else if (arg.type === 'PipeSubstitution') {
|
||||
return previousResults[expressionIndex - 1]
|
||||
} else if (arg.type === 'ArrayExpression') {
|
||||
return arg.elements.map((el) => {
|
||||
if (el.type === 'Literal') {
|
||||
return el.value
|
||||
} else if (el.type === 'Identifier') {
|
||||
return programMemory.root[el.name]
|
||||
} else if (el.type === 'BinaryExpression') {
|
||||
return getBinaryExpressionResult(el, programMemory)
|
||||
}
|
||||
throw new Error('Invalid argument type')
|
||||
})
|
||||
} else if (arg.type === 'CallExpression') {
|
||||
const result: any = executeCallExpression(
|
||||
programMemory,
|
||||
arg,
|
||||
previousPathToNode
|
||||
)
|
||||
return result
|
||||
}
|
||||
throw new Error('Invalid argument type')
|
||||
})
|
||||
if ('rx' === functionName || 'ry' === functionName || 'rz' === functionName) {
|
||||
const result = sketchFns[functionName](
|
||||
programMemory,
|
||||
[expression.start, expression.end],
|
||||
fnArgs[0],
|
||||
fnArgs[1]
|
||||
)
|
||||
return isInPipe
|
||||
? executePipeBody(
|
||||
body,
|
||||
programMemory,
|
||||
previousPathToNode,
|
||||
expressionIndex + 1,
|
||||
[...previousResults, result]
|
||||
)
|
||||
: result
|
||||
}
|
||||
if (functionName === 'extrude') {
|
||||
const result = sketchFns[functionName](
|
||||
programMemory,
|
||||
'yo',
|
||||
[expression.start, expression.end],
|
||||
fnArgs[0],
|
||||
fnArgs[1]
|
||||
)
|
||||
return isInPipe
|
||||
? executePipeBody(
|
||||
body,
|
||||
programMemory,
|
||||
previousPathToNode,
|
||||
expressionIndex + 1,
|
||||
[...previousResults, result]
|
||||
)
|
||||
: result
|
||||
}
|
||||
if (functionName === 'translate' || functionName === 'transform') {
|
||||
const result = sketchFns[functionName](
|
||||
programMemory,
|
||||
[expression.start, expression.end],
|
||||
fnArgs[0],
|
||||
fnArgs[1]
|
||||
)
|
||||
return isInPipe
|
||||
? executePipeBody(
|
||||
body,
|
||||
programMemory,
|
||||
previousPathToNode,
|
||||
expressionIndex + 1,
|
||||
[...previousResults, result]
|
||||
)
|
||||
: result
|
||||
}
|
||||
if (functionName === 'getExtrudeWallTransform') {
|
||||
const result = sketchFns[functionName](
|
||||
programMemory,
|
||||
[expression.start, expression.end],
|
||||
fnArgs[0],
|
||||
fnArgs[1]
|
||||
)
|
||||
return isInPipe
|
||||
? executePipeBody(
|
||||
body,
|
||||
programMemory,
|
||||
previousPathToNode,
|
||||
expressionIndex + 1,
|
||||
[...previousResults, result]
|
||||
)
|
||||
: result
|
||||
}
|
||||
const result = programMemory.root[functionName].value(...fnArgs)
|
||||
return isInPipe
|
||||
? executePipeBody(
|
||||
body,
|
||||
programMemory,
|
||||
previousPathToNode,
|
||||
expressionIndex + 1,
|
||||
[...previousResults, result]
|
||||
)
|
||||
: result
|
||||
}
|
||||
|
@ -5,6 +5,8 @@ import {
|
||||
ExtrudeGroup,
|
||||
SourceRange,
|
||||
ExtrudeSurface,
|
||||
Position,
|
||||
Rotation,
|
||||
} from './executor'
|
||||
import { lineGeo, extrudeGeo } from './engine'
|
||||
import { Quaternion, Vector3 } from 'three'
|
||||
@ -179,21 +181,40 @@ export const sketchFns = {
|
||||
from = lastPoint.to
|
||||
}
|
||||
const to = line.to
|
||||
const geo = extrudeGeo({
|
||||
const {
|
||||
geo,
|
||||
position: facePosition,
|
||||
rotation: faceRotation,
|
||||
} = extrudeGeo({
|
||||
from: [from[0], from[1], 0],
|
||||
to: [to[0], to[1], 0],
|
||||
length,
|
||||
})
|
||||
extrudeSurfaces.push({
|
||||
const groupQuaternion = new Quaternion(...rotation)
|
||||
const currentWallQuat = new Quaternion(...faceRotation)
|
||||
const unifiedQuit = new Quaternion().multiplyQuaternions(
|
||||
currentWallQuat,
|
||||
groupQuaternion.clone().invert()
|
||||
)
|
||||
|
||||
const facePositionVector = new Vector3(...facePosition)
|
||||
facePositionVector.applyQuaternion(groupQuaternion.clone())
|
||||
const unifiedPosition = new Vector3().addVectors(
|
||||
facePositionVector,
|
||||
new Vector3(...position)
|
||||
)
|
||||
const surface: ExtrudeSurface = {
|
||||
type: 'extrudePlane',
|
||||
position, // todo should come from extrudeGeo
|
||||
rotation, // todo should come from extrudeGeo
|
||||
position: unifiedPosition.toArray() as Position,
|
||||
rotation: unifiedQuit.toArray() as Rotation,
|
||||
__geoMeta: {
|
||||
geo,
|
||||
sourceRange: line.__geoMeta.sourceRange,
|
||||
pathToNode: line.__geoMeta.pathToNode,
|
||||
},
|
||||
})
|
||||
}
|
||||
line.name && (surface.name = line.name)
|
||||
extrudeSurfaces.push(surface)
|
||||
}
|
||||
})
|
||||
return {
|
||||
@ -211,6 +232,8 @@ export const sketchFns = {
|
||||
}
|
||||
},
|
||||
translate,
|
||||
transform,
|
||||
getExtrudeWallTransform,
|
||||
}
|
||||
|
||||
function rotateOnAxis<T extends SketchGroup | ExtrudeGroup>(
|
||||
@ -258,7 +281,7 @@ function translate<T extends SketchGroup | ExtrudeGroup>(
|
||||
const newPosition = oldPosition.add(new Vector3(...vec3))
|
||||
return {
|
||||
...sketch,
|
||||
position: [newPosition.x, newPosition.y, newPosition.z],
|
||||
position: newPosition.toArray(),
|
||||
__meta: [
|
||||
...sketch.__meta,
|
||||
{
|
||||
@ -268,3 +291,52 @@ function translate<T extends SketchGroup | ExtrudeGroup>(
|
||||
],
|
||||
}
|
||||
}
|
||||
|
||||
function transform<T extends SketchGroup | ExtrudeGroup>(
|
||||
programMemory: ProgramMemory,
|
||||
sourceRange: SourceRange,
|
||||
transformInfo: {
|
||||
position: Position
|
||||
quaternion: Rotation
|
||||
},
|
||||
sketch: T
|
||||
): T {
|
||||
const quaternionToApply = new Quaternion(...transformInfo.quaternion)
|
||||
const newQuaternion = new Quaternion(...sketch.rotation).multiply(
|
||||
quaternionToApply.invert()
|
||||
)
|
||||
|
||||
const oldPosition = new Vector3(...sketch.position)
|
||||
const newPosition = oldPosition
|
||||
.applyQuaternion(quaternionToApply)
|
||||
.add(new Vector3(...transformInfo.position))
|
||||
return {
|
||||
...sketch,
|
||||
position: newPosition.toArray(),
|
||||
rotation: newQuaternion.toArray(),
|
||||
__meta: [
|
||||
...sketch.__meta,
|
||||
{
|
||||
sourceRange,
|
||||
pathToNode: [], // TODO
|
||||
},
|
||||
],
|
||||
}
|
||||
}
|
||||
|
||||
function getExtrudeWallTransform(
|
||||
programMemory: ProgramMemory,
|
||||
sourceRange: SourceRange,
|
||||
pathName: string,
|
||||
extrudeGroup: ExtrudeGroup
|
||||
): {
|
||||
position: Position
|
||||
quaternion: Rotation
|
||||
} {
|
||||
const path = extrudeGroup.value.find((path) => path.name === pathName)
|
||||
if (!path) throw new Error(`Could not find path with name ${pathName}`)
|
||||
return {
|
||||
position: path.position,
|
||||
quaternion: path.rotation,
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user