From ae59a1e140fb584d9bf23c90784a13bd6460e510 Mon Sep 17 00:00:00 2001 From: harlock999 Date: Mon, 4 Apr 2022 11:12:36 -0400 Subject: [PATCH 1/5] Added Laser cut (unoptimized) to keep path vertex order. --- src/components/operation-diagram.js | 1 + src/components/operation.js | 1 + src/lib/cam-gcode-laser-cut.js | 4 +++- src/lib/cam-gcode.js | 2 +- src/lib/cam.js | 12 +++++++----- 5 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/components/operation-diagram.js b/src/components/operation-diagram.js index 0593f1cd..df5e7b88 100644 --- a/src/components/operation-diagram.js +++ b/src/components/operation-diagram.js @@ -45,6 +45,7 @@ const hide = [ const types = { 'Laser Cut': { show: ['LaserCut'] }, + 'Laser (unoptimized)': { show: ['LaserCut'] }, 'Laser Cut Inside': { show: ['LaserCutInside', 'laserDia'] }, 'Laser Cut Outside': { show: ['LaserCutOutside', 'laserDia'] }, 'Laser Fill Path': { show: ['LaserFill', 'lineSpace'] }, diff --git a/src/components/operation.js b/src/components/operation.js index b5fd75fc..88645ddf 100644 --- a/src/components/operation.js +++ b/src/components/operation.js @@ -580,6 +580,7 @@ const tabFields = [ export const OPERATION_TYPES = { 'Laser Cut': { allowTabs: true, tabFields: false, fields: ['name', 'filterFillColor', 'filterStrokeColor', 'laserPower', 'passes', 'passDepth', 'startHeight', 'cutRate', 'useA', 'aAxisDiameter', 'useBlower', 'segmentLength', ...OPERATION_GROUPS.Macros.fields] }, + 'Laser Cut (unoptimized)': { allowTabs: true, tabFields: false, fields: ['name', 'filterFillColor', 'filterStrokeColor', 'laserPower', 'passes', 'passDepth', 'startHeight', 'cutRate', 'useA', 'aAxisDiameter', 'useBlower', 'segmentLength', ...OPERATION_GROUPS.Macros.fields] }, 'Laser Cut Inside': { allowTabs: true, tabFields: false, fields: ['name', 'filterFillColor', 'filterStrokeColor', 'laserDiameter', 'laserPower', 'margin', 'passes', 'passDepth', 'startHeight', 'cutRate', 'useA', 'aAxisDiameter', 'useBlower', 'segmentLength', ...OPERATION_GROUPS.Macros.fields] }, 'Laser Cut Outside': { allowTabs: true, tabFields: false, fields: ['name', 'filterFillColor', 'filterStrokeColor', 'laserDiameter', 'laserPower', 'margin', 'passes', 'passDepth', 'startHeight', 'cutRate', 'useA', 'aAxisDiameter', 'useBlower', 'segmentLength', ...OPERATION_GROUPS.Macros.fields] }, 'Laser Fill Path': { allowTabs: false, tabFields: false, fields: ['name', 'filterFillColor', 'filterStrokeColor', 'lineDistance', 'lineAngle', 'laserPower', 'margin', 'passes', 'passDepth', 'startHeight', 'cutRate', 'useA', 'aAxisDiameter', 'useBlower', ...OPERATION_GROUPS.Macros.fields] }, diff --git a/src/lib/cam-gcode-laser-cut.js b/src/lib/cam-gcode-laser-cut.js index cc8e5aa8..b17e3ac8 100644 --- a/src/lib/cam-gcode-laser-cut.js +++ b/src/lib/cam-gcode-laser-cut.js @@ -165,7 +165,7 @@ export function getLaserCutGcode(props) { export function getLaserCutGcodeFromOp(settings, opIndex, op, geometry, openGeometry, tabGeometry, showAlert, done, progress) { let ok = true; - if (op.type !== 'Laser Cut' && op.type !== 'Laser Fill Path') { + if (op.type !== 'Laser Cut' && op.type !== 'Laser Cut (unoptimized)' && op.type !== 'Laser Fill Path') { if (op.laserDiameter <= 0) { showAlert("Laser Diameter must be greater than 0", "danger"); ok = false; @@ -210,6 +210,8 @@ export function getLaserCutGcodeFromOp(settings, opIndex, op, geometry, openGeom let camPaths = []; if (op.type === 'Laser Cut') { camPaths = cut(geometry, openGeometry, false); + } else if (op.type === 'Laser Cut (unoptimized)') { + camPaths = cut(geometry, openGeometry, false, false); } else if (op.type === 'Laser Cut Inside') { if (op.margin) geometry = offset(geometry, -op.margin * mmToClipperScale); diff --git a/src/lib/cam-gcode.js b/src/lib/cam-gcode.js index 18f0b143..5b8ef5b8 100644 --- a/src/lib/cam-gcode.js +++ b/src/lib/cam-gcode.js @@ -144,7 +144,7 @@ export function getGcode(settings, documents, operations, documentCacheHolder, s .then((preflight) => { let { geometry, openGeometry, tabGeometry, filteredDocIds, docsWithImages } = preflight; console.log('Queueing Worker: ' + op.type + "->" + opIndex); - if (op.type === 'Laser Cut' || op.type === 'Laser Cut Inside' || op.type === 'Laser Cut Outside' || op.type === 'Laser Fill Path') { + if (op.type === 'Laser Cut' || op.type === 'Laser Cut (unoptimized)' || op.type === 'Laser Cut Inside' || op.type === 'Laser Cut Outside' || op.type === 'Laser Fill Path') { laserOps = true; if (startCode === "") startCode = settings.gcodeStart; if (endCode === "") endCode = settings.gcodeEnd; diff --git a/src/lib/cam.js b/src/lib/cam.js index 4893ef4d..0b016bbf 100644 --- a/src/lib/cam.js +++ b/src/lib/cam.js @@ -71,7 +71,7 @@ function closeClipperPaths(paths) { // Try to merge paths. A merged path doesn't cross outside of bounds. Returns array of CamPath. // If paths contains both open and closed paths, then the closed paths must be before the open // paths within the array. -function mergePaths(bounds, paths) { +function mergePaths(bounds, paths, optimized) { if (paths.length === 0) return []; @@ -117,13 +117,13 @@ function mergePaths(bounds, paths) { paths[closestPathIndex] = []; numLeft -= 1; let needNew; - if (pathIsClosed(path)) { + if (pathIsClosed(path) && optimized) { needNew = crosses(bounds, currentPoint, path[closestPointIndex]); path = path.slice(closestPointIndex, path.length).concat(path.slice(1, closestPointIndex)); path.push(path[0]); } else { needNew = true; - if (closestReverse) { + if (closestReverse && optimized) { path = path.slice(); path.reverse(); } @@ -225,7 +225,7 @@ export function insideOutside(geometry, cutterDia, isInside, width, stepover, cl // Compute paths for cut operation on Clipper geometry. Returns array // of CamPath. -export function cut(geometry, openGeometry, climb) { +export function cut(geometry, openGeometry, climb, optimized = true) { let allPaths = []; for (let i = 0; i < geometry.length; ++i) { let path = geometry[i].slice(0); @@ -236,7 +236,9 @@ export function cut(geometry, openGeometry, climb) { } for (let path of openGeometry) allPaths.push(path.slice()); - let result = mergePaths(null, allPaths); + + let result = mergePaths(null, allPaths, optimized); + for (let i = 0; i < result.length; ++i) result[i].safeToClose = pathIsClosed(result[i].path); return result; From aa2368d8c3bbaa0c04bf1f67ce771be325e96eb7 Mon Sep 17 00:00:00 2001 From: harlock999 Date: Tue, 5 Apr 2022 14:28:34 -0400 Subject: [PATCH 2/5] Corrected typo in operation-diagram.js --- src/components/operation-diagram.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/operation-diagram.js b/src/components/operation-diagram.js index df5e7b88..21f2d2b7 100644 --- a/src/components/operation-diagram.js +++ b/src/components/operation-diagram.js @@ -45,7 +45,7 @@ const hide = [ const types = { 'Laser Cut': { show: ['LaserCut'] }, - 'Laser (unoptimized)': { show: ['LaserCut'] }, + 'Laser Cut (unoptimized)': { show: ['LaserCut'] }, 'Laser Cut Inside': { show: ['LaserCutInside', 'laserDia'] }, 'Laser Cut Outside': { show: ['LaserCutOutside', 'laserDia'] }, 'Laser Fill Path': { show: ['LaserFill', 'lineSpace'] }, From 74a2d5512aca096ff880ad95964a1ab65b2ba194 Mon Sep 17 00:00:00 2001 From: Owen Date: Wed, 6 Apr 2022 21:29:03 +0200 Subject: [PATCH 3/5] Analyser output format and correct for fast operations --- src/components/workspace.js | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/components/workspace.js b/src/components/workspace.js index 0ff2c7a1..cecd9495 100644 --- a/src/components/workspace.js +++ b/src/components/workspace.js @@ -1374,19 +1374,28 @@ class Workspace extends React.Component { updateSimDetails() { - let totalSecs = Math.floor((this.gcodePreview.g1Time + this.gcodePreview.g0Dist / this.props.settings.simG0Rate) * 60); + let totalSecs = (this.gcodePreview.g1Time + (this.gcodePreview.g0Dist / this.props.settings.simG0Rate)) * 60; let simSummary = 'No Gcode loaded' let codeSize = this.gcode.length; if (totalSecs > 0) { - let activeSecs = Math.floor(this.gcodePreview.g1Time * 60); - let secs = totalSecs % 60; + let secs = Math.floor(totalSecs) % 60; + if (totalSecs < 1) { + secs = Number(totalSecs.toFixed(2)); + } else if (totalSecs < 60) { + secs = Number(totalSecs.toFixed(1)); + } let mins = Math.floor(totalSecs / 60) % 60; let hrs = Math.floor(totalSecs / 3600); - let duty = Math.floor(activeSecs / totalSecs * 100); + let duty = Math.floor((this.gcodePreview.g1Time * 60) / totalSecs * 100); let xsize = this.gcodePreview.maxX - this.gcodePreview.minX; let ysize = this.gcodePreview.maxY - this.gcodePreview.minY; - if (hrs > 0) simSummary = 'Estimated run time: ' + hrs + 'h, ' + mins + 'm. Tool duty cycle: ' + duty + '%. '; - else simSummary = 'Estimated run time: ' + mins + 'm, '+ secs + 's. Tool duty cycle: ' + duty + '%. '; + if (hrs > 0) { + simSummary = 'Estimated run time: ' + hrs + 'h, ' + mins + 'm. Tool duty cycle: ' + duty + '%. '; + } else if (mins > 0) { + simSummary = 'Estimated run time: ' + mins + 'm, ' + secs + 's. Tool duty cycle: ' + duty + '%. '; + } else { + simSummary = 'Estimated run time: ' + secs + 's. Tool duty cycle: ' + duty + '%. '; + } simSummary += 'Size: ' + xsize.toFixed(2) + ' x ' + ysize.toFixed(2) + ' mm. '; simSummary += "Code: " + humanFileSize(codeSize) + ", Moves: " + this.gcodePreview.moves; } else if (codeSize > 0) { From f9bfe688db68c92bef8c88b731c4ebb35c6856e7 Mon Sep 17 00:00:00 2001 From: Owen Date: Wed, 6 Apr 2022 21:40:33 +0200 Subject: [PATCH 4/5] No header for empty gcode --- src/lib/cam-gcode.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/lib/cam-gcode.js b/src/lib/cam-gcode.js index 18f0b143..483939ac 100644 --- a/src/lib/cam-gcode.js +++ b/src/lib/cam-gcode.js @@ -220,7 +220,7 @@ export function getGcode(settings, documents, operations, documentCacheHolder, s let line = header[i].replace("$VERSION", settings.__version) .replace("$PROFILE", settings.__selectedProfile); if (line.length > 0) { - fullGcode += '; ' + strftime(line) + "\r\n"; + fullGcode += "; " + strftime(line) + "\r\n"; } else { fullGcode += "\r\n"; } @@ -232,6 +232,7 @@ export function getGcode(settings, documents, operations, documentCacheHolder, s } showAlert("Gcode generation complete, elapsed: " + hhmmss(elapsed) + String(Number(elapsed-Math.floor(elapsed)).toFixed(3)).substr(1), "info"); if (gcode.join() === "" ) { + fullGcode = ""; showAlert("Empty Gcode! Either there was an error during generation or the user cancelled generation.", "warning"); } else { fullGcode += startCode + gcode.join('\r\n') + endCode; From 8bef04fee61c18740c809ca6336c6b0db22c4b16 Mon Sep 17 00:00:00 2001 From: Owen Carter Date: Fri, 8 Apr 2022 16:40:41 +0200 Subject: [PATCH 5/5] Revert "Added Laser cut (unoptimized) to keep path vertex order." --- src/components/operation-diagram.js | 1 - src/components/operation.js | 1 - src/lib/cam-gcode-laser-cut.js | 4 +--- src/lib/cam-gcode.js | 2 +- src/lib/cam.js | 12 +++++------- 5 files changed, 7 insertions(+), 13 deletions(-) diff --git a/src/components/operation-diagram.js b/src/components/operation-diagram.js index 21f2d2b7..0593f1cd 100644 --- a/src/components/operation-diagram.js +++ b/src/components/operation-diagram.js @@ -45,7 +45,6 @@ const hide = [ const types = { 'Laser Cut': { show: ['LaserCut'] }, - 'Laser Cut (unoptimized)': { show: ['LaserCut'] }, 'Laser Cut Inside': { show: ['LaserCutInside', 'laserDia'] }, 'Laser Cut Outside': { show: ['LaserCutOutside', 'laserDia'] }, 'Laser Fill Path': { show: ['LaserFill', 'lineSpace'] }, diff --git a/src/components/operation.js b/src/components/operation.js index 88645ddf..b5fd75fc 100644 --- a/src/components/operation.js +++ b/src/components/operation.js @@ -580,7 +580,6 @@ const tabFields = [ export const OPERATION_TYPES = { 'Laser Cut': { allowTabs: true, tabFields: false, fields: ['name', 'filterFillColor', 'filterStrokeColor', 'laserPower', 'passes', 'passDepth', 'startHeight', 'cutRate', 'useA', 'aAxisDiameter', 'useBlower', 'segmentLength', ...OPERATION_GROUPS.Macros.fields] }, - 'Laser Cut (unoptimized)': { allowTabs: true, tabFields: false, fields: ['name', 'filterFillColor', 'filterStrokeColor', 'laserPower', 'passes', 'passDepth', 'startHeight', 'cutRate', 'useA', 'aAxisDiameter', 'useBlower', 'segmentLength', ...OPERATION_GROUPS.Macros.fields] }, 'Laser Cut Inside': { allowTabs: true, tabFields: false, fields: ['name', 'filterFillColor', 'filterStrokeColor', 'laserDiameter', 'laserPower', 'margin', 'passes', 'passDepth', 'startHeight', 'cutRate', 'useA', 'aAxisDiameter', 'useBlower', 'segmentLength', ...OPERATION_GROUPS.Macros.fields] }, 'Laser Cut Outside': { allowTabs: true, tabFields: false, fields: ['name', 'filterFillColor', 'filterStrokeColor', 'laserDiameter', 'laserPower', 'margin', 'passes', 'passDepth', 'startHeight', 'cutRate', 'useA', 'aAxisDiameter', 'useBlower', 'segmentLength', ...OPERATION_GROUPS.Macros.fields] }, 'Laser Fill Path': { allowTabs: false, tabFields: false, fields: ['name', 'filterFillColor', 'filterStrokeColor', 'lineDistance', 'lineAngle', 'laserPower', 'margin', 'passes', 'passDepth', 'startHeight', 'cutRate', 'useA', 'aAxisDiameter', 'useBlower', ...OPERATION_GROUPS.Macros.fields] }, diff --git a/src/lib/cam-gcode-laser-cut.js b/src/lib/cam-gcode-laser-cut.js index b17e3ac8..cc8e5aa8 100644 --- a/src/lib/cam-gcode-laser-cut.js +++ b/src/lib/cam-gcode-laser-cut.js @@ -165,7 +165,7 @@ export function getLaserCutGcode(props) { export function getLaserCutGcodeFromOp(settings, opIndex, op, geometry, openGeometry, tabGeometry, showAlert, done, progress) { let ok = true; - if (op.type !== 'Laser Cut' && op.type !== 'Laser Cut (unoptimized)' && op.type !== 'Laser Fill Path') { + if (op.type !== 'Laser Cut' && op.type !== 'Laser Fill Path') { if (op.laserDiameter <= 0) { showAlert("Laser Diameter must be greater than 0", "danger"); ok = false; @@ -210,8 +210,6 @@ export function getLaserCutGcodeFromOp(settings, opIndex, op, geometry, openGeom let camPaths = []; if (op.type === 'Laser Cut') { camPaths = cut(geometry, openGeometry, false); - } else if (op.type === 'Laser Cut (unoptimized)') { - camPaths = cut(geometry, openGeometry, false, false); } else if (op.type === 'Laser Cut Inside') { if (op.margin) geometry = offset(geometry, -op.margin * mmToClipperScale); diff --git a/src/lib/cam-gcode.js b/src/lib/cam-gcode.js index 02bb8e97..483939ac 100644 --- a/src/lib/cam-gcode.js +++ b/src/lib/cam-gcode.js @@ -144,7 +144,7 @@ export function getGcode(settings, documents, operations, documentCacheHolder, s .then((preflight) => { let { geometry, openGeometry, tabGeometry, filteredDocIds, docsWithImages } = preflight; console.log('Queueing Worker: ' + op.type + "->" + opIndex); - if (op.type === 'Laser Cut' || op.type === 'Laser Cut (unoptimized)' || op.type === 'Laser Cut Inside' || op.type === 'Laser Cut Outside' || op.type === 'Laser Fill Path') { + if (op.type === 'Laser Cut' || op.type === 'Laser Cut Inside' || op.type === 'Laser Cut Outside' || op.type === 'Laser Fill Path') { laserOps = true; if (startCode === "") startCode = settings.gcodeStart; if (endCode === "") endCode = settings.gcodeEnd; diff --git a/src/lib/cam.js b/src/lib/cam.js index 0b016bbf..4893ef4d 100644 --- a/src/lib/cam.js +++ b/src/lib/cam.js @@ -71,7 +71,7 @@ function closeClipperPaths(paths) { // Try to merge paths. A merged path doesn't cross outside of bounds. Returns array of CamPath. // If paths contains both open and closed paths, then the closed paths must be before the open // paths within the array. -function mergePaths(bounds, paths, optimized) { +function mergePaths(bounds, paths) { if (paths.length === 0) return []; @@ -117,13 +117,13 @@ function mergePaths(bounds, paths, optimized) { paths[closestPathIndex] = []; numLeft -= 1; let needNew; - if (pathIsClosed(path) && optimized) { + if (pathIsClosed(path)) { needNew = crosses(bounds, currentPoint, path[closestPointIndex]); path = path.slice(closestPointIndex, path.length).concat(path.slice(1, closestPointIndex)); path.push(path[0]); } else { needNew = true; - if (closestReverse && optimized) { + if (closestReverse) { path = path.slice(); path.reverse(); } @@ -225,7 +225,7 @@ export function insideOutside(geometry, cutterDia, isInside, width, stepover, cl // Compute paths for cut operation on Clipper geometry. Returns array // of CamPath. -export function cut(geometry, openGeometry, climb, optimized = true) { +export function cut(geometry, openGeometry, climb) { let allPaths = []; for (let i = 0; i < geometry.length; ++i) { let path = geometry[i].slice(0); @@ -236,9 +236,7 @@ export function cut(geometry, openGeometry, climb, optimized = true) { } for (let path of openGeometry) allPaths.push(path.slice()); - - let result = mergePaths(null, allPaths, optimized); - + let result = mergePaths(null, allPaths); for (let i = 0; i < result.length; ++i) result[i].safeToClose = pathIsClosed(result[i].path); return result;