add kiri settings export / import

This commit is contained in:
Stewart Allen 2020-04-07 21:45:21 -04:00
commit 81b6395113
6 changed files with 104 additions and 38 deletions

View file

@ -10,6 +10,7 @@ var gs_kiri_init = exports;
if (self.kiri.init) return;
let KIRI = self.kiri,
MOTO = self.moto,
WIN = self.window,
DOC = self.document,
LOC = self.location,
@ -434,6 +435,15 @@ var gs_kiri_init = exports;
}).request("/data/"+ settings().id + "/" + settings().ver, set);
}
function settingsExport() {
if (!confirm('Download Kiri:Moto Settings?')) return;
let json = API.conf.export();
let blob = new Blob([json], {type: "octet/stream"});
let url = WIN.URL.createObjectURL(blob);
$('help').innerHTML = `<a id="sexport" href="${url}" download="kiriconf.b64">x</a>`;
$('sexport').click();
}
function settingsSave() {
API.dialog.hide();
let mode = API.mode.get(),
@ -1218,6 +1228,9 @@ var gs_kiri_init = exports;
],[
UI.setupTools =
UC.newButton(LANG.su_tool, showTools, {modes:CAM})
],[
UI.setupExport =
UC.newButton(LANG.su_xprt, settingsExport, {modes:ALL})
],[
UI.localButton =
UC.newButton(LANG.su_locl, API.show.local, {modes:FDM_CAM, expert:true})

View file

@ -106,7 +106,7 @@ self.kiri.copyright = exports.COPYRIGHT;
update_stock: platformUpdateStock,
update_size: platformUpdateSize,
update_top_z: platformUpdateTopZ,
load_files: loadFiles,
load_files: platformLoadFiles,
group: platformGroup,
group_done: platformGroupDone
};
@ -143,7 +143,9 @@ self.kiri.copyright = exports.COPYRIGHT;
save: saveSettings,
show: showSettings,
update: updateSettings,
restore: restoreSettings
restore: restoreSettings,
export: settingsExport,
import: settingsImport
},
color,
const: {
@ -815,8 +817,12 @@ self.kiri.copyright = exports.COPYRIGHT;
* Selection Functions
******************************************************************* */
function meshUpdateInfo(mesh) {
if (!mesh) {
function updateSelectedInfo() {
let bounds = new THREE.Box3();
forSelectedMeshes(mesh => {
bounds = bounds.union(mesh.getBoundingBox());
});
if (bounds.min.x === Infinity) {
if (selectedMeshes.length === 0) {
UI.selWidth.innerHTML = '0';
UI.selDepth.innerHTML = '0';
@ -825,13 +831,15 @@ self.kiri.copyright = exports.COPYRIGHT;
UI.scaleY.value = '';
UI.scaleZ.value = '';
}
return
return;
}
let scale = unitScale();
let {w, h, d} = mesh.widget.track.box;
UI.selWidth.innerHTML = UTIL.round(w/scale,2);
UI.selDepth.innerHTML = UTIL.round(h/scale,2);
UI.selHeight.innerHTML = UTIL.round(d/scale,2);
let dx = bounds.max.x - bounds.min.x,
dy = bounds.max.y - bounds.min.y,
dz = bounds.max.z - bounds.min.z,
scale = unitScale();
UI.selWidth.innerHTML = UTIL.round(dx/scale,2);
UI.selDepth.innerHTML = UTIL.round(dy/scale,2);
UI.selHeight.innerHTML = UTIL.round(dz/scale,2);
UI.scaleX.value = 1;
UI.scaleY.value = 1;
UI.scaleZ.value = 1;
@ -861,8 +869,8 @@ self.kiri.copyright = exports.COPYRIGHT;
z = parseFloat(UI.scaleZ.value || dv);
forSelectedGroups(function (w) {
w.scale(x,y,z);
meshUpdateInfo(w.mesh);
});
updateSelectedInfo();
UI.scaleX.value = 1;
UI.scaleY.value = 1;
UI.scaleZ.value = 1;
@ -874,8 +882,8 @@ self.kiri.copyright = exports.COPYRIGHT;
function rotateSelection(x, y, z) {
forSelectedGroups(function (w) {
w.rotate(x, y, z);
meshUpdateInfo(w.mesh);
});
updateSelectedInfo();
platform.compute_max_z();
platform.update_stock(true);
SPACE.update();
@ -976,7 +984,7 @@ self.kiri.copyright = exports.COPYRIGHT;
selectedMeshes.push(mesh);
API.event.emit('widget.select', widget);
widget.setColor(color.selected);
meshUpdateInfo(mesh);
updateSelectedInfo();
}
platformUpdateSelected();
SPACE.update();
@ -1012,7 +1020,7 @@ self.kiri.copyright = exports.COPYRIGHT;
widget.setColor(color.deselected);
platformUpdateSelected();
SPACE.update();
meshUpdateInfo();
updateSelectedInfo();
}
function platformLoad(url, onload) {
@ -1395,7 +1403,41 @@ self.kiri.copyright = exports.COPYRIGHT;
SDB.setItem('ws-settings', JSON.stringify(settings));
}
function loadFiles(files,group) {
function settingsImport(data, ask) {
if (typeof(data) === 'string') {
try {
data = JSON.parse(atob(data));
} catch (e) {
console.log({data})
alert('invalid settings format');
return;
}
}
if (!(data.settings && data.moto && data.time)) {
alert('invalid settings format');
return;
}
if (ask && !confirm(`Import settings made on ${new Date(data.time)} from Kiri:Moto version ${data.version}?`)) {
return;
}
settings = data.settings;
MOTO.restore(data.moto);
SDB.setItem('kiri-init', data.init || 2);
API.conf.save();
LOC.reload();
}
function settingsExport() {
return btoa(JSON.stringify({
settings: settings,
version: KIRI.version,
moto: MOTO.id,
init: SDB.getItem('kiri-init'),
time: Date.now()
}));
}
function platformLoadFiles(files,group) {
let loaded = files.length;
platform.group();
for (let i=0; i<files.length; i++) {
@ -1404,7 +1446,8 @@ self.kiri.copyright = exports.COPYRIGHT;
israw = lower.indexOf(".raw") > 0 || lower.indexOf('.') < 0,
isstl = lower.indexOf(".stl") > 0,
issvg = lower.indexOf(".svg") > 0,
isgcode = lower.indexOf(".gcode") > 0 || lower.indexOf(".nc") > 0;
isgcode = lower.indexOf(".gcode") > 0 || lower.indexOf(".nc") > 0,
isset = lower.indexOf(".b64") > 0;
reader.file = files[i];
reader.onloadend = function (e) {
if (israw) platform.add(
@ -1418,6 +1461,7 @@ self.kiri.copyright = exports.COPYRIGHT;
);
if (isgcode) loadCode(e.target.result, 'gcode');
if (issvg) loadCode(e.target.result, 'svg');
if (isset) settingsImport(e.target.result, true);
if (--loaded === 0) platform.group_done();
};
reader.readAsBinaryString(reader.file);
@ -1427,7 +1471,7 @@ self.kiri.copyright = exports.COPYRIGHT;
function loadFile() {
$('load-file').onchange = function(event) {
DBUG.log(event);
loadFiles(event.target.files);
platformLoadFiles(event.target.files);
};
$('load-file').click();
// alert2("drag/drop STL files onto platform to import\nreload page to return to last saved state");
@ -1757,7 +1801,7 @@ self.kiri.copyright = exports.COPYRIGHT;
var oldMode = viewMode;
viewMode = mode;
platform.deselect();
meshUpdateInfo();
updateSelectedInfo();
switch (mode) {
case VIEWS.ARRANGE:
showLayerView(false);

View file

@ -2,18 +2,35 @@
"use strict";
var gs_moto_ajax = exports;
let gs_moto_ajax = exports;
(function() {
if (!self.moto) self.moto = {};
if (self.moto.Ajax) return;
let MOTO = self.moto;
self.moto.Ajax = Ajax;
self.moto.callAjax = function(url, handler) {
if (!MOTO) MOTO = self.moto = {};
if (MOTO.Ajax) return;
MOTO.Ajax = Ajax;
MOTO.callAjax = function(url, handler) {
new Ajax(handler).request(url);
};
var STATES = [
let AP = Ajax.prototype,
KV = moto.KV,
KEY = "moto-ajax",
TIME = function() { return new Date().getTime() },
MOKEY = moto.id = KV.getItem(KEY) || (TIME().toString(36)+rnd()+rnd());
MOTO.restore = function(id) {
MOKEY = moto.id = id;
KV.setItem(KEY, MOKEY);
}
KV.setItem(KEY, MOKEY);
let STATES = [
"request not initialized", // 0
"server connection established", // 1
"request recieved", // 2
@ -34,18 +51,10 @@ var gs_moto_ajax = exports;
return Math.round(Math.random()*0xffffffff).toString(36);
}
var AP = Ajax.prototype,
KV = moto.KV,
KEY = "moto-ajax",
TIME = function() { return new Date().getTime() },
MOKEY = KV.getItem(KEY) || (TIME().toString(36)+rnd()+rnd());
KV.setItem(KEY, MOKEY);
AP.onStateChange = function() {
this.state = STATES[this.ajax.readyState];
if (this.ajax.readyState === 4 && this.callback) {
var status = this.ajax.status;
let status = this.ajax.status;
if (status >= 200 && status < 300) {
this.callback(this.ajax.responseType ? this.ajax.response : this.ajax.responseText, this.ajax);
} else {
@ -64,7 +73,7 @@ var gs_moto_ajax = exports;
if (this.responseType) this.ajax.responseType = this.responseType;
headers = headers || {};
headers["X-Moto-Ajax"] = MOKEY;
for (var k in headers) {
for (let k in headers) {
this.ajax.setRequestHeader(k, headers[k]);
}
if (send) {

View file

@ -529,7 +529,7 @@ var gs_moto_ui = exports;
b.appendChild(t);
b.onclick = function() {
if (compact) hidePoppers();
action();
if (action) action();
};
if (options && options.class) {

View file

@ -5,10 +5,8 @@
* `B` restore settings should restore all mode/device/settings (find corner cases)
* `C` set page background color? or dark mode?
* `F` implement an in-app bug reporting system
* `F` widget general add-ons (fdm supports, cam tabs)
* `F` extend mesh object to store raw + annotations (rot,scale,pos)
* share raw data w/ dups, encode/decode
* `F` remember object's original position/orientation for reset/multi-object import alignment
* `P` bail on decimation if it's proving ineffective
* `P` improve decimation speed by avoiding in/out of Point?
* `P` server-side processing (determine protocol and storage)
@ -18,6 +16,7 @@
# FDM
* `B` check for support / brim intersections on first layer
* `F` detect M82 / M83 in the gcode header and use appropriate setting over device
* `F` manual support addition / control
* `F` polishing and other non-planar work
* `F` gradient infill https://www.youtube.com/watch?v=hq53gsYREHU&feature=emb_logo
@ -30,7 +29,7 @@
* `F` determine start point from gcode preamble
* `F` trim support offset from layer below
* `F` feather sharp tips by reducing extrusion in area of overlap
* `F` dual extruder and swapping extruder support
* `F` multi extruder and swapping extruder support
* `F` option to support interior bridges when 0% infill
* `P` disable infill fingerprinting for gyroids
* `P` refactor thin fill to use outline and inside poly normal dist to self

View file

@ -72,6 +72,7 @@ kiri.lang['en-us'] = {
su_devi: "Devices",
su_tool: "Tools",
su_locl: "Local",
su_xprt: "Export",
su_help: "Help",
// FUNCTION