checkpoint sla work

This commit is contained in:
Stewart Allen 2020-04-13 19:28:17 -04:00
commit 2f85082c79
6 changed files with 131 additions and 118 deletions

View file

@ -298,14 +298,9 @@ let gs_kiri_conf = exports;
p:{ p:{
processName: "default", processName: "default",
slaSlice: 0.05, slaSlice: 0.05,
slaSupportEnable: false, slaBottoms: 5,
slaSupportDensity: 0.5, slaSolids: 5,
slaSupportSize: 2, slaTops: 5
slaSupportArea: 1,
slaSupportSpan: 2,
slaSolidLayers: 5,
slaBottomLayers: 5,
slaTopLayers: 5
} }
}, },
cam:{ cam:{

View file

@ -40,7 +40,9 @@ let gs_kiri_laser = exports;
return ondone("invalid slice height"); return ondone("invalid slice height");
} }
SLICER.sliceWidget(widget, {height: proc.laserSliceHeight, single: proc.laserSliceSingle}, function(slices) { SLICER.sliceWidget(widget, {
height: proc.laserSliceHeight, single: proc.laserSliceSingle
}, function(slices) {
widget.slices = slices; widget.slices = slices;
slices.forEach(function(slice, index) { slices.forEach(function(slice, index) {
slice.doShells(1, -proc.laserOffset); slice.doShells(1, -proc.laserOffset);

View file

@ -36,33 +36,48 @@ let gs_kiri_sla = exports;
let process = settings.process, let process = settings.process,
device = settings.device; device = settings.device;
SLICER.sliceWidget(widget, { height: sliceHeight }, onSliceDone, onSliceUpdate); // calculate % complete and call onupdate()
function doupdate(slices, index, from, to, msg) {
function onSliceUpdate(update) { onupdate(0.5 + (from + ((index / slices.length) * (to - from))) * 0.5, msg);
return onupdate(0.0 + update * 0.5);
} }
function onSliceDone(slices) { // for each slice, performe a function and call doupdate()
function forSlices(slices, from, to, fn, msg) {
slices.forEach(function(slice) {
fn(slice);
doupdate(slices, slice.index, from, to, msg)
});
}
SLICER.sliceWidget(widget, {
height: process.slaSlice || 0.05
}, function(slices) {
widget.slices = slices; widget.slices = slices;
// reset for solids and support projections
if (!slices) return; slices.forEach(function(slice) {
slice.invalidateFill();
// calculate % complete and call onupdate() slice.invalidateSolids();
function doupdate(index, from, to, msg) { slice.invalidateSupports();
onupdate(0.5 + (from + ((index/slices.length) * (to-from))) * 0.5, msg); slice.isSolidFill = false;
} });
forSlices(slices, 0.0, 0.2, (slice) => {
// for each slice, performe a function and call doupdate() slice.doShells(1, 0);
function forSlices(from, to, fn, msg) { // slice.tops.forEach(top => { top.solids = [] });
slices.forEach(function(slice) { }, "slice");
fn(slice); forSlices(slices, 0.2, 0.4, (slice) => {
doupdate(slice.index, from, to, msg) slice.doDiff(0.00001, 0.005);
}); }, "delta");
} forSlices(slices, 0.4, 0.5, (slice) => {
slice.projectFlats(process.slaSolids || 5);
// report slicing complete slice.projectBridges(process.slaSolids || 5);
}, "project");
forSlices(slices, 0.5, 0.6, (slice) => {
slice.doSolidsFill(undefined, undefined, 0.00001);
}, "solid");
ondone(); ondone();
} }, function(update) {
return onupdate(0.0 + update * 0.5);
});
}; };
/** /**

View file

@ -32,12 +32,15 @@ var gs_kiri_init = exports;
DEG = Math.PI/180, DEG = Math.PI/180,
ALL = [MODES.FDM, MODES.LASER, MODES.CAM, MODES.SLA], ALL = [MODES.FDM, MODES.LASER, MODES.CAM, MODES.SLA],
CAM = [MODES.CAM], CAM = [MODES.CAM],
SLA = [MODES.SLA],
FDM = [MODES.FDM], FDM = [MODES.FDM],
FDM_SLA = [MODES.FDM,MODES.SLA],
FDM_CAM = [MODES.CAM,MODES.FDM], FDM_CAM = [MODES.CAM,MODES.FDM],
FDM_LASER = [MODES.LASER,MODES.FDM], FDM_LASER = [MODES.LASER,MODES.FDM],
FDM_LASER_SLA = [MODES.LASER,MODES.FDM,MODES.SLA],
CAM_LASER = [MODES.LASER,MODES.CAM], CAM_LASER = [MODES.LASER,MODES.CAM],
LASER = [MODES.LASER],
GCODE = [MODES.FDM, MODES.LASER, MODES.CAM], GCODE = [MODES.FDM, MODES.LASER, MODES.CAM],
LASER = [MODES.LASER],
CATALOG = API.catalog, CATALOG = API.catalog,
platform = API.platform, platform = API.platform,
selection = API.selection, selection = API.selection,
@ -1271,14 +1274,14 @@ var gs_kiri_init = exports;
layers: UC.setGroup($("layers")), layers: UC.setGroup($("layers")),
layerOutline: UC.newBoolean(LANG.la_olin, onLayerToggle, {modes:LOCAL ? ALL : FDM_LASER}), layerOutline: UC.newBoolean(LANG.la_olin, onLayerToggle, {modes:LOCAL ? ALL : FDM_LASER}),
layerTrace: UC.newBoolean(LANG.la_trce, onLayerToggle, {modes:FDM_LASER}), layerTrace: UC.newBoolean(LANG.la_trce, onLayerToggle, {modes:FDM_LASER_SLA}),
layerFacing: UC.newBoolean(LANG.la_face, onLayerToggle, {modes:CAM}), layerFacing: UC.newBoolean(LANG.la_face, onLayerToggle, {modes:CAM}),
layerRough: UC.newBoolean(LANG.la_ruff, onLayerToggle, {modes:CAM}), layerRough: UC.newBoolean(LANG.la_ruff, onLayerToggle, {modes:CAM}),
layerFinish: UC.newBoolean(LANG.la_fini, onLayerToggle, {modes:CAM}), layerFinish: UC.newBoolean(LANG.la_fini, onLayerToggle, {modes:CAM}),
layerFinishX: UC.newBoolean(LANG.la_finx, onLayerToggle, {modes:CAM}), layerFinishX: UC.newBoolean(LANG.la_finx, onLayerToggle, {modes:CAM}),
layerFinishY: UC.newBoolean(LANG.la_finy, onLayerToggle, {modes:CAM}), layerFinishY: UC.newBoolean(LANG.la_finy, onLayerToggle, {modes:CAM}),
layerDelta: UC.newBoolean(LANG.la_dlta, onLayerToggle, {modes:FDM}), layerDelta: UC.newBoolean(LANG.la_dlta, onLayerToggle, {modes:FDM_SLA}),
layerSolid: UC.newBoolean(LANG.la_slds, onLayerToggle, {modes:FDM}), layerSolid: UC.newBoolean(LANG.la_slds, onLayerToggle, {modes:FDM_SLA}),
layerFill: UC.newBoolean(LANG.la_fill, onLayerToggle, {modes:FDM}), layerFill: UC.newBoolean(LANG.la_fill, onLayerToggle, {modes:FDM}),
layerSparse: UC.newBoolean(LANG.la_sprs, onLayerToggle, {modes:FDM}), layerSparse: UC.newBoolean(LANG.la_sprs, onLayerToggle, {modes:FDM}),
layerSupport: UC.newBoolean(LANG.la_sprt, onLayerToggle, {modes:FDM}), layerSupport: UC.newBoolean(LANG.la_sprt, onLayerToggle, {modes:FDM}),
@ -1382,7 +1385,7 @@ var gs_kiri_init = exports;
outputRaftSpacing: UC.newInput(LANG.fr_spac_s, {title:LANG.fr_spac_l, convert:UC.toFloat, bound:UC.bound(0.0,3.0), modes:FDM}), outputRaftSpacing: UC.newInput(LANG.fr_spac_s, {title:LANG.fr_spac_l, convert:UC.toFloat, bound:UC.bound(0.0,3.0), modes:FDM}),
outputRaft: UC.newBoolean(LANG.enable, onBooleanClick, {title:LANG.fr_nabl_l, modes:FDM}), outputRaft: UC.newBoolean(LANG.enable, onBooleanClick, {title:LANG.fr_nabl_l, modes:FDM}),
output: UC.newGroup(LANG.ou_menu), output: UC.newGroup(LANG.ou_menu, null, {modes:GCODE}),
outputTileSpacing: UC.newInput(LANG.ou_spac_c, {title:LANG.ou_spac_l, convert:UC.toInt, modes:LASER}), outputTileSpacing: UC.newInput(LANG.ou_spac_c, {title:LANG.ou_spac_l, convert:UC.toInt, modes:LASER}),
outputTileScaling: UC.newInput(LANG.ou_scal_s, {title:LANG.ou_scal_l, convert:UC.toInt, bound:UC.bound(0.1,100), modes:LASER}), outputTileScaling: UC.newInput(LANG.ou_scal_s, {title:LANG.ou_scal_l, convert:UC.toInt, bound:UC.bound(0.1,100), modes:LASER}),
outputLaserPower: UC.newInput(LANG.ou_powr_s, {title:LANG.ou_powr_l, convert:UC.toInt, bound:UC.bound(1,100), modes:LASER}), outputLaserPower: UC.newInput(LANG.ou_powr_s, {title:LANG.ou_powr_l, convert:UC.toInt, bound:UC.bound(1,100), modes:LASER}),
@ -1429,7 +1432,14 @@ var gs_kiri_init = exports;
antiBacklash: UC.newInput(LANG.ad_abkl_s, {title:LANG.ad_abkl_l, bound:UC.bound(0,3), convert:UC.toInt, modes:FDM, expert:true}), antiBacklash: UC.newInput(LANG.ad_abkl_s, {title:LANG.ad_abkl_l, bound:UC.bound(0,3), convert:UC.toInt, modes:FDM, expert:true}),
// detectThinWalls: UC.newBoolean("thin wall fill", onBooleanClick, {title: "detect and fill thin openings\nbetween shells walls", modes:FDM, expert:true}) // detectThinWalls: UC.newBoolean("thin wall fill", onBooleanClick, {title: "detect and fill thin openings\nbetween shells walls", modes:FDM, expert:true})
gcodePauseLayers: UC.newInput(LANG.ag_paws_s, {title:LANG.ag_paws_l, modes:FDM, expert:true}), gcodePauseLayers: UC.newInput(LANG.ag_paws_s, {title:LANG.ag_paws_l, modes:FDM, expert:true}),
outputLayerRetract: UC.newBoolean(LANG.ad_lret_s, onBooleanClick, {title:LANG.ad_lret_l, modes:FDM, expert:true}) outputLayerRetract: UC.newBoolean(LANG.ad_lret_s, onBooleanClick, {title:LANG.ad_lret_l, modes:FDM, expert:true}),
// SLA
slaProc: UC.newGroup('slaproc', null, {modes:SLA}),
slaSlice: UC.newInput('slice height', {title:'slice height', convert:UC.toFloat, modes:SLA}),
slaBottoms: UC.newInput('bottom layers', {title:'bottom layers', convert:UC.toInt, modes:SLA}),
slaSolids: UC.newInput('solid layers', {title:'solid layers', convert:UC.toInt, modes:SLA}),
slaTops: UC.newInput('top layers', {title:'bottom layers', convert:UC.toInt, modes:SLA}),
}); });
if (!LOCAL) { if (!LOCAL) {
@ -1548,27 +1558,6 @@ var gs_kiri_init = exports;
UI.layers.style.left = ev.target.getBoundingClientRect().left + 'px'; UI.layers.style.left = ev.target.getBoundingClientRect().left + 'px';
}; };
// $('rot_x').onkeypress = (ev) => {
// if (ev.key === 'Enter') {
// API.selection.rotate(parseFloat(ev.target.value)*DEG,0,0);
// ev.target.value = 0;
// }
// };
//
// $('rot_y').onkeypress = (ev) => {
// if (ev.key === 'Enter') {
// API.selection.rotate(0,parseFloat(ev.target.value)*DEG,0);
// ev.target.value = 0;
// }
// };
//
// $('rot_z').onkeypress = (ev) => {
// if (ev.key === 'Enter') {
// API.selection.rotate(0,0,parseFloat(ev.target.value)*DEG);
// ev.target.value = 0;
// }
// };
UI.modelOpacity.onchange = UI.modelOpacity.onclick = function(ev) { UI.modelOpacity.onchange = UI.modelOpacity.onclick = function(ev) {
API.widgets.opacity(parseInt(UI.modelOpacity.value)/100); API.widgets.opacity(parseInt(UI.modelOpacity.value)/100);
}; };

View file

@ -2,14 +2,14 @@
"use strict"; "use strict";
var gs_kiri_slice = exports; let gs_kiri_slice = exports;
(function() { (function() {
if (!self.kiri) self.kiri = {}; if (!self.kiri) self.kiri = {};
if (self.kiri.Slice) return; if (self.kiri.Slice) return;
var KIRI = self.kiri, let KIRI = self.kiri,
FILL = KIRI.fill, FILL = KIRI.fill,
BASE = self.base, BASE = self.base,
UTIL = BASE.util, UTIL = BASE.util,
@ -108,7 +108,7 @@ var gs_kiri_slice = exports;
* the outline shell that the fill touches. * the outline shell that the fill touches.
*/ */
Top.prototype.innerTraces = function() { Top.prototype.innerTraces = function() {
var traces = this.traces, let traces = this.traces,
array = []; array = [];
if (traces) traces.forEach(function(p) { if (traces) traces.forEach(function(p) {
if (p.inner) array.appendAll(p.inner); if (p.inner) array.appendAll(p.inner);
@ -117,7 +117,7 @@ var gs_kiri_slice = exports;
}; };
Top.prototype.clone = function(deep) { Top.prototype.clone = function(deep) {
var top = new Top(this.poly.clone(deep)); let top = new Top(this.poly.clone(deep));
return top; return top;
}; };
@ -142,7 +142,7 @@ var gs_kiri_slice = exports;
* returns a cloned slice the option of a deep clone on the top polys * returns a cloned slice the option of a deep clone on the top polys
*/ */
PRO.clone = function(deep) { PRO.clone = function(deep) {
var from = this, let from = this,
slice = newSlice(from.z, from.view); slice = newSlice(from.z, from.view);
from.tops.forEach(function(top) { from.tops.forEach(function(top) {
slice.addTop(top.poly.clone(deep)); slice.addTop(top.poly.clone(deep));
@ -203,7 +203,7 @@ var gs_kiri_slice = exports;
* @param {Polygon} poly to merge into a top * @param {Polygon} poly to merge into a top
*/ */
PRO.mergeTop = function(poly) { PRO.mergeTop = function(poly) {
var scope = this, let scope = this,
tops = scope.tops, tops = scope.tops,
union, i; union, i;
for (i=0; i<tops.length; i++) { for (i=0; i<tops.length; i++) {
@ -221,7 +221,7 @@ var gs_kiri_slice = exports;
* @param {Polygon} poly to add * @param {Polygon} poly to add
*/ */
PRO.addTop = function(poly) { PRO.addTop = function(poly) {
var top = new Top(poly); let top = new Top(poly);
this.tops.push(top); this.tops.push(top);
return top; return top;
}; };
@ -309,7 +309,7 @@ var gs_kiri_slice = exports;
* Clear solid area cache in preparation for a new slicing action * Clear solid area cache in preparation for a new slicing action
*/ */
PRO.invalidateSolids = function() { PRO.invalidateSolids = function() {
var solids = this.solids; let solids = this.solids;
solids.poly = []; solids.poly = [];
solids.trimmed = null; solids.trimmed = null;
}; };
@ -329,7 +329,7 @@ var gs_kiri_slice = exports;
PRO.renderOutline = function(renderMode,color) { PRO.renderOutline = function(renderMode,color) {
if (!this.view) return; if (!this.view) return;
var process = KIRI.driver.CAM.process, let process = KIRI.driver.CAM.process,
slice = this, slice = this,
layers = slice.layers, layers = slice.layers,
layer = layers.outline, layer = layers.outline,
@ -347,7 +347,7 @@ var gs_kiri_slice = exports;
case 0: case 0:
if (!slice.lines) return; if (!slice.lines) return;
slice.lines.forEach(function(line) { slice.lines.forEach(function(line) {
var pa = [line.p1, line.p2]; let pa = [line.p1, line.p2];
layer.lines(pa, colors[coloridx++ % colors.length]); layer.lines(pa, colors[coloridx++ % colors.length]);
layer.points(pa, 0x0, 0.1); layer.points(pa, 0x0, 0.1);
}); });
@ -396,16 +396,16 @@ var gs_kiri_slice = exports;
*/ */
function cullIntersections(r1, r2) { function cullIntersections(r1, r2) {
if (!(r1 && r2 && r1.length && r2.length)) return; if (!(r1 && r2 && r1.length && r2.length)) return;
var valid = r2.slice(); let valid = r2.slice();
outer: for (var i=0; i<r1.length; i += 2) { outer: for (let i=0; i<r1.length; i += 2) {
for (var j=0; j<r2.length; j += 2) { for (let j=0; j<r2.length; j += 2) {
if (UTIL.intersect(r1[i], r1[i+1], r2[j], r2[j+1], BASE.key.SEGINT)) continue outer; if (UTIL.intersect(r1[i], r1[i+1], r2[j], r2[j+1], BASE.key.SEGINT)) continue outer;
} }
valid.push(r1[i]); valid.push(r1[i]);
valid.push(r1[i+1]); valid.push(r1[i+1]);
} }
// add index to point for fill order storeSettingsToServer // add index to point for fill order storeSettingsToServer
for (var k=0; k<valid.length; k++) { for (let k=0; k<valid.length; k++) {
valid[k].index = Infinity; valid[k].index = Infinity;
} }
return valid.length > 2 ? valid : []; return valid.length > 2 ? valid : [];
@ -425,11 +425,11 @@ var gs_kiri_slice = exports;
* @param {Obejct} options * @param {Obejct} options
*/ */
PRO.doShells = function(count, offset1, offsetN, fillOffset, options) { PRO.doShells = function(count, offset1, offsetN, fillOffset, options) {
var slice = this, let slice = this,
opt = options || {}; opt = options || {};
slice.tops.forEach(function(top) { slice.tops.forEach(function(top) {
var top_poly = [ top.poly ]; let top_poly = [ top.poly ];
if (slice.index === 0) { if (slice.index === 0) {
// console.log({slice_top_0: top_poly, count}); // console.log({slice_top_0: top_poly, count});
@ -442,7 +442,7 @@ var gs_kiri_slice = exports;
// top.thinner = []; // top.thinner = [];
top.traces = []; top.traces = [];
top.inner = []; top.inner = [];
var last = [], let last = [],
z = top.poly.getZ(); z = top.poly.getZ();
if (opt.thin) { if (opt.thin) {
@ -456,7 +456,7 @@ var gs_kiri_slice = exports;
top.traces = last; top.traces = last;
} else { } else {
if (opt.thin) { if (opt.thin) {
var on1s2 = offset1 * 2, let on1s2 = offset1 * 2,
on2s2 = offsetN * 2; on2s2 = offsetN * 2;
POLY.expand2( POLY.expand2(
top_poly, top_poly,
@ -480,14 +480,14 @@ var gs_kiri_slice = exports;
function(p1, p2, diff, dist) { function(p1, p2, diff, dist) {
if (p2) { if (p2) {
// nth offset // nth offset
var pall = POLY.nest(POLY.flatten([].appendAll(p1).appendAll(p2)).clone()), let pall = POLY.nest(POLY.flatten([].appendAll(p1).appendAll(p2)).clone()),
pnew1 = POLY.expand(pall, -dist, z, null, 1), pnew1 = POLY.expand(pall, -dist, z, null, 1),
r1 = fillArea(pnew1, 45, offsetN, [], dist / 2, on2s2), r1 = fillArea(pnew1, 45, offsetN, [], dist / 2, on2s2),
r2 = fillArea(pnew1, 135, offsetN, [], dist / 2, on2s2), r2 = fillArea(pnew1, 135, offsetN, [], dist / 2, on2s2),
rall = top.thin_fill.appendAll(cullIntersections(r1, r2)); rall = top.thin_fill.appendAll(cullIntersections(r1, r2));
} else { } else {
// first offset // first offset
var pall = POLY.nest(POLY.flatten([].appendAll(p1).appendAll(p2)).clone()), let pall = POLY.nest(POLY.flatten([].appendAll(p1).appendAll(p2)).clone()),
pnew1 = POLY.expand(pall, -dist, z, null, 1), pnew1 = POLY.expand(pall, -dist, z, null, 1),
r1 = fillArea(pnew1, 45, offsetN, [], 0, on1s2), r1 = fillArea(pnew1, 45, offsetN, [], 0, on1s2),
r2 = fillArea(pnew1, 135, offsetN, [], 0, on1s2), r2 = fillArea(pnew1, 135, offsetN, [], 0, on1s2),
@ -537,7 +537,7 @@ var gs_kiri_slice = exports;
* @param {number} renderMode * @param {number} renderMode
*/ */
PRO.renderShells = function(renderMode) { PRO.renderShells = function(renderMode) {
var scope = this, let scope = this,
layers = scope.layers, layers = scope.layers,
layer = layers.trace, layer = layers.trace,
process = KIRI.driver.CAM.process; process = KIRI.driver.CAM.process;
@ -633,7 +633,7 @@ var gs_kiri_slice = exports;
* Runs in client. Generate solid lines in the correct view layer. * Runs in client. Generate solid lines in the correct view layer.
*/ */
PRO.renderSolidFill = function() { PRO.renderSolidFill = function() {
var layer = this.layers.fill, let layer = this.layers.fill,
render; render;
layer.clear(); layer.clear();
@ -661,7 +661,7 @@ var gs_kiri_slice = exports;
this.isSparseFill = false; this.isSparseFill = false;
if (this.tops.length === 0 || density === 0.0 || this.isSolidFill) return; if (this.tops.length === 0 || density === 0.0 || this.isSolidFill) return;
var scope = this, let scope = this,
tops = scope.tops, tops = scope.tops,
down = scope.down, down = scope.down,
clib = self.ClipperLib, clib = self.ClipperLib,
@ -752,7 +752,7 @@ var gs_kiri_slice = exports;
* Runs in client. Generate sparse lines in the correct view layer. * Runs in client. Generate sparse lines in the correct view layer.
*/ */
PRO.renderSparseFill = function() { PRO.renderSparseFill = function() {
var layer = this.layers.sparse; let layer = this.layers.sparse;
layer.clear(); layer.clear();
@ -771,18 +771,19 @@ var gs_kiri_slice = exports;
/** /**
* Find difference between fill inset poly on two adjacent layers. * Find difference between fill inset poly on two adjacent layers.
* Used to calculate bridges, flats and then solid projections. * Used to calculate bridges, flats and then solid projections.
* 'expand' is used for top offsets in SLA mode
*/ */
PRO.doDiff = function(minArea) { PRO.doDiff = function(minArea, expand) {
if (!this.down) return; if (!this.down) return;
var top = this, let top = this,
bottom = this.down; bottom = this.down;
top.bridges = null; top.bridges = null;
bottom.flats = null; bottom.flats = null;
var topInner = top.gatherInner([]), let topInner = expand ? top.gatherTopPolys([]) : top.gatherInner([]),
bottomInner = bottom.gatherInner([]), bottomInner = expand ? bottom.gatherTopPolys([]) : bottom.gatherInner([]),
bridges = [], bridges = [],
flats = []; flats = [];
@ -795,15 +796,22 @@ var gs_kiri_slice = exports;
POLY.subtract(topInner, bottomInner, bridges, flats, this.z, minArea); POLY.subtract(topInner, bottomInner, bridges, flats, this.z, minArea);
top.bridges = bridges; if (expand) {
bottom.flats = flats; top.bridges = [];
bottom.flats = [];
POLY.expand(bridges, expand, top.z, top.bridges, 1);
POLY.expand(flats, expand, top.z, bottom.flats, 1);
} else {
top.bridges = bridges;
bottom.flats = flats;
}
}; };
/** /**
* Runs in client. Generate polygon lines in the correct view layer. * Runs in client. Generate polygon lines in the correct view layer.
*/ */
PRO.renderDiff = function() { PRO.renderDiff = function() {
var scope = this, let scope = this,
layers = scope.layers, layers = scope.layers,
bridgeLayer = layers.bridge, bridgeLayer = layers.bridge,
flatLayer = layers.flat, flatLayer = layers.flat,
@ -858,18 +866,19 @@ var gs_kiri_slice = exports;
*/ */
PRO.doSolidsFill = function(spacing, angle, minArea) { PRO.doSolidsFill = function(spacing, angle, minArea) {
var minarea = minArea || 1, let minarea = minArea || 1,
scope = this, scope = this,
tops = scope.tops, tops = scope.tops,
solids = scope.solids, solids = scope.solids,
unioned = POLY.union(solids.poly); unioned = POLY.union(solids.poly),
isSLA = (spacing === undefined && angle === undefined);
if (solids.length === 0) return false; if (solids.length === 0) return false;
if (unioned.length === 0) return false; if (unioned.length === 0) return false;
var masks, let masks,
trims = [], trims = [],
inner = scope.gatherInner([]); inner = isSLA ? scope.gatherTopPolys([]) : scope.gatherInner([]);
// trim each solid to the inner bounds // trim each solid to the inner bounds
unioned.forEach(function(p) { unioned.forEach(function(p) {
@ -897,7 +906,7 @@ var gs_kiri_slice = exports;
if (top.poly.overlaps(solid)) { if (top.poly.overlaps(solid)) {
if (!solid.parent || solid.parent.area() > top.poly.area()) { if (!solid.parent || solid.parent.area() > top.poly.area()) {
if (solid.areaDeep() < minarea) { if (solid.areaDeep() < minarea) {
// console.log({cull_solid:solid,area:solid.areaDeep()}); // console.log({i:scope.index,cull_solid:solid,area:solid.areaDeep()});
return; return;
} }
solid.parent = top.poly; solid.parent = top.poly;
@ -907,10 +916,13 @@ var gs_kiri_slice = exports;
}); });
}); });
// for SLA to bypass line infill
if (isSLA) return true;
// create empty filled line array for each top // create empty filled line array for each top
tops.forEach(function(top) { tops.forEach(function(top) {
top.fill_lines = top.thin_fill || []; top.fill_lines = top.thin_fill || [];
var tofill = [], let tofill = [],
angfill = []; angfill = [];
trims.forEach(function(solid) { trims.forEach(function(solid) {
if (solid.parent === top.poly) { if (solid.parent === top.poly) {
@ -957,7 +969,7 @@ var gs_kiri_slice = exports;
}; };
PRO.renderSolidOutlines = function() { PRO.renderSolidOutlines = function() {
var layer = this.layers.solid, let layer = this.layers.solid,
trimmed = this.solids.trimmed; trimmed = this.solids.trimmed;
layer.clear(); layer.clear();
@ -980,7 +992,7 @@ var gs_kiri_slice = exports;
* @param {number} gap layers between supports and part * @param {number} gap layers between supports and part
*/ */
PRO.doSupport = function(minOffset, maxBridge, expand, minArea, pillarSize, offset, gap) { PRO.doSupport = function(minOffset, maxBridge, expand, minArea, pillarSize, offset, gap) {
var min = minArea || 0.1, let min = minArea || 0.1,
size = (pillarSize || 2), size = (pillarSize || 2),
slice = this, slice = this,
mergeDist = size * 3, // pillar merge dist mergeDist = size * 3, // pillar merge dist
@ -996,7 +1008,7 @@ var gs_kiri_slice = exports;
// skip support detection for bottom layer // skip support detection for bottom layer
if (!slice.down) return; if (!slice.down) return;
var traces = POLY.flatten(slice.gatherTraces([])), let traces = POLY.flatten(slice.gatherTraces([])),
fill = slice.gatherFillLines([]), fill = slice.gatherFillLines([]),
points = [], points = [],
down = slice.down, down = slice.down,
@ -1006,10 +1018,10 @@ var gs_kiri_slice = exports;
// check if point is supported by layer below // check if point is supported by layer below
function checkSupported(point) { function checkSupported(point) {
// skip points close to other support points // skip points close to other support points
for (var i=0; i<points.length; i++) { for (let i=0; i<points.length; i++) {
if (point.distTo2D(points[i]) < size/4) return; if (point.distTo2D(points[i]) < size/4) return;
} }
var supported = point.isInPolygonOnly(down_tops); let supported = point.isInPolygonOnly(down_tops);
if (!supported) down_traces.forEach(function(trace) { if (!supported) down_traces.forEach(function(trace) {
trace.forEachSegment(function(p1, p2) { trace.forEachSegment(function(p1, p2) {
if (point.distToLine(p1, p2) <= minOffset) return supported = true; if (point.distToLine(p1, p2) <= minOffset) return supported = true;
@ -1022,9 +1034,9 @@ var gs_kiri_slice = exports;
// todo support entire line if both endpoints unsupported // todo support entire line if both endpoints unsupported
// segment line and check if midpoints are supported // segment line and check if midpoints are supported
function checkLine(p1, p2, poly) { function checkLine(p1, p2, poly) {
var dist, i = 1; let dist, i = 1;
if ((dist = p1.distTo2D(p2)) >= maxBridge) { if ((dist = p1.distTo2D(p2)) >= maxBridge) {
var slope = p1.slopeTo(p2).factor(1/dist), let slope = p1.slopeTo(p2).factor(1/dist),
segs = Math.floor(dist / maxBridge) + 1, segs = Math.floor(dist / maxBridge) + 1,
seglen = dist / segs; seglen = dist / segs;
while (i < segs) { while (i < segs) {
@ -1039,7 +1051,7 @@ var gs_kiri_slice = exports;
trace.forEachSegment(function(p1, p2) { checkLine(p1, p2, true) }); trace.forEachSegment(function(p1, p2) { checkLine(p1, p2, true) });
}); });
var supports = []; let supports = [];
// add offset solids to supports (or fill depending) // add offset solids to supports (or fill depending)
fill.forEachPair(function(p1,p2) { checkLine(p1, p2, false) }); fill.forEachPair(function(p1,p2) { checkLine(p1, p2, false) });
@ -1048,7 +1060,7 @@ var gs_kiri_slice = exports;
// skip the rest if no points or supports // skip the rest if no points or supports
if (!(points.length || supports.length)) return; if (!(points.length || supports.length)) return;
var pillars = []; let pillars = [];
// TODO project points down instead of unioned pillars // TODO project points down instead of unioned pillars
// TODO merge point/rect into hull of next nearest (up to maxBridge/2 away) // TODO merge point/rect into hull of next nearest (up to maxBridge/2 away)
@ -1072,11 +1084,11 @@ var gs_kiri_slice = exports;
// constrain support poly to top polys // constrain support poly to top polys
supports = POLY.trimTo(supports, trimTo); supports = POLY.trimTo(supports, trimTo);
var depth = 0; let depth = 0;
while (down && supports.length > 0) { while (down && supports.length > 0) {
down.supports = down.supports || []; down.supports = down.supports || [];
var trimmed = [], let trimmed = [],
culled = []; culled = [];
// clip supports to shell offsets // clip supports to shell offsets
@ -1109,7 +1121,7 @@ var gs_kiri_slice = exports;
*/ */
PRO.doSupportFill = function(linewidth, density, minArea) { PRO.doSupportFill = function(linewidth, density, minArea) {
// return; // return;
var slice = this, let slice = this,
supports = slice.supports, supports = slice.supports,
nsB = [], nsB = [],
nsC = [], nsC = [],
@ -1135,7 +1147,7 @@ var gs_kiri_slice = exports;
if (supports) supports.forEach(function (poly) { if (supports) supports.forEach(function (poly) {
// angle based on width/height ratio // angle based on width/height ratio
var angle = (poly.bounds.width() / poly.bounds.height() > 1) ? 90 : 0, let angle = (poly.bounds.width() / poly.bounds.height() > 1) ? 90 : 0,
// calculate fill density // calculate fill density
spacing = linewidth * (1 / density), spacing = linewidth * (1 / density),
offsets = []; offsets = [];
@ -1154,7 +1166,7 @@ var gs_kiri_slice = exports;
* *
*/ */
PRO.renderSupport = function() { PRO.renderSupport = function() {
var slice = this, let slice = this,
layer = slice.layers.support, layer = slice.layers.support,
supports = slice.supports; supports = slice.supports;
@ -1176,7 +1188,7 @@ var gs_kiri_slice = exports;
* @return {Object} * @return {Object}
*/ */
PRO.findClosestPointTo = function(target) { PRO.findClosestPointTo = function(target) {
var min, find; let min, find;
this.tops.forEach(function(top) { this.tops.forEach(function(top) {
find = top.poly.findClosestPointTo(target); find = top.poly.findClosestPointTo(target);
@ -1201,15 +1213,15 @@ var gs_kiri_slice = exports;
* @returns {?Point} * @returns {?Point}
*/ */
function lineCrossesPoly(p1, p2, poly, minDist2) { function lineCrossesPoly(p1, p2, poly, minDist2) {
var ip; let ip;
if (Array.isArray(poly)) { if (Array.isArray(poly)) {
for (var i=0; i<poly.length; i++) { for (let i=0; i<poly.length; i++) {
if (ip = lineCrossesPoly(p1, p2, poly[i], minDist2)) return ip; if (ip = lineCrossesPoly(p1, p2, poly[i], minDist2)) return ip;
} }
return null; return null;
} }
if (minDist2 && p1.distToSq2D(p2) < minDist2) return null; if (minDist2 && p1.distToSq2D(p2) < minDist2) return null;
var pp = poly.points, j = 0; let pp = poly.points, j = 0;
if (pp.length < 2) return false; if (pp.length < 2) return false;
// todo may cross multiple times ... find the closest ip to p1 // todo may cross multiple times ... find the closest ip to p1
while (j < pp.length) { while (j < pp.length) {
@ -1227,7 +1239,7 @@ var gs_kiri_slice = exports;
* @returns {Point[]} * @returns {Point[]}
*/ */
function sortIntersections(out) { function sortIntersections(out) {
var ints = []; let ints = [];
out.sort(function(a,b) { out.sort(function(a,b) {
return a.dist2 - b.dist2; return a.dist2 - b.dist2;
}); });
@ -1242,14 +1254,14 @@ var gs_kiri_slice = exports;
* @returns {?Point} * @returns {?Point}
*/ */
function findIntersections(p1, p2, polys, out) { function findIntersections(p1, p2, polys, out) {
var i, j, ip; let i, j, ip;
if (Array.isArray(polys)) { if (Array.isArray(polys)) {
for (i=0; i<polys.length; i++) { for (i=0; i<polys.length; i++) {
findIntersections(p1, p2, polys[i], out); findIntersections(p1, p2, polys[i], out);
} }
return out; return out;
} }
var pp = polys.points, let pp = polys.points,
pl = pp.length; pl = pp.length;
if (pp.length < 2) return out; if (pp.length < 2) return out;
for (i=0; i < pl; i++) { for (i=0; i < pl; i++) {
@ -1274,8 +1286,7 @@ var gs_kiri_slice = exports;
*/ */
function projectSolid(slice, polys, count, up, first) { function projectSolid(slice, polys, count, up, first) {
if (!slice || slice.isSolidFill || count <= 0) return; if (!slice || slice.isSolidFill || count <= 0) return;
let clones = polys.clone(true);
var clones = polys.clone(true);
if (first) { if (first) {
clones.forEach(function(p) { clones.forEach(function(p) {
p.hintFillAngle(); p.hintFillAngle();

View file

@ -84,6 +84,7 @@ let dispatch = {
} catch (error) { } catch (error) {
send.data({error: error.toString()}); send.data({error: error.toString()});
console.log(error);
} }
}, },