add option to cutout thru pockets instead of clearing them in roughing
This commit is contained in:
parent
8e656939e7
commit
c5f397dfdd
5 changed files with 94 additions and 11 deletions
|
|
@ -864,9 +864,9 @@ var gs_base_polygon = exports;
|
||||||
* @param {number} [tolerance]
|
* @param {number} [tolerance]
|
||||||
* @returns {boolean} all points inside poly AND not inside children
|
* @returns {boolean} all points inside poly AND not inside children
|
||||||
*/
|
*/
|
||||||
PRO.contains = function(poly, tolerance) {
|
// PRO.contains = function(poly, tolerance) {
|
||||||
return (poly && poly.isInside(this, tolerance) && poly.isOutsideAll(this.inner, tolerance));
|
// return (poly && poly.isInside(this, tolerance) && poly.isOutsideAll(this.inner, tolerance));
|
||||||
};
|
// };
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
|
@ -1095,7 +1095,9 @@ var gs_base_polygon = exports;
|
||||||
*/
|
*/
|
||||||
PRO.isEquivalent = function(poly, recurse, precision) {
|
PRO.isEquivalent = function(poly, recurse, precision) {
|
||||||
// throw new Error("isEquivalent");
|
// throw new Error("isEquivalent");
|
||||||
if (UTIL.isCloseTo(this.area(), poly.area(), precision || CONF.precision_poly_area) &&
|
let area1 = Math.abs(this.area());
|
||||||
|
let area2 = Math.abs(poly.area());
|
||||||
|
if (UTIL.isCloseTo(area1, area2, precision || CONF.precision_poly_area) &&
|
||||||
this.bounds.equals(poly.bounds, precision || CONF.precision_poly_bounds))
|
this.bounds.equals(poly.bounds, precision || CONF.precision_poly_bounds))
|
||||||
{
|
{
|
||||||
// use circularity near 1 to eliminate the extensive check below
|
// use circularity near 1 to eliminate the extensive check below
|
||||||
|
|
@ -1244,6 +1246,38 @@ var gs_base_polygon = exports;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
PRO.intersect = function(poly, min) {
|
||||||
|
if (!this.overlaps(poly)) return null;
|
||||||
|
|
||||||
|
let clib = self.ClipperLib,
|
||||||
|
ctyp = clib.ClipType,
|
||||||
|
ptyp = clib.PolyType,
|
||||||
|
cfil = clib.PolyFillType,
|
||||||
|
clip = new clib.Clipper(),
|
||||||
|
ctre = new clib.PolyTree(),
|
||||||
|
sp1 = this.toClipper(),
|
||||||
|
sp2 = poly.toClipper(),
|
||||||
|
minarea = min >= 0 ? min : 0.1;
|
||||||
|
|
||||||
|
if (this.isInside(poly)) {
|
||||||
|
return [ this ];
|
||||||
|
}
|
||||||
|
|
||||||
|
clip.AddPaths(sp1, ptyp.ptSubject, true);
|
||||||
|
clip.AddPaths(sp2, ptyp.ptClip, true);
|
||||||
|
|
||||||
|
if (clip.Execute(ctyp.ctIntersection, ctre, cfil.pftNonZero, cfil.pftNonZero)) {
|
||||||
|
let inter = POLY()
|
||||||
|
.fromClipperTreeUnion(ctre, poly.getZ(), minarea)
|
||||||
|
// .filter(p => p.isEquivalent(this) || p.isInside(this))
|
||||||
|
.filter(p => p.isInside(this))
|
||||||
|
;
|
||||||
|
return inter;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* return logical OR of two polygons' enclosed areas
|
* return logical OR of two polygons' enclosed areas
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -359,6 +359,7 @@ let gs_kiri_conf = exports;
|
||||||
roughingSpeed: 1000,
|
roughingSpeed: 1000,
|
||||||
roughingPlunge: 250,
|
roughingPlunge: 250,
|
||||||
roughingStock: 0,
|
roughingStock: 0,
|
||||||
|
roughingPocket: true,
|
||||||
roughingOn: true,
|
roughingOn: true,
|
||||||
finishingTool: 1000,
|
finishingTool: 1000,
|
||||||
finishingSpindle: 1000,
|
finishingSpindle: 1000,
|
||||||
|
|
|
||||||
|
|
@ -212,7 +212,7 @@ var gs_kiri_cam = exports;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* top down progressive union for CAM
|
* top down progressive union
|
||||||
*/
|
*/
|
||||||
function pancake(slices, onupdate) {
|
function pancake(slices, onupdate) {
|
||||||
let union, tops, last;
|
let union, tops, last;
|
||||||
|
|
@ -237,6 +237,40 @@ var gs_kiri_cam = exports;
|
||||||
return last.clone(false);
|
return last.clone(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* bottom up progressive intersection of holes
|
||||||
|
*/
|
||||||
|
function holes(slices, offset, onupdate) {
|
||||||
|
let last;
|
||||||
|
|
||||||
|
slices.reverse().forEach(function(slice,index) {
|
||||||
|
let holes = slice.gatherTopPolyInners([]).clone();
|
||||||
|
if (last) {
|
||||||
|
let inter = [];
|
||||||
|
holes.forEach(hole => {
|
||||||
|
last.forEach(poly => {
|
||||||
|
inter.appendAll(hole.intersect(poly));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
last = inter.filter((poly, index, arr) => {
|
||||||
|
for (let i=index+1, il=arr.length; i<il; i++) {
|
||||||
|
if (arr[i].isEquivalent(poly)) return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
last = holes;
|
||||||
|
}
|
||||||
|
// console.log('holes', slice.z, index, holes, last);
|
||||||
|
if (onupdate) onupdate(index/slices.length);
|
||||||
|
});
|
||||||
|
|
||||||
|
let out = [];
|
||||||
|
POLY.expand(last, -offset*1.1, 0, out, 1);
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {Slice[]} slices
|
* @param {Slice[]} slices
|
||||||
* @param {number} z position
|
* @param {number} z position
|
||||||
|
|
@ -625,11 +659,17 @@ var gs_kiri_cam = exports;
|
||||||
* @param {boolean} true for pocket only mode
|
* @param {boolean} true for pocket only mode
|
||||||
* @returns {Object} shell or newly generated shell
|
* @returns {Object} shell or newly generated shell
|
||||||
*/
|
*/
|
||||||
function createRoughingSlices(slice, shell, diameter, stock, overlap, pocket) {
|
function createRoughingSlices(slice, shell, diameter, stock, overlap, pocket, holes) {
|
||||||
let tops = slice.gatherTopPolys([]).clone(true),
|
let tops = slice.gatherTopPolys([]).clone(true),
|
||||||
outer = [],
|
outer = [],
|
||||||
offset = [];
|
offset = [];
|
||||||
|
|
||||||
|
// when holes present, use them as fake top offsets
|
||||||
|
// to prevent clearing out the entire thru pocket
|
||||||
|
if (holes) {
|
||||||
|
tops.appendAll(holes);
|
||||||
|
}
|
||||||
|
|
||||||
// clone and flatten the shell with tops to offset array
|
// clone and flatten the shell with tops to offset array
|
||||||
shell.clone(true).forEach(function(poly) { poly.setZ(slice.z).flattenTo(offset) });
|
shell.clone(true).forEach(function(poly) { poly.setZ(slice.z).flattenTo(offset) });
|
||||||
POLY.flatten(tops, offset, true);
|
POLY.flatten(tops, offset, true);
|
||||||
|
|
@ -810,9 +850,11 @@ var gs_kiri_cam = exports;
|
||||||
mesh = widget.mesh,
|
mesh = widget.mesh,
|
||||||
bounds = widget.getBoundingBox(),
|
bounds = widget.getBoundingBox(),
|
||||||
zMin = MAX(bounds.min.z, proc.camZBottom) * units,
|
zMin = MAX(bounds.min.z, proc.camZBottom) * units,
|
||||||
|
roughingStock = proc.roughingStock * units,
|
||||||
shellRough,
|
shellRough,
|
||||||
shellFinish,
|
shellFinish,
|
||||||
facePolys;
|
facePolys,
|
||||||
|
thruHoles;
|
||||||
|
|
||||||
if (settings.stock.x + 0.00001 < bounds.max.x - bounds.min.x) {
|
if (settings.stock.x + 0.00001 < bounds.max.x - bounds.min.x) {
|
||||||
return ondone('stock X too small for part. disable or use offset stock');
|
return ondone('stock X too small for part. disable or use offset stock');
|
||||||
|
|
@ -902,14 +944,14 @@ var gs_kiri_cam = exports;
|
||||||
|
|
||||||
if (procRough && !pocketOnlyRough) {
|
if (procRough && !pocketOnlyRough) {
|
||||||
// expand shell by half tool diameter + stock to leave
|
// expand shell by half tool diameter + stock to leave
|
||||||
shellRough = facePolys = POLY.expand(shellRough, (roughToolDiam / 2) + proc.roughingStock, 0);
|
shellRough = facePolys = POLY.expand(shellRough, (roughToolDiam / 2) + roughingStock, 0);
|
||||||
} else {
|
} else {
|
||||||
// expand shell minimally triggering a clean
|
// expand shell minimally triggering a clean
|
||||||
shellRough = facePolys = POLY.expand(shellRough, 0.01, 0);
|
shellRough = facePolys = POLY.expand(shellRough, 0.01, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (anyFinish && pocketOnlyRough && !pocketOnlyFinish) {
|
if (anyFinish && pocketOnlyRough && !pocketOnlyFinish) {
|
||||||
facePolys = POLY.expand(shellRough, (roughToolDiam / 2) + proc.roughingStock, 0);
|
facePolys = POLY.expand(shellRough, (roughToolDiam / 2) + roughingStock, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (anyFinish && pocketOnlyFinish) {
|
if (anyFinish && pocketOnlyFinish) {
|
||||||
|
|
@ -941,6 +983,9 @@ var gs_kiri_cam = exports;
|
||||||
let selected = [];
|
let selected = [];
|
||||||
selectSlices(slices, proc.roughingDown * units, CPRO.ROUGH, selected);
|
selectSlices(slices, proc.roughingDown * units, CPRO.ROUGH, selected);
|
||||||
sliceAll.appendAll(selected);
|
sliceAll.appendAll(selected);
|
||||||
|
if (!proc.roughingPocket) {
|
||||||
|
thruHoles = holes(slices, roughToolDiam + roughingStock);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (procFinish) {
|
if (procFinish) {
|
||||||
|
|
@ -1034,7 +1079,7 @@ var gs_kiri_cam = exports;
|
||||||
break;
|
break;
|
||||||
case CPRO.ROUGH:
|
case CPRO.ROUGH:
|
||||||
modekey = "roughing";
|
modekey = "roughing";
|
||||||
createRoughingSlices(slice, shellRough, roughToolDiam, proc.roughingStock * units, proc.roughingOver, pocketOnlyRough);
|
createRoughingSlices(slice, shellRough, roughToolDiam, roughingStock, proc.roughingOver, pocketOnlyRough, thruHoles);
|
||||||
if (addTabsRough) addCutoutTabs(slice, roughToolDiam);
|
if (addTabsRough) addCutoutTabs(slice, roughToolDiam);
|
||||||
break;
|
break;
|
||||||
case CPRO.FINISH:
|
case CPRO.FINISH:
|
||||||
|
|
|
||||||
|
|
@ -1353,8 +1353,8 @@ var gs_kiri_init = exports;
|
||||||
roughingSpeed: UC.newInput(LANG.cc_feed_s, {title:LANG.cc_feed_l, convert:UC.toInt, modes:CAM}),
|
roughingSpeed: UC.newInput(LANG.cc_feed_s, {title:LANG.cc_feed_l, convert:UC.toInt, modes:CAM}),
|
||||||
roughingPlunge: UC.newInput(LANG.cc_plng_s, {title:LANG.cc_plng_l, convert:UC.toInt, modes:CAM}),
|
roughingPlunge: UC.newInput(LANG.cc_plng_s, {title:LANG.cc_plng_l, convert:UC.toInt, modes:CAM}),
|
||||||
roughingStock: UC.newInput(LANG.cr_lsto_s, {title:LANG.cr_lsto_l, convert:UC.toFloat, modes:CAM}),
|
roughingStock: UC.newInput(LANG.cr_lsto_s, {title:LANG.cr_lsto_l, convert:UC.toFloat, modes:CAM}),
|
||||||
|
roughingPocket: UC.newBoolean(LANG.cr_clrp_s, onBooleanClick, {title:LANG.cr_clrp_l, modes:CAM}),
|
||||||
camPocketOnlyRough: UC.newBoolean(LANG.cc_pock_s, onBooleanClick, {title:LANG.cc_pock_l, modes:CAM}),
|
camPocketOnlyRough: UC.newBoolean(LANG.cc_pock_s, onBooleanClick, {title:LANG.cc_pock_l, modes:CAM}),
|
||||||
camEaseDown: UC.newBoolean(LANG.cr_ease_s, onBooleanClick, {title:LANG.cr_ease_l, modes:CAM}),
|
|
||||||
roughingOn: UC.newBoolean(LANG.enable, onBooleanClick, {modes:CAM}),
|
roughingOn: UC.newBoolean(LANG.enable, onBooleanClick, {modes:CAM}),
|
||||||
|
|
||||||
finishing: UC.newGroup(LANG.cf_menu, null, {modes:CAM}),
|
finishing: UC.newGroup(LANG.cf_menu, null, {modes:CAM}),
|
||||||
|
|
@ -1412,6 +1412,7 @@ var gs_kiri_init = exports;
|
||||||
camZBottom: UC.newInput(LANG.ou_zbot_s, {title:LANG.ou_zbot_l, convert:UC.toFloat, modes:CAM}),
|
camZBottom: UC.newInput(LANG.ou_zbot_s, {title:LANG.ou_zbot_l, convert:UC.toFloat, modes:CAM}),
|
||||||
camZClearance: UC.newInput(LANG.ou_zclr_s, {title:LANG.ou_zclr_l, convert:UC.toFloat, bound:UC.bound(0.01,100), modes:CAM}),
|
camZClearance: UC.newInput(LANG.ou_zclr_s, {title:LANG.ou_zclr_l, convert:UC.toFloat, bound:UC.bound(0.01,100), modes:CAM}),
|
||||||
outputClockwise: UC.newBoolean(LANG.ou_conv_s, onBooleanClick, {title:LANG.ou_conv_l, modes:CAM}),
|
outputClockwise: UC.newBoolean(LANG.ou_conv_s, onBooleanClick, {title:LANG.ou_conv_l, modes:CAM}),
|
||||||
|
camEaseDown: UC.newBoolean(LANG.cr_ease_s, onBooleanClick, {title:LANG.cr_ease_l, modes:CAM}),
|
||||||
camDepthFirst: UC.newBoolean(LANG.ou_depf_s, onBooleanClick, {title:LANG.ou_depf_l, modes:CAM}),
|
camDepthFirst: UC.newBoolean(LANG.ou_depf_s, onBooleanClick, {title:LANG.ou_depf_l, modes:CAM}),
|
||||||
|
|
||||||
camStock: UC.newGroup(LANG.cs_menu, null, {modes:CAM}),
|
camStock: UC.newGroup(LANG.cs_menu, null, {modes:CAM}),
|
||||||
|
|
|
||||||
|
|
@ -245,6 +245,8 @@ kiri.lang['en-us'] = {
|
||||||
cr_lsto_l: "horizontal offset from vertical faces\nstock to leave for finishing pass\nin workspace units",
|
cr_lsto_l: "horizontal offset from vertical faces\nstock to leave for finishing pass\nin workspace units",
|
||||||
cr_ease_s: "ease down",
|
cr_ease_s: "ease down",
|
||||||
cr_ease_l: "plunge cuts will\nspiral down or ease\nalong a linear path",
|
cr_ease_l: "plunge cuts will\nspiral down or ease\nalong a linear path",
|
||||||
|
cr_clrp_s: "pocket clear",
|
||||||
|
cr_clrp_l: "mill out entire pocket instead\nof just cutting the outline",
|
||||||
|
|
||||||
// CNC FINISHING
|
// CNC FINISHING
|
||||||
cf_menu: "finishing",
|
cf_menu: "finishing",
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue