diff --git a/src/components/RenderViewerArtifacts.tsx b/src/components/RenderViewerArtifacts.tsx
index 4d427c3df..a639be787 100644
--- a/src/components/RenderViewerArtifacts.tsx
+++ b/src/components/RenderViewerArtifacts.tsx
@@ -240,6 +240,14 @@ function RenderViewerArtifact({
if (artifact.type === 'sketchGroup') {
return (
<>
+ {artifact.start && (
+
+ )}
{artifact.value.map((geoInfo, key) => (
{geoInfo.__geoMeta.geos.map((meta, i) => {
- if (meta.type === 'line') {
+ if (meta.type === 'line')
return (
)
- }
- if (meta.type === 'lineEnd') {
+ if (meta.type === 'lineEnd')
return (
)
- }
+ if (meta.type === 'sketchBase')
+ return (
+
+ )
})}
>
)
diff --git a/src/components/Toolbar/SetHorzDistance.tsx b/src/components/Toolbar/SetHorzDistance.tsx
index af4d659a2..089e0221e 100644
--- a/src/components/Toolbar/SetHorzDistance.tsx
+++ b/src/components/Toolbar/SetHorzDistance.tsx
@@ -60,7 +60,10 @@ export const SetHorzDistance = ({
const isAllTooltips = nodes.every(
(node) =>
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(
diff --git a/src/index.css b/src/index.css
index 799de70de..2f1e8afda 100644
--- a/src/index.css
+++ b/src/index.css
@@ -25,5 +25,5 @@ code {
#code-mirror-override .cm-cursor {
display: block;
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%);
}
diff --git a/src/lang/artifact.test.ts b/src/lang/artifact.test.ts
index 199e67e01..f54ad6969 100644
--- a/src/lang/artifact.test.ts
+++ b/src/lang/artifact.test.ts
@@ -21,7 +21,16 @@ show(mySketch001)`
expect(artifactsWithoutGeos).toEqual([
{
type: 'sketchGroup',
- start: [0, 0],
+ start: {
+ type: 'base',
+ to: [0, 0],
+ from: [0, 0],
+ __geoMeta: {
+ sourceRange: [21, 42],
+ pathToNode: [],
+ geos: ['sketchBase'],
+ },
+ },
value: [
{
type: 'toPoint',
@@ -275,6 +284,15 @@ function removeGeo(arts: (SketchGroup | ExtrudeGroup)[]): any {
}
return {
...art,
+ start: art.start
+ ? {
+ ...art.start,
+ __geoMeta: {
+ ...art.start.__geoMeta,
+ geos: art.start.__geoMeta.geos.map((g) => g.type),
+ },
+ }
+ : {},
value: art.value.map((v) => ({
...v,
__geoMeta: {
diff --git a/src/lang/engine.tsx b/src/lang/engine.tsx
index 3037783fb..a8916dae0 100644
--- a/src/lang/engine.tsx
+++ b/src/lang/engine.tsx
@@ -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 {
line: BufferGeometry
tip: BufferGeometry
diff --git a/src/lang/executor.test.ts b/src/lang/executor.test.ts
index ee8364a7f..ef7ba0388 100644
--- a/src/lang/executor.test.ts
+++ b/src/lang/executor.test.ts
@@ -166,7 +166,16 @@ show(mySketch)
const striptVersion = removeGeoFromSketch(root.mySk1 as SketchGroup)
expect(striptVersion).toEqual({
type: 'sketchGroup',
- start: [0, 0],
+ start: {
+ type: 'base',
+ to: [0, 0],
+ from: [0, 0],
+ __geoMeta: {
+ sourceRange: [14, 34],
+ pathToNode: [],
+ geos: ['sketchBase'],
+ },
+ },
value: [
{
type: 'toPoint',
@@ -420,6 +429,15 @@ function exe(
function removeGeoFromSketch(sketch: SketchGroup): SketchGroup {
return {
...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),
}
}
diff --git a/src/lang/executor.ts b/src/lang/executor.ts
index 24f01e999..aaf862bd6 100644
--- a/src/lang/executor.ts
+++ b/src/lang/executor.ts
@@ -30,7 +30,7 @@ interface BasePath {
__geoMeta: {
geos: {
geo: BufferGeometry
- type: 'line' | 'lineEnd'
+ type: 'line' | 'lineEnd' | 'sketchBase'
}[]
sourceRange: SourceRange
pathToNode: PathToNode
@@ -41,6 +41,10 @@ export interface ToPoint extends BasePath {
type: 'toPoint'
}
+export interface Base extends BasePath {
+ type: 'base'
+}
+
export interface HorizontalLineTo extends BasePath {
type: 'horizontalLineTo'
x: number
@@ -61,12 +65,12 @@ interface GeoMeta {
}
}
-export type Path = ToPoint | HorizontalLineTo | AngledLineTo
+export type Path = ToPoint | HorizontalLineTo | AngledLineTo | Base
export interface SketchGroup {
type: 'sketchGroup'
value: Path[]
- start?: Path['from']
+ start?: Base
position: Position
rotation: Rotation
__meta: Metadata[]
diff --git a/src/lang/std/sketch.ts b/src/lang/std/sketch.ts
index 9051b6931..247bc0785 100644
--- a/src/lang/std/sketch.ts
+++ b/src/lang/std/sketch.ts
@@ -18,7 +18,7 @@ import {
getNodeFromPathCurry,
getNodePathFromSourceRange,
} from '../queryAst'
-import { lineGeo } from '../engine'
+import { lineGeo, sketchBaseGeo } from '../engine'
import { GuiModes, toolTips, TooTip } from '../../useStore'
import { getLastIndex } from '../modifyAst'
@@ -46,7 +46,7 @@ export type Coords2d = [number, number]
export function getCoordsFromPaths(skGroup: SketchGroup, index = 0): Coords2d {
const currentPath = skGroup?.value?.[index]
if (!currentPath && skGroup?.start) {
- return skGroup.start
+ return skGroup.start.to
} else if (!currentPath) {
return [0, 0]
}
@@ -83,6 +83,8 @@ export function createFirstArg(
return createObjectExpression({ length: val, tag })
if (['xLineTo', 'yLineTo'].includes(sketchFn))
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')
}
@@ -895,18 +897,22 @@ export const angledLineToX: SketchLineHelper = {
)
const angle = createLiteral(roundOff(getAngle(from, to), 0))
const xArg = createLiteral(roundOff(to[0], 2))
- const newLine = createCallback
- ? createCallback([angle, xArg]).callExp
- : createCallExpression('angledLineToX', [
- createArrayExpression([angle, xArg]),
- createPipeSubstitution(),
- ])
- const callIndex = getLastIndex(pathToNode)
- if (replaceExisting) {
- pipe.body[callIndex] = newLine
- } else {
- pipe.body = [...pipe.body, newLine]
+ if (replaceExisting && createCallback) {
+ const { callExp, valueUsedInTransform } = createCallback([angle, xArg])
+ const callIndex = getLastIndex(pathToNode)
+ pipe.body[callIndex] = callExp
+ return {
+ modifiedAst: _node,
+ pathToNode,
+ valueUsedInTransform,
+ }
}
+
+ const callExp = createCallExpression('angledLineToX', [
+ createArrayExpression([angle, xArg]),
+ createPipeSubstitution(),
+ ])
+ pipe.body = [...pipe.body, callExp]
return {
modifiedAst: _node,
pathToNode,
@@ -1288,14 +1294,20 @@ export const startSketchAt: InternalFn = (
}
): SketchGroup => {
const to = 'to' in data ? data.to : data
+ const geo = sketchBaseGeo({ to: [...to, 0] })
const currentPath: Path = {
- type: 'toPoint',
+ type: 'base',
to,
from: to,
__geoMeta: {
sourceRange,
pathToNode: [], // TODO
- geos: [],
+ geos: [
+ {
+ type: 'sketchBase',
+ geo: geo.base,
+ },
+ ],
},
}
if ('tag' in data) {
@@ -1303,7 +1315,7 @@ export const startSketchAt: InternalFn = (
}
return {
type: 'sketchGroup',
- start: to,
+ start: currentPath,
value: [],
position: [0, 0, 0],
rotation: [0, 0, 0, 1],
@@ -1393,7 +1405,7 @@ function getFirstArgValuesForXYLineFns(callExpression: CallExpression): {
return { val: firstArg }
}
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(
callExpression?.callee?.name
)
@@ -1430,5 +1442,8 @@ export function getFirstArg(callExp: CallExpression): {
if (['xLine', 'yLine', 'xLineTo', 'yLineTo'].includes(name)) {
return getFirstArgValuesForXYLineFns(callExp)
}
+ if (['startSketchAt'].includes(name)) {
+ return getFirstArgValuesForXYLineFns(callExp)
+ }
throw new Error('unexpected call expression')
}
diff --git a/src/lang/std/sketchConstraints.ts b/src/lang/std/sketchConstraints.ts
index 759d752c2..5ed5e8aae 100644
--- a/src/lang/std/sketchConstraints.ts
+++ b/src/lang/std/sketchConstraints.ts
@@ -35,7 +35,10 @@ export const segLen: InternalFn = (
function segEndFactory(which: 'x' | 'y'): InternalFn {
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
if (!line) return 0
return which === 'x' ? line.to[0] : line.to[1]