Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implementing corner cutouts #103

Open
Windfisch opened this issue Aug 24, 2024 · 1 comment
Open

Implementing corner cutouts #103

Windfisch opened this issue Aug 24, 2024 · 1 comment

Comments

@Windfisch
Copy link

Hello,

first of all, thanks for the awesome work on the openbuilds-cam project so far. Looks really promising!

I would like to use the OpenBuilds CAM (+CONTROL) softwares into our maker space, and am missing some features; I am able to implement them, but am not sure where to start and which is the appropriate way of discussion.

I'd like to add a feature (checkbox) to enable corner cutouts ("dogbones") to outside and inside path operations, such that not too few material is removed (but too much). Also, I'd like to add some support for holding tabs and holding tabs at user-defined positions.

Is there anything to look out for when starting? Is GitHub issues the right place for this kind of discussions, or do you have a mailing list or similar?

Best regards,
Windfisch

@petervanderwalt
Copy link
Contributor

Github issues is fine.

Shoot any questions you might have but sure, happy to have someone sticking in new features.

Mainly we do toolpathing in clipper.js - checkout the Toolpathworker (we do it in a webworker to keep frontend reactive) https://github.com/OpenBuilds/OpenBuilds-CAM/tree/master/workers/toolpath/worker

Clipper path is used to draw previews and generate gcode from https://github.com/OpenBuilds/OpenBuilds-CAM/blob/master/js/advanced-cam-gcode.js - so key thing is to let whatever you do happen on that early level (then usually the previews and gcode just follows what happens there - thats why you'll see tabs etc is done in the worker already too)

Current automated Tabs are around here

for (var r = 0; r < numTabs; r++) {
// then for each tab
// add another point at the current point +tabPaddingPerSpace
npt = newPointFromDistanceAndAngle(npt, ang, tabPaddingPerSpace);
// g += 'G1' + feedrate + ' X' + npt[0] + ' Y' + npt[1] + '\n';
lineUnionGeo.vertices.push(new THREE.Vector3(npt[0], npt[1], config.z));
// then we raise the z height by config.tabHeight
lineUnionGeo.vertices.push(new THREE.Vector3(npt[0], npt[1], config.tabdepth));
// g += 'G0 Z' + tabsBelowZ + '\n';
// then add another point at the current point +tabWidth
npt = newPointFromDistanceAndAngle(npt, ang, config.tabwidth + config.toolDia);
lineUnionGeo.vertices.push(new THREE.Vector3(npt[0], npt[1], config.tabdepth));
// g += 'G0' + feedrate + ' X' + npt[0] + ' Y' + npt[1] + '\n';
// then lower the z height back to zPos at plunge speed
// g += 'G0 F' + plungeSpeed + ' Z' + tabsBelowZ + '\n';
// g += 'G1 F' + plungeSpeed + ' Z' + zpos + '\n';
lineUnionGeo.vertices.push(new THREE.Vector3(npt[0], npt[1], config.z));
// then add another point at the current point +tabPaddingPerSpace
// with the cut speed
npt = newPointFromDistanceAndAngle(npt, ang, tabPaddingPerSpace);
lineUnionGeo.vertices.push(new THREE.Vector3(npt[0], npt[1], config.z));
// g += 'G1' + feedrate + ' X' + npt[0] + ' Y' + npt[1] + '\n';
}
and
for (var r = 0; r < numTabs; r++) {
var clipperTabsArr = [];
// then for each tab
// add another point at the current point +tabPaddingPerSpace
npt = newPointFromDistanceAndAngle(npt, ang, tabPaddingPerSpace);
// g += 'G1' + feedrate + ' X' + npt[0] + ' Y' + npt[1] + '\n';
lineUnionGeo.vertices.push(new THREE.Vector3(npt[0], npt[1], config.z));
clipperArr.push({
X: npt[0],
Y: npt[1]
});
clipperTabsArr.push({
X: npt[0],
Y: npt[1]
});
// then we raise the z height by config.tabHeight
lineUnionGeo.vertices.push(new THREE.Vector3(npt[0], npt[1], config.tabdepth));
clipperArr.push({
X: npt[0],
Y: npt[1]
});
clipperTabsArr.push({
X: npt[0],
Y: npt[1]
});
// g += 'G0 Z' + tabsBelowZ + '\n';
// then add another point at the current point +tabWidth
npt = newPointFromDistanceAndAngle(npt, ang, config.tabwidth + config.toolDia);
lineUnionGeo.vertices.push(new THREE.Vector3(npt[0], npt[1], config.tabdepth));
clipperArr.push({
X: npt[0],
Y: npt[1]
});
clipperTabsArr.push({
X: npt[0],
Y: npt[1]
});
// g += 'G0' + feedrate + ' X' + npt[0] + ' Y' + npt[1] + '\n';
// then lower the z height back to zPos at plunge speed
// g += 'G0 F' + plungeSpeed + ' Z' + tabsBelowZ + '\n';
// g += 'G1 F' + plungeSpeed + ' Z' + zpos + '\n';
lineUnionGeo.vertices.push(new THREE.Vector3(npt[0], npt[1], config.z));
clipperArr.push({
X: npt[0],
Y: npt[1]
});
clipperTabsArr.push({
X: npt[0],
Y: npt[1]
});
// then add another point at the current point +tabPaddingPerSpace
// with the cut speed
npt = newPointFromDistanceAndAngle(npt, ang, tabPaddingPerSpace);
lineUnionGeo.vertices.push(new THREE.Vector3(npt[0], npt[1], config.z));
clipperArr.push({
X: npt[0],
Y: npt[1]
});
clipperTabsPaths.push(clipperTabsArr);
// g += 'G1' + feedrate + ' X' + npt[0] + ' Y' + npt[1] + '\n';
}
} else { // line isnt long enough
lineUnionGeo.vertices.push(new THREE.Vector3(config.paths[i][j].X, config.paths[i][j].Y, config.z));
clipperArr.push({
X: config.paths[i][j].X,
Y: config.paths[i][j].Y
});

Our dragknife toolpaths does so swivel action in the corners

addCornerActions = function(clipperPolyline, clipperRadius, toleranceAngleRadians) {
console.log("clipperPolyline Starting : ", clipperPolyline);
if (clipperRadius == 0 || clipperPolyline.length == 0)
return clipperPolyline;
var result = [];
result.push(clipperPolyline[0]);
//previous point is not always at i-1, because repeated points in the polygon are skipped
// var previousPoint = clipperPolyline[0];
var previousPoint = new Point(clipperPolyline[0].X, clipperPolyline[0].Y, 0); //clipperPolyline[i - 1];
for (var i = 1; i < clipperPolyline.length - 1; i++) {
previousPoint = new Point(clipperPolyline[i - 1].X, clipperPolyline[i - 1].Y, 0); //clipperPolyline[i - 1];
var point = new Point(clipperPolyline[i].X, clipperPolyline[i].Y, 0); //clipperPolyline[i];
if (previousPoint.sqDistance(point) == 0)
continue;
// you don't want to play with atan2() if a point is repeated
var incomingVector = point.sub(previousPoint);
var nextPoint = new Point(clipperPolyline[i + 1].X, clipperPolyline[i + 1].Y, 0) //clipperPolyline[i + 1];
var angle = point.angle(previousPoint, nextPoint);
var overshoot = point.add(incomingVector.normalized().scale(clipperRadius));
result.push(overshoot);
if (Math.abs(angle) > toleranceAngleRadians) {
var arcPoints = 100 / (2 * Math.PI) * Math.abs(angle);
var incomingAngle = incomingVector.atan2();
for (var j = 0; j <= arcPoints; j++) {
var a = incomingAngle + angle / arcPoints * j;
var pt = point.add(polarPoint(clipperRadius, a));
result.push(pt);
}
}
previousPoint = point;
}
if (clipperPolyline.length > 1)
result.push(clipperPolyline[clipperPolyline.length - 1]);
return result;
}
called at
workerDragknifePath = function(config) { //}, infobject, inflateVal, zstep, zdepth) {
var dragknifeGrp = new THREE.Group();
console.log("user wants to create Drag Knife Path. val:", config.offset);
var clipperPaths = workerGetClipperPaths(config.toolpath)
// console.log("clipperPaths:", clipperPaths);
// simplify this set of paths which is a very powerful Clipper call that figures out holes and path orientations
var newClipperPaths = workerSimplifyPolygons(clipperPaths);
if (newClipperPaths.length < 1) {
console.error("Clipper Simplification Failed!:");
}
var zval = 0
var polygons = newClipperPaths;
polygons = polygons.map(function(poly) {
// return addCornerActions(poly, Math.pow(2, 20) * 5, 20 / 180 * Math.PI);
return addCornerActions(poly, config.offset, 20 / 180 * Math.PI);
});

Could do something similar for your dogbones, but as an option for all routing toolpaths (not another new toolpath) - apply corner dogbones before passing it to drawClipperPaths

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants