extract widgets from main
This commit is contained in:
parent
90cef5e7fa
commit
2230787b93
3 changed files with 145 additions and 136 deletions
1
app.js
1
app.js
|
|
@ -366,6 +366,7 @@ const script = {
|
||||||
"kiri/stack",
|
"kiri/stack",
|
||||||
"kiri/stacks",
|
"kiri/stacks",
|
||||||
"kiri/widget",
|
"kiri/widget",
|
||||||
|
"kiri/widgets",
|
||||||
"kiri/platform",
|
"kiri/platform",
|
||||||
"kiri/selection",
|
"kiri/selection",
|
||||||
"kiri/codec",
|
"kiri/codec",
|
||||||
|
|
|
||||||
167
src/kiri/main.js
167
src/kiri/main.js
|
|
@ -23,23 +23,18 @@
|
||||||
SPACE = kiri.space = moto.Space,
|
SPACE = kiri.space = moto.Space,
|
||||||
FILES = kiri.catalog = kiri.openFiles(new data.Index(SETUP.d ? SETUP.d[0] : 'kiri')),
|
FILES = kiri.catalog = kiri.openFiles(new data.Index(SETUP.d ? SETUP.d[0] : 'kiri')),
|
||||||
STATS = new Stats(SDB),
|
STATS = new Stats(SDB),
|
||||||
// ---------------
|
|
||||||
CONF = kiri.conf,
|
CONF = kiri.conf,
|
||||||
clone = Object.clone;
|
clone = Object.clone;
|
||||||
|
|
||||||
let settings = clone(CONF.template),
|
let settings = clone(CONF.template),
|
||||||
WIDGETS = kiri.widgets = [],
|
|
||||||
// ---------------
|
|
||||||
UI = {},
|
UI = {},
|
||||||
UC = kiri.ui.prefix('kiri').inputAction(updateSettings),
|
UC = kiri.ui.prefix('kiri').inputAction(updateSettings),
|
||||||
MODE = MODES.FDM,
|
MODE = MODES.FDM,
|
||||||
STACKS = kiri.stacks,
|
STACKS = kiri.stacks,
|
||||||
DRIVER = undefined,
|
DRIVER = undefined,
|
||||||
complete = {},
|
complete = {},
|
||||||
// selectedMeshes = [],
|
|
||||||
localFilterKey ='kiri-gcode-filters',
|
localFilterKey ='kiri-gcode-filters',
|
||||||
localFilters = js2o(SDB.getItem(localFilterKey)) || [],
|
localFilters = js2o(SDB.getItem(localFilterKey)) || [],
|
||||||
// ---------------
|
|
||||||
viewMode = VIEWS.ARRANGE,
|
viewMode = VIEWS.ARRANGE,
|
||||||
local = SETUP.local,
|
local = SETUP.local,
|
||||||
busy = 0,
|
busy = 0,
|
||||||
|
|
@ -208,67 +203,32 @@
|
||||||
unit_scale: unitScale,
|
unit_scale: unitScale,
|
||||||
wireframe: setWireframe,
|
wireframe: setWireframe,
|
||||||
},
|
},
|
||||||
widgets: {
|
|
||||||
new: newWidget,
|
|
||||||
all() { return WIDGETS.slice() },
|
|
||||||
add(widget) { WIDGETS.push(widget) },
|
|
||||||
remove(widget) { return WIDGETS.remove(widget) },
|
|
||||||
filter(fn) { WIDGETS = WIDGETS.filter(fn) },
|
|
||||||
count() { return WIDGETS.length },
|
|
||||||
heal: healWidgets,
|
|
||||||
for: forAllWidgets,
|
|
||||||
each: forAllWidgets,
|
|
||||||
load: Widget.loadFromCatalog,
|
|
||||||
replace: replaceVertices,
|
|
||||||
meshes: meshArray,
|
|
||||||
opacity: setOpacity,
|
|
||||||
annotate(id) {
|
|
||||||
let w = WIDGETS.filter(w => w.id === id)[0];
|
|
||||||
if (!w) {
|
|
||||||
console.trace(`annotate missing widget ${id}`);
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
return (w.anno = w.anno || {});
|
|
||||||
},
|
|
||||||
map() {
|
|
||||||
let map = {};
|
|
||||||
for (let widget of WIDGETS) {
|
|
||||||
map[widget.id] = widget;
|
|
||||||
}
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
work: kiri.work
|
work: kiri.work
|
||||||
});
|
});
|
||||||
|
|
||||||
function setOpacity(value) {
|
function setFocus(sel, point) {
|
||||||
api.widgets.each(w => w.setOpacity(value));
|
|
||||||
SPACE.update();
|
|
||||||
}
|
|
||||||
|
|
||||||
function setFocus(widgets, point) {
|
|
||||||
if (point) {
|
if (point) {
|
||||||
SPACE.platform.setCenter(point.x, point.z, point.y);
|
SPACE.platform.setCenter(point.x, point.z, point.y);
|
||||||
SPACE.view.setFocus(new THREE.Vector3(point.x, point.y, point.z));
|
SPACE.view.setFocus(new THREE.Vector3(point.x, point.y, point.z));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (widgets === undefined) {
|
if (sel === undefined) {
|
||||||
widgets = WIDGETS;
|
sel = api.widgets.all();
|
||||||
} else if (!Array.isArray) {
|
} else if (!Array.isArray) {
|
||||||
widgets = [ widgets ];
|
sel = [ sel ];
|
||||||
} else if (widgets.length === 0) {
|
} else if (sel.length === 0) {
|
||||||
widgets = WIDGETS;
|
sel = api.widgets.all();
|
||||||
}
|
}
|
||||||
let pos = { x:0, y:0, z:0 };
|
let pos = { x:0, y:0, z:0 };
|
||||||
for (let widget of widgets) {
|
for (let widget of sel) {
|
||||||
pos.x += widget.track.pos.x;
|
pos.x += widget.track.pos.x;
|
||||||
pos.y += widget.track.pos.y;
|
pos.y += widget.track.pos.y;
|
||||||
pos.z += widget.track.pos.z;
|
pos.z += widget.track.pos.z;
|
||||||
}
|
}
|
||||||
if (widgets.length) {
|
if (sel.length) {
|
||||||
pos.x /= widgets.length;
|
pos.x /= sel.length;
|
||||||
pos.y /= widgets.length;
|
pos.y /= sel.length;
|
||||||
pos.z /= widgets.length;
|
pos.z /= sel.length;
|
||||||
}
|
}
|
||||||
SPACE.platform.setCenter(pos.x, -pos.y, platform.top_z() / 2);
|
SPACE.platform.setCenter(pos.x, -pos.y, platform.top_z() / 2);
|
||||||
SPACE.view.setFocus(new THREE.Vector3(pos.x, platform.top_z() / 2, -pos.y));
|
SPACE.view.setFocus(new THREE.Vector3(pos.x, platform.top_z() / 2, -pos.y));
|
||||||
|
|
@ -719,77 +679,8 @@
|
||||||
showSlices();
|
showSlices();
|
||||||
}
|
}
|
||||||
|
|
||||||
function meshArray() {
|
|
||||||
let out = [];
|
|
||||||
forAllWidgets(function(widget) {
|
|
||||||
if (!feature.hoverAdds) {
|
|
||||||
out.push(widget.mesh);
|
|
||||||
}
|
|
||||||
out.appendAll(widget.adds);
|
|
||||||
});
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
function replaceVertices(vertices) {
|
|
||||||
let widgets = selection.widgets(true);
|
|
||||||
if (!widgets.length) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
function onload(vertices) {
|
|
||||||
for (let w of widgets) {
|
|
||||||
let track = Object.clone(w.track);
|
|
||||||
let { scale, rot, pos } = track;
|
|
||||||
let roto = w.roto.slice();
|
|
||||||
w.loadVertices(vertices);
|
|
||||||
for (let m of roto) {
|
|
||||||
w.mesh.geometry.applyMatrix4(m.clone());
|
|
||||||
}
|
|
||||||
w._scale(scale.x, scale.y, scale.z);
|
|
||||||
}
|
|
||||||
platform.update();
|
|
||||||
}
|
|
||||||
if (vertices) {
|
|
||||||
onload(vertices);
|
|
||||||
} else {
|
|
||||||
// dialog
|
|
||||||
$('load-file').onchange = function(event) {
|
|
||||||
load.File.load(event.target.files[0])
|
|
||||||
.then(data => onload(data[0].mesh))
|
|
||||||
.catch(error => console.log({error}));
|
|
||||||
};
|
|
||||||
$('load-file').click();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function healWidgets() {
|
|
||||||
let widgets = api.widgets.all();
|
|
||||||
let marker;
|
|
||||||
if (widgets.length) {
|
|
||||||
marker = api.show.alert("Analyzing objects", 100000);
|
|
||||||
} else {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
setTimeout(() => {
|
|
||||||
Promise.all(widgets.map(w => w.heal())).then(mod => {
|
|
||||||
api.hide.alert(marker);
|
|
||||||
let healed = mod.filter(m => m).length;
|
|
||||||
if (healed) {
|
|
||||||
api.show.alert(`${healed} Object${healed ? 's':''} healed`);
|
|
||||||
} else {
|
|
||||||
api.show.alert('Nothing found to heal');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
function forAllWidgets(f) {
|
|
||||||
WIDGETS.slice().forEach(function(widget) {
|
|
||||||
f(widget);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function setWireframe(bool, color, opacity) {
|
function setWireframe(bool, color, opacity) {
|
||||||
forAllWidgets(function(w) { w.setWireframe(bool, color, opacity) });
|
api.widgets.each(function(w) { w.setWireframe(bool, color, opacity) });
|
||||||
SPACE.update();
|
SPACE.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -805,14 +696,14 @@
|
||||||
|
|
||||||
function hideSlices() {
|
function hideSlices() {
|
||||||
STACKS.clear();
|
STACKS.clear();
|
||||||
setOpacity(COLOR.model_opacity);
|
api.widgets.opacity(COLOR.model_opacity);
|
||||||
forAllWidgets(function(widget) {
|
api.widgets.each(function(widget) {
|
||||||
widget.setWireframe(false);
|
widget.setWireframe(false);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function setWidgetVisibility(bool) {
|
function setWidgetVisibility(bool) {
|
||||||
forAllWidgets(w => {
|
api.widgets.each(w => {
|
||||||
if (bool) {
|
if (bool) {
|
||||||
w.show();
|
w.show();
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -882,6 +773,8 @@
|
||||||
callback = preparePreview;
|
callback = preparePreview;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const WIDGETS = api.widgets.all();
|
||||||
|
|
||||||
// force layout in belt mode when widget exceeds bed length
|
// force layout in belt mode when widget exceeds bed length
|
||||||
if (WIDGETS.length && settings.device.bedBelt) {
|
if (WIDGETS.length && settings.device.bedBelt) {
|
||||||
let doLayout = false;
|
let doLayout = false;
|
||||||
|
|
@ -925,7 +818,7 @@
|
||||||
}
|
}
|
||||||
let defvert = totvert / slicing.length;
|
let defvert = totvert / slicing.length;
|
||||||
|
|
||||||
setOpacity(COLOR.slicing_opacity);
|
api.widgets.opacity(COLOR.slicing_opacity);
|
||||||
|
|
||||||
let segtimes = {},
|
let segtimes = {},
|
||||||
segNumber = 0,
|
segNumber = 0,
|
||||||
|
|
@ -1039,7 +932,7 @@
|
||||||
if (scale === 1) {
|
if (scale === 1) {
|
||||||
// clear wireframe
|
// clear wireframe
|
||||||
widget.setWireframe(false, COLOR.wireframe, COLOR.wireframe_opacity);
|
widget.setWireframe(false, COLOR.wireframe, COLOR.wireframe_opacity);
|
||||||
widget.setOpacity(camOrLaser ? COLOR.cam_sliced_opacity : COLOR.sliced_opacity);
|
widget.setOacity(camOrLaser ? COLOR.cam_sliced_opacity : COLOR.sliced_opacity);
|
||||||
widget.setColor(COLOR.deselected);
|
widget.setColor(COLOR.deselected);
|
||||||
api.hide.alert(alert);
|
api.hide.alert(alert);
|
||||||
}
|
}
|
||||||
|
|
@ -1098,12 +991,12 @@
|
||||||
api.event.emit('preview.begin', pMode);
|
api.event.emit('preview.begin', pMode);
|
||||||
|
|
||||||
if (isCam) {
|
if (isCam) {
|
||||||
setOpacity(COLOR.cam_preview_opacity);
|
api.widgets.opacity(COLOR.cam_preview_opacity);
|
||||||
forAllWidgets(function(widget) {
|
api.widgets.each(function(widget) {
|
||||||
widget.setColor(COLOR.cam_preview);
|
widget.setColor(COLOR.cam_preview);
|
||||||
});
|
});
|
||||||
} else if (offset === 0) {
|
} else if (offset === 0) {
|
||||||
setOpacity(COLOR.preview_opacity);
|
api.widgets.opacity(COLOR.preview_opacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
let now = Date.now(),
|
let now = Date.now(),
|
||||||
|
|
@ -1147,7 +1040,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
api.show.progress(0);
|
api.show.progress(0);
|
||||||
if (!isCam) setOpacity(0);
|
if (!isCam) api.widgets.opacity(0);
|
||||||
|
|
||||||
if (output.length) {
|
if (output.length) {
|
||||||
let alert = feature.work_alerts ? api.show.alert("Rendering") : null;
|
let alert = feature.work_alerts ? api.show.alert("Rendering") : null;
|
||||||
|
|
@ -1227,7 +1120,7 @@
|
||||||
function loadCode(code, type) {
|
function loadCode(code, type) {
|
||||||
api.event.emit("code.load", {code, type});
|
api.event.emit("code.load", {code, type});
|
||||||
setViewMode(VIEWS.PREVIEW);
|
setViewMode(VIEWS.PREVIEW);
|
||||||
setOpacity(0);
|
api.widgets.opacity(0);
|
||||||
kiri.client.parse({code, type, settings}, progress => {
|
kiri.client.parse({code, type, settings}, progress => {
|
||||||
api.show.progress(progress, "parsing");
|
api.show.progress(progress, "parsing");
|
||||||
}, (layers, maxSpeed, minSpeed) => {
|
}, (layers, maxSpeed, minSpeed) => {
|
||||||
|
|
@ -1726,6 +1619,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function settingsExport(opts = {}) {
|
function settingsExport(opts = {}) {
|
||||||
|
const WIDGETS = api.widgets.all();
|
||||||
const note = opts.node || undefined;
|
const note = opts.node || undefined;
|
||||||
const shot = opts.work || opts.screen ? SPACE.screenshot() : undefined;
|
const shot = opts.work || opts.screen ? SPACE.screenshot() : undefined;
|
||||||
const work = opts.work ? kiri.codec.encode(WIDGETS,{_json_:true}) : undefined;
|
const work = opts.work ? kiri.codec.encode(WIDGETS,{_json_:true}) : undefined;
|
||||||
|
|
@ -1782,7 +1676,7 @@
|
||||||
api.conf.save();
|
api.conf.save();
|
||||||
const newWidgets = [];
|
const newWidgets = [];
|
||||||
const oldWidgets = js2o(SDB.getItem('ws-widgets'), []);
|
const oldWidgets = js2o(SDB.getItem('ws-widgets'), []);
|
||||||
forAllWidgets(function(widget) {
|
api.widgets.each(function(widget) {
|
||||||
if (widget.synth) return;
|
if (widget.synth) return;
|
||||||
newWidgets.push(widget.id);
|
newWidgets.push(widget.id);
|
||||||
oldWidgets.remove(widget.id);
|
oldWidgets.remove(widget.id);
|
||||||
|
|
@ -1803,7 +1697,8 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function restoreSettings(save) {
|
function restoreSettings(save) {
|
||||||
let newset = ls2o('ws-settings') || settings;
|
const WIDGETS = api.widgets.all();
|
||||||
|
const newset = ls2o('ws-settings') || settings;
|
||||||
// extract legacy widget annotations into widgets
|
// extract legacy widget annotations into widgets
|
||||||
if (newset.widget) {
|
if (newset.widget) {
|
||||||
for (let id of Object.keys(newset.widget)) {
|
for (let id of Object.keys(newset.widget)) {
|
||||||
|
|
@ -1862,7 +1757,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove any widgets from platform
|
// remove any widgets from platform
|
||||||
forAllWidgets(function(widget) {
|
api.widgets.each(function(widget) {
|
||||||
platform.delete(widget);
|
platform.delete(widget);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -2165,7 +2060,7 @@
|
||||||
updateSpeeds();
|
updateSpeeds();
|
||||||
setVisibleLayer();
|
setVisibleLayer();
|
||||||
setWidgetVisibility(true);
|
setWidgetVisibility(true);
|
||||||
setOpacity(1);
|
api.widgets.opacity(1);
|
||||||
break;
|
break;
|
||||||
case VIEWS.SLICE:
|
case VIEWS.SLICE:
|
||||||
UI.back.style.display = 'flex';
|
UI.back.style.display = 'flex';
|
||||||
|
|
@ -2235,7 +2130,7 @@
|
||||||
// other housekeeping
|
// other housekeeping
|
||||||
triggerSettingsEvent();
|
triggerSettingsEvent();
|
||||||
platform.update_selected();
|
platform.update_selected();
|
||||||
selection.update_bounds(WIDGETS);
|
selection.update_bounds(api.widgets.all());
|
||||||
updateFields();
|
updateFields();
|
||||||
// because device dialog, if showing, needs to be updated
|
// because device dialog, if showing, needs to be updated
|
||||||
if (modalShowing()) {
|
if (modalShowing()) {
|
||||||
|
|
|
||||||
113
src/kiri/widgets.js
Normal file
113
src/kiri/widgets.js
Normal file
|
|
@ -0,0 +1,113 @@
|
||||||
|
/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
(function () {
|
||||||
|
|
||||||
|
const { data, kiri, moto, noop } = self;
|
||||||
|
const { api, consts, utils, newWidget, Widget } = kiri;
|
||||||
|
const { space } = moto;
|
||||||
|
|
||||||
|
let WIDGETS = [];
|
||||||
|
|
||||||
|
function map() {
|
||||||
|
let map = {};
|
||||||
|
for (let widget of WIDGETS) {
|
||||||
|
map[widget.id] = widget;
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
function annotate(id) {
|
||||||
|
let w = WIDGETS.filter(w => w.id === id)[0];
|
||||||
|
if (!w) {
|
||||||
|
console.trace(`annotate missing widget ${id}`);
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
return (w.anno = w.anno || {});
|
||||||
|
}
|
||||||
|
|
||||||
|
function replace(vertices) {
|
||||||
|
let widgets = selection.widgets(true);
|
||||||
|
if (!widgets.length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
function onload(vertices) {
|
||||||
|
for (let w of widgets) {
|
||||||
|
let track = Object.clone(w.track);
|
||||||
|
let { scale, rot, pos } = track;
|
||||||
|
let roto = w.roto.slice();
|
||||||
|
w.loadVertices(vertices);
|
||||||
|
for (let m of roto) {
|
||||||
|
w.mesh.geometry.applyMatrix4(m.clone());
|
||||||
|
}
|
||||||
|
w._scale(scale.x, scale.y, scale.z);
|
||||||
|
}
|
||||||
|
platform.update();
|
||||||
|
}
|
||||||
|
if (vertices) {
|
||||||
|
onload(vertices);
|
||||||
|
} else {
|
||||||
|
// dialog
|
||||||
|
$('load-file').onchange = function(event) {
|
||||||
|
load.File.load(event.target.files[0])
|
||||||
|
.then(data => onload(data[0].mesh))
|
||||||
|
.catch(error => console.log({error}));
|
||||||
|
};
|
||||||
|
$('load-file').click();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function heal() {
|
||||||
|
if (!WIDGETS.length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let marker = api.show.alert("Analyzing objects", 100000);
|
||||||
|
setTimeout(() => {
|
||||||
|
Promise.all(WIDGETS.map(w => w.heal())).then(mod => {
|
||||||
|
api.hide.alert(marker);
|
||||||
|
let healed = mod.filter(m => m).length;
|
||||||
|
if (healed) {
|
||||||
|
api.show.alert(`${healed} Object${healed ? 's':''} healed`);
|
||||||
|
} else {
|
||||||
|
api.show.alert('Nothing found to heal');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
function meshes() {
|
||||||
|
let out = [];
|
||||||
|
widgets.each(widget => {
|
||||||
|
if (!api.feature.hoverAdds) {
|
||||||
|
out.push(widget.mesh);
|
||||||
|
}
|
||||||
|
out.appendAll(widget.adds);
|
||||||
|
});
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
function opacity(value) {
|
||||||
|
api.widgets.each(w => w.setOpacity(value));
|
||||||
|
space.update();
|
||||||
|
}
|
||||||
|
|
||||||
|
const widgets = api.widgets = {
|
||||||
|
load: Widget.loadFromCatalog,
|
||||||
|
new: newWidget,
|
||||||
|
map,
|
||||||
|
heal,
|
||||||
|
meshes,
|
||||||
|
replace,
|
||||||
|
opacity,
|
||||||
|
annotate,
|
||||||
|
all() { return WIDGETS.slice() },
|
||||||
|
add(w) { return WIDGETS.push(w) },
|
||||||
|
remove(w) { return WIDGETS.remove(w) },
|
||||||
|
filter(fn) { return WIDGETS = WIDGETS.filter(fn) },
|
||||||
|
count() { return WIDGETS.length },
|
||||||
|
each(fn) { WIDGETS.slice().forEach(widget => fn(widget)) },
|
||||||
|
for(fn) { widgets.each(fn) },
|
||||||
|
};
|
||||||
|
|
||||||
|
})();
|
||||||
Loading…
Reference in a new issue