diff --git a/src/kiri/conf.js b/src/kiri/conf.js index df47ff6f..a5790c9f 100644 --- a/src/kiri/conf.js +++ b/src/kiri/conf.js @@ -275,6 +275,7 @@ processName: "default", sliceHeight: 0.25, sliceShells: 3, + sliceShellOrder: "in-out", sliceFillAngle: 45, sliceFillOverlap: 0.3, sliceFillSparse: 0.5, diff --git a/src/kiri/init.js b/src/kiri/init.js index 0fdcaaec..eac86bc7 100644 --- a/src/kiri/init.js +++ b/src/kiri/init.js @@ -1418,13 +1418,14 @@ process: UC.newGroup(LANG.sl_menu, $('settings'), {modes:FDM_LASER}), sliceHeight: UC.newInput(LANG.sl_lahi_s, {title:LANG.sl_lahi_l, convert:UC.toFloat, modes:FDM}), sliceMinHeight: UC.newInput(LANG.ad_minl_s, {title:LANG.ad_minl_l, bound:UC.bound(0,3.0), convert:UC.toFloat, modes:FDM, expert:true, show: () => UI.sliceAdaptive.checked}), + fdmSep: UC.newBlank({class:"pop-sep", modes:FDM}), sliceShells: UC.newInput(LANG.sl_shel_s, {title:LANG.sl_shel_l, convert:UC.toInt, modes:FDM}), sliceTopLayers: UC.newInput(LANG.sl_ltop_s, {title:LANG.sl_ltop_l, convert:UC.toInt, modes:FDM}), sliceSolidLayers: UC.newInput(LANG.sl_lsld_s, {title:LANG.sl_lsld_l, convert:UC.toInt, modes:FDM}), sliceBottomLayers: UC.newInput(LANG.sl_lbot_s, {title:LANG.sl_lbot_l, convert:UC.toInt, modes:FDM}), fdmSep: UC.newBlank({class:"pop-sep", modes:FDM}), - detectThinWalls: UC.newBoolean(LANG.ad_thin_s, onBooleanClick, {title: LANG.ad_thin_l, modes:FDM, expert:true}), sliceAdaptive: UC.newBoolean(LANG.ad_adap_s, onBooleanClick, {title: LANG.ad_adap_l, modes:FDM, expert:true, trigger: true}), + detectThinWalls: UC.newBoolean(LANG.ad_thin_s, onBooleanClick, {title: LANG.ad_thin_l, modes:FDM, expert:true}), laserOffset: UC.newInput(LANG.ls_offs_s, {title:LANG.ls_offs_l, convert:UC.toFloat, modes:LASER}), laserSliceHeight: UC.newInput(LANG.ls_lahi_s, {title:LANG.ls_lahi_l, convert:UC.toFloat, modes:LASER, trigger: true}), @@ -1433,12 +1434,14 @@ fdmInfill: UC.newGroup(LANG.fi_menu, $('settings'), {modes:FDM, marker:true}), 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}), sliceFillAngle: UC.newInput(LANG.fi_angl_s, {title:LANG.fi_angl_l, convert:UC.toFloat, modes:FDM, expert:true}), sliceFillOverlap: UC.newInput(LANG.fi_over_s, {title:LANG.fi_over_l, convert:UC.toFloat, bound:UC.bound(0.0,2.0), modes:FDM, expert:true}), firstLayer: UC.newGroup(LANG.fl_menu, null, {modes:FDM}), firstSliceHeight: UC.newInput(LANG.fl_lahi_s, {title:LANG.fl_lahi_l, convert:UC.toFloat, modes:FDM}), + fdmSep: UC.newBlank({class:"pop-sep", modes:FDM}), firstLayerRate: UC.newInput(LANG.fl_rate_s, {title:LANG.fl_rate_l, convert:UC.toFloat, modes:FDM}), firstLayerFillRate: UC.newInput(LANG.fl_frat_s, {title:LANG.fl_frat_l, convert:UC.toFloat, modes:FDM}), firstLayerPrintMult: UC.newInput(LANG.fl_mult_s, {title:LANG.fl_mult_l, convert:UC.toFloat, modes:FDM, expert:true}), @@ -1451,14 +1454,16 @@ fdmSupport: UC.newGroup(LANG.sp_menu, null, {modes:FDM, marker:true}), sliceSupportDensity: UC.newInput(LANG.sp_dens_s, {title:LANG.sp_dens_l, convert:UC.toFloat, bound:UC.bound(0.05,1.0), modes:FDM}), + fdmSep: UC.newBlank({class:"pop-sep", modes:FDM}), sliceSupportSize: UC.newInput(LANG.sp_size_s, {title:LANG.sp_size_l, bound:UC.bound(1.0,200.0), convert:UC.toFloat, modes:FDM}), sliceSupportOffset: UC.newInput(LANG.sp_offs_s, {title:LANG.sp_offs_l, bound:UC.bound(0.0,200.0), convert:UC.toFloat, modes:FDM}), sliceSupportGap: UC.newInput(LANG.sp_gaps_s, {title:LANG.sp_gaps_l, bound:UC.bound(0,5), convert:UC.toInt, modes:FDM, expert:true}), + fdmSep: UC.newBlank({class:"pop-sep", modes:FDM}), sliceSupportSpan: UC.newInput(LANG.sp_span_s, {title:LANG.sp_span_l, bound:UC.bound(0.0,200.0), convert:UC.toFloat, modes:FDM}), sliceSupportArea: UC.newInput(LANG.sp_area_s, {title:LANG.sp_area_l, bound:UC.bound(0.0,200.0), convert:UC.toFloat, modes:FDM}), sliceSupportExtra: UC.newInput(LANG.sp_xpnd_s, {title:LANG.sp_xpnd_l, bound:UC.bound(0.0,200.0), convert:UC.toFloat, modes:FDM, expert:true}), - sliceSupportNozzle: UC.newSelect(LANG.sp_nozl_s, {title:LANG.sp_nozl_l, modes:FDM, expert:true}, "extruders"), fdmSep: UC.newBlank({class:"pop-sep", modes:FDM}), + sliceSupportNozzle: UC.newSelect(LANG.sp_nozl_s, {title:LANG.sp_nozl_l, modes:FDM, expert:true}, "extruders"), sliceSupportEnable: UC.newBoolean(LANG.enable, onBooleanClick, {modes:FDM}), fdmRaft: UC.newGroup(LANG.fr_menu, null, {modes:FDM, marker:true}), @@ -1571,6 +1576,7 @@ outputSparseMult: UC.newInput(LANG.ou_spml_s, {title:LANG.ou_exml_l, convert:UC.toFloat, bound:UC.bound(0.0,2.0), modes:FDM}), fdmSep: UC.newBlank({class:"pop-sep", modes:FDM}), outputFanLayer: UC.newInput(LANG.ou_fanl_s, {title:LANG.ou_fanl_l, convert:UC.toInt, bound:UC.bound(0,100), modes:FDM, expert:true}), + sliceShellOrder: UC.newSelect(LANG.sl_ordr_s, {title:LANG.sl_ordr_l, modes:FDM}, "shell"), camConventional: UC.newBoolean(LANG.ou_conv_s, onBooleanClick, {title:LANG.ou_conv_l, modes:CAM}), camEaseDown: UC.newBoolean(LANG.cr_ease_s, onBooleanClick, {title:LANG.cr_ease_l, modes:CAM}), camDepthFirst: UC.newBoolean(LANG.ou_depf_s, onBooleanClick, {title:LANG.ou_depf_l, modes:CAM}), diff --git a/src/kiri/main.js b/src/kiri/main.js index f4c18eee..f042f6c9 100644 --- a/src/kiri/main.js +++ b/src/kiri/main.js @@ -128,6 +128,10 @@ }; const lists = { + shell: [ + { name: "in-out" }, + { name: "out-in" }, + ], infill: [ { name: "vase" }, { name: "hex" }, diff --git a/src/kiri/print.js b/src/kiri/print.js index 1bbd63b5..43779a3d 100644 --- a/src/kiri/print.js +++ b/src/kiri/print.js @@ -397,6 +397,7 @@ retractDist = opt.retractOver || 2, 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, sparseMult = process.outputSparseMult, coastDist = process.outputCoastDist || 0, finishSpeed = opt.speed || process.outputFinishrate, @@ -703,21 +704,19 @@ // top object let bounds = POLY.flatten(next.shellsAtDepth(0).clone(true)); - let dir = -1; // 1 == inside out, -1 == outside-in - // output inner polygons - if (dir === 1) + if (shellOrder === 1) outputTraces([].appendAll(next.innerShells() || [])); // sort perimeter polygon by length to go out-to-in or in-to-out (next.shells || []).sort(function(a,b) { - return a.perimeter() > b.perimeter() ? dir : -dir; + return a.perimeter() > b.perimeter() ? shellOrder : -shellOrder; }).forEach(function(poly, index) { outputTraces(poly); }); // output outer polygons - if (dir === -1) + if (shellOrder === -1) outputTraces([].appendAll(next.innerShells() || [])); // output thin fill diff --git a/web/kiri/lang/en.js b/web/kiri/lang/en.js index 53fecffc..29443c3d 100644 --- a/web/kiri/lang/en.js +++ b/web/kiri/lang/en.js @@ -180,24 +180,28 @@ kiri.lang['en-us'] = { se_save: "save", // FDM SLICING - sl_menu: "slicing", - sl_lahi_s: "layer height", + sl_menu: "layers", + sl_lahi_s: "height", sl_lahi_l: "height of each slice\nlayer in millimeters", - ad_minl_s: "layer min", + ad_minl_s: "height min", ad_minl_l: "adaptive min layer height\nin millimeters\nmust be non-zero", - sl_shel_s: "shell count", - sl_shel_l: "number of perimeter\nwalls to generate", sl_ltop_s: "top layers", sl_ltop_l: "number of solid layers\nto enforce at the\ntop of the print", sl_lsld_s: "solid layers", sl_lsld_l: "solid fill areas computed\nfrom layer deltas. see\nlayer pop menu", sl_lbot_s: "base layers", sl_lbot_l: "number of solid layers\nto enforce at the\nbottom of the print", - ad_thin_s: "thin walls", - ad_thin_l: "detect and fill gaps\nbetween shell walls", ad_adap_s: "adaptive", ad_adap_l: "use adaptive layer heights\nwith 'layer height' as max\nand 'layer min' as the min", + // FDM SHELLS + sl_shel_s: "shell count", + sl_shel_l: "number of perimeter\nwalls to generate", + sl_ordr_s: "shell order", + sl_ordr_l: "output shell order\ninside to outside\nor outside to inside\naffects surface quality", + ad_thin_s: "thin walls", + ad_thin_l: "detect and fill gaps\nbetween shell walls", + // FDM FILL fi_menu: "infill", fi_type: "type",