add Z refining passes to complement XY smoothing in pocket contours

This commit is contained in:
Stewart Allen 2022-10-10 16:08:01 -04:00
commit c1501c7739
5 changed files with 44 additions and 5 deletions

View file

@ -456,7 +456,9 @@ base.paths = {
tip2tipEmit, tip2tipEmit,
shapeToPath, shapeToPath,
pointsToPath, pointsToPath,
pathTo3D pathTo3D,
vertexNormal: calc_vertex,
segmentNormal: calc_normal
}; };
}); });

View file

@ -1142,6 +1142,7 @@ CAM.init = function(kiri, api) {
plunge: 'camPocketPlunge', plunge: 'camPocketPlunge',
expand: 'camPocketExpand', expand: 'camPocketExpand',
smooth: 'camPocketSmooth', smooth: 'camPocketSmooth',
refine: 'cmaPocketRefine',
contour: 'camPocketContour', contour: 'camPocketContour',
outline: 'cmaPocketOutline', outline: 'cmaPocketOutline',
tolerance: 'camTolerance', tolerance: 'camTolerance',
@ -1155,6 +1156,7 @@ CAM.init = function(kiri, api) {
plunge: UC.newInput(LANG.cc_plng_s, {title:LANG.cc_plng_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"}), sep: UC.newBlank({class:"pop-sep"}),
expand: UC.newInput(LANG.cp_xpnd_s, {title:LANG.cp_xpnd_l, convert:UC.toFloat, units:true, show:() => !poppedRec.contour}), expand: UC.newInput(LANG.cp_xpnd_s, {title:LANG.cp_xpnd_l, convert:UC.toFloat, units:true, show:() => !poppedRec.contour}),
refine: UC.newInput(LANG.cp_refi_s, {title:LANG.cp_refi_l, convert:UC.toInt, show:() => poppedRec.contour}),
smooth: UC.newInput(LANG.cp_smoo_s, {title:LANG.cp_smoo_l, convert:UC.toFloat, units:true}), smooth: UC.newInput(LANG.cp_smoo_s, {title:LANG.cp_smoo_l, convert:UC.toFloat, units:true}),
tolerance: UC.newInput(LANG.ou_toll_s, {title:LANG.ou_toll_l, convert:UC.toFloat, bound:UC.bound(0,10.0), units:true, round:4, show:() => poppedRec.contour}), tolerance: UC.newInput(LANG.ou_toll_s, {title:LANG.ou_toll_l, convert:UC.toFloat, bound:UC.bound(0,10.0), units:true, round:4, show:() => poppedRec.contour}),
sep: UC.newBlank({class:"pop-sep"}), sep: UC.newBlank({class:"pop-sep"}),

View file

@ -13,7 +13,7 @@ gapp.register("kiri-mode.cam.ops", [], (root, exports) => {
const { base, kiri } = root; const { base, kiri } = root;
const { paths, polygons, newPoint, newPolygon, sliceConnect } = base; const { paths, polygons, newPoint, newPolygon, sliceConnect } = base;
const { poly2polyEmit, tip2tipEmit } = paths; const { poly2polyEmit, tip2tipEmit, segmentNormal, vertexNormal } = paths;
const { driver, newSlice } = kiri; const { driver, newSlice } = kiri;
const { CAM } = driver; const { CAM } = driver;
@ -1045,7 +1045,7 @@ class OpPocket extends CamOp {
} }
POLY.setWinding(slice.camLines, cutdir, false); POLY.setWinding(slice.camLines, cutdir, false);
if (contour) { if (contour) {
slice.camLines = pocket.conform(slice.camLines); slice.camLines = pocket.conform(slice.camLines, op.refine);
} }
slice.output() slice.output()
.setLayer("pocket", {line: color}, false) .setLayer("pocket", {line: color}, false)
@ -1093,14 +1093,46 @@ class OpPocket extends CamOp {
} }
// mold cam output lines to the surface of the topo offset by tool geometry // mold cam output lines to the surface of the topo offset by tool geometry
conform(camLines) { conform(camLines, refine = 10) {
const topo = this.topo; const topo = this.topo;
// re-segment polygon to a higher resolution
const hirez = camLines.map(p => p.segment(topo.tolerance * 2)); const hirez = camLines.map(p => p.segment(topo.tolerance * 2));
// walk points and offset from surface taking into account tool geometry
for (let poly of hirez) { for (let poly of hirez) {
for (let point of poly.points) { for (let point of poly.points) {
point.z = topo.toolAtXY(point.x, point.y); point.z = topo.toolAtXY(point.x, point.y);
} }
} }
// walk points noting z deltas and smoothing sawtooth patterns
for (let j=0; j<refine; j++)
for (let poly of hirez) {
const points = poly.points, length = points.length;
let sn = []; // segment normals
let dz = []; // z deltas
for (let i=0; i<length; i++) {
let p1 = points[i];
let p2 = points[(i + 1) % length];
dz.push(p1.z - p2.z);
sn.push(segmentNormal(p1, p2));
}
let vn = []; // vertex normals
for (let i=0; i<length; i++) {
let n1 = sn[(i + length - 1) % length];
let n2 = sn[i];
let vi = vertexNormal(n1, n2, 1);
vn.push(vi);
let vl = Math.abs(1 - vi.vl).round(2);
// vl should be close to zero on smooth / continuous curves
// factoring out hard turns, we smooth the z using the weighted
// z values of the points before and after the current point
if (vl === 0) {
let p0 = points[(i + length - 1) % length];
let p1 = points[i];
let p2 = points[(i + 1) % length];
p1.z = (p0.z + p2.z + p1.z) / 3;
}
}
}
return hirez; return hirez;
} }

View file

@ -510,6 +510,7 @@ const conf = exports({
camPocketPlunge: 200, camPocketPlunge: 200,
camPocketExpand: 0, camPocketExpand: 0,
camPocketSmooth: 0, camPocketSmooth: 0,
cmaPocketRefine: 20,
camPocketContour: false, camPocketContour: false,
cmaPocketOutline: false, cmaPocketOutline: false,
camDrillTool: 1000, camDrillTool: 1000,

View file

@ -516,7 +516,9 @@ self.kiri.lang['en-us'] = {
cp_xpnd_s: "expand", cp_xpnd_s: "expand",
cp_xpnd_l: ["grow selected area to","encompass corners"], cp_xpnd_l: ["grow selected area to","encompass corners"],
cp_smoo_s: "smooth", cp_smoo_s: "smooth",
cp_smoo_l: ["clean up jagged edges caused by angled walls. can speedup and improve pocketing for detailed geometries. recommend starting with values around 1"], cp_smoo_l: ["clean up jagged edges caused by angled walls. can speedup and improve pocketing for detailed geometries. recommend starting with values around 1 if slicing takes too long or the contours look jagged"],
cp_refi_s: "refine",
cp_refi_l: ["number of refining passes to perform on contoured polylines. meant to address Z delta sawtoothing caused by faced geometries whereas smoothing handles XY. values > 10 work well for gently contoured geometries with significant Z movement."],
cp_cont_s: "contour", cp_cont_s: "contour",
cp_cont_l: ["ignore interior voids and features"], cp_cont_l: ["ignore interior voids and features"],
cp_outl_s: "outline only", cp_outl_s: "outline only",