checkpoint new print rendering
This commit is contained in:
parent
e7a050e03e
commit
37e32ebedf
10 changed files with 300 additions and 229 deletions
3
app.js
3
app.js
|
|
@ -272,7 +272,7 @@ const script = {
|
||||||
"mode/cam/client",
|
"mode/cam/client",
|
||||||
"mode/cam/tool",
|
"mode/cam/tool",
|
||||||
"mode/laser/driver",
|
"mode/laser/driver",
|
||||||
"kiri/layer",
|
"kiri/stacks",
|
||||||
"kiri/widget",
|
"kiri/widget",
|
||||||
"kiri/print",
|
"kiri/print",
|
||||||
"kiri/codec",
|
"kiri/codec",
|
||||||
|
|
@ -348,7 +348,6 @@ const script = {
|
||||||
"geo/polygon",
|
"geo/polygon",
|
||||||
"geo/polygons",
|
"geo/polygons",
|
||||||
"geo/gyroid",
|
"geo/gyroid",
|
||||||
"kiri/layer",
|
|
||||||
"moto/kv",
|
"moto/kv",
|
||||||
"moto/ajax",
|
"moto/ajax",
|
||||||
"moto/ctrl",
|
"moto/ctrl",
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
|
|
||||||
|
return; // todo remove
|
||||||
if (self.kiri.Layer) return;
|
if (self.kiri.Layer) return;
|
||||||
|
|
||||||
const KIRI = self.kiri,
|
const KIRI = self.kiri,
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,7 @@
|
||||||
UI = {},
|
UI = {},
|
||||||
UC = KIRI.ui.prefix('kiri').inputAction(updateSettings).hideAction(updateDialogLeft),
|
UC = KIRI.ui.prefix('kiri').inputAction(updateSettings).hideAction(updateDialogLeft),
|
||||||
MODE = MODES.FDM,
|
MODE = MODES.FDM,
|
||||||
|
STACKS = KIRI.stacks,
|
||||||
DRIVER = undefined,
|
DRIVER = undefined,
|
||||||
onEvent = {},
|
onEvent = {},
|
||||||
currentPrint = null,
|
currentPrint = null,
|
||||||
|
|
@ -590,11 +591,10 @@
|
||||||
function hideSlices() {
|
function hideSlices() {
|
||||||
let showing = false;
|
let showing = false;
|
||||||
setOpacity(color.model_opacity);
|
setOpacity(color.model_opacity);
|
||||||
|
STACKS.clear();
|
||||||
forAllWidgets(function(widget) {
|
forAllWidgets(function(widget) {
|
||||||
widget.setWireframe(false);
|
widget.setWireframe(false);
|
||||||
showing = widget.hideSlices() || showing;
|
|
||||||
});
|
});
|
||||||
clearPrint();
|
|
||||||
return showing;
|
return showing;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -637,25 +637,7 @@
|
||||||
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;
|
||||||
|
|
||||||
updateSlider();
|
updateSlider();
|
||||||
|
STACKS.setRange(API.var.layer_lo, API.var.layer_hi);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SPACE.update();
|
SPACE.update();
|
||||||
}
|
}
|
||||||
|
|
@ -683,7 +665,6 @@
|
||||||
currentPrint.render();
|
currentPrint.render();
|
||||||
SPACE.platform.add(currentPrint.group);
|
SPACE.platform.add(currentPrint.group);
|
||||||
SPACE.update();
|
SPACE.update();
|
||||||
UI.layerPrint.checked = true;
|
|
||||||
updateSliderMax(true);
|
updateSliderMax(true);
|
||||||
showSlices();
|
showSlices();
|
||||||
}
|
}
|
||||||
|
|
@ -736,16 +717,15 @@
|
||||||
if (!isCam) setOpacity(0);
|
if (!isCam) setOpacity(0);
|
||||||
|
|
||||||
if (feature.preview) {
|
if (feature.preview) {
|
||||||
currentPrint.render();
|
STACKS.clear();
|
||||||
|
currentPrint.render(STACKS.create('print', SPACE.platform.world));
|
||||||
}
|
}
|
||||||
|
|
||||||
API.event.emit('print', pMode);
|
API.event.emit('print', pMode);
|
||||||
API.event.emit('preview.end', pMode);
|
API.event.emit('preview.end', pMode);
|
||||||
|
|
||||||
if (feature.preview) {
|
if (feature.preview) {
|
||||||
SPACE.platform.add(currentPrint.group);
|
|
||||||
SPACE.update();
|
SPACE.update();
|
||||||
UI.layerPrint.checked = true;
|
|
||||||
updateSliderMax(true);
|
updateSliderMax(true);
|
||||||
showSlices();
|
showSlices();
|
||||||
}
|
}
|
||||||
|
|
@ -828,6 +808,8 @@
|
||||||
|
|
||||||
setOpacity(color.slicing_opacity);
|
setOpacity(color.slicing_opacity);
|
||||||
|
|
||||||
|
STACKS.clear();
|
||||||
|
|
||||||
// for each widget, slice
|
// for each widget, slice
|
||||||
forAllWidgets(function(widget) {
|
forAllWidgets(function(widget) {
|
||||||
let segtimes = {},
|
let segtimes = {},
|
||||||
|
|
@ -835,7 +817,8 @@
|
||||||
errored = false,
|
errored = false,
|
||||||
startTime,
|
startTime,
|
||||||
lastMsg,
|
lastMsg,
|
||||||
camOrLaser = mode === 'CAM' || mode === 'LASER';
|
camOrLaser = mode === 'CAM' || mode === 'LASER',
|
||||||
|
stack = STACKS.create(widget.id, widget.mesh);
|
||||||
|
|
||||||
widget.stats.progress = 0;
|
widget.stats.progress = 0;
|
||||||
widget.setColor(color.slicing);
|
widget.setColor(color.slicing);
|
||||||
|
|
@ -854,7 +837,7 @@
|
||||||
firstMesh = false;
|
firstMesh = false;
|
||||||
}
|
}
|
||||||
// on done
|
// on done
|
||||||
segtimes[`${segNumber}_draw`] = widget.render();
|
segtimes[`${segNumber}_draw`] = widget.render(stack);
|
||||||
// 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.setOpacity(camOrLaser ? color.cam_sliced_opacity : color.sliced_opacity);
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,7 @@
|
||||||
this.time = 0;
|
this.time = 0;
|
||||||
this.lines = 0;
|
this.lines = 0;
|
||||||
this.bytes = 0;
|
this.bytes = 0;
|
||||||
this.output = [];
|
this.output = null;
|
||||||
this.distance = 0;
|
this.distance = 0;
|
||||||
this.bounds = null;
|
this.bounds = null;
|
||||||
this.imported = null;
|
this.imported = null;
|
||||||
|
|
@ -213,35 +213,31 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
PRO.setup = function(remote, onupdate, ondone) {
|
PRO.setup = function(remote, onupdate, ondone) {
|
||||||
let scope = this,
|
let print = this,
|
||||||
settings = scope.settings,
|
settings = print.settings,
|
||||||
mode = settings.mode;
|
mode = settings.mode;
|
||||||
|
|
||||||
lastPoint = null;
|
lastPoint = null;
|
||||||
lastEmit = null;
|
lastEmit = null;
|
||||||
|
|
||||||
if (remote) {
|
if (KIRI.client) {
|
||||||
|
// executed main kiri.js
|
||||||
// executed from kiri.js
|
KIRI.client.printSetup(settings, function(reply) {
|
||||||
KIRI.work.printSetup(settings, function(reply) {
|
|
||||||
if (reply.done) {
|
if (reply.done) {
|
||||||
scope.output = reply.output;
|
print.output = KIRI.codec.decode(reply.output);
|
||||||
ondone();
|
ondone();
|
||||||
} else {
|
} else {
|
||||||
onupdate(reply.update, reply.updateStatus)
|
onupdate(reply.progress, reply.message)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// executed from kiri-worker.js
|
// 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
|
// this encoding could be made vastly more efficient
|
||||||
let driver = KIRI.driver[mode];
|
let driver = KIRI.driver[mode];
|
||||||
if (driver) driver.printSetup(scope, onupdate);
|
if (driver) driver.printSetup(print, onupdate);
|
||||||
else console.log({missing_print_driver: mode});
|
else console.log({missing_print_driver: mode});
|
||||||
ondone();
|
ondone();
|
||||||
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -250,9 +246,9 @@
|
||||||
let mode = this.settings.mode;
|
let mode = this.settings.mode;
|
||||||
let driver = KIRI.driver[mode];
|
let driver = KIRI.driver[mode];
|
||||||
|
|
||||||
if (remote) {
|
if (KIRI.client) {
|
||||||
// executed from kiri.js
|
// executed from kiri.js
|
||||||
KIRI.work.printExport(this.settings, online, ondone);
|
KIRI.client.printExport(this.settings, online, ondone);
|
||||||
} else {
|
} else {
|
||||||
if (!(driver && driver.printExport)) {
|
if (!(driver && driver.printExport)) {
|
||||||
console.log({missing_export_driver: mode});
|
console.log({missing_export_driver: mode});
|
||||||
|
|
@ -273,9 +269,9 @@
|
||||||
return ondone(scope.imported);
|
return ondone(scope.imported);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (remote) {
|
if (KIRI.client) {
|
||||||
// executed from kiri.js
|
// executed from kiri.js
|
||||||
KIRI.work.printGCode(function(reply) {
|
KIRI.client.printGCode(function(reply) {
|
||||||
scope.lines = reply.lines;
|
scope.lines = reply.lines;
|
||||||
scope.bytes = reply.bytes;
|
scope.bytes = reply.bytes;
|
||||||
scope.bounds = reply.bounds;
|
scope.bounds = reply.bounds;
|
||||||
|
|
@ -283,10 +279,7 @@
|
||||||
scope.time = reply.time;
|
scope.time = reply.time;
|
||||||
ondone(reply.gcode);
|
ondone(reply.gcode);
|
||||||
});
|
});
|
||||||
return;
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// executed from kiri-worker.js
|
// executed from kiri-worker.js
|
||||||
let driver = KIRI.driver[mode];
|
let driver = KIRI.driver[mode];
|
||||||
if (driver && driver.printExport) {
|
if (driver && driver.printExport) {
|
||||||
|
|
@ -295,7 +288,6 @@
|
||||||
console.log({missing_export_driver: mode});
|
console.log({missing_export_driver: mode});
|
||||||
ondone(null);
|
ondone(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -347,20 +339,11 @@
|
||||||
return newout;
|
return newout;
|
||||||
};
|
};
|
||||||
|
|
||||||
PRO.render = function() {
|
PRO.render = function(stack) {
|
||||||
let settings = this.settings,
|
console.log({print_render: this.output});
|
||||||
origin = settings.origin,
|
this.output.forEach(layer => {
|
||||||
mode = settings.mode,
|
stack.add(layer);
|
||||||
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});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
function pref(a,b) {
|
function pref(a,b) {
|
||||||
|
|
|
||||||
|
|
@ -22,8 +22,8 @@
|
||||||
let layers = this.layers;
|
let layers = this.layers;
|
||||||
if (typeof(colors) === 'number') {
|
if (typeof(colors) === 'number') {
|
||||||
colors = {
|
colors = {
|
||||||
line: color,
|
line: colors,
|
||||||
face: color,
|
face: colors,
|
||||||
opacity: 1
|
opacity: 1
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
@ -62,6 +62,7 @@
|
||||||
this.addLine(lines[i], lines[i+1]);
|
this.addLine(lines[i], lines[i+1]);
|
||||||
this.stats.line++;
|
this.stats.line++;
|
||||||
}
|
}
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
addPoly(poly, options) {
|
addPoly(poly, options) {
|
||||||
|
|
|
||||||
189
src/kiri/stacks.js
Normal file
189
src/kiri/stacks.js
Normal 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
|
||||||
|
};
|
||||||
|
|
||||||
|
})();
|
||||||
|
|
@ -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();
|
const mark = Date.now();
|
||||||
DRIVERS[this.settings.mode.toUpperCase()].sliceRender(this);
|
this.slices.forEach(slice => {
|
||||||
return Date.now() - mark;
|
stack.add(slice.render);
|
||||||
};
|
|
||||||
|
|
||||||
PRO.hideSlices = function() {
|
|
||||||
let showing = false;
|
|
||||||
if (this.slices) this.slices.forEach(function(slice) {
|
|
||||||
showing = showing || slice.view.visible;
|
|
||||||
slice.view.visible = false;
|
|
||||||
});
|
});
|
||||||
return showing;
|
return Date.now() - mark;
|
||||||
};
|
};
|
||||||
|
|
||||||
PRO.toggleWireframe = function (color, opacity) {
|
PRO.toggleWireframe = function (color, opacity) {
|
||||||
|
|
@ -652,7 +645,6 @@
|
||||||
mesh.remove(this.wire);
|
mesh.remove(this.wire);
|
||||||
this.wire = null;
|
this.wire = null;
|
||||||
this.setOpacity(solid_opacity);
|
this.setOpacity(solid_opacity);
|
||||||
this.hideSlices();
|
|
||||||
}
|
}
|
||||||
if (set) {
|
if (set) {
|
||||||
widget.wire = base.render.wireframe(mesh, this.getPoints(), color);
|
widget.wire = base.render.wireframe(mesh, this.getPoints(), color);
|
||||||
|
|
|
||||||
|
|
@ -107,23 +107,27 @@ KIRI.worker = {
|
||||||
},
|
},
|
||||||
|
|
||||||
printSetup: function(data, send) {
|
printSetup: function(data, send) {
|
||||||
let widgets = [], key;
|
// create widget array from id:widget cache
|
||||||
for (key in cache) {
|
const widgets = [];
|
||||||
if (cache.hasOwnProperty(key)) widgets.push(cache[key]);
|
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"});
|
send.data({update:0.05, updateStatus:"preview"});
|
||||||
|
|
||||||
current.print = KIRI.newPrint(data.settings, widgets, data.id);
|
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({
|
send.data({
|
||||||
update: update,
|
progress,
|
||||||
updateStatus: msg
|
message
|
||||||
});
|
});
|
||||||
}, function() {
|
}, function() {
|
||||||
send.done({
|
send.done({
|
||||||
done: true,
|
done: true,
|
||||||
output: current.print.encodeOutput()
|
output: KIRI.codec.encode(current.print.output)
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -22,144 +22,6 @@
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* DRIVER SLICE RENDER CONTRACT
|
|
||||||
*
|
|
||||||
* @param {Object} widget to render
|
|
||||||
* @param {number} mode to use to select colors
|
|
||||||
*/
|
|
||||||
FDM.sliceRender = function(widget) {
|
|
||||||
return KIRI.Layer.renderSetup().renderSlices(widget.slices);
|
|
||||||
|
|
||||||
let slices = widget.slices;
|
|
||||||
let settings = widget.settings;
|
|
||||||
let extnum = widget.getExtruder(settings);
|
|
||||||
let extarr = settings.device.extruders || [];
|
|
||||||
let extinfo = extarr[extnum || 0];
|
|
||||||
let extoff = (extinfo.extNozzle || 0.4) / 2;
|
|
||||||
let thin = settings.controller.thinRender && settings.mode === 'FDM';
|
|
||||||
|
|
||||||
if (!slices) return;
|
|
||||||
|
|
||||||
// render outline
|
|
||||||
slices.forEach(function(s) {
|
|
||||||
let layers = s.layers;
|
|
||||||
let tops = s.tops;
|
|
||||||
let outline = layers.outline;
|
|
||||||
let shells = layers.trace;
|
|
||||||
let solids = layers.fill;
|
|
||||||
let sparse = layers.sparse;
|
|
||||||
let support = layers.support;
|
|
||||||
let outsolid = layers.solid;
|
|
||||||
let outbridge = layers.bridge;
|
|
||||||
let outflat = layers.flat;
|
|
||||||
|
|
||||||
outline.clear();
|
|
||||||
shells.clear();
|
|
||||||
solids.clear();
|
|
||||||
sparse.clear();
|
|
||||||
support.clear();
|
|
||||||
outsolid.clear();
|
|
||||||
outbridge.clear();
|
|
||||||
outflat.clear();
|
|
||||||
|
|
||||||
outline.setTransparent(true);
|
|
||||||
shells.setTransparent(false);
|
|
||||||
solids.setTransparent(false);
|
|
||||||
sparse.setTransparent(false);
|
|
||||||
support.setTransparent(false);
|
|
||||||
outsolid.setTransparent(true);
|
|
||||||
outbridge.setTransparent(true);
|
|
||||||
outflat.setTransparent(true);
|
|
||||||
|
|
||||||
tops.forEach(function(top) {
|
|
||||||
// outline
|
|
||||||
outline.poly(top.poly, 0xdddddd, true, false);
|
|
||||||
outline.solid(top.poly, thin ? 0xdddddd : 0xcccccc);
|
|
||||||
if (top.inner) outline.poly(top.inner, 0xdddddd, true);
|
|
||||||
// if (top.thinner) outline.poly(top.thinner, 0x559999, true, null);
|
|
||||||
|
|
||||||
// shells
|
|
||||||
if (thin) {
|
|
||||||
shells.poly(top.traces, 0x77bbcc, true);
|
|
||||||
} else {
|
|
||||||
shells.noodle(top.traces, extoff, 0x88aadd, 0x77bbcc);
|
|
||||||
}
|
|
||||||
if (top.polish) {
|
|
||||||
shells.poly(top.polish.x, 0x880000, true);
|
|
||||||
shells.poly(top.polish.y, 0x880000, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
// solid fill
|
|
||||||
if (thin) {
|
|
||||||
solids.lines(top.thin_fill, 0x77bbcc);
|
|
||||||
solids.lines(top.fill_lines, 0x77bbcc);
|
|
||||||
} else {
|
|
||||||
solids.noodle_lines(top.thin_fill, extoff, 0x88aadd, 0x77bbcc, s.z);
|
|
||||||
solids.noodle_lines(top.fill_lines, extoff, 0x88aadd, 0x77bbcc, s.z);
|
|
||||||
}
|
|
||||||
|
|
||||||
// sparse fill
|
|
||||||
if (top.fill_sparse) {
|
|
||||||
top.fill_sparse.forEach(function(poly) {
|
|
||||||
if (thin) {
|
|
||||||
// todo cull polys with single point before this
|
|
||||||
if (poly.length > 1) poly.render(sparse, 0x0, false, true);
|
|
||||||
} else {
|
|
||||||
sparse.noodle_open(poly, extoff, 0x88aadd, 0x77bbcc, s.z);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// support
|
|
||||||
if (s.supports) {
|
|
||||||
if (thin) {
|
|
||||||
s.supports.forEach(function(poly) {
|
|
||||||
support.poly(poly, 0xffaadd, true);
|
|
||||||
support.lines(poly.fills, 0xffaadd);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
support.noodle(s.supports, extoff, 0xeeaadd, 0x77bbcc);
|
|
||||||
s.supports.forEach(function(poly) {
|
|
||||||
support.noodle_lines(poly.fills, extoff, 0xeeaadd, 0x77bbcc, s.z);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// solid outlines
|
|
||||||
let trimmed = s.solids.trimmed;
|
|
||||||
if (trimmed) trimmed.forEach(function(poly) {
|
|
||||||
poly.setZ(s.z + 0.025);
|
|
||||||
outsolid.poly(poly, 0x00cc00, true, false);
|
|
||||||
outsolid.solid(poly, 0x00dd00);
|
|
||||||
});
|
|
||||||
|
|
||||||
// diff bridges
|
|
||||||
if (s.bridges) s.bridges.forEach(function (poly) {
|
|
||||||
poly.setZ(s.z + 0.05);
|
|
||||||
outbridge.poly(poly, 0x0099ee, true, false);
|
|
||||||
outbridge.solid(poly, 0x00aaff);
|
|
||||||
});
|
|
||||||
|
|
||||||
// diff flats
|
|
||||||
if (s.flats) s.flats.forEach(function (poly) {
|
|
||||||
poly.setZ(s.z + 0.05);
|
|
||||||
outflat.poly(poly, 0xee0099, true, false);
|
|
||||||
outflat.solid(poly, 0xff00aa);
|
|
||||||
});
|
|
||||||
|
|
||||||
outline.renderAll();
|
|
||||||
shells.renderAll();
|
|
||||||
solids.renderAll();
|
|
||||||
sparse.renderAll();
|
|
||||||
support.renderAll();
|
|
||||||
outsolid.renderAll();
|
|
||||||
outbridge.renderAll();
|
|
||||||
outflat.renderAll();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
FDM.printRender = function(print, options) {
|
FDM.printRender = function(print, options) {
|
||||||
let debug = KIRI.api.const.LOCAL;
|
let debug = KIRI.api.const.LOCAL;
|
||||||
let scope = print, emits, last,
|
let scope = print, emits, last,
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,8 @@
|
||||||
UTIL = BASE.util,
|
UTIL = BASE.util,
|
||||||
POLY = BASE.polygons,
|
POLY = BASE.polygons,
|
||||||
FDM = KIRI.driver.FDM,
|
FDM = KIRI.driver.FDM,
|
||||||
newPoint = BASE.newPoint;
|
newPoint = BASE.newPoint,
|
||||||
|
newPolygon = BASE.newPolygon;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DRIVER PRINT CONTRACT
|
* DRIVER PRINT CONTRACT
|
||||||
|
|
@ -24,7 +25,7 @@
|
||||||
nozzle = device.extruders[0].extNozzle,
|
nozzle = device.extruders[0].extNozzle,
|
||||||
process = settings.process,
|
process = settings.process,
|
||||||
mode = settings.mode,
|
mode = settings.mode,
|
||||||
output = print.output,
|
output = [],
|
||||||
bounds = settings.bounds,
|
bounds = settings.bounds,
|
||||||
printPoint = newPoint(0,0,0),
|
printPoint = newPoint(0,0,0),
|
||||||
firstLayerHeight = process.firstSliceHeight || process.sliceHeight,
|
firstLayerHeight = process.firstSliceHeight || process.sliceHeight,
|
||||||
|
|
@ -229,7 +230,7 @@
|
||||||
pos = {x:blokpos.x, y:blokpos.y, z:0},
|
pos = {x:blokpos.x, y:blokpos.y, z:0},
|
||||||
rec = {
|
rec = {
|
||||||
extruder: i,
|
extruder: i,
|
||||||
poly: BASE.newPolygon().centerSpiral(pos, blok.x, blok.y, noz*2, 3)
|
poly: newPolygon().centerSpiral(pos, blok.x, blok.y, noz*2, 3)
|
||||||
};
|
};
|
||||||
blokpos.x += walkpos.x;
|
blokpos.x += walkpos.x;
|
||||||
blokpos.y += walkpos.y;
|
blokpos.y += walkpos.y;
|
||||||
|
|
@ -370,7 +371,63 @@
|
||||||
lastOut = undefined;
|
lastOut = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log({output});
|
print.output = render(output, progress => {
|
||||||
|
// console.log({render: progress});
|
||||||
|
}, device.extruders);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function render(output, update, tools) {
|
||||||
|
const layers = [];
|
||||||
|
output.forEach((level, index) => {
|
||||||
|
update(index / output.length);
|
||||||
|
const prints = {};
|
||||||
|
const moves = [];
|
||||||
|
const pushPrint = (tool, poly) => {
|
||||||
|
let array = prints[tool] = prints[tool] || [];
|
||||||
|
array.width = tools[tool].extNozzle / 2;
|
||||||
|
array.push(poly);
|
||||||
|
};
|
||||||
|
let lastOut = null;
|
||||||
|
let current = null;
|
||||||
|
let height = level.height / 2;
|
||||||
|
let width = 1;
|
||||||
|
level.forEach(out => {
|
||||||
|
if (lastOut) {
|
||||||
|
if (out.emit) {
|
||||||
|
if (!lastOut.emit) {
|
||||||
|
current = newPolygon().setOpen();
|
||||||
|
current.push(lastOut.point);
|
||||||
|
pushPrint(out.tool, current);
|
||||||
|
}
|
||||||
|
current.push(out.point);
|
||||||
|
} else {
|
||||||
|
if (lastOut.emit) {
|
||||||
|
current = newPolygon().setOpen();
|
||||||
|
current.push(lastOut.point);
|
||||||
|
moves.push(current);
|
||||||
|
}
|
||||||
|
current.push(out.point);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
current = newPolygon().setOpen();
|
||||||
|
current.push(out.point);
|
||||||
|
if (out.emit) {
|
||||||
|
pushPrint(out.tool, current);
|
||||||
|
} else {
|
||||||
|
moves.push(current);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lastOut = out;
|
||||||
|
});
|
||||||
|
const out = new KIRI.Render();
|
||||||
|
layers.push(out);
|
||||||
|
out.setLayer('move', 0xaaaaaa).addPolys(moves);
|
||||||
|
Object.values(prints).forEach(array => {
|
||||||
|
out.setLayer('print', 0x888800).addPolys(array, { offset: array.width, height })
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
return layers;
|
||||||
|
}
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue