implement dynamic import correctly

master
howard 2021-04-23 13:13:49 -07:00
parent cef6ae23fd
commit b73aa098a5
16 changed files with 235 additions and 97 deletions

108
package-lock.json generated
View File

@ -9,6 +9,7 @@
"@tailwindcss/jit": "^0.1.18",
"babel-loader": "^8.2.2",
"browser-fs-access": "^0.16.4",
"bson": "^4.3.0",
"copy-webpack-plugin": "^8.1.1",
"css-loader": "^5.1.3",
"gh-pages": "^3.1.0",
@ -1284,6 +1285,26 @@
"node": ">=0.10.0"
}
},
"node_modules/base64-js": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
"integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
"dev": true,
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
]
},
"node_modules/batch": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz",
@ -1428,6 +1449,42 @@
"url": "https://opencollective.com/browserslist"
}
},
"node_modules/bson": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/bson/-/bson-4.3.0.tgz",
"integrity": "sha512-LkKKeFJx5D6RRCRvLE+fDs40M2ZQNuk7W7tFXmKd7OOcQQ+BHdzCgRdL4XEGjc1UEGtiYuMvIVk91Bv8qsI50A==",
"dev": true,
"dependencies": {
"buffer": "^5.6.0"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/buffer": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
"integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
"dev": true,
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
],
"dependencies": {
"base64-js": "^1.3.1",
"ieee754": "^1.1.13"
}
},
"node_modules/buffer-from": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
@ -3708,6 +3765,26 @@
"postcss": "^8.1.0"
}
},
"node_modules/ieee754": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
"integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
"dev": true,
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
]
},
"node_modules/ignore": {
"version": "5.1.8",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz",
@ -9601,6 +9678,12 @@
}
}
},
"base64-js": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
"integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
"dev": true
},
"batch": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz",
@ -9722,6 +9805,25 @@
"node-releases": "^1.1.70"
}
},
"bson": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/bson/-/bson-4.3.0.tgz",
"integrity": "sha512-LkKKeFJx5D6RRCRvLE+fDs40M2ZQNuk7W7tFXmKd7OOcQQ+BHdzCgRdL4XEGjc1UEGtiYuMvIVk91Bv8qsI50A==",
"dev": true,
"requires": {
"buffer": "^5.6.0"
}
},
"buffer": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
"integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
"dev": true,
"requires": {
"base64-js": "^1.3.1",
"ieee754": "^1.1.13"
}
},
"buffer-from": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
@ -11557,6 +11659,12 @@
"dev": true,
"requires": {}
},
"ieee754": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
"integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
"dev": true
},
"ignore": {
"version": "5.1.8",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz",

View File

@ -10,6 +10,7 @@
"@tailwindcss/jit": "^0.1.18",
"babel-loader": "^8.2.2",
"browser-fs-access": "^0.16.4",
"bson": "^4.3.0",
"copy-webpack-plugin": "^8.1.1",
"css-loader": "^5.1.3",
"gh-pages": "^3.1.0",

View File

@ -417,4 +417,4 @@ function addSketch() {
return sketch
}
window.sc = new Scene(store)
// window.sc = new Scene(store)

View File

@ -155,7 +155,7 @@ export async function drawDimension() {
}
)
this.labelContainer.removeChild(this.labelContainer.lastChild);
sc.render()
this.scene.render()
}
if (this.mode == "dimension") {
this.drawDimension()
@ -176,7 +176,7 @@ export function updateDim(c_id) {
this.constraints.set(c_id, ent)
this.updateOtherBuffers()
this.solve()
sc.render()
this.scene.render()
ev_focus.target.blur()
this.updateBoundingSpheres()
} else if (e.key == 'Escape') {
@ -217,7 +217,7 @@ export function _onMoveDimension(point, line, initial) {
point,
_p1, _p2, null, initial
)
sc.render()
this.scene.render()
}
}

View File

@ -78,7 +78,7 @@ export function drawPreClick2(e) {
}
sc.render()
this.scene.render()
}
export function drawOnClick2(e) {
@ -136,7 +136,7 @@ let ccw;
export function drawPreClick3(e) {
const mouseLoc = this.getLocation(e);
ccw = drawArc4(mouseLoc, this.toPush)
sc.render()
this.scene.render()
}
export function drawOnClick3(e) {

View File

@ -219,7 +219,8 @@ export function onPick(e) {
}
// dont think this would have been possible without redux
if (obj.userData.type == 'sketch' && !sc.store.getState().treeEntries.visible[obj.name]) {
// if (obj.userData.type == 'sketch' && !sc.store.getState().treeEntries.visible[obj.name]) {
if (obj.userData.type == 'sketch' && !this.scene.store.getState().treeEntries.visible[obj.name]) {
obj.visible = false
}

View File

@ -11,8 +11,13 @@ import { ToolTip } from './toolTip'
import './app.css'
// export async function serial(...args) {
// return (await import('bson')).serialize(...args);
// }
// export async function deserial(...args) {
// return (await import('bson')).deserialize(...args);
// }
let store
if (process.env.NODE_ENV === 'production') {
@ -22,6 +27,7 @@ if (process.env.NODE_ENV === 'production') {
store = createStore(reducer, {}, applyMiddleware(logger))
}
const App = ({ store }) => {
return <Provider store={store}>
<NavBar />
@ -30,8 +36,15 @@ const App = ({ store }) => {
</Provider>
}
document.addEventListener('DOMContentLoaded', () => {
export let sce
document.addEventListener('DOMContentLoaded', async () => {
const { Scene } = await import('../Scene')
sce = new Scene(store)
// window.sc = sce
ReactDOM.render(<App store={store} />, document.getElementById('react'));
});
window.store = store
// window.store = store

View File

@ -1,3 +1,4 @@
import {sce} from './app'
export class DepTree {
constructor(obj) {
@ -64,7 +65,8 @@ export class DepTree {
this.allIds.splice(spliceIdx, 1)
const deletedObj = sc.obj3d.children.splice(spliceIdx + 1, 1)[0] // first 1 elements are non geom
// const deletedObj = sc.obj3d.children.splice(spliceIdx + 1, 1)[0] // first 1 elements are non geom
const deletedObj = sce.obj3d.children.splice(spliceIdx + 1, 1)[0] // first 1 elements are non geom
deletedObj.traverse((obj) => {
if (obj.geometry) obj.geometry.dispose()

View File

@ -6,6 +6,8 @@ import { useDispatch, useSelector } from 'react-redux'
import { MdDone, MdClose } from 'react-icons/md'
import * as Icon from "./icons";
import {sce} from './app'
export const Dialog = () => {
@ -21,22 +23,22 @@ export const Dialog = () => {
}, [dialog])
const extrude = () => {
const mesh = sc.extrude(dialog.target, ref.current.value)
const mesh = sce.extrude(dialog.target, ref.current.value)
dispatch({ type: 'rx-extrusion', mesh, sketchId: dialog.target.obj3d.name })
if (sc.activeSketch == dialog.target) {
if (sce.activeSketch == dialog.target) {
dispatch({ type: 'finish-sketch' })
dialog.target.deactivate()
}
dispatch({ type: "clear-dialog" })
sc.render()
sce.render()
}
const extrudeCancel = () => {
if (sc.activeSketch == dialog.target) { // if extrude dialog launched from sketch mode we set dialog back to the sketch dialog
if (sce.activeSketch == dialog.target) { // if extrude dialog launched from sketch mode we set dialog back to the sketch dialog
dispatch({ type: 'set-dialog', action: 'sketch' })
} else {
dispatch({ type: "clear-dialog" })
@ -46,41 +48,41 @@ export const Dialog = () => {
const extrudeEdit = () => {
dialog.target.userData.featureInfo[1] = ref.current.value
sc.refreshNode(dialog.target.name, treeEntries)
sce.refreshNode(dialog.target.name, treeEntries)
dispatch({ type: 'set-modified', status: true })
dispatch({ type: "clear-dialog" })
sc.render()
sce.render()
}
const extrudeEditCancel = () => dispatch({ type: "clear-dialog" })
const sketchDone = () => {
if (sc.activeSketch.hasChanged
|| sc.activeSketch.idOnActivate != id
|| sc.activeSketch.c_idOnActivate != sc.activeSketch.c_id
if (sce.activeSketch.hasChanged
|| sce.activeSketch.idOnActivate != id
|| sce.activeSketch.c_idOnActivate != sce.activeSketch.c_id
) {
sc.refreshNode(sc.activeSketch.obj3d.name, treeEntries)
sce.refreshNode(sce.activeSketch.obj3d.name, treeEntries)
dispatch({ type: 'set-modified', status: true })
}
dispatch({ type: 'finish-sketch' })
sc.activeSketch.deactivate()
sc.render()
sce.activeSketch.deactivate()
sce.render()
dispatch({ type: "clear-dialog" })
}
const sketchCancel = () => {
if (!sc.activeSketch.hasChanged
&& sc.activeSketch.idOnActivate == id
&& sc.activeSketch.c_idOnActivate == sc.activeSketch.c_id
if (!sce.activeSketch.hasChanged
&& sce.activeSketch.idOnActivate == id
&& sce.activeSketch.c_idOnActivate == sce.activeSketch.c_id
) {
if (sc.newSketch) {
dispatch({ type: 'delete-node', id: sc.activeSketch.obj3d.name })
sc.sid -= 1
if (sce.newSketch) {
dispatch({ type: 'delete-node', id: sce.activeSketch.obj3d.name })
sce.sid -= 1
} else {
dispatch({ type: "restore-sketch" })
}
@ -88,8 +90,8 @@ export const Dialog = () => {
dispatch({ type: 'finish-sketch' })
sc.activeSketch.deactivate()
sc.render()
sce.activeSketch.deactivate()
sce.render()
dispatch({ type: "clear-dialog" })
}

View File

@ -3,6 +3,9 @@ import React, { useState } from 'react';
import { useDispatch, useSelector } from 'react-redux'
import {sce} from './app'
export const DropDown = () => {
const arr = [
@ -30,17 +33,15 @@ export const DropDown = () => {
}
const handleInsideClick = (e) => {
const handleInsideClick = async (e) => {
// handles click inside dropdown, business logic here
const idx = Array.prototype.indexOf.call(e.target.parentNode.children, e.target)
if (idx !== -1) {
console.log(idx)
fetch(arr[idx][0])
.then(res => res.text())
.then(text => {
dispatch({ type: 'restore-state', state: sc.loadState(text) })
sc.render()
})
const res = await fetch(arr[idx][0])
const text = await res.text()
dispatch({ type: 'restore-state', state: sce.loadState(text) })
sce.render()
}
}
const fileHandle = useSelector(state => state.ui.fileHandle)

View File

@ -10,6 +10,8 @@ import {
fileSave,
} from 'browser-fs-access';
import {sce} from './app'
// https://web.dev/file-system-access/
const link = document.createElement('a');
@ -24,7 +26,7 @@ function saveLegacy(blob, filename) {
var tzoffset = (new Date()).getTimezoneOffset() * 60000;
export function STLExport(filename) {
const result = STLexp.parse(sc.selected[0], { binary: true });
const result = STLexp.parse(sce.selected[0], { binary: true });
const time = (new Date(Date.now() - tzoffset)).toISOString().slice(0, -5).replace(/:/g, '-');
saveLegacy(new Blob([result], { type: 'model/stl' }), `${filename}_${time}.stl`);
}
@ -92,7 +94,7 @@ export async function openFile(dispatch) {
try {
const text = await file.text();;
dispatch({ type: 'restore-state', state: sc.loadState(text) })
dispatch({ type: 'restore-state', state: sce.loadState(text) })
dispatch({ type: 'set-file-handle', fileHandle:file.handle })
} catch (ex) {

View File

@ -12,6 +12,9 @@ import { Dialog } from './dialog'
import { DropDown } from './dropDown'
import { STLExport, saveFile, openFile, verifyPermission } from './fileHelpers'
import { sce } from './app'
// import { serial, deserial} from './app'
export const NavBar = () => {
const dispatch = useDispatch()
const sketchActive = useSelector(state => state.ui.sketchActive)
@ -20,15 +23,15 @@ export const NavBar = () => {
const modified = useSelector(state => state.ui.modified)
const boolOp = (code) => {
if (sc.selected.length != 2 || !sc.selected.every(e => e.userData.type == 'mesh')) {
if (sce.selected.length != 2 || !sce.selected.every(e => e.userData.type == 'mesh')) {
alert('please first select two bodies for boolean operation')
return
}
const [m1, m2] = sc.selected
const [m1, m2] = sce.selected
const mesh = sc.boolOp(m1, m2, code)
const mesh = sce.boolOp(m1, m2, code)
sc.obj3d.add(mesh)
sce.obj3d.add(mesh)
dispatch({
type: 'set-entry-visibility', obj: {
@ -43,13 +46,13 @@ export const NavBar = () => {
})
sc.render()
sce.render()
forceUpdate()
}
const addSketch = () => {
const sketch = sc.addSketch()
const sketch = sce.addSketch()
if (!sketch) {
alert('please select a plane or 3 points to set the sketch plane')
return
@ -59,7 +62,7 @@ export const NavBar = () => {
sketch.activate()
sc.render()
sce.render()
dispatch({ type: 'set-dialog', action: 'sketch' })
@ -74,11 +77,11 @@ export const NavBar = () => {
useEffect(() => {
const onBeforeUnload = (e) => {
if (modified ||
(sc.activeSketch &&
(sce.activeSketch &&
(
sc.activeSketch.hasChanged
|| sc.activeSketch.idOnActivate != id
|| sc.activeSketch.c_idOnActivate != sc.activeSketch.c_id
sce.activeSketch.hasChanged
|| sce.activeSketch.idOnActivate != id
|| sce.activeSketch.c_idOnActivate != sce.activeSketch.c_id
)
)
) {
@ -92,30 +95,31 @@ export const NavBar = () => {
useEffect(() => { // hacky way to handle mounting and unmounting mouse listeners for feature mode
if (!sketchActive) {
sc.canvas.addEventListener('pointermove', sc.onHover)
sc.canvas.addEventListener('pointerdown', sc.onPick)
sce.canvas.addEventListener('pointermove', sce.onHover)
sce.canvas.addEventListener('pointerdown', sce.onPick)
return () => {
sc.canvas.removeEventListener('pointermove', sc.onHover)
sc.canvas.removeEventListener('pointerdown', sc.onPick)
sce.canvas.removeEventListener('pointermove', sce.onHover)
sce.canvas.removeEventListener('pointerdown', sce.onPick)
}
}
}, [sketchActive])
const sketchModeButtons = [
[Icon.Extrude, () => {
dispatch({ type: 'set-dialog', action: 'extrude', target: sc.activeSketch })
dispatch({ type: 'set-dialog', action: 'extrude', target: sce.activeSketch })
}, 'Extrude'],
[Icon.Line, () => sc.activeSketch.command('l'), 'Line (L)'],
[Icon.Arc, () => sc.activeSketch.command('a'), 'Arc (A)'],
[Icon.Dimension, () => sc.activeSketch.command('d'), 'Dimension (D)'],
[Icon.Coincident, () => sc.activeSketch.command('c'), 'Coincident (C)'],
[Icon.Vertical, () => sc.activeSketch.command('v'), 'Vertical (V)'],
[Icon.Horizontal, () => sc.activeSketch.command('h'), 'Horizontal (H)'],
[Icon.Tangent, () => sc.activeSketch.command('t'), 'Tangent (T)'],
[Icon.Line, () => sce.activeSketch.command('l'), 'Line (L)'],
[Icon.Arc, () => sce.activeSketch.command('a'), 'Arc (A)'],
[Icon.Dimension, () => sce.activeSketch.command('d'), 'Dimension (D)'],
[Icon.Coincident, () => sce.activeSketch.command('c'), 'Coincident (C)'],
[Icon.Vertical, () => sce.activeSketch.command('v'), 'Vertical (V)'],
[Icon.Horizontal, () => sce.activeSketch.command('h'), 'Horizontal (H)'],
[Icon.Tangent, () => sce.activeSketch.command('t'), 'Tangent (T)'],
[MdSave,
async () => {
saveFile(fileHandle, JSON.stringify([id, sc.sid, sc.mid, treeEntries]), dispatch)
saveFile(fileHandle, JSON.stringify([id, sce.sid, sce.mid, treeEntries]), dispatch)
// saveFile(fileHandle, serial([id, sce.sid, sce.mid, treeEntries]), dispatch)
}
, 'Save'],
]
@ -125,7 +129,7 @@ export const NavBar = () => {
[FaEdit, addSketch, 'Sketch'],
[Icon.Extrude, () => {
try {
dispatch({ type: 'set-dialog', action: 'extrude', target: treeEntries.byId[sc.selected[0].name] })
dispatch({ type: 'set-dialog', action: 'extrude', target: treeEntries.byId[sce.selected[0].name] })
} catch (err) {
console.error(err)
alert('please select a sketch from the left pane extrude')
@ -138,23 +142,24 @@ export const NavBar = () => {
[Icon.Intersect, () => boolOp('i'), 'Intersect'],
[MdInsertDriveFile, () => {
if (!confirmDiscard()) return
sc.newPart()
sce.newPart()
dispatch({ type: 'new-part' })
sc.render()
sce.render()
}, 'New'],
[MdSave,
() => {
saveFile(fileHandle, JSON.stringify([id, sc.sid, sc.mid, treeEntries]), dispatch)
saveFile(fileHandle, JSON.stringify([id, sce.sid, sce.mid, treeEntries]), dispatch)
// saveFile(fileHandle, serial([id, sce.sid, sce.mid, treeEntries]), dispatch)
}
, 'Save'],
[MdFolder, () => {
if (!confirmDiscard()) return
openFile(dispatch).then(
sc.render
sce.render
)
}, 'Open'],
[Icon.Stl, () => {
if (sc.selected[0] && sc.selected[0].userData.type == 'mesh') {
if (sce.selected[0] && sce.selected[0].userData.type == 'mesh') {
STLExport(fileHandle ? fileHandle.name.replace(/\.[^/.]+$/, "") : 'untitled')
} else {
alert('please first select one body to export')

View File

@ -3,6 +3,7 @@
import { DepTree } from './depTree'
import update from 'immutability-helper'
import { combineReducers } from 'redux';
import { sce } from './app'
const defaultState = {
byId: {},
@ -38,13 +39,13 @@ export function treeEntries(state = defaultState, action) {
})
case 'finish-sketch':
return update(state, {
visible: { [sc.activeSketch.obj3d.name]: { $set: false } },
visible: { [sce.activeSketch.obj3d.name]: { $set: false } },
})
case 'restore-sketch':
const sketch = sc.loadSketch(cache)
const sketch = sce.loadSketch(cache)
const deletedObj = sc.obj3d.children.splice(state.order[sc.activeSketch.obj3d.name] + 1, 1,
const deletedObj = sce.obj3d.children.splice(state.order[sce.activeSketch.obj3d.name] + 1, 1,
sketch.obj3d
)[0]
@ -53,10 +54,10 @@ export function treeEntries(state = defaultState, action) {
if (obj.material) obj.material.dispose()
})
sc.activeSketch = sketch
sce.activeSketch = sketch
return update(state, {
byId: { [sc.activeSketch.obj3d.name]: { $set: sketch } },
byId: { [sce.activeSketch.obj3d.name]: { $set: sketch } },
})
case 'rx-extrusion':

View File

@ -6,6 +6,8 @@ import { MdVisibilityOff, MdVisibility, MdDelete } from 'react-icons/md'
import { FaCube, FaEdit } from 'react-icons/fa'
import {sce} from './app'
export const Tree = () => {
const treeEntries = useSelector(state => state.treeEntries)
const fileHandle = useSelector(state => state.ui.fileHandle)
@ -53,19 +55,19 @@ const TreeEntry = ({ entId }) => {
return <div className='btn text-gray-200 select-none flex justify-start w-full h-7 items-center text-sm'
onDoubleClick={() => {
if (obj3d.userData.type == 'sketch') {
if (sc.activeSketch) {
if (sce.activeSketch) {
dispatch({ type: 'finish-sketch' })
sc.activeSketch.deactivate()
sce.activeSketch.deactivate()
}
sketch.activate()
dispatch({ type: 'set-active-sketch', sketch })
sc.clearSelection()
sc.activeSketch = sketch;
sce.clearSelection()
sce.activeSketch = sketch;
dispatch({ type: 'set-dialog', action: 'sketch' })
sc.render()
sce.render()
} else if (obj3d.userData.featureInfo.length == 2) {
dispatch({ type: 'set-dialog', action: 'extrude-edit', target: treeEntriesById[entId] })
}
@ -79,37 +81,37 @@ const TreeEntry = ({ entId }) => {
obj3d.visible = true
}
sc.setHover(obj3d, 1)
sc.render()
sce.setHover(obj3d, 1)
sce.render()
}}
onPointerLeave={() => {
if (!mouseOn) return
setMouseOn(false)
if (obj3d.userData.type == 'sketch'
&& !sc.selected.includes(obj3d)
&& !sce.selected.includes(obj3d)
&& !visible
) {
obj3d.visible = false
}
if (sc.selected.includes(obj3d)) return
if (sce.selected.includes(obj3d)) return
sc.setHover(obj3d, 0)
sce.setHover(obj3d, 0)
sc.render()
sce.render()
}}
onClick={() => {
const idx = sc.selected.indexOf(obj3d)
const idx = sce.selected.indexOf(obj3d)
if (idx == -1) {
sc.selected.push(obj3d)
sc.setHover(obj3d, 1)
sce.selected.push(obj3d)
sce.setHover(obj3d, 1)
} else {
sc.setHover(sc.selected[idx], 0)
sc.selected.splice(idx, 1)
sce.setHover(sce.selected[idx], 0)
sce.selected.splice(idx, 1)
}
sc.render()
sce.render()
}}
tooltip= {obj3d.name[0] !='(' && "double click to edit"}
@ -125,7 +127,7 @@ const TreeEntry = ({ entId }) => {
<MdDelete className='btn-green h-full w-auto p-1.5'
onClick={(e) => {
dispatch({ type: 'delete-node', id: entId })
sc.render()
sce.render()
e.stopPropagation()
}}
/>
@ -142,7 +144,7 @@ const TreeEntry = ({ entId }) => {
obj3d.traverse((e) => e.layers.disable(1))
}
sc.render()
sce.render()
forceUpdate()
}}
/>
@ -158,7 +160,7 @@ const TreeEntry = ({ entId }) => {
e.layers.enable(1)
})
}
sc.render()
sce.render()
forceUpdate()
}}
/>

View File

@ -23,7 +23,7 @@
<div id="labels"></div>
<div id="stats"></div>
<script src="app.bundle.js"></script>
<script src="scene.bundle.js"></script>
<!-- <script src="scene.bundle.js"></script> -->
<script src="solver.js"></script>
</body>

View File

@ -5,7 +5,7 @@ const tailwindcss = require('tailwindcss')
module.exports = {
entry: {
app: './src/react/app.jsx',
scene: './src/Scene.js',
// scene: './src/Scene.js',
},
output: {
filename: '[name].bundle.js',