extract functions from main
This commit is contained in:
parent
2230787b93
commit
0b997bb8e2
3 changed files with 432 additions and 417 deletions
1
app.js
1
app.js
|
|
@ -369,6 +369,7 @@ const script = {
|
||||||
"kiri/widgets",
|
"kiri/widgets",
|
||||||
"kiri/platform",
|
"kiri/platform",
|
||||||
"kiri/selection",
|
"kiri/selection",
|
||||||
|
"kiri/function",
|
||||||
"kiri/codec",
|
"kiri/codec",
|
||||||
"kiri/conf",
|
"kiri/conf",
|
||||||
"kiri/main",
|
"kiri/main",
|
||||||
|
|
|
||||||
421
src/kiri/function.js
Normal file
421
src/kiri/function.js
Normal file
|
|
@ -0,0 +1,421 @@
|
||||||
|
/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
(function () {
|
||||||
|
|
||||||
|
const { data, kiri, noop } = self;
|
||||||
|
const { api, client, consts, utils } = kiri;
|
||||||
|
const { space } = moto;
|
||||||
|
const { COLOR, PMODES } = consts;
|
||||||
|
|
||||||
|
let complete = {};
|
||||||
|
|
||||||
|
function prepareSlices(callback, scale = 1, offset = 0) {
|
||||||
|
const { conf, event, feature, hide, mode, view, platform, show } = api;
|
||||||
|
const { stacks } = kiri;
|
||||||
|
|
||||||
|
if (view.is_arrange()) {
|
||||||
|
let snap = space.screenshot();
|
||||||
|
view.snapshot = snap.substring(snap.indexOf(",") + 1);
|
||||||
|
client.snap(space.screenshot2({width: 640}));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mode.is_sla() && !callback) {
|
||||||
|
callback = preparePreview;
|
||||||
|
}
|
||||||
|
|
||||||
|
const widgets = api.widgets.all();
|
||||||
|
const settings = conf.get();
|
||||||
|
const { device, process, controller } = settings;
|
||||||
|
const isBelt = device.bedBelt || false;
|
||||||
|
const mark = Date.now();
|
||||||
|
|
||||||
|
// force layout in belt mode when widget exceeds bed length
|
||||||
|
if (widgets.length && isBelt) {
|
||||||
|
let doLayout = false;
|
||||||
|
for (let w of widgets) {
|
||||||
|
let bb = w.getBoundingBox();
|
||||||
|
let yspan = bb.max.y - bb.min.y;
|
||||||
|
if (yspan > device.bedDepth) {
|
||||||
|
doLayout = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (doLayout) {
|
||||||
|
platform.layout();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// clear completion marks
|
||||||
|
complete = {};
|
||||||
|
|
||||||
|
platform.deselect();
|
||||||
|
hide.slider();
|
||||||
|
view.set_slice();
|
||||||
|
conf.save();
|
||||||
|
|
||||||
|
event.emit('slice.begin', settings.mode);
|
||||||
|
|
||||||
|
const slicing = widgets
|
||||||
|
.slice()
|
||||||
|
.filter(w => !w.track.ignore && !w.meta.disabled);
|
||||||
|
const totalv = slicing.map(w => w.getVertices().count).reduce((a,v) => a + v);
|
||||||
|
const defvert = totalv / slicing.length;
|
||||||
|
const track = {};
|
||||||
|
|
||||||
|
let totalProgress;
|
||||||
|
|
||||||
|
api.widgets.opacity(COLOR.slicing_opacity);
|
||||||
|
|
||||||
|
let segtimes = {},
|
||||||
|
segNumber = 0,
|
||||||
|
errored = false,
|
||||||
|
startTime = Date.now(),
|
||||||
|
toSlice = slicing.slice(),
|
||||||
|
camOrLaser = mode.is_cam() || mode.is_laser(),
|
||||||
|
extruders = {},
|
||||||
|
lastMsg;
|
||||||
|
|
||||||
|
for (let widget of toSlice) {
|
||||||
|
widget.stats.progress = 0;
|
||||||
|
widget.setColor(COLOR.slicing);
|
||||||
|
extruders[widget.anno.extruder] = widget.anno.extruder;
|
||||||
|
}
|
||||||
|
|
||||||
|
// in multi-material belt mode, the anchor needs to be extended
|
||||||
|
// to allow room for the purge tower to be built. calculate here
|
||||||
|
extruders = Object.values(extruders);
|
||||||
|
if (isBelt && extruders.length > 1 && process.outputPurgeTower) {
|
||||||
|
process.beltAnchor = Math.max(
|
||||||
|
process.firstLayerBeltLead,
|
||||||
|
Math.sqrt(process.outputPurgeTower) * extruders.length * (1/Math.sqrt(2)));
|
||||||
|
} else {
|
||||||
|
process.beltAnchor = process.firstLayerBeltLead;
|
||||||
|
}
|
||||||
|
|
||||||
|
stacks.clear();
|
||||||
|
if (isBelt) {
|
||||||
|
// force re-sync in belt mode
|
||||||
|
client.clear();
|
||||||
|
}
|
||||||
|
client.sync();
|
||||||
|
client.rotate(settings);
|
||||||
|
|
||||||
|
function sliceNext() {
|
||||||
|
if (toSlice.length) {
|
||||||
|
// while more widgets to slice
|
||||||
|
sliceWidget(toSlice.shift())
|
||||||
|
} else {
|
||||||
|
// once all slicing done, run sliceAll() once
|
||||||
|
client.sliceAll(settings, sliceDone);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function sliceWidget(widget) {
|
||||||
|
widget.stack = stacks.create(widget.id, widget.mesh);
|
||||||
|
let factor = (widget.getVertices().count / defvert);
|
||||||
|
|
||||||
|
// compensate for zcut (widget moved through floor)
|
||||||
|
widget.stack.obj.view.position.z = widget.track.zcut || 0;
|
||||||
|
|
||||||
|
widget.slice(settings, (sliced, error) => {
|
||||||
|
widget.rotinfo = null;
|
||||||
|
let mark = Date.now();
|
||||||
|
// update UI info
|
||||||
|
if (sliced) {
|
||||||
|
// update segment time
|
||||||
|
if (lastMsg) {
|
||||||
|
segtimes[`${widget.id}_${segNumber++}_${lastMsg}`] = mark - startTime;
|
||||||
|
}
|
||||||
|
event.emit('slice', settings.mode);
|
||||||
|
}
|
||||||
|
// handle slicing errors
|
||||||
|
if (error && !errored) {
|
||||||
|
errored = true;
|
||||||
|
view.set_arrange();
|
||||||
|
show.alert(error, 5);
|
||||||
|
show.progress(0);
|
||||||
|
client.restart();
|
||||||
|
event.emit('slice.error', error);
|
||||||
|
}
|
||||||
|
if (errored) {
|
||||||
|
// terminate slicing
|
||||||
|
sliceDone();
|
||||||
|
} else {
|
||||||
|
// start next widget slice
|
||||||
|
sliceNext();
|
||||||
|
}
|
||||||
|
}, (update, msg) => {
|
||||||
|
if (msg && msg !== lastMsg) {
|
||||||
|
let mark = Date.now();
|
||||||
|
if (lastMsg) {
|
||||||
|
segtimes[`${widget.id}_${segNumber++}_${lastMsg}`] = mark - startTime;
|
||||||
|
}
|
||||||
|
lastMsg = msg;
|
||||||
|
startTime = mark;
|
||||||
|
}
|
||||||
|
// on update
|
||||||
|
track[widget.id] = (update || 0) * factor;
|
||||||
|
totalProgress = 0;
|
||||||
|
for (let w of slicing) {
|
||||||
|
totalProgress += (track[w.id] || 0);
|
||||||
|
}
|
||||||
|
show.progress(offset + (totalProgress / widgets.length) * scale, msg);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function sliceDone() {
|
||||||
|
let alert = null;
|
||||||
|
if (scale === 1 && feature.work_alerts && slicing.length) {
|
||||||
|
alert = show.alert("Rendering");
|
||||||
|
};
|
||||||
|
client.unrotate(settings, () => {
|
||||||
|
for (let widget of slicing) {
|
||||||
|
// on done
|
||||||
|
segtimes[`${widget.id}_${segNumber++}_draw`] = widget.render(widget.stack);
|
||||||
|
// rotate stack for belt beds
|
||||||
|
if (widget.rotinfo) {
|
||||||
|
widget.stack.obj.rotate(widget.rotinfo);
|
||||||
|
}
|
||||||
|
if (scale === 1) {
|
||||||
|
// clear wireframe
|
||||||
|
widget.setWireframe(false, COLOR.wireframe, COLOR.wireframe_opacity);
|
||||||
|
widget.setOpacity(camOrLaser ? COLOR.cam_sliced_opacity : COLOR.sliced_opacity);
|
||||||
|
widget.setColor(COLOR.deselected);
|
||||||
|
api.hide.alert(alert);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
view.update_slider_max(true);
|
||||||
|
show.layer(-1, 0);
|
||||||
|
if (scale === 1) {
|
||||||
|
updateStackLabelState();
|
||||||
|
}
|
||||||
|
if (!isBelt && controller.lineType === 'line' && !process.xray) {
|
||||||
|
$('render-ghost').onclick();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (scale === 1) {
|
||||||
|
show.progress(0);
|
||||||
|
}
|
||||||
|
// cause visuals to update
|
||||||
|
space.scene.active();
|
||||||
|
// mark slicing complete for prep/preview
|
||||||
|
complete.slice = true;
|
||||||
|
event.emit('slice.end', settings.mode);
|
||||||
|
// print stats
|
||||||
|
segtimes.total = Date.now() - mark;
|
||||||
|
console.log(segtimes);
|
||||||
|
if (callback && typeof callback === 'function') {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// kick of slicing chain
|
||||||
|
sliceNext();
|
||||||
|
}
|
||||||
|
|
||||||
|
function preparePreview(callback, scale = 1, offset = 0) {
|
||||||
|
const { conf, event, feature, hide, mode, view, platform, show } = api;
|
||||||
|
const { stacks } = kiri;
|
||||||
|
|
||||||
|
const widgets = api.widgets.all();
|
||||||
|
const settings = conf.get();
|
||||||
|
const { device, process, controller } = settings;
|
||||||
|
|
||||||
|
if (complete.preview === feature.pmode) {
|
||||||
|
if (device.extruders.length > 1) {
|
||||||
|
if (++feature.pmode > 2) {
|
||||||
|
feature.pmode = 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (callback) {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!complete.slice) {
|
||||||
|
settings.render = false;
|
||||||
|
prepareSlices(() => { preparePreview(callback, 0.25, 0.75) }, 0.75);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
hide.slider(true);
|
||||||
|
|
||||||
|
const isCam = mode.is_cam(), pMode = settings.mode;
|
||||||
|
const isBelt = device.bedBelt || false;
|
||||||
|
|
||||||
|
view.set_preview();
|
||||||
|
conf.save();
|
||||||
|
event.emit('preview.begin', pMode);
|
||||||
|
|
||||||
|
if (isCam) {
|
||||||
|
api.widgets.opacity(COLOR.cam_preview_opacity);
|
||||||
|
api.widgets.each(widget => {
|
||||||
|
widget.setColor(COLOR.cam_preview);
|
||||||
|
});
|
||||||
|
} else if (offset === 0) {
|
||||||
|
api.widgets.opacity(COLOR.preview_opacity);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mark = Date.now(),
|
||||||
|
segNumber = 0,
|
||||||
|
segtimes = {},
|
||||||
|
startTime,
|
||||||
|
lastMsg,
|
||||||
|
output = [];
|
||||||
|
|
||||||
|
// pass preview mode to worker
|
||||||
|
settings.pmode = feature.pmode;
|
||||||
|
settings.render = true;
|
||||||
|
|
||||||
|
client.prepare(settings, (progress, message, layer) => {
|
||||||
|
if (layer) {
|
||||||
|
output.push(kiri.codec.decode(layer));
|
||||||
|
}
|
||||||
|
if (message && message !== lastMsg) {
|
||||||
|
const mark = Date.now();
|
||||||
|
if (lastMsg) {
|
||||||
|
segtimes[`${segNumber++}_${lastMsg}`] = mark - startTime;
|
||||||
|
}
|
||||||
|
lastMsg = message;
|
||||||
|
startTime = mark;
|
||||||
|
}
|
||||||
|
show.progress(offset + progress * scale, message);
|
||||||
|
}, (reply, maxSpeed, minSpeed) => {
|
||||||
|
// handle worker errors
|
||||||
|
if (reply && reply.error) {
|
||||||
|
show.alert(reply.error, 5);
|
||||||
|
view.set_arrange();
|
||||||
|
show.progress(0);
|
||||||
|
space.update();
|
||||||
|
event.emit('preview.error', reply.error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lastMsg) {
|
||||||
|
segtimes[`${segNumber++}_${lastMsg}`] = Date.now() - startTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
show.progress(0);
|
||||||
|
if (!isCam) {
|
||||||
|
api.widgets.opacity(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (output.length) {
|
||||||
|
let alert = feature.work_alerts ? show.alert("Rendering") : null;
|
||||||
|
startTime = Date.now();
|
||||||
|
stacks.clear();
|
||||||
|
const stack = stacks.create('print', space.world)
|
||||||
|
output.forEach(layer => {
|
||||||
|
stack.add(layer);
|
||||||
|
});
|
||||||
|
// rotate stack for belt beds
|
||||||
|
if (isBelt && widgets[0].rotinfo) {
|
||||||
|
let ri = widgets[0].rotinfo;
|
||||||
|
ri.dz = 0;
|
||||||
|
ri.dy = settings.device.bedDepth / 2;
|
||||||
|
stack.obj.rotate(widgets[0].rotinfo);
|
||||||
|
}
|
||||||
|
api.hide.alert(alert);
|
||||||
|
segtimes[`${segNumber}_draw`] = Date.now() - startTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
// print stats
|
||||||
|
segtimes.total = Date.now() - mark;
|
||||||
|
console.log(segtimes);
|
||||||
|
|
||||||
|
event.emit('print', pMode);
|
||||||
|
event.emit('preview.end', pMode);
|
||||||
|
|
||||||
|
space.update();
|
||||||
|
view.update_slider_max(true);
|
||||||
|
show.layer(-1, 0);
|
||||||
|
if (feature.pmode === PMODES.SPEED) {
|
||||||
|
view.update_speeds(maxSpeed, minSpeed);
|
||||||
|
} else {
|
||||||
|
view.update_speeds();
|
||||||
|
}
|
||||||
|
updateStackLabelState();
|
||||||
|
|
||||||
|
let { controller, process } = settings;
|
||||||
|
if (!isBelt && controller.lineType === 'line' && !process.xray) {
|
||||||
|
$('render-ghost').onclick();
|
||||||
|
}
|
||||||
|
|
||||||
|
// mark preview complete for export
|
||||||
|
complete.preview = feature.pmode;
|
||||||
|
|
||||||
|
if (typeof(callback) === 'function') {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function prepareAnimation() {
|
||||||
|
api.event.emit("function.animate", {mode: settings.mode});
|
||||||
|
}
|
||||||
|
|
||||||
|
function prepareExport() {
|
||||||
|
const argsave = arguments;
|
||||||
|
if (!complete.preview) {
|
||||||
|
preparePreview(() => { prepareExport(...argsave) });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
api.event.emit("function.export", {mode: settings.mode});
|
||||||
|
complete.export = true;
|
||||||
|
kiri.export(...argsave);
|
||||||
|
}
|
||||||
|
|
||||||
|
function cancelWorker() {
|
||||||
|
if (client.isBusy()) {
|
||||||
|
client.restart();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadCode(code, type) {
|
||||||
|
const { event, show, widgets, view } = api;
|
||||||
|
const { stacks } = kiri;
|
||||||
|
event.emit("code.load", {code, type});
|
||||||
|
view.set_preview();
|
||||||
|
widgets.opacity(0);
|
||||||
|
client.parse({code, type, settings}, progress => {
|
||||||
|
show.progress(progress, "parsing");
|
||||||
|
}, (layers, maxSpeed, minSpeed) => {
|
||||||
|
show.progress(0);
|
||||||
|
stacks.clear();
|
||||||
|
const stack = stacks.create('parse', space.world);
|
||||||
|
layers.forEach(layer => stack.add(layer));
|
||||||
|
view.update_slider_max(true);
|
||||||
|
view.update_speeds(maxSpeed, minSpeed);
|
||||||
|
show.slices();
|
||||||
|
updateStackLabelState();
|
||||||
|
space.update();
|
||||||
|
event.emit("code.loaded", {code, type});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateStackLabelState() {
|
||||||
|
const settings = api.conf.get();
|
||||||
|
const { stacks } = kiri;
|
||||||
|
// match label checkboxes to preference
|
||||||
|
for (let label of stacks.getLabels()) {
|
||||||
|
let check = `${settings.mode}-${api.view.get()}-${label}`;
|
||||||
|
stacks.setVisible(label, settings.labels[check] !== false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
api.function = {
|
||||||
|
slice: prepareSlices,
|
||||||
|
print: preparePreview,
|
||||||
|
prepare: preparePreview,
|
||||||
|
animate: prepareAnimation,
|
||||||
|
export: prepareExport,
|
||||||
|
cancel: cancelWorker,
|
||||||
|
parse: loadCode,
|
||||||
|
clear: client.clear,
|
||||||
|
clear_progress() { complete = {} }
|
||||||
|
};
|
||||||
|
|
||||||
|
})();
|
||||||
427
src/kiri/main.js
427
src/kiri/main.js
|
|
@ -32,7 +32,6 @@
|
||||||
MODE = MODES.FDM,
|
MODE = MODES.FDM,
|
||||||
STACKS = kiri.stacks,
|
STACKS = kiri.stacks,
|
||||||
DRIVER = undefined,
|
DRIVER = undefined,
|
||||||
complete = {},
|
|
||||||
localFilterKey ='kiri-gcode-filters',
|
localFilterKey ='kiri-gcode-filters',
|
||||||
localFilters = js2o(SDB.getItem(localFilterKey)) || [],
|
localFilters = js2o(SDB.getItem(localFilterKey)) || [],
|
||||||
viewMode = VIEWS.ARRANGE,
|
viewMode = VIEWS.ARRANGE,
|
||||||
|
|
@ -105,16 +104,6 @@
|
||||||
alerts: updateAlerts,
|
alerts: updateAlerts,
|
||||||
settings: triggerSettingsEvent
|
settings: triggerSettingsEvent
|
||||||
},
|
},
|
||||||
function: {
|
|
||||||
slice: prepareSlices,
|
|
||||||
print: preparePreview,
|
|
||||||
prepare: preparePreview,
|
|
||||||
animate: prepareAnimation,
|
|
||||||
export: prepareExport,
|
|
||||||
cancel: cancelWorker,
|
|
||||||
clear: kiri.client.clear,
|
|
||||||
parse: loadCode
|
|
||||||
},
|
|
||||||
group: {
|
group: {
|
||||||
merge: groupMerge,
|
merge: groupMerge,
|
||||||
split: groupSplit,
|
split: groupSplit,
|
||||||
|
|
@ -140,7 +129,11 @@
|
||||||
get: getMode,
|
get: getMode,
|
||||||
set: setMode,
|
set: setMode,
|
||||||
switch: switchMode,
|
switch: switchMode,
|
||||||
set_expert: noop
|
set_expert: noop,
|
||||||
|
is_fdm() { return MODE === MODES.FDM },
|
||||||
|
is_cam() { return MODE === MODES.CAM },
|
||||||
|
is_sla() { return MODE === MODES.SLA },
|
||||||
|
is_laser() { return MODE === MODES.LASER },
|
||||||
},
|
},
|
||||||
probe: {
|
probe: {
|
||||||
live: "https://live.grid.space",
|
live: "https://live.grid.space",
|
||||||
|
|
@ -746,397 +739,17 @@
|
||||||
SPACE.update();
|
SPACE.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
function cancelWorker() {
|
|
||||||
if (kiri.work.isBusy()) {
|
|
||||||
kiri.work.restart();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function showSlider() {
|
function showSlider() {
|
||||||
UI.layers.style.display = 'flex';
|
UI.layers.style.display = 'flex';
|
||||||
UI.slider.style.display = 'flex';
|
UI.slider.style.display = 'flex';
|
||||||
}
|
}
|
||||||
|
|
||||||
function hideSlider(andmenu) {
|
function hideSlider() {
|
||||||
UI.layers.style.display = 'none';
|
UI.layers.style.display = 'none';
|
||||||
UI.slider.style.display = 'none';
|
UI.slider.style.display = 'none';
|
||||||
UI.speeds.style.display = 'none';
|
UI.speeds.style.display = 'none';
|
||||||
}
|
}
|
||||||
|
|
||||||
function prepareSlices(callback, scale = 1, offset = 0) {
|
|
||||||
if (viewMode == VIEWS.ARRANGE) {
|
|
||||||
let snap = SPACE.screenshot();
|
|
||||||
api.view.snapshot = snap.substring(snap.indexOf(",") + 1);
|
|
||||||
kiri.work.snap(SPACE.screenshot2({width: 640}));
|
|
||||||
}
|
|
||||||
if (MODE === MODES.SLA && !callback) {
|
|
||||||
callback = preparePreview;
|
|
||||||
}
|
|
||||||
|
|
||||||
const WIDGETS = api.widgets.all();
|
|
||||||
|
|
||||||
// force layout in belt mode when widget exceeds bed length
|
|
||||||
if (WIDGETS.length && settings.device.bedBelt) {
|
|
||||||
let doLayout = false;
|
|
||||||
for (let w of WIDGETS) {
|
|
||||||
let bb = w.getBoundingBox();
|
|
||||||
let yspan = bb.max.y - bb.min.y;
|
|
||||||
if (yspan > settings.device.bedDepth) {
|
|
||||||
doLayout = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (doLayout) {
|
|
||||||
platformLayout();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let process = settings.process,
|
|
||||||
device = settings.device,
|
|
||||||
control = settings.controller,
|
|
||||||
isBelt = device.bedBelt,
|
|
||||||
mode = settings.mode,
|
|
||||||
now = Date.now(),
|
|
||||||
totvert = 0,
|
|
||||||
track = {},
|
|
||||||
totalProgress;
|
|
||||||
|
|
||||||
// clear completion marks
|
|
||||||
complete = {};
|
|
||||||
|
|
||||||
hideSlider(true);
|
|
||||||
platform.deselect();
|
|
||||||
setViewMode(VIEWS.SLICE);
|
|
||||||
|
|
||||||
api.conf.save();
|
|
||||||
api.event.emit('slice.begin', getMode());
|
|
||||||
|
|
||||||
let slicing = WIDGETS.slice().filter(w => !w.track.ignore && !w.meta.disabled);
|
|
||||||
|
|
||||||
// determing this widgets % of processing time estimated by vertex count
|
|
||||||
for (let widget of slicing) {
|
|
||||||
totvert += widget.getVertices().count;
|
|
||||||
}
|
|
||||||
let defvert = totvert / slicing.length;
|
|
||||||
|
|
||||||
api.widgets.opacity(COLOR.slicing_opacity);
|
|
||||||
|
|
||||||
let segtimes = {},
|
|
||||||
segNumber = 0,
|
|
||||||
errored = false,
|
|
||||||
startTime = Date.now(),
|
|
||||||
toSlice = slicing.slice(),
|
|
||||||
camOrLaser = mode === 'CAM' || mode === 'LASER',
|
|
||||||
extruders = {},
|
|
||||||
lastMsg;
|
|
||||||
|
|
||||||
for (let widget of toSlice) {
|
|
||||||
widget.stats.progress = 0;
|
|
||||||
widget.setColor(COLOR.slicing);
|
|
||||||
extruders[widget.anno.extruder] = widget.anno.extruder;
|
|
||||||
}
|
|
||||||
|
|
||||||
// in multi-material belt mode, the anchor needs to be extended
|
|
||||||
// to allow room for the purge tower to be built. calculate here
|
|
||||||
extruders = Object.values(extruders);
|
|
||||||
if (isBelt && extruders.length > 1 && process.outputPurgeTower) {
|
|
||||||
process.beltAnchor = Math.max(
|
|
||||||
process.firstLayerBeltLead,
|
|
||||||
Math.sqrt(process.outputPurgeTower) * extruders.length * (1/Math.sqrt(2)));
|
|
||||||
} else {
|
|
||||||
process.beltAnchor = process.firstLayerBeltLead;
|
|
||||||
}
|
|
||||||
|
|
||||||
STACKS.clear();
|
|
||||||
if (isBelt) {
|
|
||||||
kiri.client.clear();
|
|
||||||
}
|
|
||||||
kiri.client.sync();
|
|
||||||
kiri.client.rotate(settings);
|
|
||||||
|
|
||||||
sliceNext();
|
|
||||||
|
|
||||||
function sliceNext() {
|
|
||||||
if (toSlice.length) {
|
|
||||||
sliceWidget(toSlice.shift())
|
|
||||||
} else {
|
|
||||||
kiri.client.sliceAll(settings, sliceDone);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function sliceWidget(widget) {
|
|
||||||
widget.stack = STACKS.create(widget.id, widget.mesh);
|
|
||||||
let factor = (widget.getVertices().count / defvert);
|
|
||||||
|
|
||||||
// compensate for zcut (widget moved through floor)
|
|
||||||
widget.stack.obj.view.position.z = widget.track.zcut || 0;
|
|
||||||
|
|
||||||
widget.slice(settings, function(sliced, error) {
|
|
||||||
widget.rotinfo = null;
|
|
||||||
let mark = Date.now();
|
|
||||||
// update UI info
|
|
||||||
if (sliced) {
|
|
||||||
// update segment time
|
|
||||||
if (lastMsg) {
|
|
||||||
segtimes[`${widget.id}_${segNumber++}_${lastMsg}`] = mark - startTime;
|
|
||||||
}
|
|
||||||
api.event.emit('slice', getMode());
|
|
||||||
}
|
|
||||||
// handle slicing errors
|
|
||||||
if (error && !errored) {
|
|
||||||
errored = true;
|
|
||||||
setViewMode(VIEWS.ARRANGE);
|
|
||||||
alert2(error, 5);
|
|
||||||
api.show.progress(0);
|
|
||||||
kiri.client.restart();
|
|
||||||
api.event.emit('slice.error', error);
|
|
||||||
}
|
|
||||||
if (errored) {
|
|
||||||
// terminate slicing
|
|
||||||
sliceDone();
|
|
||||||
} else {
|
|
||||||
// start next widget slice
|
|
||||||
sliceNext();
|
|
||||||
}
|
|
||||||
}, function(update, msg) {
|
|
||||||
if (msg && msg !== lastMsg) {
|
|
||||||
let mark = Date.now();
|
|
||||||
if (lastMsg) {
|
|
||||||
segtimes[`${widget.id}_${segNumber++}_${lastMsg}`] = mark - startTime;
|
|
||||||
}
|
|
||||||
lastMsg = msg;
|
|
||||||
startTime = mark;
|
|
||||||
}
|
|
||||||
// on update
|
|
||||||
track[widget.id] = (update || 0) * factor;
|
|
||||||
totalProgress = 0;
|
|
||||||
for (let w of slicing) {
|
|
||||||
totalProgress += (track[w.id] || 0);
|
|
||||||
}
|
|
||||||
api.show.progress(offset + (totalProgress / WIDGETS.length) * scale, msg);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function sliceDone() {
|
|
||||||
let alert = null;
|
|
||||||
if (scale === 1 && feature.work_alerts && slicing.length) {
|
|
||||||
alert = api.show.alert("Rendering");
|
|
||||||
};
|
|
||||||
kiri.client.unrotate(settings, () => {
|
|
||||||
for (let widget of slicing) {
|
|
||||||
// on done
|
|
||||||
segtimes[`${widget.id}_${segNumber++}_draw`] = widget.render(widget.stack);
|
|
||||||
// rotate stack for belt beds
|
|
||||||
if (widget.rotinfo) {
|
|
||||||
widget.stack.obj.rotate(widget.rotinfo);
|
|
||||||
}
|
|
||||||
if (scale === 1) {
|
|
||||||
// clear wireframe
|
|
||||||
widget.setWireframe(false, COLOR.wireframe, COLOR.wireframe_opacity);
|
|
||||||
widget.setOacity(camOrLaser ? COLOR.cam_sliced_opacity : COLOR.sliced_opacity);
|
|
||||||
widget.setColor(COLOR.deselected);
|
|
||||||
api.hide.alert(alert);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
updateSliderMax(true);
|
|
||||||
setVisibleLayer(-1, 0);
|
|
||||||
if (scale === 1) {
|
|
||||||
updateStackLabelState();
|
|
||||||
}
|
|
||||||
if (!isBelt && control.lineType === 'line' && !process.xray) {
|
|
||||||
$('render-ghost').onclick();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (scale === 1) {
|
|
||||||
api.show.progress(0);
|
|
||||||
}
|
|
||||||
// cause visuals to update
|
|
||||||
SPACE.scene.active();
|
|
||||||
// mark slicing complete for prep/preview
|
|
||||||
complete.slice = true;
|
|
||||||
api.event.emit('slice.end', getMode());
|
|
||||||
// print stats
|
|
||||||
segtimes.total = Date.now() - now;
|
|
||||||
console.log(segtimes);
|
|
||||||
if (callback && typeof callback === 'function') {
|
|
||||||
callback();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function preparePreview(callback, scale = 1, offset = 0) {
|
|
||||||
if (complete.preview === feature.pmode) {
|
|
||||||
if (settings.device.extruders.length > 1) {
|
|
||||||
if (++feature.pmode > 2) {
|
|
||||||
feature.pmode = 1;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (callback) callback();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!complete.slice) {
|
|
||||||
settings.render = false;
|
|
||||||
prepareSlices(() => {
|
|
||||||
preparePreview(callback, 0.25, 0.75);
|
|
||||||
}, 0.75);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
hideSlider(true);
|
|
||||||
|
|
||||||
let isCam = MODE === MODES.CAM, pMode = getMode();
|
|
||||||
|
|
||||||
setViewMode(VIEWS.PREVIEW);
|
|
||||||
api.conf.save();
|
|
||||||
api.event.emit('preview.begin', pMode);
|
|
||||||
|
|
||||||
if (isCam) {
|
|
||||||
api.widgets.opacity(COLOR.cam_preview_opacity);
|
|
||||||
api.widgets.each(function(widget) {
|
|
||||||
widget.setColor(COLOR.cam_preview);
|
|
||||||
});
|
|
||||||
} else if (offset === 0) {
|
|
||||||
api.widgets.opacity(COLOR.preview_opacity);
|
|
||||||
}
|
|
||||||
|
|
||||||
let now = Date.now(),
|
|
||||||
isBelt = settings.device.bedBelt,
|
|
||||||
segNumber = 0,
|
|
||||||
segtimes = {},
|
|
||||||
startTime,
|
|
||||||
lastMsg,
|
|
||||||
output = [];
|
|
||||||
|
|
||||||
// pass preview mode to worker
|
|
||||||
settings.pmode = feature.pmode;
|
|
||||||
settings.render = true;
|
|
||||||
|
|
||||||
kiri.client.prepare(settings, function(progress, message, layer) {
|
|
||||||
if (layer) {
|
|
||||||
output.push(kiri.codec.decode(layer));
|
|
||||||
}
|
|
||||||
if (message && message !== lastMsg) {
|
|
||||||
let mark = Date.now();
|
|
||||||
if (lastMsg) {
|
|
||||||
segtimes[`${segNumber++}_${lastMsg}`] = mark - startTime;
|
|
||||||
}
|
|
||||||
lastMsg = message;
|
|
||||||
startTime = mark;
|
|
||||||
}
|
|
||||||
api.show.progress(offset + progress * scale, message);
|
|
||||||
}, function (reply, maxSpeed, minSpeed) {
|
|
||||||
// handle worker errors
|
|
||||||
if (reply && reply.error) {
|
|
||||||
alert2(reply.error, 5);
|
|
||||||
setViewMode(VIEWS.ARRANGE);
|
|
||||||
api.event.emit('preview.error', reply.error);
|
|
||||||
api.show.progress(0);
|
|
||||||
SPACE.update();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lastMsg) {
|
|
||||||
segtimes[`${segNumber++}_${lastMsg}`] = Date.now() - startTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
api.show.progress(0);
|
|
||||||
if (!isCam) api.widgets.opacity(0);
|
|
||||||
|
|
||||||
if (output.length) {
|
|
||||||
let alert = feature.work_alerts ? api.show.alert("Rendering") : null;
|
|
||||||
startTime = Date.now();
|
|
||||||
STACKS.clear();
|
|
||||||
const stack = STACKS.create('print', SPACE.world)
|
|
||||||
output.forEach(layer => {
|
|
||||||
stack.add(layer);
|
|
||||||
});
|
|
||||||
// rotate stack for belt beds
|
|
||||||
if (isBelt && WIDGETS[0].rotinfo) {
|
|
||||||
let ri = WIDGETS[0].rotinfo;
|
|
||||||
ri.dz = 0;
|
|
||||||
ri.dy = settings.device.bedDepth / 2;
|
|
||||||
stack.obj.rotate(WIDGETS[0].rotinfo);
|
|
||||||
}
|
|
||||||
api.hide.alert(alert);
|
|
||||||
segtimes[`${segNumber}_draw`] = Date.now() - startTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
// print stats
|
|
||||||
segtimes.total = Date.now() - now;
|
|
||||||
console.log(segtimes);
|
|
||||||
|
|
||||||
api.event.emit('print', pMode);
|
|
||||||
api.event.emit('preview.end', pMode);
|
|
||||||
|
|
||||||
SPACE.update();
|
|
||||||
updateSliderMax(true);
|
|
||||||
setVisibleLayer(-1, 0);
|
|
||||||
if (feature.pmode === PMODES.SPEED) {
|
|
||||||
updateSpeeds(maxSpeed, minSpeed);
|
|
||||||
} else {
|
|
||||||
updateSpeeds();
|
|
||||||
}
|
|
||||||
updateStackLabelState();
|
|
||||||
|
|
||||||
let { controller, process } = settings;
|
|
||||||
if (!isBelt && controller.lineType === 'line' && !process.xray) {
|
|
||||||
$('render-ghost').onclick();
|
|
||||||
}
|
|
||||||
|
|
||||||
// mark preview complete for export
|
|
||||||
complete.preview = feature.pmode;
|
|
||||||
|
|
||||||
if (typeof(callback) === 'function') {
|
|
||||||
callback();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function prepareAnimation() {
|
|
||||||
api.event.emit("function.animate", {mode: settings.mode});
|
|
||||||
}
|
|
||||||
|
|
||||||
function prepareExport() {
|
|
||||||
const argsave = arguments;
|
|
||||||
if (!complete.preview) {
|
|
||||||
preparePreview(() => {
|
|
||||||
prepareExport(...argsave);
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
api.event.emit("function.export", {mode: settings.mode});
|
|
||||||
complete.export = true;
|
|
||||||
kiri.export(...argsave);
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateStackLabelState() {
|
|
||||||
// match label checkboxes to preference
|
|
||||||
for (let label of STACKS.getLabels()) {
|
|
||||||
let check = `${settings.mode}-${viewMode}-${label}`;
|
|
||||||
STACKS.setVisible(label, settings.labels[check] !== false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function loadCode(code, type) {
|
|
||||||
api.event.emit("code.load", {code, type});
|
|
||||||
setViewMode(VIEWS.PREVIEW);
|
|
||||||
api.widgets.opacity(0);
|
|
||||||
kiri.client.parse({code, type, settings}, progress => {
|
|
||||||
api.show.progress(progress, "parsing");
|
|
||||||
}, (layers, maxSpeed, minSpeed) => {
|
|
||||||
api.show.progress(0);
|
|
||||||
STACKS.clear();
|
|
||||||
const stack = STACKS.create('parse', SPACE.world);
|
|
||||||
layers.forEach(layer => stack.add(layer));
|
|
||||||
updateSliderMax(true);
|
|
||||||
updateSpeeds(maxSpeed, minSpeed);
|
|
||||||
showSlices();
|
|
||||||
updateStackLabelState();
|
|
||||||
SPACE.update();
|
|
||||||
api.event.emit("code.loaded", {code, type});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function loadImageDialog(image, name, force) {
|
function loadImageDialog(image, name, force) {
|
||||||
if (!force && image.byteLength > 2500000) {
|
if (!force && image.byteLength > 2500000) {
|
||||||
return UC.confirm("Large images may fail to import<br>Consider resizing under 1000 x 1000<br>Proceed with import?").then(ok => {
|
return UC.confirm("Large images may fail to import<br>Consider resizing under 1000 x 1000<br>Proceed with import?").then(ok => {
|
||||||
|
|
@ -1178,33 +791,13 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadImage(image, opt = {}) {
|
function loadImage(image, opt = {}) {
|
||||||
let info = Object.assign({settings, png:image}, opt);
|
const info = Object.assign({settings, png:image}, opt);
|
||||||
kiri.client.image2mesh(info, progress => {
|
kiri.client.image2mesh(info, progress => {
|
||||||
api.show.progress(progress, "converting");
|
api.show.progress(progress, "converting");
|
||||||
}, output => {
|
}, output => {
|
||||||
api.show.progress(0);
|
api.show.progress(0);
|
||||||
let {bigv, verts, index} = output;
|
const { bigv, verts, index } = output;
|
||||||
// let mat = new THREE.MeshPhongMaterial({
|
const widget = newWidget().loadVertices(bigv)
|
||||||
// shininess: 0x101010,
|
|
||||||
// specular: 0x101010,
|
|
||||||
// transparent: true,
|
|
||||||
// opacity: 1,
|
|
||||||
// color: 0x999999,
|
|
||||||
// side: THREE.DoubleSide
|
|
||||||
// });
|
|
||||||
//
|
|
||||||
// let geo = new THREE.BufferGeometry();
|
|
||||||
// geo.setAttribute('position', new THREE.BufferAttribute(bigv, 3));
|
|
||||||
// // geo.setIndex([...index]); // doesn't like the Uint32Array
|
|
||||||
// geo.computeFaceNormals();
|
|
||||||
// geo.computeVertexNormals();
|
|
||||||
//
|
|
||||||
// let mesh = new THREE.Mesh(geo, mat);
|
|
||||||
// mesh.castShadow = true;
|
|
||||||
// mesh.receiveShadow = true;
|
|
||||||
//
|
|
||||||
// SPACE.world.add(mesh);
|
|
||||||
let widget = newWidget().loadVertices(bigv)
|
|
||||||
widget.meta.file = opt.file;
|
widget.meta.file = opt.file;
|
||||||
platform.add(widget);
|
platform.add(widget);
|
||||||
});
|
});
|
||||||
|
|
@ -2051,7 +1644,7 @@
|
||||||
$('view-clear').style.display = mode === VIEWS.ARRANGE ? '' : 'none';
|
$('view-clear').style.display = mode === VIEWS.ARRANGE ? '' : 'none';
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case VIEWS.ARRANGE:
|
case VIEWS.ARRANGE:
|
||||||
complete = {};
|
api.function.clear_progress();
|
||||||
UI.back.style.display = '';
|
UI.back.style.display = '';
|
||||||
UI.render.style.display = '';
|
UI.render.style.display = '';
|
||||||
kiri.client.clear();
|
kiri.client.clear();
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue