From cb61566c0800cab24e178f0c8e9ec0adf59cb8f1 Mon Sep 17 00:00:00 2001 From: casperlamboo Date: Thu, 24 Aug 2017 10:55:36 +0200 Subject: [PATCH] update comb code --- src/sliceActions/helpers/GCode.js | 13 ++-- src/sliceActions/helpers/VectorUtils.js | 27 +++++++++ src/sliceActions/helpers/comb.js | 81 ++++++++++--------------- src/sliceActions/slice.js | 4 +- src/sliceActions/slicesToGCode.js | 3 +- 5 files changed, 70 insertions(+), 58 deletions(-) create mode 100644 src/sliceActions/helpers/VectorUtils.js diff --git a/src/sliceActions/helpers/GCode.js b/src/sliceActions/helpers/GCode.js index a241754..71f9a65 100644 --- a/src/sliceActions/helpers/GCode.js +++ b/src/sliceActions/helpers/GCode.js @@ -1,4 +1,5 @@ import * as THREE from 'three'; +import { PRECISION } from '../../constants.js'; const MOVE = 'G'; const M_COMMAND = 'M'; @@ -63,15 +64,15 @@ export default class { } moveTo(x, y, z, { speed }) { - const newNozzlePosition = new THREE.Vector2(x, y); + const newNozzlePosition = new THREE.Vector2(x, y).multiplyScalar(PRECISION); const lineLength = this._nozzlePosition.distanceTo(newNozzlePosition); this._duration += lineLength / speed; this._addGCode({ [MOVE]: 0, - [POSITION_X]: x.toFixed(3), - [POSITION_Y]: y.toFixed(3), + [POSITION_X]: newNozzlePosition.x.toFixed(3), + [POSITION_Y]: newNozzlePosition.y.toFixed(3), [POSITION_Z]: z.toFixed(3), [SPEED]: (speed * 60).toFixed(3) }); @@ -82,7 +83,7 @@ export default class { } lineTo(x, y, z, { speed, flowRate }) { - const newNozzlePosition = new THREE.Vector2(x, y); + const newNozzlePosition = new THREE.Vector2(x, y).multiplyScalar(PRECISION); const lineLength = this._nozzlePosition.distanceTo(newNozzlePosition); this._extruder += this._nozzleToFilamentRatio * lineLength * flowRate; @@ -90,8 +91,8 @@ export default class { this._addGCode({ [MOVE]: 1, - [POSITION_X]: x.toFixed(3), - [POSITION_Y]: y.toFixed(3), + [POSITION_X]: newNozzlePosition.x.toFixed(3), + [POSITION_Y]: newNozzlePosition.y.toFixed(3), [POSITION_Z]: z.toFixed(3), [SPEED]: (speed * 60).toFixed(3), [EXTRUDER]: this._extruder.toFixed(3) diff --git a/src/sliceActions/helpers/VectorUtils.js b/src/sliceActions/helpers/VectorUtils.js new file mode 100644 index 0000000..e61b266 --- /dev/null +++ b/src/sliceActions/helpers/VectorUtils.js @@ -0,0 +1,27 @@ +export const subtract = (a, b) => ({ + x: a.x - b.x, + y: a.y - b.y +}); +export const add = (a, b) => ({ + x: a.x + b.x, + y: a.y + b.y +}); +export const scale = (a, factor) => ({ + x: a.x * factor, + y: a.y * factor +}); +export const normal = (a) => ({ + x: -a.y, + y: a.x +}); +export const dot = (a, b) => a.x * b.x + a.y * b.y; +export const length = (a) => Math.sqrt(a.x * a.x + a.y * a.y); +export const distanceTo = (a, b) => length(subtract(a, b)); +export const normalize = (a) => { + const l = length(a); + + return { + x: a.x / l, + y: a.y / l + }; +} diff --git a/src/sliceActions/helpers/comb.js b/src/sliceActions/helpers/comb.js index e8c6c3f..9044272 100644 --- a/src/sliceActions/helpers/comb.js +++ b/src/sliceActions/helpers/comb.js @@ -1,25 +1,33 @@ import Shape from 'clipper-js'; +import { subtract, add, scale, normalize, dot, length, distanceTo } from './VectorUtils.js'; +import { PRECISION } from '../../constants.js'; + +const TOLERANCE = 5 / PRECISION; export default function comb(outline, start, end) { - if (distanceTo(start, end) < 5) { + if (distanceTo(start, end) < TOLERANCE) { return [start, end]; } let combPath = new Shape([[start, end]], false, true, false); for (let i = 0; i < outline.paths.length; i ++) { - let outlinePart = new Shape([outline.paths[i]], true, false, false); - let snappedCombPaths = i === 0 ? combPath.intersect(outlinePart) : combPath.difference(outlinePart); + let outlinePart = new Shape([outline.paths[i]], true, false, false, true); - if (snappedCombPaths.paths.length <= 1) continue; + let snappedCombPaths = i === 0 ? combPath.intersect(outlinePart) : combPath.difference(outlinePart); snappedCombPaths = snappedCombPaths.mapToLower(); outlinePart = outlinePart.mapToLower()[0]; + if (distanceTo(start, outlinePart[outlinePart.length - 1]) < distanceTo(start, outlinePart[0])) { + outlinePart = outlinePart.reverse(); + } + const distanceMap = new WeakMap(); for (let i = 0; i < snappedCombPaths.length; i ++) { const snappedCombPath = snappedCombPaths[i]; + const distanceStart = distanceTo(start, snappedCombPath[0]); const distanceEnd = distanceTo(start, snappedCombPath[snappedCombPath.length - 1]); @@ -30,9 +38,24 @@ export default function comb(outline, start, end) { distanceMap.set(snappedCombPath, distanceEnd); } } - snappedCombPaths.sort((a, b) => distanceMap.get(a) - distanceMap.get(b)); + const firstPath = snappedCombPaths[0]; + const lastPath = snappedCombPaths[snappedCombPaths.length - 1]; + + if (snappedCombPaths.length === 0) { + continue; + // snappedCombPaths.push([start], [end]); + } else if (distanceTo(firstPath[0], start) > 1.0) { + snappedCombPaths.unshift([start]); + } else if (distanceTo(lastPath[lastPath.length - 1], end) > 1.0) { + snappedCombPaths.push([end]); + } + + if (snappedCombPaths.length === 1) { + continue; + } + const startPath = snappedCombPaths[0]; const startPoint = startPath[startPath.length - 1]; @@ -43,7 +66,9 @@ export default function comb(outline, start, end) { const lineIndexEnd = findClosestLineOnPath(outlinePart, endPoint); const path = []; - if (lineIndexEnd > lineIndexStart) { + if (lineIndexEnd === lineIndexStart) { + continue; + } else if (lineIndexEnd > lineIndexStart) { if (lineIndexStart + outlinePart.length - lineIndexEnd < lineIndexEnd - lineIndexStart) { for (let i = lineIndexStart + outlinePart.length; i > lineIndexEnd; i --) { path.push(outlinePart[i % outlinePart.length]); @@ -65,7 +90,7 @@ export default function comb(outline, start, end) { } } - combPath = new Shape([[...startPath, ...path, ...endPath]], false, true, false); + combPath = new Shape([[...startPath, ...path, ...endPath]], false, true, false, true); } return combPath.mapToLower()[0]; @@ -105,45 +130,3 @@ function findClosestPointOnLine(a, b, c) { return a; } } - -function subtract(a, b) { - return { - x: a.x - b.x, - y: a.y - b.y - }; -} - -function add(a, b) { - return { - x: a.x + b.x, - y: a.y + b.y - }; -} - -function scale(a, factor) { - return { - x: a.x * factor, - y: a.y * factor - } -} - -function dot(a, b) { - return a.x * b.x + a.y * b.y; -} - -function normalize(a) { - const l = length(a); - - return { - x: a.x / l, - y: a.y / l - }; -} - -function length(a) { - return Math.sqrt(a.x * a.x + a.y * a.y); -} - -function distanceTo(a, b) { - return length(subtract(a, b)); -} diff --git a/src/sliceActions/slice.js b/src/sliceActions/slice.js index 2d3fdd0..30168bf 100644 --- a/src/sliceActions/slice.js +++ b/src/sliceActions/slice.js @@ -11,7 +11,7 @@ import shapesToSlices from './shapesToSlices.js'; import slicesToGCode from './slicesToGCode.js'; import detectOpenClosed from './detectOpenClosed.js'; import applyPrecision from './applyPrecision.js'; -import removePrecision from './removePrecision.js'; +// import removePrecision from './removePrecision.js'; export default function(settings, geometry, onProgress) { const totalStages = 12; @@ -65,7 +65,7 @@ export default function(settings, geometry, onProgress) { updateProgress('Optimizing paths'); optimizePaths(slices, settings); - removePrecision(slices); + // removePrecision(slices); updateProgress('Constructing gcode'); const gcode = slicesToGCode(slices, settings); diff --git a/src/sliceActions/slicesToGCode.js b/src/sliceActions/slicesToGCode.js index 9d2be7d..96e1db3 100644 --- a/src/sliceActions/slicesToGCode.js +++ b/src/sliceActions/slicesToGCode.js @@ -1,5 +1,6 @@ import GCode from './helpers/GCode.js'; import comb from './helpers/comb.js'; +import { PRECISION } from '../constants.js'; const PROFILE_TYPES = ['support', 'innerShell', 'outerShell', 'innerInfill', 'outerInfill', 'brim']; @@ -90,7 +91,7 @@ function pathToGCode(outline, combing, gcode, shape, retract, unRetract, z, { li if (i === 0) { if (combing) { - const combPath = comb(outline, gcode._nozzlePosition, point); + const combPath = comb(outline, gcode._nozzlePosition.divideScalar(PRECISION), point); for (let i = 0; i < combPath.length; i ++) { const combPoint = combPath[i]; gcode.moveTo(combPoint.x, combPoint.y, z, travelProfile);