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:
@ -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)
|
||||
})
|
||||
|
||||
@ -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
|
||||
)}`
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -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>
|
||||
)
|
||||
}
|
||||
|
||||
@ -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')
|
||||
|
||||
Reference in New Issue
Block a user