From 0625ee04ef4e843916e1544fb64108d336f8c6a2 Mon Sep 17 00:00:00 2001 From: Stewart Allen Date: Wed, 22 Apr 2020 23:49:03 -0400 Subject: [PATCH] fix first cut depth in cnc, trace poly render, comments, z cut height on cnc flats --- js/kiri-layer.js | 19 +++++----- js/kiri-slice.js | 6 ++- js/kiri-slicer.js | 93 ++++++++++++++++++++++++++--------------------- 3 files changed, 64 insertions(+), 54 deletions(-) diff --git a/js/kiri-layer.js b/js/kiri-layer.js index 992196cd..ab7d264f 100644 --- a/js/kiri-layer.js +++ b/js/kiri-layer.js @@ -134,25 +134,24 @@ let gs_kiri_layer = exports; this.changed = true; }; - LP.noodle = function(poly, offset, color, traceColor) { - let layer = this; + LP.noodle = function(poly, offset, color, traceColor, open) { if (Array.isArray(poly)) { poly = POLY.flatten(poly, [], true); } else { poly = POLY.flatten([poly], [], true); } if (!poly.length) return; - poly = poly.map(p => p.clone()); - let exp = []; let z = poly[0].getZ(); poly.forEach(p => { - POLY.expand([p], offset, z, exp, 1); - POLY.expand([p], -offset, z, exp, 1); + let exp = []; + POLY.expand([p], offset, z-0.01, exp, 1); + POLY.expand([p], -offset, z-0.01, exp, 1); + POLY.nest(exp).forEach((p,i) => { + this.add(color, {solid: p}); + p = p.clone(true).setZ(z + 0.01); + this.add(traceColor, {poly: p, deep: true, open}); + }); }) - POLY.nest(exp).forEach((p,i) => { - this.add(color, {solid: p}); - this.add(traceColor, {poly: p, deep: true, open: false}); - }); this.changed = true; }; diff --git a/js/kiri-slice.js b/js/kiri-slice.js index 1d646629..2872efd9 100644 --- a/js/kiri-slice.js +++ b/js/kiri-slice.js @@ -577,8 +577,7 @@ let gs_kiri_slice = exports; if (top.traces) { layer.poly(top.traces, trace_color, true, null); // layer.setTransparent(false); - // layer.setOpacity(0.5); - // layer.noodle(top.traces, 0.19, 0x88aadd, 0x0); + // layer.noodle(top.traces, 0.19, 0x88aadd, 0x77bbcc); } if (top.polish) { layer.poly(top.polish.x, 0x880000, true, null); @@ -652,14 +651,17 @@ let gs_kiri_slice = exports; render; layer.clear(); + // layer.setTransparent(false); this.tops.forEach(function(top) { if (top.fill_lines) { layer.lines(top.fill_lines, fill_color); + // layer.noodle(top.fill_lines, 0.19, 0x88aadd, 0x77bbcc, true); } }); layer.render(); + // layer.renderSolid(); }; /** diff --git a/js/kiri-slicer.js b/js/kiri-slicer.js index 8a376c81..228899f0 100644 --- a/js/kiri-slicer.js +++ b/js/kiri-slicer.js @@ -52,6 +52,7 @@ let gs_kiri_slicer = exports; let topoMode = options.topo, simpleMode = options.simple, swap = options.swapX || options.swapY, + isCam = options.cam, ox = 0, oy = 0; @@ -110,10 +111,10 @@ let gs_kiri_slicer = exports; zOff = true ? zInc / 2 : 0, zHeights = [], // heights for zIndexes in adaptive mode zIndexes = [], // auto-detected z slicing offsets (laser/cam) - zOrdered = [], // ordered list of Z vertices - zList = {}, // list of z indices for auto slicing (laser) - zFlat = {}, // area of z offset flat areas (cam) - zLines = {}, // count of lines flat on a z index + zOrdered = [], // ordered list of Z indexes + zList = {}, // map count of z index points for adaptive slicing + zFlat = {}, // map area of z index flat areas (cam) + zLines = {}, // map count of z index lines zScale, // bucket span in z units timeStart = time(), slices = [], @@ -143,39 +144,38 @@ let gs_kiri_slicer = exports; countZ(p2.z); countZ(p3.z); } - if (true || options.cam) { - if (p1.z === p2.z && p2.z === p3.z && p1.z > bounds.min.z) { - // auto-detect flats for cam faces and to avoid slicing directly on flats - let zkey = p1.z.toFixed(5), - area = Math.abs(UTIL.area2(p1,p2,p3)) / 2; - if (!zFlat[zkey]) { - zFlat[zkey] = area; - } else { - zFlat[zkey] += area; - } - } else if (true || options.trace) { - // detect zLines (curved region tops/bottoms) - // mark these layers for ball mills only - if (p1.z === p2.z && p1.z > bounds.min.z) { - let zkey = p1.z.toFixed(5); - let zval = zLines[zkey]; - zLines[zkey] = (zval || 0) + 1; - } - if (p2.z === p3.z && p2.z > bounds.min.z) { - let zkey = p2.z.toFixed(5); - let zval = zLines[zkey]; - zLines[zkey] = (zval || 0) + 1; - } - if (p3.z === p1.z && p3.z > bounds.min.z) { - let zkey = p3.z.toFixed(5); - let zval = zLines[zkey]; - zLines[zkey] = (zval || 0) + 1; - } + // use co-flat and co-line detection to adjust slice Z + if (p1.z === p2.z && p2.z === p3.z && p1.z > bounds.min.z) { + // detect zFlat faces to avoid slicing directly on them + let zkey = p1.z.toFixed(5), + area = Math.abs(UTIL.area2(p1,p2,p3)) / 2; + if (!zFlat[zkey]) { + zFlat[zkey] = area; + } else { + zFlat[zkey] += area; + } + } else if (true || options.trace) { + // detect zLines (curved region tops/bottoms) + // mark these layers for ball and v mill tracing + if (p1.z === p2.z && p1.z > bounds.min.z) { + let zkey = p1.z.toFixed(5); + let zval = zLines[zkey]; + zLines[zkey] = (zval || 0) + 1; + } + if (p2.z === p3.z && p2.z > bounds.min.z) { + let zkey = p2.z.toFixed(5); + let zval = zLines[zkey]; + zLines[zkey] = (zval || 0) + 1; + } + if (p3.z === p1.z && p3.z > bounds.min.z) { + let zkey = p3.z.toFixed(5); + let zval = zLines[zkey]; + zLines[zkey] = (zval || 0) + 1; } } } - // find slice candidates to trace for ballmills and tapermills + // CAM: find slice candidates to trace for ballmills and tapermills if (options.trace) { let zl = {}; let le; @@ -199,7 +199,10 @@ let gs_kiri_slicer = exports; zLines = zl; } - /** bucket polygons into z-bounded groups */ + /** + * bucket polygons into z-bounded groups (inside or crossing) + * to reduce the search space in complex models + */ let bucketCount = Math.max(1, Math.ceil(zMax / (zSum / points.length)) - 1); zScale = 1 / (zMax / bucketCount); @@ -244,7 +247,7 @@ let gs_kiri_slicer = exports; for (i = 0; i < zl.length - 1; i++) { zIndexes.push((zl[i] + zl[i+1]) / 2); } - } else if (options.cam) { + } else if (isCam) { // re-divide slice height so that top and // bottom slices fall exactly on those faces zInc = (zMax - zMin) / (Math.floor(zMax / zInc) + 1); @@ -265,6 +268,8 @@ let gs_kiri_slicer = exports; zIndexes.sort(function(a,b) { return b-a; }); + // copy to store original z + zHeights = zIndexes.slice(); } else if (zIncMin) { // FDM adaptive slicing let zPos = zMin + zIncFirst, @@ -317,7 +322,6 @@ let gs_kiri_slicer = exports; zHeights.push(zInc); } } - // create a Slice for each z offset in the zIndexes array for (let i = 0; i < zIndexes.length; i++) { let ik = zIndexes[i].toFixed(5), @@ -327,16 +331,20 @@ let gs_kiri_slicer = exports; if (zFlat[ik]) onFlat = true; if (zLines[ik]) onLine = true; if (onFlat || onLine) { - zIndexes[i] += options.cam ? 0.001 : -0.001; + zIndexes[i] += isCam ? 0.001 : -0.001; } // slice next layer and add to slices[] array - sliceZ(zIndexes[i], zHeights[i], onFlat, onLine); + let slice = sliceZ(zIndexes[i], zHeights[i], onFlat, onLine); + // override z in cam in case it was moved for a flat or line + if (isCam && slice) { + slice.z = zHeights[i]; + } onupdate(i / zIndexes.length); } - // for cam, mark top and bottom as mandatory (hasFlats) - if (options.cam && slices.length > 0) { - slices[0].hasFlats = true; + // for cam, bottom as mandatory (hasFlats) + if (isCam && slices.length > 0) { + // slices[0].hasFlats = true; slices[slices.length-1].hasFlats = true; } @@ -442,7 +450,7 @@ let gs_kiri_slicer = exports; } // annotate slices with cam flats for finishing waterlines - if (onflat && options.cam) { + if (onflat && isCam) { slice.hasFlats = true; } @@ -529,6 +537,7 @@ let gs_kiri_slicer = exports; } } slices.push(slice); + return slice; } }