diff --git a/package.json b/package.json index 24e45e2..ea0ea4e 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,8 @@ "@types/react-dom": "^18.0.11", "debug": "^4.3.4", "monaco-editor": "^0.36.1", + "primeicons": "^6.0.1", + "primereact": "^9.2.1", "react": "^18.2.0", "react-dom": "^18.2.0", "react-stl-viewer": "^2.2.5", diff --git a/public/index.html b/public/index.html index aa2c8e6..ea06fb5 100644 --- a/public/index.html +++ b/public/index.html @@ -14,6 +14,12 @@ + + + + + + monacoInstance = mi); @@ -31,13 +37,13 @@ function EditorPanel() { monaco.KeyMod.CtrlCmd | monaco.KeyCode.Enter, monaco.KeyCode.F6, ], - run: () => model.render({isPreview: false}) + run: () => model.render({isPreview: false, now: true}) }); editor.addAction({ id: "openscad-preview", label: "Preview OpenSCAD", keybindings: [monaco.KeyCode.F5], - run: () => model.render({isPreview: false}) + run: () => model.render({isPreview: true, now: true}) }); setEditor(editor) } @@ -79,7 +85,7 @@ export function App({initialState}: {initialState: State}) { const model = new Model(state, setState); useEffect(() => model.init()); - const stlModelRef = useRef(null); + // const stlModelRef = forwardRef(); return ( @@ -88,41 +94,50 @@ export function App({initialState}: {initialState: State}) {
- {state.output?.stlFileURL && - + {(state.rendering || state.previewing) && + } + {state.output?.stlFileURL && + + } - }} - url={state.output?.stlFileURL ?? ''} - /> - } -
- - {model.state.previewing && 'previewing... '} - {model.state.rendering && 'rendering... '} - {model.state.checkingSyntax && 'checking syntax... '} +
+
+ + {state.output && state.output.formattedElapsedMillis} +   + {state.previewing && 'previewing... '} + {state.rendering && 'rendering... '} + {state.checkingSyntax && 'checking syntax... '} + + {state.output && ( + + {state.output.isPreview ? "preview.stl" : "render.stl"} ({state.output.formattedStlFileSize}) + + )} Docs | Cheatsheet | LICENSES - - {state.output?.stlFileURL && ( - - Download Model - - )}
diff --git a/src/actions.ts b/src/actions.ts index 37f9e93..8167a36 100644 --- a/src/actions.ts +++ b/src/actions.ts @@ -36,7 +36,7 @@ export const checkSyntax = }); var renderDelay = 1000; -export type RenderOutput = {stlFile: File, logText: string, markers: monaco.editor.IMarkerData[], elapsedMillis?: number} +export type RenderOutput = {stlFile: File, logText: string, markers: monaco.editor.IMarkerData[], elapsedMillis: number} export type RenderArgs = { source: string, @@ -45,23 +45,26 @@ export type RenderArgs = { isPreview: boolean } export const render = - turnIntoDelayableExecution(renderDelay, (args: RenderArgs) => { - - const prefixLines: string[] = []; - if (args.isPreview) prefixLines.push('$preview=false;'); - const source = args.isPreview ? [...prefixLines, args.source].join('\n') : args.source + turnIntoDelayableExecution(renderDelay, (params: RenderArgs) => { const inputFile = 'input.scad'; + const args = [ + inputFile, + "-o", "out.stl", + "--export-format=binstl", + ...(params.features ?? []).map(f => `--enable=${f}`), + ...(params.extraArgs ?? []) + ] + + const prefixLines: string[] = []; + if (params.isPreview) { + prefixLines.push('$preview=true;'); + } + const source = [...prefixLines, params.source].join('\n'); const job = spawnOpenSCAD({ // wasmMemory, inputs: [['input.scad', source]], - args: [ - inputFile, - "-o", "out.stl", - "--export-format=binstl", - ...(args.features ?? []).map(f => `--enable=${f}`), - ...(args.extraArgs ?? []) - ], + args, outputPaths: ['out.stl'] }); diff --git a/src/app-state.ts b/src/app-state.ts index 7d6d2a2..b072ad8 100644 --- a/src/app-state.ts +++ b/src/app-state.ts @@ -22,6 +22,9 @@ export interface State { isPreview: boolean, stlFile: File, stlFileURL: string, + elapsedMillis: number, + formattedElapsedMillis: string, + formattedStlFileSize: string, }, }; diff --git a/src/default-scad.ts b/src/default-scad.ts index e5a93ca..e99a60a 100644 --- a/src/default-scad.ts +++ b/src/default-scad.ts @@ -13,5 +13,5 @@ translate([10, 10, 10]) // // include // translate([-100, 0, 0]) - spheroid(d=100, style="icosa", $fn=20); +// spheroid(d=100, style="icosa", $fn=20); ` \ No newline at end of file diff --git a/src/index.css b/src/index.css index ec2585e..9529ee9 100644 --- a/src/index.css +++ b/src/index.css @@ -1,8 +1,9 @@ body { margin: 0; - font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', + font-family: (--font-family); + /* font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', - sans-serif; + sans-serif; */ -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } diff --git a/src/model.ts b/src/model.ts index 0f92fc0..9fb5c9a 100644 --- a/src/model.ts +++ b/src/model.ts @@ -42,7 +42,7 @@ export class Model { private processSource() { this.checkSyntax(); - this.render({isPreview: true}); + this.render({isPreview: true, now: false}); } checkSyntax() { this.mutate(s => s.checkingSyntax = true); @@ -52,7 +52,7 @@ export class Model { })}); } - render({isPreview}: {isPreview: boolean}) { + render({isPreview, now}: {isPreview: boolean, now: boolean}) { const setRendering = (s: State, value: boolean) => { if (isPreview) { s.previewing = value; @@ -64,9 +64,10 @@ export class Model { const source = this.state.params.source; const features = this.state.params.features; - const renderArgs = {source, features, extraArgs: ['-D$preview=true'], isPreview}; + const renderArgs = {source, features, extraArgs: [], isPreview}; + // console.log('renderArgs', renderArgs); - render(renderArgs)({now: !isPreview, callback: output => { + render(renderArgs)({now, callback: output => { this.mutate(s => { s.lastCheckerRun = { logText: output.logText, @@ -75,10 +76,14 @@ export class Model { if (s.output?.stlFileURL) { URL.revokeObjectURL(s.output.stlFileURL); } + s.output = { isPreview: isPreview, stlFile: output.stlFile, stlFileURL: URL.createObjectURL(output.stlFile), + elapsedMillis: output.elapsedMillis, + formattedElapsedMillis: formatMillis(output.elapsedMillis), + formattedStlFileSize: formatBytes(output.stlFile.size), }; setRendering(s, false); }); @@ -86,3 +91,22 @@ export class Model { } } + +function formatBytes(n: number) { + if (n < 1024) { + return `${Math.floor(n)} bytes`; + } + n /= 1024; + if (n < 1024) { + return `${Math.floor(n * 10) / 10} kB`; + } + n /= 1024; + return `${Math.floor(n * 10) / 10} MB`; +} + +function formatMillis(n: number) { + if (n < 1000) + return `${Math.floor(n)} millis`; + + return `${Math.floor(n / 100) / 10} sec`; +} \ No newline at end of file diff --git a/src/openscad-runner.ts b/src/openscad-runner.ts index f902a9c..94cafaa 100644 --- a/src/openscad-runner.ts +++ b/src/openscad-runner.ts @@ -27,7 +27,7 @@ export type OpenSCADInvocationResults = { error?: string, outputs?: [string, string][], mergedOutputs: MergedOutputs, - elapsedMillis?: number, + elapsedMillis: number, } export function spawnOpenSCAD({inputs, args, outputPaths}: OpenSCADInvocation): AbortablePromise { diff --git a/webpack.config.js b/webpack.config.js index b83fa6d..98b98d8 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -15,9 +15,16 @@ module.exports = { { test: /\.css$/i, use: [ - {loader: 'css-loader', options:{url: false}} + { + loader: 'css-loader', + options:{url: false}, + } ] - } + }, + { + test: /\.(png|gif|woff|woff2|eot|ttf|svg)$/, + loader: "url-loader?limit=100000" + }, ], }, resolve: {