add discrete control of bridge, flat, and infill print speeds

This commit is contained in:
Stewart Allen 2022-03-01 15:58:55 -05:00
commit e409bec63a
8 changed files with 49 additions and 14 deletions

View file

@ -39,10 +39,8 @@
* `F` first layer segment large flat areas for better fill reliability
* `F` option to support interior bridges when 0% infill
* `F` calculate filament use per extruder per print
* `F` apply finish speed to exposed top and underside flat areas
* `F` expand internal supporting flats / solids before projection
* `P` expand projected flats (parameterize?)
* `P` enable purge blocks when quick layers are detected
* `P` refactor skirt, brim, raft as synth widget instead of in path routing
* `P` extruder + filament max flow rate cap in planner

View file

@ -22,6 +22,8 @@
* `C` trigger solid layer when transitions lead to 50% projected areas
* `C` limit non-manifold solution search depth
* `C` refactor slicers to use single improved slice core (cnc deferred)
* `C` add parameterized solid projection expansion (infill -> solid expand)
* `C` add parameterized control of bridge/flat and infill print speeds
* `P` template vars: nozzles used and layers until next use (IDEX)
* `-` improved vertex replacement and widget update matrix tracking

View file

@ -39,6 +39,9 @@ FDM.init = function(kiri, api) {
"sliceFillType": LANG.fi_type,
"sliceFillWidth": LANG.fi_wdth_s,
"sliceFillSparse": LANG.fi_pcnt_s,
"sliceFillRate": LANG.ou_feed_s,
"sliceFillGrow": LANG.fi_grow_s,
"sliceSolidRate": LANG.ou_fini_s,
"sliceSolidMinArea": LANG.ad_msol_s,
"firstLayerRate": LANG.fl_rate_s,
"firstLayerPrintMult": LANG.fl_mult_s,

View file

@ -812,6 +812,10 @@ function slicePrintPath(print, slice, startPoint, offset, output, opt = {}) {
z = slice.z,
lastPoly;
if (slice.finishSolids) {
fillSpeed = process.sliceSolidRate || finishSpeed;
}
// apply first layer extrusion multipliers
if (firstLayer) {
fillMult *= firstPrintMult;

View file

@ -103,7 +103,6 @@ FDM.slice = function(settings, widget, onupdate, ondone) {
isDanger = controller.danger,
useAssembly = controller.assembly,
isConcurrent = controller.threaded && kiri.minions.concurrent,
solidMinArea = process.sliceSolidMinArea,
solidLayers = process.sliceSolidLayers || 0,
vaseMode = process.sliceFillType === 'vase' && !isSynth,
metadata = widget.anno,
@ -564,7 +563,10 @@ FDM.slice = function(settings, widget, onupdate, ondone) {
if (solidLayers && !vaseMode && !isSynth) {
profileStart("delta");
forSlices(0.2, 0.34, slice => {
if (slice.index > 0) doDiff(slice, solidMinArea);
let params = slice.params || process;
let solidMinArea = params.sliceSolidMinArea;
let sliceFillGrow = params.sliceFillGrow;
doDiff(slice, { min: solidMinArea, grow: sliceFillGrow });
}, "layer deltas");
profileEnd();
profileStart("delta-project");
@ -581,9 +583,12 @@ FDM.slice = function(settings, widget, onupdate, ondone) {
let solidWidth = params.sliceFillWidth || 1;
let spaceMult = first ? params.firstLayerLineMult || 1 : 1;
let fillSpace = fillSpacing * spaceMult * solidWidth;
let solidMinArea = params.sliceSolidMinArea;
doSolidsFill(slice, fillSpace, sliceFillAngle, solidMinArea, promises);
sliceFillAngle += 90.0;
}, "fill solids");
// very last layer (top) is set to finish solid rate
slices.last().finishSolids = true
if (promises) {
await tracker(promises, (i, t) => {
trackupdate(i / t, 0.4, 0.5);
@ -1057,8 +1062,8 @@ function doSparseLayerFill(slice, options = {}) {
* Used to calculate bridges, flats and then solid projections.
* 'expand' is used for top offsets in SLA mode
*/
function doDiff(slice, minArea, options = {}) {
const { sla, fakedown } = options;
function doDiff(slice, options = {}) {
const { sla, fakedown, grow, min } = options;
if (slice.index === 0 && !fakedown) {
return;
}
@ -1076,9 +1081,25 @@ function doDiff(slice, minArea, options = {}) {
return;
}
POLY.subtract(topInner, downInner, bridges, flats, slice.z, minArea, {
let newBridges = [];
let newFlats = [];
POLY.subtract(topInner, downInner, newBridges, newFlats, slice.z, min, {
wasm: true
});
newBridges = newBridges.filter(p => p.areaDeep() >= min);
newFlats = newFlats.filter(p => p.areaDeep() >= min);
if (grow > 0 && newBridges.length) {
newBridges = POLY.offset(newBridges, grow);
}
if (grow > 0 && newFlats.length) {
newFlats = POLY.offset(newFlats, grow);
}
bridges.appendAll(newBridges);
flats.appendAll(newFlats);
};
/**
@ -1099,6 +1120,8 @@ function addSolidFills(slice, polys) {
*/
function projectFlats(slice, count) {
if (!slice.down || !slice.flats) return;
// these flats are marked for finishing print speed
if (slice.flats.length) slice.finishSolids = true;
projectSolid(slice, slice.flats, count, false, true);
};
@ -1107,6 +1130,8 @@ function projectFlats(slice, count) {
*/
function projectBridges(slice, count) {
if (!slice.up || !slice.bridges) return;
// these flats are marked for finishing print speed
if (slice.bridges.length) slice.finishSolids = true;
projectSolid(slice, slice.bridges, count, true, true);
};

View file

@ -298,12 +298,14 @@ const conf = exports({
sliceShellOrder: "in-out",
sliceLayerStart: "last",
sliceLineWidth: 0,
sliceFillGrow: 0,
sliceFillAngle: 45,
sliceFillWidth: 1,
sliceFillOverlap: 0.35,
sliceFillSparse: 0.25,
sliceFillRepeat: 1,
sliceFillRate: 0,
sliceSolidRate: 0,
sliceFillType: "hex",
sliceSupportDensity: 0.25,
sliceSupportOffset: 1.0,

View file

@ -1812,10 +1812,11 @@ gapp.register("kiri.init", [], (root, exports) => {
sliceFillRepeat: uc.newInput(LANG.fi_rept_s, {title:LANG.fi_rept_l, convert:uc.toInt, bound:uc.bound(1,10), show:fillShow, modes:FDM}),
fdmSep: uc.newBlank({class:"pop-sep", modes:FDM}),
sliceFillOverlap: uc.newInput(LANG.fi_over_s, {title:LANG.fi_over_l, convert:uc.toFloat, bound:uc.bound(0.0,2.0), modes:FDM}),
sliceFillRate: uc.newInput(LANG.ou_feed_s, {title:LANG.fi_rate_l, convert:uc.toInt, bound:uc.bound(0,300), modes:FDM}),
sliceFillRate: uc.newInput(LANG.ou_feed_s, {title:LANG.ou_feed_l, convert:uc.toInt, bound:uc.bound(0,500), modes:FDM}),
sliceSolidRate: uc.newInput(LANG.ou_fini_s, {title:LANG.ou_fini_l, convert:uc.toInt, bound:uc.bound(0,500), modes:FDM}),
fdmSep: uc.newBlank({class:"pop-sep", modes:FDM}),
sliceFillGrow: uc.newInput(LANG.fi_grow_s, {title:LANG.fi_grow_l, convert:uc.toFloat, modes:FDM}),
sliceFillAngle: uc.newInput(LANG.fi_angl_s, {title:LANG.fi_angl_l, convert:uc.toFloat, modes:FDM}),
// sliceFillWidth: uc.newInput(LANG.fi_wdth_s, {title:LANG.fi_wdth_l, convert:uc.toFloat, modes:FDM}),
fdmSupport: uc.newGroup(LANG.sp_menu, null, {modes:FDM, marker:false}),
sliceSupportNozzle: uc.newSelect(LANG.sp_nozl_s, {title:LANG.sp_nozl_l, modes:FDM}, "extruders"),

View file

@ -328,10 +328,10 @@ self.kiri.lang['en-us'] = {
fi_pcnt_l: ["fill density values","0.0 - 1.0"],
fi_rept_s: "fill repeat",
fi_rept_l: ["number of times to repeat","unchanged fill layers"],
fi_angl_s: "solid start",
fi_angl_s: "solid angle",
fi_angl_l: ["starting angle in degrees","90 degrees added to ","each following layer","applies only to solid layers"],
fi_wdth_s: "solid width",
fi_wdth_l: ["line width for solid fill","as a fraction of nozzle width","values < 1 are more dense","good for surface finishes","0.0 - 1.0"],
fi_grow_s: "solid expand",
fi_grow_l: ["expand projected solids","can help with solid areas","over sparse infill areas","units in millimeters"],
fi_over_s: "shell overlap",
fi_over_l: ["overlap with shell and other fill","as fraction of nozzle diameter","0.0 - 2.0"],
// fi_rate_s: "print speed",
@ -568,9 +568,9 @@ self.kiri.lang['en-us'] = {
ou_bedd_s: "bed temp",
ou_bedd_l: "degrees in celsius",
ou_feed_s: "print speed",
ou_feed_l: ["max print speed","millimeters / second"],
ou_feed_l: ["max printing speed","set to 0 to use default","millimeters / second"],
ou_fini_s: "finish speed",
ou_fini_l: ["outermost shell speed","millimeters / second"],
ou_fini_l: ["outermost shell speed","bridge/flat solid layers","set to 0 to use default","millimeters / second"],
ou_move_s: "move speed",
ou_move_l: ["non-print move speed","millimeters / second","0 = enable G0 moves"],
ou_shml_s: "shell factor",