2022-02-17 15:04:36 -05:00
|
|
|
/** Copyright 2014-2019 Stewart Allen -- All Rights Reserved */
|
|
|
|
|
|
|
|
|
|
"use strict";
|
2022-01-29 20:37:45 -05:00
|
|
|
|
|
|
|
|
// dep: geo.base
|
2022-10-24 23:25:58 -04:00
|
|
|
// dep: ext.manifold
|
2022-02-20 14:31:27 -05:00
|
|
|
gapp.register("geo.csg", [], (root, exports) => {
|
|
|
|
|
|
|
|
|
|
const { base } = root;
|
2022-10-24 11:43:43 -04:00
|
|
|
const debug = true;
|
2022-01-29 20:37:45 -05:00
|
|
|
|
2022-02-20 14:31:27 -05:00
|
|
|
const CSG = {
|
2022-01-29 20:37:45 -05:00
|
|
|
|
2022-10-24 11:43:43 -04:00
|
|
|
// accepts 2 or more arguments with threejs vertex position arrays
|
2022-01-30 20:24:02 -05:00
|
|
|
union() {
|
2022-10-24 23:34:15 -04:00
|
|
|
return CSG.moduleOp('manifold.union', 'union', ...arguments);
|
2022-01-30 20:24:02 -05:00
|
|
|
},
|
2022-01-29 20:37:45 -05:00
|
|
|
|
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
|
2022-01-30 20:24:02 -05:00
|
|
|
subtract() {
|
2022-10-24 23:34:15 -04:00
|
|
|
return CSG.moduleOp('manifold.subtract', 'difference', ...arguments);
|
2022-01-30 20:24:02 -05:00
|
|
|
},
|
2022-01-29 20:37:45 -05:00
|
|
|
|
2022-10-24 11:43:43 -04:00
|
|
|
// accepts 2 or more arguments with threejs vertex position arrays
|
2022-01-30 20:24:02 -05:00
|
|
|
intersect() {
|
2022-10-24 23:34:15 -04:00
|
|
|
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);
|
2022-10-25 14:48:06 -04:00
|
|
|
const output = result.getMesh({ normal: () => undefined });
|
2022-10-24 23:34:15 -04:00
|
|
|
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();
|
|
|
|
|
}
|
2022-10-24 23:34:15 -04:00
|
|
|
if (errors.reduce((a,b) => a+b)) {
|
|
|
|
|
throw `${errors}`;
|
|
|
|
|
}
|
2022-10-24 11:43:43 -04:00
|
|
|
return output;
|
2022-01-30 20:24:02 -05:00
|
|
|
},
|
2022-01-29 20:37:45 -05:00
|
|
|
|
2022-10-24 23:25:58 -04:00
|
|
|
toPositionArray(mesh) {
|
|
|
|
|
const { vertPos, triVerts, vertex, index } = mesh;
|
2022-10-25 14:48:06 -04:00
|
|
|
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
|
|
|
}
|
2022-10-25 14:48:06 -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
|
|
|
}
|
2022-10-25 14:48:06 -04:00
|
|
|
throw "mesh missing required fields";
|
2022-01-30 20:24:02 -05:00
|
|
|
},
|
2022-01-29 20:37:45 -05:00
|
|
|
|
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-01-29 20:37:45 -05:00
|
|
|
}
|
2022-10-24 23:25:58 -04:00
|
|
|
return { index, vertices };
|
|
|
|
|
}
|
2022-01-29 20:37:45 -05:00
|
|
|
|
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(),
|
2022-10-25 14:48:06 -04:00
|
|
|
cmd: c.getMesh({ normal: () => undefined }),
|
|
|
|
|
cmdn: c.getMesh({})
|
2022-10-24 23:25:58 -04:00
|
|
|
});
|
|
|
|
|
|
2022-10-25 14:48:06 -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,
|
2022-10-25 14:48:06 -04:00
|
|
|
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`);
|
2022-10-25 14:48:06 -04:00
|
|
|
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`);
|
2022-10-25 14:48:06 -04:00
|
|
|
for (let i=0; i<l; i++) s.getMesh({});
|
2022-10-24 23:25:58 -04:00
|
|
|
console.timeEnd(`getMeshDirect`);
|
|
|
|
|
}
|
2022-01-29 20:37:45 -05:00
|
|
|
};
|
|
|
|
|
|
2022-02-20 14:31:27 -05:00
|
|
|
gapp.overlay(base, {
|
|
|
|
|
CSG
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
});
|