basic implementation of comb

This commit is contained in:
casperlamboo 2017-08-11 18:54:04 +02:00
parent 4ededa4dfe
commit 65472890eb
2 changed files with 131 additions and 10 deletions

View File

@ -0,0 +1,114 @@
export default function comb(outline, start, end) {
const [path] = outline.mapToLower();
const combPath = [];
const { closestPoint: closestPointStart, lineIndex: lineIndexStart } = findClosestPointOnPath(path, start);
const { closestPoint: closestPointEnd, lineIndex: lineIndexEnd } = findClosestPointOnPath(path, end);
combPath.push(start, closestPointStart);
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]);
}
} else {
for (let i = lineIndexStart; i < lineIndexEnd; i ++) {
combPath.push(path[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]);
}
} else {
for (let i = lineIndexStart; i > lineIndexEnd; i --) {
combPath.push(path[i]);
}
}
}
combPath.push(closestPointEnd, end);
return combPath;
}
function findClosestPointOnPath(path, point) {
let distance = Infinity;
let lineIndex;
let closestPoint;
for (let i = 0; i < path.length; i ++) {
const pointA = path[i];
const pointB = path[(i + 1) % path.length];
const tempClosestPoint = findClosestPointOnLine(pointA, pointB, point);
const tempDistance = distanceTo(tempClosestPoint, point);
if (tempDistance < distance) {
distance = tempDistance;
lineIndex = i;
closestPoint = tempClosestPoint;
}
}
return { closestPoint, lineIndex };
}
function findClosestPointOnLine(a, b, c) {
const b_ = subtract(b, a);
const c_ = subtract(c, a);
const lambda = dot(normalize(b_), c_) / length(b_);
if (lambda >= 1) {
return b;
} else if (lambda > 0) {
return add(a, scale(b_, lambda));
} else {
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));
}

View File

@ -1,4 +1,5 @@
import GCode from './helpers/GCode.js';
import comb from './helpers/comb.js';
const PROFILE_TYPES = ['support', 'innerShell', 'outerShell', 'innerInfill', 'outerInfill', 'brim'];
@ -42,7 +43,7 @@ export default function slicesToGCode(slices, settings) {
}, {});
if (typeof slice.brim !== 'undefined') {
pathToGCode(gcode, slice.brim, true, true, z, profiles.brim);
pathToGCode(null, false, gcode, slice.brim, true, true, z, profiles.brim);
}
for (let i = 0; i < slice.parts.length; i ++) {
@ -55,26 +56,26 @@ export default function slicesToGCode(slices, settings) {
const unRetract = isOuterShell;
const profile = isOuterShell ? profiles.outerShell : profiles.innerShell;
pathToGCode(gcode, shell, false, unRetract, z, profile);
pathToGCode(null, false, gcode, shell, false, unRetract, z, profile);
}
pathToGCode(gcode, part.outerFill, false, false, z, profiles.outerInfill);
pathToGCode(gcode, part.innerFill, true, false, z, profiles.innerInfill);
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);
} else {
const retract = !(slice.parts.length === 1 && typeof slice.support === 'undefined');
pathToGCode(gcode, part.shape, retract, retract, z, profiles.outerShell);
pathToGCode(null, false, gcode, part.shape, retract, retract, z, profiles.outerShell);
}
}
if (typeof slice.support !== 'undefined') {
pathToGCode(gcode, slice.support, true, true, z, profiles.support);
pathToGCode(null, false, gcode, slice.support, true, true, z, profiles.support);
}
}
return gcode.getGCode();
}
function pathToGCode(gcode, shape, retract, unRetract, z, { lineProfile, travelProfile, retractionProfile }) {
function pathToGCode(outline, combing, gcode, shape, retract, unRetract, z, { lineProfile, travelProfile, retractionProfile }) {
const { closed } = shape;
const paths = shape.mapToLower();
@ -86,9 +87,15 @@ function pathToGCode(gcode, shape, retract, unRetract, z, { lineProfile, travelP
const point = line[i % line.length];
if (i === 0) {
// TODO
// moveTo should impliment combing
gcode.moveTo(point.x, point.y, z, travelProfile);
if (combing && gcode._nozzlePosition.distanceTo(point) > 3) {
const combPath = comb(outline, gcode._nozzlePosition, point);
for (let i = 0; i < combPath.length; i ++) {
const combPoint = combPath[i];
gcode.moveTo(combPoint.x, combPoint.y, z, travelProfile);
}
} else {
gcode.moveTo(point.x, point.y, z, travelProfile);
}
if (unRetract) {
gcode.unRetract(retractionProfile);