'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