add tab support in contouring

This commit is contained in:
Stewart Allen 2020-11-14 13:19:37 -05:00
commit a66a794f14
4 changed files with 61 additions and 35 deletions

View file

@ -3,7 +3,6 @@
## 2.3 remaining
* adaptive shadow-line generation for small parts collision detection
* test path clearance for every move > % of tool diam and ...
* contour tabs support
* path arrows, retracts, and engages
* cap path ends
* help dialog

View file

@ -1507,7 +1507,7 @@
camDrillingOn: UC.newBoolean(LANG.enable, onBooleanClick, {modes:CAM}),
camDrillSep: UC.newBlank({class:"pop-sep"}),
camDrillReg: UC.newSelect(LANG.cd_regi_s, {modes:CAM, title:LANG.cd_regi_l}, "drillreg"),
camTabs: UC.newGroup(LANG.ct_menu, null, {modes:CAM, marker:true, show:() => { return UI.camOutlineOn.checked || UI.camRoughOn.checked }}),
camTabs: UC.newGroup(LANG.ct_menu, null, {modes:CAM, marker:true}),
camTabsAngle: UC.newInput(LANG.ct_angl_s, {title:LANG.ct_angl_l, convert:UC.toInt, bound:UC.bound(0,360), modes:CAM}),
camTabsCount: UC.newInput(LANG.ct_numb_s, {title:LANG.ct_numb_l, convert:UC.toInt, bound:UC.bound(1,20), modes:CAM}),
camTabsWidth: UC.newInput(LANG.ct_wdth_s, {title:LANG.ct_wdth_l, convert:UC.toFloat, bound:UC.bound(0.1,100), modes:CAM, units:true}),

View file

@ -469,43 +469,30 @@
}
// cut outside traces at the right points
function addCutoutTabs(offset, z, toolDiam, tabWidth, tabCount, tabAngle) {
function addCutoutTabs(polys, z, toolDiam, tabWidth, tabCount, tabAngle) {
// skip if no tops | traces
if (offset.length === 0) return offset;
if (polys.length === 0) return polys;
let notabs = 0;
let nutrace = [];
// find trace with greatest area
offset.forEach(function(trace, index) {
polys.forEach(function(trace, index) {
// required to match computed order of cutouts
trace.setClockwise();
let count = tabCount,
angle = tabAngle,
angle_inc = 360 / count,
center = trace.bounds.center(z),
offset = (tabWidth + toolDiam) / 2,
ints = [],
segs = [];
while (count-- > 0) {
let slope = BASE.newSlopeFromAngle(angle),
normal = BASE.newSlopeFromAngle(angle + 90),
c1 = center.projectOnSlope(normal, offset),
c2 = center.projectOnSlope(normal, -offset),
o1 = c1.projectOnSlope(slope, 10000),
o2 = c2.projectOnSlope(slope, 10000),
let ints = [];
let center = trace.bounds.center(z);
CAM.createTabLines(center, toolDiam, tabWidth, tabCount, tabAngle).forEach(tab => {
const {c1, c2, o1, o2} = tab,
int1 = trace.intersections(c1, o1).pop(),
int2 = trace.intersections(c2, o2).pop();
if (int1 && int2) {
ints.push(int1);
ints.push(int2);
}
angle -= angle_inc;
}
});
let segs = [];
if (ints.length) {
ints.push(ints.shift());
for (let i=0; i<ints.length; i+=2) {
@ -529,7 +516,6 @@
nutrace.push(trace);
notabs++;
}
});
if (notabs) {
@ -539,4 +525,23 @@
return nutrace;
}
CAM.createTabLines = function(center, toolDiam, tabWidth, tabCount, tabAngle) {
let angle_inc = 360 / tabCount,
offset = (tabWidth + toolDiam) / 2,
lines = [];
while (tabCount-- > 0) {
let slope = BASE.newSlopeFromAngle(tabAngle),
normal = BASE.newSlopeFromAngle(tabAngle + 90),
c1 = center.projectOnSlope(normal, offset),
c2 = center.projectOnSlope(normal, -offset),
o1 = c1.projectOnSlope(slope, 10000),
o2 = c2.projectOnSlope(slope, 10000);
tabAngle -= angle_inc;
lines.push({c1, o1, c2, o2});
}
return lines;
}
})();

View file

@ -56,12 +56,30 @@
widget: widget
},
newslices = [],
tabsOn = proc.camTabsOn,
tabHeight = proc.camTabsHeight,
clipTab = tabsOn ? [] : null,
clipTo = inside ? shadow : POLY.expand(shadow, toolDiameter + resolution),
partOff = inside ? 0 : toolDiameter / 2 + resolution,
gridDelta = Math.floor(partOff / resolution);
let newlines,
newtop,
if (proc.camTabsOn) {
CAM.createTabLines(
clipTo[0].bounds.center(),
toolDiameter,
proc.camTabsWidth,
proc.camTabsCount,
proc.camTabsAngle
).forEach(tab => {
const { o1, o2, c1, c2 } = tab;
const poly = newPolygon().addPoints([
o1, c1, c2, o2
]);
clipTab.push(poly);
});
}
let newtop,
newtrace,
sliceout,
latent,
@ -174,16 +192,16 @@
}
const checkr = newPoint(0,0);
const inClip = clipTo ? function() {
const inClip = function(polys) {
checkr.x = x;
checkr.y = y;
for (let i=0; i<clipTo.length; i++) {
if (checkr.isInPolygon(clipTo[i])) {
for (let i=0; i<polys.length; i++) {
if (checkr.isInPolygon(polys[i])) {
return true;
}
}
return false;
} : function() { return true };
};
// x contouring
if (proc.camContourXOn) {
@ -194,13 +212,15 @@
ly = gridy = -gridDelta;
slice = newSlice(gridx);
slice.camMode = PRO.CONTOUR_X;
// slice.lines = newlines = [];
newtop = slice.addTop(newPolygon().setOpen()).poly;
newtrace = newPolygon().setOpen();
sliceout = [];
for (y = minY - partOff; y < maxY + partOff; y += resolution) {
tv = toolTipZ(gridx, gridy);
if (tv === 0 && clipTo && !inClip()) {
if (tabsOn && tv < tabHeight && inClip(clipTab)) {
tv = tabHeight;
}
if (tv === 0 && clipTo && !inClip(clipTo)) {
end_poly();
gridy++;
ly = -gridDelta;
@ -245,13 +265,15 @@
lx = gridx = -gridDelta;
slice = newSlice(gridy);
slice.camMode = PRO.CONTOUR_Y;
// slice.lines = newlines = [];
newtop = slice.addTop(newPolygon().setOpen()).poly;
newtrace = newPolygon().setOpen();
sliceout = [];
for (x = minX - partOff; x <= maxX + partOff; x += resolution) {
tv = toolTipZ(gridx, gridy);
if (tv === 0 && clipTo && !inClip()) {
if (tabsOn && tv < tabHeight && inClip(clipTab)) {
tv = tabHeight;
}
if (tv === 0 && clipTo && !inClip(clipTo)) {
end_poly();
gridx++;
lx = -gridDelta;