diff --git a/dist/solver.wasm b/dist/solver.wasm
index a4a67f0..29d8128 100755
Binary files a/dist/solver.wasm and b/dist/solver.wasm differ
diff --git a/src/Scene.js b/src/Scene.js
index f06ea0f..da467c9 100644
--- a/src/Scene.js
+++ b/src/Scene.js
@@ -6,7 +6,7 @@ import { TrackballControls } from '../lib/trackball'
import { Sketch } from './Sketch'
import Stats from '../lib/stats.module.js';
-import { extrude } from './extrude'
+import { extrude, flipBufferGeometryNormals } from './extrude'
import { onHover, onPick } from './mouseEvents';
import { _vec2, _vec3, color, awaitSelection, ptObj, setHover } from './shared'
@@ -26,9 +26,19 @@ const eq = (a1, a2) => {
window.loader = new THREE.ObjectLoader();
window.id = 0
+window.sid = 1
+window.mid = 1
+
+
+const pointMaterial = new THREE.PointsMaterial({
+ color: color.selpoint,
+ size: 4,
+})
export class Scene {
constructor(store) {
+ this.sid = 1
+ this.mid = 1
this.store = store;
this.canvas = document.querySelector('#c');
@@ -63,10 +73,14 @@ export class Scene {
for (let i = 0; i < 4; i++) {
- const freePt = ptObj()
+ const freePt = new THREE.Points(
+ new THREE.BufferGeometry().setAttribute('position',
+ new THREE.Float32BufferAttribute(3, 3)
+ ),
+ pointMaterial.clone()
+ )
+
freePt.matrixAutoUpdate = false
- freePt.material.size = 4
- freePt.material.color.set(color.selpoint)
freePt.visible = false
freePt.depthTest = false
freePt.userData.type = 'selpoint'
@@ -160,37 +174,49 @@ export class Scene {
saveState() {
localStorage.setItem(
- 'sv', JSON.stringify([id, this.store.getState()])
+ 'sv2', JSON.stringify([id, this.sid, this.mid, this.store.getState().treeEntries])
)
}
loadState() { //uglyyy
- const [curid, state] = JSON.parse(
- localStorage.getItem('sv')
+ const [curid, cursid, curmid, state] = JSON.parse(
+ localStorage.getItem('sv2')
)
window.id = curid
+ this.sid = cursid
+ this.mid = curmid
- const entries = state.treeEntries.byId
+ const entries = state.byId
for (let k in entries) {
if (k[0] == 's') {
entries[k].obj3d = loader.parse(entries[k].obj3d)
this.obj3d.add(entries[k].obj3d)
- entries[k] = new Sketch(this, state.treeEntries.byId[k])
+ entries[k] = new Sketch(this, state.byId[k])
entries[k].obj3d.addEventListener('change', this.render) // !! took 3 hours to realize
- } else if (k[0] == 'm') {
+ } else if (k[0] == 'e') {
+
+ entries[k] = loader.parse(state.byId[k])
+
+ if (entries[k].userData.inverted) {
+ flipBufferGeometryNormals(entries[k].geometry)
+ }
+
+ this.obj3d.add(entries[k])
+
+ } else {
+ entries[k] = loader.parse(state.byId[k])
- entries[k] = loader.parse(state.treeEntries.byId[k])
- // console.log(entries[k])
this.obj3d.add(entries[k])
}
}
this.store.dispatch({ type: 'restore-state', state })
+ return state
}
clearSelection() {
@@ -244,8 +270,9 @@ export class Scene {
let mesh = CSG.toMesh(bspResult, m1.matrix, m1.material)
mesh.userData.type = 'mesh'
+ mesh.userData.featureInfo = [m1.name, m2.name, op]
- mesh.name = `(${m1.name}${opChar}${m2.name})`
+ mesh.name = `(${m1.name} ${opChar} ${m2.name})`
mesh.layers.enable(1)
const vertices = new THREE.Points(mesh.geometry, new THREE.PointsMaterial({ size: 0 }));
@@ -288,7 +315,7 @@ function render() {
this.renderer.render(this.obj3d, this.camera);
if (this.activeSketch) {
- dims = this.activeSketch.obj3d.children[1].children
+ dims = this.activeSketch.dimGroup.children
matrix = this.activeSketch.obj3d.matrix
for (idx = 1; idx < dims.length; idx += 2) {
@@ -347,7 +374,7 @@ async function addSketch() {
}
window.sc = new Scene(store)
-// sc.loadState()
+sc.loadState()
// sc.camera.layers.enable(1)
// rc.layers.set(1)
\ No newline at end of file
diff --git a/src/Sketch.js b/src/Sketch.js
index 09fcece..bece5c6 100644
--- a/src/Sketch.js
+++ b/src/Sketch.js
@@ -5,7 +5,7 @@ import * as THREE from '../node_modules/three/src/Three';
import { _vec2, _vec3, raycaster, awaitSelection, ptObj, setHover } from './shared'
import { drawOnClick1, drawOnClick2, drawPreClick2, drawOnClick3, drawPreClick3, drawClear, drawPoint } from './drawEvents'
-import { onHover, onDrag, onPick, onRelease} from './mouseEvents'
+import { onHover, onDrag, onPick, onRelease } from './mouseEvents'
import { setCoincident, setOrdinate, setTangent } from './constraintEvents'
import { get3PtArc } from './drawArc'
import { replacer, reviver } from './utils'
@@ -37,7 +37,7 @@ class Sketch {
if (preload === undefined) {
this.obj3d = new THREE.Group()
- this.obj3d.name = "s" + id++
+ this.obj3d.name = "s" + scene.sid++
this.obj3d.userData.type = "sketch"
this.obj3d.matrixAutoUpdate = false;
@@ -50,8 +50,10 @@ class Sketch {
this.c_id = 1;
this.obj3d.add(new THREE.Group());
- this.obj3d.add(new THREE.Group());
- this.obj3d.add(new THREE.Group());
+
+ this.geomStartIdx = this.obj3d.children.length
+ this.obj3d.userData.geomStartIdx = this.geomStartIdx
+ this.dimGroup = this.obj3d.children[this.geomStartIdx - 1]
this.labels = []
@@ -80,6 +82,8 @@ class Sketch {
this.constraints = JSON.parse(preload.constraints, reviver)
this.c_id = preload.c_id;
+ this.geomStartIdx = this.obj3d.userData.geomStartIdx
+ this.dimGroup = this.obj3d.children[this.geomStartIdx - 1]
this.updatePointsBuffer()
this.updateOtherBuffers()
@@ -385,13 +389,14 @@ class Sketch {
updateBoundingSpheres() {
- for (let x = 3; x < this.obj3d.children.length; x++) { // geometry boundign spheres
+
+ for (let x = this.geomStartIdx; x < this.obj3d.children.length; x++) { // geometry boundign spheres
const obj = this.obj3d.children[x]
obj.geometry.computeBoundingSphere()
}
- for (let x = 0; x < this.obj3d.children[1].children.length; x++) { // dimension bounding sphere
- const obj = this.obj3d.children[1].children[x]
+ for (let x = 0; x < this.dimGroup.children.length; x++) { // dimension bounding sphere
+ const obj = this.dimGroup.children[x]
obj.geometry.computeBoundingSphere()
}
}
@@ -432,16 +437,16 @@ class Sketch {
Module["_solver"](
this.obj3d.children.length, pts_buffer,
this.constraints.size, constraints_buffer,
- this.linkedObjs.size, links_buffer)
+ this.linkedObjs.size, links_buffer,
+ this.geomStartIdx
+ )
/*
- loop to update all the children that are points
- - why +6? we skip first two triplets because it refers to a non-geometry children
- we also sneak in updating lines children as well, by checking when ptsBuf[ptr] is NaN
*/
- for (let i = 3, ptr = (pts_buffer >> 2) + 9; i < this.obj3d.children.length; i += 1, ptr += 3) {
- // for (let i = 0, ptr = (pts_buffer >> 2) + 3; i < this.obj3d.children.length; i += 1, ptr += 3) {
+ for (let i = this.geomStartIdx, ptr = (pts_buffer >> 2) + this.geomStartIdx * 3; i < this.obj3d.children.length; i += 1, ptr += 3) {
const pos = this.obj3d.children[i].geometry.attributes.position;
if (isNaN(Module.HEAPF32[ptr])) {
diff --git a/src/drawDimension.js b/src/drawDimension.js
index 5d357f0..ea7b5fe 100644
--- a/src/drawDimension.js
+++ b/src/drawDimension.js
@@ -92,7 +92,7 @@ export async function drawDimension() {
line.layers.enable(2)
point.layers.enable(2)
- this.obj3d.children[1].add(line).add(point)
+ this.dimGroup.add(line).add(point)
const onMove = this._onMoveDimension(point, line)
point.label = document.createElement('div');
point.label.textContent = dimVal.toFixed(3);
@@ -138,7 +138,7 @@ export async function drawDimension() {
} else {
- this.obj3d.children[1].children.splice(this.obj3d.children[1].length - 2, 2).forEach(
+ this.dimGroup.children.splice(this.dimGroup.length - 2, 2).forEach(
e => {
e.geometry.dispose()
e.material.dispose()
@@ -209,7 +209,7 @@ export function _onMoveDimension(point, line) {
export function setDimLines() {
const restoreLabels = this.labelContainer.childElementCount == 0;
- const dims = this.obj3d.children[1].children
+ const dims = this.dimGroup.children
let point, dist;
for (let i = 0; i < dims.length; i += 2) {
if (restoreLabels) {
diff --git a/src/extrude.js b/src/extrude.js
index 9c68abf..665c5ec 100644
--- a/src/extrude.js
+++ b/src/extrude.js
@@ -1,7 +1,7 @@
import * as THREE from '../node_modules/three/src/Three';
-import { color} from './shared'
+import { color } from './shared'
export function extrude(sketch, depth) {
- console.log(sketch,'here')
+ console.log(sketch, 'here')
let constraints = sketch.constraints;
let linkedObjs = sketch.linkedObjs;
@@ -68,20 +68,43 @@ export function extrude(sketch, depth) {
findPair(children[4]) //??? need fixing
const shape = new THREE.Shape(v2s);
+ // const extrudeSettings = { depth: Math.abs(depth), bevelEnabled: false };
const extrudeSettings = { depth, bevelEnabled: false };
const geometry = new THREE.ExtrudeGeometry(shape, extrudeSettings);
// const material = new THREE.MeshLambertMaterial({
- const material = new THREE.MeshPhongMaterial({
- color: color.mesh,
- emissive: color.emissive,
- });
+ // const material = new THREE.MeshPhongMaterial({
+ // color: color.mesh,
+ // emissive: color.emissive,
+ // });
- const mesh = new THREE.Mesh(geometry, material)
- mesh.name = 'm' + id++
+ // const mesh = new THREE.Mesh(geometry, material)
+
+ // const material = new THREE.MeshPhongMaterial({
+ // color: color.mesh,
+ // });
+ // const wireframe = new THREE.EdgesGeometry( geometry );
+ // const mesh = new THREE.LineSegments( wireframe );
+ // // mesh.material.depthTest = false;
+ // // mesh.material.opacity = 0.25;
+ // // mesh.material.transparent = true;
+ // mesh.material.transparent = false;
+
+ const edges = new THREE.EdgesGeometry( geometry, 15 );
+ edges.type = 'BufferGeometry'
+ edges.parameters = undefined
+
+ const mesh = new THREE.LineSegments( edges, new THREE.LineBasicMaterial( { color: 0x000000 } ) );
+
+
+
+ mesh.name = 'e' + this.mid++
+ // mesh.name = 'm' + sketch.obj3d.name.slice(1)
+ // mesh.name = 'e' + sketch.obj3d.name.slice(1)
mesh.userData.type = 'mesh'
+ mesh.userData.featureInfo = [sketch.obj3d.name, depth]
mesh.layers.enable(1)
const vertices = new THREE.Points(mesh.geometry, new THREE.PointsMaterial({ size: 0 }));
@@ -89,13 +112,27 @@ export function extrude(sketch, depth) {
vertices.layers.enable(1)
mesh.add(vertices)
+
+
+
+
+
+
+
mesh.matrixAutoUpdate = false;
mesh.matrix.multiply(sketch.obj3d.matrix)
+ if (depth < 0) {
+ flipBufferGeometryNormals(mesh.geometry)
+ mesh.userData.inverted = true
+ }
+
+
this.obj3d.add(mesh)
this.store.dispatch({ type: 'rx-extrusion', mesh, sketchId: sketch.obj3d.name })
+ // sketch.userData
if (this.activeSketch == sketch) {
this.activeSketch = null
sketch.deactivate()
@@ -107,3 +144,75 @@ export function extrude(sketch, depth) {
+
+
+
+export function flipBufferGeometryNormals(geometry) {
+ //https://stackoverflow.com/a/54496265
+ const tempXYZ = [0, 0, 0];
+
+ // flip normals
+ for (let i = 0; i < geometry.attributes.normal.array.length / 9; i++) {
+ // cache a coordinates
+ tempXYZ[0] = geometry.attributes.normal.array[i * 9];
+ tempXYZ[1] = geometry.attributes.normal.array[i * 9 + 1];
+ tempXYZ[2] = geometry.attributes.normal.array[i * 9 + 2];
+
+ // overwrite a with c
+ geometry.attributes.normal.array[i * 9] =
+ geometry.attributes.normal.array[i * 9 + 6];
+ geometry.attributes.normal.array[i * 9 + 1] =
+ geometry.attributes.normal.array[i * 9 + 7];
+ geometry.attributes.normal.array[i * 9 + 2] =
+ geometry.attributes.normal.array[i * 9 + 8];
+
+ // overwrite c with stored a values
+ geometry.attributes.normal.array[i * 9 + 6] = tempXYZ[0];
+ geometry.attributes.normal.array[i * 9 + 7] = tempXYZ[1];
+ geometry.attributes.normal.array[i * 9 + 8] = tempXYZ[2];
+ }
+
+ // change face winding order
+ for (let i = 0; i < geometry.attributes.position.array.length / 9; i++) {
+ // cache a coordinates
+ tempXYZ[0] = geometry.attributes.position.array[i * 9];
+ tempXYZ[1] = geometry.attributes.position.array[i * 9 + 1];
+ tempXYZ[2] = geometry.attributes.position.array[i * 9 + 2];
+
+ // overwrite a with c
+ geometry.attributes.position.array[i * 9] =
+ geometry.attributes.position.array[i * 9 + 6];
+ geometry.attributes.position.array[i * 9 + 1] =
+ geometry.attributes.position.array[i * 9 + 7];
+ geometry.attributes.position.array[i * 9 + 2] =
+ geometry.attributes.position.array[i * 9 + 8];
+
+ // overwrite c with stored a values
+ geometry.attributes.position.array[i * 9 + 6] = tempXYZ[0];
+ geometry.attributes.position.array[i * 9 + 7] = tempXYZ[1];
+ geometry.attributes.position.array[i * 9 + 8] = tempXYZ[2];
+ }
+
+ // flip UV coordinates
+ for (let i = 0; i < geometry.attributes.uv.array.length / 6; i++) {
+ // cache a coordinates
+ tempXYZ[0] = geometry.attributes.uv.array[i * 6];
+ tempXYZ[1] = geometry.attributes.uv.array[i * 6 + 1];
+
+ // overwrite a with c
+ geometry.attributes.uv.array[i * 6] =
+ geometry.attributes.uv.array[i * 6 + 4];
+ geometry.attributes.uv.array[i * 6 + 1] =
+ geometry.attributes.uv.array[i * 6 + 5];
+
+ // overwrite c with stored a values
+ geometry.attributes.uv.array[i * 6 + 4] = tempXYZ[0];
+ geometry.attributes.uv.array[i * 6 + 5] = tempXYZ[1];
+ }
+
+ geometry.attributes.normal.needsUpdate = true;
+ geometry.attributes.position.needsUpdate = true;
+ geometry.attributes.uv.needsUpdate = true;
+}
+
+
diff --git a/src/mouseEvents.js b/src/mouseEvents.js
index 45a2e04..213c8d0 100644
--- a/src/mouseEvents.js
+++ b/src/mouseEvents.js
@@ -24,7 +24,7 @@ export function onHover(e) {
} else {
// raycaster.layers.set(0)
raycaster.layers.set(2)
- hoverPts = raycaster.intersectObjects([...this.obj3d.children[1].children, ...this.obj3d.children])
+ hoverPts = raycaster.intersectObjects([...this.dimGroup.children, ...this.obj3d.children])
}
@@ -171,27 +171,26 @@ export function onPick(e) {
switch (obj.userData.type) {
case 'dimension':
- const idx = this.obj3d.children[1].children.indexOf(this.hovered[0])
+ const idx = this.dimGroup.children.indexOf(this.hovered[0])
if (idx % 2) { // we only allow tag point (odd idx) to be dragged
this.onDragDim = this._onMoveDimension(
- this.obj3d.children[1].children[idx],
- this.obj3d.children[1].children[idx - 1],
+ this.dimGroup.children[idx],
+ this.dimGroup.children[idx - 1],
)
this.canvas.addEventListener('pointermove', this.onDragDim);
this.canvas.addEventListener('pointerup', () => {
- onDimMoveEnd(this.obj3d.children[1].children[idx])
+ onDimMoveEnd(this.dimGroup.children[idx])
this.onRelease()
})
}
- draggedLabel = this.obj3d.children[1].children[idx].label
+ draggedLabel = this.dimGroup.children[idx].label
draggedLabel.style.zIndex = -1;
break;
case 'point':
this.canvas.addEventListener('pointermove', this.onDrag);
this.canvas.addEventListener('pointerup', () => {
- // onDimMoveEnd(this.obj3d.children[1].children[idx])
this.onRelease()
})
break;
diff --git a/src/react/app.css b/src/react/app.css
index 0326244..0569650 100644
--- a/src/react/app.css
+++ b/src/react/app.css
@@ -86,4 +86,22 @@ body {
border: solid 6px transparent;
border-bottom-color: white;
border-top: none;
-}
\ No newline at end of file
+}
+
+input::-webkit-outer-spin-button,
+input::-webkit-inner-spin-button {
+ -webkit-appearance: none;
+ margin: 0;
+}
+
+/* Firefox */
+input[type=number] {
+ -moz-appearance: textfield;
+ border:none;
+ background-color:transparent;
+ outline: none;
+ text-align:right;
+}
+
+/* input:focus[type=number] { */
+/* } */
diff --git a/src/react/app.jsx b/src/react/app.jsx
index 2c84bc1..95afbdd 100644
--- a/src/react/app.jsx
+++ b/src/react/app.jsx
@@ -26,7 +26,10 @@ const preloadedState = {
}
// const store = createStore(reducer, preloadedState, applyMiddleware(logger))
+
+
const store = createStore(reducer, {}, applyMiddleware(logger))
+// const store = createStore(reducer, sc.loadState(), applyMiddleware(logger))
const App = ({ store }) => {
const [dialog, setDialog] = useState()
@@ -34,7 +37,7 @@ const App = ({ store }) => {
return