migrate more settings, fix index/ranges in slice post
This commit is contained in:
parent
290b6b7ca1
commit
e0ca12fe58
6 changed files with 266 additions and 243 deletions
|
|
@ -207,7 +207,7 @@ async function slice(points, options = {}) {
|
||||||
async function sliceBuckets() {
|
async function sliceBuckets() {
|
||||||
let output = [];
|
let output = [];
|
||||||
let count = 0;
|
let count = 0;
|
||||||
let opt = { ...options, zMin, zMax };
|
let opt = { ...options, zMin, zMax, zIndexes };
|
||||||
let ps = [];
|
let ps = [];
|
||||||
|
|
||||||
for (let i = 0, l = buckets.length; i < l; i++) {
|
for (let i = 0, l = buckets.length; i < l; i++) {
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@
|
||||||
*/
|
*/
|
||||||
base.slicePost.FDM = function(data, options) {
|
base.slicePost.FDM = function(data, options) {
|
||||||
const { z, lines, groups } = data;
|
const { z, lines, groups } = data;
|
||||||
const { useAssembly, post_args, index } = options;
|
const { useAssembly, post_args, zIndexes } = options;
|
||||||
const { process, isSynth, isDanger, vaseMode } = post_args;
|
const { process, isSynth, isDanger, vaseMode } = post_args;
|
||||||
const { shellOffset, fillOffset, clipOffset } = post_args;
|
const { shellOffset, fillOffset, clipOffset } = post_args;
|
||||||
const tops = POLY.nest(groups);
|
const tops = POLY.nest(groups);
|
||||||
|
|
@ -65,6 +65,7 @@
|
||||||
delete data.groups;
|
delete data.groups;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
const index = zIndexes.indexOf(z);
|
||||||
const range = FDM.getRangeParameters(process, index);
|
const range = FDM.getRangeParameters(process, index);
|
||||||
// calculate fractional shells
|
// calculate fractional shells
|
||||||
let shellFrac = (range.sliceShells - (range.sliceShells | 0));
|
let shellFrac = (range.sliceShells - (range.sliceShells | 0));
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,18 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
function toCodable(object) {
|
function toCodable(object) {
|
||||||
|
switch (typeof object) {
|
||||||
|
case 'function':
|
||||||
|
return undefined;
|
||||||
|
case 'string':
|
||||||
|
case 'number':
|
||||||
|
return object;
|
||||||
|
case 'object':
|
||||||
|
if (Array.isArray(object)) {
|
||||||
|
return object.map(v => toCodable(v));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
let o = {};
|
let o = {};
|
||||||
for (let [key, val] of Object.entries(object)) {
|
for (let [key, val] of Object.entries(object)) {
|
||||||
switch (typeof val) {
|
switch (typeof val) {
|
||||||
|
|
@ -35,6 +47,7 @@
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
o[key] = val;
|
o[key] = val;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return o;
|
return o;
|
||||||
|
|
|
||||||
|
|
@ -74,12 +74,12 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function unitsSave() {
|
function unitsSave() {
|
||||||
api.conf.update({controller:true});
|
api.conf.update({ controller: true });
|
||||||
platform.update_size();
|
platform.update_size();
|
||||||
}
|
}
|
||||||
|
|
||||||
function aniMeshSave() {
|
function aniMeshSave() {
|
||||||
api.conf.update({controller:true});
|
api.conf.update({ controller: true });
|
||||||
api.conf.save();
|
api.conf.save();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -835,7 +835,7 @@
|
||||||
}
|
}
|
||||||
ui.deviceAdd.disabled = dev.noclone;
|
ui.deviceAdd.disabled = dev.noclone;
|
||||||
|
|
||||||
api.view.update_fields();
|
api.conf.update_fields();
|
||||||
platform.update_size();
|
platform.update_size();
|
||||||
platform.update_origin();
|
platform.update_origin();
|
||||||
platform.update();
|
platform.update();
|
||||||
|
|
@ -1272,7 +1272,7 @@
|
||||||
});
|
});
|
||||||
setToolChanged(false);
|
setToolChanged(false);
|
||||||
api.conf.save();
|
api.conf.save();
|
||||||
api.view.update_fields();
|
api.conf.update_fields();
|
||||||
api.event.settings();
|
api.event.settings();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -2555,7 +2555,7 @@
|
||||||
selectDevice(DEVNAME || api.device.get());
|
selectDevice(DEVNAME || api.device.get());
|
||||||
|
|
||||||
// update ui fields from settings
|
// update ui fields from settings
|
||||||
api.view.update_fields();
|
api.conf.update_fields();
|
||||||
|
|
||||||
// default to ARRANGE view mode
|
// default to ARRANGE view mode
|
||||||
api.view.set(VIEWS.ARRANGE);
|
api.view.set(VIEWS.ARRANGE);
|
||||||
|
|
|
||||||
245
src/kiri/main.js
245
src/kiri/main.js
|
|
@ -153,9 +153,9 @@
|
||||||
},
|
},
|
||||||
util: {
|
util: {
|
||||||
isSecure,
|
isSecure,
|
||||||
ui2rec() { api.conf.update_from(...arguments) },
|
|
||||||
rec2ui: updateFieldsFromSettings,
|
|
||||||
download: downloadBlob,
|
download: downloadBlob,
|
||||||
|
ui2rec() { api.conf.update_from(...arguments) },
|
||||||
|
rec2ui() { api.conf.update_fields(...arguments) },
|
||||||
b64enc(obj) { return base64js.fromByteArray(new TextEncoder().encode(JSON.stringify(obj))) },
|
b64enc(obj) { return base64js.fromByteArray(new TextEncoder().encode(JSON.stringify(obj))) },
|
||||||
b64dec(obj) { return JSON.parse(new TextDecoder().decode(base64js.toByteArray(obj))) }
|
b64dec(obj) { return JSON.parse(new TextDecoder().decode(base64js.toByteArray(obj))) }
|
||||||
},
|
},
|
||||||
|
|
@ -168,11 +168,10 @@
|
||||||
is_arrange() { return viewMode === VIEWS.ARRANGE },
|
is_arrange() { return viewMode === VIEWS.ARRANGE },
|
||||||
is_slice() { return viewMode === VIEWS.SLICE },
|
is_slice() { return viewMode === VIEWS.SLICE },
|
||||||
is_preview() { return viewMode === VIEWS.PREVIEW },
|
is_preview() { return viewMode === VIEWS.PREVIEW },
|
||||||
hide_slices: hideSlices,
|
|
||||||
update_speeds: updateSpeeds,
|
|
||||||
update_fields: updateFields,
|
|
||||||
update_slider: updateSlider,
|
|
||||||
update_slider_max: updateSliderMax,
|
update_slider_max: updateSliderMax,
|
||||||
|
update_slider: updateSlider,
|
||||||
|
update_speeds: updateSpeeds,
|
||||||
|
hide_slices: hideSlices,
|
||||||
snapshot: null,
|
snapshot: null,
|
||||||
unit_scale: unitScale,
|
unit_scale: unitScale,
|
||||||
wireframe: setWireframe,
|
wireframe: setWireframe,
|
||||||
|
|
@ -374,7 +373,7 @@
|
||||||
******************************************************************* */
|
******************************************************************* */
|
||||||
|
|
||||||
function unitScale() {
|
function unitScale() {
|
||||||
return MODE === MODES.CAM && settings.ctrl().units === 'in' ? 25.4 : 1;
|
return api.mode.is_cam() && settings.ctrl().units === 'in' ? 25.4 : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
function alert2(message, time) {
|
function alert2(message, time) {
|
||||||
|
|
@ -465,139 +464,6 @@
|
||||||
return Math.max(min,Math.min(max,v));
|
return Math.max(min,Math.min(max,v));
|
||||||
}
|
}
|
||||||
|
|
||||||
function getOverlappingRanges(lo, hi) {
|
|
||||||
let ranges = [];
|
|
||||||
for (let range of settings.proc().ranges || []) {
|
|
||||||
let in_lo = range.lo >= lo && range.lo <= hi;
|
|
||||||
let in_hi = range.hi >= lo && range.hi <= hi;
|
|
||||||
if (in_lo || in_hi) {
|
|
||||||
ranges.push(range);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ranges;
|
|
||||||
}
|
|
||||||
|
|
||||||
// set process override values for a range
|
|
||||||
function updateRange(lo, hi, values, add) {
|
|
||||||
let ranges = settings.proc().ranges;
|
|
||||||
let slices = {};
|
|
||||||
let min = lo;
|
|
||||||
let max = hi;
|
|
||||||
|
|
||||||
// special case for belt loops which should not be flattened
|
|
||||||
if (values.outputLoops) {
|
|
||||||
ranges.push({
|
|
||||||
lo, hi, fields: values
|
|
||||||
});
|
|
||||||
updateFieldsFromSettings(settings.proc());
|
|
||||||
api.show.alert("update ranges", 2);
|
|
||||||
api.event.emit("range.updates", ranges);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// just remove values from matching ranges
|
|
||||||
if (!add) {
|
|
||||||
for (let range of getOverlappingRanges(lo, hi)) {
|
|
||||||
for (let key of Object.keys(values)) {
|
|
||||||
delete range.fields[key];
|
|
||||||
}
|
|
||||||
if (Object.keys(range.fields).length === 0) {
|
|
||||||
let pos = ranges.indexOf(range);
|
|
||||||
if (pos >= 0) {
|
|
||||||
ranges.splice(pos,1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
api.event.emit("range.updates", ranges);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// set aside belt loops and re-append later
|
|
||||||
// since we do not want to collapse/merge loops
|
|
||||||
let exclude = ranges.filter(r => r.fields.outputLoops);
|
|
||||||
ranges = ranges.filter(r => !r.fields.outputLoops);
|
|
||||||
|
|
||||||
// flatten ranges
|
|
||||||
ranges.push({lo, hi, fields: values});
|
|
||||||
for (let range of ranges) {
|
|
||||||
min = Math.min(range.lo, min);
|
|
||||||
max = Math.max(range.hi, max);
|
|
||||||
for (let i=range.lo; i<=range.hi; i++) {
|
|
||||||
let slice = slices[i];
|
|
||||||
if (!slice) {
|
|
||||||
slice = slices[i] = {};
|
|
||||||
}
|
|
||||||
for (let [key,val] of Object.entries(range.fields)) {
|
|
||||||
slice[key] = val;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// merge contiguous matching ranges
|
|
||||||
ranges = settings.proc().ranges = [];
|
|
||||||
let range;
|
|
||||||
for (let i=min; i<=max; i++) {
|
|
||||||
let slice = slices[i];
|
|
||||||
if (slice && !range) {
|
|
||||||
range = {lo: i, hi: i, fields: slice};
|
|
||||||
} else if (slice && range && areEqual(range.fields, slice)) {
|
|
||||||
range.hi = i;
|
|
||||||
} else if (range) {
|
|
||||||
ranges.push(range);
|
|
||||||
if (slice) {
|
|
||||||
range = {lo: i, hi: i, fields: slice};
|
|
||||||
} else {
|
|
||||||
range = undefined;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ranges.push(range);
|
|
||||||
ranges.appendAll(exclude);
|
|
||||||
|
|
||||||
updateFieldsFromSettings(settings.proc());
|
|
||||||
api.show.alert("update ranges", 2);
|
|
||||||
api.event.emit("range.updates", ranges);
|
|
||||||
}
|
|
||||||
|
|
||||||
let overrides = {};
|
|
||||||
|
|
||||||
// updates editable fields that are range dependent
|
|
||||||
function updateFieldsFromRange() {
|
|
||||||
return;
|
|
||||||
if (settings.mode !== 'FDM' || viewMode !== VIEWS.SLICE || !settings.proc().ranges) {
|
|
||||||
let okeys = Object.keys(overrides);
|
|
||||||
if (okeys.length) {
|
|
||||||
updateFieldsFromSettings(overrides);
|
|
||||||
overrides = {};
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let match = 0;
|
|
||||||
let values = {};
|
|
||||||
let restores = Object.clone(overrides);
|
|
||||||
let { layer_lo, layer_hi } = api.var;
|
|
||||||
for (let range of getOverlappingRanges(api.var.layer_lo, api.var.layer_hi)) {
|
|
||||||
for (let key of Object.keys(range.fields)) {
|
|
||||||
values[key] = range.fields[key];
|
|
||||||
overrides[key] = settings.proc()[key];
|
|
||||||
delete restores[key];
|
|
||||||
match++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (match) {
|
|
||||||
updateFieldsFromSettings(values);
|
|
||||||
}
|
|
||||||
let rkeys = Object.keys(restores);
|
|
||||||
if (rkeys.length) {
|
|
||||||
updateFieldsFromSettings(restores);
|
|
||||||
for (let key of rkeys) {
|
|
||||||
delete overrides[key];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
UC.refresh();
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateSpeeds(maxSpeed, minSpeed) {
|
function updateSpeeds(maxSpeed, minSpeed) {
|
||||||
const { ui } = api;
|
const { ui } = api;
|
||||||
ui.speeds.style.display =
|
ui.speeds.style.display =
|
||||||
|
|
@ -636,7 +502,7 @@
|
||||||
start: (api.var.layer_lo / api.var.layer_max),
|
start: (api.var.layer_lo / api.var.layer_max),
|
||||||
end: (api.var.layer_hi / api.var.layer_max)
|
end: (api.var.layer_hi / api.var.layer_max)
|
||||||
});
|
});
|
||||||
updateFieldsFromRange();
|
api.conf.update_fields_from_range();
|
||||||
}
|
}
|
||||||
|
|
||||||
function setVisibleLayer(h, l) {
|
function setVisibleLayer(h, l) {
|
||||||
|
|
@ -705,8 +571,8 @@
|
||||||
api.var.layer_hi = layer;
|
api.var.layer_hi = layer;
|
||||||
api.event.emit("slider.label");
|
api.event.emit("slider.label");
|
||||||
|
|
||||||
let cam = MODE === MODES.CAM,
|
let cam = api.mode.is_cam(),
|
||||||
sla = MODE === MODES.SLA,
|
sla = api.mode.is_sla(),
|
||||||
hi = cam ? api.var.layer_max - api.var.layer_lo : api.var.layer_hi,
|
hi = cam ? api.var.layer_max - api.var.layer_lo : api.var.layer_hi,
|
||||||
lo = cam ? api.var.layer_max - api.var.layer_hi : api.var.layer_lo;
|
lo = cam ? api.var.layer_max - api.var.layer_hi : api.var.layer_lo;
|
||||||
|
|
||||||
|
|
@ -796,95 +662,6 @@
|
||||||
* Settings Functions
|
* Settings Functions
|
||||||
******************************************************************* */
|
******************************************************************* */
|
||||||
|
|
||||||
// given a settings region, update values of matching bound UI fields
|
|
||||||
function updateFieldsFromSettings(setrec, uirec = UI, trace) {
|
|
||||||
if (!setrec) {
|
|
||||||
return console.trace("missing scope");
|
|
||||||
}
|
|
||||||
for (let key in setrec) {
|
|
||||||
if (!setrec.hasOwnProperty(key)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
let val = setrec[key];
|
|
||||||
if (!uirec.hasOwnProperty(key)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
let uie = uirec[key], typ = uie ? uie.type : null;
|
|
||||||
if (typ === 'text') {
|
|
||||||
if (uie.setv) {
|
|
||||||
uie.setv(val);
|
|
||||||
} else {
|
|
||||||
uie.value = val;
|
|
||||||
}
|
|
||||||
} else if (typ === 'checkbox') {
|
|
||||||
uie.checked = val;
|
|
||||||
} else if (typ === 'select-one') {
|
|
||||||
uie.innerHTML = '';
|
|
||||||
let source = uie.parentNode.getAttribute('source'),
|
|
||||||
list = uie._source || settings[source] || api.lists[source],
|
|
||||||
chosen = null;
|
|
||||||
if (list) list.forEach(function(el, index) {
|
|
||||||
let id = el.id || el.name;
|
|
||||||
let ev = el.value || id;
|
|
||||||
if (val == id) {
|
|
||||||
chosen = index;
|
|
||||||
}
|
|
||||||
let opt = DOC.createElement('option');
|
|
||||||
opt.appendChild(DOC.createTextNode(el.name));
|
|
||||||
opt.setAttribute('value', ev);
|
|
||||||
uie.appendChild(opt);
|
|
||||||
});
|
|
||||||
if (chosen) {
|
|
||||||
uie.selectedIndex = chosen;
|
|
||||||
}
|
|
||||||
} else if (typ === 'textarea') {
|
|
||||||
if (Array.isArray(val)) {
|
|
||||||
uie.value = val.join('\n');
|
|
||||||
} else {
|
|
||||||
uie.value = '';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateFields() {
|
|
||||||
updateFieldsFromSettings(settings.dev());
|
|
||||||
updateFieldsFromSettings(settings.proc());
|
|
||||||
updateFieldsFromSettings(settings.ctrl());
|
|
||||||
updateExtruderFields(settings.dev());
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateExtruderFields(device) {
|
|
||||||
if (device.extruders && device.extruders[device.internal]) {
|
|
||||||
updateFieldsFromSettings(device.extruders[device.internal]);
|
|
||||||
UI.extruder.firstChild.innerText = `${LANG.dv_gr_ext} [${device.internal+1}/${device.extruders.length}]`;
|
|
||||||
UI.extPrev.disabled = device.internal === 0;
|
|
||||||
UI.extPrev.onclick = function() {
|
|
||||||
device.internal--;
|
|
||||||
updateExtruderFields(device);
|
|
||||||
};
|
|
||||||
UI.extNext.disabled = device.internal === device.extruders.length - 1;
|
|
||||||
UI.extNext.onclick = function() {
|
|
||||||
device.internal++;
|
|
||||||
updateExtruderFields(device);
|
|
||||||
};
|
|
||||||
UI.extDel.disabled = UI.extDel.disabled || device.extruders.length < 2;
|
|
||||||
UI.extDel.onclick = function() {
|
|
||||||
device.extruders.splice(device.internal,1);
|
|
||||||
device.internal = Math.min(device.internal, device.extruders.length-1);
|
|
||||||
updateExtruderFields(device);
|
|
||||||
};
|
|
||||||
UI.extAdd.onclick = function() {
|
|
||||||
let copy = clone(device.extruders[device.internal]);
|
|
||||||
copy.extSelect = [`T${device.extruders.length}`];
|
|
||||||
copy.extDeselect = [];
|
|
||||||
device.extruders.push(copy);
|
|
||||||
device.internal = device.extruders.length - 1;
|
|
||||||
updateExtruderFields(device);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function loadImageConvert(res, name) {
|
function loadImageConvert(res, name) {
|
||||||
let url = URL.createObjectURL(new Blob([res]));
|
let url = URL.createObjectURL(new Blob([res]));
|
||||||
|
|
||||||
|
|
@ -944,7 +721,7 @@
|
||||||
loaded = 0,
|
loaded = 0,
|
||||||
position = true;
|
position = true;
|
||||||
|
|
||||||
updateFields();
|
api.conf.update_fields();
|
||||||
platform.update_size();
|
platform.update_size();
|
||||||
|
|
||||||
SPACE.view.reset();
|
SPACE.view.reset();
|
||||||
|
|
@ -1291,7 +1068,7 @@
|
||||||
triggerSettingsEvent();
|
triggerSettingsEvent();
|
||||||
platform.update_selected();
|
platform.update_selected();
|
||||||
selection.update_bounds(api.widgets.all());
|
selection.update_bounds(api.widgets.all());
|
||||||
updateFields();
|
api.conf.update_fields();
|
||||||
// because device dialog, if showing, needs to be updated
|
// because device dialog, if showing, needs to be updated
|
||||||
if (modalShowing()) {
|
if (modalShowing()) {
|
||||||
api.show.devices();
|
api.show.devices();
|
||||||
|
|
|
||||||
|
|
@ -68,7 +68,7 @@ function loadSettings(evt, named) {
|
||||||
api.event.emit("settings.load", settings);
|
api.event.emit("settings.load", settings);
|
||||||
|
|
||||||
// update UI fields to reflect current settings
|
// update UI fields to reflect current settings
|
||||||
api.view.update_fields();
|
api.conf.update_fields();
|
||||||
api.conf.update();
|
api.conf.update();
|
||||||
|
|
||||||
// publish event when loading from ui event
|
// publish event when loading from ui event
|
||||||
|
|
@ -86,15 +86,19 @@ function updateSettings(opt = {}) {
|
||||||
const { uc } = api;
|
const { uc } = api;
|
||||||
|
|
||||||
updateSettingsFromFields(controller);
|
updateSettingsFromFields(controller);
|
||||||
|
|
||||||
switch (controller.units) {
|
switch (controller.units) {
|
||||||
case 'mm': uc.setUnits(1); break;
|
case 'mm': uc.setUnits(1); break;
|
||||||
case 'in': uc.setUnits(25.4); break;
|
case 'in': uc.setUnits(25.4); break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// limit update to controller fields (ui prefs dialog)
|
||||||
if (opt.controller) {
|
if (opt.controller) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
updateSettingsFromFields(device, undefined, undefined, true);
|
updateSettingsFromFields(device);
|
||||||
|
|
||||||
// range-specific values
|
// range-specific values
|
||||||
if (settings.mode === 'FDM' && api.view.is_slice()) {
|
if (settings.mode === 'FDM' && api.view.is_slice()) {
|
||||||
let changes = {};
|
let changes = {};
|
||||||
|
|
@ -106,6 +110,7 @@ function updateSettings(opt = {}) {
|
||||||
values = Object.clone(process);
|
values = Object.clone(process);
|
||||||
add = true;
|
add = true;
|
||||||
}
|
}
|
||||||
|
// collect changes to pass to range updates
|
||||||
updateSettingsFromFields(values, undefined, changes);
|
updateSettingsFromFields(values, undefined, changes);
|
||||||
if (range) {
|
if (range) {
|
||||||
updateRange(range.lo, range.hi, changes, add);
|
updateRange(range.lo, range.hi, changes, add);
|
||||||
|
|
@ -113,10 +118,13 @@ function updateSettings(opt = {}) {
|
||||||
} else {
|
} else {
|
||||||
updateSettingsFromFields(process);
|
updateSettingsFromFields(process);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (device.extruders && device.extruders[device.internal]) {
|
if (device.extruders && device.extruders[device.internal]) {
|
||||||
updateSettingsFromFields(device.extruders[device.internal]);
|
updateSettingsFromFields(device.extruders[device.internal]);
|
||||||
}
|
}
|
||||||
|
|
||||||
api.conf.save();
|
api.conf.save();
|
||||||
|
|
||||||
let compare = sproc[mode][cproc[mode]];
|
let compare = sproc[mode][cproc[mode]];
|
||||||
let same = true;
|
let same = true;
|
||||||
if (compare)
|
if (compare)
|
||||||
|
|
@ -136,6 +144,7 @@ function updateSettings(opt = {}) {
|
||||||
same = false;
|
same = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$('mode-device').innerText = device.deviceName;
|
$('mode-device').innerText = device.deviceName;
|
||||||
$('mode-profile').innerText = `${cproc[mode]}${same ? '' : ' *'}`;
|
$('mode-profile').innerText = `${cproc[mode]}${same ? '' : ' *'}`;
|
||||||
}
|
}
|
||||||
|
|
@ -196,6 +205,227 @@ function updateSettingsFromFields(setrec, uirec = api.ui, changes) {
|
||||||
return settings;
|
return settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// given a settings region, update values of matching bound UI fields
|
||||||
|
function updateFieldsFromSettings(setrec, uirec = api.ui, trace) {
|
||||||
|
if (!setrec) {
|
||||||
|
updateFieldsFromSettings(settings.device);
|
||||||
|
updateFieldsFromSettings(settings.process);
|
||||||
|
updateFieldsFromSettings(settings.controller);
|
||||||
|
updateExtruderFields(settings.device);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (let key in setrec) {
|
||||||
|
if (!setrec.hasOwnProperty(key)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let val = setrec[key];
|
||||||
|
if (!uirec.hasOwnProperty(key)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let uie = uirec[key], typ = uie ? uie.type : null;
|
||||||
|
if (typ === 'text') {
|
||||||
|
if (uie.setv) {
|
||||||
|
uie.setv(val);
|
||||||
|
} else {
|
||||||
|
uie.value = val;
|
||||||
|
}
|
||||||
|
} else if (typ === 'checkbox') {
|
||||||
|
uie.checked = val;
|
||||||
|
} else if (typ === 'select-one') {
|
||||||
|
uie.innerHTML = '';
|
||||||
|
let source = uie.parentNode.getAttribute('source'),
|
||||||
|
list = uie._source || settings[source] || api.lists[source],
|
||||||
|
chosen = null;
|
||||||
|
if (list) list.forEach(function(el, index) {
|
||||||
|
let id = el.id || el.name;
|
||||||
|
let ev = el.value || id;
|
||||||
|
if (val == id) {
|
||||||
|
chosen = index;
|
||||||
|
}
|
||||||
|
let opt = document.createElement('option');
|
||||||
|
opt.appendChild(document.createTextNode(el.name));
|
||||||
|
opt.setAttribute('value', ev);
|
||||||
|
uie.appendChild(opt);
|
||||||
|
});
|
||||||
|
if (chosen) {
|
||||||
|
uie.selectedIndex = chosen;
|
||||||
|
}
|
||||||
|
} else if (typ === 'textarea') {
|
||||||
|
if (Array.isArray(val)) {
|
||||||
|
uie.value = val.join('\n');
|
||||||
|
} else {
|
||||||
|
uie.value = '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateExtruderFields(device) {
|
||||||
|
const { ui } = api;
|
||||||
|
const { LANG } = api.const;
|
||||||
|
if (device.extruders && device.extruders[device.internal]) {
|
||||||
|
updateFieldsFromSettings(device.extruders[device.internal]);
|
||||||
|
ui.extruder.firstChild.innerText = `${LANG.dv_gr_ext} [${device.internal+1}/${device.extruders.length}]`;
|
||||||
|
ui.extPrev.disabled = device.internal === 0;
|
||||||
|
ui.extPrev.onclick = function() {
|
||||||
|
device.internal--;
|
||||||
|
updateExtruderFields(device);
|
||||||
|
};
|
||||||
|
ui.extNext.disabled = device.internal === device.extruders.length - 1;
|
||||||
|
ui.extNext.onclick = function() {
|
||||||
|
device.internal++;
|
||||||
|
updateExtruderFields(device);
|
||||||
|
};
|
||||||
|
ui.extDel.disabled = ui.extDel.disabled || device.extruders.length < 2;
|
||||||
|
ui.extDel.onclick = function() {
|
||||||
|
device.extruders.splice(device.internal,1);
|
||||||
|
device.internal = Math.min(device.internal, device.extruders.length-1);
|
||||||
|
updateExtruderFields(device);
|
||||||
|
};
|
||||||
|
ui.extAdd.onclick = function() {
|
||||||
|
let copy = clone(device.extruders[device.internal]);
|
||||||
|
copy.extSelect = [`T${device.extruders.length}`];
|
||||||
|
copy.extDeselect = [];
|
||||||
|
device.extruders.push(copy);
|
||||||
|
device.internal = device.extruders.length - 1;
|
||||||
|
updateExtruderFields(device);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getOverlappingRanges(lo, hi) {
|
||||||
|
let ranges = [];
|
||||||
|
for (let range of settings.process.ranges || []) {
|
||||||
|
let in_lo = range.lo >= lo && range.lo <= hi;
|
||||||
|
let in_hi = range.hi >= lo && range.hi <= hi;
|
||||||
|
if (in_lo || in_hi) {
|
||||||
|
ranges.push(range);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ranges;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set process override values for a range
|
||||||
|
function updateRange(lo, hi, values, add) {
|
||||||
|
let ranges = settings.process.ranges;
|
||||||
|
let slices = {};
|
||||||
|
let min = lo;
|
||||||
|
let max = hi;
|
||||||
|
|
||||||
|
// special case for belt loops which should not be flattened
|
||||||
|
if (values.outputLoops) {
|
||||||
|
ranges.push({
|
||||||
|
lo, hi, fields: values
|
||||||
|
});
|
||||||
|
api.conf.update_fields(settings.process);
|
||||||
|
api.show.alert("update ranges", 2);
|
||||||
|
api.event.emit("range.updates", ranges);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// just remove values from matching ranges
|
||||||
|
if (!add) {
|
||||||
|
for (let range of getOverlappingRanges(lo, hi)) {
|
||||||
|
for (let key of Object.keys(values)) {
|
||||||
|
delete range.fields[key];
|
||||||
|
}
|
||||||
|
if (Object.keys(range.fields).length === 0) {
|
||||||
|
let pos = ranges.indexOf(range);
|
||||||
|
if (pos >= 0) {
|
||||||
|
ranges.splice(pos,1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
api.event.emit("range.updates", ranges);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set aside belt loops and re-append later
|
||||||
|
// since we do not want to collapse/merge loops
|
||||||
|
let exclude = ranges.filter(r => r.fields.outputLoops);
|
||||||
|
ranges = ranges.filter(r => !r.fields.outputLoops);
|
||||||
|
|
||||||
|
// flatten ranges
|
||||||
|
ranges.push({lo, hi, fields: values});
|
||||||
|
for (let range of ranges) {
|
||||||
|
min = Math.min(range.lo, min);
|
||||||
|
max = Math.max(range.hi, max);
|
||||||
|
for (let i=range.lo; i<=range.hi; i++) {
|
||||||
|
let slice = slices[i];
|
||||||
|
if (!slice) {
|
||||||
|
slice = slices[i] = {};
|
||||||
|
}
|
||||||
|
for (let [key,val] of Object.entries(range.fields)) {
|
||||||
|
slice[key] = val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// merge contiguous matching ranges
|
||||||
|
ranges = settings.process.ranges = [];
|
||||||
|
let range;
|
||||||
|
for (let i=min; i<=max; i++) {
|
||||||
|
let slice = slices[i];
|
||||||
|
if (slice && !range) {
|
||||||
|
range = {lo: i, hi: i, fields: slice};
|
||||||
|
} else if (slice && range && areEqual(range.fields, slice)) {
|
||||||
|
range.hi = i;
|
||||||
|
} else if (range) {
|
||||||
|
ranges.push(range);
|
||||||
|
if (slice) {
|
||||||
|
range = {lo: i, hi: i, fields: slice};
|
||||||
|
} else {
|
||||||
|
range = undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ranges.push(range);
|
||||||
|
ranges.appendAll(exclude);
|
||||||
|
|
||||||
|
api.conf.update_fields(settings.process);
|
||||||
|
api.show.alert("update ranges", 2);
|
||||||
|
api.event.emit("range.updates", ranges);
|
||||||
|
}
|
||||||
|
|
||||||
|
let overrides = {};
|
||||||
|
|
||||||
|
// updates editable fields that are range dependent
|
||||||
|
function updateFieldsFromRange() {
|
||||||
|
return;
|
||||||
|
if (settings.mode !== 'FDM' || !api.view.is_slice() || !settings.process.ranges) {
|
||||||
|
let okeys = Object.keys(overrides);
|
||||||
|
if (okeys.length) {
|
||||||
|
api.conf.update_fields(overrides);
|
||||||
|
overrides = {};
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let match = 0;
|
||||||
|
let values = {};
|
||||||
|
let restores = Object.clone(overrides);
|
||||||
|
let { layer_lo, layer_hi } = api.var;
|
||||||
|
for (let range of getOverlappingRanges(api.var.layer_lo, api.var.layer_hi)) {
|
||||||
|
for (let key of Object.keys(range.fields)) {
|
||||||
|
values[key] = range.fields[key];
|
||||||
|
overrides[key] = settings.process[key];
|
||||||
|
delete restores[key];
|
||||||
|
match++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (match) {
|
||||||
|
api.conf.update_fields(values);
|
||||||
|
}
|
||||||
|
let rkeys = Object.keys(restores);
|
||||||
|
if (rkeys.length) {
|
||||||
|
api.conf.update_fields(restores);
|
||||||
|
for (let key of rkeys) {
|
||||||
|
delete overrides[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
api.uc.refresh();
|
||||||
|
}
|
||||||
|
|
||||||
function restoreSettings(save) {
|
function restoreSettings(save) {
|
||||||
const widgets = api.widgets.all();
|
const widgets = api.widgets.all();
|
||||||
const newset = ls2o('ws-settings') || settings;
|
const newset = ls2o('ws-settings') || settings;
|
||||||
|
|
@ -438,6 +668,8 @@ api.conf = {
|
||||||
show: showSettings,
|
show: showSettings,
|
||||||
update: updateSettings,
|
update: updateSettings,
|
||||||
update_from: updateSettingsFromFields,
|
update_from: updateSettingsFromFields,
|
||||||
|
update_fields: updateFieldsFromSettings,
|
||||||
|
update_fields_from_range: updateFieldsFromRange,
|
||||||
restore: restoreSettings,
|
restore: restoreSettings,
|
||||||
export: settingsExport,
|
export: settingsExport,
|
||||||
import: settingsImport,
|
import: settingsImport,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue