workiing file expoort
parent
4076c90e58
commit
4e0706211f
10
src/Scene.js
10
src/Scene.js
|
@ -15,10 +15,14 @@ import { AxesHelper } from './axes'
|
|||
|
||||
import CSG from "../lib/three-csg"
|
||||
|
||||
import { STLExporter } from '../node_modules/three/examples/jsm/exporters/STLExporter'
|
||||
|
||||
|
||||
|
||||
|
||||
window.loader = new THREE.ObjectLoader();
|
||||
window.STLexp = new STLExporter();
|
||||
|
||||
window.id = 0
|
||||
window.sid = 1
|
||||
window.mid = 1
|
||||
|
@ -173,6 +177,10 @@ export class Scene {
|
|||
)
|
||||
|
||||
}
|
||||
|
||||
saveString() {
|
||||
return JSON.stringify([id, this.sid, this.mid, this.store.getState().treeEntries])
|
||||
}
|
||||
|
||||
loadState() { //uglyyy
|
||||
const [curid, cursid, curmid, state] = JSON.parse(
|
||||
|
@ -218,7 +226,7 @@ export class Scene {
|
|||
let entry = JSON.parse(string)
|
||||
entry.obj3d = loader.parse(entry.obj3d)
|
||||
|
||||
this.obj3d.add(entry.obj3d)
|
||||
// this.obj3d.add(entry.obj3d)
|
||||
|
||||
entry = new Sketch(this, entry)
|
||||
entry.obj3d.addEventListener('change', this.render)
|
||||
|
|
|
@ -175,9 +175,9 @@ class Sketch {
|
|||
// overkill but good solution if this check was more costly
|
||||
this.hasChanged = false
|
||||
this.idOnActivate = id
|
||||
this.c_idOnActivate = this.c_id
|
||||
// console.log(this,this.selected)
|
||||
const changeDetector = (e) => {
|
||||
console.log(this.selected.length, e.buttons)
|
||||
if (this.selected.length && e.buttons) {
|
||||
this.canvas.removeEventListener('pointermove', changeDetector)
|
||||
this.hasChanged = true
|
||||
|
@ -187,11 +187,10 @@ class Sketch {
|
|||
}
|
||||
|
||||
deactivate() {
|
||||
console.log('deactivateeeeeeee')
|
||||
window.removeEventListener('keydown', this.onKeyPress)
|
||||
this.canvas.removeEventListener('pointerdown', this.onPick)
|
||||
this.canvas.removeEventListener('pointermove', this.onHover)
|
||||
this.store.dispatch({ type: 'finish-sketch' })
|
||||
|
||||
this.labelContainer.innerHTML = ""
|
||||
this.obj3d.visible = false
|
||||
this.obj3d.traverse(e => e.layers.disable(2))
|
||||
|
|
|
@ -116,6 +116,7 @@ export function extrude(sketch, depth, refresh=false) {
|
|||
this.store.dispatch({ type: 'rx-extrusion', mesh, sketchId: sketch.obj3d.name })
|
||||
|
||||
if (this.activeSketch == sketch) {
|
||||
this.store.dispatch({ type: 'finish-sketch' })
|
||||
sketch.deactivate()
|
||||
}
|
||||
this.render()
|
||||
|
|
|
@ -1,14 +1,12 @@
|
|||
|
||||
|
||||
import React, { useEffect, useReducer, useRef, useState } from 'react';
|
||||
import React, { useEffect, useRef } from 'react';
|
||||
|
||||
import { useDispatch, useSelector } from 'react-redux'
|
||||
import { MdDone, MdClose } from 'react-icons/md'
|
||||
import * as Icon from "./icons";
|
||||
|
||||
|
||||
|
||||
|
||||
export const Dialog = () => {
|
||||
|
||||
const dialog = useSelector(state => state.ui.dialog)
|
||||
|
@ -17,6 +15,7 @@ export const Dialog = () => {
|
|||
const ref = useRef()
|
||||
|
||||
useEffect(() => {
|
||||
console.log(dialog)
|
||||
if (!ref.current) return
|
||||
ref.current.focus()
|
||||
}, [dialog])
|
||||
|
@ -29,7 +28,18 @@ export const Dialog = () => {
|
|||
|
||||
}
|
||||
|
||||
const [_, forceUpdate] = useReducer(x => x + 1, 0);
|
||||
const extrudeEdit = () => {
|
||||
|
||||
|
||||
dialog.target.userData.featureInfo[1] = ref.current.value
|
||||
|
||||
sc.refreshNode(dialog.target.name)
|
||||
|
||||
sc.render()
|
||||
dispatch({ type: "clear-dialog" })
|
||||
|
||||
}
|
||||
|
||||
|
||||
switch (dialog.action) {
|
||||
case 'extrude':
|
||||
|
@ -46,44 +56,54 @@ export const Dialog = () => {
|
|||
onClick={() => dispatch({ type: "clear-dialog" })}
|
||||
/>
|
||||
</>
|
||||
case 'extrude-edit':
|
||||
return <>
|
||||
<input className='w-16 border-t-0 border-l-0 border-r-0 border-b border-gray-50 text-gray-50 mr-6' type="number" defaultValue={dialog.target.userData.featureInfo[1]} step="0.1" ref={ref} />
|
||||
<Icon.Flip className="btn w-auto h-full p-3.5"
|
||||
onClick={() => ref.current.value *= -1}
|
||||
/>
|
||||
<MdDone
|
||||
className="btn w-auto h-full p-3.5"
|
||||
onClick={extrudeEdit}
|
||||
/>
|
||||
<MdClose className="btn w-auto h-full p-3.5 mr-6"
|
||||
onClick={() => dispatch({ type: "clear-dialog" })}
|
||||
/>
|
||||
</>
|
||||
case 'sketch':
|
||||
return <>
|
||||
<MdDone
|
||||
className="btn w-auto h-full p-3.5"
|
||||
onClick={() => {
|
||||
if (sc.activeSketch.hasChanged || sc.activeSketch.idOnActivate != id) {
|
||||
|
||||
// for (let k in sc.store.getState().treeEntries.tree[sc.activeSketch.obj3d.name]) {
|
||||
// console.log('circlllles',k)
|
||||
// }
|
||||
|
||||
if (sc.activeSketch.hasChanged
|
||||
|| sc.activeSketch.idOnActivate != id
|
||||
|| sc.activeSketch.c_idOnActivate != sc.activeSketch.c_id
|
||||
) {
|
||||
sc.refreshNode(sc.activeSketch.obj3d.name)
|
||||
}
|
||||
// dispatch({ type: 'update-descendents', sketch})
|
||||
|
||||
dispatch({ type: 'finish-sketch' })
|
||||
|
||||
sc.activeSketch.deactivate()
|
||||
sc.render()
|
||||
|
||||
dispatch({ type: "clear-dialog" })
|
||||
}}
|
||||
/>
|
||||
<MdClose className="btn w-auto h-full p-3.5 mr-6"
|
||||
onClick={() => {
|
||||
console.log('cancle',sc.activeSketch.hasChanged, sc.activeSketch.idOnActivate, id)
|
||||
if (sc.activeSketch.hasChanged || sc.activeSketch.idOnActivate != id) {
|
||||
console.log('has changed')
|
||||
dispatch({ type: "cancel-sketch" })
|
||||
sc.store.getState().treeEntries.byId[sc.activeSketch.obj3d.name].deactivate()
|
||||
if (sc.activeSketch.hasChanged
|
||||
|| sc.activeSketch.idOnActivate != id
|
||||
|| sc.activeSketch.c_idOnActivate != sc.activeSketch.c_id
|
||||
) {
|
||||
dispatch({ type: "restore-sketch" })
|
||||
} else {
|
||||
|
||||
sc.activeSketch.deactivate()
|
||||
dispatch({ type: 'finish-sketch' })
|
||||
}
|
||||
|
||||
|
||||
sc.activeSketch.deactivate()
|
||||
sc.render()
|
||||
dispatch({ type: "clear-dialog" })
|
||||
|
||||
}
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
default:
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
const link = document.createElement( 'a' );
|
||||
link.style.display = 'none';
|
||||
document.body.appendChild( link );
|
||||
|
||||
function save(blob, filename) {
|
||||
|
||||
link.href = URL.createObjectURL(blob);
|
||||
link.download = filename;
|
||||
link.click();
|
||||
|
||||
}
|
||||
|
||||
|
||||
function saveArrayBuffer( buffer, filename ) {
|
||||
|
||||
save( new Blob( [ buffer ], { type: 'application/octet-stream' } ), filename );
|
||||
|
||||
}
|
||||
|
||||
function saveString( text, filename ) {
|
||||
|
||||
save( new Blob( [ text ], { type: 'text/plain' } ), filename );
|
||||
|
||||
}
|
||||
|
||||
export function STLExport() {
|
||||
if (sc.selected[0] && sc.selected[0].userData.type == 'mesh') {
|
||||
const result = STLexp.parse( sc.selected[0], { binary: true } );
|
||||
saveArrayBuffer( result, 'box.stl' );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export function savePart() {
|
||||
const string = sc.saveString()
|
||||
|
||||
saveString( LZString.compress(string), 'test2.bin' );
|
||||
|
||||
}
|
|
@ -5,11 +5,35 @@ import React, { useEffect, useReducer } from 'react';
|
|||
import { useDispatch, useSelector } from 'react-redux'
|
||||
|
||||
import { FaEdit } from 'react-icons/fa'
|
||||
import { MdSave, MdFolder } from 'react-icons/md'
|
||||
import { MdSave } from 'react-icons/md'
|
||||
import { FaFolderOpen } from 'react-icons/fa'
|
||||
|
||||
import * as Icon from "./icons";
|
||||
import { Dialog } from './dialog'
|
||||
import { STLExport, savePart } from './fileExporter'
|
||||
|
||||
|
||||
const link = document.createElement('a');
|
||||
link.style.display = 'none';
|
||||
document.body.appendChild(link);
|
||||
|
||||
function save(blob, filename) {
|
||||
|
||||
link.href = URL.createObjectURL(blob);
|
||||
link.download = filename;
|
||||
link.click();
|
||||
|
||||
}
|
||||
|
||||
|
||||
function saveArrayBuffer(buffer, filename) {
|
||||
|
||||
save(new Blob([buffer], { type: 'application/octet-stream' }), filename);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
export const NavBar = () => {
|
||||
const dispatch = useDispatch()
|
||||
|
@ -44,8 +68,9 @@ export const NavBar = () => {
|
|||
|
||||
const sketchModeButtons = [
|
||||
[Icon.Extrude, () => {
|
||||
sc.activeSketch.deactivate()
|
||||
dispatch({ type: 'finish-sketch' })
|
||||
dispatch({ type: 'set-dialog', action: 'extrude', target: sc.activeSketch })
|
||||
|
||||
}, 'Extrude [e]'],
|
||||
[Icon.Dimension, () => sc.activeSketch.command('d'), 'Dimension [d]'],
|
||||
[Icon.Line, () => sc.activeSketch.command('l'), 'Line [l]'],
|
||||
|
@ -66,9 +91,9 @@ export const NavBar = () => {
|
|||
[Icon.Union, () => boolOp('u'), 'Union'],
|
||||
[Icon.Subtract, () => boolOp('s'), 'Subtract'],
|
||||
[Icon.Intersect, () => boolOp('i'), 'Intersect'],
|
||||
[MdSave, () => boolOp('i'), 'Save [ctrl+s]'],
|
||||
[MdSave, savePart, 'Save [ctrl+s]'],
|
||||
[FaFolderOpen, () => boolOp('i'), 'Load'],
|
||||
[Icon.Stl, () => boolOp('i'), 'Export STL'],
|
||||
[Icon.Stl, STLExport, 'Export STL'],
|
||||
]
|
||||
|
||||
const [_, forceUpdate] = useReducer(x => x + 1, 0);
|
||||
|
|
|
@ -43,21 +43,20 @@ export function treeEntries(state = defaultState, action) {
|
|||
activeSketchId: { $set: "" },
|
||||
visible: { [state.activeSketchId]: { $set: false } },
|
||||
})
|
||||
case 'cancel-sketch':
|
||||
case 'restore-sketch':
|
||||
|
||||
const sketch = sc.loadSketch(cache)
|
||||
|
||||
const deletedObj = sc.obj3d.children.splice(state.order[state.activeSketchId] + 1, 1,
|
||||
sketch.obj3d
|
||||
)[0]
|
||||
console.log('spliced and starting to delete')
|
||||
|
||||
deletedObj.traverse((obj) => {
|
||||
if (obj.geometry) obj.geometry.dispose()
|
||||
if (obj.material) obj.material.dispose()
|
||||
})
|
||||
|
||||
// sketch.deactivate()
|
||||
sc.activeSketch = sketch
|
||||
|
||||
return update(state, {
|
||||
activeSketchId: { $set: "" },
|
||||
|
|
|
@ -11,7 +11,7 @@ export const Tree = () => {
|
|||
|
||||
return <div className='sideNav flex flex-col bg-gray-800'>
|
||||
{treeEntries.allIds.map((entId, idx) => (
|
||||
<TreeEntry key={idx} entId={entId}/>
|
||||
<TreeEntry key={idx} entId={entId} />
|
||||
))}
|
||||
</div>
|
||||
|
||||
|
@ -28,19 +28,18 @@ const TreeEntry = ({ entId }) => {
|
|||
|
||||
|
||||
|
||||
const state = useSelector(state => state.treeEntries)
|
||||
const treeEntries = useSelector(state => state.treeEntries.byId)
|
||||
const treeEntriesById = useSelector(state => state.treeEntries.byId)
|
||||
const dispatch = useDispatch()
|
||||
|
||||
const visible = useSelector(state => state.treeEntries.visible[entId])
|
||||
|
||||
let obj3d, sketch;
|
||||
|
||||
if (treeEntries[entId].obj3d) {
|
||||
obj3d = treeEntries[entId].obj3d
|
||||
sketch = treeEntries[entId]
|
||||
if (treeEntriesById[entId].obj3d) {
|
||||
obj3d = treeEntriesById[entId].obj3d
|
||||
sketch = treeEntriesById[entId]
|
||||
} else {
|
||||
obj3d = treeEntries[entId]
|
||||
obj3d = treeEntriesById[entId]
|
||||
}
|
||||
let Icon = treeIcons[obj3d.userData.type]
|
||||
|
||||
|
@ -50,14 +49,17 @@ const TreeEntry = ({ entId }) => {
|
|||
return <div className='btn select-none flex justify-start w-full h-7 items-center text-sm'
|
||||
onDoubleClick={() => {
|
||||
if (obj3d.userData.type == 'sketch') {
|
||||
sc.activeSketch && sc.activeSketch.deactivate()
|
||||
|
||||
if (sc.activeSketch) {
|
||||
dispatch({ type: 'finish-sketch' })
|
||||
sc.activeSketch.deactivate()
|
||||
}
|
||||
sketch.activate()
|
||||
|
||||
sc.clearSelection()
|
||||
sc.activeSketch = sketch;
|
||||
dispatch({ type: 'set-dialog', action: 'sketch' })
|
||||
sc.render()
|
||||
} else if (obj3d.userData.featureInfo.length == 2) {
|
||||
dispatch({ type: 'set-dialog', action: 'extrude-edit', target: treeEntriesById[entId] })
|
||||
}
|
||||
|
||||
}}
|
||||
|
@ -116,14 +118,14 @@ const TreeEntry = ({ entId }) => {
|
|||
e.stopPropagation()
|
||||
}}
|
||||
/>
|
||||
<MdRefresh className='btn-green h-full w-auto p-1.5'
|
||||
{/* <MdRefresh className='btn-green h-full w-auto p-1.5'
|
||||
onClick={(e) => {
|
||||
e.stopPropagation()
|
||||
|
||||
sc.refreshNode(entId)
|
||||
sc.render()
|
||||
}}
|
||||
/>
|
||||
/> */}
|
||||
|
||||
{
|
||||
visible ?
|
||||
|
|
16
todo.txt
16
todo.txt
|
@ -32,28 +32,36 @@ extrude dialogue / done
|
|||
better default ent names / done
|
||||
loopfind especially arc, // fixed for single looop, good enough, maybe stretch goal of selecting search start pt
|
||||
dim tag delete //resolved
|
||||
auto update extrude // done
|
||||
extrude edit dialog // done
|
||||
|
||||
|
||||
|
||||
-sometimes unable to hit return and change dimensionk
|
||||
-unable to delete arc
|
||||
hover not clearing sometimes in sketch
|
||||
0.000 artifact
|
||||
|
||||
|
||||
auto update extrude
|
||||
file save, stl export
|
||||
|
||||
reattach sketch
|
||||
|
||||
highlight button to indicate active mode
|
||||
|
||||
|
||||
|
||||
add cancle soft button for line arc
|
||||
|
||||
reattach sketch
|
||||
|
||||
auto snap
|
||||
constraint labels,equal
|
||||
parallel
|
||||
|
||||
parallel // need to add antoher button to feature ,or empty placeholder
|
||||
|
||||
|
||||
tree relation tool tip
|
||||
tree ent renaming
|
||||
vertical and horzontal baseline to dimension to
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue