restore sla slice, preview, export
This commit is contained in:
parent
1c5c8e9cb4
commit
feca4902d1
11 changed files with 77 additions and 541 deletions
1
app.js
1
app.js
|
|
@ -263,7 +263,6 @@ const script = {
|
||||||
"kiri/db",
|
"kiri/db",
|
||||||
"kiri/slice",
|
"kiri/slice",
|
||||||
"kiri/render",
|
"kiri/render",
|
||||||
// "kiri/slicer",
|
|
||||||
"mode/fdm/driver",
|
"mode/fdm/driver",
|
||||||
"mode/fdm/client",
|
"mode/fdm/client",
|
||||||
"mode/sla/driver",
|
"mode/sla/driver",
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@
|
||||||
case 'LASER': return callExport();
|
case 'LASER': return callExport();
|
||||||
case 'FDM': return callExport(options);
|
case 'FDM': return callExport(options);
|
||||||
case 'CAM': return callExport(options);
|
case 'CAM': return callExport(options);
|
||||||
case 'SLA': return exportSLA();
|
case 'SLA': return callExportSLA(options);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
API.function.prepare(function() {
|
API.function.prepare(function() {
|
||||||
|
|
@ -40,55 +40,25 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function callExport(options) {
|
function callExport(options) {
|
||||||
if (isPrepared()) {
|
const gcode = [];
|
||||||
const gcode = [];
|
KIRI.client.export(API.conf.get(), (line) => {
|
||||||
KIRI.client.export(API.conf.get(), (line) => {
|
gcode.push(line);
|
||||||
gcode.push(line);
|
}, (output) => {
|
||||||
}, (output) => {
|
exportGCodeDialog(gcode.join('\n'), output);
|
||||||
exportGCodeDialog(gcode.join('\n'), output);
|
});
|
||||||
});
|
|
||||||
} else {
|
|
||||||
API.function.prepare(function() { exportPrint(options) });
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function exportSLADialog(currentPrint) {
|
function callExportSLA(options) {
|
||||||
if (isPrepared()) {
|
const preview = [];
|
||||||
if (currentPrint.exported) {
|
KIRI.client.export(API.conf.get(), (line) => {
|
||||||
KIRI.driver.SLA.printDownload(currentPrint);
|
API.show.progress(line.progress, "exporting");
|
||||||
return;
|
if (line.data) {
|
||||||
|
preview.push(line.data);
|
||||||
}
|
}
|
||||||
let lines = [];
|
}, (output) => {
|
||||||
let times = {};
|
API.show.progress(0);
|
||||||
let mark = Date.now();
|
KIRI.driver.SLA.printDownload(preview, output, API);
|
||||||
let seq = 1;
|
});
|
||||||
let segment;
|
|
||||||
currentPrint.export(true, function(line) {
|
|
||||||
if (line.message) {
|
|
||||||
if (segment && segment !== line.message) {
|
|
||||||
let now = Date.now();
|
|
||||||
times[`${seq++}_${segment}`] = now - mark;
|
|
||||||
mark = now;
|
|
||||||
}
|
|
||||||
segment = line.message;
|
|
||||||
}
|
|
||||||
if (line.progress) {
|
|
||||||
API.show.progress(line.progress, "exporting");
|
|
||||||
}
|
|
||||||
if (line.data) {
|
|
||||||
lines.push(line.data);
|
|
||||||
}
|
|
||||||
}, function(done) {
|
|
||||||
currentPrint.exported = true;
|
|
||||||
times[`${seq++}_${segment}`] = Date.now() - mark;
|
|
||||||
console.log(times);
|
|
||||||
API.show.progress(0);
|
|
||||||
currentPrint.sla = { lines, done, API };
|
|
||||||
KIRI.driver.SLA.printDownload(currentPrint);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
API.function.prepare(exportSLA);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function exportLaserDialog(currentPrint) {
|
function exportLaserDialog(currentPrint) {
|
||||||
|
|
@ -132,7 +102,7 @@
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function exportGCodeDialog(gcode, currentPrint) {
|
function exportGCodeDialog(gcode, info) {
|
||||||
SDB['kiri-print-seq'] = printSeq++;
|
SDB['kiri-print-seq'] = printSeq++;
|
||||||
|
|
||||||
let settings = API.conf.get(),
|
let settings = API.conf.get(),
|
||||||
|
|
@ -395,8 +365,8 @@
|
||||||
"filename=" + filename +
|
"filename=" + filename +
|
||||||
"&target=" + target +
|
"&target=" + target +
|
||||||
"&key=" + apik +
|
"&key=" + apik +
|
||||||
"&time=" + Math.round(currentPrint.time) +
|
"&time=" + Math.round(info.time) +
|
||||||
"&length=" + Math.round(currentPrint.distance) +
|
"&length=" + Math.round(info.distance) +
|
||||||
"&image=" + filename
|
"&image=" + filename
|
||||||
);
|
);
|
||||||
xhtr.setRequestHeader("Content-Type", "text/plain");
|
xhtr.setRequestHeader("Content-Type", "text/plain");
|
||||||
|
|
@ -420,9 +390,9 @@
|
||||||
let density = $('print-density');
|
let density = $('print-density');
|
||||||
$('print-weight').value = (
|
$('print-weight').value = (
|
||||||
(Math.PI * UTIL.sqr(
|
(Math.PI * UTIL.sqr(
|
||||||
currentPrint.settings.device.extruders[0].extFilament / 2
|
info.settings.device.extruders[0].extFilament / 2
|
||||||
)) *
|
)) *
|
||||||
currentPrint.distance *
|
info.distance *
|
||||||
(parseFloat(density.value) || 1.25) /
|
(parseFloat(density.value) || 1.25) /
|
||||||
1000
|
1000
|
||||||
).toFixed(2);
|
).toFixed(2);
|
||||||
|
|
@ -434,7 +404,7 @@
|
||||||
|
|
||||||
function calcTime() {
|
function calcTime() {
|
||||||
let floor = Math.floor,
|
let floor = Math.floor,
|
||||||
time = floor(currentPrint.time),
|
time = floor(info.time),
|
||||||
hours = floor(time / 3600),
|
hours = floor(time / 3600),
|
||||||
newtime = time - hours * 3600,
|
newtime = time - hours * 3600,
|
||||||
mins = floor(newtime / 60),
|
mins = floor(newtime / 60),
|
||||||
|
|
@ -454,8 +424,8 @@
|
||||||
$('print-filament-head').style.display = fdm ? '' : 'none';
|
$('print-filament-head').style.display = fdm ? '' : 'none';
|
||||||
$('print-filament-info').style.display = fdm ? '' : 'none';
|
$('print-filament-info').style.display = fdm ? '' : 'none';
|
||||||
$('print-filename').value = filename;
|
$('print-filename').value = filename;
|
||||||
$('print-filesize').value = UTIL.comma(currentPrint.bytes);
|
$('print-filesize').value = UTIL.comma(info.bytes);
|
||||||
$('print-filament').value = Math.round(currentPrint.distance);
|
$('print-filament').value = Math.round(info.distance);
|
||||||
calcTime();
|
calcTime();
|
||||||
if (fdm) {
|
if (fdm) {
|
||||||
calcWeight();
|
calcWeight();
|
||||||
|
|
|
||||||
|
|
@ -1,149 +0,0 @@
|
||||||
/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
(function() {
|
|
||||||
|
|
||||||
return; // todo remove
|
|
||||||
if (self.kiri.Layer) return;
|
|
||||||
|
|
||||||
const KIRI = self.kiri,
|
|
||||||
POLY = self.base.polygons,
|
|
||||||
shininess = 15,
|
|
||||||
specular = 0x444444,
|
|
||||||
emissive = 0x101010,
|
|
||||||
metalness = 0,
|
|
||||||
roughness = 0.3,
|
|
||||||
newMesh = createPhongMesh;
|
|
||||||
|
|
||||||
KIRI.Layer = Layer;
|
|
||||||
KIRI.newLayer = function() { return new Layer() };
|
|
||||||
|
|
||||||
function Layer(view) { }
|
|
||||||
|
|
||||||
Layer.renderSetup = function() {
|
|
||||||
const API = KIRI.api, UC = API.uc, UI = API.ui;
|
|
||||||
const dyn = UI.dyn = {};
|
|
||||||
const layers = $("layers");
|
|
||||||
UC.setGroup(layers);
|
|
||||||
layers.innerHTML = '';
|
|
||||||
return Layer;
|
|
||||||
};
|
|
||||||
|
|
||||||
Layer.renderSlices = function(slices) {
|
|
||||||
if (slices && slices.length) {
|
|
||||||
slices.forEach(slice => Layer.renderSlice(slice));
|
|
||||||
}
|
|
||||||
return Layer;
|
|
||||||
};
|
|
||||||
|
|
||||||
Layer.renderSlice = function(slice) {
|
|
||||||
let group = new THREE.Group();
|
|
||||||
let render = slice.render;
|
|
||||||
let view = slice.view;
|
|
||||||
|
|
||||||
if (!render) return;
|
|
||||||
|
|
||||||
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));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const API = KIRI.api, UC = API.uc, UI = API.ui, DYN = UI.dyn;;
|
|
||||||
|
|
||||||
for (const [layer, data] of Object.entries(render.layers)) {
|
|
||||||
if (!DYN[layer]) {
|
|
||||||
DYN[layer] = {
|
|
||||||
group: [],
|
|
||||||
toggle: UC.newBoolean(layer, (abc) => {
|
|
||||||
ctrl.group.forEach(mat => {
|
|
||||||
mat.visible = ctrl.toggle.checked;
|
|
||||||
});
|
|
||||||
})
|
|
||||||
};
|
|
||||||
}
|
|
||||||
const ctrl = DYN[layer];
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
slice.view.add(group);
|
|
||||||
};
|
|
||||||
|
|
||||||
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
|
|
||||||
});
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
|
|
@ -138,14 +138,18 @@ KIRI.worker = {
|
||||||
return send.done()
|
return send.done()
|
||||||
}
|
}
|
||||||
|
|
||||||
const output = driver.export(current.print, function(line) {
|
let output;
|
||||||
send.data({line});
|
driver.export(current.print, function(line, direct) {
|
||||||
|
send.data({line}, direct);
|
||||||
|
}, function(done) {
|
||||||
|
// SLA workaround
|
||||||
|
output = done;
|
||||||
});
|
});
|
||||||
const { bounds, time, lines, bytes, distance } = current.print;
|
const { bounds, time, lines, bytes, distance, settings } = current.print;
|
||||||
|
|
||||||
send.done({
|
send.done({
|
||||||
done: true,
|
done: true,
|
||||||
output: { bounds, time, lines, bytes, distance }
|
output: output ? output : { bounds, time, lines, bytes, distance, settings }
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@
|
||||||
/**
|
/**
|
||||||
* @returns {Array} gcode lines
|
* @returns {Array} gcode lines
|
||||||
*/
|
*/
|
||||||
CAM.export = function printExport(print, online) {
|
CAM.export = function(print, online) {
|
||||||
let widget = print.widgets[0];
|
let widget = print.widgets[0];
|
||||||
|
|
||||||
if (!widget) return;
|
if (!widget) return;
|
||||||
|
|
@ -80,26 +80,17 @@
|
||||||
},
|
},
|
||||||
append;
|
append;
|
||||||
|
|
||||||
if (online) {
|
append = function(line) {
|
||||||
append = function(line) {
|
if (line) {
|
||||||
if (line) {
|
|
||||||
lines++;
|
|
||||||
bytes += line.length;
|
|
||||||
output.append(line);
|
|
||||||
}
|
|
||||||
if (!line || output.length > 1000) {
|
|
||||||
online(output.join("\n"));
|
|
||||||
output = [];
|
|
||||||
}
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
append = function(line) {
|
|
||||||
if (!line) return;
|
|
||||||
output.append(line);
|
|
||||||
lines++;
|
lines++;
|
||||||
bytes += line.length;
|
bytes += line.length;
|
||||||
|
output.append(line);
|
||||||
}
|
}
|
||||||
}
|
if (!line || output.length > 1000) {
|
||||||
|
online(output.join("\n"));
|
||||||
|
output = [];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
function filterEmit(array, consts) {
|
function filterEmit(array, consts) {
|
||||||
if (!array) return;
|
if (!array) return;
|
||||||
|
|
@ -317,8 +308,6 @@
|
||||||
print.lines = lines;
|
print.lines = lines;
|
||||||
print.bytes = bytes + lines - 1;
|
print.bytes = bytes + lines - 1;
|
||||||
print.bounds = runbox;
|
print.bounds = runbox;
|
||||||
|
|
||||||
return online ? null : output.join("\n");
|
|
||||||
};
|
};
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
|
|
||||||
|
|
@ -79,26 +79,17 @@
|
||||||
if (v >= 0) pause.push(v);
|
if (v >= 0) pause.push(v);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (online) {
|
append = function(line) {
|
||||||
append = function(line) {
|
if (line) {
|
||||||
if (line) {
|
|
||||||
lines++;
|
|
||||||
bytes += line.length;
|
|
||||||
output.append(line);
|
|
||||||
}
|
|
||||||
if (!line || output.length > 1000) {
|
|
||||||
online(output.join("\n"));
|
|
||||||
output = [];
|
|
||||||
}
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
append = function(line) {
|
|
||||||
if (!line) return;
|
|
||||||
output.append(line);
|
|
||||||
lines++;
|
lines++;
|
||||||
bytes += line.length;
|
bytes += line.length;
|
||||||
|
output.append(line);
|
||||||
}
|
}
|
||||||
}
|
if (!line || output.length > 1000) {
|
||||||
|
online(output.join("\n"));
|
||||||
|
output = [];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
function appendSub(line) {
|
function appendSub(line) {
|
||||||
append(print.constReplace(line, subst));
|
append(print.constReplace(line, subst));
|
||||||
|
|
@ -375,8 +366,6 @@
|
||||||
print.lines = lines;
|
print.lines = lines;
|
||||||
print.bytes = bytes + lines - 1;
|
print.bytes = bytes + lines - 1;
|
||||||
print.time = time;
|
print.time = time;
|
||||||
|
|
||||||
return online ? null : output.join("\n");
|
|
||||||
};
|
};
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
|
|
||||||
|
|
@ -218,191 +218,6 @@
|
||||||
doRender(slice);
|
doRender(slice);
|
||||||
}, "render");
|
}, "render");
|
||||||
|
|
||||||
// let polish = spro.polishLayers;
|
|
||||||
// // experimental polishing
|
|
||||||
// if (polish) {
|
|
||||||
// let polish_layer = Math.floor(polish);
|
|
||||||
// let polish_step = Math.max(polish - polish_layer || 1, 0.25);
|
|
||||||
// widget.polish = {};
|
|
||||||
// let px = [];
|
|
||||||
// let py = [];
|
|
||||||
// // compute x polishing slices
|
|
||||||
// SLICER.sliceWidget(widget, {
|
|
||||||
// height: nozzleSize * polish_step,
|
|
||||||
// swapX: true,
|
|
||||||
// swapY: false,
|
|
||||||
// simple: true
|
|
||||||
// }, (polish_done => {
|
|
||||||
// widget.polish.x = polish_done
|
|
||||||
// .filter(s => s.groups.length)
|
|
||||||
// .map(s => s.groups)
|
|
||||||
// .forEach(p => px.appendAll(p));
|
|
||||||
// }), (polish_update) => {
|
|
||||||
// // console.log({polish_update});
|
|
||||||
// });
|
|
||||||
// // compute y polishing slices
|
|
||||||
// SLICER.sliceWidget(widget, {
|
|
||||||
// height: nozzleSize * polish_step,
|
|
||||||
// swapX: false,
|
|
||||||
// swapY: true,
|
|
||||||
// simple: true
|
|
||||||
// }, (polish_done => {
|
|
||||||
// widget.polish.y = polish_done
|
|
||||||
// .filter(s => s.groups.length)
|
|
||||||
// .map(s => s.groups)
|
|
||||||
// .forEach(p => py.appendAll(p));
|
|
||||||
// }), (polish_update) => {
|
|
||||||
// // console.log({polish_update});
|
|
||||||
// });
|
|
||||||
// // apply polishing finishes to layers
|
|
||||||
// forSlices(1.0, 1.0, (slice) => {
|
|
||||||
// if (polish_layer >= 2) {
|
|
||||||
// let sai = (slice.index - polish_layer);
|
|
||||||
// if (sai % (polish_layer-1) !== 0) {
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// if (slice.index >= polish_layer) {
|
|
||||||
// let sd = slice;
|
|
||||||
// for (let i=0; i<polish_layer; i++) {
|
|
||||||
// sd = sd.down;
|
|
||||||
// }
|
|
||||||
// let zb = sd.z;
|
|
||||||
// let zt = slice.z;
|
|
||||||
// let pout = [];
|
|
||||||
// let cont = 0;
|
|
||||||
// [px, py].forEach(pa => {
|
|
||||||
//
|
|
||||||
// let polys = [];
|
|
||||||
// pa.forEach(p => {
|
|
||||||
// // rotate and test for self-intersection (points under model)
|
|
||||||
// p.ensureXY();
|
|
||||||
// let ox = p._aligned == 'yz' ? 0.1 : 0;
|
|
||||||
// let oy = p._aligned == 'yz' ? 0 : 0.1;
|
|
||||||
// p.forEachPoint(pt => {
|
|
||||||
// let int = p.intersections(
|
|
||||||
// pt.offset(ox,oy,0),
|
|
||||||
// pt.offset(ox*10000,oy*10000,0));
|
|
||||||
// if (int.length > 0) {
|
|
||||||
// pt._under = true;
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// p.restoreXY();
|
|
||||||
//
|
|
||||||
// let lastp = undefined;
|
|
||||||
// let poly = [];
|
|
||||||
// // look for qualifying segments
|
|
||||||
// p.forEachSegment((p1, p2) => {
|
|
||||||
// // eliminate segments that projected up
|
|
||||||
// // intersect with the polygon (bottom faces)
|
|
||||||
// if (p1._under || p2._under) {
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
// // skip when both below layer range
|
|
||||||
// if (p1.z < zb && p2.z < zb) {
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
// // skip when both above layer range
|
|
||||||
// if (p1.z > zt && p2.z > zt) {
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
// // skip vertical
|
|
||||||
// if (p1.x === p2.x && p1.y === p2.y) {
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
// // skip horizontal
|
|
||||||
// // if (p1.z === p2.z) {
|
|
||||||
// // return;
|
|
||||||
// // }
|
|
||||||
// // order points lowest to highest
|
|
||||||
// let swap = false;
|
|
||||||
// if (p1.z > p2.z) {
|
|
||||||
// let t = p2;
|
|
||||||
// p2 = p1;
|
|
||||||
// p1 = t;
|
|
||||||
// swap = true;
|
|
||||||
// }
|
|
||||||
// let trimlo = false;
|
|
||||||
// let trimhi = false;
|
|
||||||
// if (p1.z < zb) {
|
|
||||||
// trimlo = true;
|
|
||||||
// }
|
|
||||||
// if (p2.z > zt) {
|
|
||||||
// trimhi = true;
|
|
||||||
// }
|
|
||||||
// let xaxis = p1.x === p2.x;
|
|
||||||
// if (xaxis) {
|
|
||||||
// p1 = BASE.newPoint(p1.y,p1.z,p1.x);
|
|
||||||
// p2 = BASE.newPoint(p2.y,p2.z,p2.x);
|
|
||||||
// } else {
|
|
||||||
// p1 = BASE.newPoint(p1.x,p1.z,p1.y);
|
|
||||||
// p2 = BASE.newPoint(p2.x,p2.z,p2.y);
|
|
||||||
// }
|
|
||||||
// let slope = BASE.newSlope(p1, p2);
|
|
||||||
// let angle = slope.angle;
|
|
||||||
// if (angle > 80 && angle < 100) {
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
// let len = p1.distTo2D(p2);
|
|
||||||
// let np1 = p1;
|
|
||||||
// if (trimlo) {
|
|
||||||
// let zunder = zb - p1.y;
|
|
||||||
// let zover = p2.y - zb;
|
|
||||||
// let zdelt = p2.y - p1.y;
|
|
||||||
// let pct = zunder / zdelt;
|
|
||||||
// np1 = p1.follow(slope, len * pct);
|
|
||||||
// }
|
|
||||||
// if (trimhi) {
|
|
||||||
// let zunder = zt - p1.y;
|
|
||||||
// let zover = p2.y - zt;
|
|
||||||
// let zdelt = p2.y - p1.y;
|
|
||||||
// let pct = zover / zdelt;
|
|
||||||
// p2 = p2.follow(slope.invert(), len * pct);
|
|
||||||
// }
|
|
||||||
// p1 = np1;
|
|
||||||
// if (xaxis) {
|
|
||||||
// p1 = BASE.newPoint(p1.z,p1.x,p1.y);
|
|
||||||
// p2 = BASE.newPoint(p2.z,p2.x,p2.y);
|
|
||||||
// } else {
|
|
||||||
// p1 = BASE.newPoint(p1.x,p1.z,p1.y);
|
|
||||||
// p2 = BASE.newPoint(p2.x,p2.z,p2.y);
|
|
||||||
// }
|
|
||||||
// if (!lastp) {
|
|
||||||
// poly.push(p1);
|
|
||||||
// poly.push(p2);
|
|
||||||
// } else if (p1.isMergable2D(lastp)) {
|
|
||||||
// // } else if (p1.isEqual(lastp)) {
|
|
||||||
// poly.push(p2);
|
|
||||||
// cont++;
|
|
||||||
// } else if (poly.length) {
|
|
||||||
// polys.push(poly);
|
|
||||||
// poly = [p1, p2];
|
|
||||||
// }
|
|
||||||
// lastp = p2;
|
|
||||||
// });
|
|
||||||
// if (poly.length) {
|
|
||||||
// polys.push(poly);
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// pout.push(polys);
|
|
||||||
// polys = [];
|
|
||||||
// });
|
|
||||||
//
|
|
||||||
// if (pout.length && slice.tops.length) {
|
|
||||||
// slice.tops[0].polish = {
|
|
||||||
// x: pout[0]
|
|
||||||
// .map(a => BASE.newPolygon(a).setOpen())
|
|
||||||
// // .filter(p => p.perimeter() > nozzleSize)
|
|
||||||
// ,
|
|
||||||
// y: pout[1]
|
|
||||||
// .map(a => BASE.newPolygon(a).setOpen())
|
|
||||||
// // .filter(p => p.perimeter() > nozzleSize)
|
|
||||||
// };
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
|
|
||||||
// report slicing complete
|
// report slicing complete
|
||||||
ondone();
|
ondone();
|
||||||
}
|
}
|
||||||
|
|
@ -799,6 +614,10 @@
|
||||||
* 'expand' is used for top offsets in SLA mode
|
* 'expand' is used for top offsets in SLA mode
|
||||||
*/
|
*/
|
||||||
function doDiff(slice, minArea, sla, fakedown) {
|
function doDiff(slice, minArea, sla, fakedown) {
|
||||||
|
if (slice.index === 0 && !fakedown) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const top = slice,
|
const top = slice,
|
||||||
down = slice.down || (fakedown ? newSlice(-1) : null),
|
down = slice.down || (fakedown ? newSlice(-1) : null),
|
||||||
topInner = sla ? top.topPolys() : top.topInners(),
|
topInner = sla ? top.topPolys() : top.topInners(),
|
||||||
|
|
|
||||||
|
|
@ -19,98 +19,17 @@
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
SLA.sliceRender = function(widget) {
|
SLA.printDownload = function(preview, output, API) {
|
||||||
// legacy debug
|
const lines = preview;
|
||||||
return;
|
const { file, width, height } = output;
|
||||||
|
const filename = `print-${new Date().getTime().toString(36)}`;
|
||||||
widget.slices.forEach(slice => {
|
|
||||||
let layers = slice.layers,
|
|
||||||
outline = layers.outline,
|
|
||||||
support = layers.support;
|
|
||||||
|
|
||||||
if (slice.solids.unioned) {
|
|
||||||
// console.log('solid', slice.index)
|
|
||||||
slice.solids.unioned.forEach(poly => {
|
|
||||||
poly = poly.clone(true);//.move(widget.track.pos);
|
|
||||||
outline.poly(poly, 0x010101, true);
|
|
||||||
outline.solid(poly, 0x0099cc);
|
|
||||||
});
|
|
||||||
} else if (slice.tops) {
|
|
||||||
// console.log('top', slice.index)
|
|
||||||
slice.tops.forEach(top => {
|
|
||||||
let poly = top.poly;//.clone(true).move(widget.track.pos);
|
|
||||||
outline.poly(poly, 0x010101, true, false);
|
|
||||||
outline.solid(poly, 0xfcba03);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (slice.supports) {
|
|
||||||
// console.log('support', slice.index)
|
|
||||||
slice.supports.forEach(poly => {
|
|
||||||
//poly = poly.clone(true).move(widget.track.pos);
|
|
||||||
support.poly(poly, 0x010101, true, false);
|
|
||||||
support.solid(poly, 0xfcba03);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
slice.renderDiff();
|
|
||||||
slice.renderSolidOutlines();
|
|
||||||
|
|
||||||
outline.renderAll();
|
|
||||||
support.renderAll();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
SLA.printRender = function(print) {
|
|
||||||
let widgets = print.widgets,
|
|
||||||
settings = print.settings,
|
|
||||||
device = settings.device,
|
|
||||||
process = settings.process;
|
|
||||||
|
|
||||||
for (let index=0; ; index++) {
|
|
||||||
let layer = KIRI.newLayer(print.group);
|
|
||||||
let count = 0;
|
|
||||||
|
|
||||||
widgets.forEach(widget => {
|
|
||||||
let slice = widget.slices[index];
|
|
||||||
if (!slice) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
count++;
|
|
||||||
let polys = slice.solids.unioned;
|
|
||||||
if (!polys) polys = slice.tops.map(t => t.poly);
|
|
||||||
if (slice.supports) polys.appendAll(slice.supports);
|
|
||||||
polys.forEach(poly => {
|
|
||||||
poly = poly.clone(true).move(widget.track.pos);
|
|
||||||
layer.poly(poly, 0x777777, true);
|
|
||||||
layer.solid(poly, 0x0099cc);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
layer.renderSolid();
|
|
||||||
layer.render();
|
|
||||||
|
|
||||||
if (count === 0) {
|
|
||||||
// TODO fix with contract for exposing layer count
|
|
||||||
// hack uses expected gcode output array in print object
|
|
||||||
print.output = print.printView;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
print.printView.push(layer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SLA.printDownload = function(print) {
|
|
||||||
let { API, lines, done } = print.sla;
|
|
||||||
let filename = `print-${new Date().getTime().toString(36)}`;
|
|
||||||
|
|
||||||
API.ajax("/kiri/output-sla.html", html => {
|
API.ajax("/kiri/output-sla.html", html => {
|
||||||
API.ui.print.innerHTML = html;
|
API.ui.print.innerHTML = html;
|
||||||
|
|
||||||
let printset = print.settings,
|
let settings = API.conf.get(),
|
||||||
process = printset.process,
|
process = settings.process,
|
||||||
device = printset.device,
|
device = settings.device,
|
||||||
print_sec = (process.slaBaseLayers * process.slaBaseOn) +
|
print_sec = (process.slaBaseLayers * process.slaBaseOn) +
|
||||||
(lines.length - process.slaBaseLayers) * process.slaLayerOn;
|
(lines.length - process.slaBaseLayers) * process.slaLayerOn;
|
||||||
|
|
||||||
|
|
@ -148,17 +67,17 @@
|
||||||
switch (device.deviceName) {
|
switch (device.deviceName) {
|
||||||
case 'Anycubic.Photon':
|
case 'Anycubic.Photon':
|
||||||
download.innerText += " .photon";
|
download.innerText += " .photon";
|
||||||
download.onclick = () => { saveFile(API, done.file, ".photon") };
|
download.onclick = () => { saveFile(API, file, ".photon") };
|
||||||
break;
|
break;
|
||||||
case 'Anycubic.Photon.S':
|
case 'Anycubic.Photon.S':
|
||||||
download.innerText += " .photons";
|
download.innerText += " .photons";
|
||||||
download.onclick = () => { saveFile(API, done.file, ".photons") };
|
download.onclick = () => { saveFile(API, file, ".photons") };
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
let canvas = $('print-canvas');
|
let canvas = $('print-canvas');
|
||||||
let ctx = canvas.getContext('2d');
|
let ctx = canvas.getContext('2d');
|
||||||
let img = ctx.createImageData(done.height, done.width);
|
let img = ctx.createImageData(height, width);
|
||||||
let imgDV = new DataView(img.data.buffer);
|
let imgDV = new DataView(img.data.buffer);
|
||||||
let range = $('print-range');
|
let range = $('print-range');
|
||||||
range.value = 0;
|
range.value = 0;
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@
|
||||||
SLA = KIRI.driver.SLA = {
|
SLA = KIRI.driver.SLA = {
|
||||||
// init, // src/mode/sla/client.js
|
// init, // src/mode/sla/client.js
|
||||||
// slice, // src/mode/sla/slice.js
|
// slice, // src/mode/sla/slice.js
|
||||||
printSetup,
|
prepare,
|
||||||
// export, // src/mode/sla/export.js
|
// export, // src/mode/sla/export.js
|
||||||
// printDownload, // src/mode/sla/client.js
|
// printDownload, // src/mode/sla/client.js
|
||||||
legacy: false
|
legacy: false
|
||||||
|
|
@ -19,13 +19,10 @@
|
||||||
|
|
||||||
if (SLA.legacy) console.log("SLA Driver in Legacy Mode");
|
if (SLA.legacy) console.log("SLA Driver in Legacy Mode");
|
||||||
|
|
||||||
/**
|
// runs in worker. would usually be in src/mode/sla/prepare.js
|
||||||
* DRIVER PRINT CONTRACT - runs in worker
|
function prepare(widgets, settings, update) {
|
||||||
* @param {Object} print state object
|
self.worker.print = KIRI.newPrint(settings, widgets);
|
||||||
* @param {Function} update incremental callback
|
|
||||||
*/
|
|
||||||
function printSetup(print, update) {
|
|
||||||
update(1);
|
update(1);
|
||||||
};
|
}
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@
|
||||||
* @param {Function} online streaming reply
|
* @param {Function} online streaming reply
|
||||||
* @param {Function} ondone last reply
|
* @param {Function} ondone last reply
|
||||||
*/
|
*/
|
||||||
SLA.printExport = function(print, online, ondone) {
|
SLA.export = function(print, online, ondone) {
|
||||||
let widgets = print.widgets,
|
let widgets = print.widgets,
|
||||||
settings = print.settings,
|
settings = print.settings,
|
||||||
device = settings.device,
|
device = settings.device,
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
let KIRI = self.kiri,
|
let KIRI = self.kiri,
|
||||||
BASE = self.base,
|
BASE = self.base,
|
||||||
|
POLY = BASE.polygons,
|
||||||
UTIL = BASE.util,
|
UTIL = BASE.util,
|
||||||
SLA = KIRI.driver.SLA,
|
SLA = KIRI.driver.SLA,
|
||||||
FDM = KIRI.driver.FDM.share,
|
FDM = KIRI.driver.FDM.share,
|
||||||
|
|
@ -120,14 +121,12 @@
|
||||||
slices[i-1].up = slices[i];
|
slices[i-1].up = slices[i];
|
||||||
slices[i].down = slices[i-1];
|
slices[i].down = slices[i-1];
|
||||||
}
|
}
|
||||||
// reset for solids and support projections
|
|
||||||
// slices.forEach(function(slice) {
|
|
||||||
// slice.invalidateFill();
|
|
||||||
// slice.invalidateSolids();
|
|
||||||
// slice.invalidateSupports();
|
|
||||||
// slice.isSolidFill = false;
|
|
||||||
// });
|
|
||||||
let solidLayers = Math.round(process.slaShell / process.slaSlice);
|
let solidLayers = Math.round(process.slaShell / process.slaSlice);
|
||||||
|
// setup solid fill
|
||||||
|
slices.forEach(function(slice) {
|
||||||
|
slice.solids = [];
|
||||||
|
});
|
||||||
|
// compute total work for progress bar
|
||||||
work_total = [
|
work_total = [
|
||||||
5, // shell
|
5, // shell
|
||||||
10, // diff
|
10, // diff
|
||||||
|
|
@ -147,7 +146,7 @@
|
||||||
}, "slice");
|
}, "slice");
|
||||||
forSlices(slices, 10, (slice) => {
|
forSlices(slices, 10, (slice) => {
|
||||||
if (slice.synth) return;
|
if (slice.synth) return;
|
||||||
FDM.doDiff(slice, 0.000001, 0.005, true, !process.slaOpenBase);
|
FDM.doDiff(slice, 0.000001, true, !process.slaOpenBase);
|
||||||
}, "delta");
|
}, "delta");
|
||||||
if (solidLayers) {
|
if (solidLayers) {
|
||||||
forSlices(slices, 10, (slice) => {
|
forSlices(slices, 10, (slice) => {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue