checkpoint sla supports work
This commit is contained in:
parent
d8925e0b28
commit
bb8be37b21
3 changed files with 62 additions and 18 deletions
|
|
@ -321,7 +321,9 @@ let gs_kiri_conf = exports;
|
||||||
slaFirstOffset: 0,
|
slaFirstOffset: 0,
|
||||||
slaSupportLayers: 0,
|
slaSupportLayers: 0,
|
||||||
slaSupportDensity: 0,
|
slaSupportDensity: 0,
|
||||||
slaSupportSize: 0.5
|
slaSupportSize: 0.6,
|
||||||
|
slaSupportPoints: 4,
|
||||||
|
slaSupportGap: 10
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
cam:{
|
cam:{
|
||||||
|
|
|
||||||
|
|
@ -90,7 +90,7 @@ let gs_kiri_sla = exports;
|
||||||
zoff = height / 2,
|
zoff = height / 2,
|
||||||
snew = [],
|
snew = [],
|
||||||
polys = [],
|
polys = [],
|
||||||
gap = 10, // gap layers above raft
|
gap = process.slaSupportGap, // gap layers above raft
|
||||||
grow = height, // union per layer expand
|
grow = height, // union per layer expand
|
||||||
off = 1 - (layers * grow); // starting union offset from part
|
off = 1 - (layers * grow); // starting union offset from part
|
||||||
let outer = slices.forEach(slice => {
|
let outer = slices.forEach(slice => {
|
||||||
|
|
@ -278,7 +278,7 @@ let gs_kiri_sla = exports;
|
||||||
let seq = 0,
|
let seq = 0,
|
||||||
seqLast = 0,
|
seqLast = 0,
|
||||||
spacing = (1 - process.slaSupportDensity) * 10,
|
spacing = (1 - process.slaSupportDensity) * 10,
|
||||||
size = Math.bound(process.slaSupportSize * process.slaSupportDensity, 0.1, 0.5);
|
size = Math.bound(process.slaSupportSize / 2, 0.25, 1);
|
||||||
|
|
||||||
// compute and project support pillars
|
// compute and project support pillars
|
||||||
slices.forEach(slice => {
|
slices.forEach(slice => {
|
||||||
|
|
@ -337,7 +337,7 @@ let gs_kiri_sla = exports;
|
||||||
while (seg.length && (crit > 0 || out.length < 3)) {
|
while (seg.length && (crit > 0 || out.length < 3)) {
|
||||||
let {dist, p1, p2} = seg.shift();
|
let {dist, p1, p2} = seg.shift();
|
||||||
if (dist >= spacing) {
|
if (dist >= spacing) {
|
||||||
// spaced
|
// spaced along line
|
||||||
let num = Math.ceil(dist / spacing) + 1,
|
let num = Math.ceil(dist / spacing) + 1,
|
||||||
step = dist / num,
|
step = dist / num,
|
||||||
pt = p1;
|
pt = p1;
|
||||||
|
|
@ -347,13 +347,29 @@ let gs_kiri_sla = exports;
|
||||||
}
|
}
|
||||||
crit--;
|
crit--;
|
||||||
} else {
|
} else {
|
||||||
// midpoint
|
// line midpoint
|
||||||
out.push(p1.offsetPointTo(p2, dist / 2));
|
out.push(p1.offsetPointTo(p2, dist / 2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// drop points too close to other pillars
|
||||||
|
drop: for (let i=0; i<out.length; i++) {
|
||||||
|
for (let j=i+1; j<out.length; j++) {
|
||||||
|
if (out[i].distTo2D(out[j]) <= size) {
|
||||||
|
out[i] = null;
|
||||||
|
continue drop;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (slice.pillars) slice.pillars.forEach(rec => {
|
||||||
|
if (out[i] && out[i].distTo2D(rec.point) <= size) {
|
||||||
|
out[i] = null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// mark support pillar for each point
|
// mark support pillar for each point
|
||||||
out.forEach(p => projectPillar(process, slice, p, size, []));
|
out.filter(p => p !== null)
|
||||||
|
.forEach(p => projectPillar(process, slice, p, size, []));
|
||||||
|
|
||||||
// inset polygon for flat area support
|
// inset polygon for flat area support
|
||||||
if (flat) poly.offset(Math.max(0.2, 1 - process.slaSupportDensity), arr);
|
if (flat) poly.offset(Math.max(0.2, 1 - process.slaSupportDensity), arr);
|
||||||
|
|
@ -362,13 +378,18 @@ let gs_kiri_sla = exports;
|
||||||
|
|
||||||
function projectPillar(process, slice, point, size, track) {
|
function projectPillar(process, slice, point, size, track) {
|
||||||
if (!slice.supports) slice.supports = [];
|
if (!slice.supports) slice.supports = [];
|
||||||
|
if (!slice.pillars) slice.pillars = [];
|
||||||
|
|
||||||
let pillar = newPolygon().centerRectangle(point, size/2, size/2).setZ(slice.z),
|
let points = process.slaSupportPoints,
|
||||||
|
pillar = newPolygon()
|
||||||
|
.centerCircle(point, size/2, points, true)
|
||||||
|
.setZ(slice.z),
|
||||||
max = process.slaSupportSize,
|
max = process.slaSupportSize,
|
||||||
inc = process.slaSlice * 2,
|
inc = process.slaSlice * 2,
|
||||||
end = false, // center intersects
|
end = false, // center intersects
|
||||||
over = [], // overlapping points
|
over = [], // overlapping points
|
||||||
safe = []; // non-overlapping points
|
safe = [], // non-overlapping points
|
||||||
|
low = slice.index < process.slaSupportGap + process.slaSupportLayers;
|
||||||
|
|
||||||
// slice.supports.push(pillar); return;
|
// slice.supports.push(pillar); return;
|
||||||
|
|
||||||
|
|
@ -380,7 +401,7 @@ let gs_kiri_sla = exports;
|
||||||
end = true;
|
end = true;
|
||||||
}
|
}
|
||||||
pillar.points.forEach(p => {
|
pillar.points.forEach(p => {
|
||||||
let isin = p.isInPolygon(t.poly);
|
let isin = p.isInPolygon(t.poly);// || p.nearPolygon(t.poly, 0.001);
|
||||||
if (isin) {
|
if (isin) {
|
||||||
over.push(p);
|
over.push(p);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -390,12 +411,28 @@ let gs_kiri_sla = exports;
|
||||||
});
|
});
|
||||||
|
|
||||||
if (end) {
|
if (end) {
|
||||||
// backtrack shrinking pillars if not landing on a flat
|
// backtrack shrinking pillars to point if
|
||||||
|
// not landing on the base and size is max'd
|
||||||
|
if (!slice.synth && track.max) {
|
||||||
|
let nusize = track.min;
|
||||||
|
while (nusize < max) {
|
||||||
|
let prec = track.pop(),
|
||||||
|
npil = newPolygon()
|
||||||
|
.centerCircle(point, nusize/2, points, true)
|
||||||
|
.setZ(prec.slice.z),
|
||||||
|
spos = prec.slice.supports.indexOf(prec.pillar);
|
||||||
|
// if we find our old pillar, replace
|
||||||
|
if (spos >= 0) {
|
||||||
|
prec.slice.supports[spos] = npil;
|
||||||
|
nusize += inc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (over.length) {
|
if (over.length) {
|
||||||
// move toward average of safe points
|
// move toward average of safe (non-overlapping) points
|
||||||
if (safe.length) {
|
if (safe.length) {
|
||||||
let x = 0, y = 0;
|
let x = 0, y = 0;
|
||||||
safe.forEach(p => { x += p.x; y += p.y });
|
safe.forEach(p => { x += p.x; y += p.y });
|
||||||
|
|
@ -403,11 +440,13 @@ let gs_kiri_sla = exports;
|
||||||
y /= safe.length;
|
y /= safe.length;
|
||||||
point = point.offsetPointTo({x, y, z:slice.z}, inc / 2);
|
point = point.offsetPointTo({x, y, z:slice.z}, inc / 2);
|
||||||
}
|
}
|
||||||
|
// once max'ed out, can only shrink in size
|
||||||
if (track.max) {
|
if (track.max) {
|
||||||
size -= inc;
|
size -= inc;
|
||||||
}
|
}
|
||||||
} else if (!track.max) {
|
} else if (!track.max || low) {
|
||||||
size += inc;
|
size += inc;
|
||||||
|
if (low) max *= 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (size < track.min) {
|
if (size < track.min) {
|
||||||
|
|
@ -416,7 +455,8 @@ let gs_kiri_sla = exports;
|
||||||
|
|
||||||
if (pillar) {
|
if (pillar) {
|
||||||
slice.supports.push(pillar);
|
slice.supports.push(pillar);
|
||||||
track.push(pillar);
|
slice.pillars.push({point, pillar, size});
|
||||||
|
track.push({slice, point, pillar, size});
|
||||||
if (slice.down) {
|
if (slice.down) {
|
||||||
projectPillar(process, slice.down, point, Math.min(size, max), track);
|
projectPillar(process, slice.down, point, Math.min(size, max), track);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1460,17 +1460,17 @@ var gs_kiri_init = exports;
|
||||||
// SLA
|
// SLA
|
||||||
slaOutput: UC.newGroup('layers', null, {modes:SLA, group:"sla-layers"}),
|
slaOutput: UC.newGroup('layers', null, {modes:SLA, group:"sla-layers"}),
|
||||||
slaLayerOn: UC.newInput('light on time', {title:'layer light on\ntime in seconds', convert:UC.toFloat, modes:SLA}),
|
slaLayerOn: UC.newInput('light on time', {title:'layer light on\ntime in seconds', convert:UC.toFloat, modes:SLA}),
|
||||||
slaLayerOff: UC.newInput('light off time', {title:'layer light off\ntime in seconds', convert:UC.toFloat, modes:SLA}),
|
slaLayerOff: UC.newInput('light off time', {title:'layer light off\ntime in seconds', convert:UC.toFloat, modes:SLA, expert:true}),
|
||||||
slaPeelDist: UC.newInput('peel distance', {title:'peel distance\nin millimeters', convert:UC.toFloat, modes:SLA}),
|
slaPeelDist: UC.newInput('peel distance', {title:'peel distance\nin millimeters', convert:UC.toFloat, modes:SLA}),
|
||||||
slaPeelLiftRate: UC.newInput('peel lift rate', {title:'peel lift speed\nin mm/sec', convert:UC.toFloat, modes:SLA}),
|
slaPeelLiftRate: UC.newInput('peel lift rate', {title:'peel lift speed\nin mm/sec', convert:UC.toFloat, modes:SLA, expert:true}),
|
||||||
slaPeelDropRate: UC.newInput('peel drop rate', {title:'peel drop speed\nin mm/sec', convert:UC.toFloat, modes:SLA}),
|
slaPeelDropRate: UC.newInput('peel drop rate', {title:'peel drop speed\nin mm/sec', convert:UC.toFloat, modes:SLA, expert:true}),
|
||||||
|
|
||||||
slaOutput: UC.newGroup('base layers', null, {modes:SLA, group:"sla-base"}),
|
slaOutput: UC.newGroup('base layers', null, {modes:SLA, group:"sla-base"}),
|
||||||
slaBaseLayers: UC.newInput('layer count', {title:'number of\nbase layers', convert:UC.toInt, modes:SLA}),
|
slaBaseLayers: UC.newInput('layer count', {title:'number of\nbase layers', convert:UC.toInt, modes:SLA}),
|
||||||
slaBaseOn: UC.newInput('light on time', {title:'base layer light on\ntime in seconds', convert:UC.toFloat, modes:SLA}),
|
slaBaseOn: UC.newInput('light on time', {title:'base layer light on\ntime in seconds', convert:UC.toFloat, modes:SLA}),
|
||||||
slaBaseOff: UC.newInput('light off time', {title:'base layer light on\ntime in seconds', convert:UC.toFloat, modes:SLA}),
|
slaBaseOff: UC.newInput('light off time', {title:'base layer light on\ntime in seconds', convert:UC.toFloat, modes:SLA, expert:true}),
|
||||||
slaBasePeelDist: UC.newInput('peel distance', {title:'peel distance\nin millimeters', convert:UC.toFloat, modes:SLA}),
|
slaBasePeelDist: UC.newInput('peel distance', {title:'peel distance\nin millimeters', convert:UC.toFloat, modes:SLA}),
|
||||||
slaBasePeelLiftRate: UC.newInput('peel lift rate', {title:'peel lift speed\nin mm/sec', convert:UC.toFloat, modes:SLA}),
|
slaBasePeelLiftRate: UC.newInput('peel lift rate', {title:'peel lift speed\nin mm/sec', convert:UC.toFloat, modes:SLA, expert:true}),
|
||||||
|
|
||||||
slaFill: UC.newGroup('infill', null, {modes:SLA, group:"sla-infill"}),
|
slaFill: UC.newGroup('infill', null, {modes:SLA, group:"sla-infill"}),
|
||||||
slaFillDensity: UC.newInput('density', {title:'percent infill\n0.0-1.0', convert:UC.toFloat, bound:UC.bound(0,1), modes:SLA}),
|
slaFillDensity: UC.newInput('density', {title:'percent infill\n0.0-1.0', convert:UC.toFloat, bound:UC.bound(0,1), modes:SLA}),
|
||||||
|
|
@ -1480,6 +1480,8 @@ var gs_kiri_init = exports;
|
||||||
slaSupportLayers: LOCAL ? UC.newInput('layers', {title:'base support layers\n0-10', convert:UC.toInt, bound:UC.bound(0,10), modes:SLA}) : null,
|
slaSupportLayers: LOCAL ? UC.newInput('layers', {title:'base support layers\n0-10', convert:UC.toInt, bound:UC.bound(0,10), modes:SLA}) : null,
|
||||||
slaSupportDensity: LOCAL ? UC.newInput('density', {title:'used to compute the\nnumber of support pillars\n0.0-1.0 (0 = disable)', convert:UC.toFloat, bound:UC.bound(0,1), modes:SLA}) : null,
|
slaSupportDensity: LOCAL ? UC.newInput('density', {title:'used to compute the\nnumber of support pillars\n0.0-1.0 (0 = disable)', convert:UC.toFloat, bound:UC.bound(0,1), modes:SLA}) : null,
|
||||||
slaSupportSize: LOCAL ? UC.newInput('size', {title:'max size of a\nsupport pillar\nin millimeters', convert:UC.toFloat, bound:UC.bound(0,1), modes:SLA}) : null,
|
slaSupportSize: LOCAL ? UC.newInput('size', {title:'max size of a\nsupport pillar\nin millimeters', convert:UC.toFloat, bound:UC.bound(0,1), modes:SLA}) : null,
|
||||||
|
slaSupportPoints: LOCAL ? UC.newInput('points', {title:'number of points in\neach support pillar\nin millimeters', convert:UC.toInt, bound:UC.bound(3,10), modes:SLA, expert:true}) : null,
|
||||||
|
slaSupportGap: LOCAL ? UC.newInput('gap layers', {title:'number of layers between\nraft and bottom of obejct', convert:UC.toInt, bound:UC.bound(3,10), modes:SLA, expert:true}) : null,
|
||||||
|
|
||||||
slaOutput: UC.newGroup('output', null, {modes:SLA, group:"sla-first"}),
|
slaOutput: UC.newGroup('output', null, {modes:SLA, group:"sla-first"}),
|
||||||
slaFirstOffset: UC.newInput('z offset', {title:'z layer offset\nalmost always 0.0\n0.0-1.0 in millimeters', convert:UC.toFloat, bound:UC.bound(0,1), modes:SLA, expert:true}),
|
slaFirstOffset: UC.newInput('z offset', {title:'z layer offset\nalmost always 0.0\n0.0-1.0 in millimeters', convert:UC.toFloat, bound:UC.bound(0,1), modes:SLA, expert:true}),
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue