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

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')