when healing enabled, warn when non-manifold geometry detected. update release notes

This commit is contained in:
Stewart Allen 2022-09-08 13:26:47 -04:00
commit 059dbced58
8 changed files with 62 additions and 14 deletions

View file

@ -79,6 +79,7 @@
* `F` add option for op-major ordering (instead of part major)
* `F` animate only selected range (as an option)
* `F` add `plunge max` to contouring that can override z feed limit
* `F` add ability to select regions for contouring op (like pocketing)
* `F` roughing flats should be constrained to flat region, not create a layer
* `F` limit cut depth to flute length of selected tool (or warn)
* `F` change color of line selection in trace op when not a closed poly

View file

@ -7,6 +7,16 @@ Full docs @ https://docs.grid.space/projects/kiri-moto
## Kiri:moto
* add support to run as Progressive Web Apps for installation and offline use
* add assembly import when KM used inside of Onshape
* add configurable flatness for contour clipping
* add axis label remapping in FDM
* extend url loading of workspaces to all formats
* alert when healing is enabled and non-manifold geometries are detected
* fix thin output start and end point tracking which broke retraction
* fix for importing with some obj formatting
* fix profile seeding for newer device record formats
* fix workspace import / restore for some file formats
* fix potential crash into stock during moves when parts are z bottom anchored
* ~ refactor vertex replacement and widget update matrix tracking
* ~ refactor cnc to use core slicer engine

View file

@ -36,6 +36,7 @@ const POLYS = base.polygons = {
expand,
expand_lines,
points,
length,
route,
union,
inset,
@ -52,6 +53,14 @@ const POLYS = base.polygons = {
fingerprint
};
function length(polys) {
let length = 0;
for (let p of polys) {
length += p.deepLength;
}
return length;
}
function setZ(polys, z) {
for (let poly of polys) {
poly.setZ(z);
@ -376,13 +385,16 @@ function subtract(setA, setB, outA, outB, z, minArea, opt = {}) {
*/
function union(polys, minarea, all, opt = {}) {
if (polys.length < 2) return polys;
let lpre = length(polys);
if (opt.wasm && geo.wasm) {
let min = minarea || 0.01;
// let deepLength = polys.map(p => p.deepLength).reduce((a,v) => a+v);
// if (deepLength < 15000)
try {
return geo.wasm.js.union(polys, polys[0].getZ()).filter(p => p.area() > min);
let out = geo.wasm.js.union(polys, polys[0].getZ()).filter(p => p.area() > min);
opt.changes = length(out) - lpre;
return out;
} catch (e) {
console.log({union_fail: polys, minarea, all});
}
@ -419,6 +431,7 @@ function subtract(setA, setB, outA, outB, z, minArea, opt = {}) {
if (out[i]) uset.push(out[i]);
}
opt.changes = length(uset) - lpre;
return uset;
}

View file

@ -385,7 +385,11 @@ async function sliceZ(z, points, options = {}) {
let groups = groupFn(lines, z, options);
if (options.union) {
// simplistic healing of non-manifold meshes
groups = POLY.flatten(POLY.union(POLY.nest(groups), 0.1, true), null, true);
let opt = { x: 1 };
let union = POLY.union(POLY.nest(groups), 0.1, true, opt);
// track total poly length changes to determine if healed
rval.changes = opt.changes;
groups = POLY.flatten(union, null, true);
}
rval.groups = groups;
}

View file

@ -159,6 +159,7 @@ FDM.slice = function(settings, widget, onupdate, ondone) {
let points = widget.getPoints();
let indices = [];
let heights = [];
let healed = false;
// handle z cutting (floor method) and base flattening
let zPress = isBelt ? process.firstLayerFlatten || 0 : 0;
@ -296,12 +297,16 @@ FDM.slice = function(settings, widget, onupdate, ondone) {
}).then((output) => {
// post process slices and re-incorporate missing meta-data
return output.slices.map(data => {
let { z, clip, lines, groups } = data;
let { z, clip, lines, groups, changes } = data;
if (!data.tops) return null;
let slice = newSlice(z).addTops(data.tops);
slice.index = indices.indexOf(z);
slice.height = heights[slice.index];
slice.clips = clip;
if (changes) {
healed = true;
slice.changes = changes;
}
if (process.xray) {
slice.index = process.xrayi.shift();
slice.lines = lines;
@ -342,6 +347,11 @@ FDM.slice = function(settings, widget, onupdate, ondone) {
}
async function onSliceDone(slices) {
// alert non-manifold parts
if (healed) {
onupdate(null, null, "part may not be manifold");
}
// remove all empty slices above part but leave below
// for multi-part (multi-extruder) setups where the void is ok
// also reverse because slicing occurs bottom-up

View file

@ -433,11 +433,13 @@ kiri.worker = {
send.data({send_end: time()});
}
send.done({done: true});
}, function(update, msg) {
}, function(update, msg, alert) {
now = time();
if (now - last < 10 && update < 0.99) return;
// on alert
if (alert) send.data({ alert });
// on update
send.data({update: (0.05 + update * 0.95), updateStatus: msg});
if (now - last < 10 && update < 0.99) return;
if (update || msg) send.data({update: (0.05 + update * 0.95), updateStatus: msg});
last = now;
});
},

View file

@ -161,7 +161,10 @@ function prepareSlices(callback, scale = 1, offset = 0) {
// start next widget slice
sliceNext();
}
}, (update, msg) => {
}, (update, msg, alert) => {
if (alert) {
api.show.alert(alert);
}
if (msg && msg !== lastMsg) {
let mark = Date.now();
if (lastMsg) {
@ -171,12 +174,14 @@ function prepareSlices(callback, scale = 1, offset = 0) {
startTime = mark;
}
// on update
track[widget.id] = (update || 0) * factor;
totalProgress = 0;
for (let w of slicing) {
totalProgress += (track[w.id] || 0);
if (update >= 0) {
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);
}
show.progress(offset + (totalProgress / widgets.length) * scale, msg);
});
}

View file

@ -733,6 +733,9 @@ class Widget {
// executed from kiri.js
kiri.client.slice(settings, this, function(reply) {
if (reply.alert) {
onupdate(null, null, reply.alert);
}
if (reply.update) {
onupdate(reply.update, reply.updateStatus);
}
@ -774,8 +777,8 @@ class Widget {
ondone();
};
let catchupdate = function(progress, message) {
onupdate(progress, message);
let catchupdate = function(progress, message, alert) {
onupdate(progress, message, alert);
};
let drv = driver[settings.mode.toUpperCase()];