grid-apps-cmms/src/mesh/work.js

177 lines
5.5 KiB
JavaScript
Raw Normal View History

/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
"use strict";
(function() {
// start worker pool (disabled for now with *0)
moto.client.start(`/code/mesh_pool?${gapp.version}`, moto.client.max() * 0);
// dep: ext.three
// dep: ext.three-bgu
gapp.finalize("mesh.work", [
"moto.license", // dep: moto.license
2021-12-29 17:20:17 -05:00
"moto.client", // dep: moto.client
"moto.worker", // dep: moto.worker
"mesh.tool", // dep: mesh.tool
2021-12-31 22:11:20 -05:00
"add.three", // dep: add.three
]);
2021-12-27 18:13:11 -05:00
2021-12-31 22:11:20 -05:00
// compensation for space/world/platform rotation
2022-01-02 16:30:05 -05:00
let core_matrix = new THREE.Matrix4().makeRotationX(Math.PI / 2);
2021-12-31 22:11:20 -05:00
let { client, worker } = moto;
2022-01-01 22:39:49 -05:00
let cache = {};
2022-01-07 18:53:49 -05:00
function log(msg) {
return worker.publish("mesh.log", msg);
}
function cacheUpdate(id, data) {
Object.assign(cache[id], data);
}
2022-01-08 21:00:19 -05:00
function translate_encode(id, matrix) {
let rec = cache[id];
let geo = rec.geo.clone();
geo.applyMatrix4(core_matrix.clone().multiply( new THREE.Matrix4().fromArray(matrix) ));
return geo.attributes.position.array;
}
let model = {
load(data) {
2022-01-04 01:11:13 -05:00
let { vertices, indices, name, id } = data;
let geo = new THREE.BufferGeometry();
geo.setAttribute('position', new THREE.BufferAttribute(vertices, 3));
2022-01-04 01:11:13 -05:00
if (indices) geo.setIndex(new THREE.BufferAttribute(indices, 1));
2022-01-02 16:30:05 -05:00
cacheUpdate(id, { name, geo, matrix: core_matrix.clone() });
},
debug(data) {
2022-01-08 21:00:19 -05:00
let { id, matrix } = data;
return translate_encode(id, matrix);
throw "should not here";
let rec = cache[id];
let geo = rec.geo.clone();
2022-01-02 16:30:05 -05:00
let m4 = core_matrix.clone().multiply( new THREE.Matrix4().fromArray(matrix) );
geo.applyMatrix4(m4);
// for debugging state / matrix ops
return geo.attributes.position.array;
2022-01-03 22:57:19 -05:00
},
heal(id) {
2022-01-07 18:53:49 -05:00
log(`${id} | indexing...`);
2022-01-04 01:11:13 -05:00
let geo = cache[id].geo;
2022-01-03 22:57:19 -05:00
let tool = new mesh.tool({
2022-01-04 01:11:13 -05:00
vertices: geo.attributes.position.array,
faces: geo.index ? geo.index.array : undefined,
debug: false
2022-01-03 22:57:19 -05:00
});
2022-01-07 18:53:49 -05:00
log(`${id} | healing...`);
2022-01-04 09:48:36 -05:00
tool.heal();
2022-01-03 22:57:19 -05:00
dbug.log(tool);
2022-01-04 01:11:13 -05:00
return true || tool.newFaces ? {
2022-01-05 09:29:27 -05:00
vertices: tool.unrolled().toFloat32(),
2022-01-03 22:57:19 -05:00
} : 0;
}
};
let group = {
add(data) {
let { id, model } = data;
},
remove(data) {
let { id, model } = data;
}
};
let object = {
create(data) {
let { id, type } = data;
cache[id] = { id, type };
},
destroy(data) {
delete cache[data.id];
}
};
2022-01-08 21:00:19 -05:00
let file = {
export(data, send) {
2022-01-11 10:04:07 -05:00
let header = `# Generated By Mesh:Tool @ https://grid.space/mesh (units = millimeters)`;
2022-01-08 21:00:19 -05:00
let { format, recs } = data;
let vtot = 0;
for (let rec of recs) {
let { id, matrix, file } = rec;
let vs = rec.varr = Array.from(translate_encode(id, matrix)).map(v => v.round(5));
vtot += (vs.length / 3);
}
2022-01-08 21:00:19 -05:00
switch (format) {
case "obj":
let p = 1;
2022-01-11 10:04:07 -05:00
let obj = [header];
2022-01-08 21:00:19 -05:00
for (let rec of recs) {
let { id, matrix, file, varr } = rec;
2022-01-08 21:00:19 -05:00
obj.push(`g ${file}`);
for (let i=0; i<varr.length; p += 3) {
obj.push(`v ${varr[i++]} ${varr[i++]} ${varr[i++]}`);
obj.push(`v ${varr[i++]} ${varr[i++]} ${varr[i++]}`);
obj.push(`v ${varr[i++]} ${varr[i++]} ${varr[i++]}`);
2022-01-08 21:00:19 -05:00
obj.push(`f ${p} ${p+1} ${p+2}`);
}
}
return obj.join('\n');
case "stl":
let stl = new Uint8Array(80 + 4 + vtot/3 * 50);
let dat = new DataView(stl.buffer);
let pos = 84;
2022-01-11 10:04:07 -05:00
header.split('').forEach((c,i) => {
dat.setUint8(i, c.charCodeAt(0));
});
// todo put Kiri:Moto info in header
dat.setInt32(80, vtot/3, true);
for (let rec of recs) {
let { id, matrix, file, varr } = rec;
for (let i=0, l=varr.length; i<l;) {
let p0 = new THREE.Vector3(varr[i++], varr[i++], varr[i++]);
let p1 = new THREE.Vector3(varr[i++], varr[i++], varr[i++]);
let p2 = new THREE.Vector3(varr[i++], varr[i++], varr[i++]);
let norm = THREE.computeFaceNormal(p0, p1, p2);
dat.setFloat32(pos + 0, norm.x, true);
dat.setFloat32(pos + 4, norm.y, true);
dat.setFloat32(pos + 8, norm.z, true);
dat.setFloat32(pos + 12, p0.x, true);
dat.setFloat32(pos + 16, p0.y, true);
dat.setFloat32(pos + 20, p0.z, true);
dat.setFloat32(pos + 24, p1.x, true);
dat.setFloat32(pos + 28, p1.y, true);
dat.setFloat32(pos + 32, p1.z, true);
dat.setFloat32(pos + 36, p2.x, true);
dat.setFloat32(pos + 40, p2.y, true);
dat.setFloat32(pos + 44, p2.z, true);
pos += 50;
}
}
return stl;
2022-01-08 21:00:19 -05:00
default:
throw `invalid format "${format}"`;
}
}
};
function debug() {
console.log({work_cache: cache});
2022-01-08 21:00:19 -05:00
}
worker.bindObject({
2022-01-08 21:00:19 -05:00
debug,
model,
group,
2022-01-08 21:00:19 -05:00
object,
file
2021-12-31 22:11:20 -05:00
});
worker.ready();
2021-12-27 18:13:11 -05:00
})();