Internal fix: make expandPath
not assume path has associated sweep (#4386)
* Add a test that shows current error within `expandPath` * Make `expandPath` not assume there is an associated sweep artifact * Look at this (photo)Graph *in the voice of Nickelback* --------- Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
This commit is contained in:
@ -49,6 +49,26 @@ sketch002 = startSketchOn(extrude001, seg02)
|
|||||||
extrude002 = extrude(5, sketch002)
|
extrude002 = extrude(5, sketch002)
|
||||||
`
|
`
|
||||||
|
|
||||||
|
const exampleCodeNo3D = `sketch003 = startSketchOn('YZ')
|
||||||
|
|> startProfileAt([5.82, 0], %)
|
||||||
|
|> angledLine([180, 11.54], %, $rectangleSegmentA001)
|
||||||
|
|> angledLine([
|
||||||
|
segAng(rectangleSegmentA001) - 90,
|
||||||
|
8.21
|
||||||
|
], %, $rectangleSegmentB001)
|
||||||
|
|> angledLine([
|
||||||
|
segAng(rectangleSegmentA001),
|
||||||
|
-segLen(rectangleSegmentA001)
|
||||||
|
], %, $rectangleSegmentC001)
|
||||||
|
|> lineTo([profileStartX(%), profileStartY(%)], %)
|
||||||
|
|> close(%)
|
||||||
|
sketch004 = startSketchOn('-XZ')
|
||||||
|
|> startProfileAt([0, 14.36], %)
|
||||||
|
|> line([15.49, 0.05], %)
|
||||||
|
|> tangentialArcTo([0, 0], %)
|
||||||
|
|> tangentialArcTo([-6.8, 8.17], %)
|
||||||
|
`
|
||||||
|
|
||||||
const sketchOnFaceOnFaceEtc = `sketch001 = startSketchOn('XZ')
|
const sketchOnFaceOnFaceEtc = `sketch001 = startSketchOn('XZ')
|
||||||
|> startProfileAt([0, 0], %)
|
|> startProfileAt([0, 0], %)
|
||||||
|> line([4, 8], %)
|
|> line([4, 8], %)
|
||||||
@ -83,6 +103,7 @@ extrude004 = extrude(3, sketch004)
|
|||||||
const codeToWriteCacheFor = {
|
const codeToWriteCacheFor = {
|
||||||
exampleCode1,
|
exampleCode1,
|
||||||
sketchOnFaceOnFaceEtc,
|
sketchOnFaceOnFaceEtc,
|
||||||
|
exampleCodeNo3D,
|
||||||
} as const
|
} as const
|
||||||
|
|
||||||
type CodeKey = keyof typeof codeToWriteCacheFor
|
type CodeKey = keyof typeof codeToWriteCacheFor
|
||||||
@ -236,6 +257,69 @@ describe('testing createArtifactGraph', () => {
|
|||||||
await GraphTheGraph(theMap, 2000, 2000, 'exampleCode1.png')
|
await GraphTheGraph(theMap, 2000, 2000, 'exampleCode1.png')
|
||||||
}, 20000)
|
}, 20000)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe(`code with sketches but no extrusions or other 3D elements`, () => {
|
||||||
|
let ast: Program
|
||||||
|
let theMap: ReturnType<typeof createArtifactGraph>
|
||||||
|
it(`setup`, () => {
|
||||||
|
// putting this logic in here because describe blocks runs before beforeAll has finished
|
||||||
|
const {
|
||||||
|
orderedCommands,
|
||||||
|
responseMap,
|
||||||
|
ast: _ast,
|
||||||
|
} = getCommands('exampleCodeNo3D')
|
||||||
|
ast = _ast
|
||||||
|
theMap = createArtifactGraph({ orderedCommands, responseMap, ast })
|
||||||
|
})
|
||||||
|
|
||||||
|
it('there should be two planes, one for each sketch path', () => {
|
||||||
|
const planes = [...filterArtifacts({ types: ['plane'] }, theMap)].map(
|
||||||
|
(plane) => expandPlane(plane[1], theMap)
|
||||||
|
)
|
||||||
|
expect(planes).toHaveLength(2)
|
||||||
|
planes.forEach((path) => {
|
||||||
|
expect(path.type).toBe('plane')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
it('there should be two paths, one on each plane', () => {
|
||||||
|
const paths = [...filterArtifacts({ types: ['path'] }, theMap)].map(
|
||||||
|
(path) => expandPath(path[1], theMap)
|
||||||
|
)
|
||||||
|
expect(paths).toHaveLength(2)
|
||||||
|
paths.forEach((path) => {
|
||||||
|
if (err(path)) throw path
|
||||||
|
expect(path.type).toBe('path')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it(`there should be 1 solid2D, just for the first closed path`, () => {
|
||||||
|
const solid2Ds = [...filterArtifacts({ types: ['solid2D'] }, theMap)]
|
||||||
|
expect(solid2Ds).toHaveLength(1)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('there should be no extrusions', () => {
|
||||||
|
const extrusions = [...filterArtifacts({ types: ['sweep'] }, theMap)].map(
|
||||||
|
(extrusion) => expandSweep(extrusion[1], theMap)
|
||||||
|
)
|
||||||
|
expect(extrusions).toHaveLength(0)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('there should be 8 segments, 4 + 1 (close) from the first sketch and 3 from the second', () => {
|
||||||
|
const segments = [...filterArtifacts({ types: ['segment'] }, theMap)].map(
|
||||||
|
(segment) => expandSegment(segment[1], theMap)
|
||||||
|
)
|
||||||
|
expect(segments).toHaveLength(8)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('screenshot graph', async () => {
|
||||||
|
// Ostensibly this takes a screen shot of the graph of the artifactGraph
|
||||||
|
// but it's it also tests that all of the id links are correct because if one
|
||||||
|
// of the edges refers to a non-existent node, the graph will throw.
|
||||||
|
// further more we can check that each edge is bi-directional, if it's not
|
||||||
|
// by checking the arrow heads going both ways, on the graph.
|
||||||
|
await GraphTheGraph(theMap, 2000, 2000, 'exampleCodeNo3D.png')
|
||||||
|
}, 20000)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('capture graph of sketchOnFaceOnFace...', () => {
|
describe('capture graph of sketchOnFaceOnFace...', () => {
|
||||||
@ -457,7 +541,10 @@ async function GraphTheGraph(
|
|||||||
`./src/lang/std/artifactMapGraphs/${imageName}`
|
`./src/lang/std/artifactMapGraphs/${imageName}`
|
||||||
)
|
)
|
||||||
// chop the top 30 pixels off the image
|
// chop the top 30 pixels off the image
|
||||||
const originalImg = PNG.sync.read(fs.readFileSync(originalImgPath))
|
const originalImgExists = fs.existsSync(originalImgPath)
|
||||||
|
const originalImg = originalImgExists
|
||||||
|
? PNG.sync.read(fs.readFileSync(originalImgPath))
|
||||||
|
: null
|
||||||
// const img1Data = new Uint8Array(img1.data)
|
// const img1Data = new Uint8Array(img1.data)
|
||||||
// const img1DataChopped = img1Data.slice(30 * img1.width * 4)
|
// const img1DataChopped = img1Data.slice(30 * img1.width * 4)
|
||||||
// img1.data = Buffer.from(img1DataChopped)
|
// img1.data = Buffer.from(img1DataChopped)
|
||||||
@ -468,10 +555,10 @@ async function GraphTheGraph(
|
|||||||
const newImageDataChopped = newImageData.slice(30 * newImage.width * 4)
|
const newImageDataChopped = newImageData.slice(30 * newImage.width * 4)
|
||||||
newImage.data = Buffer.from(newImageDataChopped)
|
newImage.data = Buffer.from(newImageDataChopped)
|
||||||
|
|
||||||
const { width, height } = originalImg
|
const { width, height } = originalImg ?? newImage
|
||||||
const diff = new PNG({ width, height })
|
const diff = new PNG({ width, height })
|
||||||
|
|
||||||
const imageSizeDifferent = originalImg.data.length !== newImage.data.length
|
const imageSizeDifferent = originalImg?.data.length !== newImage.data.length
|
||||||
let numDiffPixels = 0
|
let numDiffPixels = 0
|
||||||
if (!imageSizeDifferent) {
|
if (!imageSizeDifferent) {
|
||||||
numDiffPixels = pixelmatch(
|
numDiffPixels = pixelmatch(
|
||||||
|
@ -36,9 +36,12 @@ interface solid2D {
|
|||||||
}
|
}
|
||||||
export interface PathArtifactRich {
|
export interface PathArtifactRich {
|
||||||
type: 'path'
|
type: 'path'
|
||||||
|
/** A path must always lie on a plane */
|
||||||
plane: PlaneArtifact | WallArtifact
|
plane: PlaneArtifact | WallArtifact
|
||||||
|
/** A path must always contain 0 or more segments */
|
||||||
segments: Array<SegmentArtifact>
|
segments: Array<SegmentArtifact>
|
||||||
sweep: SweepArtifact
|
/** A path may not result in a sweep artifact */
|
||||||
|
sweep?: SweepArtifact
|
||||||
codeRef: CommonCommandProperties
|
codeRef: CommonCommandProperties
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -587,13 +590,15 @@ export function expandPath(
|
|||||||
{ keys: path.segIds, types: ['segment'] },
|
{ keys: path.segIds, types: ['segment'] },
|
||||||
artifactGraph
|
artifactGraph
|
||||||
)
|
)
|
||||||
const sweep = getArtifactOfTypes(
|
const sweep = path.sweepId
|
||||||
|
? getArtifactOfTypes(
|
||||||
{
|
{
|
||||||
key: path.sweepId,
|
key: path.sweepId,
|
||||||
types: ['sweep'],
|
types: ['sweep'],
|
||||||
},
|
},
|
||||||
artifactGraph
|
artifactGraph
|
||||||
)
|
)
|
||||||
|
: undefined
|
||||||
const plane = getArtifactOfTypes(
|
const plane = getArtifactOfTypes(
|
||||||
{ key: path.planeId, types: ['plane', 'wall'] },
|
{ key: path.planeId, types: ['plane', 'wall'] },
|
||||||
artifactGraph
|
artifactGraph
|
||||||
|
BIN
src/lang/std/artifactMapGraphs/exampleCodeNo3D.png
Normal file
BIN
src/lang/std/artifactMapGraphs/exampleCodeNo3D.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 92 KiB |
Reference in New Issue
Block a user