add level (facing) operation. add ops tool tips

This commit is contained in:
Stewart Allen 2020-12-24 20:13:11 -05:00
commit 2401c539e5
6 changed files with 117 additions and 54 deletions

View file

@ -406,6 +406,10 @@
// process defaults CAM:Process // process defaults CAM:Process
p:{ p:{
processName: "default", processName: "default",
camLevelTool: 1000,
camLevelSpindle: 1000,
camLevelOver: 0.75,
camLevelSpeed: 1000,
camRoughTool: 1000, camRoughTool: 1000,
camRoughSpindle: 1000, camRoughSpindle: 1000,
camRoughDown: 2, camRoughDown: 2,

View file

@ -550,7 +550,6 @@
// fixup un-rotates polygons for CAM // fixup un-rotates polygons for CAM
if (options.swapX || options.swapY) { if (options.swapX || options.swapY) {
let move = {x:ox, y:oy, z:0}; let move = {x:ox, y:oy, z:0};
slice.camMode = options.swapX ? CPRO.FINISH_X : CPRO.FINISH_Y;
if (topoMode) { if (topoMode) {
let lines = slice.lines, llen = lines.length, idx, line; let lines = slice.lines, llen = lines.length, idx, line;
// shared points causing problems // shared points causing problems

View file

@ -142,12 +142,9 @@
let settings = API.conf.get(); let settings = API.conf.get();
let { process, device } = settings; let { process, device } = settings;
switch (ev.target.innerText) { switch (ev.target.innerText) {
case "rough": case "level": return func.opAddLevel();
func.opAddRough(); case "rough": return func.opAddRough();
break; case "outline": return func.opAddOutline();
case "outline":
func.opAddOutline();
break;
case "contour": case "contour":
let oplist = current.process.ops, axis = "X"; let oplist = current.process.ops, axis = "X";
for (let op of oplist) { for (let op of oplist) {
@ -155,20 +152,17 @@
axis = "Y"; axis = "Y";
} }
} }
func.opAddContour(axis); return func.opAddContour(axis);
break; case "register": return func.opAddRegister('X', 2);
case "register": case "drill": return func.opAddDrill();
func.opAddRegister('X', 2); case "trace": return func.opAddTrace();
break;
case "drill":
func.opAddDrill();
break;
case "trace":
func.opAddTrace();
break;
} }
}; };
func.opAddLevel = () => {
func.opAdd(popOp.level.new());
};
func.opAddRough = () => { func.opAddRough = () => {
func.opAdd(popOp.rough.new()); func.opAdd(popOp.rough.new());
}; };
@ -636,6 +630,19 @@
return current.device.spindleMax > 0; return current.device.spindleMax > 0;
} }
createPopOp('level', {
tool: 'camLevelTool',
spindle: 'camLevelSpindle',
step: 'camLevelOver',
rate: 'camLevelSpeed'
}).inputs = {
tool: UC.newSelect(LANG.cc_tool, {}, "tools"),
sep: UC.newBlank({class:"pop-sep"}),
spindle: UC.newInput(LANG.cc_spnd_s, {title:LANG.cc_spnd_l, convert:UC.toInt, show:hasSpindle}),
step: UC.newInput(LANG.cc_sovr_s, {title:LANG.cc_sovr_l, convert:UC.toFloat, bound:UC.bound(0.01,1.0)}),
rate: UC.newInput(LANG.cc_feed_s, {title:LANG.cc_feed_l, convert:UC.toInt, units:true})
};
createPopOp('rough', { createPopOp('rough', {
tool: 'camRoughTool', tool: 'camRoughTool',
spindle: 'camRoughSpindle', spindle: 'camRoughSpindle',

View file

@ -33,6 +33,70 @@
prepare() { } prepare() { }
} }
class OpLevel extends CamOp {
constructor(state, op) {
super(state, op);
}
slice(progress) {
let { op, state } = this;
let { settings, widget, sliceAll } = state;
let { updateToolDiams, thruHoles, tabs, cutTabs } = state;
let { bounds, zMax, ztOff } = state;
let { stock } = settings;
let toolDiam = new CAM.Tool(settings, op.tool).fluteDiameter();
let stepOver = toolDiam * op.step;
updateToolDiams(toolDiam);
let path = newPolygon().setOpen(),
center = {x:0, y:0, z:0},
x1 = bounds.min.x,
y1 = bounds.min.y,
x2 = bounds.max.x,
y2 = bounds.max.y,
z = bounds.max.z;
if (stock.x && stock.y && stock.z) {
x1 = -stock.x / 2;
y1 = -stock.y / 2;
x2 = -x1;
y2 = -y1;
z = zMax + ztOff;
}
let ei = 0,
xd = x2 - x1,
xi = xd / Math.floor(xd / stepOver);
for (let x = x1, lx = x, ei = 0; x <= x2; x += xi, ei++, lx = x) {
if (ei % 2 === 0) {
path.add(x,y1,z).add(x,y2,z);
} else {
path.add(x,y2,z).add(x,y1,z);
}
}
let slice = newSlice(z);
this.lines = slice.camLines = [ path ];
slice.output()
.setLayer("level", {face: 0, line: 0})
.addPolys(this.lines);
sliceAll.push(slice);
}
prepare(ops, progress) {
let { op, state, lines } = this;
let { setTool, setSpindle } = ops;
let { polyEmit, newLayer } = ops;
setTool(op.tool, op.rate);
setSpindle(op.spindle);
polyEmit(lines[0]);
newLayer();
}
}
class OpRough extends CamOp { class OpRough extends CamOp {
constructor(state, op) { constructor(state, op) {
super(state, op); super(state, op);
@ -47,15 +111,14 @@
let roughIn = op.inside; let roughIn = op.inside;
let roughTop = op.top; let roughTop = op.top;
let roughDown = op.down; let roughDown = op.down;
let roughTool = new CAM.Tool(settings, op.tool);
let roughToolDiam = roughTool.fluteDiameter();
let roughLeave = op.leave; let roughLeave = op.leave;
let toolDiam = new CAM.Tool(settings, op.tool).fluteDiameter();
// create facing slices // create facing slices
if (roughTop) { if (roughTop) {
let shadow = tshadow.clone(); let shadow = tshadow.clone();
let inset = POLY.offset(shadow, (roughToolDiam / (roughIn ? 2 : 1))); let inset = POLY.offset(shadow, (toolDiam / (roughIn ? 2 : 1)));
let facing = POLY.offset(inset, -(roughToolDiam * op.step), { count: 999, flat: true }); let facing = POLY.offset(inset, -(toolDiam * op.step), { count: 999, flat: true });
let zdiv = ztOff / roughDown; let zdiv = ztOff / roughDown;
let zstep = (zdiv % 1 > 0) ? ztOff / (Math.floor(zdiv) + 1) : roughDown; let zstep = (zdiv % 1 > 0) ? ztOff / (Math.floor(zdiv) + 1) : roughDown;
if (ztOff === 0) { if (ztOff === 0) {
@ -68,10 +131,9 @@
for (let z = zstart; zsteps > 0; zsteps--) { for (let z = zstart; zsteps > 0; zsteps--) {
let slice = shadowTop.slice.clone(false); let slice = shadowTop.slice.clone(false);
slice.z = z; slice.z = z;
slice.camMode = PRO.LEVEL;
slice.camLines = POLY.setZ(facing.clone(true), slice.z); slice.camLines = POLY.setZ(facing.clone(true), slice.z);
slice.output() slice.output()
.setLayer("facing", {face: 0, line: 0}) .setLayer("face", {face: 0, line: 0})
.addPolys(slice.camLines); .addPolys(slice.camLines);
sliceAll.push(slice); sliceAll.push(slice);
camFaces.push(slice); camFaces.push(slice);
@ -80,7 +142,7 @@
} }
// create roughing slices // create roughing slices
updateToolDiams(roughToolDiam); updateToolDiams(toolDiam);
let flats = []; let flats = [];
let shadow = []; let shadow = [];
@ -129,7 +191,6 @@
return; return;
} }
data.shadow = shadow.clone(true); data.shadow = shadow.clone(true);
data.slice.camMode = PRO.ROUGH;
data.slice.shadow = data.shadow; data.slice.shadow = data.shadow;
// data.slice.tops[0].inner = data.shadow; // data.slice.tops[0].inner = data.shadow;
// data.slice.tops[0].inner = POLY.setZ(tshadow.clone(true), data.z); // data.slice.tops[0].inner = POLY.setZ(tshadow.clone(true), data.z);
@ -148,7 +209,7 @@
if (op.voids) { if (op.voids) {
return undefined; return undefined;
} }
let po = POLY.offset([p], -(roughToolDiam / 2 + roughLeave + 0.01)); let po = POLY.offset([p], -(toolDiam / 2 + roughLeave + 0.01));
return po ? po[0] : undefined; return po ? po[0] : undefined;
} else { } else {
return p; return p;
@ -158,8 +219,7 @@
shadow = POLY.nest(shadow); shadow = POLY.nest(shadow);
// expand shadow by half tool diameter + stock to leave // expand shadow by half tool diameter + stock to leave
// const sadd = roughIn ? roughToolDiam / 4 : roughToolDiam / 2; const sadd = roughIn ? toolDiam / 2 : toolDiam / 2;
const sadd = roughIn ? roughToolDiam / 2 : roughToolDiam / 2;
const shell = POLY.offset(shadow, sadd + roughLeave); const shell = POLY.offset(shadow, sadd + roughLeave);
slices.forEach((slice, index) => { slices.forEach((slice, index) => {
@ -168,7 +228,7 @@
let nest = POLY.setZ(POLY.nest(flat), slice.z); let nest = POLY.setZ(POLY.nest(flat), slice.z);
// inset offset array by 1/2 diameter then by tool overlap % // inset offset array by 1/2 diameter then by tool overlap %
offset = POLY.offset(nest, [-(roughToolDiam / 2 + roughLeave), -roughToolDiam * op.step], { offset = POLY.offset(nest, [-(toolDiam / 2 + roughLeave), -toolDiam * op.step], {
minArea: 0, minArea: 0,
z: slice.z, z: slice.z,
count: 999, count: 999,
@ -186,7 +246,7 @@
// add outside pass if not inside only // add outside pass if not inside only
if (!roughIn) { if (!roughIn) {
const outside = POLY.offset(shadow.clone(), roughToolDiam * op.step, {z: slice.z}); const outside = POLY.offset(shadow.clone(), toolDiam * op.step, {z: slice.z});
if (outside) { if (outside) {
offset.appendAll(outside); offset.appendAll(outside);
} }
@ -194,7 +254,7 @@
if (tabs) { if (tabs) {
tabs.forEach(tab => { tabs.forEach(tab => {
tab.off = POLY.expand([tab.poly], roughToolDiam / 2).flat(); tab.off = POLY.expand([tab.poly], toolDiam / 2).flat();
}); });
offset = cutTabs(tabs, offset, slice.z); offset = cutTabs(tabs, offset, slice.z);
} }
@ -318,9 +378,8 @@
let { settings, widget, slicer, sliceAll, tshadow } = state; let { settings, widget, slicer, sliceAll, tshadow } = state;
let { updateToolDiams, zThru, zBottom, shadowTop, tabs, cutTabs } = state; let { updateToolDiams, zThru, zBottom, shadowTop, tabs, cutTabs } = state;
let outlineTool = new CAM.Tool(settings, op.tool); let toolDiam = this.toolDiam = new CAM.Tool(settings, op.tool).fluteDiameter();
let outlineToolDiam = this.toolDiam = outlineTool.fluteDiameter(); updateToolDiams(toolDiam);
updateToolDiams(outlineToolDiam);
let shadow = []; let shadow = [];
let slices = []; let slices = [];
@ -341,7 +400,6 @@
return; return;
} }
let slice = newSlice(ind); let slice = newSlice(ind);
slice.camMode = PRO.OUTLINE;
slice.shadow = shadow.clone(true); slice.shadow = shadow.clone(true);
slices.push(slice); slices.push(slice);
}); });
@ -353,7 +411,6 @@
return; return;
} }
data.shadow = shadow.clone(true); data.shadow = shadow.clone(true);
data.slice.camMode = PRO.OUTLINE;
data.slice.shadow = data.shadow; data.slice.shadow = data.shadow;
// data.slice.tops[0].inner = data.shadow; // data.slice.tops[0].inner = data.shadow;
// data.slice.tops[0].inner = POLY.setZ(tshadow.clone(true), data.z); // data.slice.tops[0].inner = POLY.setZ(tshadow.clone(true), data.z);
@ -368,7 +425,6 @@
if (zThru) { if (zThru) {
let last = slices[slices.length-1]; let last = slices[slices.length-1];
let add = last.clone(true); let add = last.clone(true);
add.camMode = last.camMode;
add.tops.forEach(top => { add.tops.forEach(top => {
top.poly.setZ(add.z); top.poly.setZ(add.z);
}); });
@ -385,7 +441,7 @@
tops = tshadow; tops = tshadow;
} }
let offset = POLY.expand(tops, outlineToolDiam / 2, slice.z); let offset = POLY.expand(tops, toolDiam / 2, slice.z);
if (!(offset && offset.length)) { if (!(offset && offset.length)) {
return; return;
} }
@ -393,7 +449,7 @@
// when pocket only, drop first outer poly // when pocket only, drop first outer poly
// if it matches the shell and promote inner polys // if it matches the shell and promote inner polys
if (op.inside) { if (op.inside) {
let shell = POLY.expand(tops.clone(), outlineToolDiam / 2); let shell = POLY.expand(tops.clone(), toolDiam / 2);
offset = POLY.filter(offset, [], function(poly) { offset = POLY.filter(offset, [], function(poly) {
if (poly.area() < 1) { if (poly.area() < 1) {
return null; return null;
@ -409,7 +465,7 @@
}); });
} else { } else {
if (op.wide) { if (op.wide) {
let stepover = outlineToolDiam * op.step; let stepover = toolDiam * op.step;
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
@ -420,13 +476,13 @@
if (tabs) { if (tabs) {
tabs.forEach(tab => { tabs.forEach(tab => {
tab.off = POLY.expand([tab.poly], outlineToolDiam / 2).flat(); tab.off = POLY.expand([tab.poly], toolDiam / 2).flat();
}); });
offset = cutTabs(tabs, offset, slice.z); offset = cutTabs(tabs, offset, slice.z);
} }
if (op.dogbones && !op.wide) { if (op.dogbones && !op.wide) {
CAM.addDogbones(offset, outlineToolDiam / 5); CAM.addDogbones(offset, toolDiam / 5);
} }
// offset.xout(`slice ${slice.z}`); // offset.xout(`slice ${slice.z}`);
@ -615,7 +671,6 @@
let slice = newSlice(); let slice = newSlice();
let poly = newPolygon().fromArray(arr); let poly = newPolygon().fromArray(arr);
slice.addTop(poly); slice.addTop(poly);
slice.camMode = PRO.TRACE;
slice.camLines = [ poly ]; slice.camLines = [ poly ];
slice.camTrace = { tool, rate, plunge }; slice.camTrace = { tool, rate, plunge };
if (true) slice.output() if (true) slice.output()
@ -687,7 +742,6 @@
point.x = center.x; point.x = center.x;
point.y = center.y; point.y = center.y;
}); });
slice.camMode = PRO.DRILL;
slice.camLines = [ drill ]; slice.camLines = [ drill ];
slice.output() slice.output()
.setLayer("drill", {face: 0, line: 0}) .setLayer("drill", {face: 0, line: 0})
@ -764,7 +818,6 @@
.append(point.clone().setZ(bounds.max.z)) .append(point.clone().setZ(bounds.max.z))
.append(point.clone().setZ(bounds.max.z - stock.z - mz))); .append(point.clone().setZ(bounds.max.z - stock.z - mz)));
}); });
slice.camMode = PRO.DRILL;
slice.camLines = polys; slice.camLines = polys;
slice.output() slice.output()
.setLayer("register", {face: 0, line: 0}) .setLayer("register", {face: 0, line: 0})
@ -868,6 +921,7 @@
CAM.OPS = CamOp.MAP = { CAM.OPS = CamOp.MAP = {
"xray": OpXRay, "xray": OpXRay,
"shadow": OpShadow, "shadow": OpShadow,
"level": OpLevel,
"rough": OpRough, "rough": OpRough,
"outline": OpOutline, "outline": OpOutline,
"contour": OpContour, "contour": OpContour,

View file

@ -308,7 +308,6 @@
gridx = Math.round(((x - minX) / boundsX) * stepsx); gridx = Math.round(((x - minX) / boundsX) * stepsx);
ly = gridy = -gridDelta; ly = gridy = -gridDelta;
slice = newSlice(gridx); slice = newSlice(gridx);
slice.camMode = PRO.CONTOUR_X;
newtrace = newPolygon().setOpen(); newtrace = newPolygon().setOpen();
sliceout = []; sliceout = [];
for (y = minY - partOff; y < maxY + partOff; y += resolution) { for (y = minY - partOff; y < maxY + partOff; y += resolution) {
@ -351,7 +350,6 @@
gridy = Math.round(((y - minY) / boundsY) * stepsy); gridy = Math.round(((y - minY) / boundsY) * stepsy);
lx = gridx = -gridDelta; lx = gridx = -gridDelta;
slice = newSlice(gridy); slice = newSlice(gridy);
slice.camMode = PRO.CONTOUR_Y;
newtrace = newPolygon().setOpen(); newtrace = newPolygon().setOpen();
sliceout = []; sliceout = [];
for (x = minX - partOff; x <= maxX + partOff; x += resolution) { for (x = minX - partOff; x <= maxX + partOff; x += resolution) {

View file

@ -418,12 +418,13 @@
<i class="fas fa-plus"></i> <i class="fas fa-plus"></i>
<div id="op-add-pop" class="f-col"> <div id="op-add-pop" class="f-col">
<div id="op-add-list" class="opdiv"> <div id="op-add-list" class="opdiv">
<div>rough</div> <div title="clear stock face&#13;or top of part&#13;when no stock">level</div>
<div>outline</div> <div title="remove an area of material&#13;inside a defined boundary&#13;sometimes called pocketing">rough</div>
<div>contour</div> <div title="clean up after roughing&#13;or perform a part cutout">outline</div>
<div>register</div> <div title="2.5D tracing along X or Y axis&#13;used for complex part features">contour</div>
<div>trace</div> <div title="drill registration holes&#13;along the X or Y axis for&#13;double-sided milling">register</div>
<div>drill</div> <div title="follow selected features with&#13;a specified tool. often used&#13;for lettering and engraving">trace</div>
<div title="drill any holes matching&#13;selected tool diameter">drill</div>
</div> </div>
</div> </div>
</div> </div>