From b959328906edce6daba647cdd564cce31d0ff0ae Mon Sep 17 00:00:00 2001 From: Stewart Allen Date: Fri, 6 Nov 2020 19:59:18 -0500 Subject: [PATCH] more accurate progress bar for cam operations --- notes.md | 8 ++------ src/mode/cam/slice.js | 43 +++++++++++++++++++++++++++++++++++++------ src/mode/cam/topo.js | 16 ++++++++++------ 3 files changed, 49 insertions(+), 18 deletions(-) diff --git a/notes.md b/notes.md index 03057dc5..71bccd95 100644 --- a/notes.md +++ b/notes.md @@ -2,14 +2,12 @@ ## `C` cosmetic, `F` functional, `P` performance, `B` bug fix -* `F` ui control of import + decimation + precision * `F` implement an in-app bug reporting system * `F` extend mesh object to store raw + annotations (rot,scale,pos) * share raw data w/ dups, encode/decode * `F` gcode color to speed visualization bar * `F` X,Y,Z colored axes visualizations * `F` 2D image import -* `P` bail on decimation if it's proving ineffective * `P` improve decimation speed by avoiding in/out of Point? * `P` duplicate objects should share same slice data unless rotated or scaled @@ -43,13 +41,12 @@ # CAM -* `B` outline slicing should be distinct from roughing which handles flats -* `B` excessive moves with tabs. allow reversing in open polys or do not nest them * `B` contouring should extend beyond part boundaries by tool radius * `B` outside cutting direction in roughing mode inverted * `F` z bounded slices (extension of z bottom offset feature) * `F` z planar settings visualizations -* `F` use arcs to connect hard angles +* `F` use arcs to connect acute angles +* `F` extend acute roughing on inside polys to clear small voids * `F` lead-in milling * `F` adaptive clearing in roughing mode * `F` trapezoidal tabs (in the Z axis) @@ -60,7 +57,6 @@ * `F` add support for tapered ball mills * `F` warn when part > stock or cuts go outside bed * `P` crossing open space check point is outside camshell before returning max z -* `P` background worker to speculatively generate topo maps (and maybe pre-slicing) # Laser diff --git a/src/mode/cam/slice.js b/src/mode/cam/slice.js index 25115154..7ac5cd96 100644 --- a/src/mode/cam/slice.js +++ b/src/mode/cam/slice.js @@ -86,9 +86,31 @@ return ondone(`invalid z bottom >= bounds z max ${bounds.max.z}`); } + // allows progress output to me weighted and matched to processes + let ops = [ [ "mapping", 1.5 ] ]; + if (procRough) ops.push([ "roughing", 1 ]); + if (procRough) ops.push([ "rough offset", 1 ]); + if (procOutline) ops.push([ "outline", 0.5 ]); + if (procContour) ops.push([ "contour", 4 ]); + let opsTot = ops.map(op => op[1]).reduce((a,v) => a + v); + let opSum = 0; + let opTot; + let opOn; + + function nextOp() { + if (opOn) opSum += opOn[1]; + opOn = ops.shift(); + opTot = opOn[1] / opsTot; + } + + function updateOp(index, total, msg) { + onupdate((opSum/opsTot) + (index/total) * opTot, msg || opOn[0]); + } + // TODO pass widget.isModified() on slice and re-use cache if false // TODO pre-slice in background from client signal // TODO same applies to topo map generation + nextOp(); let slicer = new KIRI.slicer2(widget.getPoints(), { zlist: true, zline: true @@ -105,7 +127,8 @@ // slice.camMode = PRO.LEVEL; // slice.tops[0].inner = POLY.setZ(tshadow.clone(true), data.z); // sliceAll.push(slice); - onupdate(0.0 + (index/total) * 0.1, "mapping"); + // onupdate(opSum + (index/total) * opOn[1], opOn[0]); + updateOp(index, total); }, genso: true }); let shadowTop = terrain[terrain.length - 1]; @@ -141,6 +164,7 @@ // create roughing slices if (procRough) { + nextOp(); maxToolDiam = Math.max(maxToolDiam, roughToolDiam); let shadow = []; let slices = []; @@ -152,7 +176,7 @@ // data.slice.tops[0].inner = data.shadow; // data.slice.tops[0].inner = POLY.setZ(tshadow.clone(true), data.z); slices.push(data.slice); - onupdate(0.1 + (index/total) * 0.1, "roughing"); + updateOp(index, total); }, genso: true }); shadow = POLY.union(shadow.appendAll(shadowTop.tops), 0.01, true); @@ -178,7 +202,8 @@ // expand shadow by half tool diameter + stock to leave let shell = POLY.offset(shadow, (roughToolDiam / 4) + camRoughStock); - slices.forEach(slice => { + nextOp(); + slices.forEach((slice, index) => { let shadow = slice.shadow; let offset = [shell.clone(true),shadow.clone(true)].flat(); let flat = POLY.flatten(offset, [], true); @@ -204,6 +229,7 @@ slice.tops[0].traces = offset; slice.index = sliceIndex++; + updateOp(index, slices.length); }); sliceAll.appendAll(slices); @@ -211,6 +237,7 @@ // create outline slices if (procOutline) { + nextOp(); let outlineTool = new CAM.Tool(conf, proc.camOutlineTool); let outlineToolDiam = outlineTool.fluteDiameter(); maxToolDiam = Math.max(maxToolDiam, outlineToolDiam); @@ -225,7 +252,8 @@ // data.slice.tops[0].inner = data.shadow; // data.slice.tops[0].inner = POLY.setZ(tshadow.clone(true), data.z); slices.push(data.slice); - onupdate(0.2 + (index/total) * 0.1, "outlines"); + // onupdate(0.2 + (index/total) * 0.1, "outlines"); + updateOp(index, total); }, genso: true }); shadow = POLY.union(shadow.appendAll(shadowTop.tops), 0.01, true); @@ -287,9 +315,12 @@ // not generated when drilling-only. then all z moves use bounds max. // also generates x and y contouring when selected if (procContour) { + nextOp(); new CAM.Topo(widget, settings, { - onupdate: (update, msg) => { - onupdate(0.40 + update * 0.50, msg || "create topo"); + // onupdate: (update, msg) => { + onupdate: (index, total, msg) => { + updateOp(index, total, msg); + // onupdate(0.30 + update * 0.50, msg || "create topo"); }, ondone: (slices) => { sliceAll.appendAll(slices); diff --git a/src/mode/cam/topo.js b/src/mode/cam/topo.js index b8ca238c..7aa0fa02 100644 --- a/src/mode/cam/topo.js +++ b/src/mode/cam/topo.js @@ -60,7 +60,9 @@ latent, lastP, slice, lx, ly, - startTime = time(); + startTime = time(), + stepsTaken = 0, + stepsTotal = 0; // return the touching z given topo x,y and a tool profile function toolTipZ(x,y) { @@ -167,7 +169,7 @@ gridy++; } gridx++; - onupdate(0.20 + (gridx/stepsx) * 0.50, "trace surface"); + onupdate(++stepsTaken, stepsTotal, "trace surface"); } // x contouring @@ -223,7 +225,7 @@ if (sliceout.length > 0) { newslices.push(slice); } - onupdate(0.70 + (gridx/stepsx) * 0.15, "contour x"); + onupdate(++stepsTaken, stepsTotal, "contour x"); } } @@ -280,7 +282,7 @@ if (sliceout.length > 0) { newslices.push(slice); } - onupdate(0.85 + (gridy/stepsy) * 0.15, "contour y"); + onupdate(++stepsTaken, stepsTotal, "contour y"); } } @@ -289,10 +291,12 @@ let slicer = new KIRI.slicer2(widget.getPoints(), { swapX: true }); let sindex = slicer.interval(resolution); + stepsTotal += sindex.length * 2; + if (proc.camContourXOn) stepsTotal += (maxX-minX) / toolStep; + if (proc.camContourYOn) stepsTotal += (maxY-minY) / toolStep; let slices = slicer.slice(sindex, { each: (data, index, total) => { - onupdate(0.0 + (index/total) * 0.20, "topo slice"); + onupdate(++stepsTaken, stepsTotal, "topo slice"); }, genso: true }); - processSlices(slices.map(data => data.slice)); } }