diff --git a/src/kiri/conf.js b/src/kiri/conf.js index e1b4f47c..1ea366af 100644 --- a/src/kiri/conf.js +++ b/src/kiri/conf.js @@ -289,6 +289,7 @@ sliceShellOrder: "in-out", sliceLayerStart: "last", sliceFillAngle: 45, + sliceFillWidth: 1, sliceFillOverlap: 0.3, sliceFillSparse: 0.5, sliceFillRate: 0, diff --git a/src/kiri/init.js b/src/kiri/init.js index 8e8ff20a..8bad67f0 100644 --- a/src/kiri/init.js +++ b/src/kiri/init.js @@ -1667,13 +1667,13 @@ fdmInfill: UC.newGroup(LANG.fi_menu, $('settings'), {modes:FDM}), sliceFillType: UC.newSelect(LANG.fi_type, {modes:FDM}, "infill"), - fdmSep: UC.newBlank({class:"pop-sep", modes:FDM}), sliceFillSparse: UC.newInput(LANG.fi_pcnt_s, {title:LANG.fi_pcnt_l, convert:UC.toFloat, bound:UC.bound(0.0,1.0), 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}), - sliceFillAngle: UC.newInput(LANG.fi_angl_s, {title:LANG.fi_angl_l, convert:UC.toFloat, modes:FDM}), - // fdmSep: UC.newBlank({class:"pop-sep", modes:FDM}), sliceFillRate: UC.newInput(LANG.ou_feed_s, {title:LANG.fi_rate_l, convert:UC.toInt, bound:UC.bound(0,300), modes:FDM}), + fdmSep: UC.newBlank({class:"pop-sep", 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"), diff --git a/src/kiri/print.js b/src/kiri/print.js index c856ed42..44583264 100644 --- a/src/kiri/print.js +++ b/src/kiri/print.js @@ -515,6 +515,7 @@ firstLayer = opt.first || false, thinWall = nozzleSize * (opt.thinWall || 1.75), retractDist = opt.retractOver || 2, + solidWidth = process.sliceFillWidth || 1, fillMult = opt.mult || process.outputFillMult, shellMult = opt.mult || process.outputShellMult || (process.laserSliceHeight >= 0 ? 1 : 0), shellOrder = {"out-in":-1,"in-out":1}[process.sliceShellOrder] || -1, @@ -801,7 +802,7 @@ }); } - function outputFills(lines, options) { + function outputFills(lines, opt = {}) { if (!lines || lines.length === 0) { return; } @@ -810,10 +811,10 @@ start = 0, skip = false, lastIndex = -1, - opt = options || {}, + flow = opt.flow || 1, near = opt.near || false, fast = opt.fast || false, - fill = opt.fill >= 0 ? opt.fill : fillMult, + fill = (opt.fill >= 0 ? opt.fill : fillMult) * flow, thinDist = near ? thinWall : thinWall; while (lines && marked < lines.length) { @@ -1036,7 +1037,7 @@ outputFills(next.thin_fill, {near: true}); // then output solid and sparse fill - outputFills(next.fill_lines); + outputFills(next.fill_lines, {flow: solidWidth}); outputSparse(next.fill_sparse, sparseMult, infillSpeed); lastTop = next; diff --git a/src/mode/fdm/client.js b/src/mode/fdm/client.js index 809e745a..77464d47 100644 --- a/src/mode/fdm/client.js +++ b/src/mode/fdm/client.js @@ -33,6 +33,7 @@ // slice "sliceShells": LANG.sl_shel_s, "sliceFillType": LANG.fi_type, + "sliceFillWidth": LANG.fi_wdth_s, "sliceFillSparse": LANG.fi_pcnt_s, "sliceSolidMinArea": LANG.ad_msol_s, // prepare diff --git a/src/mode/fdm/fill.js b/src/mode/fdm/fill.js index 9a1245eb..4b73126c 100644 --- a/src/mode/fdm/fill.js +++ b/src/mode/fdm/fill.js @@ -155,27 +155,28 @@ function fillLinear(target) { let bounds = target.bounds(); let height = target.zHeight(); + + let density = target.density(); + let line = target.lineWidth(); + let span_x = bounds.max.x - bounds.min.x; let span_y = bounds.max.y - bounds.min.y; - let density = target.density(); - let offset = target.offset() / 2; - let line = target.lineWidth(); - let mf = Math.max(span_x, span_y) / line; - let tile = 1 + (1 - density); - let tile_xc = Math.ceil(span_x / tile); - let tile_yc = Math.ceil(span_y / tile); + let steps_x = (span_x / line) * density; + let steps_y = (span_y / line) * density; + let step_x = span_x / steps_x; + let step_y = span_x / steps_x; if (target.zIndex() % 2 === 1) { - for (let tx=0; tx<=tile_xc; tx++) { + for (let tx=bounds.min.x; tx<=bounds.max.x; tx += step_x) { target.newline(); - target.emit(tx * tile + bounds.min.x, bounds.min.y); - target.emit(tx * tile + bounds.min.x, bounds.max.y); + target.emit(tx, bounds.min.y); + target.emit(tx, bounds.max.y); } } else { - for (let ty=0; ty<=tile_yc; ty++) { + for (let ty=bounds.min.y; ty<=bounds.max.y; ty += step_y) { target.newline(); - target.emit(bounds.min.x, ty * tile + bounds.min.y); - target.emit(bounds.max.x, ty * tile + bounds.min.y); + target.emit(bounds.min.x, ty); + target.emit(bounds.max.x, ty); } } } diff --git a/src/mode/fdm/slice.js b/src/mode/fdm/slice.js index c36cb920..688d3c40 100644 --- a/src/mode/fdm/slice.js +++ b/src/mode/fdm/slice.js @@ -294,6 +294,7 @@ let isTop = slice.index > slices.length - spro.sliceTopLayers-1; let isDense = params.sliceFillSparse > 0.98; let solid = (isBottom || ((isTop || isDense) && !vaseMode)) && !isSynth; + let solidWidth = params.sliceFillWidth || 1; let spaceMult = first ? spro.firstLayerLineMult || 1 : 1; let offset = shellOffset * spaceMult; let fillOff = fillOffset * spaceMult; @@ -305,7 +306,7 @@ danger: ctrl.danger }); if (solid) { - let fillSpace = fillSpacing * spaceMult; + let fillSpace = fillSpacing * spaceMult * solidWidth; doSolidLayerFill(slice, fillSpace, sliceFillAngle); } sliceFillAngle += 90.0; @@ -381,9 +382,11 @@ projectBridges(slice, solidLayers); }, "solids"); forSlices(0.35, 0.5, slice => { + let params = getRangeParameters(settings, slice.index); let first = slice.index === 0; - let spaceMult = first ? spro.firstLayerLineMult || 1 : 1; - let fillSpace = fillSpacing * spaceMult; + let solidWidth = params.sliceFillWidth || 1; + let spaceMult = first ? params.firstLayerLineMult || 1 : 1; + let fillSpace = fillSpacing * spaceMult * solidWidth; doSolidsFill(slice, fillSpace, sliceFillAngle, minSolid); sliceFillAngle += 90.0; }, "solids"); @@ -439,7 +442,8 @@ // render if not explicitly disabled if (render) { forSlices(0.9, 1.0, slice => { - doRender(slice, isSynth); + let params = getRangeParameters(settings, slice.index); + doRender(slice, isSynth, params); }, "render"); } @@ -462,9 +466,10 @@ return Math.max(min,Math.min(max,v)); } - function doRender(slice, isSynth) { + function doRender(slice, isSynth, params) { const output = slice.output(); const height = slice.height / 2; + const solidWidth = params.sliceFillWidth || 1; slice.tops.forEach(top => { if (isThin) output @@ -489,7 +494,7 @@ if (top.fill_lines && top.fill_lines.length) output .setLayer("fill", isSynth ? COLOR.support : COLOR.fill) - .addLines(top.fill_lines, vopt({ offset, height })); + .addLines(top.fill_lines, vopt({ offset: offset * solidWidth, height })); if (top.fill_sparse) output .setLayer("infill", COLOR.infill) diff --git a/web/kiri/lang/en.js b/web/kiri/lang/en.js index 7244e587..4016cfe4 100644 --- a/web/kiri/lang/en.js +++ b/web/kiri/lang/en.js @@ -270,13 +270,15 @@ kiri.lang['en-us'] = { // FDM FILL fi_menu: "infill", - fi_type: "type", + fi_type: "fill type", fi_pcnt_s: "fill fraction", fi_pcnt_l: ["fill density values","0.0 - 1.0"], fi_angl_s: "solid start", fi_angl_l: ["starting angle in degrees","90 degrees added to ","each following layer","applies only to solid layers"], - fi_over_s: "overlap", - fi_over_l: ["overlap with shell and other fill","as fraction of nozzle diameter","0.0 - 1.0"], + 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_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", fi_rate_l: ["extrusion speed for infill","set to 0 to use default","output print speeds"],