mirror of
https://github.com/Doodle3D/Doodle3D-Slicer.git
synced 2024-11-22 21:47:59 +01:00
update comb code
This commit is contained in:
parent
12a0eadaf4
commit
cb61566c08
@ -1,4 +1,5 @@
|
|||||||
import * as THREE from 'three';
|
import * as THREE from 'three';
|
||||||
|
import { PRECISION } from '../../constants.js';
|
||||||
|
|
||||||
const MOVE = 'G';
|
const MOVE = 'G';
|
||||||
const M_COMMAND = 'M';
|
const M_COMMAND = 'M';
|
||||||
@ -63,15 +64,15 @@ export default class {
|
|||||||
}
|
}
|
||||||
|
|
||||||
moveTo(x, y, z, { speed }) {
|
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);
|
const lineLength = this._nozzlePosition.distanceTo(newNozzlePosition);
|
||||||
|
|
||||||
this._duration += lineLength / speed;
|
this._duration += lineLength / speed;
|
||||||
|
|
||||||
this._addGCode({
|
this._addGCode({
|
||||||
[MOVE]: 0,
|
[MOVE]: 0,
|
||||||
[POSITION_X]: x.toFixed(3),
|
[POSITION_X]: newNozzlePosition.x.toFixed(3),
|
||||||
[POSITION_Y]: y.toFixed(3),
|
[POSITION_Y]: newNozzlePosition.y.toFixed(3),
|
||||||
[POSITION_Z]: z.toFixed(3),
|
[POSITION_Z]: z.toFixed(3),
|
||||||
[SPEED]: (speed * 60).toFixed(3)
|
[SPEED]: (speed * 60).toFixed(3)
|
||||||
});
|
});
|
||||||
@ -82,7 +83,7 @@ export default class {
|
|||||||
}
|
}
|
||||||
|
|
||||||
lineTo(x, y, z, { speed, flowRate }) {
|
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);
|
const lineLength = this._nozzlePosition.distanceTo(newNozzlePosition);
|
||||||
|
|
||||||
this._extruder += this._nozzleToFilamentRatio * lineLength * flowRate;
|
this._extruder += this._nozzleToFilamentRatio * lineLength * flowRate;
|
||||||
@ -90,8 +91,8 @@ export default class {
|
|||||||
|
|
||||||
this._addGCode({
|
this._addGCode({
|
||||||
[MOVE]: 1,
|
[MOVE]: 1,
|
||||||
[POSITION_X]: x.toFixed(3),
|
[POSITION_X]: newNozzlePosition.x.toFixed(3),
|
||||||
[POSITION_Y]: y.toFixed(3),
|
[POSITION_Y]: newNozzlePosition.y.toFixed(3),
|
||||||
[POSITION_Z]: z.toFixed(3),
|
[POSITION_Z]: z.toFixed(3),
|
||||||
[SPEED]: (speed * 60).toFixed(3),
|
[SPEED]: (speed * 60).toFixed(3),
|
||||||
[EXTRUDER]: this._extruder.toFixed(3)
|
[EXTRUDER]: this._extruder.toFixed(3)
|
||||||
|
27
src/sliceActions/helpers/VectorUtils.js
Normal file
27
src/sliceActions/helpers/VectorUtils.js
Normal file
@ -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
|
||||||
|
};
|
||||||
|
}
|
@ -1,25 +1,33 @@
|
|||||||
import Shape from 'clipper-js';
|
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) {
|
export default function comb(outline, start, end) {
|
||||||
if (distanceTo(start, end) < 5) {
|
if (distanceTo(start, end) < TOLERANCE) {
|
||||||
return [start, end];
|
return [start, end];
|
||||||
}
|
}
|
||||||
|
|
||||||
let combPath = new Shape([[start, end]], false, true, false);
|
let combPath = new Shape([[start, end]], false, true, false);
|
||||||
|
|
||||||
for (let i = 0; i < outline.paths.length; i ++) {
|
for (let i = 0; i < outline.paths.length; i ++) {
|
||||||
let outlinePart = new Shape([outline.paths[i]], true, false, false);
|
let outlinePart = new Shape([outline.paths[i]], true, false, false, true);
|
||||||
let snappedCombPaths = i === 0 ? combPath.intersect(outlinePart) : combPath.difference(outlinePart);
|
|
||||||
|
|
||||||
if (snappedCombPaths.paths.length <= 1) continue;
|
let snappedCombPaths = i === 0 ? combPath.intersect(outlinePart) : combPath.difference(outlinePart);
|
||||||
|
|
||||||
snappedCombPaths = snappedCombPaths.mapToLower();
|
snappedCombPaths = snappedCombPaths.mapToLower();
|
||||||
outlinePart = outlinePart.mapToLower()[0];
|
outlinePart = outlinePart.mapToLower()[0];
|
||||||
|
|
||||||
|
if (distanceTo(start, outlinePart[outlinePart.length - 1]) < distanceTo(start, outlinePart[0])) {
|
||||||
|
outlinePart = outlinePart.reverse();
|
||||||
|
}
|
||||||
|
|
||||||
const distanceMap = new WeakMap();
|
const distanceMap = new WeakMap();
|
||||||
|
|
||||||
for (let i = 0; i < snappedCombPaths.length; i ++) {
|
for (let i = 0; i < snappedCombPaths.length; i ++) {
|
||||||
const snappedCombPath = snappedCombPaths[i];
|
const snappedCombPath = snappedCombPaths[i];
|
||||||
|
|
||||||
const distanceStart = distanceTo(start, snappedCombPath[0]);
|
const distanceStart = distanceTo(start, snappedCombPath[0]);
|
||||||
const distanceEnd = distanceTo(start, snappedCombPath[snappedCombPath.length - 1]);
|
const distanceEnd = distanceTo(start, snappedCombPath[snappedCombPath.length - 1]);
|
||||||
|
|
||||||
@ -30,9 +38,24 @@ export default function comb(outline, start, end) {
|
|||||||
distanceMap.set(snappedCombPath, distanceEnd);
|
distanceMap.set(snappedCombPath, distanceEnd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
snappedCombPaths.sort((a, b) => distanceMap.get(a) - distanceMap.get(b));
|
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 startPath = snappedCombPaths[0];
|
||||||
const startPoint = startPath[startPath.length - 1];
|
const startPoint = startPath[startPath.length - 1];
|
||||||
|
|
||||||
@ -43,7 +66,9 @@ export default function comb(outline, start, end) {
|
|||||||
const lineIndexEnd = findClosestLineOnPath(outlinePart, endPoint);
|
const lineIndexEnd = findClosestLineOnPath(outlinePart, endPoint);
|
||||||
|
|
||||||
const path = [];
|
const path = [];
|
||||||
if (lineIndexEnd > lineIndexStart) {
|
if (lineIndexEnd === lineIndexStart) {
|
||||||
|
continue;
|
||||||
|
} else if (lineIndexEnd > lineIndexStart) {
|
||||||
if (lineIndexStart + outlinePart.length - lineIndexEnd < lineIndexEnd - lineIndexStart) {
|
if (lineIndexStart + outlinePart.length - lineIndexEnd < lineIndexEnd - lineIndexStart) {
|
||||||
for (let i = lineIndexStart + outlinePart.length; i > lineIndexEnd; i --) {
|
for (let i = lineIndexStart + outlinePart.length; i > lineIndexEnd; i --) {
|
||||||
path.push(outlinePart[i % outlinePart.length]);
|
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];
|
return combPath.mapToLower()[0];
|
||||||
@ -105,45 +130,3 @@ function findClosestPointOnLine(a, b, c) {
|
|||||||
return a;
|
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));
|
|
||||||
}
|
|
||||||
|
@ -11,7 +11,7 @@ import shapesToSlices from './shapesToSlices.js';
|
|||||||
import slicesToGCode from './slicesToGCode.js';
|
import slicesToGCode from './slicesToGCode.js';
|
||||||
import detectOpenClosed from './detectOpenClosed.js';
|
import detectOpenClosed from './detectOpenClosed.js';
|
||||||
import applyPrecision from './applyPrecision.js';
|
import applyPrecision from './applyPrecision.js';
|
||||||
import removePrecision from './removePrecision.js';
|
// import removePrecision from './removePrecision.js';
|
||||||
|
|
||||||
export default function(settings, geometry, onProgress) {
|
export default function(settings, geometry, onProgress) {
|
||||||
const totalStages = 12;
|
const totalStages = 12;
|
||||||
@ -65,7 +65,7 @@ export default function(settings, geometry, onProgress) {
|
|||||||
updateProgress('Optimizing paths');
|
updateProgress('Optimizing paths');
|
||||||
optimizePaths(slices, settings);
|
optimizePaths(slices, settings);
|
||||||
|
|
||||||
removePrecision(slices);
|
// removePrecision(slices);
|
||||||
|
|
||||||
updateProgress('Constructing gcode');
|
updateProgress('Constructing gcode');
|
||||||
const gcode = slicesToGCode(slices, settings);
|
const gcode = slicesToGCode(slices, settings);
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import GCode from './helpers/GCode.js';
|
import GCode from './helpers/GCode.js';
|
||||||
import comb from './helpers/comb.js';
|
import comb from './helpers/comb.js';
|
||||||
|
import { PRECISION } from '../constants.js';
|
||||||
|
|
||||||
const PROFILE_TYPES = ['support', 'innerShell', 'outerShell', 'innerInfill', 'outerInfill', 'brim'];
|
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 (i === 0) {
|
||||||
if (combing) {
|
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 ++) {
|
for (let i = 0; i < combPath.length; i ++) {
|
||||||
const combPoint = combPath[i];
|
const combPoint = combPath[i];
|
||||||
gcode.moveTo(combPoint.x, combPoint.y, z, travelProfile);
|
gcode.moveTo(combPoint.x, combPoint.y, z, travelProfile);
|
||||||
|
Loading…
Reference in New Issue
Block a user