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
bedTemperature: 70
layerHeight: 0.15
combing: true
thickness:
top: 1.2
bottom: 1.2

View File

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

View File

@ -10,7 +10,8 @@ export default function slicesToGCode(slices, settings) {
nozzleDiameter,
travelSpeed,
retraction,
travel
travel,
combing
} = settings;
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 ++) {
const part = slice.parts[i];
const outline = part.shell[0];
if (part.closed) {
for (let i = 0; i < part.shell.length; i ++) {
@ -56,11 +58,11 @@ export default function slicesToGCode(slices, settings) {
const unRetract = isOuterShell;
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(part.shell[0], true, gcode, part.innerFill, true, false, z, profiles.innerInfill);
pathToGCode(outline, combing && true, gcode, part.outerFill, false, false, z, profiles.outerInfill);
pathToGCode(outline, combing && true, 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);
@ -87,7 +89,7 @@ function pathToGCode(outline, combing, gcode, shape, retract, unRetract, z, { li
const point = line[i % line.length];
if (i === 0) {
if (combing && gcode._nozzlePosition.distanceTo(point) > 3) {
if (combing) {
const combPath = comb(outline, gcode._nozzlePosition, point);
for (let i = 0; i < combPath.length; i ++) {
const combPoint = combPath[i];