Re-enable STL support (#61)

* OBJ as the new default viewer format

* Replace deprecated btoa

* Clean up

* Hide existing STL toggle

* No Box if no before/after

* Adds error message when no geometry
This commit is contained in:
Pierre Jacquier
2023-03-30 20:55:38 -04:00
committed by GitHub
parent f491739193
commit 31eef054b6
7 changed files with 1809 additions and 726 deletions

2393
.pnp.cjs generated

File diff suppressed because it is too large Load Diff

View File

@ -22,6 +22,7 @@
"@types/react-dom": "^18.0.11",
"@types/testing-library__jest-dom": "^5.14.5",
"@types/three": "^0.149.0",
"buffer": "^6.0.3",
"github-injection": "^1.1.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",

View File

@ -4,8 +4,8 @@ import { downloadFile, isFilenameSupported } from './diff'
it('checks if the filename has a supported extension', () => {
expect(isFilenameSupported('noextension')).toBe(false)
expect(isFilenameSupported('unsupported.txt')).toBe(false)
expect(isFilenameSupported('unsupported.stl')).toBe(false)
expect(isFilenameSupported('supported.obj')).toBe(true)
expect(isFilenameSupported('supported.stl')).toBe(true)
expect(isFilenameSupported('supported.stp')).toBe(true)
expect(isFilenameSupported('supported.step')).toBe(true)
})

View File

@ -5,21 +5,22 @@ import {
FileExportFormat_type,
FileImportFormat_type,
} from '@kittycad/lib/dist/types/src/models'
import { Buffer } from 'buffer'
export const extensionToSrcFormat: {
[extension: string]: FileImportFormat_type
} = {
'dae': 'dae',
'dxf': 'dxf',
'fbx': 'fbx',
'obj': 'obj',
'stp': 'step',
'step': 'step',
'svg': 'svg',
// stl disabled for now as there's some GitHub support for them already, see #40
dae: 'dae',
dxf: 'dxf',
fbx: 'fbx',
obj: 'obj',
stl: 'stl',
stp: 'step',
step: 'step',
svg: 'svg',
}
export function isFilenameSupported(filename: string): boolean{
export function isFilenameSupported(filename: string): boolean {
const extension = filename.split('.').pop()
return !!(extension && extensionToSrcFormat[extension])
}
@ -56,9 +57,14 @@ async function convert(
client: Client,
body: string,
extension: string,
outputFormat = 'stl'
outputFormat = 'obj'
) {
// TODO: think about the best output format for visual diff injection, now defaults to STL
if (extension === outputFormat) {
console.log(
'Skipping conversion, as extension is equal to outputFormat'
)
return Buffer.from(body).toString('base64')
}
const response = await file.create_file_conversion({
client,
body,
@ -86,7 +92,9 @@ export async function getFileDiff(
const extension = filename.split('.').pop()
if (!extension || !extensionToSrcFormat[extension]) {
throw Error(
`Unsupported extension. Given ${extension}, was expecting ${Object.keys(extensionToSrcFormat)}`
`Unsupported extension. Given ${extension}, was expecting ${Object.keys(
extensionToSrcFormat
)}`
)
}

View File

@ -1,27 +1,31 @@
import React, { useEffect, useState } from 'react'
import '@react-three/fiber'
import { Box, useTheme } from '@primer/react'
import { Box, useTheme, Text } from '@primer/react'
import { FileDiff } from '../../chrome/types'
import { Viewer3D } from './Viewer3D'
import { STLLoader } from 'three/examples/jsm/loaders/STLLoader'
import { BufferGeometry } from 'three'
import { OBJLoader } from 'three/examples/jsm/loaders/OBJLoader'
import { BufferGeometry, Mesh } from 'three'
import { WireframeColors } from './WireframeModel'
import { Buffer } from 'buffer'
type ViewerSTLProps = {
file: string
colors: WireframeColors
}
function ViewerSTL({ file, colors }: ViewerSTLProps) {
const [geomety, setGeometry] = useState<BufferGeometry>()
function Loader3D({ file, colors }: { file: string; colors: WireframeColors }) {
const [geometry, setGeometry] = useState<BufferGeometry>()
useEffect(() => {
const loader = new STLLoader()
const buffer = window.atob(file)
const geometry = loader.parse(buffer)
console.log(`Model ${geometry.id} loaded`)
const loader = new OBJLoader()
const buffer = Buffer.from(file, 'base64').toString()
const group = loader.parse(buffer)
console.log(`Model ${group.id} loaded`)
console.log(group)
const geometry = (group.children[0] as Mesh)?.geometry
setGeometry(geometry)
}, [file])
return geomety ? <Viewer3D geometry={geomety} colors={colors} /> : null
return geometry ? (
<Viewer3D geometry={geometry} colors={colors} />
) : (
<Box p={3}>
<Text>Sorry, the rich diff can't be displayed for this file.</Text>
</Box>
)
}
export function CadDiff({ before, after }: FileDiff): React.ReactElement {
@ -38,19 +42,23 @@ export function CadDiff({ before, after }: FileDiff): React.ReactElement {
}
return (
<Box display="flex" height={300} overflow="hidden" minWidth={0}>
<Box flexGrow={1} minWidth={0} backgroundColor="danger.subtle">
{before && <ViewerSTL file={before} colors={beforeColors} />}
</Box>
<Box
flexGrow={1}
minWidth={0}
backgroundColor="success.subtle"
borderLeftWidth={1}
borderLeftColor="border.default"
borderLeftStyle="solid"
>
{after && <ViewerSTL file={after} colors={afterColors} />}
</Box>
{before && (
<Box flexGrow={1} minWidth={0} backgroundColor="danger.subtle">
<Loader3D file={before} colors={beforeColors} />
</Box>
)}
{after && (
<Box
flexGrow={1}
minWidth={0}
backgroundColor="success.subtle"
borderLeftWidth={1}
borderLeftColor="border.default"
borderLeftStyle="solid"
>
<Loader3D file={after} colors={afterColors} />
</Box>
)}
</Box>
)
}

View File

@ -32,6 +32,14 @@ function CadDiffPortal({
const toolbar = element.querySelector<HTMLElement>('.file-info')
if (toolbar != null) {
setToolbarContainer(toolbar)
// STL files might have a toggle already
const existingToggle = element.querySelector<HTMLElement>(
'.js-prose-diff-toggle-form'
)
if (existingToggle) {
existingToggle.style.display = 'none'
}
}
const diff = element.querySelector<HTMLElement>('.js-file-content')

View File

@ -4814,6 +4814,13 @@ __metadata:
languageName: node
linkType: hard
"base64-js@npm:^1.3.1":
version: 1.5.1
resolution: "base64-js@npm:1.5.1"
checksum: 669632eb3745404c2f822a18fc3a0122d2f9a7a13f7fb8b5823ee19d1d2ff9ee5b52c53367176ea4ad093c332fd5ab4bd0ebae5a8e27917a4105a4cfc86b1005
languageName: node
linkType: hard
"batch@npm:0.6.1":
version: 0.6.1
resolution: "batch@npm:0.6.1"
@ -4974,6 +4981,16 @@ __metadata:
languageName: node
linkType: hard
"buffer@npm:^6.0.3":
version: 6.0.3
resolution: "buffer@npm:6.0.3"
dependencies:
base64-js: ^1.3.1
ieee754: ^1.2.1
checksum: 5ad23293d9a731e4318e420025800b42bf0d264004c0286c8cc010af7a270c7a0f6522e84f54b9ad65cbd6db20b8badbfd8d2ebf4f80fa03dab093b89e68c3f9
languageName: node
linkType: hard
"builtin-modules@npm:^3.1.0":
version: 3.3.0
resolution: "builtin-modules@npm:3.3.0"
@ -6164,6 +6181,7 @@ __metadata:
"@types/react-dom": ^18.0.11
"@types/testing-library__jest-dom": ^5.14.5
"@types/three": ^0.149.0
buffer: ^6.0.3
dotenv: ^16.0.3
eslint: ^8.37.0
eslint-config-prettier: ^8.6.0
@ -7528,7 +7546,7 @@ __metadata:
"fsevents@patch:fsevents@2.3.2#~builtin<compat/fsevents>, fsevents@patch:fsevents@^2.3.2#~builtin<compat/fsevents>, fsevents@patch:fsevents@~2.3.2#~builtin<compat/fsevents>":
version: 2.3.2
resolution: "fsevents@patch:fsevents@npm%3A2.3.2#~builtin<compat/fsevents>::version=2.3.2&hash=18f3a7"
resolution: "fsevents@patch:fsevents@npm%3A2.3.2#~builtin<compat/fsevents>::version=2.3.2&hash=df0bf1"
dependencies:
node-gyp: latest
conditions: os=darwin
@ -8159,6 +8177,13 @@ __metadata:
languageName: node
linkType: hard
"ieee754@npm:^1.2.1":
version: 1.2.1
resolution: "ieee754@npm:1.2.1"
checksum: 5144c0c9815e54ada181d80a0b810221a253562422e7c6c3a60b1901154184f49326ec239d618c416c1c5945a2e197107aee8d986a3dd836b53dffefd99b5e7e
languageName: node
linkType: hard
"ignore@npm:^5.2.0":
version: 5.2.4
resolution: "ignore@npm:5.2.4"
@ -12363,7 +12388,7 @@ __metadata:
"resolve@patch:resolve@^1.1.7#~builtin<compat/resolve>, resolve@patch:resolve@^1.14.2#~builtin<compat/resolve>, resolve@patch:resolve@^1.19.0#~builtin<compat/resolve>, resolve@patch:resolve@^1.20.0#~builtin<compat/resolve>, resolve@patch:resolve@^1.22.1#~builtin<compat/resolve>":
version: 1.22.1
resolution: "resolve@patch:resolve@npm%3A1.22.1#~builtin<compat/resolve>::version=1.22.1&hash=07638b"
resolution: "resolve@patch:resolve@npm%3A1.22.1#~builtin<compat/resolve>::version=1.22.1&hash=c3c19d"
dependencies:
is-core-module: ^2.9.0
path-parse: ^1.0.7
@ -12376,7 +12401,7 @@ __metadata:
"resolve@patch:resolve@^2.0.0-next.4#~builtin<compat/resolve>":
version: 2.0.0-next.4
resolution: "resolve@patch:resolve@npm%3A2.0.0-next.4#~builtin<compat/resolve>::version=2.0.0-next.4&hash=07638b"
resolution: "resolve@patch:resolve@npm%3A2.0.0-next.4#~builtin<compat/resolve>::version=2.0.0-next.4&hash=c3c19d"
dependencies:
is-core-module: ^2.9.0
path-parse: ^1.0.7
@ -13826,11 +13851,11 @@ __metadata:
"typescript@patch:typescript@^4.4.2#~builtin<compat/typescript>":
version: 4.9.5
resolution: "typescript@patch:typescript@npm%3A4.9.5#~builtin<compat/typescript>::version=4.9.5&hash=a1c5e5"
resolution: "typescript@patch:typescript@npm%3A4.9.5#~builtin<compat/typescript>::version=4.9.5&hash=23ec76"
bin:
tsc: bin/tsc
tsserver: bin/tsserver
checksum: 2eee5c37cad4390385db5db5a8e81470e42e8f1401b0358d7390095d6f681b410f2c4a0c496c6ff9ebd775423c7785cdace7bcdad76c7bee283df3d9718c0f20
checksum: ab417a2f398380c90a6cf5a5f74badd17866adf57f1165617d6a551f059c3ba0a3e4da0d147b3ac5681db9ac76a303c5876394b13b3de75fdd5b1eaa06181c9d
languageName: node
linkType: hard