replace tabs with spaces

This commit is contained in:
casperlamboo 2017-05-13 14:48:48 +02:00
parent b7b2eff61b
commit 229f194def
13 changed files with 478 additions and 478 deletions

View File

@ -7,8 +7,8 @@ import THREE from 'three.js';
import * as SLICER from 'doodle3d-slicer'; import * as SLICER from 'doodle3d-slicer';
const settings = new SLICER.Settings({ const settings = new SLICER.Settings({
...SLICER.printerSettings['ultimaker2go'], ...SLICER.printerSettings['ultimaker2go'],
...SLICER.userSettings ...SLICER.userSettings
}); });
const geometry = new THREE.TorusGeometry(20, 10, 30, 30); const geometry = new THREE.TorusGeometry(20, 10, 30, 30);
@ -17,6 +17,6 @@ const slicer = new SLICER.Slicer();
slicer.setGeometry(geometry); slicer.setGeometry(geometry);
slicer.slice(settings, false).then(gcode => { slicer.slice(settings, false).then(gcode => {
document.getElementById('gcode').innerHTML = gcode.replace(/(?:\r\n|\r|\n)/g, '<br />'); document.getElementById('gcode').innerHTML = gcode.replace(/(?:\r\n|\r|\n)/g, '<br />');
}); });
``` ```

View File

@ -1,45 +1,45 @@
import React from 'react'; import React from 'react';
export default class SlicerViewer extends React.Component { export default class SlicerViewer extends React.Component {
state = { state = {
slice: 0 slice: 0
}; };
changeSlider = (event) => { changeSlider = (event) => {
this.setState({ this.setState({
...this.state, ...this.state,
slice: parseInt(event.target.value) slice: parseInt(event.target.value)
}); });
}; };
render() { render() {
const { slice } = this.state; const { slice } = this.state;
const { layerIntersectionPoints, settings, layerShapes } = this.props; const { layerIntersectionPoints, settings, layerShapes } = this.props;
const numLayers = settings.dimensionsZ / settings.layerHeight; const numLayers = settings.dimensionsZ / settings.layerHeight;
const intersectionPoints = layerIntersectionPoints[slice + 1]; const intersectionPoints = layerIntersectionPoints[slice + 1];
const shape = layerShapes[slice]; const shape = layerShapes[slice];
return ( return (
<div> <div>
<svg viewBox={`-20 -20 ${settings.dimensionsX + 40} ${settings.dimensionsX + 40}`}> <svg viewBox={`-20 -20 ${settings.dimensionsX + 40} ${settings.dimensionsX + 40}`}>
<rect <rect
width={settings.dimensionsX} width={settings.dimensionsX}
height={settings.dimensionsY} height={settings.dimensionsY}
fill="lightGrey" fill="lightGrey"
/> />
{intersectionPoints.map(({ x, y }, i) => <circle key={i} cx={x} cy={y} r="0.3"/>)} {intersectionPoints.map(({ x, y }, i) => <circle key={i} cx={x} cy={y} r="0.3"/>)}
{shape && shape.closedShapes.map((closedShape, i) => ( {shape && shape.closedShapes.map((closedShape, i) => (
<polygon <polygon
key={i} key={i}
points={closedShape.map(({ x, y }) => `${x} ${y}`).join(' ')} points={closedShape.map(({ x, y }) => `${x} ${y}`).join(' ')}
fill="rgba(255, 0, 0, 0.5)" fill="rgba(255, 0, 0, 0.5)"
/> />
))} ))}
</svg> </svg>
<input onChange={this.changeSlider} value={slice} type="range" min="0" max={numLayers} /> <input onChange={this.changeSlider} value={slice} type="range" min="0" max={numLayers} />
</div> </div>
); );
} }
} }

View File

@ -7,27 +7,27 @@ import generateRawData from './generateRawData.js';
import SlicerViewer from './SlicerViewer.js'; import SlicerViewer from './SlicerViewer.js';
const settings = new SLICER.Settings({ const settings = new SLICER.Settings({
...SLICER.printerSettings['ultimaker2go'], ...SLICER.printerSettings['ultimaker2go'],
...SLICER.userSettings ...SLICER.userSettings
}); });
const stlLoader = new THREE.STLLoader(); const stlLoader = new THREE.STLLoader();
stlLoader.load('stl/Airplane.stl', (geometry) => { stlLoader.load('stl/Airplane.stl', (geometry) => {
geometry.applyMatrix(new THREE.Matrix4().makeRotationX(Math.PI / -2)); geometry.applyMatrix(new THREE.Matrix4().makeRotationX(Math.PI / -2));
geometry.applyMatrix(new THREE.Matrix4().setPosition(new THREE.Vector3(50, -0.1, 50))); geometry.applyMatrix(new THREE.Matrix4().setPosition(new THREE.Vector3(50, -0.1, 50)));
// geometry.applyMatrix(new THREE.Matrix4().scale(0.8)); // geometry.applyMatrix(new THREE.Matrix4().scale(0.8));
geometry.mergeVertices(); geometry.mergeVertices();
geometry.computeFaceNormals(); geometry.computeFaceNormals();
const rawData = generateRawData(geometry, settings); const rawData = generateRawData(geometry, settings);
render(<SlicerViewer render(<SlicerViewer
layerIntersectionPoints={rawData.layerIntersectionPoints} layerIntersectionPoints={rawData.layerIntersectionPoints}
layerShapes={rawData.layerShapes} layerShapes={rawData.layerShapes}
slices={rawData.slices} slices={rawData.slices}
settings={settings.config} settings={settings.config}
/>, document.getElementById('container')); />, document.getElementById('container'));
}); });
// const geometry = new THREE.TorusGeometry(20, 10, 30, 30).clone(); // const geometry = new THREE.TorusGeometry(20, 10, 30, 30).clone();
@ -38,8 +38,8 @@ stlLoader.load('stl/Airplane.stl', (geometry) => {
// const rawData = generateRawData(geometry, settings); // const rawData = generateRawData(geometry, settings);
// //
// render(<SlicerViewer // render(<SlicerViewer
// layerIntersectionPoints={rawData.layerIntersectionPoints} // layerIntersectionPoints={rawData.layerIntersectionPoints}
// layerShapes={rawData.layerShapes} // layerShapes={rawData.layerShapes}
// slices={rawData.slices} // slices={rawData.slices}
// settings={settings.config} // settings={settings.config}
// />, document.getElementById('container')); // />, document.getElementById('container'));

View File

@ -12,43 +12,43 @@ import applyPrecision from 'src/sliceActions/applyPrecision.js';
import removePrecision from 'src/sliceActions/removePrecision.js'; import removePrecision from 'src/sliceActions/removePrecision.js';
export default function generateRawData(geometry, settings) { export default function generateRawData(geometry, settings) {
const rawData = {}; const rawData = {};
const lines = createLines(geometry, settings); const lines = createLines(geometry, settings);
const { const {
layerIntersectionIndexes, layerIntersectionIndexes,
layerIntersectionPoints layerIntersectionPoints
} = calculateLayersIntersections(lines, settings); } = calculateLayersIntersections(lines, settings);
rawData.layerIntersectionPoints = layerIntersectionPoints rawData.layerIntersectionPoints = layerIntersectionPoints
.map(intersectionPoints => intersectionPoints.map(intersectionPoint => intersectionPoint.clone())); .map(intersectionPoints => intersectionPoints.map(intersectionPoint => intersectionPoint.clone()));
const layerShapes = intersectionsToShapes(layerIntersectionIndexes, layerIntersectionPoints, lines, settings); const layerShapes = intersectionsToShapes(layerIntersectionIndexes, layerIntersectionPoints, lines, settings);
rawData.layerShapes = layerShapes rawData.layerShapes = layerShapes
.map(({ closedShapes, openShapes }) => ({ .map(({ closedShapes, openShapes }) => ({
closedShapes: closedShapes.map(closedShape => closedShape.map(vector => vector.clone())), closedShapes: closedShapes.map(closedShape => closedShape.map(vector => vector.clone())),
openShapes: openShapes.map(openShape => openShape.map(vector => vector.clone())) openShapes: openShapes.map(openShape => openShape.map(vector => vector.clone()))
})); }));
applyPrecision(layerShapes); applyPrecision(layerShapes);
const slices = shapesToSlices(layerShapes, settings); const slices = shapesToSlices(layerShapes, settings);
generateInnerLines(slices, settings); generateInnerLines(slices, settings);
generateInfills(slices, settings); generateInfills(slices, settings);
generateSupport(slices, settings); generateSupport(slices, settings);
addBrim(slices, settings); addBrim(slices, settings);
optimizePaths(slices, settings); optimizePaths(slices, settings);
removePrecision(slices); removePrecision(slices);
rawData.slices = slices; rawData.slices = slices;
const gcode = slicesToGCode(slices, settings); const gcode = slicesToGCode(slices, settings);
rawData.gcode = gcode; rawData.gcode = gcode;
return rawData; return rawData;
} }

View File

@ -1,29 +1,29 @@
<!DOCTYPE> <!DOCTYPE>
<html> <html>
<head> <head>
<title>Doodle3D Slicer</title> <title>Doodle3D Slicer</title>
<style> <style>
#gcode { #gcode {
font-family: monospace; font-family: monospace;
} }
</style> </style>
<script type="text/javascript" src="../jspm_packages/system.js"></script> <script type="text/javascript" src="../jspm_packages/system.js"></script>
<script type="text/javascript" src="../jspm.config.js"></script> <script type="text/javascript" src="../jspm.config.js"></script>
<link href="main.css" rel="stylesheet"/> <link href="main.css" rel="stylesheet"/>
<script type="text/javascript"> <script type="text/javascript">
System.import('example/app.js'); System.import('example/app.js');
</script> </script>
</head> </head>
<body> <body>
<div id="container"></div> <div id="container"></div>
</body> </body>
</html> </html>

View File

@ -1,21 +1,21 @@
* { * {
margin: 0; margin: 0;
padding: 0; padding: 0;
} }
#container { #container {
position: relative; position: relative;
} }
#container, svg { #container, svg {
width: 100%; width: 100%;
height: 100%; height: 100%;
} }
svg, input { svg, input {
position: absolute; position: absolute;
} }
input { input {
width: 100%; width: 100%;
} }

View File

@ -10,178 +10,178 @@ const POSITION_Y = 'Y';
const POSITION_Z = 'Z'; const POSITION_Z = 'Z';
export default class { export default class {
constructor(settings) { constructor(settings) {
this.gcode = ''; this.gcode = '';
this.current = {}; this.current = {};
this.extruder = 0.0; this.extruder = 0.0;
this.bottom = true; this.bottom = true;
this.isRetracted = false; this.isRetracted = false;
this.isFanOn = false; this.isFanOn = false;
this._nozzlePosition = new THREE.Vector2(0, 0); this._nozzlePosition = new THREE.Vector2(0, 0);
if (settings !== undefined) { if (settings !== undefined) {
this.setSettings(settings); this.setSettings(settings);
} }
} }
_addGCode(command) { _addGCode(command) {
let str = ''; let str = '';
let first = true; let first = true;
for (const action in command) { for (const action in command) {
const value = command[action]; const value = command[action];
const currentValue = this.current[action]; const currentValue = this.current[action];
if (first) { if (first) {
str = action + value; str = action + value;
first = false; first = false;
} else if (currentValue !== value) { } else if (currentValue !== value) {
str += ` ${action}${value}`; str += ` ${action}${value}`;
this.current[action] = value; this.current[action] = value;
} }
} }
this.gcode += `${str}\n`; this.gcode += `${str}\n`;
} }
setSettings(settings) { setSettings(settings) {
this.settings = settings; this.settings = settings;
return this; return this;
} }
turnFanOn(fanSpeed) { turnFanOn(fanSpeed) {
this.isFanOn = true; this.isFanOn = true;
const gcode = { [M_COMMAND]: 106 } const gcode = { [M_COMMAND]: 106 }
if (fanSpeed !== undefined) gcode[FAN_SPEED] = fanSpeed; if (fanSpeed !== undefined) gcode[FAN_SPEED] = fanSpeed;
this._addGCode(gcode); this._addGCode(gcode);
return this; return this;
} }
turnFanOff() { turnFanOff() {
this.isFanOn = false; this.isFanOn = false;
this._addGCode({ [M_COMMAND]: 107 }); this._addGCode({ [M_COMMAND]: 107 });
return this; return this;
} }
moveTo(x, y, layer) { moveTo(x, y, layer) {
const { const {
layerHeight, layerHeight,
travelSpeed travelSpeed
} = this.settings.config; } = this.settings.config;
const z = (layer + 1) * layerHeight; const z = (layer + 1) * layerHeight;
const speed = travelSpeed * 60; const speed = travelSpeed * 60;
this._addGCode({ this._addGCode({
[G_COMMAND]: 0, [G_COMMAND]: 0,
[POSITION_X]: x.toFixed(3), [POSITION_X]: x.toFixed(3),
[POSITION_Y]: y.toFixed(3), [POSITION_Y]: y.toFixed(3),
[POSITION_Z]: z.toFixed(3), [POSITION_Z]: z.toFixed(3),
[SPEED]: speed.toFixed(3) [SPEED]: speed.toFixed(3)
}); });
this._nozzlePosition.set(x, y); this._nozzlePosition.set(x, y);
return this; return this;
} }
lineTo(x, y, layer, type) { lineTo(x, y, layer, type) {
const newNozzlePosition = new THREE.Vector2(x, y); const newNozzlePosition = new THREE.Vector2(x, y);
const { const {
layerHeight, layerHeight,
nozzleDiameter, nozzleDiameter,
filamentThickness, filamentThickness,
travelSpeed travelSpeed
} = this.settings.config; } = this.settings.config;
const profile = this.settings.config[(this.bottom ? 'bottom' : type)]; const profile = this.settings.config[(this.bottom ? 'bottom' : type)];
let { let {
speed, speed,
flowRate flowRate
} = profile; } = profile;
speed *= 60; speed *= 60;
const z = (layer + 1) * layerHeight; const z = (layer + 1) * layerHeight;
const lineLength = this._nozzlePosition.distanceTo(newNozzlePosition); const lineLength = this._nozzlePosition.distanceTo(newNozzlePosition);
const filamentSurfaceArea = Math.pow((filamentThickness / 2), 2) * Math.PI; const filamentSurfaceArea = Math.pow((filamentThickness / 2), 2) * Math.PI;
this.extruder += lineLength * nozzleDiameter * layerHeight / filamentSurfaceArea * flowRate; this.extruder += lineLength * nozzleDiameter * layerHeight / filamentSurfaceArea * flowRate;
this._addGCode({ this._addGCode({
[G_COMMAND]: 1, [G_COMMAND]: 1,
[POSITION_X]: x.toFixed(3), [POSITION_X]: x.toFixed(3),
[POSITION_Y]: y.toFixed(3), [POSITION_Y]: y.toFixed(3),
[POSITION_Z]: z.toFixed(3), [POSITION_Z]: z.toFixed(3),
[SPEED]: speed.toFixed(3), [SPEED]: speed.toFixed(3),
[EXTRUDER]: this.extruder.toFixed(3) [EXTRUDER]: this.extruder.toFixed(3)
}); });
this._nozzlePosition.copy(newNozzlePosition); this._nozzlePosition.copy(newNozzlePosition);
return this; return this;
} }
unRetract() { unRetract() {
const { const {
retractionEnabled, retractionEnabled,
retractionMinDistance, retractionMinDistance,
retractionSpeed retractionSpeed
} = this.settings.config; } = this.settings.config;
if (this.isRetracted && retractionEnabled) { if (this.isRetracted && retractionEnabled) {
this.isRetracted = false; this.isRetracted = false;
const speed = retractionSpeed * 60; const speed = retractionSpeed * 60;
if (this.extruder > retractionMinDistance) { if (this.extruder > retractionMinDistance) {
this._addGCode({ this._addGCode({
[G_COMMAND]: 0, [G_COMMAND]: 0,
[EXTRUDER]: this.extruder.toFixed(3), [EXTRUDER]: this.extruder.toFixed(3),
[SPEED]: speed.toFixed(3) [SPEED]: speed.toFixed(3)
}); });
} }
} }
return this; return this;
} }
retract() { retract() {
const { const {
retractionAmount, retractionAmount,
retractionEnabled, retractionEnabled,
retractionMinDistance, retractionMinDistance,
retractionSpeed retractionSpeed
} = this.settings.config; } = this.settings.config;
if (!this.isRetracted && retractionEnabled) { if (!this.isRetracted && retractionEnabled) {
this.isRetracted = true; this.isRetracted = true;
const speed = retractionSpeed * 60; const speed = retractionSpeed * 60;
if (this.extruder > retractionMinDistance && retractionEnabled) { if (this.extruder > retractionMinDistance && retractionEnabled) {
this._addGCode({ this._addGCode({
[G_COMMAND]: 0, [G_COMMAND]: 0,
[EXTRUDER]: (this.extruder - retractionAmount).toFixed(3), [EXTRUDER]: (this.extruder - retractionAmount).toFixed(3),
[SPEED]: speed.toFixed(3) [SPEED]: speed.toFixed(3)
}); });
} }
} }
return this; return this;
} }
getGCode() { getGCode() {
return this.settings.startCode() + this.gcode + this.settings.endCode(); return this.settings.startCode() + this.gcode + this.settings.endCode();
} }
} }

View File

@ -1,53 +1,53 @@
export default class { export default class {
constructor(config = {}) { constructor(config = {}) {
this.config = config; this.config = config;
} }
updateConfig(config) { updateConfig(config) {
this.config = { ...this.config, ...config }; this.config = { ...this.config, ...config };
return this; return this;
} }
startCode() { startCode() {
const { startCode } = this.config; const { startCode } = this.config;
const gcode = this._subsituteVariables(startCode); const gcode = this._subsituteVariables(startCode);
return gcode; return gcode;
} }
endCode() { endCode() {
const { endCode } = this.config; const { endCode } = this.config;
const gcode = this._subsituteVariables(endCode); const gcode = this._subsituteVariables(endCode);
return gcode; return gcode;
} }
_subsituteVariables(gcode) { _subsituteVariables(gcode) {
let { let {
temperature, temperature,
bedTemperature, bedTemperature,
heatTemperature, heatTemperature,
heatBedTemperature, heatBedTemperature,
travelSpeed, travelSpeed,
printerType, printerType,
heatedbed heatedbed
} = this.config; } = this.config;
travelSpeed *= 60; travelSpeed *= 60;
switch (printerType) { switch (printerType) {
case 'makerbot_replicator2': printerType = 'r2'; break; case 'makerbot_replicator2': printerType = 'r2'; break;
case 'makerbot_replicator2x': printerType = 'r2x'; break; case 'makerbot_replicator2x': printerType = 'r2x'; break;
case 'makerbot_thingomatic': printerType = 't6'; break; case 'makerbot_thingomatic': printerType = 't6'; break;
case 'makerbot_generic': printerType = 'r2'; break; case 'makerbot_generic': printerType = 'r2'; break;
case '_3Dison_plus': printerType = 'r2'; break; case '_3Dison_plus': printerType = 'r2'; break;
} }
const heatedBedReplacement = heatedbed ? '' : ';'; const heatedBedReplacement = heatedbed ? '' : ';';
gcode = gcode.replace(/{printingTemp}/gi, temperature); gcode = gcode.replace(/{printingTemp}/gi, temperature);
gcode = gcode.replace(/{printingBedTemp}/gi, bedTemperature); gcode = gcode.replace(/{printingBedTemp}/gi, bedTemperature);
gcode = gcode.replace(/{preheatTemp}/gi, heatTemperature); gcode = gcode.replace(/{preheatTemp}/gi, heatTemperature);
gcode = gcode.replace(/{preheatBedTemp}/gi, heatBedTemperature); gcode = gcode.replace(/{preheatBedTemp}/gi, heatBedTemperature);
gcode = gcode.replace(/{printerType}/gi, printerType); gcode = gcode.replace(/{printerType}/gi, printerType);
gcode = gcode.replace(/{travelSpeed}/gi, travelSpeed); gcode = gcode.replace(/{travelSpeed}/gi, travelSpeed);
gcode = gcode.replace(/{if heatedBed}/gi, heatedBedReplacement); gcode = gcode.replace(/{if heatedBed}/gi, heatedBedReplacement);
return gcode; return gcode;
} }
} }

View File

@ -1,31 +1,31 @@
import Shape from 'Doodle3D/clipper-js'; import Shape from 'Doodle3D/clipper-js';
export default class { export default class {
constructor() { constructor() {
this.parts = []; this.parts = [];
} }
getOutline() { getOutline() {
const outLines = new Shape([], true); const outLines = new Shape([], true);
for (let i = 0; i < this.parts.length; i ++) { for (let i = 0; i < this.parts.length; i ++) {
const part = this.parts[i]; const part = this.parts[i];
if (part.shape.closed) { if (part.shape.closed) {
outLines.join(this.parts[i].outerLine); outLines.join(this.parts[i].outerLine);
} }
} }
return outLines; return outLines;
} }
add(shape) { add(shape) {
const part = { shape }; const part = { shape };
if (shape.closed) { if (shape.closed) {
part.innerLines = []; part.innerLines = [];
part.outerLine = new Shape([], true); part.outerLine = new Shape([], true);
part.fill = new Shape([], false); part.fill = new Shape([], false);
} }
this.parts.push(part); this.parts.push(part);
} }
} }

View File

@ -3,60 +3,60 @@ import slice from './sliceActions/slice.js';
import SlicerWorker from './slicerWorker.js!worker'; import SlicerWorker from './slicerWorker.js!worker';
export default class { export default class {
setMesh(mesh) { setMesh(mesh) {
mesh.updateMatrix(); mesh.updateMatrix();
this.setGeometry(mesh.geometry, mesh.matrix); this.setGeometry(mesh.geometry, mesh.matrix);
return this; return this;
} }
setGeometry(geometry, matrix) { setGeometry(geometry, matrix) {
if (geometry.type === 'BufferGeometry') { if (geometry.type === 'BufferGeometry') {
geometry = new THREE.Geometry().fromBufferGeometry(geometry); geometry = new THREE.Geometry().fromBufferGeometry(geometry);
} else if (geometry.type === 'Geometry') { } else if (geometry.type === 'Geometry') {
geometry = geometry.clone(); geometry = geometry.clone();
} else { } else {
throw new Error('Geometry is not an instance of BufferGeometry or Geometry'); throw new Error('Geometry is not an instance of BufferGeometry or Geometry');
} }
if (matrix) { if (matrix) {
geometry.applyMatrix(matrix); geometry.applyMatrix(matrix);
} }
geometry.mergeVertices(); geometry.mergeVertices();
geometry.computeFaceNormals(); geometry.computeFaceNormals();
this.geometry = geometry; this.geometry = geometry;
return this; return this;
} }
sliceSync(settings) { sliceSync(settings) {
return slice(this.geometry, settings); return slice(this.geometry, settings);
} }
slice(settings) { slice(settings) {
const slicerWorker = new SlicerWorker(); const slicerWorker = new SlicerWorker();
const geometry = this.geometry.toJSON(); const geometry = this.geometry.toJSON();
const { config } = settings; const { config } = settings;
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
slicerWorker.onerror = reject; slicerWorker.onerror = reject;
slicerWorker.addEventListener('message', (event) => { slicerWorker.addEventListener('message', (event) => {
const { message, data } = event.data; const { message, data } = event.data;
switch (message) { switch (message) {
case 'SLICE': { case 'SLICE': {
slicerWorker.terminate(); slicerWorker.terminate();
resolve(data.gcode); resolve(data.gcode);
break; break;
} }
} }
}); });
slicerWorker.postMessage({ slicerWorker.postMessage({
message: 'SLICE', message: 'SLICE',
data: { geometry, config } data: { geometry, config }
}); });
}); });
} }
} }

View File

@ -1,38 +1,38 @@
{ {
"ultimaker": { "ultimaker": {
"dimensionsX": 200, "dimensionsX": 200,
"dimensionsY": 200, "dimensionsY": 200,
"dimensionsZ": 200, "dimensionsZ": 200,
"endCode": "M107 ;fan off\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+0.5 E-5 X-20 Y-20 F9000 ;move Z up a bit and retract filament even more\nG28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\nM84 ;disable axes / steppers\nG90 ;absolute positioning\nM104 S{preheatTemp}\n{if heatedBed}M140 S{preheatBedTemp}\nM117 Done ;display message (20 characters to clear whole screen)\n", "endCode": "M107 ;fan off\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+0.5 E-5 X-20 Y-20 F9000 ;move Z up a bit and retract filament even more\nG28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\nM84 ;disable axes / steppers\nG90 ;absolute positioning\nM104 S{preheatTemp}\n{if heatedBed}M140 S{preheatBedTemp}\nM117 Done ;display message (20 characters to clear whole screen)\n",
"filamentThickness": 2.85, "filamentThickness": 2.85,
"heatedBed": false, "heatedBed": false,
"heatupEnabled": true, "heatupEnabled": true,
"nozzleDiameter": 0.4, "nozzleDiameter": 0.4,
"startCode": ";Generated with Doodle3D (default)\nM109 S{printingTemp} ;set target temperature \n{if heatedBed}M190 S{printingBedTemp} ;set target bed temperature\nG21 ;metric values\nG91 ;relative positioning\nM107 ;start with the fan off\nG28 X0 Y0 ;move X/Y to min endstops\nG28 Z0 ;move Z to min endstops\nG1 Z15 F9000 ;move the platform down 15mm\nG92 E0 ;zero the extruded length\nG1 F200 E10 ;extrude 10mm of feed stock\nG92 E0 ;zero the extruded length again\nG92 E0 ;zero the extruded length again\nG1 F9000\nG90 ;absolute positioning\nM117 Printing Doodle... ;display message (20 characters to clear whole screen)\n", "startCode": ";Generated with Doodle3D (default)\nM109 S{printingTemp} ;set target temperature \n{if heatedBed}M190 S{printingBedTemp} ;set target bed temperature\nG21 ;metric values\nG91 ;relative positioning\nM107 ;start with the fan off\nG28 X0 Y0 ;move X/Y to min endstops\nG28 Z0 ;move Z to min endstops\nG1 Z15 F9000 ;move the platform down 15mm\nG92 E0 ;zero the extruded length\nG1 F200 E10 ;extrude 10mm of feed stock\nG92 E0 ;zero the extruded length again\nG92 E0 ;zero the extruded length again\nG1 F9000\nG90 ;absolute positioning\nM117 Printing Doodle... ;display message (20 characters to clear whole screen)\n",
"type": "ultimaker" "type": "ultimaker"
}, },
"ultimaker2": { "ultimaker2": {
"dimensionsX": 223, "dimensionsX": 223,
"dimensionsY": 223, "dimensionsY": 223,
"dimensionsZ": 205, "dimensionsZ": 205,
"endCode": "M107 ;fan off\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+5.5 E-5 X-20 Y-20 F9000 ;move Z up a bit and retract filament even more\nG28 ;home the printer\nM84 ;disable axes / steppers\nG90 ;absolute positioning\nM104 S{preheatTemp}\n{if heatedBed}M140 S{preheatBedTemp}\nM117 Done ;display message (20 characters to clear whole screen)\n", "endCode": "M107 ;fan off\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+5.5 E-5 X-20 Y-20 F9000 ;move Z up a bit and retract filament even more\nG28 ;home the printer\nM84 ;disable axes / steppers\nG90 ;absolute positioning\nM104 S{preheatTemp}\n{if heatedBed}M140 S{preheatBedTemp}\nM117 Done ;display message (20 characters to clear whole screen)\n",
"filamentThickness": 2.85, "filamentThickness": 2.85,
"heatedBed": true, "heatedBed": true,
"heatupEnabled": true, "heatupEnabled": true,
"nozzleDiameter": 0.4, "nozzleDiameter": 0.4,
"startCode": ";Generated with Doodle3D (ultimaker2)\nM109 S{printingTemp} ;set target temperature \n{if heatedBed}M190 S{printingBedTemp} ;set target bed temperature\nG21 ;metric values\nG90 ;absolute positioning\nM107 ;start with the fan off\nG28 ; home to endstops\nG1 Z15 F9000 ;move the platform down 15mm\nG92 E0 ;zero the extruded length\nG1 F200 E10 ;extrude 10mm of feed stock\nG92 E0 ;zero the extruded length again\nG0 X0 Y0 F{travelSpeed} ;home position is not X0 Y0\nM117 Printing Doodle... ;display message (20 characters to clear whole screen)\n", "startCode": ";Generated with Doodle3D (ultimaker2)\nM109 S{printingTemp} ;set target temperature \n{if heatedBed}M190 S{printingBedTemp} ;set target bed temperature\nG21 ;metric values\nG90 ;absolute positioning\nM107 ;start with the fan off\nG28 ; home to endstops\nG1 Z15 F9000 ;move the platform down 15mm\nG92 E0 ;zero the extruded length\nG1 F200 E10 ;extrude 10mm of feed stock\nG92 E0 ;zero the extruded length again\nG0 X0 Y0 F{travelSpeed} ;home position is not X0 Y0\nM117 Printing Doodle... ;display message (20 characters to clear whole screen)\n",
"type": "ultimaker2" "type": "ultimaker2"
}, },
"ultimaker2go": { "ultimaker2go": {
"dimensionsX": 120, "dimensionsX": 120,
"dimensionsY": 120, "dimensionsY": 120,
"dimensionsZ": 115, "dimensionsZ": 115,
"endCode": "M107 ;fan off\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 E-5 X-20 Y-20 F9000 ;move Z up a bit and retract filament even more\nG28 ;home the printer\nM84 ;disable axes / steppers\nG90 ;absolute positioning\nM104 S{preheatTemp}\n{if heatedBed}M140 S{preheatBedTemp}\nM117 Done ;display message (20 characters to clear whole screen)\n", "endCode": "M107 ;fan off\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 E-5 X-20 Y-20 F9000 ;move Z up a bit and retract filament even more\nG28 ;home the printer\nM84 ;disable axes / steppers\nG90 ;absolute positioning\nM104 S{preheatTemp}\n{if heatedBed}M140 S{preheatBedTemp}\nM117 Done ;display message (20 characters to clear whole screen)\n",
"filamentThickness": 2.85, "filamentThickness": 2.85,
"heatedBed": false, "heatedBed": false,
"heatupEnabled": true, "heatupEnabled": true,
"nozzleDiameter": 0.4, "nozzleDiameter": 0.4,
"startCode": ";Generated with Doodle3D (ultimaker2go)\nM109 S{printingTemp} ;set target temperature \n{if heatedBed}M190 S{printingBedTemp} ;set target bed temperature\nG21 ;metric values\nG90 ;absolute positioning\nM107 ;start with the fan off\nG28 ; home to endstops\nG1 Z15 F9000 ;move the platform down 15mm\nG92 E0 ;zero the extruded length\nG1 F200 E10 ;extrude 10mm of feed stock\nG92 E0 ;zero the extruded length again\nG0 X0 Y0 F{travelSpeed} ;home position is not X0 Y0\nM117 Printing Doodle... ;display message (20 characters to clear whole screen)\n", "startCode": ";Generated with Doodle3D (ultimaker2go)\nM109 S{printingTemp} ;set target temperature \n{if heatedBed}M190 S{printingBedTemp} ;set target bed temperature\nG21 ;metric values\nG90 ;absolute positioning\nM107 ;start with the fan off\nG28 ; home to endstops\nG1 Z15 F9000 ;move the platform down 15mm\nG92 E0 ;zero the extruded length\nG1 F200 E10 ;extrude 10mm of feed stock\nG92 E0 ;zero the extruded length again\nG0 X0 Y0 F{travelSpeed} ;home position is not X0 Y0\nM117 Printing Doodle... ;display message (20 characters to clear whole screen)\n",
"type": "ultimaker2g0" "type": "ultimaker2g0"
} }
} }

View File

@ -1,47 +1,47 @@
{ {
"heatupBedTemperature": 70, "heatupBedTemperature": 70,
"heatupTemperature": 20, "heatupTemperature": 20,
"temperature": 210.0, "temperature": 210.0,
"layerHeight": 0.15, "layerHeight": 0.15,
"bottomThickness": 0.4, "bottomThickness": 0.4,
"topThickness": 0.8, "topThickness": 0.8,
"shellThickness": 0.4, "shellThickness": 0.4,
"brimOffset": 4.0, "brimOffset": 4.0,
"fillGridSize": 5.0, "fillGridSize": 5.0,
"infillOverlap": 0.0, "infillOverlap": 0.0,
"travelSpeed": 200.0, "travelSpeed": 200.0,
"retractionAmount": 3.0, "retractionAmount": 3.0,
"retractionEnabled": true, "retractionEnabled": true,
"retractionSpeed": 50.0, "retractionSpeed": 50.0,
"retractionMinDistance": 0.0, "retractionMinDistance": 0.0,
"supportAcceptanceMargin": 1.5, "supportAcceptanceMargin": 1.5,
"supportDistanceY": 0.4, "supportDistanceY": 0.4,
"supportEnabled": false, "supportEnabled": false,
"supportGridSize": 6.0, "supportGridSize": 6.0,
"supportMargin": 2.0, "supportMargin": 2.0,
"supportPlateSize": 4.0, "supportPlateSize": 4.0,
"outerLine": { "outerLine": {
"flowRate": 1.0, "flowRate": 1.0,
"speed": 40.0 "speed": 40.0
}, },
"innerLine": { "innerLine": {
"flowRate": 1.0, "flowRate": 1.0,
"speed": 50.0 "speed": 50.0
}, },
"fill": { "fill": {
"flowRate": 1.0, "flowRate": 1.0,
"speed": 50.0 "speed": 50.0
}, },
"brim": { "brim": {
"flowRate": 1.0, "flowRate": 1.0,
"speed": 40.0 "speed": 40.0
}, },
"support": { "support": {
"flowRate": 0.8, "flowRate": 0.8,
"speed": 40.0 "speed": 40.0
}, },
"bottom": { "bottom": {
"flowRate": 1.2, "flowRate": 1.2,
"speed": 40.0 "speed": 40.0
} }
} }

View File

@ -10,72 +10,72 @@ export default function optimizePaths(slices, settings) {
const slice = slices[layer]; const slice = slices[layer];
if (slice.brim !== undefined && slice.brim.paths.length > 0) { if (slice.brim !== undefined && slice.brim.paths.length > 0) {
slice.brim = optimizeShape(slice.brim, start); slice.brim = optimizeShape(slice.brim, start);
start.copy(slice.brim.lastPoint(true)); start.copy(slice.brim.lastPoint(true));
} }
const parts = []; const parts = [];
while (slice.parts.length > 0) { while (slice.parts.length > 0) {
let closestDistance = Infinity; let closestDistance = Infinity;
let closestPart; let closestPart;
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];
let bounds; let bounds;
if (part.shape.closed) { if (part.shape.closed) {
bounds = part.outerLine.shapeBounds(); bounds = part.outerLine.shapeBounds();
} else { } else {
bounds = part.shape.shapeBounds(); bounds = part.shape.shapeBounds();
} }
const top = bounds.top - start.y; const top = bounds.top - start.y;
const bottom = start.y - bounds.bottom; const bottom = start.y - bounds.bottom;
const left = bounds.left - start.x; const left = bounds.left - start.x;
const right = start.x - bounds.right; const right = start.x - bounds.right;
const distance = Math.max(top, bottom, left, right); const distance = Math.max(top, bottom, left, right);
if (distance < closestDistance) { if (distance < closestDistance) {
closestDistance = distance; closestDistance = distance;
closestPart = i; closestPart = i;
} }
} }
const part = slice.parts.splice(closestPart, 1)[0]; const part = slice.parts.splice(closestPart, 1)[0];
parts.push(part); parts.push(part);
if (part.shape.closed) { if (part.shape.closed) {
if (part.outerLine.paths.length > 0) { if (part.outerLine.paths.length > 0) {
part.outerLine = optimizeShape(part.outerLine, start); part.outerLine = optimizeShape(part.outerLine, start);
start.copy(part.outerLine.lastPoint(true)); start.copy(part.outerLine.lastPoint(true));
} }
for (let i = 0; i < part.innerLines.length; i ++) { for (let i = 0; i < part.innerLines.length; i ++) {
const innerLine = part.innerLines[i]; const innerLine = part.innerLines[i];
if (innerLine.paths.length > 0) { if (innerLine.paths.length > 0) {
part.innerLines[i] = optimizeShape(innerLine, start); part.innerLines[i] = optimizeShape(innerLine, start);
start.copy(part.innerLines[i].lastPoint(true)); start.copy(part.innerLines[i].lastPoint(true));
} }
} }
if (part.fill.paths.length > 0) { if (part.fill.paths.length > 0) {
part.fill = optimizeShape(part.fill, start); part.fill = optimizeShape(part.fill, start);
start.copy(part.fill.lastPoint(true)); start.copy(part.fill.lastPoint(true));
} }
} else { } else {
part.shape = optimizeShape(part.shape, start); part.shape = optimizeShape(part.shape, start);
start.copy(part.shape.lastPoint(true)); start.copy(part.shape.lastPoint(true));
} }
} }
slice.parts = parts; slice.parts = parts;
if (slice.support !== undefined && slice.support.length > 0) { if (slice.support !== undefined && slice.support.length > 0) {
slice.support = optimizeShape(slice.support, start); slice.support = optimizeShape(slice.support, start);
start.copy(slice.support.lastPoint(true)); start.copy(slice.support.lastPoint(true));
} }
} }
} }