update worker/db sync model

This commit is contained in:
Stewart Allen 2024-08-10 13:24:01 -04:00
commit 08f67a0ea6
5 changed files with 68 additions and 67 deletions

View file

@ -943,23 +943,22 @@ const tool = {
return log('nothing to union'); return log('nothing to union');
} }
log(`union ${models.length} models`).pin(); log(`union ${models.length} models`).pin();
worker.model_union(models.map(m => { worker
return { id: m.id, matrix: m.matrix } .model_union(models.map(m => m.id))
})) .then(data => {
.then(data => { api.selection.visible(false);
api.selection.visible(false); let group = api.group.new([new mesh.model({
let group = api.group.new([new mesh.model({ file: `union`,
file: `union`, mesh: data
mesh: data })]).promote();
})]).promote(); api.selection.set([ group ]);
api.selection.set([group]); })
}) .catch(error => {
.catch(error => { log(`union error: ${error}`);
log(`union error: ${error}`); })
}) .finally(() => {
.finally(() => { log('union complete').unpin();
log('union complete').unpin(); });
});
}, },
difference(models) { difference(models) {
@ -968,9 +967,7 @@ const tool = {
return log('nothing to diff'); return log('nothing to diff');
} }
log(`diff ${models.length} models`).pin(); log(`diff ${models.length} models`).pin();
worker.model_difference(models.map(m => { worker.model_difference(models.map(m => m.id))
return { id: m.id, matrix: m.matrix }
}))
.then(data => { .then(data => {
api.selection.visible(false); api.selection.visible(false);
let group = api.group.new([new mesh.model({ let group = api.group.new([new mesh.model({
@ -993,9 +990,7 @@ const tool = {
return log('nothing to intersect'); return log('nothing to intersect');
} }
log(`intersect ${models.length} models`).pin(); log(`intersect ${models.length} models`).pin();
worker.model_intersect(models.map(m => { worker.model_intersect(models.map(m => m.id))
return { id: m.id, matrix: m.matrix }
}))
.then(data => { .then(data => {
let group = api.group.new([new mesh.model({ let group = api.group.new([new mesh.model({
file: `intersect`, file: `intersect`,
@ -1019,7 +1014,7 @@ const tool = {
} }
log(`subtract ${models.length} models`).pin(); log(`subtract ${models.length} models`).pin();
worker.model_subtract(models.map(m => { worker.model_subtract(models.map(m => {
return { id: m.id, matrix: m.matrix, tool: m.tool() } return { id: m.id, tool: m.tool() }
})) }))
.then(data => { .then(data => {
let group = api.group.new([new mesh.model({ let group = api.group.new([new mesh.model({

View file

@ -94,7 +94,6 @@ mesh.group = class MeshGroup extends mesh.object {
} }
promote() { promote() {
this.centerModels();
let { dim, mid } = this.bounds; let { dim, mid } = this.bounds;
let { x, y, z } = dim; let { x, y, z } = dim;
let max = Math.max(x, y, z); let max = Math.max(x, y, z);

View file

@ -140,6 +140,10 @@ mesh.model = class MeshModel extends mesh.object {
.attributes.position.array; .attributes.position.array;
} }
get positions() {
return this.geometry.attributes.position.array;
}
get matrix() { get matrix() {
return this.mesh.matrixWorld.elements; return this.mesh.matrixWorld.elements;
} }
@ -188,8 +192,6 @@ mesh.model = class MeshModel extends mesh.object {
this.log('model-rotate', quaternion.toArray()); this.log('model-rotate', quaternion.toArray());
this.geometry.applyQuaternion(quaternion); this.geometry.applyQuaternion(quaternion);
this.updateBounds(); this.updateBounds();
this.persist();
moto.space.update();
} }
scale(x = 1, y = 1, z = 1) { scale(x = 1, y = 1, z = 1) {
@ -197,8 +199,6 @@ mesh.model = class MeshModel extends mesh.object {
if (x === 1 && y === 1 && z === 1) return; if (x === 1 && y === 1 && z === 1) return;
this.geometry.scale(x, y, z); this.geometry.scale(x, y, z);
this.updateBounds(); this.updateBounds();
this.persist();
moto.space.update();
} }
translate(x = 0, y = 0, z = 0) { translate(x = 0, y = 0, z = 0) {
@ -206,7 +206,6 @@ mesh.model = class MeshModel extends mesh.object {
if (!(x || y || z)) return; if (!(x || y || z)) return;
this.geometry.translate(x, y, z); this.geometry.translate(x, y, z);
this.updateBounds(); this.updateBounds();
this.persist();
} }
move(x = 0, y = 0, z = 0) { move(x = 0, y = 0, z = 0) {
@ -222,7 +221,7 @@ mesh.model = class MeshModel extends mesh.object {
return pos; return pos;
} }
pos.set(...arguments); pos.set(...arguments);
this.metaChanged(); this.metaChanged({ pos: pos.toArray() });
return this; return this;
} }
@ -264,6 +263,7 @@ mesh.model = class MeshModel extends mesh.object {
this.log('update-bounds', this.geometry.boundingBox); this.log('update-bounds', this.geometry.boundingBox);
this.updateBoundsBox(); this.updateBoundsBox();
moto.space.update(); moto.space.update();
this.sync();
} }
updateBoundsBox() { updateBoundsBox() {
@ -315,11 +315,7 @@ mesh.model = class MeshModel extends mesh.object {
this.opacity(1); this.opacity(1);
// this ref allows clicks to be traced to models and groups // this ref allows clicks to be traced to models and groups
meh.model = this; meh.model = this;
// persist in db so it can be restored on page load // sync worker, allows raycasting to work
this.persist();
// sync data to worker
worker.model_load({ id: this.id, name: this.file, vertices });
// update bounds
this.updateBounds(); this.updateBounds();
} }
@ -331,29 +327,25 @@ mesh.model = class MeshModel extends mesh.object {
// signal util.box3expand that geometry changed // signal util.box3expand that geometry changed
geo._model_invalid = true; geo._model_invalid = true;
geo.computeVertexNormals(); geo.computeVertexNormals();
// allows raycasting to work
// geo.computeBoundingSphere();
// persist in db so it can be restored on page load
this.persist();
// sync data to worker
worker.model_load({id: this.id, name: this.name, vertices });
// restore wireframe state // restore wireframe state
this.wireframe(was); this.wireframe(was);
// fixup normals // fixup normals
this.normals({refresh: true}); this.normals({refresh: true});
// sync worker, allows raycasting to work
this.updateBounds();
// re-gen face index in surface mode // re-gen face index in surface mode
mesh.api.mode.check(); mesh.api.mode.check();
// allows raycasting to work
// update bounds
this.updateBounds();
} }
rename(file) { rename(file) {
this.file = file; this.file = file;
this.persist(); this.sync();
} }
persist() { // sync to worker and indexeddb for page restoration or worker ops
sync() {
// sync to worker
worker.model_load({ id: this.id, name: this.file, vertices: this.positions });
// persist in db so it can be restored on page load // persist in db so it can be restored on page load
mapp.db.space.put(this.id, { mapp.db.space.put(this.id, {
file: this.file, file: this.file,
@ -556,7 +548,7 @@ mesh.model = class MeshModel extends mesh.object {
// extract axes from plane and split when present (only z for now) // extract axes from plane and split when present (only z for now)
let { z } = plane; let { z } = plane;
return new Promise((resolve,reject) => { return new Promise((resolve,reject) => {
worker.model_split({ pos: this.world_positions, z }).then(data => { worker.model_split({ id: this.id, z }).then(data => {
let { o1, o2 } = data; let { o1, o2 } = data;
let model; let model;
if (o1.length) if (o1.length)

View file

@ -34,7 +34,7 @@ mesh.object = class MeshObject {
} }
log() { log() {
console.log(this.id, this.type, ...arguments); // mesh.api.log.emit(this.id, this.type, ...arguments);
} }
get type() { get type() {
@ -65,6 +65,7 @@ mesh.object = class MeshObject {
this.log('apply-meta', meta); this.log('apply-meta', meta);
this.applyMatrix(meta.matrix); this.applyMatrix(meta.matrix);
this.visible(meta.visible ?? true); this.visible(meta.visible ?? true);
this.metaChanged(meta);
return this; return this;
} }
@ -73,10 +74,8 @@ mesh.object = class MeshObject {
if (elements) { if (elements) {
this.log('apply-matrix'); this.log('apply-matrix');
this.object.applyMatrix4(new Matrix4().fromArray(elements)); this.object.applyMatrix4(new Matrix4().fromArray(elements));
return this.metaChanged();
} else {
return this;
} }
return this;
} }
// used during model splitting // used during model splitting
@ -195,11 +194,14 @@ mesh.object = class MeshObject {
} }
} }
metaChanged() { metaChanged(values = {}) {
this.object.updateMatrix(); this.object.updateMatrix();
this.updateBoundsBox(); this.updateBoundsBox();
space.update(); space.update();
this.meta.matrix = this.object.matrix.elements; Object.assign(this.meta, values, {
matrix: this.object.matrix.elements
});
worker.object_meta({ id: this.id, meta: this.meta });
publish.meta({ id: this.id, meta: this.meta }); publish.meta({ id: this.id, meta: this.meta });
return this; return this;
} }

View file

@ -21,7 +21,7 @@
gapp.main("mesh.work", [], (root) => { gapp.main("mesh.work", [], (root) => {
const { Matrix4, Vector3, BufferGeometry, BufferAttribute, computeFaceNormal } = THREE; const { Matrix4, Vector3, BufferGeometry, BufferAttribute, computeFaceNormal } = THREE;
const { Quaternion } = THREE; const { Quaternion, } = THREE;
const { base, mesh, moto } = root; const { base, mesh, moto } = root;
const { client, worker } = moto; const { client, worker } = moto;
const { util } = mesh; const { util } = mesh;
@ -48,13 +48,19 @@ function cacheUpdate(id, data) {
} }
// translate original mesh vertices into UI world view (PI/2 rotation on X) // translate original mesh vertices into UI world view (PI/2 rotation on X)
function translate_encode(id, matrix) { function translate_encode(id) {
let rec = cache[id]; let rec = cache[id];
let { pos, matrix } = rec;
let mkey = matrix.map(v => v.round(6)).join('-'); let mkey = matrix.map(v => v.round(6)).join('-');
// re-translate on missing cache or changed matrix
if (!rec || !rec.trans || rec.mkey !== mkey) { if (!rec || !rec.trans || rec.mkey !== mkey) {
let geo = rec.geo.clone(); let geo = rec.geo.clone();
let mat = core_matrix.clone().multiply(new Matrix4().fromArray(matrix)); if (pos) {
geo.applyMatrix4(mat); geo.translate(new Vector3().fromArray(pos));
} else {
let mat = core_matrix.clone().multiply(new Matrix4().fromArray(matrix));
geo.applyMatrix4(mat);
}
rec.mkey = mkey; rec.mkey = mkey;
rec.trans = geo.attributes.position.array rec.trans = geo.attributes.position.array
} }
@ -122,22 +128,22 @@ let model = {
return data; return data;
}, },
union(recs) { union(ids) {
let arrays = recs.map(rec => translate_encode(rec.id, rec.matrix)); let arrays = ids.map(id => translate_encode(id));
let solids = arrays.map(a => CSG.fromPositionArray(a)); let solids = arrays.map(a => CSG.fromPositionArray(a));
let union = CSG.union(...solids); let union = CSG.union(...solids);
return CSG.toPositionArray(union); return CSG.toPositionArray(union);
}, },
difference(recs) { difference(ids) {
let arrays = recs.map(rec => translate_encode(rec.id, rec.matrix)); let arrays = ids.map(id => translate_encode(id));
let solids = arrays.map(a => CSG.fromPositionArray(a)); let solids = arrays.map(a => CSG.fromPositionArray(a));
let diff = CSG.difference(...solids); let diff = CSG.difference(...solids);
return CSG.toPositionArray(diff); return CSG.toPositionArray(diff);
}, },
intersect(recs) { intersect(ids) {
let arrays = recs.map(rec => translate_encode(rec.id, rec.matrix)); let arrays = ids.map(id => translate_encode(id));
let solids = arrays.map(a => CSG.fromPositionArray(a)); let solids = arrays.map(a => CSG.fromPositionArray(a));
let union = CSG.intersect(...solids); let union = CSG.intersect(...solids);
return CSG.toPositionArray(union); return CSG.toPositionArray(union);
@ -145,10 +151,10 @@ let model = {
subtract(recs) { subtract(recs) {
let bases = recs.filter(rec => !rec.tool) let bases = recs.filter(rec => !rec.tool)
.map(rec => translate_encode(rec.id, rec.matrix)) .map(rec => translate_encode(rec.id))
.map(a => CSG.fromPositionArray(a)); .map(a => CSG.fromPositionArray(a));
let tools = recs.filter(rec => rec.tool) let tools = recs.filter(rec => rec.tool)
.map(rec => translate_encode(rec.id, rec.matrix)) .map(rec => translate_encode(rec.id))
.map(a => CSG.fromPositionArray(a)); .map(a => CSG.fromPositionArray(a));
let subs = []; let subs = [];
for (let obj of bases) { for (let obj of bases) {
@ -161,7 +167,8 @@ let model = {
// split a model along an axis at a given point // split a model along an axis at a given point
// return two arrays of vertices for each resulting object // return two arrays of vertices for each resulting object
split(data) { split(data) {
let { pos, z } = data; let { id, z } = data;
let pos = translate_encode(id);
let o1 = []; // new bottom let o1 = []; // new bottom
let o2 = []; // new top let o2 = []; // new top
let on = []; let on = [];
@ -372,6 +379,12 @@ let group = {
}; };
let object = { let object = {
meta(data) {
let { id, meta } = data;
cacheUpdate(id, meta);
console.log('object_meta', data);
},
create(data) { create(data) {
let { id, type } = data; let { id, type } = data;
cache[id] = { id, type }; cache[id] = { id, type };