Give startSketchAt a 3D artifact (#65)
* Give startSketchAt a 3D artifact * fix tests * refactor start geo to be in the start property * small tweak
This commit is contained in:
@ -240,6 +240,14 @@ function RenderViewerArtifact({
|
|||||||
if (artifact.type === 'sketchGroup') {
|
if (artifact.type === 'sketchGroup') {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
{artifact.start && (
|
||||||
|
<PathRender
|
||||||
|
geoInfo={artifact.start}
|
||||||
|
forceHighlight={false}
|
||||||
|
rotation={artifact.rotation}
|
||||||
|
position={artifact.position}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
{artifact.value.map((geoInfo, key) => (
|
{artifact.value.map((geoInfo, key) => (
|
||||||
<PathRender
|
<PathRender
|
||||||
geoInfo={geoInfo}
|
geoInfo={geoInfo}
|
||||||
@ -356,7 +364,7 @@ function PathRender({
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{geoInfo.__geoMeta.geos.map((meta, i) => {
|
{geoInfo.__geoMeta.geos.map((meta, i) => {
|
||||||
if (meta.type === 'line') {
|
if (meta.type === 'line')
|
||||||
return (
|
return (
|
||||||
<LineRender
|
<LineRender
|
||||||
key={i}
|
key={i}
|
||||||
@ -367,8 +375,7 @@ function PathRender({
|
|||||||
position={position}
|
position={position}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
if (meta.type === 'lineEnd')
|
||||||
if (meta.type === 'lineEnd') {
|
|
||||||
return (
|
return (
|
||||||
<MovingSphere
|
<MovingSphere
|
||||||
key={i}
|
key={i}
|
||||||
@ -380,7 +387,17 @@ function PathRender({
|
|||||||
position={position}
|
position={position}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
if (meta.type === 'sketchBase')
|
||||||
|
return (
|
||||||
|
<LineRender
|
||||||
|
key={i}
|
||||||
|
geo={meta.geo}
|
||||||
|
sourceRange={geoInfo.__geoMeta.sourceRange}
|
||||||
|
forceHighlight={forceHighlight || editorCursor}
|
||||||
|
rotation={rotation}
|
||||||
|
position={position}
|
||||||
|
/>
|
||||||
|
)
|
||||||
})}
|
})}
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
|
@ -60,7 +60,10 @@ export const SetHorzDistance = ({
|
|||||||
const isAllTooltips = nodes.every(
|
const isAllTooltips = nodes.every(
|
||||||
(node) =>
|
(node) =>
|
||||||
node?.type === 'CallExpression' &&
|
node?.type === 'CallExpression' &&
|
||||||
toolTips.includes(node.callee.name as any)
|
[
|
||||||
|
...toolTips,
|
||||||
|
'startSketchAt', // TODO probably a better place for this to live
|
||||||
|
].includes(node.callee.name as any)
|
||||||
)
|
)
|
||||||
|
|
||||||
const theTransforms = getTransformInfos(
|
const theTransforms = getTransformInfos(
|
||||||
|
@ -25,5 +25,5 @@ code {
|
|||||||
#code-mirror-override .cm-cursor {
|
#code-mirror-override .cm-cursor {
|
||||||
display: block;
|
display: block;
|
||||||
width: 200px;
|
width: 200px;
|
||||||
background: linear-gradient(to right, rgb(0, 55, 94) 0%, #0084e2ff 2%, #0084e255 5%, transparent 100%);
|
background: linear-gradient(to right, rgb(0, 55, 94) 0%, #0084e2ff 2%, #0084e255 5%, transparent 100%);
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,16 @@ show(mySketch001)`
|
|||||||
expect(artifactsWithoutGeos).toEqual([
|
expect(artifactsWithoutGeos).toEqual([
|
||||||
{
|
{
|
||||||
type: 'sketchGroup',
|
type: 'sketchGroup',
|
||||||
start: [0, 0],
|
start: {
|
||||||
|
type: 'base',
|
||||||
|
to: [0, 0],
|
||||||
|
from: [0, 0],
|
||||||
|
__geoMeta: {
|
||||||
|
sourceRange: [21, 42],
|
||||||
|
pathToNode: [],
|
||||||
|
geos: ['sketchBase'],
|
||||||
|
},
|
||||||
|
},
|
||||||
value: [
|
value: [
|
||||||
{
|
{
|
||||||
type: 'toPoint',
|
type: 'toPoint',
|
||||||
@ -275,6 +284,15 @@ function removeGeo(arts: (SketchGroup | ExtrudeGroup)[]): any {
|
|||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
...art,
|
...art,
|
||||||
|
start: art.start
|
||||||
|
? {
|
||||||
|
...art.start,
|
||||||
|
__geoMeta: {
|
||||||
|
...art.start.__geoMeta,
|
||||||
|
geos: art.start.__geoMeta.geos.map((g) => g.type),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
: {},
|
||||||
value: art.value.map((v) => ({
|
value: art.value.map((v) => ({
|
||||||
...v,
|
...v,
|
||||||
__geoMeta: {
|
__geoMeta: {
|
||||||
|
@ -88,6 +88,12 @@ export function lineGeo({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function sketchBaseGeo({ to }: { to: [number, number, number] }): {
|
||||||
|
base: BufferGeometry
|
||||||
|
} {
|
||||||
|
return { base: new SphereGeometry(0.25).translate(to[0], to[1], to[2]) }
|
||||||
|
}
|
||||||
|
|
||||||
export interface extrudeWallGeo {
|
export interface extrudeWallGeo {
|
||||||
line: BufferGeometry
|
line: BufferGeometry
|
||||||
tip: BufferGeometry
|
tip: BufferGeometry
|
||||||
|
@ -166,7 +166,16 @@ show(mySketch)
|
|||||||
const striptVersion = removeGeoFromSketch(root.mySk1 as SketchGroup)
|
const striptVersion = removeGeoFromSketch(root.mySk1 as SketchGroup)
|
||||||
expect(striptVersion).toEqual({
|
expect(striptVersion).toEqual({
|
||||||
type: 'sketchGroup',
|
type: 'sketchGroup',
|
||||||
start: [0, 0],
|
start: {
|
||||||
|
type: 'base',
|
||||||
|
to: [0, 0],
|
||||||
|
from: [0, 0],
|
||||||
|
__geoMeta: {
|
||||||
|
sourceRange: [14, 34],
|
||||||
|
pathToNode: [],
|
||||||
|
geos: ['sketchBase'],
|
||||||
|
},
|
||||||
|
},
|
||||||
value: [
|
value: [
|
||||||
{
|
{
|
||||||
type: 'toPoint',
|
type: 'toPoint',
|
||||||
@ -420,6 +429,15 @@ function exe(
|
|||||||
function removeGeoFromSketch(sketch: SketchGroup): SketchGroup {
|
function removeGeoFromSketch(sketch: SketchGroup): SketchGroup {
|
||||||
return {
|
return {
|
||||||
...sketch,
|
...sketch,
|
||||||
|
start: !sketch.start
|
||||||
|
? undefined
|
||||||
|
: {
|
||||||
|
...sketch.start,
|
||||||
|
__geoMeta: {
|
||||||
|
...sketch.start.__geoMeta,
|
||||||
|
geos: sketch.start.__geoMeta.geos.map((geo) => geo.type as any),
|
||||||
|
},
|
||||||
|
},
|
||||||
value: removeGeoFromPaths(sketch.value),
|
value: removeGeoFromPaths(sketch.value),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,7 @@ interface BasePath {
|
|||||||
__geoMeta: {
|
__geoMeta: {
|
||||||
geos: {
|
geos: {
|
||||||
geo: BufferGeometry
|
geo: BufferGeometry
|
||||||
type: 'line' | 'lineEnd'
|
type: 'line' | 'lineEnd' | 'sketchBase'
|
||||||
}[]
|
}[]
|
||||||
sourceRange: SourceRange
|
sourceRange: SourceRange
|
||||||
pathToNode: PathToNode
|
pathToNode: PathToNode
|
||||||
@ -41,6 +41,10 @@ export interface ToPoint extends BasePath {
|
|||||||
type: 'toPoint'
|
type: 'toPoint'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface Base extends BasePath {
|
||||||
|
type: 'base'
|
||||||
|
}
|
||||||
|
|
||||||
export interface HorizontalLineTo extends BasePath {
|
export interface HorizontalLineTo extends BasePath {
|
||||||
type: 'horizontalLineTo'
|
type: 'horizontalLineTo'
|
||||||
x: number
|
x: number
|
||||||
@ -61,12 +65,12 @@ interface GeoMeta {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export type Path = ToPoint | HorizontalLineTo | AngledLineTo
|
export type Path = ToPoint | HorizontalLineTo | AngledLineTo | Base
|
||||||
|
|
||||||
export interface SketchGroup {
|
export interface SketchGroup {
|
||||||
type: 'sketchGroup'
|
type: 'sketchGroup'
|
||||||
value: Path[]
|
value: Path[]
|
||||||
start?: Path['from']
|
start?: Base
|
||||||
position: Position
|
position: Position
|
||||||
rotation: Rotation
|
rotation: Rotation
|
||||||
__meta: Metadata[]
|
__meta: Metadata[]
|
||||||
|
@ -18,7 +18,7 @@ import {
|
|||||||
getNodeFromPathCurry,
|
getNodeFromPathCurry,
|
||||||
getNodePathFromSourceRange,
|
getNodePathFromSourceRange,
|
||||||
} from '../queryAst'
|
} from '../queryAst'
|
||||||
import { lineGeo } from '../engine'
|
import { lineGeo, sketchBaseGeo } from '../engine'
|
||||||
import { GuiModes, toolTips, TooTip } from '../../useStore'
|
import { GuiModes, toolTips, TooTip } from '../../useStore'
|
||||||
import { getLastIndex } from '../modifyAst'
|
import { getLastIndex } from '../modifyAst'
|
||||||
|
|
||||||
@ -46,7 +46,7 @@ export type Coords2d = [number, number]
|
|||||||
export function getCoordsFromPaths(skGroup: SketchGroup, index = 0): Coords2d {
|
export function getCoordsFromPaths(skGroup: SketchGroup, index = 0): Coords2d {
|
||||||
const currentPath = skGroup?.value?.[index]
|
const currentPath = skGroup?.value?.[index]
|
||||||
if (!currentPath && skGroup?.start) {
|
if (!currentPath && skGroup?.start) {
|
||||||
return skGroup.start
|
return skGroup.start.to
|
||||||
} else if (!currentPath) {
|
} else if (!currentPath) {
|
||||||
return [0, 0]
|
return [0, 0]
|
||||||
}
|
}
|
||||||
@ -83,6 +83,8 @@ export function createFirstArg(
|
|||||||
return createObjectExpression({ length: val, tag })
|
return createObjectExpression({ length: val, tag })
|
||||||
if (['xLineTo', 'yLineTo'].includes(sketchFn))
|
if (['xLineTo', 'yLineTo'].includes(sketchFn))
|
||||||
return createObjectExpression({ to: val, tag })
|
return createObjectExpression({ to: val, tag })
|
||||||
|
if (['startSketchAt'].includes(sketchFn))
|
||||||
|
return createObjectExpression({ to: val, tag })
|
||||||
}
|
}
|
||||||
throw new Error('all sketch line types should have been covered')
|
throw new Error('all sketch line types should have been covered')
|
||||||
}
|
}
|
||||||
@ -895,18 +897,22 @@ export const angledLineToX: SketchLineHelper = {
|
|||||||
)
|
)
|
||||||
const angle = createLiteral(roundOff(getAngle(from, to), 0))
|
const angle = createLiteral(roundOff(getAngle(from, to), 0))
|
||||||
const xArg = createLiteral(roundOff(to[0], 2))
|
const xArg = createLiteral(roundOff(to[0], 2))
|
||||||
const newLine = createCallback
|
if (replaceExisting && createCallback) {
|
||||||
? createCallback([angle, xArg]).callExp
|
const { callExp, valueUsedInTransform } = createCallback([angle, xArg])
|
||||||
: createCallExpression('angledLineToX', [
|
const callIndex = getLastIndex(pathToNode)
|
||||||
createArrayExpression([angle, xArg]),
|
pipe.body[callIndex] = callExp
|
||||||
createPipeSubstitution(),
|
return {
|
||||||
])
|
modifiedAst: _node,
|
||||||
const callIndex = getLastIndex(pathToNode)
|
pathToNode,
|
||||||
if (replaceExisting) {
|
valueUsedInTransform,
|
||||||
pipe.body[callIndex] = newLine
|
}
|
||||||
} else {
|
|
||||||
pipe.body = [...pipe.body, newLine]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const callExp = createCallExpression('angledLineToX', [
|
||||||
|
createArrayExpression([angle, xArg]),
|
||||||
|
createPipeSubstitution(),
|
||||||
|
])
|
||||||
|
pipe.body = [...pipe.body, callExp]
|
||||||
return {
|
return {
|
||||||
modifiedAst: _node,
|
modifiedAst: _node,
|
||||||
pathToNode,
|
pathToNode,
|
||||||
@ -1288,14 +1294,20 @@ export const startSketchAt: InternalFn = (
|
|||||||
}
|
}
|
||||||
): SketchGroup => {
|
): SketchGroup => {
|
||||||
const to = 'to' in data ? data.to : data
|
const to = 'to' in data ? data.to : data
|
||||||
|
const geo = sketchBaseGeo({ to: [...to, 0] })
|
||||||
const currentPath: Path = {
|
const currentPath: Path = {
|
||||||
type: 'toPoint',
|
type: 'base',
|
||||||
to,
|
to,
|
||||||
from: to,
|
from: to,
|
||||||
__geoMeta: {
|
__geoMeta: {
|
||||||
sourceRange,
|
sourceRange,
|
||||||
pathToNode: [], // TODO
|
pathToNode: [], // TODO
|
||||||
geos: [],
|
geos: [
|
||||||
|
{
|
||||||
|
type: 'sketchBase',
|
||||||
|
geo: geo.base,
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
if ('tag' in data) {
|
if ('tag' in data) {
|
||||||
@ -1303,7 +1315,7 @@ export const startSketchAt: InternalFn = (
|
|||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
type: 'sketchGroup',
|
type: 'sketchGroup',
|
||||||
start: to,
|
start: currentPath,
|
||||||
value: [],
|
value: [],
|
||||||
position: [0, 0, 0],
|
position: [0, 0, 0],
|
||||||
rotation: [0, 0, 0, 1],
|
rotation: [0, 0, 0, 1],
|
||||||
@ -1393,7 +1405,7 @@ function getFirstArgValuesForXYLineFns(callExpression: CallExpression): {
|
|||||||
return { val: firstArg }
|
return { val: firstArg }
|
||||||
}
|
}
|
||||||
const tag = firstArg.properties.find((p) => p.key.name === 'tag')?.value
|
const tag = firstArg.properties.find((p) => p.key.name === 'tag')?.value
|
||||||
const secondArgName = ['xLineTo', 'yLineTo'].includes(
|
const secondArgName = ['xLineTo', 'yLineTo', 'startSketchAt'].includes(
|
||||||
// const secondArgName = ['xLineTo', 'yLineTo', 'angledLineToX', 'angledLineToY'].includes(
|
// const secondArgName = ['xLineTo', 'yLineTo', 'angledLineToX', 'angledLineToY'].includes(
|
||||||
callExpression?.callee?.name
|
callExpression?.callee?.name
|
||||||
)
|
)
|
||||||
@ -1430,5 +1442,8 @@ export function getFirstArg(callExp: CallExpression): {
|
|||||||
if (['xLine', 'yLine', 'xLineTo', 'yLineTo'].includes(name)) {
|
if (['xLine', 'yLine', 'xLineTo', 'yLineTo'].includes(name)) {
|
||||||
return getFirstArgValuesForXYLineFns(callExp)
|
return getFirstArgValuesForXYLineFns(callExp)
|
||||||
}
|
}
|
||||||
|
if (['startSketchAt'].includes(name)) {
|
||||||
|
return getFirstArgValuesForXYLineFns(callExp)
|
||||||
|
}
|
||||||
throw new Error('unexpected call expression')
|
throw new Error('unexpected call expression')
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,10 @@ export const segLen: InternalFn = (
|
|||||||
|
|
||||||
function segEndFactory(which: 'x' | 'y'): InternalFn {
|
function segEndFactory(which: 'x' | 'y'): InternalFn {
|
||||||
return (_, segName: string, sketchGroup: SketchGroup): number => {
|
return (_, segName: string, sketchGroup: SketchGroup): number => {
|
||||||
const line = sketchGroup?.value.find((seg) => seg.name === segName)
|
const line =
|
||||||
|
sketchGroup.start?.name === segName
|
||||||
|
? sketchGroup.start
|
||||||
|
: sketchGroup?.value.find((seg) => seg.name === segName)
|
||||||
// maybe this should throw, but the language doesn't have a way to handle errors yet
|
// maybe this should throw, but the language doesn't have a way to handle errors yet
|
||||||
if (!line) return 0
|
if (!line) return 0
|
||||||
return which === 'x' ? line.to[0] : line.to[1]
|
return which === 'x' ? line.to[0] : line.to[1]
|
||||||
|
Reference in New Issue
Block a user