add wire-edm origin offsets to setup a lead-in

This commit is contained in:
Stewart Allen 2024-06-11 20:18:09 -07:00
commit 3a48b319d7
6 changed files with 53 additions and 43 deletions

View file

@ -192,6 +192,7 @@ async function prepare(widgets, settings, update) {
let device = settings.device, let device = settings.device,
process = settings.process, process = settings.process,
print = self.worker.print = kiri.newPrint(settings, widgets), print = self.worker.print = kiri.newPrint(settings, widgets),
isWire = self.worker.mode === 'WEDM',
knifeOn = self.worker.mode === 'DRAG', knifeOn = self.worker.mode === 'DRAG',
knifeTipOff = process.ctOutKnifeTip, knifeTipOff = process.ctOutKnifeTip,
output = print.output = [], output = print.output = [],
@ -266,12 +267,12 @@ async function prepare(widgets, settings, update) {
} }
// find max layers (for updates) // find max layers (for updates)
widgets.forEach(widget => { for (let widget of widgets) {
totalSlices += widget.slices.length; totalSlices += widget.slices.length;
}); }
// emit objects from each slice into output array // emit objects from each slice into output array
widgets.forEach(widget => { for (let widget of widgets) {
// slice stack merging // slice stack merging
if (process.ctOutMerged) { if (process.ctOutMerged) {
let merged = []; let merged = [];
@ -324,61 +325,58 @@ async function prepare(widgets, settings, update) {
update((slices++ / totalSlices) * 0.5, "prepare"); update((slices++ / totalSlices) * 0.5, "prepare");
} }
} }
}); }
let pack = true;
// compute tile width / height // compute tile width / height
output.forEach(layerout => { for (let layerout of output) {
let min = {w:Infinity, h:Infinity}, max = {w:-Infinity, h:-Infinity}, p; let min = {w:Infinity, h:Infinity}, max = {w:-Infinity, h:-Infinity}, p;
// compute bounding box for each layer // compute bounding box for each layer
layerout.forEach(out => { for (let out of layerout) {
p = out.point; p = out.point;
out.point = p.clone(); // b/c first/last point are often shared out.point = p.clone(); // b/c first/last point are often shared
min.w = Math.min(min.w, p.x); min.w = Math.min(min.w, p.x);
max.w = Math.max(max.w, p.x); max.w = Math.max(max.w, p.x);
min.h = Math.min(min.h, p.y); min.h = Math.min(min.h, p.y);
max.h = Math.max(max.h, p.y); max.h = Math.max(max.h, p.y);
}); }
layerout.w = max.w - min.w; layerout.w = max.w - min.w;
layerout.h = max.h - min.h; layerout.h = max.h - min.h;
// shift objects to top/left of w/h bounds // shift objects to top/left of w/h box bounds
if (pack) for (let out of layerout) {
layerout.forEach(out => {
p = out.point; p = out.point;
p.x -= min.w; p.x -= min.w;
p.y -= min.h; p.y -= min.h;
}); }
}); }
// do object layout packing // do object layout packing
let i, m, e, let dw = device.bedWidth / 2,
dw = device.bedWidth / 2,
dh = device.bedDepth / 2, dh = device.bedDepth / 2,
sort = !process.ctOutLayer, sort = !process.ctOutLayer,
spacing = process.ctOutTileSpacing,
// sort objects by size when not using laser layer ordering // sort objects by size when not using laser layer ordering
c = sort ? output.sort(kiri.Sort) : output, c = sort ? output.sort() : output,
p = new kiri.Pack(dw, dh, process.ctOutTileSpacing).fit(c, !sort); p = new kiri.Pack(dw, dh, spacing, isWire).fit(c, !sort);
// test different ratios until packed // test different ratios until packed
while (!p.packed) { while (!p.packed) {
dw *= 1.1; dw *= 1.1;
dh *= 1.1; dh *= 1.1;
p = new kiri.Pack(dw, dh, process.ctOutTileSpacing).fit(c ,!sort); p = new kiri.Pack(dw, dh, spacing, isWire).fit(c ,!sort);
} }
if (true) // update packed tile with new location
for (i = 0; i < c.length; i++) { let pad = c.length > 1 ? p.pad : 0;
m = c[i]; for (let m of c) {
m.fit.x += m.w + p.pad; m.fit.x += m.w + pad;
m.fit.y += m.h + p.pad; m.fit.y += m.h + pad;
m.forEach(function(o, i) { for (let o of m) {
// because first point emitted twice (begin/end) // because first point emitted twice (begin/end)
e = o.point; let e = o.point;
e.x += p.max.w / 2 - m.fit.x; e.x += p.max.w / 2 - m.fit.x;
e.y += p.max.h / 2 - m.fit.y; e.y += p.max.h / 2 - m.fit.y;
e.z = 0; e.z = 0;
}); }
} }
return kiri.render.path(output, (progress, layer) => { return kiri.render.path(output, (progress, layer) => {

View file

@ -768,6 +768,8 @@ const conf = exports({
ctOutMerged: false, ctOutMerged: false,
ctOriginCenter: false, ctOriginCenter: false,
ctOriginBounds: true, ctOriginBounds: true,
ctOriginOffX: 0,
ctOriginOffY: -10,
outputInvertX: false, outputInvertX: false,
outputInvertY: false, outputInvertY: false,
ctOutKnifeDepth: 1, ctOutKnifeDepth: 1,

View file

@ -1970,6 +1970,9 @@ gapp.register("kiri.init", [], (root, exports) => {
separator: newBlank({ class:"set-sep", driven }), separator: newBlank({ class:"set-sep", driven }),
ctOriginBounds: newBoolean(LANG.or_bnds_s, onBooleanClick, {title:LANG.or_bnds_l}), ctOriginBounds: newBoolean(LANG.or_bnds_s, onBooleanClick, {title:LANG.or_bnds_l}),
ctOriginCenter: newBoolean(LANG.or_cntr_s, onBooleanClick, {title:LANG.or_cntr_l}), ctOriginCenter: newBoolean(LANG.or_cntr_s, onBooleanClick, {title:LANG.or_cntr_l}),
separator: newBlank({ class:"set-sep", driven, modes:WEDM }),
ctOriginOffX: newInput(LANG.or_offx_s, {title:LANG.or_offx_l, convert:toFloat, modes:WEDM}),
ctOriginOffY: newInput(LANG.or_offy_s, {title:LANG.or_offy_l, convert:toFloat, modes:WEDM}),
separator: newBlank({ class:"set-sep", driven, modes:TWONED }), separator: newBlank({ class:"set-sep", driven, modes:TWONED }),
ctOutZColor: newBoolean(LANG.ou_layo_s, onBooleanClick, {title:LANG.ou_layo_l, modes:TWONED, show:() => { return ui.ctOutMerged.checked === false }}), ctOutZColor: newBoolean(LANG.ou_layo_s, onBooleanClick, {title:LANG.ou_layo_l, modes:TWONED, show:() => { return ui.ctOutMerged.checked === false }}),
ctOutLayer: newBoolean(LANG.ou_layr_s, onBooleanClick, {title:LANG.ou_layr_l, modes:TWONED}), ctOutLayer: newBoolean(LANG.ou_layr_s, onBooleanClick, {title:LANG.ou_layr_l, modes:TWONED}),

View file

@ -12,28 +12,33 @@ gapp.register("kiri.pack", [], (root, exports) => {
const { kiri } = root; const { kiri } = root;
class Packer { class Packer {
constructor(w, h, spacing) { constructor(w, h, spacing, inv) {
this.root = { x: 0, y: 0, w: w, h: h }; this.root = { x: 0, y: 0, w: w, h: h };
this.max = { w: 0, h: 0 }; this.max = { w: 0, h: 0 };
this.packed = false; this.packed = false;
this.spacing = typeof(spacing) === 'number' ? spacing : 1; this.spacing = typeof(spacing) === 'number' ? spacing : 1;
this.inv = inv;
this.pad = this.spacing / 2; this.pad = this.spacing / 2;
} }
simple(blocks) { simple(blocks) {
let n = 0, block, x = 0, y = 0, mh = 0; let n = 0, block, x = 0, y = 0, mh = 0;
let spacing = blocks.length > 1 ? this.spacing : 0;
while (n < blocks.length) { while (n < blocks.length) {
block = blocks[n++]; block = blocks[n++];
block.fit = { x, y }; block.fit = { x, y };
this.max.w = Math.max(this.max.w, x + block.w); this.max.w = Math.max(this.max.w, x + block.w);
this.max.h = Math.max(this.max.h, y + block.h); this.max.h = Math.max(this.max.h, y + block.h);
mh = Math.max(mh, block.h); mh = Math.max(mh, block.h);
x += block.w + this.spacing; x += block.w + spacing;
if (x > this.root.w) { if (x > this.root.w) {
x = 0; x = 0;
y += mh + this.spacing; y += ((mh + spacing) * (this.inv ? -1 : 1));
mh = 0; mh = 0;
} }
if (this.inv && (y < -this.root.h)) {
return this;
}
if (y > this.root.h) { if (y > this.root.h) {
return this; return this;
} }
@ -47,10 +52,11 @@ class Packer {
return this.simple(blocks); return this.simple(blocks);
} }
let n = 0, node, block, w, h; let n = 0, node, block, w, h;
let spacing = blocks.length > 1 ? this.spacing : 0;
while (n < blocks.length) { while (n < blocks.length) {
block = blocks[n++]; block = blocks[n++];
w = block.w + this.spacing; w = block.w + spacing;
h = block.h + this.spacing; h = block.h + spacing;
if (node = this.findNode(this.root, w, h)) { if (node = this.findNode(this.root, w, h)) {
block.fit = this.splitNode(node, w, h); block.fit = this.splitNode(node, w, h);
} else { } else {
@ -81,16 +87,6 @@ class Packer {
} }
} }
// kiri.Sort = function (a, b) {
// let aa = (a.w * a.h);
// let ab = (b.w * b.h);
// if (Math.abs(aa - ab) < 1) {
// return (b.w / b.h) - (a.w / a.h);
// } else {
// return ab - aa;
// }
// };
kiri.Pack = Packer; kiri.Pack = Packer;
}); });

View file

@ -88,12 +88,19 @@ function platformUpdateOrigin(update_bounds = true) {
origin.y = device.bedDepth / 2; origin.y = device.bedDepth / 2;
} }
// CNC origin offsets
if (MODE === MODES.CAM) { if (MODE === MODES.CAM) {
origin.x += process.camOriginOffX; origin.x += process.camOriginOffX;
origin.y += process.camOriginOffY; origin.y += process.camOriginOffY;
origin.z += process.camOriginOffZ; origin.z += process.camOriginOffZ;
} }
// WireEDM origin offsets
if (MODE === MODES.WEDM) {
origin.x -= process.ctOriginOffX;
origin.y -= process.ctOriginOffY;
}
if (isIndexed) { if (isIndexed) {
origin.y = 0; origin.y = 0;
} }
@ -711,7 +718,7 @@ function platformLayout() {
let i, m, sz = space.platform.size(), let i, m, sz = space.platform.size(),
mp = [sz.x, sz.y], mp = [sz.x, sz.y],
ms = [mp[0] / 2, mp[1] / 2], ms = [mp[0] / 2, mp[1] / 2],
c = Widget.Groups.blocks().sort(moto.Sort), c = Widget.Groups.blocks().sort(),
p = new kiri.Pack(ms[0], ms[1], gap).fit(c); p = new kiri.Pack(ms[0], ms[1], gap).fit(c);
while (!p.packed) { while (!p.packed) {

View file

@ -750,6 +750,10 @@ self.kiri.lang['en-us'] = {
or_cntr_l: "origin is referenced from the center", or_cntr_l: "origin is referenced from the center",
or_topp_s: "origin top", or_topp_s: "origin top",
or_topp_l: "origin is references from the top of objects", or_topp_l: "origin is references from the top of objects",
or_offx_s: "origin offset X",
or_offx_l: "origin offset X",
or_offy_s: "origin offset Y",
or_offy_l: "origin offset Y",
// CAM ORIGIN // CAM ORIGIN
co_menu: "origin", co_menu: "origin",