From b0da5d4b1fa35a8315390aff9d6f0436d26df1b9 Mon Sep 17 00:00:00 2001 From: Stewart Allen Date: Mon, 15 Nov 2021 14:10:15 -0500 Subject: [PATCH] add palette control editing --- src/kiri/conf.js | 6 +-- src/kiri/export.js | 25 ++++++++----- src/kiri/init.js | 83 +++++++++++++++++++++++++++++++++-------- src/kiri/worker.js | 10 ++++- src/mode/fdm/export.js | 68 ++++++++++++++++++++++++++------- src/mode/fdm/prepare.js | 5 ++- web/kiri/index.css | 5 ++- web/kiri/index.html | 1 + web/kiri/lang/en.js | 17 +++++++++ 9 files changed, 174 insertions(+), 46 deletions(-) diff --git a/src/kiri/conf.js b/src/kiri/conf.js index c1f4ec07..771bd7bf 100644 --- a/src/kiri/conf.js +++ b/src/kiri/conf.js @@ -301,7 +301,9 @@ extDeselect: [], extOffsetX: 0, extOffsetY: 0 - }] + }], + // other stored info like palette3 config + extras: {} }, // process defaults FDM:Process p:{ @@ -713,8 +715,6 @@ synth: {}, // widget extra info for slicing (extruder mapping) widget: {}, - // other stored info like palette3 config - extras: {}, mode: 'FDM', id: genID(), ver: CVER diff --git a/src/kiri/export.js b/src/kiri/export.js index 6b0a00da..70ce6c9a 100644 --- a/src/kiri/export.js +++ b/src/kiri/export.js @@ -463,23 +463,28 @@ console.log/** Copyright Stewart Allen -- All Rights Reserved */ let { settings, segments } = info; let { device, bounds } = settings; let { min, max } = bounds; + let extras = device.extras || {}; + let pinfo = extras.palette || {}; + // filter pings to those occuring after all tubes combined + let pings = info.purges || []; let driveInfo = {}; let volume = {}; let length = {}; - // add 600mm of filament to the last segment for bowden drives - segments.peek().emitted += 650; + // add length push filament to the last segment + // console.log({device, pinfo}); + segments.peek().emitted += pinfo.push; for (let seg of segments) { let seginfo = driveInfo[seg.tool] = driveInfo[seg.tool] || { length: 0, volume: 0 }; seginfo.length += seg.emitted; seginfo.volume += seg.emitted * Math.PI; - volume[seg.tool+1] = seginfo.volume; + volume[seg.tool+1] = seginfo.volume + 2; // prepad 2mm length[seg.tool+1] = seginfo.length; } let totalVolume = Object.values(volume).reduce((a,v) => a+v); let meta = { version: "3.2", printerProfile: { - id: settings.extras.palette.printer, + id: pinfo.printer, name: device.deviceName || "My Printer" }, preheatTemperature: { nozzle: [0], bed: 0 }, @@ -491,7 +496,7 @@ console.log/** Copyright Stewart Allen -- All Rights Reserved */ totalVolume, inputsUsed: Object.keys(driveInfo).length, splices: segments.length, - pings: 0, + pings: pings.length, boundingBox: { min: [ min.x, min.y, min.z ], max: [ max.x, max.y, max.z ] @@ -508,9 +513,9 @@ console.log/** Copyright Stewart Allen -- All Rights Reserved */ let algokeys = {}; let algorithms = []; let defaultSplice = { - compression: 3, - cooling: 2, - heat: 4 + compression: pinfo.press, + cooling: pinfo.cool, + heat: pinfo.head }; for (let key of Object.keys(driveInfo)) { key = parseInt(key) + 1; @@ -542,14 +547,14 @@ console.log/** Copyright Stewart Allen -- All Rights Reserved */ lastDrive = r.tool; return { id: r.tool + 1, length: r.emitted.round(2) } }), - pings: [], + pings, algorithms }; let png; KIRI.work.png({}, data => { png = data.png; }); - console.log({meta,palette}); + // console.log({meta,palette}); downloadPalette.onclick = function() { KIRI.client.zip([ {name:"meta.json", data:JSON.stringify(meta,undefined,4)}, diff --git a/src/kiri/init.js b/src/kiri/init.js index 535da970..e040cc47 100644 --- a/src/kiri/init.js +++ b/src/kiri/init.js @@ -127,17 +127,6 @@ filamentSourceEditUpdate(); } - function palette3Config() { - let conf = API.conf.get().extras; - if (!conf.palette) { - conf.palette = { printer: "uuid" }; - } - let uuid = prompt('Unique Printer Identifier (can me made up)', conf.palette.printer); - if (uuid) { - conf.palette.printer = uuid; - } - } - function detailSave() { let level = UI.detail.options[UI.detail.selectedIndex]; if (level) { @@ -735,6 +724,7 @@ } function setDeviceCode(code, devicename) { + API.event.emit('device.select', {devicename, code}); try { if (typeof(code) === 'string') code = js2o(code) || {}; @@ -1010,7 +1000,10 @@ devices = devices.sort(); + API.event.emit('devices.render', devices); + UI.deviceSave.onclick = function() { + API.event.emit('device.save'); API.function.clear(); API.conf.save(); showDevices(); @@ -1671,7 +1664,16 @@ UI.extNext = UC.newButton(undefined, undefined, {icon:''}) ], {modes:FDM, class:"dev-buttons ext-buttons"}), - gcode: UC.newGroup(LANG.dv_gr_out, $('device2'), {group:"dgco", inline:true, modes:CAM_LASER}), + palette: UC.newGroup(LANG.dv_gr_pal, $('palette3'), {group:"dext", inline:true, modes:FDM}), + paletteId: UC.newInput(LANG.dv_paid_s, {title:LANG.dv_paid_l, modes:FDM, size:15}), + palettePing: UC.newInput(LANG.dv_paps_s, {title:LANG.dv_paps_l, modes:FDM, convert:UC.toInt}), + paletteFeed: UC.newInput(LANG.dv_pafe_s, {title:LANG.dv_pafe_l, modes:FDM, convert:UC.toInt}), + palettePush: UC.newInput(LANG.dv_papl_s, {title:LANG.dv_papl_l, modes:FDM, convert:UC.toInt}), + paletteHeat: UC.newInput(LANG.dv_pahe_s, {title:LANG.dv_pahe_l, modes:FDM, convert:UC.toInt}), + paletteCool: UC.newInput(LANG.dv_paco_s, {title:LANG.dv_paco_l, modes:FDM, convert:UC.toInt}), + palettePress: UC.newInput(LANG.dv_pacm_s, {title:LANG.dv_pacm_l, modes:FDM, convert:UC.toInt}), + + gcode: UC.newGroup(LANG.dv_gr_out, $('device3'), {group:"dgco", inline:true, modes:CAM_LASER}), gcodeSpace: UC.newBoolean(LANG.dv_tksp_s, onBooleanClick, {title:LANG.dv_tksp_l, modes:CAM_LASER}), gcodeStrip: UC.newBoolean(LANG.dv_strc_s, onBooleanClick, {title:LANG.dv_strc_l, modes:CAM}), gcodeFExt: UC.newInput(LANG.dv_fext_s, {title:LANG.dv_fext_l, modes:CAM_LASER, size:7, text:true}), @@ -1680,9 +1682,9 @@ gcodeMacros: UC.newRow([ (UI.gcodePre = UC.newGCode(LANG.dv_head_s, {title:LANG.dv_head_l, modes:GCODE, area:gcode})).button, (UI.gcodePost = UC.newGCode(LANG.dv_foot_s, {title:LANG.dv_foot_l, modes:GCODE, area:gcode})).button, - (UI.gcodeFan = UC.newGCode(LANG.dv_fanp_s, {title:LANG.dv_fanp_l, modes:FDM, area:gcode})).button, - (UI.gcodeTrack = UC.newGCode(LANG.dv_prog_s, {title:LANG.dv_prog_l, modes:FDM, area:gcode})).button, (UI.gcodeLayer = UC.newGCode(LANG.dv_layr_s, {title:LANG.dv_layr_l, modes:FDM, area:gcode})).button, + (UI.gcodeTrack = UC.newGCode(LANG.dv_prog_s, {title:LANG.dv_prog_l, modes:FDM, area:gcode})).button, + (UI.gcodeFan = UC.newGCode(LANG.dv_fanp_s, {title:LANG.dv_fanp_l, modes:FDM, area:gcode})).button, (UI.gcodeExt = UC.newGCode(LANG.dv_pext_s, {title:LANG.dv_pext_l, modes:FDM, area:gcode, show:isDanger})).button, (UI.gcodeInt = UC.newGCode(LANG.dv_pint_s, {title:LANG.dv_pint_l, modes:FDM, area:gcode, show:isDanger})).button, (UI.gcodeLaserOn = UC.newGCode(LANG.dv_lzon_s, {title:LANG.dv_lzon_l, modes:LASER, area:gcode})).button, @@ -2792,7 +2794,58 @@ btn.setAttribute('id', 'fs-edit'); btn.appendChild(DOC.createTextNode('edit')); fsp.insertBefore(btn, UI.filamentSource); - btn.onclick = palette3Config; + let editDone; + let edit = btn.onclick = () => { + let device = API.conf.get().device; + let extra = device.extras = device.extras || {}; + let pinfo = extra.palette; + if (!pinfo) { + pinfo = extra.palette = { + printer: Math.round(Math.random() * 0xffffffffffff).toString(16), + feed: 570, + push: 600, + heat: 0, + cool: 0, + press: 0 + }; + } + UI.paletteId.value = pinfo.printer; + UI.palettePing.value = pinfo.ping || 0; + UI.paletteFeed.value = pinfo.feed || 0; + UI.palettePush.value = pinfo.push || 0; + UI.paletteHeat.value = pinfo.heat || 0; + UI.paletteCool.value = pinfo.cool || 0; + UI.palettePress.value = pinfo.press || 0; + UI.extruder.parentNode.style.display = 'none'; + UI.palette.parentNode.style.display = 'flex'; + btn.innerText = 'done'; + btn.onclick = editDone = () => { + btn.onclick = edit; + btn.innerText = 'edit'; + UI.extruder.parentNode.style.display = 'flex'; + UI.palette.parentNode.style.display = 'none'; + // save settings + extra.palette = { + printer: UI.paletteId.value, + ping: UI.palettePing.convert(), + feed: UI.paletteFeed.convert(), + push: UI.palettePush.convert(), + heat: UI.paletteHeat.convert(), + cool: UI.paletteCool.convert(), + press: UI.palettePress.convert() + }; + }; + }; + API.event.on("device.select", () => { + UI.extruder.parentNode.style.display = 'flex'; + UI.palette.parentNode.style.display = 'none'; + btn.innerText = 'edit'; + btn.onclick = edit; + }); + API.event.on("device.save", () => { + console.log('before device save'); + editDone(); + }); } } diff --git a/src/kiri/worker.js b/src/kiri/worker.js index 7973dfc7..0c42e225 100644 --- a/src/kiri/worker.js +++ b/src/kiri/worker.js @@ -460,11 +460,17 @@ KIRI.worker = { }, function(debug) { send.data({debug}); }); - const { bounds, time, lines, bytes, distance, settings, segments } = current.print; + const { + bounds, time, lines, bytes, distance, + settings, segments, purges + } = current.print; send.done({ done: true, - output: output ? output : { bounds, time, lines, bytes, distance, settings, segments } + output: output ? output : { + bounds, time, lines, bytes, distance, + settings, segments, purges + } }); }, diff --git a/src/mode/fdm/export.js b/src/mode/fdm/export.js index 035aa2c3..62125674 100644 --- a/src/mode/fdm/export.js +++ b/src/mode/fdm/export.js @@ -20,6 +20,7 @@ thumbnails = controller.exportThumb, getRangeParameters = FDM.getRangeParameters, device = settings.device, + extras = device.extras || {}, extruders = device.extruders, extused = Object.keys(print.extruders).map(v => parseInt(v)), gcodeFan = device.gcodeFan, @@ -121,6 +122,9 @@ arcQ = [], minz = { x: Infinity, y: Infinity, z: Infinity }, isPalette = device.filamentSource === 'palette3', + paletteInfo = extras.palette || {}, + palettePingStart = paletteInfo.push + paletteInfo.feed + 200, + palettePingSpace = paletteInfo.ping || 0, segments = []; // smallish band-aid. refactor above to remove redundancy @@ -312,6 +316,26 @@ time += (retDist / retSpeed) * 60 * 2; // retraction time } + function unretract() { + if (!retracted) { + return; + } + drainQ(); + // console.log({engage:zhop}); + // when enabled, resume previous Z + if (zhop && pos.z != zpos) moveTo({z:zpos}, seekMMM, "z-hop end"); + // re-engage retracted filament + if (fwRetract) { + append('G11'); + } else { + moveTo({e:retracted}, retSpeed, `e-engage ${retracted}`); + } + retracted = 0; + // optional dwell after re-engaging filament to allow pressure to build + if (retDwell) dwell(retDwell); + time += (retDist / retSpeed) * 60 * 2; // retraction time + } + let taxis = new THREE.Vector3( 1, 0, 0 ); let tcent = new THREE.Vector2( 0, 0 ); let angle = -Math.PI / 4; @@ -471,11 +495,40 @@ moveTo({z:zpos}, seekMMM); } + // track purges for palette3 pings + let purgeOn; + let purgeOff = 0; + // iterate through layer outputs for (pidx=0; pidx= palettePingStart) { + if (out.point.purgeOn && emitted - purgeOff >= palettePingSpace) { + retract(); + append(`G4 P13000`); + unretract(); + purgeOn = emitted; + } + if (purgeOn && out.point.purgeOff) { + retract(); + append(`G4 P7000`); + unretract(); + purgeOff = emitted; + if (!print.purges) { + print.purges = []; + } + print.purges.push({ + length: purgeOn, + extrusion: purgeOff - purgeOn + }); + } + } + // emit gcode macro for changed print region if (last && out.type !== last.type) { switch (out.type) { @@ -531,20 +584,7 @@ // re-engage post-retraction before new extrusion if (out.emit && retracted) { - drainQ(); - // console.log({engage:zhop}); - // when enabled, resume previous Z - if (zhop && pos.z != zpos) moveTo({z:zpos}, seekMMM, "z-hop end"); - // re-engage retracted filament - if (fwRetract) { - append('G11'); - } else { - moveTo({e:retracted}, retSpeed, `e-engage ${retracted}`); - } - retracted = 0; - // optional dwell after re-engaging filament to allow pressure to build - if (retDwell) dwell(retDwell); - time += (retDist / retSpeed) * 60 * 2; // retraction time + unretract(); } if (lastp && out.emit) { diff --git a/src/mode/fdm/prepare.js b/src/mode/fdm/prepare.js index b7f817d3..32ac6c43 100644 --- a/src/mode/fdm/prepare.js +++ b/src/mode/fdm/prepare.js @@ -327,12 +327,15 @@ simple: true, open: false, }); - start = print.polyPrintPath((thin && !first ? rec.sparse : rec.full).clone().setZ(z), start, layer, { + let purgeOn = first || !thin; + start = print.polyPrintPath((purgeOn ? rec.full : rec.sparse).clone().setZ(z), start, layer, { tool, rate, simple: true, open: true, + onfirst: (point) => { point.purgeOn = purgeOn } }); + start.purgeOff = purgeOn; layer.last().retract = true; return start; } else { diff --git a/web/kiri/index.css b/web/kiri/index.css index 2b267147..e7c1d713 100644 --- a/web/kiri/index.css +++ b/web/kiri/index.css @@ -1379,9 +1379,12 @@ th, tr, td, label { #devices { width: 225px; } -#device1, #device2 { +#device1, #device2, #palette3 { width: 225px; } +#palette3 { + display: none; +} #dev-gcode textarea { font-family: monospace; overflow: auto; diff --git a/web/kiri/index.html b/web/kiri/index.html index 0d8c5e82..fbe0a519 100644 --- a/web/kiri/index.html +++ b/web/kiri/index.html @@ -333,6 +333,7 @@
+
diff --git a/web/kiri/lang/en.js b/web/kiri/lang/en.js index 5a4e469f..9a98420c 100644 --- a/web/kiri/lang/en.js +++ b/web/kiri/lang/en.js @@ -83,6 +83,7 @@ kiri.lang['en-us'] = { // DEVICE dialog groups dv_gr_dev: "device", dv_gr_ext: "extruder", + dv_gr_pal: "palette", dv_gr_out: "output", dv_gr_gco: "gcode macros", @@ -133,6 +134,7 @@ kiri.lang['en-us'] = { dv_strc_l: ["strip gcode comments","comments begin with ;"], dv_fext_s: "file extension", dv_fext_l: "file name extension", + dv_dwll_s: "dwell", dv_dwll_l: "gcode dwell script", dv_tool_s: "tool change", @@ -164,6 +166,21 @@ kiri.lang['en-us'] = { dv_exoy_s: "offset y", dv_exoy_l: "nozzle offset y", + dv_paid_s: "printer id", + dv_paid_l: ["unique printer identifier","may be made up"], + dv_paps_s: "ping spacing", + dv_paps_l: ["minimum filament consumption","between pings in millimeters","0 = disable pings"], + dv_pafe_s: "feed length", + dv_pafe_l: ["feeder tube length in millimeters","short=570, medium=800, long=1100"], + dv_papl_s: "push length", + dv_papl_l: ["distance between extruder gear","and nozzle tip in millimeters"], + dv_pahe_s: "heating time", + dv_pahe_l: ["offset from default"], + dv_paco_s: "cooling time", + dv_paco_l: ["offset from default"], + dv_pacm_s: "compression time", + dv_pacm_l: ["offset from default"], + // MODE mo_menu: "mode", mo_fdmp: "FDM Print",