rearrange layout
parent
3b49000e2b
commit
b6bc0cb2e0
105
src/app.jsx
105
src/app.jsx
|
@ -47,13 +47,14 @@ const App = () => {
|
||||||
,
|
,
|
||||||
[FaCube, () => sc.extrude(treeEntries.byId[activeSketchId]), 'Extrude'],
|
[FaCube, () => sc.extrude(treeEntries.byId[activeSketchId]), 'Extrude'],
|
||||||
[Icon.Union, () => sc.extrude(treeEntries.byId[activeSketchId]), 'Union'],
|
[Icon.Union, () => sc.extrude(treeEntries.byId[activeSketchId]), 'Union'],
|
||||||
[Icon.Subtract, ()=> {
|
[Icon.Subtract, () => {
|
||||||
if (sc.selected.length != 2 || !sc.selected.every(e => e.userData.type == 'mesh')) return
|
if (sc.selected.length != 2 || !sc.selected.every(e => e.userData.type == 'mesh')) return
|
||||||
// console.log('here')
|
// console.log('here')
|
||||||
const [m1, m2] = sc.selected
|
const [m1, m2] = sc.selected
|
||||||
const mesh = subtract(m1,m2)
|
const mesh = subtract(m1, m2)
|
||||||
|
|
||||||
dispatch({ type: 'rx-extrusion', mesh, deps:[m1.name,m2.name] })
|
console.log(mesh, 'meshres')
|
||||||
|
dispatch({ type: 'rx-boolean', mesh, deps: [m1.name, m2.name] })
|
||||||
sc.render()
|
sc.render()
|
||||||
forceUpdate()
|
forceUpdate()
|
||||||
}, 'Subtract'],
|
}, 'Subtract'],
|
||||||
|
@ -65,19 +66,21 @@ const App = () => {
|
||||||
|
|
||||||
const [_, forceUpdate] = useReducer(x => x + 1, 0);
|
const [_, forceUpdate] = useReducer(x => x + 1, 0);
|
||||||
|
|
||||||
return <div className='absolute left-0 w-40 flex flex-col'>
|
return <div className=''>
|
||||||
|
<div className='absolute flex'>
|
||||||
{
|
{
|
||||||
btnz.map(([Icon, fcn, txt], idx) => (
|
btnz.map(([Icon, fcn, txt], idx) => (
|
||||||
<div className="btn flex items-center justify-end p-1 text-lg" key={idx}
|
<div className="btn flex items-center justify-start p-1 text-lg" key={idx}
|
||||||
onClick={fcn}
|
onClick={fcn}
|
||||||
>
|
>
|
||||||
<div>{txt}</div>
|
<Icon className="w-6 h-6" />
|
||||||
<Icon className="w-6 h-6 ml-1" />
|
<div className="ml-2">{txt}</div>
|
||||||
</div>
|
</div>
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
</div>
|
||||||
|
|
||||||
<div className=''>
|
<div className='absolute left-0 top-10 w-40 flex flex-col'>
|
||||||
{treeEntries.allIds.map((entId, idx) => (
|
{treeEntries.allIds.map((entId, idx) => (
|
||||||
<TreeEntry key={idx} entId={entId} />
|
<TreeEntry key={idx} entId={entId} />
|
||||||
))}
|
))}
|
||||||
|
@ -109,46 +112,6 @@ const TreeEntry = ({ entId }) => {
|
||||||
const vis = obj3d.visible
|
const vis = obj3d.visible
|
||||||
|
|
||||||
return <div className='bg-gray-50 flex justify-between w-full'>
|
return <div className='bg-gray-50 flex justify-between w-full'>
|
||||||
<div className='btn'
|
|
||||||
onClick={() => {
|
|
||||||
activeSketchId && treeEntries[activeSketchId].deactivate()
|
|
||||||
entry.activate()
|
|
||||||
sc.activeSketch = entry;
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<MdEdit />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className='btn'
|
|
||||||
onClick={() => {
|
|
||||||
dispatch({type:'delete-node',id:entId})
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<MdDelete/>
|
|
||||||
</div>
|
|
||||||
{
|
|
||||||
vis ?
|
|
||||||
<div className='btn'
|
|
||||||
onClick={() => {
|
|
||||||
obj3d.visible = false;
|
|
||||||
sc.render()
|
|
||||||
forceUpdate()
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<MdVisibility />
|
|
||||||
</div>
|
|
||||||
:
|
|
||||||
<div className='btn'
|
|
||||||
onClick={() => {
|
|
||||||
obj3d.visible = true;
|
|
||||||
sc.render()
|
|
||||||
forceUpdate()
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<MdVisibilityOff />
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
|
|
||||||
<div className="btn"
|
<div className="btn"
|
||||||
onPointerEnter={() => {
|
onPointerEnter={() => {
|
||||||
if (entId[0] == 'm') {
|
if (entId[0] == 'm') {
|
||||||
|
@ -174,11 +137,53 @@ const TreeEntry = ({ entId }) => {
|
||||||
>
|
>
|
||||||
{entId}
|
{entId}
|
||||||
</div>
|
</div>
|
||||||
|
<div className='flex'>
|
||||||
|
<div className='btn'
|
||||||
|
onClick={() => {
|
||||||
|
activeSketchId && treeEntries[activeSketchId].deactivate()
|
||||||
|
entry.activate()
|
||||||
|
sc.activeSketch = entry;
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<MdEdit />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className='btn'
|
||||||
|
onClick={() => {
|
||||||
|
dispatch({ type: 'delete-node', id: entId })
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<MdDelete />
|
||||||
|
</div>
|
||||||
|
{
|
||||||
|
vis ?
|
||||||
|
<div className='btn'
|
||||||
|
onClick={() => {
|
||||||
|
obj3d.visible = false;
|
||||||
|
sc.render()
|
||||||
|
forceUpdate()
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<MdVisibility />
|
||||||
|
</div>
|
||||||
|
:
|
||||||
|
<div className='btn'
|
||||||
|
onClick={() => {
|
||||||
|
obj3d.visible = true;
|
||||||
|
sc.render()
|
||||||
|
forceUpdate()
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<MdVisibilityOff />
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const subtract = (m1,m2) => {
|
const subtract = (m1, m2) => {
|
||||||
// //Create a bsp tree from each of the meshes
|
// //Create a bsp tree from each of the meshes
|
||||||
// console.log(sc.selected.length != 2 || !sc.selected.every(e => e.userData.type == 'mesh'), "wtf")
|
// console.log(sc.selected.length != 2 || !sc.selected.every(e => e.userData.type == 'mesh'), "wtf")
|
||||||
|
|
||||||
|
@ -196,7 +201,7 @@ const subtract = (m1,m2) => {
|
||||||
|
|
||||||
let meshResult = BoolOp.toMesh(bspResult, m1.matrix, m1.material)
|
let meshResult = BoolOp.toMesh(bspResult, m1.matrix, m1.material)
|
||||||
meshResult.userData.type = 'mesh'
|
meshResult.userData.type = 'mesh'
|
||||||
meshResult.userData.name = `${m1.name}-${m2.name}`
|
meshResult.name = `${m1.name}-${m2.name}`
|
||||||
|
|
||||||
sc.obj3d.add(meshResult)
|
sc.obj3d.add(meshResult)
|
||||||
|
|
||||||
|
|
|
@ -1,102 +0,0 @@
|
||||||
class DepTree {
|
|
||||||
constructor() {
|
|
||||||
this.tree = {}
|
|
||||||
this.order = {}
|
|
||||||
this.arr = []
|
|
||||||
}
|
|
||||||
|
|
||||||
addParent(id) {
|
|
||||||
if (this.tree[id]) return
|
|
||||||
this.tree[id] = new Set()
|
|
||||||
this.order[id] = this.arr.length
|
|
||||||
this.arr.push(id)
|
|
||||||
}
|
|
||||||
|
|
||||||
addChild(childId, ...parentIds) {
|
|
||||||
for (let parentId of parentIds) {
|
|
||||||
this.tree[parentId].add(childId)
|
|
||||||
}
|
|
||||||
|
|
||||||
this.addParent(childId)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
deleteNode(id) {
|
|
||||||
this.visited = new Set()
|
|
||||||
|
|
||||||
this.nodesToDel = []
|
|
||||||
this.dfs(id)
|
|
||||||
|
|
||||||
const idx = []
|
|
||||||
this.nodesToDel.sort((a, b) => this.order[b] - this.order[a])
|
|
||||||
|
|
||||||
for (let id of this.nodesToDel) {
|
|
||||||
idx.push(this.order[id])
|
|
||||||
this.arr.splice(this.order[id], 1)
|
|
||||||
delete this.tree[id]
|
|
||||||
delete this.order[id]
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let i = idx[idx.length - 1]; i < this.arr.length; i++) {
|
|
||||||
this.order[this.arr[i]] = i
|
|
||||||
}
|
|
||||||
|
|
||||||
const nodeToDelSet = new Set(this.nodesToDel)
|
|
||||||
|
|
||||||
for (let k in this.tree) {
|
|
||||||
for (let ent of this.tree[k]) {
|
|
||||||
if (nodeToDelSet.has(ent)) {
|
|
||||||
this.tree[k].delete(ent)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return idx
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
dfs(id) {
|
|
||||||
this.visited.add(id)
|
|
||||||
this.nodesToDel.push(id)
|
|
||||||
for (let x of this.tree[id]) {
|
|
||||||
if (!this.visited.has(x)) {
|
|
||||||
this.dfs(x)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const dt = new DepTree()
|
|
||||||
|
|
||||||
|
|
||||||
dt.addParent('r1')
|
|
||||||
dt.addParent('r2')
|
|
||||||
|
|
||||||
|
|
||||||
dt.addChild('r3', 'r1', 'r2')
|
|
||||||
|
|
||||||
dt.addParent('r4')
|
|
||||||
|
|
||||||
dt.addChild('r5', 'r4', 'r3')
|
|
||||||
|
|
||||||
dt.addChild('r6', 'r1', 'r5')
|
|
||||||
|
|
||||||
dt.addChild('r7', 'r3', 'r5')
|
|
||||||
|
|
||||||
|
|
||||||
// const x = dt.deleteNode('r3')
|
|
||||||
|
|
||||||
// console.log(x)
|
|
||||||
// console.log(dt.arr, dt.order)
|
|
||||||
|
|
||||||
// expectd output
|
|
||||||
// [ 6, 5, 4, 2 ]
|
|
||||||
// [ 'r1', 'r2', 'r4' ] { r1: 0, r2: 1, r4: 2 }
|
|
||||||
|
|
||||||
|
|
||||||
const x = dt.deleteNode('r5')
|
|
||||||
|
|
||||||
console.log(x)
|
|
||||||
console.log(dt.tree)
|
|
|
@ -1,7 +1,6 @@
|
||||||
export class DepTree {
|
export class DepTree {
|
||||||
constructor(obj) {
|
constructor(obj) {
|
||||||
if (obj) {
|
if (obj) {
|
||||||
console.log('load', obj)
|
|
||||||
this.order = { ...obj.order }
|
this.order = { ...obj.order }
|
||||||
this.byId = { ...obj.byId }
|
this.byId = { ...obj.byId }
|
||||||
this.allIds = [...obj.allIds]
|
this.allIds = [...obj.allIds]
|
||||||
|
|
17
src/index.js
17
src/index.js
|
@ -42,11 +42,26 @@ function reducer(state = {}, action) {
|
||||||
allIds: { $push: [action.mesh.name] },
|
allIds: { $push: [action.mesh.name] },
|
||||||
tree: {
|
tree: {
|
||||||
[action.sketchId]: { [action.mesh.name]: { $set: true } },
|
[action.sketchId]: { [action.mesh.name]: { $set: true } },
|
||||||
|
[action.mesh.name]: { $set: {} }
|
||||||
},
|
},
|
||||||
order: { [action.mesh.name]: { $set: state.treeEntries.allIds.length } }
|
order: { [action.mesh.name]: { $set: state.treeEntries.allIds.length } }
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
case 'rx-boolean':
|
||||||
|
|
||||||
|
return update(state, {
|
||||||
|
treeEntries: {
|
||||||
|
byId: {
|
||||||
|
[action.mesh.name]: { $set: action.mesh }
|
||||||
|
},
|
||||||
|
allIds: { $push: [action.mesh.name] },
|
||||||
|
tree: {
|
||||||
|
[action.deps[0]]: { [action.mesh.name]: { $set: true } },
|
||||||
|
[action.deps[1]]: { [action.mesh.name]: { $set: true } },
|
||||||
|
},
|
||||||
|
order: { [action.mesh.name]: { $set: state.treeEntries.allIds.length } }
|
||||||
|
}
|
||||||
|
})
|
||||||
case 'delete-node':
|
case 'delete-node':
|
||||||
|
|
||||||
const depTree = new DepTree(state.treeEntries)
|
const depTree = new DepTree(state.treeEntries)
|
||||||
|
@ -55,7 +70,7 @@ function reducer(state = {}, action) {
|
||||||
|
|
||||||
|
|
||||||
return update(state, {
|
return update(state, {
|
||||||
treeEntries: {$set: obj}
|
treeEntries: { $set: obj }
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
10
todo.txt
10
todo.txt
|
@ -2,10 +2,14 @@ fix css on design tree (a lot of work) \
|
||||||
clear dim on exit exit sketch / rehydrate when back or after loading \\\ done
|
clear dim on exit exit sketch / rehydrate when back or after loading \\\ done
|
||||||
|
|
||||||
boolean flesh out refresh / replace mesh / delete mesh
|
boolean flesh out refresh / replace mesh / delete mesh
|
||||||
- need to auto hide ( consume) when new boolean created
|
- need to auto hide ( consume) when new boolean created \\
|
||||||
- create derived part using relationship as name
|
- create derived part using relationship as name \\ done
|
||||||
- sensible default names, like extrude 1, sketch 1, leverage react for this
|
- sensible default names, like extrude 1, sketch 1, leverage react for this
|
||||||
- hidden bodies messes up hover highlight
|
- hidden bodies messes up hover highlight \\ fixed
|
||||||
|
- add for union and intersect
|
||||||
|
- auto update
|
||||||
|
|
||||||
|
- consume skeches after extrude
|
||||||
|
|
||||||
extrude edit dialog. directio and magnitude
|
extrude edit dialog. directio and magnitude
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue