checkpoint cam pocket contour setup

This commit is contained in:
Stewart Allen 2022-10-10 00:00:08 -04:00
commit 56e4206930
6 changed files with 92 additions and 14 deletions

View file

@ -7,6 +7,8 @@ Full docs @ https://docs.grid.space/projects/kiri-moto
* improve CAM animation speeds
* add CAM op level part offset parameters for xy and z
* add CAM pocket smoothing and contouring which is closer to true 3 axis
* fix CAM invalidation of tabs on scale and traces on scale or rotate
* fix belt fan override for base extrusions touching belt
# Release 3.5 (2022-10-07)

View file

@ -1629,6 +1629,8 @@ class Polygon {
}
}
// cut poly using array of closed polygons. used primarily in cnc
// to cut perimeters using tabs resulting in open poly lines.
cut(polys, inter) {
let target = this;
@ -1670,7 +1672,7 @@ class Polygon {
}
}
// find the intersection of two polygons
intersect(poly, min) {
if (!this.overlaps(poly)) return null;
@ -1793,6 +1795,7 @@ class Polygon {
return this;
}
// turn 2d polygon into closed 3d mesh faces
extrude(z = 1) {
let poly = this.clone().setClockwise();
let faces = [];
@ -1810,6 +1813,42 @@ class Polygon {
}
return faces;
}
// split long straight lines into segments no longer than max
// and return a new polygon
segment(max = 1) {
const newp = [];
const points = this.points;
const length = points.length;
for (let i=0, p=points, l1=length, l2=l1+1; i<l1; i++) {
const p1 = p[i];
const p2 = p[(i + 1) % l1];
const dx = p2.x - p1.x;
const dy = p2.y - p1.y;
const dl = Math.sqrt(dx * dx + dy * dy);
newp.push(p1);
if (dl < max) {
continue;
}
const div = dl / dist;
const fit = div | 0;
const add = fit - 1;
const ix = dx / fit;
const iy = dy / fit;
let ox = p1.x + ix;
let oy = p1.y + iy;
for (let i=0; i<add; i++) {
newp.push(new Point(undefined, ox, oy));
ox += ix;
oy += iy;
}
}
if (newp.length > length) {
return newPolygon().addPoints(newp.map(p => p.clone()));
}
return this;
}
}
// use Slope.angleDiff() then re-test path mitering / rendering

View file

@ -151,6 +151,7 @@ CAM.init = function(kiri, api) {
"selection.scale",
"selection.rotate"
], () => {
if (!isCamMode) return;
for (let op of current.process.ops) {
if (op.type === 'trace') {
op.areas = {};
@ -1140,6 +1141,8 @@ CAM.init = function(kiri, api) {
rate: 'camPocketSpeed',
plunge: 'camPocketPlunge',
expand: 'camPocketExpand',
smooth: 'camPocketSmooth',
contour: 'camPocketContour',
outline: 'cmaPocketOutline'
}).inputs = {
tool: UC.newSelect(LANG.cc_tool, {}, "tools"),
@ -1150,8 +1153,11 @@ CAM.init = function(kiri, api) {
rate: UC.newInput(LANG.cc_feed_s, {title:LANG.cc_feed_l, convert:UC.toInt, units:true}),
plunge: UC.newInput(LANG.cc_plng_s, {title:LANG.cc_plng_l, convert:UC.toInt, units:true}),
sep: UC.newBlank({class:"pop-sep"}),
expand: UC.newInput(LANG.cp_xpnd_s, {title:LANG.cp_xpnd_l, convert:UC.toFloat, units:true}),
outline: UC.newBoolean(LANG.cp_outl_s, undefined, {title:LANG.cp_outl_l}),
expand: UC.newInput(LANG.cp_xpnd_s, {title:LANG.cp_xpnd_l, convert:UC.toFloat, units:true, show:() => !poppedRec.contour}),
smooth: UC.newInput(LANG.cp_smoo_s, {title:LANG.cp_smoo_l, convert:UC.toFloat, units:true}),
sep: UC.newBlank({class:"pop-sep"}),
contour: UC.newBoolean(LANG.cp_cont_s, undefined, {title:LANG.cp_cont_s}),
outline: UC.newBoolean(LANG.cp_outl_s, undefined, {title:LANG.cp_outl_l, show:() => !poppedRec.contour}),
sep: UC.newBlank({class:"pop-sep"}),
menu: UC.newRow([
UC.newButton(undefined, func.surfaceAdd, {icon:'<i class="fas fa-plus"></i>'}),

View file

@ -957,8 +957,9 @@ class OpPocket extends CamOp {
}
slice(progress) {
const debug = true;
let { op, state } = this;
let { tool, rate, down, plunge, expand } = op;
let { tool, rate, down, plunge, expand, contour, smooth } = op;
let { settings, widget, sliceAll, zMax, zTop, zThru, tabs, color } = state;
let { updateToolDiams, cutTabs, cutPolys, healPolys, shadowAt } = state;
let { process, stock } = settings;
@ -967,6 +968,9 @@ class OpPocket extends CamOp {
let toolDiam = new CAM.Tool(settings, tool).fluteDiameter();
let toolOver = toolDiam * op.step;
let cutdir = process.camConventional;
if (contour) {
down = 0;
}
updateToolDiams(toolDiam);
if (tabs) {
tabs.forEach(tab => {
@ -987,13 +991,32 @@ class OpPocket extends CamOp {
down = diff / Math.ceil(diff / down);
}
let zs = down ? base.util.lerp(zTop, z, down) : [ z ];
if (expand) polys = POLY.offset(polys, expand);
let zpro = 0, zinc = 1 / (polys.length * zs.length);
if (contour) {
expand = toolOver;
}
if (expand) {
polys = POLY.offset(polys, expand);
}
let zpro = 0, zinc = 1 / (polys.length * zs.length);
for (let poly of polys) {
for (let z of zs) {
let shadow = shadowAt(z);
let clip = [];
POLY.subtract([ poly ], shadow, clip);
let clip = [], shadow;
if (contour) {
if (smooth) {
clip = POLY.offset(POLY.offset([ poly ], smooth), -smooth);
} else {
clip = [ poly ];
}
} else {
shadow = shadowAt(z);
if (smooth) {
shadow = POLY.offset(POLY.offset(shadow, smooth), -smooth);
}
POLY.subtract([ poly ], shadow, clip);
}
if (clip.length === 0) {
continue;
}
let slice = newSliceOut(z);
slice.camTrace = { tool, rate, plunge };
POLY.offset(clip, [ -toolDiam / 2, -toolOver ], {
@ -1008,7 +1031,7 @@ class OpPocket extends CamOp {
slice.output()
.setLayer("pocket", {line: color}, false)
.addPolys(slice.camLines)
if (false) slice.output()
if (debug && shadow) slice.output()
.setLayer("pocket shadow", {line: 0xff8811}, false)
.addPolys(shadow)
progress(zpro += zinc, "pocket");
@ -1032,15 +1055,17 @@ class OpPocket extends CamOp {
outline = POLY.union(outline, 0.0001, true);
outline = POLY.setWinding(outline, cutdir, false);
outline = healPolys(outline);
let pinc = 1;
if (smooth) {
outline = POLY.offset(POLY.offset(outline, smooth), -smooth);
}
if (outline.length) {
// option to skip interior features (holes, pillars)
if (op.outline) {
if (!contour && op.outline) {
for (let p of outline) {
p.inner = undefined;
}
}
if (false) newSliceOut(zmin).output()
if (debug) newSliceOut(zmin).output()
.setLayer("pocket area", {line: 0x1188ff}, false)
.addPolys(outline)
clearZ(outline, zmin + 0.0001, down);
@ -1055,7 +1080,7 @@ class OpPocket extends CamOp {
setTool(op.tool, op.rate);
setSpindle(op.spindle);
let i=0, l=sliceOut.length;
for (let slice of sliceOut) {
for (let slice of sliceOut.filter(s => s.camLines)) {
ops.emitTrace(slice);
progress(++i / l, "pocket");
}

View file

@ -509,6 +509,8 @@ const conf = exports({
camPocketSpeed: 250,
camPocketPlunge: 200,
camPocketExpand: 0,
camPocketSmooth: 0,
camPocketContour: false,
cmaPocketOutline: false,
camDrillTool: 1000,
camDrillSpindle: 1000,

View file

@ -515,6 +515,10 @@ self.kiri.lang['en-us'] = {
// CNC POCKET
cp_xpnd_s: "expand",
cp_xpnd_l: ["grow selected area to","encompass corners"],
cp_smoo_s: "smooth",
cp_smoo_l: ["clean up jagged edges caused by highly angled walls. can speedup pocketing for detailed geometries. recommend a value around 1"],
cp_cont_s: "contour",
cp_cont_l: ["ignore interior voids and features"],
cp_outl_s: "outline only",
cp_outl_l: ["ignore interior voids and features"],