Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- diff --git a/src/components/operation.js b/src/components/operation.js
- index 4acf911..c4c68f9 100644
- --- a/src/components/operation.js
- +++ b/src/components/operation.js
- @@ -513,6 +513,8 @@ export const OPERATION_FIELDS = {
- cutRate: { name: 'cutRate', label: 'Cut Rate', units: 'mm/min', input: NumberInput, ...checkFeedRateRange('XY'), contextMenu: FieldContextMenu() },
- toolSpeed: { name: 'toolSpeed', label: 'Tool Speed (0=Off)', units: 'rpm', input: NumberInput, ...checkFeedRateRange('S') },
- + dogBones: { name: 'dogBones', label: 'Dog Bones', units: '', input: ToggleInput, contextMenu: FieldContextMenu() },
- +
- useA: { name: 'useA', label: 'Use A Axis', units: '', input: ToggleInput, contextMenu: FieldContextMenu() },
- aAxisDiameter: { name: 'aAxisDiameter', label: 'A Diameter', units: 'mm', input: NumberInput, ...checkPositive, ...ifUseA },
- @@ -588,10 +590,10 @@ export const OPERATION_TYPES = {
- ...OPERATION_GROUPS.Filters.fields, ...OPERATION_GROUPS.Macros.fields
- ]
- },
- - 'Mill Pocket': { allowTabs: true, tabFields: true, fields: ['name', 'filterFillColor', 'filterStrokeColor', 'direction', 'margin', 'toolSpeed', 'millRapidZ', 'millStartZ', 'millEndZ', 'passDepth', 'toolDiameter', 'stepOver', 'segmentLength', 'plungeRate', 'cutRate', 'ramp', 'hookOperationStart', 'hookOperationEnd'] },
- + 'Mill Pocket': { allowTabs: true, tabFields: true, fields: ['name', 'filterFillColor', 'filterStrokeColor', 'direction', 'margin', 'toolSpeed', 'millRapidZ', 'millStartZ', 'millEndZ', 'passDepth', 'toolDiameter', 'stepOver', 'segmentLength', 'plungeRate', 'cutRate', 'ramp', 'dogBones', 'hookOperationStart', 'hookOperationEnd'] },
- 'Mill Cut': { allowTabs: true, tabFields: true, fields: ['name', 'filterFillColor', 'filterStrokeColor', 'direction', 'toolSpeed', 'millRapidZ', 'millStartZ', 'millEndZ', 'passDepth', 'toolDiameter', 'segmentLength', 'plungeRate', 'cutRate', 'ramp', 'hookOperationStart', 'hookOperationEnd'] },
- - 'Mill Cut Inside': { allowTabs: true, tabFields: true, fields: ['name', 'filterFillColor', 'filterStrokeColor', 'direction', 'margin', 'toolSpeed', 'millRapidZ', 'millStartZ', 'millEndZ', 'passDepth', 'cutWidth', 'toolDiameter', 'stepOver', 'plungeRate', 'cutRate', 'segmentLength', 'ramp', 'hookOperationStart', 'hookOperationEnd'] },
- - 'Mill Cut Outside': { allowTabs: true, tabFields: true, fields: ['name', 'filterFillColor', 'filterStrokeColor', 'direction', 'margin', 'toolSpeed', 'millRapidZ', 'millStartZ', 'millEndZ', 'passDepth', 'cutWidth', 'toolDiameter', 'stepOver', 'plungeRate', 'cutRate', 'segmentLength', 'ramp', 'hookOperationStart', 'hookOperationEnd'] },
- + 'Mill Cut Inside': { allowTabs: true, tabFields: true, fields: ['name', 'filterFillColor', 'filterStrokeColor', 'direction', 'margin', 'toolSpeed', 'millRapidZ', 'millStartZ', 'millEndZ', 'passDepth', 'cutWidth', 'toolDiameter', 'stepOver', 'plungeRate', 'cutRate', 'segmentLength', 'ramp', 'dogBones', 'hookOperationStart', 'hookOperationEnd'] },
- + 'Mill Cut Outside': { allowTabs: true, tabFields: true, fields: ['name', 'filterFillColor', 'filterStrokeColor', 'direction', 'margin', 'toolSpeed', 'millRapidZ', 'millStartZ', 'millEndZ', 'passDepth', 'cutWidth', 'toolDiameter', 'stepOver', 'plungeRate', 'cutRate', 'segmentLength', 'ramp', 'dogBones', 'hookOperationStart', 'hookOperationEnd'] },
- 'Mill V Carve': { allowTabs: false, fields: ['name', 'filterFillColor', 'filterStrokeColor', 'direction', 'toolAngle', 'millRapidZ', 'millStartZ', 'toolSpeed', 'passDepth', 'segmentLength', 'plungeRate', 'cutRate', 'hookOperationStart', 'hookOperationEnd'] },
- 'Lathe Conv Face/Turn': { skipDocs: true, tabFields: false, fields: ['name', 'latheToolBackSide', 'latheRapidToDiameter', 'latheRapidToZ', 'latheStartZ', 'latheRoughingFeed', 'latheRoughingDepth', 'latheFinishFeed', 'latheFinishDepth', 'latheFinishExtraPasses', 'latheFace', 'latheFaceEndDiameter', 'latheTurnAdd', 'latheTurns', 'hookOperationStart', 'hookOperationEnd'] },
- };
- diff --git a/src/lib/cam-gcode-laser-cut.js b/src/lib/cam-gcode-laser-cut.js
- index a0526b2..b907062 100644
- --- a/src/lib/cam-gcode-laser-cut.js
- +++ b/src/lib/cam-gcode-laser-cut.js
- @@ -213,11 +213,11 @@ export function getLaserCutGcodeFromOp(settings, opIndex, op, geometry, openGeom
- } else if (op.type === 'Laser Cut Inside') {
- if (op.margin)
- geometry = offset(geometry, -op.margin * mmToClipperScale);
- - camPaths = insideOutside(geometry, op.laserDiameter * mmToClipperScale, true, op.cutWidth * mmToClipperScale, op.stepOver, op.direction === 'Climb', false);
- + camPaths = insideOutside(geometry, op.laserDiameter * mmToClipperScale, true, op.cutWidth * mmToClipperScale, op.stepOver, op.direction === 'Climb', false, false);
- } else if (op.type === 'Laser Cut Outside') {
- if (op.margin)
- geometry = offset(geometry, op.margin * mmToClipperScale);
- - camPaths = insideOutside(geometry, op.laserDiameter * mmToClipperScale, false, op.cutWidth * mmToClipperScale, op.stepOver, op.direction === 'Climb', false);
- + camPaths = insideOutside(geometry, op.laserDiameter * mmToClipperScale, false, op.cutWidth * mmToClipperScale, op.stepOver, op.direction === 'Climb', false, false);
- } else if (op.type === 'Laser Fill Path') {
- if (op.margin)
- geometry = offset(geometry, -op.margin * mmToClipperScale);
- diff --git a/src/lib/cam-gcode-mill.js b/src/lib/cam-gcode-mill.js
- index d88d1a3..2b22072 100644
- --- a/src/lib/cam-gcode-mill.js
- +++ b/src/lib/cam-gcode-mill.js
- @@ -230,17 +230,17 @@ export function getMillGcodeFromOp(settings, opIndex, op, geometry, openGeometry
- if (op.type === 'Mill Pocket') {
- if (op.margin)
- geometry = offset(geometry, -op.margin * mmToClipperScale);
- - camPaths = pocket(geometry, op.toolDiameter * mmToClipperScale, op.stepOver, op.direction === 'Climb');
- + camPaths = pocket(geometry, op.toolDiameter * mmToClipperScale, op.stepOver, op.direction === 'Climb', op.dogBones);
- } else if (op.type === 'Mill Cut') {
- camPaths = cut(geometry, openGeometry, op.direction === 'Climb');
- } else if (op.type === 'Mill Cut Inside') {
- if (op.margin)
- geometry = offset(geometry, -op.margin * mmToClipperScale);
- - camPaths = insideOutside(geometry, op.toolDiameter * mmToClipperScale, true, op.cutWidth * mmToClipperScale, op.stepOver, op.direction === 'Climb', true);
- + camPaths = insideOutside(geometry, op.toolDiameter * mmToClipperScale, true, op.cutWidth * mmToClipperScale, op.stepOver, op.direction === 'Climb', true, op.dogBones);
- } else if (op.type === 'Mill Cut Outside') {
- if (op.margin)
- geometry = offset(geometry, op.margin * mmToClipperScale);
- - camPaths = insideOutside(geometry, op.toolDiameter * mmToClipperScale, false, op.cutWidth * mmToClipperScale, op.stepOver, op.direction === 'Climb', true);
- + camPaths = insideOutside(geometry, op.toolDiameter * mmToClipperScale, false, op.cutWidth * mmToClipperScale, op.stepOver, op.direction === 'Climb', true, op.dogBones);
- } else if (op.type === 'Mill V Carve') {
- camPaths = vCarve(geometry, op.toolAngle, op.passDepth * mmToClipperScale);
- }
- diff --git a/src/lib/cam.js b/src/lib/cam.js
- index 4893ef4..faaf216 100644
- --- a/src/lib/cam.js
- +++ b/src/lib/cam.js
- @@ -18,7 +18,7 @@
- import ClipperLib from 'clipper-lib';
- import { mat3, vec2 } from 'gl-matrix';
- -import { diff, offset, cPathsToClipperPaths, cPathsToCamPaths, clipperBounds, clipperPathsToCPaths, clipperToCppScale } from './mesh';
- +import { diff, offset, cPathsToClipperPaths, cPathsToCamPaths, clipperBounds, clipperPathsToCPaths, clipperToCppScale, mmToClipperScale } from './mesh';
- require('script-loader!web-cam-cpp');
- @@ -152,11 +152,86 @@ function mergePaths(bounds, paths) {
- return camPaths;
- }
- +// Add segments for dog bones to a calculated offset path.
- +function addDogBones(paths, geometry, diam, isInside) {
- + function normalize(v) {
- + let mag = Math.hypot(v.X, v.Y);
- + return {X: v.X / mag, Y: v.Y / mag};
- + }
- +
- + let newPaths = [];
- + for (let path of paths) {
- + let newPath = [];
- + if (path.length < 3) {
- + newPaths.push(path);
- + continue;
- + }
- + if (isInside)
- + path.reverse();
- + let p0 = path[path.length - 2];
- + let p1 = path[path.length - 1];
- + for (let p2 of path) {
- + let v01 = {X: p1.X - p0.X, Y: p1.Y - p0.Y};
- + let v12 = {X: p2.X - p1.X, Y: p2.Y - p1.Y};
- + if (v01.X * v12.Y < v01.Y * v12.X) { // if inside corner
- + v01 = normalize(v01);
- + v12 = normalize(v12);
- + // check for too accute angle. cosd(180 - 22.5) = -0.924
- + if (v01.X * v12.X + v01.Y * v12.Y < -0.924) {
- + newPath.push(p2);
- + p0 = p1;
- + p1 = p2;
- + continue;
- + }
- +
- + // direction of dog bone
- + let vdb = normalize({X: v01.X - v12.X, Y: v01.Y - v12.Y});
- + // max extend of dog bone, purely based on angle of segments
- + let me = .5 * diam * (1 / (vdb.Y * v01.X - vdb.X * v01.Y) - 1);
- +
- + // find closest intersect with geometry to cope with fillets
- + let r = {X: vdb.X * me, Y: vdb.Y * me};
- + let s, t, u;
- + for (let geomPath of geometry) {
- + let q0 = geomPath[geomPath.length - 1];
- + for (let q1 of geomPath) {
- + let s = {X: q1.X - q0.X, Y: q1.Y - q0.Y};
- + let rxs = r.X * s.Y - r.Y * s.X;
- + if (-1e-10 > rxs || rxs > 1e-10) { // not in parallel
- + t = ((q0.X-p1.X) * s.Y - (q0.Y-p1.Y) * s.X) / rxs;
- + u = ((q0.X-p1.X) * r.Y - (q0.Y-p1.Y) * r.X) / rxs;
- + if (0 <= t && t <= 1 && 0 <= u && u <= 1) {
- + r.X = r.X * t - vdb.X * .5 * diam;
- + r.Y = r.Y * t - vdb.Y * .5 * diam;
- + }
- + }
- + q0 = q1;
- + }
- + }
- + // prevent tiny dogbones <= 0.1 mm
- + if (Math.hypot(r.X, r.Y) > .1 * mmToClipperScale) {
- + newPath.push({X: p1.X + r.X, Y: p1.Y + r.Y});
- + newPath.push(p1);
- + }
- + }
- + newPath.push(p2);
- + p0 = p1;
- + p1 = p2;
- + }
- + if (isInside)
- + newPath.reverse();
- + newPaths.push(newPath);
- + }
- + return newPaths;
- +}
- +
- // Compute paths for pocket operation on Clipper geometry. Returns array
- // of CamPath. cutterDia is in Clipper units. stepover is in the range (0, 100).
- -export function pocket(geometry, cutterDia, stepover, climb) {
- +export function pocket(geometry, cutterDia, stepover, climb, dogBones) {
- stepover = stepover / 100;
- let current = offset(geometry, -cutterDia / 2);
- + if (dogBones)
- + current = addDogBones(current, geometry, cutterDia, true);
- let bounds = current.slice(0);
- let allPaths = [];
- while (current.length !== 0) {
- @@ -170,10 +245,11 @@ export function pocket(geometry, cutterDia, stepover, climb) {
- return mergePaths(bounds, allPaths);
- };
- +
- // Compute paths for inside/outside operation on Clipper geometry. Returns array
- // of CamPath. cutterDia and width are in Clipper units. stepover is in the
- // range (0, 100].
- -export function insideOutside(geometry, cutterDia, isInside, width, stepover, climb, allowRecutInBounds) {
- +export function insideOutside(geometry, cutterDia, isInside, width, stepover, climb, allowRecutInBounds, dogBones) {
- stepover = stepover / 100;
- width = Math.max(width, cutterDia);
- @@ -200,6 +276,8 @@ export function insideOutside(geometry, cutterDia, isInside, width, stepover, cl
- eachOffset = eachWidth;
- needReverse = climb;
- }
- + if (dogBones)
- + current = addDogBones(current, geometry, cutterDia, isInside);
- while (currentWidth <= width) {
- if (needReverse)
- diff --git a/src/reducers/operation.js b/src/reducers/operation.js
- index b90bc47..861079d 100644
- --- a/src/reducers/operation.js
- +++ b/src/reducers/operation.js
- @@ -42,6 +42,7 @@ export const OPERATION_INITIALSTATE = {
- ramp: false,
- useA: false,
- aAxisDiameter: 0,
- + dogBones: false,
- useBlower: false,
- smoothing: false, // lw.raster-to-gcode: Smoothing the input image ?
- brightness: 0, // lw.raster-to-gcode: Image brightness [-255 to +255]
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement