new 'detect' support algorithm
This commit is contained in:
parent
87ff83ca97
commit
ce994b6a21
1 changed files with 32 additions and 78 deletions
|
|
@ -1689,66 +1689,17 @@ FDM.supports = function(settings, widget) {
|
||||||
let min = 0.01;
|
let min = 0.01;
|
||||||
let geo = new THREE.BufferGeometry();
|
let geo = new THREE.BufferGeometry();
|
||||||
geo.setAttribute('position', new THREE.BufferAttribute(widget.vertices, 3));
|
geo.setAttribute('position', new THREE.BufferAttribute(widget.vertices, 3));
|
||||||
let mat = new THREE.MeshBasicMaterial();
|
|
||||||
let rad = (Math.PI / 180);
|
let rad = (Math.PI / 180);
|
||||||
let deg = (180 / Math.PI);
|
let deg = (180 / Math.PI);
|
||||||
let angle = rad * settings.process.sliceSupportAngle;
|
let angle = rad * settings.process.sliceSupportAngle;
|
||||||
let thresh = -Math.sin(angle);
|
let thresh = -Math.sin(angle);
|
||||||
let dir = new THREE.Vector3(0,0,-1)
|
let dir = new THREE.Vector3(0,0,-1)
|
||||||
let add = [];
|
let add = [];
|
||||||
|
let mat = new THREE.MeshBasicMaterial();
|
||||||
let mesh = new THREE.Mesh(geo, mat);
|
let mesh = new THREE.Mesh(geo, mat);
|
||||||
let platform = new THREE.Mesh(
|
let platform = new THREE.Mesh(
|
||||||
new THREE.PlaneGeometry(1000,1000,1), mat
|
new THREE.PlaneGeometry(10000,10000,1), mat
|
||||||
);
|
);
|
||||||
function pointIn(x, y, p1, p2, p3) {
|
|
||||||
let det = (p2.x - p1.x) * (p3.y - p1.y) - (p2.y - p1.y) * (p3.x - p1.x)
|
|
||||||
return det * ((p2.x - p1.x) * (y - p1.y) - (p2.y - p1.y) * (x - p1.x)) > 0 &&
|
|
||||||
det * ((p3.x - p2.x) * (y - p2.y) - (p3.y - p2.y) * (x - p2.x)) > 0 &&
|
|
||||||
det * ((p1.x - p3.x) * (y - p3.y) - (p1.y - p3.y) * (x - p3.x)) > 0
|
|
||||||
}
|
|
||||||
// first, last, distance
|
|
||||||
function fld(arr, key) {
|
|
||||||
let first = arr[0];
|
|
||||||
let last = arr.last();
|
|
||||||
let dist = last[key] - first[key];
|
|
||||||
return { first, last, dist }
|
|
||||||
}
|
|
||||||
// sorted range distance from key
|
|
||||||
function rdist(range, key) {
|
|
||||||
return range.last[key] - range.first[key];
|
|
||||||
}
|
|
||||||
// test area
|
|
||||||
function ta(p1, p2, p3) {
|
|
||||||
let sortx = [p1,p2,p3].sort((a,b) => { return a.x - b.x });
|
|
||||||
let sorty = [p1,p2,p3].sort((a,b) => { return a.y - b.y });
|
|
||||||
let sortz = [p1,p2,p3].sort((a,b) => { return a.z - b.z });
|
|
||||||
let xv = fld(sortx, 'x');
|
|
||||||
let yv = fld(sorty, 'y');
|
|
||||||
let xa = base.util.lerp(xv.first.x + s4, xv.last.x - s4, s2, true);
|
|
||||||
let ya = base.util.lerp(yv.first.y + s4, yv.last.y - s4, s2, true);
|
|
||||||
for (let x of xa) {
|
|
||||||
for (let y of ya) {
|
|
||||||
if (pointIn(x, y, p1, p2, p3)) {
|
|
||||||
let z = base.util.zInPlane(p1, p2, p3, x, y);
|
|
||||||
tp(new THREE.Vector3(x, y, z));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// test poly
|
|
||||||
function tP(poly, face) {
|
|
||||||
let bounds = poly.bounds;
|
|
||||||
let xa = base.util.lerp(bounds.minx + s4, bounds.maxx - s4, s2, true);
|
|
||||||
let ya = base.util.lerp(bounds.miny + s4, bounds.maxy - s4, s2, true);
|
|
||||||
for (let x of xa) {
|
|
||||||
for (let y of ya) {
|
|
||||||
if (base.newPoint(x, y, 0).isInPolygon(poly)) {
|
|
||||||
let z = base.util.zInPlane(face[0], face[1], face[2], x, y);
|
|
||||||
tp(new THREE.Vector3(x, y, z));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// test point
|
// test point
|
||||||
function tp(point) {
|
function tp(point) {
|
||||||
if (point.added) {
|
if (point.added) {
|
||||||
|
|
@ -1770,6 +1721,30 @@ FDM.supports = function(settings, widget) {
|
||||||
point.added = true;
|
point.added = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
function tf(a, b, c) {
|
||||||
|
let dab = a.distanceTo(b);
|
||||||
|
let dbc = b.distanceTo(c);
|
||||||
|
let dca = c.distanceTo(a);
|
||||||
|
let max = Math.max(dab, dbc, dca);
|
||||||
|
if (max < size) {
|
||||||
|
// test midpoint of tri face
|
||||||
|
return tp(new THREE.Vector3().add(a).add(b).add(c).divideScalar(3));
|
||||||
|
}
|
||||||
|
if (dab === max) {
|
||||||
|
let mp = new THREE.Vector3().add(a).add(b).divideScalar(2);
|
||||||
|
tf(mp, b, c);
|
||||||
|
tf(a, mp, c);
|
||||||
|
} else if (dbc === max) {
|
||||||
|
let mp = new THREE.Vector3().add(b).add(c).divideScalar(2);
|
||||||
|
tf(a, mp, c);
|
||||||
|
tf(a, b, mp);
|
||||||
|
} else {
|
||||||
|
let mp = new THREE.Vector3().add(c).add(a).divideScalar(2);
|
||||||
|
tf(a, b, mp);
|
||||||
|
tf(mp, b, c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let filter = isBelt ? (norm) => {
|
let filter = isBelt ? (norm) => {
|
||||||
return norm.z <= thresh && norm.y < 0;
|
return norm.z <= thresh && norm.y < 0;
|
||||||
} : (norm) => {
|
} : (norm) => {
|
||||||
|
|
@ -1777,43 +1752,22 @@ FDM.supports = function(settings, widget) {
|
||||||
};
|
};
|
||||||
let { position } = geo.attributes;
|
let { position } = geo.attributes;
|
||||||
let { itemSize, count, array } = position;
|
let { itemSize, count, array } = position;
|
||||||
let v3cache = new Vector3Cache();
|
|
||||||
let coplane = new Coplanars();
|
|
||||||
for (let i = 0; i<count; i += 3) {
|
for (let i = 0; i<count; i += 3) {
|
||||||
let ip = i * itemSize;
|
let ip = i * itemSize;
|
||||||
let a = v3cache.get(array[ip++], array[ip++], array[ip++]);
|
let a = new THREE.Vector3(array[ip++], array[ip++], array[ip++]);
|
||||||
let b = v3cache.get(array[ip++], array[ip++], array[ip++]);
|
let b = new THREE.Vector3(array[ip++], array[ip++], array[ip++]);
|
||||||
let c = v3cache.get(array[ip++], array[ip++], array[ip++]);
|
let c = new THREE.Vector3(array[ip++], array[ip++], array[ip++]);
|
||||||
let norm = THREE.computeFaceNormal(a,b,c);
|
let norm = THREE.computeFaceNormal(a,b,c);
|
||||||
// limit to downward faces
|
// limit to downward faces
|
||||||
if (!filter(norm)) {
|
if (!filter(norm)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// skip tiny faces
|
|
||||||
let poly = base.newPolygon().addPoints([a,b,c].map(v => base.newPoint(v.x, v.y, v.z)));
|
|
||||||
if (poly.area() < min && poly.perimeter() < size) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// skip faces on bed
|
// skip faces on bed
|
||||||
if (a.z + b.z + c.z < 0.01) {
|
if (Math.max(a.z, b.z, c.z) < 0.1) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// match with other attached, coplanar faces
|
// triangulate larger polys and test centers
|
||||||
coplane.put(a, b, c, norm.z);
|
tf(a,b,c);
|
||||||
}
|
|
||||||
let groups = coplane.group(true);
|
|
||||||
// console.log({v3cache, coplane, groups});
|
|
||||||
// let ptotl = Object.values(groups).flat().flat().length;
|
|
||||||
// console.log({ptotl});
|
|
||||||
// let pdone = 0;
|
|
||||||
for (let group of Object.values(groups)) {
|
|
||||||
for (let polys of group) {
|
|
||||||
for (let poly of polys) {
|
|
||||||
if (poly.area() >= process.sliceSupportArea)
|
|
||||||
tP(poly, polys.face);
|
|
||||||
// console.log(++pdone / ptotl);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
widget.supports = add;
|
widget.supports = add;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue