From bcf62c71ec6054b06329b1113a4aa3311d497c84 Mon Sep 17 00:00:00 2001 From: casperlamboo Date: Thu, 27 Jul 2017 18:20:08 +0200 Subject: [PATCH 1/8] remove settings from gcode class --- src/sliceActions/helpers/GCode.js | 63 ++++++------------------------- src/sliceActions/slicesToGCode.js | 63 ++++++++++++++++++++++++------- 2 files changed, 60 insertions(+), 66 deletions(-) diff --git a/src/sliceActions/helpers/GCode.js b/src/sliceActions/helpers/GCode.js index efadde9..c2e7f2f 100644 --- a/src/sliceActions/helpers/GCode.js +++ b/src/sliceActions/helpers/GCode.js @@ -10,16 +10,15 @@ const POSITION_Y = 'Y'; const POSITION_Z = 'Z'; export default class { - constructor(settings) { + constructor(nozzleToFilamentRatio) { + this._nozzleToFilamentRatio = nozzleToFilamentRatio; + this._gcode = ''; this._currentValues = {}; - this._settings = settings; this._nozzlePosition = new THREE.Vector2(0, 0); this._extruder = 0.0; this._isRetracted = false; this._isFanOn = false; - - this.bottom = true; } _addGCode(command) { @@ -62,14 +61,8 @@ export default class { return this; } - moveTo(x, y, layer) { - const { - layerHeight, - travelSpeed - } = this._settings; - - const z = layer * layerHeight + 0.2; - const speed = travelSpeed * 60; + moveTo(x, y, z, { speed }) { + speed *= 60; this._addGCode({ [MOVE]: 0, @@ -84,30 +77,13 @@ export default class { return this; } - lineTo(x, y, layer, type) { + lineTo(x, y, z, { speed, flowRate }) { const newNozzlePosition = new THREE.Vector2(x, y); - const { - layerHeight, - nozzleDiameter, - filamentThickness, - travelSpeed - } = this._settings; - - const profile = this._settings[(this.bottom ? 'bottom' : type)]; - - let { - speed, - flowRate - } = profile; - speed *= 60; - const z = layer * layerHeight + 0.2; const lineLength = this._nozzlePosition.distanceTo(newNozzlePosition); - - const filamentSurfaceArea = Math.pow((filamentThickness / 2), 2) * Math.PI; - this._extruder += lineLength * nozzleDiameter * layerHeight / filamentSurfaceArea * flowRate; + this._extruder += this._nozzleToFilamentRatio * lineLength * flowRate; this._addGCode({ [MOVE]: 1, @@ -123,16 +99,8 @@ export default class { return this; } - unRetract() { - const { - retraction: { - enabled: retractionEnabled, - minDistance: retractionMinDistance, - speed: retractionSpeed - } - } = this._settings; - - if (this._isRetracted && retractionEnabled) { + unRetract({ enabled, speed, minDistance }) { + if (this._isRetracted && enabled) { this._isRetracted = false; const speed = retractionSpeed * 60; @@ -149,17 +117,8 @@ export default class { return this; } - retract() { - const { - retraction: { - amount: retractionAmount, - enabled: retractionEnabled, - minDistance: retractionMinDistance, - speed: retractionSpeed - } - } = this._settings; - - if (!this._isRetracted && retractionEnabled) { + retract({ enabled, speed, minDistance }) { + if (!this._isRetracted && enabled) { this._isRetracted = true; const speed = retractionSpeed * 60; diff --git a/src/sliceActions/slicesToGCode.js b/src/sliceActions/slicesToGCode.js index 407619a..247220a 100644 --- a/src/sliceActions/slicesToGCode.js +++ b/src/sliceActions/slicesToGCode.js @@ -1,47 +1,82 @@ import GCode from './helpers/GCode.js'; -export default function slicesToGCode(slices, settings) { - const gcode = new GCode(settings); +const PROFILE_TYPES = ['brim', 'outerLine', 'innerLine', 'fill', 'support']; +export default function slicesToGCode(slices, settings) { + const { + layerHeight, + filamentThickness, + nozzleDiameter, + travelSpeed, + retraction, + retractionEnabled + } = settings; + + const filamentSurfaceArea = Math.pow((filamentThickness / 2), 2) * Math.PI; + const lineSurfaceArea = nozzleDiameter * layerHeight; + const nozzleToFilamentRatio = lineSurfaceArea / filamentSurfaceArea; + + const gcode = new GCode(nozzleToFilamentRatio); + + const defaultProfile = { + travelProfile: { + speed: travelSpeed + }, + retractProfile: { + ...retraction, + enabled: retractionEnabled + } + }; + + let isBottom = true; for (let layer = 0; layer < slices.length; layer ++) { const slice = slices[layer]; + const z = layer * layerHeight + 0.2; if (layer === 1) { gcode.turnFanOn(); - gcode.bottom = false; + isBottom = false; } + const profiles = PROFILE_TYPES.reduce((profiles, profileType) => { + profiles[profileType] = { + ...defaultProfile, + lineProfile: isBottom ? settings.bottom : settings[profileType] + } + return profiles; + }, {}); + if (typeof slice.brim !== 'undefined') { - pathToGCode(gcode, slice.brim, true, true, layer, 'brim'); + pathToGCode(gcode, slice.brim, true, true, z, profiles.brim); } for (let i = 0; i < slice.parts.length; i ++) { const part = slice.parts[i]; if (part.shape.closed) { - pathToGCode(gcode, part.outerLine, false, true, layer, 'outerLine'); + pathToGCode(gcode, part.outerLine, false, true, profiles.outerLine); for (let i = 0; i < part.innerLines.length; i ++) { const innerLine = part.innerLines[i]; - pathToGCode(gcode, innerLine, false, false, layer, 'innerLine'); + pathToGCode(gcode, innerLine, false, false, z, profiles.innerLine); } - pathToGCode(gcode, part.fill, true, false, layer, 'fill'); + pathToGCode(gcode, part.fill, true, false, z, profiles.fill); } else { const retract = !(slice.parts.length === 1 && typeof slice.support === 'undefined'); - pathToGCode(gcode, part.shape, retract, retract, layer, 'outerLine'); + pathToGCode(gcode, part.shape, retract, retract, z, profiles.outerLine); } } if (typeof slice.support !== 'undefined') { - pathToGCode(gcode, slice.support, true, true, layer, 'support'); + pathToGCode(gcode, slice.support, true, true, z, profiles.support); } } return gcode.getGCode(); } -function pathToGCode(gcode, shape, retract, unRetract, layer, type) { +function pathToGCode(gcode, shape, retract, unRetract, z, { lineProfile, travelProfile, retractProfile }) { const { closed } = shape; const paths = shape.mapToLower(); @@ -55,18 +90,18 @@ function pathToGCode(gcode, shape, retract, unRetract, layer, type) { if (i === 0) { // TODO // moveTo should impliment combing - gcode.moveTo(point.x, point.y, layer); + gcode.moveTo(point.x, point.y, z, travelProfile); if (unRetract) { - gcode.unRetract(); + gcode.unRetract(retractProfile); } } else { - gcode.lineTo(point.x, point.y, layer, type); + gcode.lineTo(point.x, point.y, z, lineProfile); } } } if (retract) { - gcode.retract(); + gcode.retract(retractProfile); } } From 9805991d9f23c30fd67d59c61e1c3f794fa64ab0 Mon Sep 17 00:00:00 2001 From: casperlamboo Date: Thu, 27 Jul 2017 18:33:25 +0200 Subject: [PATCH 2/8] use new settings #25 --- src/settings/default.yml | 42 +++++++++++++------------- src/sliceActions/generateInfills.js | 13 ++++---- src/sliceActions/generateInnerLines.js | 4 ++- src/sliceActions/helpers/GCode.js | 8 ++--- src/sliceActions/slicesToGCode.js | 33 +++++++++----------- 5 files changed, 49 insertions(+), 51 deletions(-) diff --git a/src/settings/default.yml b/src/settings/default.yml index 0fd05a0..694cf51 100644 --- a/src/settings/default.yml +++ b/src/settings/default.yml @@ -2,49 +2,49 @@ dimensions: x: 200 y: 200 z: 200 -temperature: 210 -bedTemperature: 70 -# heatBedTemperature: 20 -# heatTemperature: 20 -# heatupEnabled: true -travelSpeed: 200.0 -layerHeight: 0.15 heatedBed: false nozzleDiameter: 0.4 filamentThickness: 2.85 +temperature: 210 +bedTemperature: 70 +layerHeight: 0.15 +brimOffset: 4.0 +thickness: + top: 1.2 + bottom: 1.2 + shell: 0.8 retraction: - amount: 3.0 enabled: true + amount: 3.0 speed: 50.0 minDistance: 0.0 +travel: + speed: 200.0 support: + enabled: false acceptanceMargin: 1.5 distanceY: 0.4 - enabled: false gridSize: 6.0 margin: 2.0 plateSize: 4.0 flowRate: 0.8 speed: 40.0 -outerLine: - flowRate: 1.0 - speed: 40.0 -innerLine: +innerShell: flowRate: 1.0 speed: 50.0 -fill: +outerShell: + flowRate: 1.0 + speed: 40.0 +innerInfill: flowRate: 1.0 speed: 50.0 gridSize: 5.0 +outerInfill: + flowRate: 1.0 + speed: 50.0 brim: flowRate: 1.0 speed: 40.0 - offset: 4.0 -top: - thickness: 1.2 -bottom: +firstLayer: flowRate: 1.2 speed: 40.0 - thickness: 0.4 -shell: - thickness: 0.4 diff --git a/src/sliceActions/generateInfills.js b/src/sliceActions/generateInfills.js index 31c4ec7..d071e55 100644 --- a/src/sliceActions/generateInfills.js +++ b/src/sliceActions/generateInfills.js @@ -5,15 +5,16 @@ import Shape from 'clipper-js'; export default function generateInfills(slices, settings) { let { layerHeight, - fill: { gridSize: fillGridSize }, - bottom: { thickness: bottomThickness }, - top: { thickness: topThickness }, + innerInfill: { gridSize: infillGridSize }, + thickness: { + top: topThickness, + bottom: bottomThickness + }, nozzleDiameter } = settings; - fillGridSize /= PRECISION; + infillGridSize /= PRECISION; nozzleDiameter /= PRECISION; - infillOverlap /= PRECISION; const bottomSkinCount = Math.ceil(bottomThickness/layerHeight); const topSkinCount = Math.ceil(topThickness/layerHeight); @@ -54,7 +55,7 @@ export default function generateInfills(slices, settings) { if (lowFillArea && lowFillArea.paths.length > 0) { const bounds = lowFillArea.shapeBounds(); - const lowFillTemplate = getFillTemplate(bounds, fillGridSize, true, true); + const lowFillTemplate = getFillTemplate(bounds, infillGridSize, true, true); part.fill.join(lowFillTemplate.intersect(lowFillArea)); } diff --git a/src/sliceActions/generateInnerLines.js b/src/sliceActions/generateInnerLines.js index cfab81e..2da441a 100644 --- a/src/sliceActions/generateInnerLines.js +++ b/src/sliceActions/generateInnerLines.js @@ -12,10 +12,12 @@ export default function generateInnerLines(slices, settings) { let { layerHeight, nozzleDiameter, - shell: { thickness: shellThickness } + thickness: { shell: shellThickness } } = settings; + nozzleDiameter /= PRECISION; shellThickness /= PRECISION; + const nozzleRadius = nozzleDiameter / 2; const shells = Math.round(shellThickness / nozzleDiameter); diff --git a/src/sliceActions/helpers/GCode.js b/src/sliceActions/helpers/GCode.js index c2e7f2f..c8df4ad 100644 --- a/src/sliceActions/helpers/GCode.js +++ b/src/sliceActions/helpers/GCode.js @@ -103,9 +103,9 @@ export default class { if (this._isRetracted && enabled) { this._isRetracted = false; - const speed = retractionSpeed * 60; + speed *= 60; - if (this._extruder > retractionMinDistance) { + if (this._extruder > minDistance) { this._addGCode({ [MOVE]: 0, [EXTRUDER]: this._extruder.toFixed(3), @@ -121,9 +121,9 @@ export default class { if (!this._isRetracted && enabled) { this._isRetracted = true; - const speed = retractionSpeed * 60; + speed *= 60; - if (this._extruder > retractionMinDistance) { + if (this._extruder > minDistance) { this._addGCode({ [MOVE]: 0, [EXTRUDER]: (this._extruder - retractionAmount).toFixed(3), diff --git a/src/sliceActions/slicesToGCode.js b/src/sliceActions/slicesToGCode.js index 247220a..02cac68 100644 --- a/src/sliceActions/slicesToGCode.js +++ b/src/sliceActions/slicesToGCode.js @@ -1,6 +1,6 @@ import GCode from './helpers/GCode.js'; -const PROFILE_TYPES = ['brim', 'outerLine', 'innerLine', 'fill', 'support']; +const PROFILE_TYPES = ['support', 'innerShell', 'outerShell', 'innerInfill', 'outerInfill', 'brim']; export default function slicesToGCode(slices, settings) { const { @@ -9,7 +9,7 @@ export default function slicesToGCode(slices, settings) { nozzleDiameter, travelSpeed, retraction, - retractionEnabled + travel } = settings; const filamentSurfaceArea = Math.pow((filamentThickness / 2), 2) * Math.PI; @@ -19,29 +19,24 @@ export default function slicesToGCode(slices, settings) { const gcode = new GCode(nozzleToFilamentRatio); const defaultProfile = { - travelProfile: { - speed: travelSpeed - }, - retractProfile: { - ...retraction, - enabled: retractionEnabled - } + travelProfile: travel, + retractionProfile: retraction }; - let isBottom = true; + let isFirstLayer = true; for (let layer = 0; layer < slices.length; layer ++) { const slice = slices[layer]; const z = layer * layerHeight + 0.2; if (layer === 1) { gcode.turnFanOn(); - isBottom = false; + isFirstLayer = false; } const profiles = PROFILE_TYPES.reduce((profiles, profileType) => { profiles[profileType] = { ...defaultProfile, - lineProfile: isBottom ? settings.bottom : settings[profileType] + lineProfile: isFirstLayer ? settings.firstLayer : settings[profileType] } return profiles; }, {}); @@ -54,17 +49,17 @@ export default function slicesToGCode(slices, settings) { const part = slice.parts[i]; if (part.shape.closed) { - pathToGCode(gcode, part.outerLine, false, true, profiles.outerLine); + pathToGCode(gcode, part.outerLine, false, true, profiles.outerShell); for (let i = 0; i < part.innerLines.length; i ++) { const innerLine = part.innerLines[i]; - pathToGCode(gcode, innerLine, false, false, z, profiles.innerLine); + pathToGCode(gcode, innerLine, false, false, z, profiles.innerShell); } - pathToGCode(gcode, part.fill, true, false, z, profiles.fill); + pathToGCode(gcode, part.fill, true, false, z, profiles.outerInfill); } else { const retract = !(slice.parts.length === 1 && typeof slice.support === 'undefined'); - pathToGCode(gcode, part.shape, retract, retract, z, profiles.outerLine); + pathToGCode(gcode, part.shape, retract, retract, z, profiles.outerShell); } } @@ -76,7 +71,7 @@ export default function slicesToGCode(slices, settings) { return gcode.getGCode(); } -function pathToGCode(gcode, shape, retract, unRetract, z, { lineProfile, travelProfile, retractProfile }) { +function pathToGCode(gcode, shape, retract, unRetract, z, { lineProfile, travelProfile, retractionProfile }) { const { closed } = shape; const paths = shape.mapToLower(); @@ -93,7 +88,7 @@ function pathToGCode(gcode, shape, retract, unRetract, z, { lineProfile, travelP gcode.moveTo(point.x, point.y, z, travelProfile); if (unRetract) { - gcode.unRetract(retractProfile); + gcode.unRetract(retractionProfile); } } else { gcode.lineTo(point.x, point.y, z, lineProfile); @@ -102,6 +97,6 @@ function pathToGCode(gcode, shape, retract, unRetract, z, { lineProfile, travelP } if (retract) { - gcode.retract(retractProfile); + gcode.retract(retractionProfile); } } From a19ffbffab24ca0414ede12392db48d8b3caf9c9 Mon Sep 17 00:00:00 2001 From: casperlamboo Date: Fri, 28 Jul 2017 10:48:46 +0200 Subject: [PATCH 3/8] merge vertices of example --- simpleExample/index.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/simpleExample/index.js b/simpleExample/index.js index 282237a..43f9cd1 100644 --- a/simpleExample/index.js +++ b/simpleExample/index.js @@ -9,6 +9,7 @@ const settings = { }; const geometry = new THREE.TorusGeometry(20, 10, 30, 30).clone(); +geometry.mergeVertices(); const onProgress = ({ progress: { done, total, action } }) => { const percentage = `${(done / total * 100).toFixed()}%` @@ -17,4 +18,4 @@ const onProgress = ({ progress: { done, total, action } }) => { sliceGeometry(settings, geometry, null, false, onProgress).then(gcode => { document.body.innerHTML = gcode.replace(/(?:\r\n|\r|\n)/g, '
'); -}); \ No newline at end of file +}); From 39f29eb489454e24b663c83a7387c293c7235dc6 Mon Sep 17 00:00:00 2001 From: casperlamboo Date: Fri, 28 Jul 2017 11:05:48 +0200 Subject: [PATCH 4/8] separate inner fill and outer fill --- src/sliceActions/generateInfills.js | 28 ++++++++++++++-------------- src/sliceActions/helpers/GCode.js | 4 ++-- src/sliceActions/helpers/Slice.js | 3 ++- src/sliceActions/optimizePaths.js | 17 +++++++++++------ src/sliceActions/removePrecision.js | 3 ++- src/sliceActions/slicesToGCode.js | 7 +++++-- 6 files changed, 36 insertions(+), 26 deletions(-) diff --git a/src/sliceActions/generateInfills.js b/src/sliceActions/generateInfills.js index d071e55..14c5f66 100644 --- a/src/sliceActions/generateInfills.js +++ b/src/sliceActions/generateInfills.js @@ -19,7 +19,7 @@ export default function generateInfills(slices, settings) { const bottomSkinCount = Math.ceil(bottomThickness/layerHeight); const topSkinCount = Math.ceil(topThickness/layerHeight); const nozzleRadius = nozzleDiameter / 2; - const hightemplateSize = Math.sqrt(2 * Math.pow(nozzleDiameter, 2)); + const outerFillTemplateSize = Math.sqrt(2 * Math.pow(nozzleDiameter, 2)); for (let layer = 0; layer < slices.length; layer ++) { const slice = slices[layer]; @@ -44,28 +44,28 @@ export default function generateInfills(slices, settings) { const inset = (part.innerLines.length > 0) ? part.innerLines[part.innerLines.length - 1] : outerLine; const fillArea = inset.offset(-nozzleRadius); - let lowFillArea; - let highFillArea; + let innerFillArea; + let outerFillArea; if (surroundingLayer) { - highFillArea = fillArea.difference(surroundingLayer).intersect(fillArea); - lowFillArea = fillArea.difference(highFillArea); + outerFillArea = fillArea.difference(surroundingLayer).intersect(fillArea); + innerFillArea = fillArea.difference(outerFillArea); } else { - highFillArea = fillArea; + outerFillArea = fillArea; } - if (lowFillArea && lowFillArea.paths.length > 0) { - const bounds = lowFillArea.shapeBounds(); - const lowFillTemplate = getFillTemplate(bounds, infillGridSize, true, true); + if (innerFillArea && innerFillArea.paths.length > 0) { + const bounds = innerFillArea.shapeBounds(); + const innerFillTemplate = getFillTemplate(bounds, infillGridSize, true, true); - part.fill.join(lowFillTemplate.intersect(lowFillArea)); + part.innerFill.join(innerFillTemplate.intersect(innerFillArea)); } - if (highFillArea.paths.length > 0) { - const bounds = highFillArea.shapeBounds(); + if (outerFillArea.paths.length > 0) { + const bounds = outerFillArea.shapeBounds(); const even = (layer % 2 === 0); - const highFillTemplate = getFillTemplate(bounds, hightemplateSize, even, !even); + const outerFillTemplate = getFillTemplate(bounds, outerFillTemplateSize, even, !even); - part.fill.join(highFillTemplate.intersect(highFillArea)); + part.outerFill.join(outerFillTemplate.intersect(outerFillArea)); } } } diff --git a/src/sliceActions/helpers/GCode.js b/src/sliceActions/helpers/GCode.js index c8df4ad..4323ce9 100644 --- a/src/sliceActions/helpers/GCode.js +++ b/src/sliceActions/helpers/GCode.js @@ -117,7 +117,7 @@ export default class { return this; } - retract({ enabled, speed, minDistance }) { + retract({ enabled, speed, minDistance, amount }) { if (!this._isRetracted && enabled) { this._isRetracted = true; @@ -126,7 +126,7 @@ export default class { if (this._extruder > minDistance) { this._addGCode({ [MOVE]: 0, - [EXTRUDER]: (this._extruder - retractionAmount).toFixed(3), + [EXTRUDER]: (this._extruder - amount).toFixed(3), [SPEED]: speed.toFixed(3) }); } diff --git a/src/sliceActions/helpers/Slice.js b/src/sliceActions/helpers/Slice.js index 968f70a..ee966ff 100644 --- a/src/sliceActions/helpers/Slice.js +++ b/src/sliceActions/helpers/Slice.js @@ -10,7 +10,8 @@ export default class { if (shape.closed) { part.innerLines = []; part.outerLine = new Shape([], true); - part.fill = new Shape([], false); + part.innerFill = new Shape([], false); + part.outerFill = new Shape([], false); } this.parts.push(part); diff --git a/src/sliceActions/optimizePaths.js b/src/sliceActions/optimizePaths.js index 5c6e718..8f67786 100644 --- a/src/sliceActions/optimizePaths.js +++ b/src/sliceActions/optimizePaths.js @@ -48,9 +48,14 @@ export default function optimizePaths(slices, settings) { parts.push(part); if (part.shape.closed) { - if (part.outerLine.paths.length > 0) { - part.outerLine = optimizeShape(part.outerLine, start); - start.copy(part.outerLine.lastPoint(true)); + if (part.innerFill.paths.length > 0) { + part.innerFill = optimizeShape(part.innerFill, start); + start.copy(part.innerFill.lastPoint(true)); + } + + if (part.outerFill.paths.length > 0) { + part.outerFill = optimizeShape(part.outerFill, start); + start.copy(part.outerFill.lastPoint(true)); } for (let i = 0; i < part.innerLines.length; i ++) { @@ -62,9 +67,9 @@ export default function optimizePaths(slices, settings) { } } - if (part.fill.paths.length > 0) { - part.fill = optimizeShape(part.fill, start); - start.copy(part.fill.lastPoint(true)); + if (part.outerLine.paths.length > 0) { + part.outerLine = optimizeShape(part.outerLine, start); + start.copy(part.outerLine.lastPoint(true)); } } else { part.shape = optimizeShape(part.shape, start); diff --git a/src/sliceActions/removePrecision.js b/src/sliceActions/removePrecision.js index ec02f25..f84ce05 100644 --- a/src/sliceActions/removePrecision.js +++ b/src/sliceActions/removePrecision.js @@ -15,7 +15,8 @@ export default function removePrecision(slices) { const innerLine = part.innerLines[i]; innerLine.scaleDown(inversePrecision); } - part.fill.scaleDown(inversePrecision); + part.innerFill.scaleDown(inversePrecision); + part.outerFill.scaleDown(inversePrecision); } else { part.shape.scaleDown(inversePrecision); } diff --git a/src/sliceActions/slicesToGCode.js b/src/sliceActions/slicesToGCode.js index 02cac68..9e95135 100644 --- a/src/sliceActions/slicesToGCode.js +++ b/src/sliceActions/slicesToGCode.js @@ -49,14 +49,15 @@ export default function slicesToGCode(slices, settings) { const part = slice.parts[i]; if (part.shape.closed) { - pathToGCode(gcode, part.outerLine, false, true, profiles.outerShell); + pathToGCode(gcode, part.innerFill, false, true, z, profiles.innerInfill); + pathToGCode(gcode, part.outerFill, false, false, z, profiles.outerInfill); for (let i = 0; i < part.innerLines.length; i ++) { const innerLine = part.innerLines[i]; pathToGCode(gcode, innerLine, false, false, z, profiles.innerShell); } - pathToGCode(gcode, part.fill, true, false, z, profiles.outerInfill); + pathToGCode(gcode, part.outerLine, true, false, z, profiles.outerShell); } else { const retract = !(slice.parts.length === 1 && typeof slice.support === 'undefined'); pathToGCode(gcode, part.shape, retract, retract, z, profiles.outerShell); @@ -75,6 +76,8 @@ function pathToGCode(gcode, shape, retract, unRetract, z, { lineProfile, travelP const { closed } = shape; const paths = shape.mapToLower(); + console.log('retractionProfile: ', retractionProfile); + for (let i = 0; i < paths.length; i ++) { const line = paths[i]; From d380db1d7aac8f364f156161af21ed4501270220 Mon Sep 17 00:00:00 2001 From: casperlamboo Date: Fri, 28 Jul 2017 11:21:51 +0200 Subject: [PATCH 5/8] remove log --- src/sliceActions/slicesToGCode.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/sliceActions/slicesToGCode.js b/src/sliceActions/slicesToGCode.js index 9e95135..9ae9194 100644 --- a/src/sliceActions/slicesToGCode.js +++ b/src/sliceActions/slicesToGCode.js @@ -76,8 +76,6 @@ function pathToGCode(gcode, shape, retract, unRetract, z, { lineProfile, travelP const { closed } = shape; const paths = shape.mapToLower(); - console.log('retractionProfile: ', retractionProfile); - for (let i = 0; i < paths.length; i ++) { const line = paths[i]; From 72db7105fbfe7df209de05de877f222325c1e9de Mon Sep 17 00:00:00 2001 From: casperlamboo Date: Fri, 28 Jul 2017 12:13:53 +0200 Subject: [PATCH 6/8] combine interlines and outline into shell --- src/settings/default.yml | 2 +- src/sliceActions/generateInfills.js | 52 ++++++++++++-------------- src/sliceActions/generateInnerLines.js | 14 +++---- src/sliceActions/generateOutlines.js | 5 ++- src/sliceActions/helpers/Slice.js | 3 +- src/sliceActions/optimizePaths.js | 27 ++++++------- src/sliceActions/removePrecision.js | 5 +-- src/sliceActions/slicesToGCode.js | 14 ++++--- 8 files changed, 58 insertions(+), 64 deletions(-) diff --git a/src/settings/default.yml b/src/settings/default.yml index 694cf51..d337f04 100644 --- a/src/settings/default.yml +++ b/src/settings/default.yml @@ -37,7 +37,7 @@ outerShell: speed: 40.0 innerInfill: flowRate: 1.0 - speed: 50.0 + speed: 80.0 gridSize: 5.0 outerInfill: flowRate: 1.0 diff --git a/src/sliceActions/generateInfills.js b/src/sliceActions/generateInfills.js index 14c5f66..1b87787 100644 --- a/src/sliceActions/generateInfills.js +++ b/src/sliceActions/generateInfills.js @@ -34,39 +34,35 @@ export default function generateInfills(slices, settings) { for (let i = 0; i < slice.parts.length; i ++) { const part = slice.parts[i]; - if (!part.shape.closed) { - continue; + if (!part.shape.closed) continue; + + const innerShell = part.shell[part.shell.length - 1]; + + if (innerShell.paths.length === 0) continue; + + const fillArea = innerShell.offset(-nozzleRadius); + let innerFillArea; + let outerFillArea; + if (surroundingLayer) { + outerFillArea = fillArea.difference(surroundingLayer).intersect(fillArea); + innerFillArea = fillArea.difference(outerFillArea); + } else { + outerFillArea = fillArea; } - const outerLine = part.outerLine; + if (innerFillArea && innerFillArea.paths.length > 0) { + const bounds = innerFillArea.shapeBounds(); + const innerFillTemplate = getFillTemplate(bounds, infillGridSize, true, true); - if (outerLine.paths.length > 0) { - const inset = (part.innerLines.length > 0) ? part.innerLines[part.innerLines.length - 1] : outerLine; + part.innerFill.join(innerFillTemplate.intersect(innerFillArea)); + } - const fillArea = inset.offset(-nozzleRadius); - let innerFillArea; - let outerFillArea; - if (surroundingLayer) { - outerFillArea = fillArea.difference(surroundingLayer).intersect(fillArea); - innerFillArea = fillArea.difference(outerFillArea); - } else { - outerFillArea = fillArea; - } + if (outerFillArea.paths.length > 0) { + const bounds = outerFillArea.shapeBounds(); + const even = (layer % 2 === 0); + const outerFillTemplate = getFillTemplate(bounds, outerFillTemplateSize, even, !even); - if (innerFillArea && innerFillArea.paths.length > 0) { - const bounds = innerFillArea.shapeBounds(); - const innerFillTemplate = getFillTemplate(bounds, infillGridSize, true, true); - - part.innerFill.join(innerFillTemplate.intersect(innerFillArea)); - } - - if (outerFillArea.paths.length > 0) { - const bounds = outerFillArea.shapeBounds(); - const even = (layer % 2 === 0); - const outerFillTemplate = getFillTemplate(bounds, outerFillTemplateSize, even, !even); - - part.outerFill.join(outerFillTemplate.intersect(outerFillArea)); - } + part.outerFill.join(outerFillTemplate.intersect(outerFillArea)); } } } diff --git a/src/sliceActions/generateInnerLines.js b/src/sliceActions/generateInnerLines.js index 2da441a..c2767c7 100644 --- a/src/sliceActions/generateInnerLines.js +++ b/src/sliceActions/generateInnerLines.js @@ -19,7 +19,7 @@ export default function generateInnerLines(slices, settings) { shellThickness /= PRECISION; const nozzleRadius = nozzleDiameter / 2; - const shells = Math.round(shellThickness / nozzleDiameter); + const numShells = Math.round(shellThickness / nozzleDiameter); for (let layer = 0; layer < slices.length; layer ++) { const slice = slices[layer]; @@ -32,16 +32,16 @@ export default function generateInnerLines(slices, settings) { const outerLine = part.shape.offset(-nozzleRadius, offsetOptions); if (outerLine.paths.length > 0) { - part.outerLine.join(outerLine); + part.shell.push(outerLine); // start with 1 because outerLine is the 1st (0) shell - for (let shell = 1; shell < shells; shell += 1) { - const offset = shell * nozzleDiameter; + for (let inset = 1; inset < numShells; inset += 1) { + const offset = inset * nozzleDiameter; - const innerLine = outerLine.offset(-offset, offsetOptions); + const shell = outerLine.offset(-offset, offsetOptions); - if (innerLine.paths.length > 0) { - part.innerLines.push(innerLine); + if (shell.paths.length > 0) { + part.shell.push(shell); } else { break; } diff --git a/src/sliceActions/generateOutlines.js b/src/sliceActions/generateOutlines.js index 9fca57b..b3609db 100644 --- a/src/sliceActions/generateOutlines.js +++ b/src/sliceActions/generateOutlines.js @@ -5,7 +5,10 @@ export default function calculateOutlines(slices, settings) { const slice = slices[layer]; slice.outline = slice.parts.reduce((shape, part) => { - if (part.outerLine) shape.join(part.outerLine); + if (part.shape.closed) { + const [outerLine] = part.shell; + shape.join(outerLine); + } return shape; }, new Shape([], true)); } diff --git a/src/sliceActions/helpers/Slice.js b/src/sliceActions/helpers/Slice.js index ee966ff..b02c6ab 100644 --- a/src/sliceActions/helpers/Slice.js +++ b/src/sliceActions/helpers/Slice.js @@ -8,8 +8,7 @@ export default class { const part = { shape }; if (shape.closed) { - part.innerLines = []; - part.outerLine = new Shape([], true); + part.shell = []; part.innerFill = new Shape([], false); part.outerFill = new Shape([], false); } diff --git a/src/sliceActions/optimizePaths.js b/src/sliceActions/optimizePaths.js index 8f67786..dd249a2 100644 --- a/src/sliceActions/optimizePaths.js +++ b/src/sliceActions/optimizePaths.js @@ -17,7 +17,7 @@ export default function optimizePaths(slices, settings) { for (let i = 0; i < slice.parts.length; i ++) { const part = slice.parts[i]; - const shape = part.shape.closed ? part.outerLine : part.shape; + const shape = part.shape.closed ? part.shell[0] : part.shape; const bounds = shape.shapeBounds(); boundingBoxes.set(part, bounds); @@ -48,9 +48,13 @@ export default function optimizePaths(slices, settings) { parts.push(part); if (part.shape.closed) { - if (part.innerFill.paths.length > 0) { - part.innerFill = optimizeShape(part.innerFill, start); - start.copy(part.innerFill.lastPoint(true)); + for (let i = 0; i < part.shell.length; i ++) { + const shell = part.shell[i]; + + if (shell.paths.length === 0) continue; + + part.shell[i] = optimizeShape(shell, start); + start.copy(part.shell[i].lastPoint(true)); } if (part.outerFill.paths.length > 0) { @@ -58,18 +62,9 @@ export default function optimizePaths(slices, settings) { start.copy(part.outerFill.lastPoint(true)); } - for (let i = 0; i < part.innerLines.length; i ++) { - const innerLine = part.innerLines[i]; - - if (innerLine.paths.length > 0) { - part.innerLines[i] = optimizeShape(innerLine, start); - start.copy(part.innerLines[i].lastPoint(true)); - } - } - - if (part.outerLine.paths.length > 0) { - part.outerLine = optimizeShape(part.outerLine, start); - start.copy(part.outerLine.lastPoint(true)); + if (part.innerFill.paths.length > 0) { + part.innerFill = optimizeShape(part.innerFill, start); + start.copy(part.innerFill.lastPoint(true)); } } else { part.shape = optimizeShape(part.shape, start); diff --git a/src/sliceActions/removePrecision.js b/src/sliceActions/removePrecision.js index f84ce05..ccc8466 100644 --- a/src/sliceActions/removePrecision.js +++ b/src/sliceActions/removePrecision.js @@ -10,9 +10,8 @@ export default function removePrecision(slices) { const part = slice.parts[i]; if (part.shape.closed) { - part.outerLine.scaleDown(inversePrecision); - for (let i = 0; i < part.innerLines.length; i ++) { - const innerLine = part.innerLines[i]; + for (let i = 0; i < part.shell.length; i ++) { + const innerLine = part.shell[i]; innerLine.scaleDown(inversePrecision); } part.innerFill.scaleDown(inversePrecision); diff --git a/src/sliceActions/slicesToGCode.js b/src/sliceActions/slicesToGCode.js index 9ae9194..b14e9d4 100644 --- a/src/sliceActions/slicesToGCode.js +++ b/src/sliceActions/slicesToGCode.js @@ -49,15 +49,17 @@ export default function slicesToGCode(slices, settings) { const part = slice.parts[i]; if (part.shape.closed) { - pathToGCode(gcode, part.innerFill, false, true, z, profiles.innerInfill); - pathToGCode(gcode, part.outerFill, false, false, z, profiles.outerInfill); + for (let i = 0; i < part.shell.length; i ++) { + const shell = part.shell[i]; + const isOuterShell = i === 0; - for (let i = 0; i < part.innerLines.length; i ++) { - const innerLine = part.innerLines[i]; - pathToGCode(gcode, innerLine, false, false, z, profiles.innerShell); + const unRetract = isOuterShell; + const profile = isOuterShell ? profiles.outerShell : profiles.innerShell; + pathToGCode(gcode, shell, false, unRetract, z, profile); } - pathToGCode(gcode, part.outerLine, true, false, z, profiles.outerShell); + pathToGCode(gcode, part.outerFill, false, false, z, profiles.outerInfill); + pathToGCode(gcode, part.innerFill, true, false, z, profiles.innerInfill); } else { const retract = !(slice.parts.length === 1 && typeof slice.support === 'undefined'); pathToGCode(gcode, part.shape, retract, retract, z, profiles.outerShell); From 53bd335d7f4fcf806cab09de5b1afc29f52cba9a Mon Sep 17 00:00:00 2001 From: casperlamboo Date: Fri, 28 Jul 2017 12:17:40 +0200 Subject: [PATCH 7/8] fix settings --- src/settings/default.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/settings/default.yml b/src/settings/default.yml index d337f04..128a25c 100644 --- a/src/settings/default.yml +++ b/src/settings/default.yml @@ -8,7 +8,6 @@ filamentThickness: 2.85 temperature: 210 bedTemperature: 70 layerHeight: 0.15 -brimOffset: 4.0 thickness: top: 1.2 bottom: 1.2 @@ -43,6 +42,7 @@ outerInfill: flowRate: 1.0 speed: 50.0 brim: + offset: 4.0 flowRate: 1.0 speed: 40.0 firstLayer: From ab4427e8180f55cab5a58c3db7b55d9244641d30 Mon Sep 17 00:00:00 2001 From: casperlamboo Date: Fri, 28 Jul 2017 15:02:24 +0200 Subject: [PATCH 8/8] differentiate between open lines and closed lines for non filled paths --- src/sliceActions/applyPrecision.js | 7 +++--- src/sliceActions/generateInfills.js | 2 +- src/sliceActions/generateInnerLines.js | 2 +- src/sliceActions/generateOutlines.js | 2 +- src/sliceActions/helpers/Slice.js | 6 ++--- src/sliceActions/intersectionsToShapes.js | 16 +++++++----- src/sliceActions/optimizePaths.js | 4 +-- src/sliceActions/removePrecision.js | 2 +- src/sliceActions/shapesToSlices.js | 30 +++++++++++++++-------- src/sliceActions/slicesToGCode.js | 4 +-- 10 files changed, 45 insertions(+), 30 deletions(-) diff --git a/src/sliceActions/applyPrecision.js b/src/sliceActions/applyPrecision.js index 8fa3187..d7f8089 100644 --- a/src/sliceActions/applyPrecision.js +++ b/src/sliceActions/applyPrecision.js @@ -2,10 +2,11 @@ import { PRECISION } from '../constants.js' export default function applyPrecision(shapes) { for (let i = 0; i < shapes.length; i ++) { - const { closedShapes, openShapes } = shapes[i]; + const { fillShapes, lineShapesOpen, lineShapesClosed } = shapes[i]; - scaleUpShape(closedShapes); - scaleUpShape(openShapes); + scaleUpShape(fillShapes); + scaleUpShape(lineShapesOpen); + scaleUpShape(lineShapesClosed); } } diff --git a/src/sliceActions/generateInfills.js b/src/sliceActions/generateInfills.js index 1b87787..3ddfa56 100644 --- a/src/sliceActions/generateInfills.js +++ b/src/sliceActions/generateInfills.js @@ -34,7 +34,7 @@ export default function generateInfills(slices, settings) { for (let i = 0; i < slice.parts.length; i ++) { const part = slice.parts[i]; - if (!part.shape.closed) continue; + if (!part.closed) continue; const innerShell = part.shell[part.shell.length - 1]; diff --git a/src/sliceActions/generateInnerLines.js b/src/sliceActions/generateInnerLines.js index c2767c7..0c97a5d 100644 --- a/src/sliceActions/generateInnerLines.js +++ b/src/sliceActions/generateInnerLines.js @@ -27,7 +27,7 @@ export default function generateInnerLines(slices, settings) { for (let i = 0; i < slice.parts.length; i ++) { const part = slice.parts[i]; - if (!part.shape.closed) continue; + if (!part.closed) continue; const outerLine = part.shape.offset(-nozzleRadius, offsetOptions); diff --git a/src/sliceActions/generateOutlines.js b/src/sliceActions/generateOutlines.js index b3609db..036b519 100644 --- a/src/sliceActions/generateOutlines.js +++ b/src/sliceActions/generateOutlines.js @@ -5,7 +5,7 @@ export default function calculateOutlines(slices, settings) { const slice = slices[layer]; slice.outline = slice.parts.reduce((shape, part) => { - if (part.shape.closed) { + if (part.closed) { const [outerLine] = part.shell; shape.join(outerLine); } diff --git a/src/sliceActions/helpers/Slice.js b/src/sliceActions/helpers/Slice.js index b02c6ab..10b22fe 100644 --- a/src/sliceActions/helpers/Slice.js +++ b/src/sliceActions/helpers/Slice.js @@ -4,10 +4,10 @@ export default class { constructor() { this.parts = []; } - add(shape) { - const part = { shape }; + add(shape, closed) { + const part = { shape, closed }; - if (shape.closed) { + if (closed) { part.shell = []; part.innerFill = new Shape([], false); part.outerFill = new Shape([], false); diff --git a/src/sliceActions/intersectionsToShapes.js b/src/sliceActions/intersectionsToShapes.js index c46fc05..f416f79 100644 --- a/src/sliceActions/intersectionsToShapes.js +++ b/src/sliceActions/intersectionsToShapes.js @@ -10,8 +10,9 @@ export default function intersectionsToShapes(layerIntersectionIndexes, layerInt if (intersectionIndexes.length === 0) continue; - const closedShapes = []; - const openShapes = []; + const fillShapes = []; + const lineShapesOpen = []; + const lineShapesClosed = []; for (let i = 0; i < intersectionIndexes.length; i ++) { let index = intersectionIndexes[i]; @@ -107,14 +108,17 @@ export default function intersectionsToShapes(layerIntersectionIndexes, layerInt } if (openGeometry) { - if (!openShape) shape.push(shape[0].clone()); - openShapes.push(shape); + if (openShape) { + lineShapesOpen.push(shape); + } else { + lineShapesClosed.push(shape); + } } else { - closedShapes.push(shape); + fillShapes.push(shape); } } - layers.push({ closedShapes, openShapes }); + layers.push({ fillShapes, lineShapesOpen, lineShapesClosed }); } return layers; diff --git a/src/sliceActions/optimizePaths.js b/src/sliceActions/optimizePaths.js index dd249a2..18043ef 100644 --- a/src/sliceActions/optimizePaths.js +++ b/src/sliceActions/optimizePaths.js @@ -17,7 +17,7 @@ export default function optimizePaths(slices, settings) { for (let i = 0; i < slice.parts.length; i ++) { const part = slice.parts[i]; - const shape = part.shape.closed ? part.shell[0] : part.shape; + const shape = part.closed ? part.shell[0] : part.shape; const bounds = shape.shapeBounds(); boundingBoxes.set(part, bounds); @@ -47,7 +47,7 @@ export default function optimizePaths(slices, settings) { const [part] = slice.parts.splice(closestPart, 1); parts.push(part); - if (part.shape.closed) { + if (part.closed) { for (let i = 0; i < part.shell.length; i ++) { const shell = part.shell[i]; diff --git a/src/sliceActions/removePrecision.js b/src/sliceActions/removePrecision.js index ccc8466..2ecd8df 100644 --- a/src/sliceActions/removePrecision.js +++ b/src/sliceActions/removePrecision.js @@ -9,7 +9,7 @@ export default function removePrecision(slices) { for (let i = 0; i < slice.parts.length; i ++) { const part = slice.parts[i]; - if (part.shape.closed) { + if (part.closed) { for (let i = 0; i < part.shell.length; i ++) { const innerLine = part.shell[i]; innerLine.scaleDown(inversePrecision); diff --git a/src/sliceActions/shapesToSlices.js b/src/sliceActions/shapesToSlices.js index ea0e5be..2d0fe94 100644 --- a/src/sliceActions/shapesToSlices.js +++ b/src/sliceActions/shapesToSlices.js @@ -9,15 +9,18 @@ export default function shapesToSlices(shapes, settings) { const sliceLayers = []; for (let layer = 0; layer < shapes.length; layer ++) { - let { closedShapes, openShapes } = shapes[layer]; + let { fillShapes, lineShapesOpen, lineShapesClosed } = shapes[layer]; - closedShapes = new Shape(closedShapes, true, true, true, true) + fillShapes = new Shape(fillShapes, true, true, true, true) .fixOrientation() .simplify('pftNonZero') .clean(cleanDelta) .seperateShapes(); - openShapes = new Shape(openShapes, false, true, true, true); + lineShapesClosed = new Shape(lineShapesClosed, true, true, true, true) + .clean(cleanDelta); + + lineShapesOpen = new Shape(lineShapesOpen, false, true, true, true); // .clean(cleanDelta); // TODO // Cleaning is actually wanted here but there is a bug in the clean function @@ -25,17 +28,24 @@ export default function shapesToSlices(shapes, settings) { const slice = new Slice(); - for (let i = 0; i < closedShapes.length; i ++) { - const closedShape = closedShapes[i]; - slice.add(closedShape); + for (let i = 0; i < fillShapes.length; i ++) { + const fillShape = fillShapes[i]; + slice.add(fillShape, true); - // if (openShapes.path.length > 0) { - // openShapes = openShapes.difference(closedShape); + // if (lineShapesClosed.paths.length > 0) { + // lineShapesClosed = lineShapesClosed.difference(closedShape); + // } + // if (lineShapesOpen.paths.length > 0) { + // lineShapesOpen = lineShapesOpen.difference(closedShape); // } } - if (openShapes.paths.length > 0) { - slice.add(openShapes); + if (lineShapesClosed.paths.length > 0) { + slice.add(lineShapesClosed, false); + } + + if (lineShapesOpen.paths.length > 0) { + slice.add(lineShapesOpen, false); } sliceLayers.push(slice); diff --git a/src/sliceActions/slicesToGCode.js b/src/sliceActions/slicesToGCode.js index b14e9d4..fd38039 100644 --- a/src/sliceActions/slicesToGCode.js +++ b/src/sliceActions/slicesToGCode.js @@ -37,7 +37,7 @@ export default function slicesToGCode(slices, settings) { profiles[profileType] = { ...defaultProfile, lineProfile: isFirstLayer ? settings.firstLayer : settings[profileType] - } + }; return profiles; }, {}); @@ -48,7 +48,7 @@ export default function slicesToGCode(slices, settings) { for (let i = 0; i < slice.parts.length; i ++) { const part = slice.parts[i]; - if (part.shape.closed) { + if (part.closed) { for (let i = 0; i < part.shell.length; i ++) { const shell = part.shell[i]; const isOuterShell = i === 0;