checkpoint trace work. wide cutout now does interiors

This commit is contained in:
Stewart Allen 2020-11-30 00:19:28 -05:00
commit 7777ea6932
7 changed files with 63 additions and 41 deletions

View file

@ -4,6 +4,7 @@
* `cnc` * `cnc`
* - tracing (chamfer, engrave) * - tracing (chamfer, engrave)
* - auto feature detection (slicing) * - auto feature detection (slicing)
* - show tool x,y,z during animation
* `laser` * `laser`
* - drag knife support * - drag knife support
* `all` * `all`

View file

@ -15,6 +15,10 @@
function time() { return Date.now() } function time() { return Date.now() }
function numOrDefault(num, def) {
return num !== undefined ? num : def;
}
/** /**
* call function with all combinations of a1, a2 * call function with all combinations of a1, a2
* and passing in the supplied arg object. * and passing in the supplied arg object.
@ -372,23 +376,24 @@
}; };
BASE.util = { BASE.util = {
sqr : sqr, sqr,
time : time, time,
round : round, round,
area2: area2, area2,
distSq : dist2, distSq : dist2,
distSqv2 : dist2v2, distSqv2 : dist2v2,
inRange : inRange, inRange,
isCloseTo : isCloseTo, isCloseTo,
inCloseRange : inCloseRange, inCloseRange,
isCollinear : isCollinear, isCollinear,
isClockwise : isClockwise, isClockwise,
isCounterClockwise : isCounterClockwise, isCounterClockwise,
doCombinations : doCombinations, doCombinations,
offsetPrecision : offsetPrecision, offsetPrecision,
intersectRayLine : intersectRayLine, intersectRayLine,
intersect : intersect, intersect,
determinant : determinant, determinant,
numOrDefault,
comma: (v) => { comma: (v) => {
if (!v) return v; if (!v) return v;
let [lt,rt] = v.toString().split('.'); let [lt,rt] = v.toString().split('.');

View file

@ -15,7 +15,8 @@
SQRT = Math.sqrt, SQRT = Math.sqrt,
SQR = UTIL.sqr, SQR = UTIL.sqr,
NOKEY = BASE.key.NONE, NOKEY = BASE.key.NONE,
newPoint = BASE.newPoint; newPoint = BASE.newPoint,
numOrDefault = UTIL.numOrDefault;
BASE.polygons = { BASE.polygons = {
rayIntersect, rayIntersect,
@ -46,10 +47,6 @@
* Polygon array utility functions * Polygon array utility functions
******************************************************************* */ ******************************************************************* */
function numOrDefault(num, def) {
return num !== undefined ? num : def;
}
function setZ(polys, z) { function setZ(polys, z) {
polys.forEach(p => p.setZ(z)); polys.forEach(p => p.setZ(z));
return polys; return polys;

View file

@ -1479,8 +1479,8 @@
lprefs: UC.newGroup(LANG.op_menu, $('prefs-gen1'), {inline: true}), lprefs: UC.newGroup(LANG.op_menu, $('prefs-gen1'), {inline: true}),
// hoverPop: UC.newBoolean(LANG.op_hopo_s, booleanSave, {title:LANG.op_hopo_l}), // hoverPop: UC.newBoolean(LANG.op_hopo_s, booleanSave, {title:LANG.op_hopo_l}),
dark: UC.newBoolean(LANG.op_dark_s, booleanSave, {title:LANG.op_dark_l}),
reverseZoom: UC.newBoolean(LANG.op_invr_s, booleanSave, {title:LANG.op_invr_l}), reverseZoom: UC.newBoolean(LANG.op_invr_s, booleanSave, {title:LANG.op_invr_l}),
dark: UC.newBoolean(LANG.op_dark_s, booleanSave, {title:LANG.op_dark_l}),
decals: UC.newBoolean(LANG.op_decl_s, booleanSave, {title:LANG.op_decl_s}), decals: UC.newBoolean(LANG.op_decl_s, booleanSave, {title:LANG.op_decl_s}),
expert: UC.newBoolean(LANG.op_xprt_s, booleanSave, {title:LANG.op_xprt_l}), expert: UC.newBoolean(LANG.op_xprt_s, booleanSave, {title:LANG.op_xprt_l}),
@ -1607,11 +1607,11 @@
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}),
// camTracing: UC.newGroup(LANG.cu_menu, null, {modes:CAM, marker:true}), camTracing: UC.newGroup(LANG.cu_menu, null, {modes:CAM, marker:true}),
// camTraceTool: UC.newSelect(LANG.cc_tool, {modes:CAM}), camTraceTool: UC.newSelect(LANG.cc_tool, {modes:CAM}),
// camTraceSpeed: UC.newInput(LANG.cc_feed_s, {title:LANG.cc_feed_l, convert:UC.toInt, modes:CAM}), camTraceSpeed: UC.newInput(LANG.cc_feed_s, {title:LANG.cc_feed_l, convert:UC.toInt, modes:CAM}),
// camTracingSep: UC.newBlank({class:"pop-sep"}), camTracingSep: UC.newBlank({class:"pop-sep"}),
// camTraceOn: UC.newBoolean(LANG.enable, onBooleanClick, {title:'todo', modes:CAM}), camTraceOn: UC.newBoolean(LANG.enable, onBooleanClick, {title:'todo', modes:CAM}),
camDrill: UC.newGroup(LANG.cd_menu, null, {modes:CAM, marker:true}), camDrill: UC.newGroup(LANG.cd_menu, null, {modes:CAM, marker:true}),
camDrillTool: UC.newSelect(LANG.cc_tool, {modes:CAM}), camDrillTool: UC.newSelect(LANG.cc_tool, {modes:CAM}),
camDrillSpindle: UC.newInput(LANG.cc_spnd_s, {title:LANG.cc_spnd_l, convert:UC.toInt, modes:CAM, visible:spindleShow}), camDrillSpindle: UC.newInput(LANG.cc_spnd_s, {title:LANG.cc_spnd_l, convert:UC.toInt, modes:CAM, visible:spindleShow}),

View file

@ -175,7 +175,7 @@
zM = Math.max(p1.z, p2.z, p3.z), zM = Math.max(p1.z, p2.z, p3.z),
bm = Math.floor(zm * zScale), bm = Math.floor(zm * zScale),
bM = Math.ceil(zM * zScale); bM = Math.ceil(zM * zScale);
for (let j = bm; j < bM; j++) { for (let j = bm; j <= bM; j++) {
buckets[j].push(p1); buckets[j].push(p1);
buckets[j].push(p2); buckets[j].push(p2);
buckets[j].push(p3); buckets[j].push(p3);
@ -203,8 +203,9 @@
} }
let znorm = z.toFixed(5), let znorm = z.toFixed(5),
flatoff = opt.flatoff || 0.01, flatoff = UTIL.numOrDefault(opt.flatoff, 0.01),
onflat = this.zFlat[znorm], onflat = this.zFlat[znorm],
edges = opt.edges || false,
phash = {}, phash = {},
lines = [], lines = [],
zScale = this.zScale, zScale = this.zScale,
@ -236,7 +237,7 @@
// one side of triangle is on the Z plane and 3rd is below // one side of triangle is on the Z plane and 3rd is below
// drop lines with 3rd above because that leads to ambiguities // drop lines with 3rd above because that leads to ambiguities
// with complex nested polygons on flat surface // with complex nested polygons on flat surface
if (where.under.length === 1) { if (edges || where.under.length === 1) {
lines.push(makeZLine(phash, where.on[0], where.on[1], false, true)); lines.push(makeZLine(phash, where.on[0], where.on[1], false, true));
} }
} else if (where.on.length === 3) { } else if (where.on.length === 3) {
@ -245,7 +246,7 @@
// that will satisfy the if above (line) with 2 points // that will satisfy the if above (line) with 2 points
} else if (where.under.length === 0 || where.over.length === 0) { } else if (where.under.length === 0 || where.over.length === 0) {
// does not intersect but one point is on the slice Z plane // does not intersect but one point is on the slice Z plane
} else { } else if (!edges) {
// compute two point intersections and construct line // compute two point intersections and construct line
let line = intersectPoints(where.over, where.under, z); let line = intersectPoints(where.over, where.under, z);
if (line.length < 2 && where.on.length === 1) { if (line.length < 2 && where.on.length === 1) {
@ -277,7 +278,7 @@
} }
const haslines = lines.length || opt.emptyok; const haslines = lines.length || opt.emptyok;
const hastops = !opt.genso || opt.notopok || (retn.tops && retn.tops.length); const hastops = !opt.genso || opt.notopok || (retn.tops && retn.tops.length) || edges;
if (opt.each && haslines && hastops) { if (opt.each && haslines && hastops) {
opt.each(retn, index, total, UTIL.time() - mark); opt.each(retn, index, total, UTIL.time() - mark);
@ -515,6 +516,7 @@
search = 1, search = 1,
nextMod = 1, nextMod = 1,
bridge = CONF.bridgeLineGapDistance, bridge = CONF.bridgeLineGapDistance,
minPoly = opt.openok ? 2 : 3,
p1, p2; p1, p2;
function cachedPoint(p) { function cachedPoint(p) {
@ -609,7 +611,7 @@
// emit a polygon if it can be cleaned and still have 2 or more points // emit a polygon if it can be cleaned and still have 2 or more points
function emit(poly) { function emit(poly) {
poly = poly.clean(); poly = poly.clean();
if (poly.length > 2) output.push(poly); if (poly.length >= minPoly) output.push(poly);
} }
// given an array of paths, emit longest to shortest // given an array of paths, emit longest to shortest
@ -641,7 +643,7 @@
// emit polygons largest to smallest // emit polygons largest to smallest
// omit polygon if it intersects previously emitted (has del points) // omit polygon if it intersects previously emitted (has del points)
paths.forEach(function(path) { paths.forEach(function(path) {
if (path.length < 3) return; if (path.length < minPoly) return;
let len = path.length, i; let len = path.length, i;
for (i = 0; i < len; i++) if (path[i].del) return; for (i = 0; i < len; i++) if (path[i].del) return;
for (i = 0; i < len; i++) path[i].del = true; for (i = 0; i < len; i++) path[i].del = true;

View file

@ -49,13 +49,13 @@
api.event.on("settings.saved", (settings) => { api.event.on("settings.saved", (settings) => {
const proc = settings.process; const proc = settings.process;
// show/hide dots in enabled process pop buttons // show/hide dots in enabled process pop buttons
// api.ui.camTabs.marker.style.display = proc.camTabsOn ? 'flex' : 'none';
api.ui.camRough.marker.style.display = proc.camRoughOn ? 'flex' : 'none'; api.ui.camRough.marker.style.display = proc.camRoughOn ? 'flex' : 'none';
api.ui.camDrill.marker.style.display = api.ui.camDrill.marker.style.display =
proc.camDrillingOn || proc.camDrillReg !== 'none' ? 'flex' : 'none'; proc.camDrillingOn || proc.camDrillReg !== 'none' ? 'flex' : 'none';
api.ui.camOutline.marker.style.display = proc.camOutlineOn ? 'flex' : 'none'; api.ui.camOutline.marker.style.display = proc.camOutlineOn ? 'flex' : 'none';
api.ui.camContour.marker.style.display = api.ui.camContour.marker.style.display =
proc.camContourXOn || proc.camContourYOn ? 'flex' : 'none'; proc.camContourXOn || proc.camContourYOn ? 'flex' : 'none';
api.ui.camTracing.marker.style.display = proc.camTraceOn ? 'flex' : 'none';
updateStock(settings, 'settings.saved.internal'); updateStock(settings, 'settings.saved.internal');
}); });

View file

@ -438,7 +438,7 @@
offset.slice().forEach(op => { offset.slice().forEach(op => {
// clone removes inners but the real solution is // clone removes inners but the real solution is
// to limit expanded shells to through holes // to limit expanded shells to through holes
POLY.expand([op.clone()], outlineToolDiam * 0.5, slice.z, offset, 1); POLY.expand([op.clone(true)], outlineToolDiam * 0.5, slice.z, offset, 1);
}); });
} }
} }
@ -484,13 +484,30 @@
} }
// prepare for tracing paths // prepare for tracing paths
let traceTool;
let traceToolProfile;
if (procTrace) { if (procTrace) {
traceTool = getToolById(conf, proc.camTraceTool); let traceTool = new CAM.Tool(conf, proc.camTraceTool);
if (traceTool.type !== 'endmill') { let traceToolDiam = traceTool.fluteDiameter();
traceToolProfile = createToolProfile(conf, proc.camTraceTool, widget.topo); maxToolDiam = Math.max(maxToolDiam, traceToolDiam);
} // unique merge of z flats and z line indices
let indices = [...new Set(Object.keys(slicer.zFlat)
.map(kv => parseFloat(kv).round(5))
.appendAll(Object.entries(slicer.zLine).map(ze => {
let [ zk, zv ] = ze;
return zv > 0 ? parseFloat(zk).round(5) : null;
})
.filter(v => v !== null)))]
.sort((a,b) => b - a);
let slices = [];
slicer.slice(indices, { each: (data, index, total) => {
let slice = data.slice;
slice.camMode = PRO.TRACE;
slices.push(slice);
sliceAll.append(slice);
if (true) slice.output()
.setLayer("trace", {line: 0x88aa55}, false)
.addPolys(slice.topPolys())
updateOp(index, total);
}, genso: true, emptyok: true, flatoff: 0, edges: true, openok: true });
} }
if (procDrill) { if (procDrill) {