Add "STL Download" to project profile page (#585)
* Moved EditorMenu/helpers.ts file to src/helpers. Reused STL download helper on a new button in the project profile page * Tweak download STL style - flex-wrap the column and grow original "built with" content so the button is pushed write but remains responsive on smaller screens
This commit was merged in pull request #585.
This commit is contained in:
86
app/web/src/helpers/download_stl.ts
Normal file
86
app/web/src/helpers/download_stl.ts
Normal file
@@ -0,0 +1,86 @@
|
||||
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))
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user