更新版本
This commit is contained in:
156
CSGSubtract.worker.cjs
Normal file
156
CSGSubtract.worker.cjs
Normal file
@@ -0,0 +1,156 @@
|
||||
'use strict';
|
||||
|
||||
var poly3 = require('@jscad/modeling/src/geometries/poly3');
|
||||
var booleans = require('@jscad/modeling/src/operations/booleans');
|
||||
|
||||
/**
|
||||
* @param compart true => t2 , false => t1
|
||||
* @returns 索引
|
||||
*/
|
||||
function Max(arr, compart)
|
||||
{
|
||||
let best = arr[0];
|
||||
let bestIndex = 0;
|
||||
for (let i = 1; i < arr.length; i++) {
|
||||
let t1 = arr[i];
|
||||
if (compart(best, t1)) {
|
||||
best = t1;
|
||||
bestIndex = i;
|
||||
}
|
||||
}
|
||||
return bestIndex;
|
||||
}
|
||||
|
||||
/** Epsilon used during determination of near zero distances.
|
||||
* @default
|
||||
*/
|
||||
const EPS = 5e-2;
|
||||
|
||||
// //////////////////////////////
|
||||
// tolerance: The maximum difference for each parameter allowed to be considered a match
|
||||
class FuzzyFactory
|
||||
{
|
||||
constructor(numdimensions = 3, tolerance = EPS)
|
||||
{
|
||||
this.lookuptable = {};
|
||||
this.multiplier = 1.0 / tolerance;
|
||||
}
|
||||
// let obj = f.lookupOrCreate([el1, el2, el3], function(elements) {/* create the new object */});
|
||||
// Performs a fuzzy lookup of the object with the specified elements.
|
||||
// If found, returns the existing object
|
||||
// If not found, calls the supplied callback function which should create a new object with
|
||||
// the specified properties. This object is inserted in the lookup database.
|
||||
lookupOrCreate(els, object)
|
||||
{
|
||||
let hash = "";
|
||||
let multiplier = this.multiplier;
|
||||
for (let el of els) {
|
||||
let valueQuantized = Math.round(el * multiplier);
|
||||
hash += valueQuantized + "/";
|
||||
}
|
||||
if (hash in this.lookuptable)
|
||||
return this.lookuptable[hash];
|
||||
else {
|
||||
let hashparts = els.map(el =>
|
||||
{
|
||||
let q0 = Math.floor(el * multiplier);
|
||||
let q1 = q0 + 1;
|
||||
return ["" + q0 + "/", "" + q1 + "/"];
|
||||
});
|
||||
let numelements = els.length;
|
||||
let numhashes = 1 << numelements;
|
||||
for (let hashmask = 0; hashmask < numhashes; ++hashmask) {
|
||||
let hashmaskShifted = hashmask;
|
||||
hash = "";
|
||||
hashparts.forEach(hashpart =>
|
||||
{
|
||||
hash += hashpart[hashmaskShifted & 1];
|
||||
hashmaskShifted >>= 1;
|
||||
});
|
||||
this.lookuptable[hash] = object;
|
||||
}
|
||||
return object;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//并集path2dCsgs 差集 删除小面积结果
|
||||
function CSGSubtract(geom, path2dCsgs)
|
||||
{
|
||||
let gemUnion = path2dCsgs[0];
|
||||
for (let i = 1; i < path2dCsgs.length; i++)
|
||||
gemUnion = booleans.union(gemUnion, path2dCsgs[i]);
|
||||
let newGeom = booleans.subtract(geom, gemUnion);
|
||||
//删除小面积(只留一个)
|
||||
{
|
||||
let fuzz = new FuzzyFactory;
|
||||
let vmap = new Map;
|
||||
for (let poly of newGeom.polygons) {
|
||||
for (let v of poly.vertices) {
|
||||
let key = fuzz.lookupOrCreate(v, v);
|
||||
let arr = vmap.get(key);
|
||||
if (!arr) {
|
||||
arr = [];
|
||||
vmap.set(key, arr);
|
||||
}
|
||||
arr.push(poly);
|
||||
v["__key__"] = key;
|
||||
}
|
||||
}
|
||||
let polys = newGeom.polygons.concat();
|
||||
let polyGroups = [];
|
||||
let calcs = new Set;
|
||||
while (polys.length) {
|
||||
let poly1 = polys.pop();
|
||||
calcs.add(poly1);
|
||||
let polyGroup = [poly1];
|
||||
polyGroups.push(polyGroup);
|
||||
for (let i = 0; i < polyGroup.length; i++) {
|
||||
let poly = polyGroup[i];
|
||||
for (let v of poly.vertices) {
|
||||
let key = v["__key__"];
|
||||
let arr = vmap.get(key);
|
||||
for (let vpoly of arr) {
|
||||
if (calcs.has(vpoly))
|
||||
continue;
|
||||
calcs.add(vpoly);
|
||||
polyGroup.push(vpoly);
|
||||
}
|
||||
}
|
||||
}
|
||||
// arrayRemoveIf(polys, poly => !calcs.has(poly)); //加上这个无法提高性能
|
||||
}
|
||||
let areas = polyGroups.map(polys =>
|
||||
{
|
||||
let area = 0;
|
||||
for (let poly of polys)
|
||||
area += poly3.measureArea(poly);
|
||||
return area;
|
||||
});
|
||||
let maxIndex = Max(areas, (t1, t2) => t2 > t1);
|
||||
newGeom.polygons = polyGroups[maxIndex];
|
||||
}
|
||||
return newGeom;
|
||||
}
|
||||
|
||||
addEventListener("message", e =>
|
||||
{
|
||||
const [path2dCsgs, geom] = e.data;
|
||||
try {
|
||||
const newGeom = CSGSubtract(geom, path2dCsgs);
|
||||
postMessage({
|
||||
status: 0,
|
||||
geom: newGeom
|
||||
});
|
||||
}
|
||||
catch (error) {
|
||||
postMessage({
|
||||
status: 1,
|
||||
error
|
||||
});
|
||||
}
|
||||
});
|
||||
var CSGSubtract_worker = {};
|
||||
|
||||
module.exports = CSGSubtract_worker;
|
||||
//# sourceMappingURL=CSGSubtract.worker.cjs.map
|
Reference in New Issue
Block a user