Files
cadhub/app/web/src/components/EditorMenu/helpers.ts
2021-11-21 18:14:16 +11:00

86 lines
2.5 KiB
TypeScript

import { flow, identity } from 'lodash/fp'
import { fileSave } from 'browser-fs-access'
import { MeshBasicMaterial, Mesh, Scene } from 'three'
import { STLExporter } from 'three/examples/jsm/exporters/STLExporter'
import { requestRender, State } from 'src/helpers/hooks/useIdeState'
import { toast } from '@redwoodjs/web/toast'
export const PullTitleFromFirstLine = (code = '') => {
const firstLine = code.split('\n').filter(identity)[0] || ''
if (!(firstLine.startsWith('//') || firstLine.startsWith('#'))) {
return 'object.stl'
}
return (
(firstLine.replace(/^(\/\/|#)\s*(.+)/, (_, __, titleWithSpaces) =>
titleWithSpaces.replaceAll(/\s/g, '-')
) || 'object') + '.stl'
)
}
interface makeStlDownloadHandlerArgs {
geometry: any
fileName: string
type: State['objectData']['type']
ideType: State['ideType']
thunkDispatch: (a: any) => any
quality: State['objectData']['quality']
}
export const makeStlDownloadHandler =
({
geometry,
fileName,
type,
thunkDispatch,
quality,
ideType,
}: makeStlDownloadHandlerArgs) =>
() => {
const makeStlBlobFromMesh = flow(
(...meshes) => new Scene().add(...meshes),
(scene) => new STLExporter().parse(scene),
(stl) =>
new Blob([stl], {
type: 'text/plain',
})
)
const makeStlBlobFromGeo = flow(
(geo) => new Mesh(geo, new MeshBasicMaterial()),
(mesh) => makeStlBlobFromMesh(mesh)
)
const saveFile = (blob) => {
fileSave(blob, {
fileName,
extensions: ['.stl'],
})
}
toast(
"CadHub is a work in process and We're still working out kinks with the STL download."
)
if (geometry) {
if (
type === 'geometry' &&
(quality === 'high' || ideType === 'openscad')
) {
saveFile(makeStlBlobFromGeo(geometry))
} else if (ideType == 'jscad') {
const clonedGeometry = geometry.map((mesh) => mesh.clone())
saveFile(makeStlBlobFromMesh(...clonedGeometry))
} else {
thunkDispatch((dispatch, getState) => {
const state = getState()
const specialCadProcess = (ideType === 'openscad' || ideType === 'curv') && 'stl'
dispatch({ type: 'setLoading' })
requestRender({
state,
dispatch,
quality: 'high',
specialCadProcess,
}).then(
(result) => result && saveFile(makeStlBlobFromGeo(result.data))
)
})
}
}
}