fix cam trace dup selection, add cam trace merge option, add more bambu print options
This commit is contained in:
parent
3e27f195d0
commit
2e1114510a
12 changed files with 120 additions and 58 deletions
|
|
@ -37,7 +37,8 @@ self.kiri.load(api => {
|
|||
let { serial, message, error } = data;
|
||||
if (error) {
|
||||
console.log({ serial, error });
|
||||
printer_status(`error: ${error}`);
|
||||
api.alerts.show(`Bambu Error: ${error}`, 3);
|
||||
// printer_status(`error: ${error}`);
|
||||
} else if (serial) {
|
||||
let rec = status[serial] = deepMerge(status[serial] || {}, message);
|
||||
if (selected?.rec.serial === serial) {
|
||||
|
|
@ -176,9 +177,14 @@ self.kiri.load(api => {
|
|||
$('bbl_bed_target').value = bed_target_temper?.toFixed(1) ?? '';
|
||||
if (files) {
|
||||
h.bind($('bbl_files'), files.map(file => {
|
||||
let name = file.name
|
||||
.toLowerCase()
|
||||
.replace('.gcode','')
|
||||
.replace('.3mf','');
|
||||
return h.option({
|
||||
_: file.name || file,
|
||||
style: "max-width: 20em"
|
||||
_: name,
|
||||
style: "max-width: 20em",
|
||||
value:`${file.path}${file.name}`
|
||||
});
|
||||
}));
|
||||
rec.files = undefined;
|
||||
|
|
@ -196,7 +202,7 @@ self.kiri.load(api => {
|
|||
$('bbl_status').value = msg;
|
||||
}
|
||||
|
||||
function render_list() {
|
||||
function render_list(to) {
|
||||
let list = Object.keys(printers).map(name => {
|
||||
return h.option({ _: name, value: name })
|
||||
});
|
||||
|
|
@ -204,7 +210,7 @@ self.kiri.load(api => {
|
|||
h.option({ _: '', value: '' }),
|
||||
...list
|
||||
]
|
||||
h.bind(select, list);
|
||||
h.bind(to || select, list);
|
||||
}
|
||||
|
||||
function monitor_start(rec) {
|
||||
|
|
@ -421,26 +427,35 @@ self.kiri.load(api => {
|
|||
}
|
||||
});
|
||||
|
||||
function sendok(params = {}) {
|
||||
host = password = serial = amsmap = undefined;
|
||||
const { settings } = params;
|
||||
const ams = settings.device?.gcodePre.filter(line => line.indexOf(defams) === 0)[0];
|
||||
if (ams) {
|
||||
try {
|
||||
amsmap = ams.substring(defams.length).trim().replaceAll(' ','');
|
||||
} catch (e) {
|
||||
console.log({ invalid_ams_map: ams });
|
||||
}
|
||||
function prep_export(gen3mf, gcode, info, settings) {
|
||||
if (!settings.device.extras?.bbl) {
|
||||
$('bambu-output').style.display = 'none';
|
||||
return;
|
||||
}
|
||||
const feature = settings.device?.gcodePre.filter(line => line.indexOf(defhost) === 0)[0];
|
||||
if (feature) {
|
||||
[ host, password, serial ] = feature.substring(defhost.length).split(' ').map(v => v.trim());
|
||||
console.log('BAMBU', { host , password, serial });
|
||||
if (host && password) {
|
||||
return true;
|
||||
}
|
||||
printers = settings.device.extras.bbl;
|
||||
let devlist = $('print-bambu-device');
|
||||
render_list(devlist);
|
||||
$('bambu-output').style.display = 'flex';
|
||||
$('print-bambu').onclick = function() {
|
||||
gen3mf(zip => send(`${$('print-filename').value}.3mf`, zip));
|
||||
}
|
||||
return false;
|
||||
devlist.onchange = () => {
|
||||
let info = printers[devlist.value];
|
||||
console.log({ selected: devlist.value, info });
|
||||
host = info.host;
|
||||
serial = info.serial;
|
||||
password = info.code;
|
||||
$('print-bambu').disabled = (host && serial && password) ? false : true;
|
||||
const ams = settings.device?.gcodePre.filter(line => line.indexOf(defams) === 0)[0];
|
||||
if (ams) {
|
||||
try {
|
||||
amsmap = ams.substring(defams.length).trim().replaceAll(' ','');
|
||||
} catch (e) {
|
||||
console.log({ invalid_ams_map: ams });
|
||||
}
|
||||
}
|
||||
console.log({ bambu: host, serial, amsmap });
|
||||
};
|
||||
}
|
||||
|
||||
function send(filename, gcode) {
|
||||
|
|
@ -479,5 +494,5 @@ self.kiri.load(api => {
|
|||
|
||||
setInterval(monitor_keepalive, 5000);
|
||||
|
||||
api.bambu = { send, sendok, amsmap };
|
||||
api.bambu = { send, amsmap, prep_export };
|
||||
});
|
||||
|
|
|
|||
|
|
@ -145,8 +145,16 @@ module.exports = async (server) => {
|
|||
async function ftp_list(args = {}) {
|
||||
const client = await ftp_open(args);
|
||||
const list = [];
|
||||
try { list.push(...(await client.list())) } catch (e) { }
|
||||
try { list.push(...(await client.list("/cache"))) } catch (e) { }
|
||||
try {
|
||||
let files = await client.list();
|
||||
files.forEach(file => file.path = "/");
|
||||
list.push(...files);
|
||||
} catch (e) { }
|
||||
try {
|
||||
let files = await client.list("/cache");
|
||||
files.forEach(file => file.path = "/cache/");
|
||||
list.push(...files);
|
||||
} catch (e) { }
|
||||
client.close();
|
||||
return list;
|
||||
}
|
||||
|
|
@ -193,7 +201,8 @@ module.exports = async (server) => {
|
|||
const { host, password, filename, serial, ams } = query;
|
||||
const ams_mapping = ams ? ams.split(',').map(v => parseInt(v)) : undefined;
|
||||
const mqtt_conn = serial ? get_mqtt(host, password, serial, message => {
|
||||
util.log('mqtt_recv', JSON.parse(message.toString()));
|
||||
util.log('mqtt_recv', message);
|
||||
// util.log('mqtt_recv', JSON.parse(message.toString()));
|
||||
}) : undefined;
|
||||
ftp_send({ host, password, filename, data })
|
||||
.then(() => {
|
||||
|
|
@ -271,6 +280,7 @@ module.exports = async (server) => {
|
|||
.filter(file => file.name.toLowerCase().endsWith(".3mf"))
|
||||
.map(file => {
|
||||
return {
|
||||
path: file.path,
|
||||
name: file.name,
|
||||
size: file.size,
|
||||
date: file.rawModifiedAt
|
||||
|
|
|
|||
|
|
@ -2037,7 +2037,7 @@ class Polygon {
|
|||
tree = new PolyTree(),
|
||||
sp1 = this.toClipper(),
|
||||
sp2 = poly.toClipper(),
|
||||
minarea = min >= 0 ? min : 0.1;
|
||||
minarea = min ?? 0.1;
|
||||
|
||||
clip.AddPaths(sp1, PathSubject, true);
|
||||
clip.AddPaths(sp2, PathClip, true);
|
||||
|
|
|
|||
|
|
@ -431,7 +431,7 @@ function subtract(setA, setB, outA, outB, z, minArea, opt = {}) {
|
|||
let lpre = length(polys);
|
||||
|
||||
if (opt.wasm && geo.wasm) {
|
||||
let min = minarea || 0.01;
|
||||
let min = minarea ?? 0.01;
|
||||
// let deepLength = polys.map(p => p.deepLength).reduce((a,v) => a+v);
|
||||
// if (deepLength < 15000)
|
||||
try {
|
||||
|
|
@ -632,7 +632,7 @@ function offset(polys, dist, opts = {}) {
|
|||
let coff = new ClipperOffset(opts.miter, opts.arc),
|
||||
tree = new PolyTree();
|
||||
|
||||
// setup offset
|
||||
// setup offset
|
||||
for (let poly of polys) {
|
||||
// convert to clipper format
|
||||
poly = poly.toClipper();
|
||||
|
|
|
|||
|
|
@ -1467,6 +1467,7 @@ CAM.init = function(kiri, api) {
|
|||
offover: 'camTraceOffOver',
|
||||
dogbone: 'camTraceDogbone',
|
||||
revbone: 'camTraceDogbone',
|
||||
merge: 'camTraceMerge',
|
||||
select: 'camTraceMode'
|
||||
}).inputs = {
|
||||
tool: UC.newSelect(LANG.cc_tool, {}, "tools"),
|
||||
|
|
@ -1483,6 +1484,7 @@ CAM.init = function(kiri, api) {
|
|||
thru: UC.newInput(LANG.cc_thru_s, {title:LANG.cc_thru_l, convert:UC.toFloat, units:true}),
|
||||
offover: UC.newInput(LANG.cc_offd_s, {title:LANG.cc_offd_l, convert:UC.toFloat, units:true, show:() => poppedRec.offset !== "none"}),
|
||||
sep: UC.newBlank({class:"pop-sep", modes:MCAM, xshow:zDogSep}),
|
||||
merge: UC.newBoolean(LANG.co_merg_s, undefined, {title:LANG.co_merg_l}),
|
||||
bottom: UC.newBoolean(LANG.cf_botm_s, undefined, {title:LANG.cf_botm_l, show:(op,conf) => conf.process.camZBottom}),
|
||||
dogbone: UC.newBoolean(LANG.co_dogb_s, undefined, {title:LANG.co_dogb_l, show:canDogBones}),
|
||||
revbone: UC.newBoolean(LANG.co_dogr_s, undefined, {title:LANG.co_dogr_l, show:canDogBonesRev}),
|
||||
|
|
|
|||
|
|
@ -69,6 +69,7 @@ kiri.load(api => {
|
|||
kiri.client.send("cam_traces", { settings, single }, output => {
|
||||
const ids = [];
|
||||
kiri.codec.decode(output).forEach(rec => {
|
||||
console.log({ rec });
|
||||
ids.push(rec.id);
|
||||
widgets[rec.id].traces = rec.traces;
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1090,6 +1090,7 @@ class OpTrace extends CamOp {
|
|||
poly2polyEmit(polys, newPoint(0,0,0), (poly, index, count, spoint) => {
|
||||
routed.push(poly);
|
||||
});
|
||||
let output = [];
|
||||
for (let poly of POLY.nest(routed)) {
|
||||
let offdist = offset !== 'none' ? offover : 0;
|
||||
if (!offdist)
|
||||
|
|
@ -1116,15 +1117,24 @@ class OpTrace extends CamOp {
|
|||
zto -= zThru;
|
||||
}
|
||||
for (let z of base.util.lerp(zTop, zto, down)) {
|
||||
followZ(pi.clone().setZ(z));
|
||||
output.push(pi.clone().setZ(z));
|
||||
}
|
||||
} else {
|
||||
if (thru) {
|
||||
pi.setZ(pi.getZ() - thru);
|
||||
}
|
||||
followZ(pi);
|
||||
output.push(pi);
|
||||
}
|
||||
}
|
||||
// merge overlapping output to prevent overcuts
|
||||
if (op.merge) {
|
||||
let nest = POLY.nest(output);
|
||||
let union = POLY.union(nest, 0, true);
|
||||
output = POLY.flatten(union, [], true);
|
||||
}
|
||||
for (let poly of output) {
|
||||
followZ(poly);
|
||||
}
|
||||
break;
|
||||
case "clear":
|
||||
const zbo = widget.track.top - widget.track.box.d;
|
||||
|
|
|
|||
|
|
@ -365,7 +365,7 @@ CAM.traces = async function(settings, widget, single) {
|
|||
let trace = traces[i];
|
||||
let dz = Math.abs(z - trace.getZ());
|
||||
// only compare polys farther apart in Z
|
||||
if (dz < 0.01) {
|
||||
if (dz > 0.01) {
|
||||
continue;
|
||||
}
|
||||
// do not add duplicates
|
||||
|
|
|
|||
|
|
@ -477,8 +477,7 @@ function exportGCodeDialog(gcode, sections, info, names) {
|
|||
$('code-preview-head').style.display = preview ? '' : 'none';
|
||||
$('code-preview').style.display = preview ? '' : 'none';
|
||||
$('print-download').onclick = download;
|
||||
$('print-filament-head').style.display = fdm ? '' : 'none';
|
||||
$('print-filament-info').style.display = fdm ? '' : 'none';
|
||||
$('print-filament').style.display = fdm ? '' : 'none';
|
||||
$('print-filename').value = filename;
|
||||
$('print-filesize').value = util.comma(info.bytes);
|
||||
$('print-filament').value = Math.round(info.distance);
|
||||
|
|
@ -523,10 +522,10 @@ function exportGCodeDialog(gcode, sections, info, names) {
|
|||
download3MF.onclick = function() {
|
||||
gen3mf(zip => api.util.download(zip, `${$('print-filename').value}.3mf`));
|
||||
};
|
||||
let downloadBambu = $('print-bambu');
|
||||
downloadBambu.style.display = api.bambu && api.bambu.sendok({ gcode, info, settings }) ? 'flex' : 'none';
|
||||
downloadBambu.onclick = function() {
|
||||
gen3mf(zip => api.bambu.send(`${$('print-filename').value}.3mf`, zip));
|
||||
|
||||
// present bambu print options when selected device is bambu
|
||||
if (api.bambu) {
|
||||
api.bambu.prep_export(gen3mf, gcode, info, settings);
|
||||
}
|
||||
|
||||
function gen3mf(then) {
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ button {
|
|||
cursor: pointer;
|
||||
text-transform: capitalize;
|
||||
}
|
||||
button:hover {
|
||||
button:not([disabled]):hover {
|
||||
background-color: var(--main-color);
|
||||
color: white;
|
||||
}
|
||||
|
|
@ -118,6 +118,9 @@ button[load] {
|
|||
button[del] {
|
||||
margin-left: 5px;
|
||||
}
|
||||
button[disabled] {
|
||||
color: #999;
|
||||
}
|
||||
input {
|
||||
background-color: #f8f8ff;
|
||||
margin-bottom: 1px;
|
||||
|
|
@ -225,6 +228,9 @@ details[open] > summary::after {
|
|||
}
|
||||
|
||||
/** dark conversion */
|
||||
.dark button[disabled] {
|
||||
color: #888;
|
||||
}
|
||||
.dark input[disabled] {
|
||||
border-color: #666;
|
||||
background-color: #444;
|
||||
|
|
@ -250,7 +256,7 @@ details[open] > summary::after {
|
|||
background-color: #555;
|
||||
border: 1px solid #777;
|
||||
}
|
||||
button:hover {
|
||||
.dark button:not([disabled]):hover {
|
||||
background-color: var(--blue-2);
|
||||
color: black;
|
||||
}
|
||||
|
|
@ -670,6 +676,9 @@ button:hover {
|
|||
.basis-50 {
|
||||
flex-basis: 50%;
|
||||
}
|
||||
.grow0 {
|
||||
flex-grow: 0 !important;
|
||||
}
|
||||
.grow {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
|
@ -1633,7 +1642,7 @@ button:hover {
|
|||
background-color: rgba(255,255,255,0.5);
|
||||
border: 1px solid #bbb;
|
||||
border-radius: 3px;
|
||||
padding: 20px 10px 10px 10px;
|
||||
padding: 12px 10px 10px 10px;
|
||||
}
|
||||
.mod-print .box select {
|
||||
min-width: 10em;
|
||||
|
|
@ -1695,9 +1704,10 @@ button:hover {
|
|||
display: none;
|
||||
}
|
||||
#code-preview-textarea {
|
||||
width: 40em;
|
||||
height: 12em;
|
||||
font-size: smaller;
|
||||
min-width: 50em;
|
||||
width: 100%;
|
||||
height: 7em;
|
||||
font-size: x-small;
|
||||
font-family: Courier,monospace;
|
||||
white-space: nowrap;
|
||||
resize: none;
|
||||
|
|
|
|||
|
|
@ -583,19 +583,25 @@
|
|||
<div id="mod-local" class="mdialog f-col"></div>
|
||||
<!-- export dialogs -->
|
||||
<div id="mod-x-any" class="mod-print mdialog f-col">
|
||||
<div class="header"><label>export</label></div>
|
||||
<div id="print-info" class="f-col box">
|
||||
<div><label>file name</label><input id="print-filename" size="20" spellcheck="false" /></div>
|
||||
<div><label>file size (bytes)</label><input id="print-filesize" size="12" disabled="true" /></div>
|
||||
<div><label>time estimate (h:m:s)</label><input id="output-time" size="12" disabled="true" /></div>
|
||||
<div class="f-row gap4">
|
||||
<div class="f-col grow">
|
||||
<div class="header"><label>job</label></div>
|
||||
<div id="print-info" class="f-col box">
|
||||
<div><label>file name</label><input id="print-filename" size="20" spellcheck="false" /></div>
|
||||
<div><label>file size (bytes)</label><input id="print-filesize" size="12" disabled="true" /></div>
|
||||
<div><label>time estimate (h:m:s)</label><input id="output-time" size="12" disabled="true" /></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="print-filament" class="f-col">
|
||||
<div class="header"><label>material</label></div>
|
||||
<div class="f-col box">
|
||||
<div><label>filament density (g/cm^3)</label><input id="print-density" size="12" value="1.25" /></div>
|
||||
<div><label>filament used (mm)</label><input id="print-filament" size="12" disabled="true" /></div>
|
||||
<div><label>printed weight (g)</label><input id="print-weight" size="12" disabled="true" /></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="print-filament-head" class="header"><label>filament</label></div>
|
||||
<div id="print-filament-info" class="f-col box">
|
||||
<div><label>filament density (g/cm^3)</label><input id="print-density" size="12" value="1.25" /></div>
|
||||
<div><label>filament used (mm)</label><input id="print-filament" size="12" disabled="true" /></div>
|
||||
<div><label>printed weight (g)</label><input id="print-weight" size="12" disabled="true" /></div>
|
||||
</div>
|
||||
<div id="code-preview-head" class="header"><label>preview</label></div>
|
||||
<div id="code-preview-head" class="header"><label>gcode preview</label></div>
|
||||
<div id="code-preview" class="f-col box">
|
||||
<div><textarea id="code-preview-textarea"></textarea></div>
|
||||
</div>
|
||||
|
|
@ -605,7 +611,14 @@
|
|||
<button id="print-palette" class="grow">palette</button>
|
||||
<button id="print-zip" class="grow">zip</button>
|
||||
<button id="print-3mf" class="grow">3mf</button>
|
||||
<button id="print-bambu" class="grow">bambu</button>
|
||||
</div>
|
||||
<div id="bambu-output" class="f-col">
|
||||
<div class="header"><label>send to bambu</label></div>
|
||||
<div class="f-row box gap4 a-center">
|
||||
<label class="grow0">printer</label>
|
||||
<select id="print-bambu-device"></select>
|
||||
<button id="print-bambu" class="grow" disabled>send job</button>
|
||||
</div>
|
||||
</div>
|
||||
<div id="send-to-octohead" class="header"><label>octoprint</label></div>
|
||||
<div id="send-to-octoprint" class="f-col box">
|
||||
|
|
|
|||
|
|
@ -521,6 +521,8 @@ self.kiri.lang['en-us'] = {
|
|||
|
||||
// CNC OUTLINE
|
||||
co_menu: "outline",
|
||||
co_merg_s: "merge overlap",
|
||||
co_merg_l: ["merge overlapping lines to prevent overcutting into adjacent solids"],
|
||||
co_dogb_s: "dogbones",
|
||||
co_dogb_l: ["insert dogbone cuts","into inside corners"],
|
||||
co_dogr_s: "reverse bones",
|
||||
|
|
|
|||
Loading…
Reference in a new issue