grid-apps-cmms/src/geo/csg.js

176 lines
5 KiB
JavaScript
Raw Normal View History

/** Copyright 2014-2019 Stewart Allen -- All Rights Reserved */
"use strict";
// dep: geo.base
2022-10-24 23:25:58 -04:00
// dep: ext.manifold
gapp.register("geo.csg", [], (root, exports) => {
const { base } = root;
2022-10-24 11:43:43 -04:00
const debug = true;
const CSG = {
2022-10-24 11:43:43 -04:00
// accepts 2 or more arguments with threejs vertex position arrays
union() {
return CSG.moduleOp('manifold.union', 'union', ...arguments);
},
2022-10-24 11:43:43 -04:00
// accepts 2 or more arguments with threejs vertex position arrays
// the fist argument is the target mesh. the rest are negatives
subtract() {
return CSG.moduleOp('manifold.subtract', 'difference', ...arguments);
},
2022-10-24 11:43:43 -04:00
// accepts 2 or more arguments with threejs vertex position arrays
intersect() {
return CSG.moduleOp('manifold.intersect', 'intersection', ...arguments);
},
moduleOp(name, op) {
mesh.log(`${name} ${arguments.length} meshes`);
const args = [...arguments].slice(2).map(a => new Module.Manifold(a));
if (args.length < 2) {
throw "missing one or more meshes";
}
const result = Module[op](...args);
const output = result.getMesh({ normal: () => undefined });
const errors = [ ...args, result ].map(m => m.status().value);
2022-10-24 11:43:43 -04:00
for (let m of [ ...args, result ]) {
m.delete();
}
if (errors.reduce((a,b) => a+b)) {
throw `${errors}`;
}
2022-10-24 11:43:43 -04:00
return output;
},
2022-10-24 23:25:58 -04:00
toPositionArray(mesh) {
const { vertPos, triVerts, vertex, index } = mesh;
if (vertex && index) {
const vertices = new Float32Array(index.length * 3);
for (let p=0, i=0, l=index.length; i<l; i++) {
let vi = index[i] * 3;
vertices[p++] = vertex[vi++];
vertices[p++] = vertex[vi++];
vertices[p++] = vertex[vi++];
}
return vertices;
2022-10-24 23:25:58 -04:00
}
if (vertPos && triVerts) {
const vertices = new Float32Array(triVerts.length * 9);
for (let i = 0, t = 0, l = triVerts.length; t < l; t++) {
let tri = triVerts[t];
let vert = vertPos[tri[0]]; // X
vertices[i++] = vert[0];
vertices[i++] = vert[1];
vertices[i++] = vert[2];
vert = vertPos[tri[1]]; // Y
vertices[i++] = vert[0];
vertices[i++] = vert[1];
vertices[i++] = vert[2];
vert = vertPos[tri[2]]; // Z
vertices[i++] = vert[0];
vertices[i++] = vert[1];
vertices[i++] = vert[2];
}
return vertices;
2022-10-24 23:25:58 -04:00
}
throw "mesh missing required fields";
},
2022-10-24 23:25:58 -04:00
fromPositionArray(pos) {
const { index, vertices } = indexVertices(pos);
const mesh = {
vertPos: new Module.Vector_vec3(),
triVerts: new Module.Vector_ivec3(),
vertNormal: new Module.Vector_vec3(),
halfedgeTangent: new Module.Vector_vec4()
};
for (let i = 0, l = vertices.length; i < l; ) {
mesh.vertPos.push_back({
x: vertices[i++],
y: vertices[i++],
z: vertices[i++]
});
}
for (let i = 0, l = index.length; i < l; ) {
mesh.triVerts.push_back([ index[i++], index[i++], index[i++] ]);
}
return mesh;
}
};
function indexVertices(pos) {
mesh.log(`indexing ${pos.length/3} vertices`);
let ipos = 0;
const index = [];
const vertices = [];
const cache = {};
const temp = { x: 0, y: 0, z: 0 };
for (let i=0, length = pos.length; i<length; ) {
temp.x = pos[i++];
temp.y = pos[i++];
temp.z = pos[i++];
let key = [
((temp.x * 100000) | 0),
((temp.y * 100000) | 0),
((temp.z * 100000) | 0)
].join('');
let ip = cache[key];
if (ip >= 0) {
index.push(ip);
} else {
index.push(ipos);
cache[key] = (ipos++);
vertices.push(temp.x, temp.y, temp.z);
}
}
2022-10-24 23:25:58 -04:00
return { index, vertices };
}
2022-10-24 23:25:58 -04:00
function pos2mesh(pos) {
}
Module.onRuntimeInitialized = () => {
Module.setup();
if (false) {
let c = Module.cube([1,1,1], true);
console.log({
c,
cm: c.getMesh(),
cmd: c.getMesh({ normal: () => undefined }),
cmdn: c.getMesh({})
2022-10-24 23:25:58 -04:00
});
let l = 1000;
2022-10-24 23:25:58 -04:00
let s = Module.sphere(10, 100);
let sm = s.getMesh();
console.log({
s,
sm,
smd: s.getMesh({}),
2022-10-24 23:25:58 -04:00
});
console.time('getMesh');
for (let i=0; i<l; i++) s.getMesh();
console.timeEnd('getMesh');
console.time(`getMeshDirect`);
for (let i=0; i<l; i++) s.getMesh({ normal: () => undefined });
2022-10-24 23:25:58 -04:00
console.timeEnd(`getMeshDirect`);
console.time(`getMeshDirect`);
for (let i=0; i<l; i++) s.getMesh({});
2022-10-24 23:25:58 -04:00
console.timeEnd(`getMeshDirect`);
}
};
gapp.overlay(base, {
CSG
});
});