add mode infill api accessors. checkpoint sla support work

This commit is contained in:
Stewart Allen 2020-04-24 10:43:03 -04:00
commit 07b1a075a5
5 changed files with 87 additions and 19 deletions

View file

@ -320,6 +320,7 @@ let gs_kiri_conf = exports;
slaFillLine: 0.5, slaFillLine: 0.5,
slaFirstOffset: 0, slaFirstOffset: 0,
slaSupportLayers: 0, slaSupportLayers: 0,
slaSupportDensity: 0,
} }
}, },
cam:{ cam:{

View file

@ -185,6 +185,9 @@ let gs_kiri_fdm = exports;
if (!vaseMode && spro.sliceFillSparse > 0.0) { if (!vaseMode && spro.sliceFillSparse > 0.0) {
forSlices(0.8, 1.0, function(slice) { forSlices(0.8, 1.0, function(slice) {
slice.doSparseLayerFill({ slice.doSparseLayerFill({
settings: settings,
process: spro,
device: sdev,
lineWidth: nozzleSize, lineWidth: nozzleSize,
spacing: fillOffset, spacing: fillOffset,
density: spro.sliceFillSparse, density: spro.sliceFillSparse,

View file

@ -75,43 +75,58 @@ let gs_kiri_sla = exports;
height: height, height: height,
add: !process.slaOpenTop add: !process.slaOpenTop
}, function(slices) { }, function(slices) {
widget.slices = slices.filter(slice => slice.tops.length); // hold onto last (empty) slice
if (process.slaOpenTop) { let last = slices[slices.length-1];
// with closed top, filter out any empty above slices // remove empty slices
// that will generate a diff producing a solid projection slices = widget.slices = slices.filter(slice => slice.tops.length);
slices = widget.slices; if (!process.slaOpenTop) {
// re-add last empty slice for open top
slices.push(last);
} }
// insert support layers // prepend raft layers to slices array
if (process.slaSupportLayers) { if (process.slaSupportLayers) {
let zoff = height / 2, let zoff = height / 2,
snew = [], snew = [],
polys = []; polys = [],
off = 2, // starting union offset from part
gap = 10, // gap layers above raft
grow = 0.1; // union per layer expand
let outer = slices.forEach(slice => { let outer = slices.forEach(slice => {
polys.appendAll(slice.tops.map(t => t.poly)); polys.appendAll(slice.tops.map(t => t.poly));
}); });
let union = POLY.expand(POLY.union(polys), 2, zoff, [], 1); let union = POLY.union(polys);
for (let s=0; s<process.slaSupportLayers + 3; s++) { let expand = POLY.expand(union, off, zoff, [], 1);
let lastraft;
for (let s=0; s<process.slaSupportLayers + gap; s++) {
let slice = newSlice(zoff); let slice = newSlice(zoff);
slice.synth = true;
slice.height = height; slice.height = height;
slice.index = snew.length; slice.index = snew.length;
if (s < process.slaSupportLayers) { if (s < process.slaSupportLayers) {
union.forEach(u => { slice.synth = true;
expand.forEach(u => {
slice.tops.push(newTop(u.clone(true).setZ(zoff))); slice.tops.push(newTop(u.clone(true).setZ(zoff)));
}); });
union = POLY.expand(union, 0.1, zoff, [], 1); expand = POLY.expand(expand, grow, zoff, [], 1);
lastraft = slice;
} }
snew.push(slice); snew.push(slice);
zoff += height; zoff += height;
} }
widget.slices = slices = snew.concat(slices.map(s => { // replace slices with new appended array
s.tops.forEach(t => { slices = widget.slices = snew.concat(slices.map(s => {
t.poly.setZ(s.z + zoff); s.tops.forEach(t => t.poly.setZ(s.z + zoff));
});
s.index += snew.length; s.index += snew.length;
s.z += zoff; s.z += zoff;
return s; return s;
})); }));
// annotate widget for support generation
widget.union = union;
widget.lastraft = lastraft;
}
// re-connect slices into linked list for island/bridge projections
for (let i=1; i<slices.length; i++) {
slices[i-1].up = slices[i];
slices[i].down = slices[i-1];
} }
// reset for solids and support projections // reset for solids and support projections
slices.forEach(function(slice) { slices.forEach(function(slice) {
@ -160,12 +175,59 @@ let gs_kiri_sla = exports;
fillPolys(slice, settings); fillPolys(slice, settings);
}, "infill"); }, "infill");
} }
if (process.slaSupportLayers && process.slaSupportDensity) {
computeSupports(widget, process);
}
ondone(); ondone();
}, function(update) { }, function(update) {
return onupdate(0.0 + update * 0.25); return onupdate(0.0 + update * 0.25);
}); });
}; };
function computeSupports(widget, process) {
let area = widget.union.reduce((t,p) => { return t + p.areaDeep() }, 0),
slices = widget.slices,
length = slices.length,
trigger = (1 - process.slaSupportDensity),
layer = 0,
accu = 0,
totmass = 0, // total widget "mass"
totbear = 0; // total "mass-bearing" area
// compute total "mass" by slice
slices.forEach(slice => {
if (slice.synth || !slice.solids.unioned) return;
slice.mass = slice.solids.unioned.reduce((t,p) => { return t + p.areaDeep() }, 0);
if (slice.up && slice.up.bridges) {
slice.bear = slice.up.bridges.reduce((t,p) => { return t + p.areaDeep() }, 0);
totbear += slice.bear;
} else {
slice.bear = 0;
}
totmass += slice.mass;
// console.log('mass', slice.index, slice.mass.toFixed(3), slice.bear.toFixed(3));
});
slices.forEach(slice => {
let weight = Math.pow(10, 0 + ((length - layer) / length));
if (slice.up && slice.up.bridges) {
let sum = 0;
slice.up.bridges.forEach(bridge => {
sum += bridge.areaDeep() / area;
});
accu += sum * weight;
if (layer === 0 || accu > trigger) {
// console.log('gen @', layer, slice.index);
accu = 0;
slice.supports = slice.up.bridges.map(p => {
return p.clone(true).setZ(slice.z);
});
}
}
if (slice.mass > 0) layer++;
});
}
function fillPolys(slice, settings) { function fillPolys(slice, settings) {
let process = settings.process, let process = settings.process,
device = settings.device, device = settings.device,
@ -374,14 +436,14 @@ let gs_kiri_sla = exports;
} else if (slice.tops) { } else if (slice.tops) {
slice.tops.forEach(top => { slice.tops.forEach(top => {
outline.poly(top.poly, 0x010101, true, false); outline.poly(top.poly, 0x010101, true, false);
outline.solid(top.poly, 0xeeee55); outline.solid(top.poly, 0xfcba03);
}); });
} }
if (slice.supports) if (slice.supports)
slice.supports.forEach(poly => { slice.supports.forEach(poly => {
layer.poly(poly, 0x010105, true, false); support.poly(poly, 0x010105, true, false);
layer.solid(poly, 0xffff99); support.solid(poly, 0xfcba03);
}); });
slice.renderDiff(); slice.renderDiff();

View file

@ -1478,6 +1478,7 @@ var gs_kiri_init = exports;
slaSupport: LOCAL ? UC.newGroup('support', null, {modes:SLA, group:"sla-support"}) : null, slaSupport: LOCAL ? UC.newGroup('support', null, {modes:SLA, group:"sla-support"}) : null,
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,
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}),

View file

@ -65,6 +65,7 @@
# References # References
* https://www.canva.com/colors/color-wheel/
* http://lcamtuf.coredump.cx/gcnc/full/ * http://lcamtuf.coredump.cx/gcnc/full/
* http://wiki.imal.org/howto/cnc-milling-introduction-cutting-tools * http://wiki.imal.org/howto/cnc-milling-introduction-cutting-tools
* http://www.twak.co.uk/2011/01/degeneracy-in-weighted-straight.html * http://www.twak.co.uk/2011/01/degeneracy-in-weighted-straight.html