checkpoint new print rendering

This commit is contained in:
Stewart Allen 2020-11-08 10:55:36 -05:00
commit 37e32ebedf
10 changed files with 300 additions and 229 deletions

View file

@ -4,6 +4,7 @@
(function() {
return; // todo remove
if (self.kiri.Layer) return;
const KIRI = self.kiri,

View file

@ -40,6 +40,7 @@
UI = {},
UC = KIRI.ui.prefix('kiri').inputAction(updateSettings).hideAction(updateDialogLeft),
MODE = MODES.FDM,
STACKS = KIRI.stacks,
DRIVER = undefined,
onEvent = {},
currentPrint = null,
@ -590,11 +591,10 @@
function hideSlices() {
let showing = false;
setOpacity(color.model_opacity);
STACKS.clear();
forAllWidgets(function(widget) {
widget.setWireframe(false);
showing = widget.hideSlices() || showing;
});
clearPrint();
return showing;
}
@ -637,25 +637,7 @@
lo = cam ? API.var.layer_max - API.var.layer_hi : API.var.layer_lo;
updateSlider();
forAllWidgets(function(widget) {
if (currentPrint) return widget.hideSlices();
let slices = widget.slices;
if (!slices) return;
for (let j = 0; j < slices.length; j++) {
let slice = slices[j];
slice.view.visible = j >= lo && j <= hi;
}
});
if (currentPrint) {
let len = currentPrint.getLayerCount();
for (let j = 0; j < len; j++) {
currentPrint.showLayer(j, print && j >= lo && j <= hi);
}
}
STACKS.setRange(API.var.layer_lo, API.var.layer_hi);
SPACE.update();
}
@ -683,7 +665,6 @@
currentPrint.render();
SPACE.platform.add(currentPrint.group);
SPACE.update();
UI.layerPrint.checked = true;
updateSliderMax(true);
showSlices();
}
@ -736,16 +717,15 @@
if (!isCam) setOpacity(0);
if (feature.preview) {
currentPrint.render();
STACKS.clear();
currentPrint.render(STACKS.create('print', SPACE.platform.world));
}
API.event.emit('print', pMode);
API.event.emit('preview.end', pMode);
if (feature.preview) {
SPACE.platform.add(currentPrint.group);
SPACE.update();
UI.layerPrint.checked = true;
updateSliderMax(true);
showSlices();
}
@ -828,6 +808,8 @@
setOpacity(color.slicing_opacity);
STACKS.clear();
// for each widget, slice
forAllWidgets(function(widget) {
let segtimes = {},
@ -835,7 +817,8 @@
errored = false,
startTime,
lastMsg,
camOrLaser = mode === 'CAM' || mode === 'LASER';
camOrLaser = mode === 'CAM' || mode === 'LASER',
stack = STACKS.create(widget.id, widget.mesh);
widget.stats.progress = 0;
widget.setColor(color.slicing);
@ -854,7 +837,7 @@
firstMesh = false;
}
// on done
segtimes[`${segNumber}_draw`] = widget.render();
segtimes[`${segNumber}_draw`] = widget.render(stack);
// clear wireframe
widget.setWireframe(false, color.wireframe, color.wireframe_opacity);
widget.setOpacity(camOrLaser ? color.cam_sliced_opacity : color.sliced_opacity);

View file

@ -46,7 +46,7 @@
this.time = 0;
this.lines = 0;
this.bytes = 0;
this.output = [];
this.output = null;
this.distance = 0;
this.bounds = null;
this.imported = null;
@ -213,35 +213,31 @@
};
PRO.setup = function(remote, onupdate, ondone) {
let scope = this,
settings = scope.settings,
let print = this,
settings = print.settings,
mode = settings.mode;
lastPoint = null;
lastEmit = null;
if (remote) {
// executed from kiri.js
KIRI.work.printSetup(settings, function(reply) {
if (KIRI.client) {
// executed main kiri.js
KIRI.client.printSetup(settings, function(reply) {
if (reply.done) {
scope.output = reply.output;
print.output = KIRI.codec.decode(reply.output);
ondone();
} else {
onupdate(reply.update, reply.updateStatus)
onupdate(reply.progress, reply.message)
}
});
} else {
// executed from kiri-worker.js
// uses encodeOutput in this class to produce scope.output above
// uses encodeOutput in this class to produce print.output above
// this encoding could be made vastly more efficient
let driver = KIRI.driver[mode];
if (driver) driver.printSetup(scope, onupdate);
if (driver) driver.printSetup(print, onupdate);
else console.log({missing_print_driver: mode});
ondone();
}
};
@ -250,9 +246,9 @@
let mode = this.settings.mode;
let driver = KIRI.driver[mode];
if (remote) {
if (KIRI.client) {
// executed from kiri.js
KIRI.work.printExport(this.settings, online, ondone);
KIRI.client.printExport(this.settings, online, ondone);
} else {
if (!(driver && driver.printExport)) {
console.log({missing_export_driver: mode});
@ -273,9 +269,9 @@
return ondone(scope.imported);
}
if (remote) {
if (KIRI.client) {
// executed from kiri.js
KIRI.work.printGCode(function(reply) {
KIRI.client.printGCode(function(reply) {
scope.lines = reply.lines;
scope.bytes = reply.bytes;
scope.bounds = reply.bounds;
@ -283,10 +279,7 @@
scope.time = reply.time;
ondone(reply.gcode);
});
return;
} else {
// executed from kiri-worker.js
let driver = KIRI.driver[mode];
if (driver && driver.printExport) {
@ -295,7 +288,6 @@
console.log({missing_export_driver: mode});
ondone(null);
}
}
};
@ -347,20 +339,11 @@
return newout;
};
PRO.render = function() {
let settings = this.settings,
origin = settings.origin,
mode = settings.mode,
tools = [],
driver = KIRI.driver[mode],
mark = Date.now();
if (mode === 'FDM') {
tools = settings.device.extruders || [];
}
driver.printRender(this, {tools, aslines:settings.controller.thinRender});
if (KIRI.api.const.LOCAL) console.log({printRender: Date.now() - mark});
PRO.render = function(stack) {
console.log({print_render: this.output});
this.output.forEach(layer => {
stack.add(layer);
});
};
function pref(a,b) {

View file

@ -22,8 +22,8 @@
let layers = this.layers;
if (typeof(colors) === 'number') {
colors = {
line: color,
face: color,
line: colors,
face: colors,
opacity: 1
};
}
@ -62,6 +62,7 @@
this.addLine(lines[i], lines[i+1]);
this.stats.line++;
}
return this;
}
addPoly(poly, options) {

189
src/kiri/stacks.js Normal file
View file

@ -0,0 +1,189 @@
/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
"use strict";
(function() {
const KIRI = self.kiri,
shininess = 15,
specular = 0x444444,
emissive = 0x101010,
metalness = 0,
roughness = 0.3,
newMesh = createPhongMesh;
let stacks = {},
tallest = 0,
min = 0,
max = 0,
labels, API, UC, UI, DYN;
function init() {
labels = $("layers");
API = KIRI.api,
UC = API.uc,
UI = API.ui,
DYN = UI.dyn = {};
}
function clear() {
if (!API) {
init();
}
// remove stacks from their views
for (const [stack, data] of Object.entries(stacks)) {
data.clear();
}
min = max = tallest = 0;
stacks = {};
// clear labels
UC.setGroup(labels);
labels.innerHTML = '';
}
function create(name, view) {
if (stacks[name]) {
return stacks[name];
}
const stack = stacks[name] = {
layers: [ ],
view: view.newGroup(),
add: function(layer) {
const nuview = stack.view.newGroup();
stack.layers.push(nuview);
render(layer, nuview);
tallest = Math.max(tallest, stack.layers.length);
},
clear: function() {
view.remove(stack.view);
}
};
return stack;
}
function getRange() {
return {min, max, tallest};
}
function setRange(newMin, newMax) {
for (const [stack, data] of Object.entries(stacks)) {
const layers = data.layers, len = layers.length;
for (let i=0; i<len; i++) {
layers[i].visible = i >= newMin && i <= newMax;
}
}
min = newMin;
max = newMax;
}
function render(render, group) {
function addPoly(vertices, poly) {
const points = poly.points, len = points.length;
for (let i=1; i<len; i++) {
const p1 = points[i-1], p2 = points[i];
vertices.push(new THREE.Vector3(p1.x, p1.y, p1.z));
vertices.push(new THREE.Vector3(p2.x, p2.y, p2.z));
}
if (!poly.open) {
const p1 = points[len - 1], p2 = points[0];
vertices.push(new THREE.Vector3(p1.x, p1.y, p1.z));
vertices.push(new THREE.Vector3(p2.x, p2.y, p2.z));
}
}
for (const [label, data] of Object.entries(render.layers)) {
if (!DYN[label]) {
DYN[label] = {
group: [],
toggle: UC.newBoolean(label, (abc) => {
ctrl.group.forEach(mat => {
mat.visible = ctrl.toggle.checked;
});
})
};
}
const ctrl = DYN[label];
ctrl.toggle.checked = true;
const { polys, lines, faces, paths } = data;
if (polys.length || lines.length) {
const mat = new THREE.LineBasicMaterial({ color: data.color.line });
const geo = new THREE.Geometry(), vert = geo.vertices;
for (let i=0, il=polys.length; i<il; i++) {
addPoly(vert, polys[i]);
}
for (let i=0, il=lines.length; i<il; i++) {
const p = lines[i];
vert.push(new THREE.Vector3(p.x, p.y, p.z));
}
if (vert.length) {
group.add(new THREE.LineSegments(geo, mat));
}
ctrl.group.push(mat);
}
if (faces.length) {
const mat = newMesh(data);
const geo = new THREE.BufferGeometry();
geo.setAttribute('position', new THREE.BufferAttribute(faces, 3));
geo.computeFaceNormals();
geo.computeVertexNormals();
const mesh = new THREE.Mesh(geo, mat);
mesh.castShadow = true;
mesh.receiveShadow = true;
group.add(mesh);
ctrl.group.push(mat);
}
if (paths.length) {
const mat = newMesh(data);
paths.forEach((path, i) => {
const { index, faces, z } = path;
const geo = new THREE.BufferGeometry();
geo.setAttribute('position', new THREE.BufferAttribute(faces, 3));
geo.setIndex(index);
geo.computeFaceNormals();
geo.computeVertexNormals();
const mesh = new THREE.Mesh(geo, mat);
mesh.position.z = z;
mesh.castShadow = true;
mesh.receiveShadow = true;
group.add(mesh);
});
ctrl.group.push(mat);
}
}
};
function createStandardMesh(data) {
return new THREE.MeshStandardMaterial({
emissive,
roughness,
metalness,
transparent: data.color.opacity != 1,
opacity: data.color.opacity,
color: data.color.face,
side: THREE.DoubleSide
});
}
function createPhongMesh(data) {
return new THREE.MeshPhongMaterial({
shininess,
specular,
transparent: data.color.opacity != 1,
opacity: data.color.opacity,
color: data.color.face,
side: THREE.DoubleSide
});
}
KIRI.stacks = {
clear,
create,
getRange,
setRange
};
})();

View file

@ -624,21 +624,14 @@
};
/**
* render all slice and processed data
* render to provided stack
*/
PRO.render = function() {
PRO.render = function(stack) {
const mark = Date.now();
DRIVERS[this.settings.mode.toUpperCase()].sliceRender(this);
return Date.now() - mark;
};
PRO.hideSlices = function() {
let showing = false;
if (this.slices) this.slices.forEach(function(slice) {
showing = showing || slice.view.visible;
slice.view.visible = false;
this.slices.forEach(slice => {
stack.add(slice.render);
});
return showing;
return Date.now() - mark;
};
PRO.toggleWireframe = function (color, opacity) {
@ -652,7 +645,6 @@
mesh.remove(this.wire);
this.wire = null;
this.setOpacity(solid_opacity);
this.hideSlices();
}
if (set) {
widget.wire = base.render.wireframe(mesh, this.getPoints(), color);

View file

@ -107,23 +107,27 @@ KIRI.worker = {
},
printSetup: function(data, send) {
let widgets = [], key;
for (key in cache) {
if (cache.hasOwnProperty(key)) widgets.push(cache[key]);
// create widget array from id:widget cache
const widgets = [];
for (let key in cache) {
if (cache.hasOwnProperty(key)) {
widgets.push(cache[key]);
}
}
// let client know we've started
send.data({update:0.05, updateStatus:"preview"});
current.print = KIRI.newPrint(data.settings, widgets, data.id);
current.print.setup(false, function(update, msg) {
current.print.setup(false, function(progress, message) {
send.data({
update: update,
updateStatus: msg
progress,
message
});
}, function() {
send.done({
done: true,
output: current.print.encodeOutput()
output: KIRI.codec.encode(current.print.output)
});
});
},