diff --git a/src/interface/Settings.js b/src/interface/Settings.js index ec94401..5c7fb5e 100644 --- a/src/interface/Settings.js +++ b/src/interface/Settings.js @@ -166,6 +166,14 @@ class Settings extends React.Component { case 'settings.brim.flowRate': case 'settings.firstLayer.speed': case 'settings.firstLayer.flowRate': + case 'settings.support.enabled': + case 'settings.support.speed': + case 'settings.support.distanceY': + case 'settings.support.density': + case 'settings.support.minArea': + case 'settings.support.margin': + case 'settings.support.speed': + case 'settings.support.flowRate': if (!localStorage.active) return this.openAddPrinterDialog(); if (value === null) { @@ -357,6 +365,15 @@ class Settings extends React.Component { +

Support

+ + + + + + + +

First layer

diff --git a/src/settings/default.yml b/src/settings/default.yml index b3c42ec..d38ba24 100644 --- a/src/settings/default.yml +++ b/src/settings/default.yml @@ -22,11 +22,10 @@ travel: speed: 200.0 support: enabled: false - acceptanceMargin: 1.5 + minArea: 2 distanceY: 0.4 - gridSize: 6.0 + density: 5.0 margin: 2.0 - plateSize: 4.0 flowRate: 0.8 speed: 40.0 innerShell: diff --git a/src/sliceActions/generateSupport.js b/src/sliceActions/generateSupport.js index 8e9e0c3..3f1f767 100644 --- a/src/sliceActions/generateSupport.js +++ b/src/sliceActions/generateSupport.js @@ -7,70 +7,37 @@ export default function generateSupport(slices, settings) { let { layerHeight, - support: { - gridSize: supportGridSize, - margin: supportMargin, - plateSize: plateSize, - distanceY: supportDistanceY - }, + support: { density, margin, minArea, distanceY }, nozzleDiameter } = settings; - supportGridSize /= PRECISION; - supportMargin /= PRECISION; - plateSize /= PRECISION; + density /= 100; + margin /= PRECISION; nozzleDiameter /= PRECISION; - var supportDistanceLayers = Math.max(Math.ceil(supportDistanceY / layerHeight), 1); - var supportAreas = new Shape([], true); + const bidirectionalInfill = density < 0.8; + const infillGridSize = nozzleDiameter * 2 / density; + const supportDistanceLayers = Math.max(Math.ceil(distanceY / layerHeight), 1); - for (var layer = slices.length - 1 - supportDistanceLayers; layer >= 0; layer --) { - var currentSlice = slices[layer]; + let supportArea = new Shape([], true); - if (supportAreas.length > 0) { + for (let layer = slices.length - 1 - supportDistanceLayers; layer >= supportDistanceLayers; layer --) { + const currentLayer = slices[layer + supportDistanceLayers - 1]; + const upSkin = slices[layer + supportDistanceLayers]; + const downSkin = slices[layer - supportDistanceLayers]; - if (layer >= supportDistanceLayers) { - var sliceSkin = slices[layer - supportDistanceLayers].outline; - sliceSkin = sliceSkin; + const neededSupportArea = upSkin.outline.difference(currentLayer.outline.offset(margin)); - var supportAreasSlimmed = supportAreas.difference(sliceSkin.offset(supportMargin)); - if (supportAreasSlimmed.area() < 100.0) { - supportAreas = supportAreas.difference(sliceSkin); - } - else { - supportAreas = supportAreasSlimmed; - } - } - - var supportTemplate = getFillTemplate(supportAreas.bounds(), supportGridSize, true, true); - var supportFill = supportTemplate.intersect(supportAreas); - if (supportFill.length === 0) { - currentSlice.support = supportAreas.clone(); - } - else { - currentSlice.support = supportFill; - } + if (neededSupportArea.totalArea() * Math.pow(PRECISION, 2) > minArea) { + supportArea = supportArea.union(neededSupportArea); } + if (downSkin) supportArea = supportArea.difference(downSkin.outline.offset(margin)); - var supportSkin = slices[layer + supportDistanceLayers - 1].outline; + const even = (layer % 2 === 0); + const bounds = supportArea.shapeBounds(); + const innerFillTemplate = getFillTemplate(bounds, infillGridSize, bidirectionalInfill || even, bidirectionalInfill || !even); - var slice = slices[layer + supportDistanceLayers]; - for (var i = 0; i < slice.parts.length; i ++) { - var slicePart = slice.parts[i]; - - if (slicePart.intersect.closed) { - var outerLine = slicePart.outerLine; - } - else { - var outerLine = slicePart.intersect.offset(supportMargin); - } - - var overlap = supportSkin.offset(supportMargin).intersect(outerLine); - var overhang = outerLine.difference(overlap); - - if (overlap.length === 0 || overhang.length > 0) { - supportAreas = supportAreas.join(overhang); - } - } + slices[layer].support = supportArea.clone().join(supportArea.intersect(innerFillTemplate)); + slices[layer].supportOutline = supportArea; } } diff --git a/src/sliceActions/optimizePaths.js b/src/sliceActions/optimizePaths.js index 18043ef..cde3fb3 100644 --- a/src/sliceActions/optimizePaths.js +++ b/src/sliceActions/optimizePaths.js @@ -74,7 +74,7 @@ export default function optimizePaths(slices, settings) { slice.parts = parts; - if (typeof slice.support !== 'undefined' && slice.support.length > 0) { + if (typeof slice.support !== 'undefined' && slice.support.paths.length > 0) { slice.support = optimizeShape(slice.support, start); start.copy(slice.support.lastPoint(true)); } diff --git a/src/sliceActions/slicesToGCode.js b/src/sliceActions/slicesToGCode.js index 209ce9b..e794499 100644 --- a/src/sliceActions/slicesToGCode.js +++ b/src/sliceActions/slicesToGCode.js @@ -74,7 +74,7 @@ export default function slicesToGCode(slices, settings) { } if (typeof slice.support !== 'undefined') { - pathToGCode(null, false, gcode, slice.support, true, true, z, profiles.support); + pathToGCode(slice.supportOutline, combing, gcode, slice.support, true, true, z, profiles.support); } }