add contour support outside part boundaries

This commit is contained in:
Stewart Allen 2020-11-11 23:27:58 -05:00
commit 9d29faed74
6 changed files with 46 additions and 29 deletions

View file

@ -1,7 +1,11 @@
# Kiri:Moto todo # Kiri:Moto todo
NEXT NEXT
- contour outside part boundaries - contour tabs support
- path arrows
- help dialog
- full bug reports
- frame rate tracking
## `C` cosmetic, `F` functional, `P` performance, `B` bug fix ## `C` cosmetic, `F` functional, `P` performance, `B` bug fix
@ -46,6 +50,7 @@ NEXT
* `B` contouring should extend beyond part boundaries by tool radius * `B` contouring should extend beyond part boundaries by tool radius
* `B` outside cutting direction in roughing mode inverted * `B` outside cutting direction in roughing mode inverted
* `F` flat and volumetric rendering of paths
* `F` z bounded slices (extension of z bottom offset feature) * `F` z bounded slices (extension of z bottom offset feature)
* `F` z planar settings visualizations * `F` z planar settings visualizations
* `F` use arcs to connect acute angles * `F` use arcs to connect acute angles

View file

@ -420,6 +420,7 @@
camContourSpeed: 1000, camContourSpeed: 1000,
camContourAngle: 85, camContourAngle: 85,
camContourCurves: false, camContourCurves: false,
camContourIn: true,
camContourXOn: true, camContourXOn: true,
camContourYOn: true, camContourYOn: true,
camTraceTool: 1000, camTraceTool: 1000,

View file

@ -1463,6 +1463,7 @@
camContourSpeed: UC.newInput(LANG.cc_feed_s, {title:LANG.cc_feed_l, convert:UC.toInt, modes:CAM, units:true}), camContourSpeed: UC.newInput(LANG.cc_feed_s, {title:LANG.cc_feed_l, convert:UC.toInt, modes:CAM, units:true}),
camContourAngle: UC.newInput(LANG.cf_angl_s, {title:LANG.cf_angl_l, convert:UC.toFloat, bound:UC.bound(45,90), modes:CAM}), camContourAngle: UC.newInput(LANG.cf_angl_s, {title:LANG.cf_angl_l, convert:UC.toFloat, bound:UC.bound(45,90), modes:CAM}),
camContourCurves: UC.newBoolean(LANG.cf_curv_s, onBooleanClick, {title:LANG.cf_curv_l, modes:CAM}), camContourCurves: UC.newBoolean(LANG.cf_curv_s, onBooleanClick, {title:LANG.cf_curv_l, modes:CAM}),
camContourIn: UC.newBoolean(LANG.cf_olin_s, onBooleanClick, {title:LANG.cf_olin_l, modes:CAM}),
camContourSep: UC.newBlank({class:"pop-sep"}), camContourSep: UC.newBlank({class:"pop-sep"}),
camContourXOn: UC.newBoolean(LANG.cf_linx_s, onBooleanClick, {title:LANG.cf_linx_l, modes:CAM}), camContourXOn: UC.newBoolean(LANG.cf_linx_s, onBooleanClick, {title:LANG.cf_linx_l, modes:CAM}),
camContourYOn: UC.newBoolean(LANG.cf_liny_s, onBooleanClick, {title:LANG.cf_liny_l, modes:CAM}), camContourYOn: UC.newBoolean(LANG.cf_liny_s, onBooleanClick, {title:LANG.cf_liny_l, modes:CAM}),

View file

@ -343,7 +343,8 @@
}, },
ondone: (slices) => { ondone: (slices) => {
sliceAll.appendAll(slices); sliceAll.appendAll(slices);
} },
shadow: shadowTop.tops
}); });
} }

View file

@ -7,7 +7,8 @@
let KIRI = self.kiri, let KIRI = self.kiri,
BASE = self.base, BASE = self.base,
CAM = KIRI.driver.CAM, CAM = KIRI.driver.CAM,
CPRO = CAM.process, PRO = CAM.process,
POLY = BASE.polygons,
newSlice = KIRI.newSlice, newSlice = KIRI.newSlice,
newLine = BASE.newLine, newLine = BASE.newLine,
newPoint = BASE.newPoint, newPoint = BASE.newPoint,
@ -16,10 +17,12 @@
class Topo { class Topo {
constructor(widget, settings, options) { constructor(widget, settings, options) {
let opt = options || {}, const opt = options || {},
ondone = opt.ondone || noop, ondone = opt.ondone || noop,
onupdate = opt.onupdate || noop, onupdate = opt.onupdate || noop,
shadow = opt.shadow,
proc = settings.process, proc = settings.process,
inside = proc.camContourIn,
resolution = proc.camTolerance, resolution = proc.camTolerance,
tool = new CAM.Tool(settings, proc.camContourTool), tool = new CAM.Tool(settings, proc.camContourTool),
toolOffset = tool.generateProfile(resolution).profile, toolOffset = tool.generateProfile(resolution).profile,
@ -52,7 +55,11 @@
widget: widget widget: widget
}, },
newslices = [], newslices = [],
newlines, clipTo = inside ? shadow : POLY.expand(shadow, toolDiameter),
partOff = inside ? 0 : toolDiameter / 2,
gridDelta = Math.floor(partOff / resolution);
let newlines,
newtop, newtop,
newtrace, newtrace,
sliceout, sliceout,
@ -171,31 +178,37 @@
onupdate(++stepsTaken, stepsTotal, "trace surface"); onupdate(++stepsTaken, stepsTotal, "trace surface");
} }
const checkr = newPoint(0,0);
const inClip = clipTo ? function() {
checkr.x = x;
checkr.y = y;
for (let i=0; i<clipTo.length; i++) {
if (checkr.isInPolygon(clipTo[i])) {
return true;
}
}
return false;
} : function() { return true };
// x contouring // x contouring
if (proc.camContourXOn) { if (proc.camContourXOn) {
startTime = time(); startTime = time();
// emit slice per X // emit slice per X
for (x = minX; x <= maxX; x += toolStep) { for (x = minX - partOff; x <= maxX + partOff; x += toolStep) {
gridx = Math.round(((x - minX) / boundsX) * stepsx); gridx = Math.round(((x - minX) / boundsX) * stepsx);
ly = gridy = 0; ly = gridy = -gridDelta;
slice = newSlice(gridx); slice = newSlice(gridx);
slice.camMode = CPRO.CONTOUR_X; slice.camMode = PRO.CONTOUR_X;
// slice.lines = newlines = []; // slice.lines = newlines = [];
newtop = slice.addTop(newPolygon().setOpen()).poly; newtop = slice.addTop(newPolygon().setOpen()).poly;
newtrace = newPolygon().setOpen(); newtrace = newPolygon().setOpen();
sliceout = []; sliceout = [];
for (y = minY; y < maxY; y += resolution) { for (y = minY - partOff; y < maxY + partOff; y += resolution) {
if (pocketOnly && (data[gridx * stepsy + gridy] || 0) === 0) {
end_poly();
gridy++;
ly = 0;
continue;
}
tv = toolTipZ(gridx, gridy); tv = toolTipZ(gridx, gridy);
if (tv === 0) { if (tv === 0 && clipTo && !inClip()) {
end_poly(); end_poly();
gridy++; gridy++;
ly = 0; ly = -gridDelta;
continue; continue;
} }
if (ly) { if (ly) {
@ -232,27 +245,21 @@
if (proc.camContourYOn) { if (proc.camContourYOn) {
startTime = time(); startTime = time();
// emit slice per Y // emit slice per Y
for (y = minY; y <= maxY; y += toolStep) { for (y = minY - partOff; y <= maxY + partOff; y += toolStep) {
gridy = Math.round(((y - minY) / boundsY) * stepsy); gridy = Math.round(((y - minY) / boundsY) * stepsy);
lx = gridx = 0; lx = gridx = -gridDelta;
slice = newSlice(gridy); slice = newSlice(gridy);
slice.camMode = CPRO.CONTOUR_Y; slice.camMode = PRO.CONTOUR_Y;
// slice.lines = newlines = []; // slice.lines = newlines = [];
newtop = slice.addTop(newPolygon().setOpen()).poly; newtop = slice.addTop(newPolygon().setOpen()).poly;
newtrace = newPolygon().setOpen(); newtrace = newPolygon().setOpen();
sliceout = []; sliceout = [];
for (x = minX; x <= maxX; x += resolution) { for (x = minX - partOff; x <= maxX + partOff; x += resolution) {
if (pocketOnly && (data[gridx * stepsy + gridy] || 0) === 0) {
end_poly();
gridx++;
ly = 0;
continue;
}
tv = toolTipZ(gridx, gridy); tv = toolTipZ(gridx, gridy);
if (tv === 0) { if (tv === 0 && clipTo && !inClip()) {
end_poly(); end_poly();
gridx++; gridx++;
lx = 0; lx = -gridDelta;
continue; continue;
} }
if (lx) { if (lx) {

View file

@ -290,6 +290,8 @@ kiri.lang['en-us'] = {
cf_angl_l: "angles greater than this\nare considered vertical", cf_angl_l: "angles greater than this\nare considered vertical",
cf_curv_s: "curves only", cf_curv_s: "curves only",
cf_curv_l: "limit linear cleanup\nto curved surfaces", cf_curv_l: "limit linear cleanup\nto curved surfaces",
cf_olin_s: "inside only",
cf_olin_l: "limit cutting to\ninside part boundaries",
cf_linx_s: "enable x pass", cf_linx_s: "enable x pass",
cf_linx_l: "linear x-axis finishing", cf_linx_l: "linear x-axis finishing",
cf_liny_s: "enable y pass", cf_liny_s: "enable y pass",