mirror of
https://github.com/Doodle3D/Doodle3D-Slicer.git
synced 2024-12-23 11:33:49 +01:00
rafacter
This commit is contained in:
parent
2b10f388f7
commit
4edb1985c8
58
config.js
58
config.js
@ -16,81 +16,77 @@ System.config({
|
||||
},
|
||||
|
||||
map: {
|
||||
"babel": "npm:babel-core@5.8.21",
|
||||
"babel-runtime": "npm:babel-runtime@5.8.20",
|
||||
"Doodle3D/clipper-js": "github:Doodle3D/clipper-js@0.0.2",
|
||||
"babel": "npm:babel-core@5.8.38",
|
||||
"babel-runtime": "npm:babel-runtime@5.8.38",
|
||||
"casperlamboo/EventDispatcher": "github:casperlamboo/EventDispatcher@master",
|
||||
"clipper-lib": "npm:clipper-lib@1.0.0",
|
||||
"core-js": "npm:core-js@0.9.18",
|
||||
"json": "github:systemjs/plugin-json@0.1.0",
|
||||
"nodeca/js-yaml": "github:nodeca/js-yaml@3.3.1",
|
||||
"nodeca/js-yaml": "github:nodeca/js-yaml@3.5.5",
|
||||
"read-yaml": "npm:read-yaml@1.0.0",
|
||||
"systemjs/plugin-json": "github:systemjs/plugin-json@0.1.0",
|
||||
"three.js": "github:mrdoob/three.js@r72",
|
||||
"github:Doodle3D/clipper-js@0.0.2": {
|
||||
"clipper-lib": "npm:clipper-lib@1.0.0"
|
||||
},
|
||||
"github:jspm/nodelibs-assert@0.1.0": {
|
||||
"assert": "npm:assert@1.3.0"
|
||||
},
|
||||
"github:jspm/nodelibs-path@0.1.0": {
|
||||
"path-browserify": "npm:path-browserify@0.0.0"
|
||||
},
|
||||
"github:jspm/nodelibs-process@0.1.1": {
|
||||
"process": "npm:process@0.10.1"
|
||||
"github:jspm/nodelibs-process@0.1.2": {
|
||||
"process": "npm:process@0.11.2"
|
||||
},
|
||||
"github:jspm/nodelibs-util@0.1.0": {
|
||||
"util": "npm:util@0.10.3"
|
||||
},
|
||||
"npm:argparse@1.0.2": {
|
||||
"assert": "github:jspm/nodelibs-assert@0.1.0",
|
||||
"npm:argparse@1.0.7": {
|
||||
"fs": "github:jspm/nodelibs-fs@0.1.2",
|
||||
"lodash": "npm:lodash@3.10.1",
|
||||
"path": "github:jspm/nodelibs-path@0.1.0",
|
||||
"process": "github:jspm/nodelibs-process@0.1.1",
|
||||
"process": "github:jspm/nodelibs-process@0.1.2",
|
||||
"sprintf-js": "npm:sprintf-js@1.0.3",
|
||||
"util": "github:jspm/nodelibs-util@0.1.0"
|
||||
},
|
||||
"npm:assert@1.3.0": {
|
||||
"util": "npm:util@0.10.3"
|
||||
},
|
||||
"npm:babel-runtime@5.8.20": {
|
||||
"process": "github:jspm/nodelibs-process@0.1.1"
|
||||
"npm:babel-runtime@5.8.38": {
|
||||
"process": "github:jspm/nodelibs-process@0.1.2"
|
||||
},
|
||||
"npm:clipper-lib@1.0.0": {
|
||||
"process": "github:jspm/nodelibs-process@0.1.1"
|
||||
"process": "github:jspm/nodelibs-process@0.1.2"
|
||||
},
|
||||
"npm:core-js@0.9.18": {
|
||||
"fs": "github:jspm/nodelibs-fs@0.1.2",
|
||||
"process": "github:jspm/nodelibs-process@0.1.1",
|
||||
"process": "github:jspm/nodelibs-process@0.1.2",
|
||||
"systemjs-json": "github:systemjs/plugin-json@0.1.0"
|
||||
},
|
||||
"npm:esprima@2.2.0": {
|
||||
"fs": "github:jspm/nodelibs-fs@0.1.2",
|
||||
"process": "github:jspm/nodelibs-process@0.1.1"
|
||||
},
|
||||
"npm:inherits@2.0.1": {
|
||||
"util": "github:jspm/nodelibs-util@0.1.0"
|
||||
},
|
||||
"npm:js-yaml@3.3.1": {
|
||||
"argparse": "npm:argparse@1.0.2",
|
||||
"esprima": "npm:esprima@2.2.0",
|
||||
"npm:js-yaml@3.5.5": {
|
||||
"argparse": "npm:argparse@1.0.7",
|
||||
"esprima": "npm:esprima@2.7.2",
|
||||
"fs": "github:jspm/nodelibs-fs@0.1.2",
|
||||
"path": "github:jspm/nodelibs-path@0.1.0",
|
||||
"process": "github:jspm/nodelibs-process@0.1.1",
|
||||
"systemjs-json": "github:systemjs/plugin-json@0.1.0",
|
||||
"util": "github:jspm/nodelibs-util@0.1.0"
|
||||
},
|
||||
"npm:lodash@3.10.1": {
|
||||
"process": "github:jspm/nodelibs-process@0.1.1"
|
||||
"process": "github:jspm/nodelibs-process@0.1.2",
|
||||
"systemjs-json": "github:systemjs/plugin-json@0.1.0"
|
||||
},
|
||||
"npm:path-browserify@0.0.0": {
|
||||
"process": "github:jspm/nodelibs-process@0.1.1"
|
||||
"process": "github:jspm/nodelibs-process@0.1.2"
|
||||
},
|
||||
"npm:process@0.11.2": {
|
||||
"assert": "github:jspm/nodelibs-assert@0.1.0"
|
||||
},
|
||||
"npm:read-yaml@1.0.0": {
|
||||
"fs": "github:jspm/nodelibs-fs@0.1.2",
|
||||
"js-yaml": "npm:js-yaml@3.3.1",
|
||||
"xtend": "npm:xtend@4.0.0"
|
||||
"js-yaml": "npm:js-yaml@3.5.5",
|
||||
"xtend": "npm:xtend@4.0.1"
|
||||
},
|
||||
"npm:util@0.10.3": {
|
||||
"inherits": "npm:inherits@2.0.1",
|
||||
"process": "github:jspm/nodelibs-process@0.1.1"
|
||||
"process": "github:jspm/nodelibs-process@0.1.2"
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -5,6 +5,7 @@
|
||||
"lib": "src"
|
||||
},
|
||||
"dependencies": {
|
||||
"Doodle3D/clipper-js": "github:Doodle3D/clipper-js@^0.0.2",
|
||||
"casperlamboo/EventDispatcher": "github:casperlamboo/EventDispatcher@master",
|
||||
"clipper-lib": "npm:clipper-lib@^1.0.0",
|
||||
"nodeca/js-yaml": "github:nodeca/js-yaml@^3.3.1",
|
||||
|
59
src/slice.js
59
src/slice.js
@ -1,35 +1,10 @@
|
||||
import Paths from './paths.js';
|
||||
import Shape from 'Doodle3D/clipper-js';
|
||||
|
||||
export default class {
|
||||
constructor () {
|
||||
this.parts = [];
|
||||
}
|
||||
|
||||
removeSelfIntersect () {
|
||||
for (var i = 0; i < this.parts.length; i ++) {
|
||||
var part1 = this.parts[i].intersect;
|
||||
|
||||
if (!part1.closed) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (var j = i + 1; j < this.parts.length; j ++) {
|
||||
var part2 = this.parts[j].intersect;
|
||||
|
||||
if (!part2.closed) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (part2.intersect(part1).length > 0) {
|
||||
part1 = this.parts[i].intersect = part1.union(part2);
|
||||
|
||||
this.parts.splice(j, 1);
|
||||
j --;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
optimizePaths (start) {
|
||||
if (this.brim !== undefined && this.brim.length > 0) {
|
||||
this.brim = this.brim.optimizePath(start);
|
||||
@ -45,11 +20,11 @@ export default class {
|
||||
|
||||
for (var i = 0; i < this.parts.length; i ++) {
|
||||
var part = this.parts[i];
|
||||
if (part.intersect.closed) {
|
||||
if (part.shape.closed) {
|
||||
var bounds = part.outerLine.bounds();
|
||||
}
|
||||
else {
|
||||
var bounds = part.intersect.bounds();
|
||||
var bounds = part.shape.bounds();
|
||||
}
|
||||
|
||||
var top = bounds.top - start.y;
|
||||
@ -68,7 +43,7 @@ export default class {
|
||||
var part = this.parts.splice(closestPart, 1)[0];
|
||||
parts.push(part);
|
||||
|
||||
if (part.intersect.closed) {
|
||||
if (part.shape.closed) {
|
||||
if (part.outerLine.length > 0) {
|
||||
part.outerLine = part.outerLine.optimizePath(start);
|
||||
start = part.outerLine.lastPoint();
|
||||
@ -88,8 +63,8 @@ export default class {
|
||||
}
|
||||
}
|
||||
else {
|
||||
part.intersect.optimizePath(start);
|
||||
start = part.intersect.lastPoint();
|
||||
part.shape.optimizePath(start);
|
||||
start = part.shape.lastPoint();
|
||||
}
|
||||
|
||||
}
|
||||
@ -105,12 +80,12 @@ export default class {
|
||||
}
|
||||
|
||||
getOutline () {
|
||||
var outLines = new Paths([], true);
|
||||
var outLines = new Shape([], true);
|
||||
|
||||
for (var i = 0; i < this.parts.length; i ++) {
|
||||
var part = this.parts[i];
|
||||
|
||||
if (part.intersect.closed) {
|
||||
if (part.shape.closed) {
|
||||
outLines.join(this.parts[i].outerLine);
|
||||
}
|
||||
}
|
||||
@ -118,17 +93,15 @@ export default class {
|
||||
return outLines;
|
||||
}
|
||||
|
||||
add (intersect) {
|
||||
var parts = {
|
||||
intersect
|
||||
};
|
||||
add (shape) {
|
||||
const part = { shape };
|
||||
|
||||
if (intersect.closed) {
|
||||
parts.innerLines = [];
|
||||
parts.outerLine = new Paths([], true);
|
||||
parts.fill = new Paths([], false);
|
||||
if (shape.closed) {
|
||||
part.innerLines = [];
|
||||
part.outerLine = new Shape([], true);
|
||||
part.fill = new Shape([], false);
|
||||
}
|
||||
|
||||
this.parts.push(parts);
|
||||
this.parts.push(part);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -41,7 +41,7 @@ export default function generateInfills(slices, settings) {
|
||||
for (var i = 0; i < slice.parts.length; i ++) {
|
||||
var part = slice.parts[i];
|
||||
|
||||
if (!part.intersect.closed) {
|
||||
if (!part.shape.closed) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -1,10 +1,16 @@
|
||||
const scale = 100;
|
||||
const offsetOptions = {
|
||||
jointType: 'jtSquare',
|
||||
endType: 'etClosedPolygon',
|
||||
miterLimit: 2.0,
|
||||
roundPrecision: 0.25
|
||||
};
|
||||
|
||||
export default function generateInnerLines(slices, settings) {
|
||||
console.log("generating outer lines and inner lines");
|
||||
|
||||
// need to scale up everything because of clipper rounding errors
|
||||
let {layerHeight, nozzleDiameter, shellThickness} = settings.config;
|
||||
let { layerHeight, nozzleDiameter, shellThickness } = settings.config;
|
||||
nozzleDiameter *= scale;
|
||||
shellThickness *= scale;
|
||||
var nozzleRadius = nozzleDiameter / 2;
|
||||
@ -16,23 +22,21 @@ export default function generateInnerLines(slices, settings) {
|
||||
for (var i = 0; i < slice.parts.length; i ++) {
|
||||
var part = slice.parts[i];
|
||||
|
||||
if (!part.intersect.closed) {
|
||||
continue;
|
||||
}
|
||||
if (!part.shape.closed) continue;
|
||||
|
||||
// var outerLine = part.intersect.clone().scaleUp(scale).offset(-nozzleRadius);
|
||||
var outerLine = part.intersect.scaleUp(scale).offset(-nozzleRadius);
|
||||
// var outerLine = part.shape.clone().scaleUp(scale).offset(-nozzleRadius);
|
||||
var outerLine = part.shape.scaleUp(scale).offset(-nozzleRadius, offsetOptions);
|
||||
|
||||
if (outerLine.length > 0) {
|
||||
part.outerLine = outerLine;
|
||||
part.outerLine.join(outerLine);
|
||||
|
||||
for (var shell = 1; shell < shells; shell += 1) {
|
||||
var offset = shell * nozzleDiameter;
|
||||
|
||||
var innerLine = outerLine.offset(-offset);
|
||||
var innerLine = outerLine.offset(-offset, offsetOptions);
|
||||
|
||||
if (innerLine.length > 0) {
|
||||
part.innerLines.push(innerLine);
|
||||
part.innerLines.paths.push(innerLine);
|
||||
}
|
||||
else {
|
||||
break;
|
||||
|
@ -1,7 +1,7 @@
|
||||
import Paths from '../paths.js';
|
||||
import Shape from 'Doodle3D/clipper-js';
|
||||
|
||||
export default function getFillTemplate(bounds, size, even, uneven) {
|
||||
var paths = new Paths([], false);
|
||||
var shape = new Shape([], false);
|
||||
|
||||
var left = Math.floor(bounds.left / size) * size;
|
||||
var right = Math.ceil(bounds.right / size) * size;
|
||||
@ -12,7 +12,7 @@ export default function getFillTemplate(bounds, size, even, uneven) {
|
||||
|
||||
if (even) {
|
||||
for (var y = top; y <= bottom + width; y += size) {
|
||||
paths.push([
|
||||
shape.paths.push([
|
||||
{X: left, Y: y},
|
||||
{X: right, Y: y - width}
|
||||
]);
|
||||
@ -20,12 +20,12 @@ export default function getFillTemplate(bounds, size, even, uneven) {
|
||||
}
|
||||
if (uneven) {
|
||||
for (var y = top - width; y <= bottom; y += size) {
|
||||
paths.push([
|
||||
shape.paths.push([
|
||||
{X: left, Y: y},
|
||||
{X: right, Y: y + width}
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
return paths;
|
||||
return shape;
|
||||
}
|
||||
|
@ -1,10 +1,10 @@
|
||||
import THREE from 'three.js';
|
||||
import Paths from '../paths.js';
|
||||
import Shape from 'Doodle3D/clipper-js';
|
||||
|
||||
export default function intersectionsToShapes(layerIntersectionIndexes, layerIntersectionPoints, lines, settings) {
|
||||
console.log("generating slices");
|
||||
|
||||
var shapes = [];
|
||||
var layers = [];
|
||||
|
||||
for (var layer = 1; layer < layerIntersectionIndexes.length; layer ++) {
|
||||
var intersectionIndexes = layerIntersectionIndexes[layer];
|
||||
@ -14,7 +14,8 @@ export default function intersectionsToShapes(layerIntersectionIndexes, layerInt
|
||||
continue;
|
||||
}
|
||||
|
||||
var shapeParts = [];
|
||||
var closedShapes = [];
|
||||
var openShapes = [];
|
||||
for (var i = 0; i < intersectionIndexes.length; i ++) {
|
||||
var index = intersectionIndexes[i];
|
||||
|
||||
@ -31,7 +32,7 @@ export default function intersectionsToShapes(layerIntersectionIndexes, layerInt
|
||||
while (index !== -1) {
|
||||
var intersection = intersectionPoints[index];
|
||||
// uppercase X and Y because clipper vector
|
||||
shape.push({X: intersection.x, Y: intersection.y});
|
||||
shape.push(intersection);
|
||||
|
||||
delete intersectionPoints[index];
|
||||
|
||||
@ -94,7 +95,7 @@ export default function intersectionsToShapes(layerIntersectionIndexes, layerInt
|
||||
while (index !== -1) {
|
||||
if (firstPoints.indexOf(index) === -1) {
|
||||
var intersection = intersectionPoints[index];
|
||||
shape.unshift({X: intersection.x, Y: intersection.y});
|
||||
shape.unshift(intersection);
|
||||
|
||||
delete intersectionPoints[index];
|
||||
}
|
||||
@ -114,14 +115,16 @@ export default function intersectionsToShapes(layerIntersectionIndexes, layerInt
|
||||
}
|
||||
}
|
||||
|
||||
var part = new Paths([shape], closed).clean(0.01);
|
||||
if (part.length > 0) {
|
||||
shapeParts.push(part);
|
||||
if (closed) {
|
||||
closedShapes.push(shape);
|
||||
}
|
||||
else {
|
||||
openShapes.push(shape);
|
||||
}
|
||||
}
|
||||
|
||||
shapes.push(shapeParts);
|
||||
layers.push({ closedShapes, openShapes });
|
||||
}
|
||||
|
||||
return shapes;
|
||||
return layers;
|
||||
}
|
||||
|
@ -1,4 +1,10 @@
|
||||
import THREE from 'three.js';
|
||||
const offsetOptions = {
|
||||
jointType: 'jtSquare',
|
||||
endType: 'etClosedPolygon',
|
||||
miterLimit: 2.0,
|
||||
roundPrecision: 0.25
|
||||
};
|
||||
|
||||
export default function optimizePaths(slices, settings) {
|
||||
console.log("opimize paths");
|
||||
@ -14,15 +20,15 @@ export default function optimizePaths(slices, settings) {
|
||||
var slice = slices[layer];
|
||||
|
||||
if (layer === 0) {
|
||||
slice.brim = slice.getOutline().offset(brimOffset);
|
||||
slice.brim = slice.getOutline().offset(brimOffset, offsetOptions);
|
||||
}
|
||||
|
||||
start = slice.optimizePaths(start);
|
||||
// start = slice.optimizePaths(start);
|
||||
|
||||
for (var i = 0; i < slice.parts.length; i ++) {
|
||||
var part = slice.parts[i];
|
||||
|
||||
if (part.intersect.closed) {
|
||||
if (part.shape.closed) {
|
||||
part.outerLine.scaleDown(scale);
|
||||
for (var j = 0; j < part.innerLines.length; j ++) {
|
||||
var innerLine = part.innerLines[j];
|
||||
|
@ -1,65 +1,37 @@
|
||||
import Shape from 'Doodle3D/clipper-js';
|
||||
import Slice from '../slice.js';
|
||||
|
||||
export default function shapesToSlices(shapes, settings) {
|
||||
var slices = [];
|
||||
const sliceLayers = [];
|
||||
|
||||
for (var layer = 0; layer < shapes.length; layer ++) {
|
||||
var shapeParts = shapes[layer];
|
||||
var { closedShapes, openShapes } = shapes[layer];
|
||||
|
||||
closedShapes = new Shape(closedShapes, true, true)
|
||||
.clean(0.01)
|
||||
.fixOrientation()
|
||||
.removeOverlap()
|
||||
.seperateShapes();
|
||||
|
||||
openShapes = new Shape(openShapes, false, true)
|
||||
.clean(0.01);
|
||||
|
||||
var slice = new Slice();
|
||||
|
||||
var holes = [];
|
||||
var outlines = [];
|
||||
for (var i = 0; i < closedShapes.length; i ++) {
|
||||
var closedShape = closedShapes[i];
|
||||
slice.add(closedShape);
|
||||
|
||||
for (var i = 0; i < shapeParts.length; i ++) {
|
||||
var shape = shapeParts[i];
|
||||
|
||||
if (!shape.closed) {
|
||||
slice.add(shape);
|
||||
}
|
||||
else if (shape.isHole()) {
|
||||
holes.push(shape);
|
||||
}
|
||||
else {
|
||||
slice.add(shape);
|
||||
outlines.push(shape);
|
||||
}
|
||||
// if (openShapes.path.length > 0) {
|
||||
// openShapes = openShapes.difference(closedShape);
|
||||
// }
|
||||
}
|
||||
if (openShapes.paths.length > 0) {
|
||||
slice.add(openShapes);
|
||||
}
|
||||
|
||||
outlines.sort((a, b) => {
|
||||
return a.boundSize() - b.boundSize();
|
||||
});
|
||||
|
||||
if (holes.length > outlines.length) {
|
||||
[holes, outlines] = [outlines, holes];
|
||||
}
|
||||
else if (holes.length === outlines.length) {
|
||||
holes.sort((a, b) => {
|
||||
return a.boundSize() - b.boundSize();
|
||||
});
|
||||
|
||||
if (holes[0].boundSize > outlines[0].boundSize()) {
|
||||
[holes, outlines] = [outlines, holes];
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; i < holes.length; i ++) {
|
||||
var hole = holes[i];
|
||||
|
||||
for (var j = 0; j < outlines.length; j ++) {
|
||||
var outline = outlines[j];
|
||||
|
||||
if (outline.pointCollision(hole[0][0])) {
|
||||
outline.join(hole);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
slice.removeSelfIntersect();
|
||||
|
||||
slices.push(slice);
|
||||
sliceLayers.push(slice);
|
||||
}
|
||||
|
||||
return slices;
|
||||
return sliceLayers;
|
||||
}
|
||||
|
@ -3,15 +3,14 @@ import GCode from '../gcode.js';
|
||||
export default function slicesToGCode(slices, settings) {
|
||||
var gcode = new GCode().setSettings(settings);
|
||||
|
||||
function pathToGCode (path, retract, unRetract, type) {
|
||||
function pathToGCode (shape, retract, unRetract, type) {
|
||||
for (var i = 0; i < shape.paths.length; i ++) {
|
||||
var line = shape.paths[i];
|
||||
|
||||
for (var i = 0; i < path.length; i ++) {
|
||||
var shape = path[i];
|
||||
|
||||
var length = path.closed ? (shape.length + 1) : shape.length;
|
||||
var length = shape.closed ? (line.length + 1) : line.length;
|
||||
|
||||
for (var j = 0; j < length; j ++) {
|
||||
var point = shape[j % shape.length];
|
||||
var point = line[j % line.length];
|
||||
|
||||
if (j === 0) {
|
||||
// TODO
|
||||
@ -48,7 +47,7 @@ export default function slicesToGCode(slices, settings) {
|
||||
for (var i = 0; i < slice.parts.length; i ++) {
|
||||
var part = slice.parts[i];
|
||||
|
||||
if (part.intersect.closed) {
|
||||
if (part.shape.closed) {
|
||||
pathToGCode(part.outerLine, false, true, "outerLine");
|
||||
|
||||
for (var j = 0; j < part.innerLines.length; j ++) {
|
||||
@ -60,7 +59,7 @@ export default function slicesToGCode(slices, settings) {
|
||||
}
|
||||
else {
|
||||
var retract = !(slice.parts.length === 1 && slice.support === undefined);
|
||||
pathToGCode(part.intersect, retract, retract, "outerLine");
|
||||
pathToGCode(part.shape, retract, retract, "outerLine");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -67,15 +67,18 @@ export default class extends EventDispatcher {
|
||||
this.progress.createdLines = true;
|
||||
this._updateProgress(settings);
|
||||
|
||||
var {layerIntersectionIndexes, layerIntersectionPoints} = calculateLayersIntersections(lines, settings);
|
||||
const {
|
||||
layerIntersectionIndexes,
|
||||
layerIntersectionPoints
|
||||
} = calculateLayersIntersections(lines, settings);
|
||||
this.progress.calculatedLayerIntersections = true;
|
||||
this._updateProgress(settings);
|
||||
|
||||
var shapes = intersectionsToShapes(layerIntersectionIndexes, layerIntersectionPoints, lines, settings);
|
||||
const shapes = intersectionsToShapes(layerIntersectionIndexes, layerIntersectionPoints, lines, settings);
|
||||
this.progress.sliced = true;
|
||||
this._updateProgress(settings);
|
||||
|
||||
var slices = shapesToSlices(shapes, settings);
|
||||
const slices = shapesToSlices(shapes, settings);
|
||||
this.progress.generatedSlices = true;
|
||||
this._updateProgress(settings);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user