diff --git a/src/interface/Settings.js b/src/interface/Settings.js
index ee61bad..9a5276c 100644
--- a/src/interface/Settings.js
+++ b/src/interface/Settings.js
@@ -165,6 +165,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) {
@@ -374,6 +382,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/generateInfills.js b/src/sliceActions/generateInfills.js
index 6d854aa..fd04edc 100644
--- a/src/sliceActions/generateInfills.js
+++ b/src/sliceActions/generateInfills.js
@@ -5,7 +5,7 @@ import Shape from 'clipper-js';
export default function generateInfills(slices, settings) {
let {
layerHeight,
- innerInfill: { density: infillDensity },
+ innerInfill: { density },
thickness: {
top: topThickness,
bottom: bottomThickness
@@ -13,11 +13,11 @@ export default function generateInfills(slices, settings) {
nozzleDiameter
} = settings;
- infillDensity /= 100;
+ density /= 100;
nozzleDiameter /= PRECISION;
- const bidirectionalInfill = infillDensity < 0.8;
- const infillGridSize = nozzleDiameter * (bidirectionalInfill ? 2 : 1) / infillDensity;
+ const bidirectionalInfill = density < 0.8;
+ const infillGridSize = nozzleDiameter * (bidirectionalInfill ? 2 : 1) / density;
const bottomSkinCount = Math.ceil(bottomThickness / layerHeight);
const topSkinCount = Math.ceil(topThickness / layerHeight);
diff --git a/src/sliceActions/generateSupport.js b/src/sliceActions/generateSupport.js
index 8e9e0c3..2c8393b 100644
--- a/src/sliceActions/generateSupport.js
+++ b/src/sliceActions/generateSupport.js
@@ -2,75 +2,42 @@ import getFillTemplate from './getFillTemplate.js';
import Shape from 'clipper-js';
import { PRECISION } from '../constants.js';
+const PRECISION_SQUARED = Math.pow(PRECISION, 2);
+
export default function generateSupport(slices, settings) {
if (!settings.support.enabled) return;
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 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() * PRECISION_SQUARED > minArea) {
+ supportArea = supportArea.union(neededSupportArea);
}
+ if (downSkin) supportArea = supportArea.difference(downSkin.outline.offset(margin));
- var supportSkin = slices[layer + supportDistanceLayers - 1].outline;
+ const bounds = supportArea.shapeBounds();
+ const innerFillTemplate = getFillTemplate(bounds, infillGridSize, true, true);
- 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 14070b1..e794499 100644
--- a/src/sliceActions/slicesToGCode.js
+++ b/src/sliceActions/slicesToGCode.js
@@ -62,11 +62,11 @@ export default function slicesToGCode(slices, settings) {
const unRetract = isOuterShell;
const profile = isOuterShell ? profiles.outerShell : profiles.innerShell;
- pathToGCode(outline, combing && true, gcode, shell, false, unRetract, z, profile);
+ pathToGCode(outline, combing, gcode, shell, false, unRetract, z, profile);
}
- pathToGCode(outline, combing && true, gcode, part.outerFill, false, false, z, profiles.outerInfill);
- pathToGCode(outline, combing && true, gcode, part.innerFill, true, false, z, profiles.innerInfill);
+ pathToGCode(outline, combing, gcode, part.outerFill, false, false, z, profiles.outerInfill);
+ pathToGCode(outline, combing, gcode, part.innerFill, true, false, z, profiles.innerInfill);
} else {
const retract = !(slice.parts.length === 1 && typeof slice.support === 'undefined');
pathToGCode(null, false, gcode, part.shape, retract, retract, z, profiles.outerShell);
@@ -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);
}
}