fork me on github ribbon + model refactor
This commit is contained in:
parent
42d0d0a5d2
commit
f5ba146688
8 changed files with 75 additions and 82 deletions
29
LICENSE.md
29
LICENSE.md
|
|
@ -14,7 +14,6 @@ Please file an issue if you think a license or credits are missing or misreprese
|
||||||
The WASM build was made possible by https://github.com/DSchroer/openscad-wasm.
|
The WASM build was made possible by https://github.com/DSchroer/openscad-wasm.
|
||||||
|
|
||||||
* [Monaco Editor](#monaco-editor)
|
* [Monaco Editor](#monaco-editor)
|
||||||
* [Viewstl Plugin](#viewstl-plugin)
|
|
||||||
* [React Stl Viewer](#react-stl-viewer)
|
* [React Stl Viewer](#react-stl-viewer)
|
||||||
* [Three.js](#threejs)
|
* [Three.js](#threejs)
|
||||||
* [Boost](#boost)
|
* [Boost](#boost)
|
||||||
|
|
@ -79,34 +78,6 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
SOFTWARE.
|
SOFTWARE.
|
||||||
```
|
```
|
||||||
|
|
||||||
## Viewstl Plugin
|
|
||||||
|
|
||||||
https://github.com/omrips/viewstl
|
|
||||||
|
|
||||||
```
|
|
||||||
MIT License
|
|
||||||
|
|
||||||
Copyright (c) 2020 omrips
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
||||||
```
|
|
||||||
|
|
||||||
## React STL Viewer
|
## React STL Viewer
|
||||||
|
|
||||||
https://github.com/gabotechs/react-stl-viewer
|
https://github.com/gabotechs/react-stl-viewer
|
||||||
|
|
|
||||||
|
|
@ -13,5 +13,13 @@ Prerequisites:
|
||||||
* deno
|
* deno
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
make clean
|
||||||
|
|
||||||
|
# When doing local development, ensure the import.meta.url is replaced to localhost:
|
||||||
|
# (otherwise will get cryptic `RangeError: WebAssembly.Table.get(): invalid index 999948 into function table`)
|
||||||
|
dev=1 make public
|
||||||
|
npm start
|
||||||
|
|
||||||
|
# When building a release
|
||||||
make
|
make
|
||||||
```
|
```
|
||||||
|
|
@ -10,6 +10,8 @@
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
<meta name="theme-color" content="#000000" />
|
<meta name="theme-color" content="#000000" />
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/github-fork-ribbon-css/0.2.3/gh-fork-ribbon.min.css" />
|
||||||
|
|
||||||
<meta
|
<meta
|
||||||
name="description"
|
name="description"
|
||||||
content="OpenSCAD Playground: edit .scad models and render them to STL from the browser (WebAssembly build OpenSCAD, with Monaco editor and STL Viewer)"
|
content="OpenSCAD Playground: edit .scad models and render them to STL from the browser (WebAssembly build OpenSCAD, with Monaco editor and STL Viewer)"
|
||||||
|
|
@ -38,8 +40,17 @@
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
<style>.github-fork-ribbon:before { background-color: #333; }</style>
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
<a target="_blank" class="github-fork-ribbon"
|
||||||
|
href="https://github.com/openscad/openscad-playground/tree/rewrite1"
|
||||||
|
data-ribbon="Fork me on GitHub"
|
||||||
|
title="Fork me on GitHub">
|
||||||
|
Fork me on GitHub
|
||||||
|
</a>
|
||||||
|
|
||||||
<noscript>You need to enable JavaScript to run the OpenSCAD Playground.</noscript>
|
<noscript>You need to enable JavaScript to run the OpenSCAD Playground.</noscript>
|
||||||
<div id="root"></div>
|
<div id="root"></div>
|
||||||
<!--
|
<!--
|
||||||
|
|
|
||||||
22
src/App.tsx
22
src/App.tsx
|
|
@ -1,6 +1,6 @@
|
||||||
// Portions of this file are Copyright 2021 Google LLC, and licensed under GPL2+. See COPYING.
|
// Portions of this file are Copyright 2021 Google LLC, and licensed under GPL2+. See COPYING.
|
||||||
|
|
||||||
import React, { useContext, useEffect, useState } from 'react';
|
import React, { useContext, useEffect, useRef, useState } from 'react';
|
||||||
import {ModelContext, State} from './app-state'
|
import {ModelContext, State} from './app-state'
|
||||||
import Editor, { loader, Monaco } from '@monaco-editor/react';
|
import Editor, { loader, Monaco } from '@monaco-editor/react';
|
||||||
import './App.css';
|
import './App.css';
|
||||||
|
|
@ -73,6 +73,8 @@ export function App({initialState}: {initialState: State}) {
|
||||||
const model = new Model(state, setState);
|
const model = new Model(state, setState);
|
||||||
useEffect(() => model.init());
|
useEffect(() => model.init());
|
||||||
|
|
||||||
|
const stlModelRef = useRef(null);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ModelContext.Provider value={model}>
|
<ModelContext.Provider value={model}>
|
||||||
<div style={{display: 'flex', flexDirection: 'column', flex: 1}}>
|
<div style={{display: 'flex', flexDirection: 'column', flex: 1}}>
|
||||||
|
|
@ -85,9 +87,14 @@ export function App({initialState}: {initialState: State}) {
|
||||||
style={{
|
style={{
|
||||||
flex: 1
|
flex: 1
|
||||||
}}
|
}}
|
||||||
|
ref={stlModelRef}
|
||||||
showAxes={true}
|
showAxes={true}
|
||||||
orbitControls
|
orbitControls
|
||||||
shadows
|
shadows
|
||||||
|
modelProps={{
|
||||||
|
color: '#f9d72c',
|
||||||
|
|
||||||
|
}}
|
||||||
url={state.output?.stlFileURL ?? ''}
|
url={state.output?.stlFileURL ?? ''}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
|
|
@ -97,6 +104,19 @@ export function App({initialState}: {initialState: State}) {
|
||||||
{model.state.previewing && 'previewing... '}
|
{model.state.previewing && 'previewing... '}
|
||||||
{model.state.rendering && 'rendering... '}
|
{model.state.rendering && 'rendering... '}
|
||||||
{model.state.checkingSyntax && 'checking syntax... '}
|
{model.state.checkingSyntax && 'checking syntax... '}
|
||||||
|
|
||||||
|
<span style={{flex: 1}}></span>
|
||||||
|
|
||||||
|
<a target="_blank" className="text-fragment" href="http://openscad.org/documentation.html">Docs</a> |
|
||||||
|
<a target="_blank" className="text-fragment" href="http://openscad.org/cheatsheet/">Cheatsheet</a> |
|
||||||
|
<a target="_blank" href="https://github.com/openscad/openscad-playground/blob/rewrite1/LICENSE.md">LICENSES</a>
|
||||||
|
|
||||||
|
{state.output?.stlFileURL && (
|
||||||
|
<a href={state.output?.stlFileURL}
|
||||||
|
title="STL Download">
|
||||||
|
Download Model
|
||||||
|
</a>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</ModelContext.Provider>
|
</ModelContext.Provider>
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ export type RenderArgs = {
|
||||||
source: string,
|
source: string,
|
||||||
features?: string[],
|
features?: string[],
|
||||||
extraArgs?: string[],
|
extraArgs?: string[],
|
||||||
isPreview?: boolean
|
isPreview: boolean
|
||||||
}
|
}
|
||||||
export const render =
|
export const render =
|
||||||
turnIntoDelayableExecution(renderDelay, (args: RenderArgs) => {
|
turnIntoDelayableExecution(renderDelay, (args: RenderArgs) => {
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,8 @@ function collectObjectEntriesDeeply(o: KVObject, out: KVEntriesMap = new Map()):
|
||||||
if (typeof v !== 'object') {
|
if (typeof v !== 'object') {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (v instanceof RegExp) {
|
if (v instanceof RegExp ||
|
||||||
|
v instanceof Blob) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
collectObjectEntriesDeeply(v, out);
|
collectObjectEntriesDeeply(v, out);
|
||||||
|
|
|
||||||
80
src/model.ts
80
src/model.ts
|
|
@ -34,10 +34,6 @@ export class Model {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// get features() { return this.state_.params.features; }
|
|
||||||
|
|
||||||
// get source(): string { return this.state_.params.source; }
|
|
||||||
|
|
||||||
set source(source: string) {
|
set source(source: string) {
|
||||||
if (this.mutate(s => { s.params.source = source; })) {
|
if (this.mutate(s => { s.params.source = source; })) {
|
||||||
this.processSource();
|
this.processSource();
|
||||||
|
|
@ -45,62 +41,48 @@ export class Model {
|
||||||
}
|
}
|
||||||
|
|
||||||
private processSource() {
|
private processSource() {
|
||||||
this.mutate(s => {
|
this.checkSyntax();
|
||||||
s.previewing = true;
|
this.render({isPreview: true});
|
||||||
s.checkingSyntax = true;
|
}
|
||||||
});
|
checkSyntax() {
|
||||||
|
this.mutate(s => s.checkingSyntax = true);
|
||||||
checkSyntax(this.state.params.source)({now: false, callback: checkerRun => this.mutate(s => {
|
checkSyntax(this.state.params.source)({now: false, callback: checkerRun => this.mutate(s => {
|
||||||
s.lastCheckerRun = checkerRun;
|
s.lastCheckerRun = checkerRun;
|
||||||
s.checkingSyntax = false;
|
s.checkingSyntax = false;
|
||||||
})});
|
})});
|
||||||
render({...this.renderArgs, isPreview: true})({now: false, callback: output => this.handleRenderOutput(output, s => {
|
|
||||||
s.previewing = false;
|
|
||||||
})});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// checkSyntax() {
|
render({isPreview}: {isPreview: boolean}) {
|
||||||
// this.mutate(s => s.checkingSyntax = true);
|
const setRendering = (s: State, value: boolean) => {
|
||||||
// checkSyntax(this.state.params.source)({now: false, callback: checkerRun => this.mutate(s => {
|
if (isPreview) {
|
||||||
// s.lastCheckerRun = checkerRun;
|
s.previewing = value;
|
||||||
// s.checkingSyntax = false;
|
} else {
|
||||||
// })});
|
s.rendering = value;
|
||||||
// }
|
|
||||||
// preview() {
|
|
||||||
// this.mutate(s => s.previewing = true);
|
|
||||||
// render({...this.renderArgs, isPreview: true})({now: false, callback: output => this.handleRenderOutput(output, s => {
|
|
||||||
// s.previewing = false;
|
|
||||||
// })});
|
|
||||||
// }
|
|
||||||
|
|
||||||
private handleRenderOutput(output: RenderOutput, extraMutations: (s: State) => void) {
|
|
||||||
this.mutate(s => {
|
|
||||||
s.lastCheckerRun = {
|
|
||||||
logText: output.logText,
|
|
||||||
markers: output.markers,
|
|
||||||
}
|
}
|
||||||
if (s.output?.stlFileURL) {
|
}
|
||||||
URL.revokeObjectURL(s.output.stlFileURL);
|
this.mutate(s => setRendering(s, true));
|
||||||
}
|
|
||||||
s.output = {
|
|
||||||
stlFile: output.stlFile,
|
|
||||||
stlFileURL: URL.createObjectURL(output.stlFile),
|
|
||||||
};
|
|
||||||
extraMutations(s);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private get renderArgs(): RenderArgs {
|
|
||||||
const source = this.state.params.source;
|
const source = this.state.params.source;
|
||||||
const features = this.state.params.features;
|
const features = this.state.params.features;
|
||||||
return {source, features, extraArgs: ['-D$preview=true']};
|
const renderArgs = {source, features, extraArgs: ['-D$preview=true'], isPreview};
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
render(renderArgs)({now: !isPreview, callback: output => {
|
||||||
this.mutate(s => s.rendering = true);
|
this.mutate(s => {
|
||||||
|
s.lastCheckerRun = {
|
||||||
render(this.renderArgs)({now: true, callback: output => this.handleRenderOutput(output, s => {
|
logText: output.logText,
|
||||||
s.rendering = false;
|
markers: output.markers,
|
||||||
})})
|
}
|
||||||
|
if (s.output?.stlFileURL) {
|
||||||
|
URL.revokeObjectURL(s.output.stlFileURL);
|
||||||
|
}
|
||||||
|
s.output = {
|
||||||
|
isPreview: isPreview,
|
||||||
|
stlFile: output.stlFile,
|
||||||
|
stlFileURL: URL.createObjectURL(output.stlFile),
|
||||||
|
};
|
||||||
|
setRendering(s, false);
|
||||||
|
});
|
||||||
|
}})
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,6 @@
|
||||||
},
|
},
|
||||||
"include": [
|
"include": [
|
||||||
"src/*.ts",
|
"src/*.ts",
|
||||||
"public"
|
// "public"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue