update combing

This commit is contained in:
casperlamboo 2017-08-17 16:13:21 +02:00
parent 65472890eb
commit 1afbe54dc7
4 changed files with 157 additions and 39 deletions

View File

@ -0,0 +1,80 @@
import Shape from 'clipper-js';
import comb from '../src/sliceActions/helpers/comb.js';
const canvas = document.createElement('canvas');
document.body.appendChild(canvas);
canvas.width = 720;
canvas.height = 480;
const context = canvas.getContext('2d');
const outline = new Shape([[
{ x: 100, y: 100 },
{ x: 400, y: 100 },
{ x: 400, y: 150 },
{ x: 200, y: 150 },
{ x: 200, y: 200 },
{ x: 400, y: 200 },
{ x: 400, y: 250 },
{ x: 200, y: 250 },
{ x: 200, y: 300 },
{ x: 400, y: 300 },
{ x: 400, y: 400 },
{ x: 100, y: 400 }
], [
{ x: 130, y: 310 },
{ x: 130, y: 370 },
{ x: 360, y: 370 },
{ x: 360, y: 360 },
{ x: 150, y: 360 },
{ x: 150, y: 350 },
{ x: 360, y: 350 },
{ x: 360, y: 340 },
{ x: 150, y: 340 },
{ x: 150, y: 330 },
{ x: 360, y: 330 },
{ x: 360, y: 310 }
]], true, true, false);
const start = { x: 380, y: 120 };
const end = { x: 200, y: 380 };
let combPath = comb(outline, start, end);
canvas.onmousemove = (event) => {
start.x = event.x;
start.y = event.y;
combPath = comb(outline, start, end);
draw();
};
draw();
function draw() {
context.clearRect(0, 0, canvas.width, canvas.height);
context.strokeStyle = 'black';
for (const path of outline.mapToLower()) {
context.beginPath();
for (const point of path) {
context.lineTo(point.x, point.y);
}
context.closePath();
context.stroke();
}
context.strokeStyle = 'red';
context.beginPath();
for (const point of combPath) {
context.lineTo(point.x, point.y);
}
context.stroke();
context.beginPath();
context.arc(start.x, start.y, 3, 0, Math.PI * 2.0, false);
context.stroke();
context.beginPath();
context.arc(end.x, end.y, 3, 0, Math.PI * 2.0, false);
context.stroke();
}

View File

@ -8,6 +8,7 @@ filamentThickness: 2.85
temperature: 210 temperature: 210
bedTemperature: 70 bedTemperature: 70
layerHeight: 0.15 layerHeight: 0.15
combing: true
thickness: thickness:
top: 1.2 top: 1.2
bottom: 1.2 bottom: 1.2

View File

@ -1,43 +1,79 @@
import Shape from 'clipper-js';
export default function comb(outline, start, end) { export default function comb(outline, start, end) {
const [path] = outline.mapToLower(); if (distanceTo(start, end) < 5) {
const combPath = []; return [start, end];
}
const { closestPoint: closestPointStart, lineIndex: lineIndexStart } = findClosestPointOnPath(path, start); let combPath = new Shape([[start, end]], false, true, false);
const { closestPoint: closestPointEnd, lineIndex: lineIndexEnd } = findClosestPointOnPath(path, end);
combPath.push(start, closestPointStart); 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);
if (snappedCombPaths.paths.length <= 1) continue;
snappedCombPaths = snappedCombPaths.mapToLower();
outlinePart = outlinePart.mapToLower()[0];
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]);
if (distanceStart < distanceEnd) {
distanceMap.set(snappedCombPath, distanceStart);
} else {
snappedCombPath.reverse();
distanceMap.set(snappedCombPath, distanceEnd);
}
}
snappedCombPaths.sort((a, b) => distanceMap.get(a) - distanceMap.get(b));
const startPath = snappedCombPaths[0];
const startPoint = startPath[startPath.length - 1];
const endPath = snappedCombPaths[snappedCombPaths.length - 1];
const endPoint = endPath[0];
const lineIndexStart = findClosestLineOnPath(outlinePart, startPoint);
const lineIndexEnd = findClosestLineOnPath(outlinePart, endPoint);
const path = [];
if (lineIndexEnd > lineIndexStart) { if (lineIndexEnd > lineIndexStart) {
if (lineIndexStart + path.length - lineIndexEnd < lineIndexEnd - lineIndexStart) { if (lineIndexStart + outlinePart.length - lineIndexEnd < lineIndexEnd - lineIndexStart) {
for (let i = lineIndexStart + path.length; i > lineIndexEnd; i --) { for (let i = lineIndexStart + outlinePart.length; i > lineIndexEnd; i --) {
combPath.push(path[i % path.length]); path.push(outlinePart[i % outlinePart.length]);
} }
} else { } else {
for (let i = lineIndexStart; i < lineIndexEnd; i ++) { for (let i = lineIndexStart; i < lineIndexEnd; i ++) {
combPath.push(path[i + 1]); path.push(outlinePart[i + 1]);
} }
} }
} else { } else {
if (lineIndexEnd + path.length - lineIndexStart < lineIndexStart - lineIndexEnd) { if (lineIndexEnd + outlinePart.length - lineIndexStart < lineIndexStart - lineIndexEnd) {
for (let i = lineIndexStart; i < lineIndexEnd + path.length; i ++) { for (let i = lineIndexStart; i < lineIndexEnd + outlinePart.length; i ++) {
combPath.push(path[(i + 1) % path.length]); path.push(outlinePart[(i + 1) % outlinePart.length]);
} }
} else { } else {
for (let i = lineIndexStart; i > lineIndexEnd; i --) { for (let i = lineIndexStart; i > lineIndexEnd; i --) {
combPath.push(path[i]); path.push(outlinePart[i]);
} }
} }
} }
combPath.push(closestPointEnd, end); combPath = new Shape([[...startPath, ...path, ...endPath]], false, true, false);
return combPath;
} }
function findClosestPointOnPath(path, point) { return combPath.mapToLower()[0];
}
function findClosestLineOnPath(path, point) {
let distance = Infinity; let distance = Infinity;
let lineIndex; let lineIndex;
let closestPoint;
for (let i = 0; i < path.length; i ++) { for (let i = 0; i < path.length; i ++) {
const pointA = path[i]; const pointA = path[i];
@ -49,11 +85,10 @@ function findClosestPointOnPath(path, point) {
if (tempDistance < distance) { if (tempDistance < distance) {
distance = tempDistance; distance = tempDistance;
lineIndex = i; lineIndex = i;
closestPoint = tempClosestPoint;
} }
} }
return { closestPoint, lineIndex }; return lineIndex;
} }
function findClosestPointOnLine(a, b, c) { function findClosestPointOnLine(a, b, c) {

View File

@ -10,7 +10,8 @@ export default function slicesToGCode(slices, settings) {
nozzleDiameter, nozzleDiameter,
travelSpeed, travelSpeed,
retraction, retraction,
travel travel,
combing
} = settings; } = settings;
const filamentSurfaceArea = Math.pow((filamentThickness / 2), 2) * Math.PI; const filamentSurfaceArea = Math.pow((filamentThickness / 2), 2) * Math.PI;
@ -48,6 +49,7 @@ export default function slicesToGCode(slices, settings) {
for (let i = 0; i < slice.parts.length; i ++) { for (let i = 0; i < slice.parts.length; i ++) {
const part = slice.parts[i]; const part = slice.parts[i];
const outline = part.shell[0];
if (part.closed) { if (part.closed) {
for (let i = 0; i < part.shell.length; i ++) { for (let i = 0; i < part.shell.length; i ++) {
@ -56,11 +58,11 @@ export default function slicesToGCode(slices, settings) {
const unRetract = isOuterShell; const unRetract = isOuterShell;
const profile = isOuterShell ? profiles.outerShell : profiles.innerShell; const profile = isOuterShell ? profiles.outerShell : profiles.innerShell;
pathToGCode(null, false, gcode, shell, false, unRetract, z, profile); pathToGCode(outline, combing && true, gcode, shell, false, unRetract, z, profile);
} }
pathToGCode(part.shell[0], true, gcode, part.outerFill, false, false, z, profiles.outerInfill); pathToGCode(outline, combing && true, gcode, part.outerFill, false, false, z, profiles.outerInfill);
pathToGCode(part.shell[0], true, gcode, part.innerFill, true, false, z, profiles.innerInfill); pathToGCode(outline, combing && true, gcode, part.innerFill, true, false, z, profiles.innerInfill);
} else { } else {
const retract = !(slice.parts.length === 1 && typeof slice.support === 'undefined'); const retract = !(slice.parts.length === 1 && typeof slice.support === 'undefined');
pathToGCode(null, false, gcode, part.shape, retract, retract, z, profiles.outerShell); pathToGCode(null, false, gcode, part.shape, retract, retract, z, profiles.outerShell);
@ -87,7 +89,7 @@ function pathToGCode(outline, combing, gcode, shape, retract, unRetract, z, { li
const point = line[i % line.length]; const point = line[i % line.length];
if (i === 0) { if (i === 0) {
if (combing && gcode._nozzlePosition.distanceTo(point) > 3) { if (combing) {
const combPath = comb(outline, gcode._nozzlePosition, point); const combPath = comb(outline, gcode._nozzlePosition, point);
for (let i = 0; i < combPath.length; i ++) { for (let i = 0; i < combPath.length; i ++) {
const combPoint = combPath[i]; const combPoint = combPath[i];