add annotations necessary to allow object cancellation during print
This commit is contained in:
parent
c6355dfa61
commit
4d6b72d81d
7 changed files with 103 additions and 23 deletions
|
|
@ -14,14 +14,20 @@ const { getRangeParameters } = FDM;
|
||||||
const debug = false;
|
const debug = false;
|
||||||
|
|
||||||
FDM.export = function(print, online, ondone, ondebug) {
|
FDM.export = function(print, online, ondone, ondebug) {
|
||||||
const { settings, belty, tools, firstTool } = print;
|
const { widgets, settings, belty, tools, firstTool } = print;
|
||||||
const { bounds, controller, device, process, filter, mode } = settings;
|
const { bounds, controller, device, process, filter, mode } = settings;
|
||||||
const { extruders, fwRetract } = device;
|
const { extruders, fwRetract } = device;
|
||||||
const { bedWidth, bedDepth, bedRound, bedBelt, maxHeight } = device;
|
const { bedWidth, bedDepth, bedRound, bedBelt, maxHeight } = device;
|
||||||
const { gcodeFan, gcodeLayer, gcodeTrack, gcodePause, gcodeFeature } = device;
|
const { gcodeFan, gcodeLayer, gcodeTrack, gcodePause, gcodeFeature } = device;
|
||||||
|
|
||||||
|
let model_labels = [];
|
||||||
|
for (let widget of widgets) {
|
||||||
|
model_labels.push(widget.track.grid_id);
|
||||||
|
}
|
||||||
|
|
||||||
let layers = print.output,
|
let layers = print.output,
|
||||||
extras = device.extras || {},
|
extras = device.extras || {},
|
||||||
|
isBambu = extras.bbl,
|
||||||
{ extrudeAbs } = device,
|
{ extrudeAbs } = device,
|
||||||
{ exportThumb } = controller,
|
{ exportThumb } = controller,
|
||||||
extused = Object.keys(print.extruders).map(v => parseInt(v)),
|
extused = Object.keys(print.extruders).map(v => parseInt(v)),
|
||||||
|
|
@ -108,7 +114,8 @@ FDM.export = function(print, online, ondone, ondebug) {
|
||||||
layers: layers.length,
|
layers: layers.length,
|
||||||
progress: 0,
|
progress: 0,
|
||||||
nozzle: tool,
|
nozzle: tool,
|
||||||
tool: tool
|
tool: tool,
|
||||||
|
model_labels: model_labels.sort().join(',')
|
||||||
},
|
},
|
||||||
pidx, path, out, speedMMM, emitMM, emitPerMM, lastp, laste, dist,
|
pidx, path, out, speedMMM, emitMM, emitPerMM, lastp, laste, dist,
|
||||||
lines = 0,
|
lines = 0,
|
||||||
|
|
@ -588,11 +595,36 @@ FDM.export = function(print, online, ondone, ondebug) {
|
||||||
moveTo({z:zpos}, seekMMM);
|
moveTo({z:zpos}, seekMMM);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function encodeOffset(index) {
|
||||||
|
let bytes = new Uint8Array(8);
|
||||||
|
let byteIndex = Math.floor(index / 8);
|
||||||
|
let bitPosition = index % 8;
|
||||||
|
bytes[byteIndex] |= (1 << bitPosition);
|
||||||
|
return btoa(String.fromCharCode(...bytes));
|
||||||
|
}
|
||||||
|
|
||||||
|
let cwidget;
|
||||||
// iterate through layer outputs
|
// iterate through layer outputs
|
||||||
for (pidx=0; pidx<path.length; pidx++) {
|
for (pidx=0; pidx<path.length; pidx++) {
|
||||||
out = path[pidx];
|
out = path[pidx];
|
||||||
speedMMM = (out.speed || process.outputFeedrate) * 60; // range
|
speedMMM = (out.speed || process.outputFeedrate) * 60; // range
|
||||||
|
|
||||||
|
// hint to controller that we're working on a specific object
|
||||||
|
// so that gcode between start/stop comments can be cancelled
|
||||||
|
if (out.widget !== cwidget) {
|
||||||
|
if (cwidget) {
|
||||||
|
append(`; end object id: ${cwidget.track.grid_id}`);
|
||||||
|
isBambu && append('M625');
|
||||||
|
}
|
||||||
|
if (out.widget) {
|
||||||
|
let off = model_labels.indexOf(out.widget.track.grid_id);
|
||||||
|
let b64 = encodeOffset(off);
|
||||||
|
append(`; start object id: ${out.widget.track.grid_id}`);
|
||||||
|
isBambu && append(`M624 ${b64}`);
|
||||||
|
}
|
||||||
|
cwidget = out.widget;
|
||||||
|
}
|
||||||
|
|
||||||
// emit comment on output type chage
|
// emit comment on output type chage
|
||||||
if (last && out.type !== last.type) {
|
if (last && out.type !== last.type) {
|
||||||
lastType = subst.feature = out.type;
|
lastType = subst.feature = out.type;
|
||||||
|
|
@ -791,6 +823,11 @@ FDM.export = function(print, online, ondone, ondebug) {
|
||||||
laste = out.emit;
|
laste = out.emit;
|
||||||
}
|
}
|
||||||
layer++;
|
layer++;
|
||||||
|
if (cwidget) {
|
||||||
|
append(`; end object id: ${cwidget.track.grid_id}`);
|
||||||
|
isBambu && append('M625');
|
||||||
|
cwidget = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
// end open loop when detected
|
// end open loop when detected
|
||||||
while (endloop-- > 0) {
|
while (endloop-- > 0) {
|
||||||
|
|
@ -949,6 +986,7 @@ FDM.export = function(print, online, ondone, ondebug) {
|
||||||
print.lines = lines;
|
print.lines = lines;
|
||||||
print.bytes = bytes + lines - 1;
|
print.bytes = bytes + lines - 1;
|
||||||
print.time = time;
|
print.time = time;
|
||||||
|
print.labels = model_labels;
|
||||||
|
|
||||||
if (debug) {
|
if (debug) {
|
||||||
console.log('segments', segments);
|
console.log('segments', segments);
|
||||||
|
|
|
||||||
|
|
@ -549,6 +549,7 @@ FDM.prepare = async function(widgets, settings, update) {
|
||||||
let beltStart = slice.belt && slice.belt.touch;// && (widgets.length === 1);
|
let beltStart = slice.belt && slice.belt.touch;// && (widgets.length === 1);
|
||||||
// output seek to start point between mesh slices if previous data
|
// output seek to start point between mesh slices if previous data
|
||||||
print.setType('layer');
|
print.setType('layer');
|
||||||
|
print.setWidget(lastWidget);
|
||||||
printPoint = slicePrintPath(
|
printPoint = slicePrintPath(
|
||||||
print,
|
print,
|
||||||
slice,
|
slice,
|
||||||
|
|
@ -579,6 +580,7 @@ FDM.prepare = async function(widgets, settings, update) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
print.setWidget(null);
|
||||||
|
|
||||||
lastOut = slice;
|
lastOut = slice;
|
||||||
lastExt = lastOut.extruder;
|
lastExt = lastOut.extruder;
|
||||||
|
|
|
||||||
|
|
@ -63,6 +63,19 @@ FDM.sliceAll = function(settings, onupdate) {
|
||||||
.sort((a,b) => {
|
.sort((a,b) => {
|
||||||
return a.slices[0].z - b.slices[0].z
|
return a.slices[0].z - b.slices[0].z
|
||||||
});
|
});
|
||||||
|
// assign grid_id which can be embedded in gcode and
|
||||||
|
// used by the controller to cancel objects during print
|
||||||
|
let { bounds } = settings;
|
||||||
|
for (let widget of widgets) {
|
||||||
|
let { pos, box } = widget.track;
|
||||||
|
// calculate top/left coordinate for widget
|
||||||
|
// relative to bounding box for all widgets
|
||||||
|
let tl = {
|
||||||
|
x: Math.round((pos.x - box.w/2 - bounds.min.x) / 10) + 1,
|
||||||
|
y: Math.round((pos.y - box.h/2 - bounds.min.y) / 10) + 1
|
||||||
|
};
|
||||||
|
widget.track.grid_id = tl.x * 100 + tl.y;
|
||||||
|
}
|
||||||
// count extruders used
|
// count extruders used
|
||||||
let ext = [];
|
let ext = [];
|
||||||
for (let w of widgets) {
|
for (let w of widgets) {
|
||||||
|
|
|
||||||
|
|
@ -494,15 +494,29 @@ kiri.worker = {
|
||||||
send.data({debug});
|
send.data({debug});
|
||||||
});
|
});
|
||||||
const {
|
const {
|
||||||
bounds, time, lines, bytes, distance,
|
bounds,
|
||||||
settings, segments, purges
|
time,
|
||||||
|
lines,
|
||||||
|
bytes,
|
||||||
|
distance,
|
||||||
|
settings,
|
||||||
|
segments,
|
||||||
|
purges,
|
||||||
|
labels
|
||||||
} = current.print;
|
} = current.print;
|
||||||
|
|
||||||
send.done({
|
send.done({
|
||||||
done: true,
|
done: true,
|
||||||
output: output ? output : {
|
output: output ? output : {
|
||||||
bounds, time, lines, bytes, distance,
|
bounds,
|
||||||
settings, segments, purges
|
time,
|
||||||
|
lines,
|
||||||
|
bytes,
|
||||||
|
distance,
|
||||||
|
settings,
|
||||||
|
segments,
|
||||||
|
purges,
|
||||||
|
labels
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -529,7 +529,11 @@ function exportGCodeDialog(gcode, sections, info, names) {
|
||||||
api.bambu.prep_export(gen3mf, gcode, info, settings);
|
api.bambu.prep_export(gen3mf, gcode, info, settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
function gen3mf(then, ptype = 'unknown') {
|
// let wids = api.widgets.all();
|
||||||
|
// let bnds = settings.bounds;
|
||||||
|
// console.log({ wids, bnds });
|
||||||
|
|
||||||
|
function gen3mf(then, ptype = 'unknown', ams = [0]) {
|
||||||
let now = new Date();
|
let now = new Date();
|
||||||
let ymd = [
|
let ymd = [
|
||||||
now.getFullYear(),
|
now.getFullYear(),
|
||||||
|
|
@ -582,28 +586,28 @@ function exportGCodeDialog(gcode, sections, info, names) {
|
||||||
' <Relationship Target="/Metadata/plate_1.gcode" Id="rel-1" Type="http://schemas.microsoft.com/3dmanufacturing/2013/01/gcode"/>',
|
' <Relationship Target="/Metadata/plate_1.gcode" Id="rel-1" Type="http://schemas.microsoft.com/3dmanufacturing/2013/01/gcode"/>',
|
||||||
'</Relationships>'
|
'</Relationships>'
|
||||||
].join('\n')
|
].join('\n')
|
||||||
},{
|
// },{
|
||||||
// name: `Metadata/plate_1.json`,
|
// name: `Metadata/plate_1.json`,
|
||||||
// data: JSON.toString({
|
// data: JSON.stringify({
|
||||||
// "bbox_all": [ 115.199992, 115.199992, 140.799992, 140.799992 ],
|
// "bbox_all": [ 100, 100, 200, 200 ],
|
||||||
// "bbox_objects": [
|
// "bbox_objects": (info.labels || []).map(label => {
|
||||||
// {
|
// return {
|
||||||
// "area": 655.3599853515625,
|
// area: 600,
|
||||||
// "bbox": [ 115.199992, 115.199992, 140.799992, 140.799992 ],
|
// bbox: [ 100, 100, 200, 200 ],
|
||||||
// "id": 42,
|
// id: label,
|
||||||
// "layer_height": 0.25,
|
// layer_height: 0.2,
|
||||||
// "name": "Cube"
|
// name: "Object"
|
||||||
// }
|
// }
|
||||||
// ],
|
// }),
|
||||||
// "bed_type": "textured_plate",
|
// "bed_type": "textured_plate",
|
||||||
// "filament_colors": ["#FFFFFF"],
|
// "filament_colors": ["#FFFFFF"],
|
||||||
// "filament_ids": [0],
|
// "filament_ids": ams,
|
||||||
// "first_extruder": 0,
|
// "first_extruder": ams[0],
|
||||||
// "is_seq_print": false,
|
// "is_seq_print": false,
|
||||||
// "nozzle_diameter": 0.6,
|
// "nozzle_diameter": 0.6,
|
||||||
// "version": 2
|
// "version": 2
|
||||||
// })
|
// })
|
||||||
// },{
|
},{
|
||||||
name: `Metadata/model_settings.config`,
|
name: `Metadata/model_settings.config`,
|
||||||
data: [
|
data: [
|
||||||
'<?xml version="1.0" encoding="UTF-8"?>',
|
'<?xml version="1.0" encoding="UTF-8"?>',
|
||||||
|
|
@ -639,12 +643,13 @@ function exportGCodeDialog(gcode, sections, info, names) {
|
||||||
' <metadata key="outside" value="false"/>',
|
' <metadata key="outside" value="false"/>',
|
||||||
' <metadata key="support_used" value="false"/>',
|
' <metadata key="support_used" value="false"/>',
|
||||||
' <metadata key="label_object_enabled" value="false"/>',
|
' <metadata key="label_object_enabled" value="false"/>',
|
||||||
// ' <object identify_id="560" name="Cube" skipped="false" />',
|
(info.labels || []).map(label =>
|
||||||
|
` <object identify_id="${label}" name="Object" skipped="false" />`),
|
||||||
// ' <filament id="1" tray_info_idx="GFL96" type="PLA" color="#FFFFFF" used_m="0.17" used_g="0.50" />',
|
// ' <filament id="1" tray_info_idx="GFL96" type="PLA" color="#FFFFFF" used_m="0.17" used_g="0.50" />',
|
||||||
// ' <warning msg="bed_temperature_too_high_than_filament" level="1" error_code ="1000C001" />',
|
// ' <warning msg="bed_temperature_too_high_than_filament" level="1" error_code ="1000C001" />',
|
||||||
' </plate>',
|
' </plate>',
|
||||||
'</config>'
|
'</config>'
|
||||||
].join('\n')
|
].filter(v => v).flat().join('\n')
|
||||||
},{
|
},{
|
||||||
name: `Metadata/project_settings.config`,
|
name: `Metadata/project_settings.config`,
|
||||||
data: JSON.stringify({},undefined,4)
|
data: JSON.stringify({},undefined,4)
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,12 @@ class Print {
|
||||||
this.nextType = type;
|
this.nextType = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// allows for gcode object id annotations enabling
|
||||||
|
// discrete object cancellation during print (bambu)
|
||||||
|
setWidget(widget) {
|
||||||
|
this.widget = widget;
|
||||||
|
}
|
||||||
|
|
||||||
addOutput(array, point, emit, speed, tool, type) {
|
addOutput(array, point, emit, speed, tool, type) {
|
||||||
let { lastPoint, lastEmit, lastOut } = this;
|
let { lastPoint, lastEmit, lastOut } = this;
|
||||||
// drop duplicates (usually intruced by FDM bisections)
|
// drop duplicates (usually intruced by FDM bisections)
|
||||||
|
|
@ -52,6 +58,7 @@ class Print {
|
||||||
if (tool !== undefined) {
|
if (tool !== undefined) {
|
||||||
this.tools[tool] = true;
|
this.tools[tool] = true;
|
||||||
}
|
}
|
||||||
|
lastOut.widget = this.widget;
|
||||||
array.push(lastOut);
|
array.push(lastOut);
|
||||||
this.nextType = undefined;
|
this.nextType = undefined;
|
||||||
return lastOut;
|
return lastOut;
|
||||||
|
|
|
||||||
|
|
@ -212,6 +212,7 @@ details[open] summary::after {
|
||||||
transform: rotate(90deg);
|
transform: rotate(90deg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* for bambu mgr dialog */
|
||||||
.video {
|
.video {
|
||||||
border: 1px solid #888;
|
border: 1px solid #888;
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue