added support for non closing parts

This commit is contained in:
casperlamboo 2015-07-10 18:04:10 +02:00 committed by Simon Voordouw
parent c0cfa8de9d
commit 61437295b9
4 changed files with 218 additions and 102 deletions

View File

@ -25,16 +25,16 @@ canvas {border: 1px solid black;}
<canvas id="canvas" width="400" height="400"></canvas> <canvas id="canvas" width="400" height="400"></canvas>
<script> <script>
var USER_SETTINGS, PRINTER_SETTINGS, doodleBox, gcode; var USER_SETTINGS, PRINTER_SETTINGS, doodleBox, gcode, scene;
function init () { function init () {
"use strict"; "use strict";
var scene = createScene(); scene = createScene();
var localIp = location.hash.substring(1); var localIp = location.hash.substring(1);
//doodleBox = new D3D.Box(localIp); doodleBox = new D3D.Box(localIp).init();
var printer = new D3D.Printer().updateConfig(USER_SETTINGS).updateConfig(PRINTER_SETTINGS["ultimaker"]); var printer = new D3D.Printer().updateConfig(USER_SETTINGS).updateConfig(PRINTER_SETTINGS["ultimaker2go"]);
var loader = new THREE.STLLoader(); var loader = new THREE.STLLoader();
loader.load('models/pokemon/pikachu.stl', function (geometry) { loader.load('models/pokemon/pikachu.stl', function (geometry) {
@ -66,11 +66,29 @@ function init () {
return geometry; return geometry;
})(); })();
*/ */
var material = new THREE.MeshPhongMaterial({color: 0x00ff00, wireframe: false});
/*var path = [{x: 60, y: 40}, {x: 60, y: 50}, {x: 60, y: 60}, {x: 80, y: 60}, {x: 40, y: 40}, {x: 50, y: 40}, {x: 10, y: 60}];
var geometry = new THREE.Geometry();
for (var i = 0; i < path.length; i ++) {
var point = path[i];
geometry.vertices.push(new THREE.Vector3(point.x, 0, point.y));
geometry.vertices.push(new THREE.Vector3(point.x, 50, point.y));
}
for (var i = 0; i < path.length - 1; i ++) {
var base = i * 2;
geometry.faces.push(new THREE.Face3(base, base + 1, base + 2));
geometry.faces.push(new THREE.Face3(base + 3, base + 2, base + 1));
}*/
var material = new THREE.MeshPhongMaterial({color: 0x00ff00, wireframe: false, side: THREE.DoubleSide});
var mesh = new THREE.Mesh(geometry, material); var mesh = new THREE.Mesh(geometry, material);
mesh.rotation.x = -Math.PI/2; mesh.rotation.x = -Math.PI/2;
mesh.scale.x = mesh.scale.y = mesh.scale.z = 1; //mesh.scale.x = mesh.scale.y = mesh.scale.z = 1;
mesh.position.x = 60; mesh.position.x = 60;
mesh.position.z = 60; mesh.position.z = 60;

View File

@ -26,7 +26,12 @@ D3D.Slice.prototype.optimizePaths = function (start) {
for (var i = 0; i < this.parts.length; i ++) { for (var i = 0; i < this.parts.length; i ++) {
var part = this.parts[i]; var part = this.parts[i];
var bounds = part.outerLine.bounds(); if (part.addFill) {
var bounds = part.outerLine.bounds();
}
else {
var bounds = part.intersect.bounds();
}
var top = bounds.top - start.y; var top = bounds.top - start.y;
var bottom = start.y - bounds.bottom; var bottom = start.y - bounds.bottom;
@ -44,22 +49,28 @@ D3D.Slice.prototype.optimizePaths = function (start) {
var part = this.parts.splice(closestPart, 1)[0]; var part = this.parts.splice(closestPart, 1)[0];
parts.push(part); parts.push(part);
if (part.outerLine.length > 0) { if (part.addFill) {
part.outerLine = part.outerLine.optimizePath(start); if (part.outerLine.length > 0) {
start = part.outerLine.lastPoint(); part.outerLine = part.outerLine.optimizePath(start);
} start = part.outerLine.lastPoint();
}
for (var j = 0; j < part.innerLines.length; j ++) { for (var j = 0; j < part.innerLines.length; j ++) {
var innerLine = part.innerLines[j]; var innerLine = part.innerLines[j];
if (innerLine.length > 0) { if (innerLine.length > 0) {
part.innerLines[j] = innerLine.optimizePath(start); part.innerLines[j] = innerLine.optimizePath(start);
start = part.innerLines[j].lastPoint(); start = part.innerLines[j].lastPoint();
}
}
if (part.fill.length > 0) {
part.fill = part.fill.optimizePath(start);
start = part.fill.lastPoint();
} }
} }
else {
if (part.fill.length > 0) { part.intersect.optimizePath(start);
part.fill = part.fill.optimizePath(start); start = part.intersect.lastPoint();
start = part.fill.lastPoint();
} }
} }
@ -79,18 +90,31 @@ D3D.Slice.prototype.getOutline = function () {
var outLines = new D3D.Paths([], true); var outLines = new D3D.Paths([], true);
for (var i = 0; i < this.parts.length; i ++) { for (var i = 0; i < this.parts.length; i ++) {
outLines.join(this.parts[i].outerLine); var part = this.parts[i];
if (part.addFill) {
outLines.join(this.parts[i].outerLine);
}
} }
return outLines; return outLines;
}; };
D3D.Slice.prototype.addIntersect = function (intersect) { D3D.Slice.prototype.add = function (intersect) {
'use strict'; 'use strict';
this.parts.push({ if (intersect.closed) {
intersect: intersect, this.parts.push({
innerLines: [], intersect: intersect,
outerLine: new D3D.Paths([], true), innerLines: [],
fill: new D3D.Paths([], false) outerLine: new D3D.Paths([], true),
}); fill: new D3D.Paths([], false),
addFill: true
});
}
else {
this.parts.push({
intersect: intersect,
addFill: false
});
}
}; };

View File

@ -182,6 +182,8 @@ D3D.Slicer.prototype._slice = function (lines, printer) {
var sliceParts = []; var sliceParts = [];
for (var i = 0; i < layerIntersections.length; i ++) { for (var i = 0; i < layerIntersections.length; i ++) {
var index = layerIntersections[i]; var index = layerIntersections[i];
var firstPoint = index;
var closed = false;
if (done.indexOf(index) === -1) { if (done.indexOf(index) === -1) {
var shape = []; var shape = [];
@ -195,32 +197,44 @@ D3D.Slicer.prototype._slice = function (lines, printer) {
var connects = lines[index].connects.clone(); var connects = lines[index].connects.clone();
var faceNormals = lines[index].normals.clone(); var faceNormals = lines[index].normals.clone();
if (shape.length > 2 && connects.indexOf(firstPoint) !== -1) {
closed = true;
break;
}
for (var j = 0; j < connects.length; j ++) { for (var j = 0; j < connects.length; j ++) {
index = connects[j]; index = connects[j];
if (intersections[index] !== undefined && done.indexOf(index) === -1) { if (done.indexOf(index) === -1) {
if (intersections[index] !== undefined) {
var a = new THREE.Vector2(intersection.x, intersection.y); var a = new THREE.Vector2(intersection.x, intersection.y);
var b = new THREE.Vector2(intersections[index].x, intersections[index].y); var b = new THREE.Vector2(intersections[index].x, intersections[index].y);
var faceNormal = faceNormals[Math.floor(j/2)]; var faceNormal = faceNormals[Math.floor(j/2)];
if (a.distanceTo(b) < 0.0001 || faceNormal.length() === 0) { if (a.distanceTo(b) < 0.0001 || faceNormal.length() === 0) {
done.push(index); done.push(index);
connects = connects.concat(lines[index].connects); connects = connects.concat(lines[index].connects);
faceNormals = faceNormals.concat(lines[index].normals); faceNormals = faceNormals.concat(lines[index].normals);
index = -1;
}
else {
var normal = a.sub(b).normal().normalize();
if (normal.dot(faceNormal) > 0) {
break;
}
else {
index = -1; index = -1;
} }
else {
var normal = a.sub(b).normal().normalize();
if (normal.dot(faceNormal) > 0) {
break;
}
else {
index = -1;
}
}
}
else {
done.push(index);
index = -1;
} }
} }
else { else {
@ -229,7 +243,49 @@ D3D.Slicer.prototype._slice = function (lines, printer) {
} }
} }
var part = new D3D.Paths([shape]).clean(0.01); if (!closed) {
var index = firstPoint;
while (index !== -1) {
if (index !== firstPoint) {
done.push(index);
var intersection = intersections[index];
console.log(intersection);
//uppercase X and Y because clipper vector
shape.unshift({X: intersection.x, Y: intersection.y});
}
var connects = lines[index].connects.clone();
for (var j = 0; j < connects.length; j ++) {
index = connects[j];
if (done.indexOf(index) === -1) {
if (intersections[index] !== undefined) {
if (a.distanceTo(b) < 0.0001) {
done.push(index);
connects = connects.concat(lines[index].connects);
index = -1;
}
else {
break;
}
}
else {
done.push(index);
index = -1;
}
}
else {
index = -1;
}
}
}
}
var part = new D3D.Paths([shape], closed).clean(0.01);
if (part.length > 0) { if (part.length > 0) {
sliceParts.push(part); sliceParts.push(part);
} }
@ -240,19 +296,24 @@ D3D.Slicer.prototype._slice = function (lines, printer) {
for (var i = 0; i < sliceParts.length; i ++) { for (var i = 0; i < sliceParts.length; i ++) {
var slicePart1 = sliceParts[i]; var slicePart1 = sliceParts[i];
var merge = false; if (slicePart1.closed) {
var merge = false;
for (var j = 0; j < slice.parts.length; j ++) { for (var j = 0; j < slice.parts.length; j ++) {
var slicePart2 = slice.parts[j].intersect; var slicePart2 = slice.parts[j].intersect;
if (slicePart2.intersect(slicePart1).length > 0) { if (slicePart2.closed && slicePart2.intersect(slicePart1).length > 0) {
slicePart2.join(slicePart1); slicePart2.join(slicePart1);
merge = true; merge = true;
break; break;
}
}
if (!merge) {
slice.add(slicePart1);
} }
} }
if (!merge) { else {
slice.addIntersect(slicePart1); slice.add(slicePart1);
} }
} }
@ -284,19 +345,21 @@ D3D.Slicer.prototype._generateInnerLines = function (slices, printer) {
for (var i = 0; i < slice.parts.length; i ++) { for (var i = 0; i < slice.parts.length; i ++) {
var part = slice.parts[i]; var part = slice.parts[i];
var outerLine = part.intersect.clone().scaleUp(scale).offset(-nozzleRadius); if (part.addFill) {
var outerLine = part.intersect.clone().scaleUp(scale).offset(-nozzleRadius);
if (outerLine.length > 0) { if (outerLine.length > 0) {
part.outerLine = outerLine; part.outerLine = outerLine;
for (var offset = nozzleDiameter; offset <= shellThickness; offset += nozzleDiameter) { for (var offset = nozzleDiameter; offset <= shellThickness; offset += nozzleDiameter) {
var innerLine = outerLine.offset(-offset); var innerLine = outerLine.offset(-offset);
if (innerLine.length > 0) { if (innerLine.length > 0) {
part.innerLines.push(innerLine); part.innerLines.push(innerLine);
} }
else { else {
break; break;
}
} }
} }
} }
@ -340,40 +403,43 @@ D3D.Slicer.prototype._generateInfills = function (slices, printer) {
for (var i = 0; i < slice.parts.length; i ++) { for (var i = 0; i < slice.parts.length; i ++) {
var part = slice.parts[i]; var part = slice.parts[i];
var outerLine = part.outerLine;
if (outerLine.length > 0) { if (part.addFill) {
var inset = ((part.innerLines.length > 0) ? part.innerLines[part.innerLines.length - 1] : outerLine); var outerLine = part.outerLine;
var fillArea = inset.offset(-nozzleRadius); if (outerLine.length > 0) {
if (surroundingLayer) { var inset = ((part.innerLines.length > 0) ? part.innerLines[part.innerLines.length - 1] : outerLine);
if (infillOverlap === 0) {
var highFillArea = fillArea.difference(surroundingLayer).intersect(fillArea); var fillArea = inset.offset(-nozzleRadius);
if (surroundingLayer) {
if (infillOverlap === 0) {
var highFillArea = fillArea.difference(surroundingLayer).intersect(fillArea);
}
else {
var highFillArea = fillArea.difference(surroundingLayer).offset(infillOverlap).intersect(fillArea);
}
} }
else { else {
var highFillArea = fillArea.difference(surroundingLayer).offset(infillOverlap).intersect(fillArea); var highFillArea = fillArea;
} }
} var lowFillArea = fillArea.difference(highFillArea);
else {
var highFillArea = fillArea;
}
var lowFillArea = fillArea.difference(highFillArea);
var fill = new D3D.Paths([], false); var fill = new D3D.Paths([], false);
if (lowFillArea.length > 0) { if (lowFillArea.length > 0) {
var bounds = lowFillArea.bounds(); var bounds = lowFillArea.bounds();
var lowFillTemplate = this._getFillTemplate(bounds, fillGridSize, true, true); var lowFillTemplate = this._getFillTemplate(bounds, fillGridSize, true, true);
part.fill.join(lowFillTemplate.intersect(lowFillArea)); part.fill.join(lowFillTemplate.intersect(lowFillArea));
} }
if (highFillArea.length > 0) { if (highFillArea.length > 0) {
var bounds = highFillArea.bounds(); var bounds = highFillArea.bounds();
var even = (layer % 2 === 0); var even = (layer % 2 === 0);
var highFillTemplate = this._getFillTemplate(bounds, hightemplateSize, even, !even); var highFillTemplate = this._getFillTemplate(bounds, hightemplateSize, even, !even);
part.fill.join(highFillTemplate.intersect(highFillArea)); part.fill.join(highFillTemplate.intersect(highFillArea));
}
} }
} }
} }
@ -471,12 +537,14 @@ D3D.Slicer.prototype._optimizePaths = function (slices, printer) {
for (var i = 0; i < slice.parts.length; i ++) { for (var i = 0; i < slice.parts.length; i ++) {
var part = slice.parts[i]; var part = slice.parts[i];
part.outerLine.scaleDown(scale); if (part.addFill) {
for (var j = 0; j < part.innerLines.length; j ++) { part.outerLine.scaleDown(scale);
var innerLine = part.innerLines[j]; for (var j = 0; j < part.innerLines.length; j ++) {
innerLine.scaleDown(scale); var innerLine = part.innerLines[j];
innerLine.scaleDown(scale);
}
part.fill.scaleDown(scale);
} }
part.fill.scaleDown(scale);
} }
if (slice.support !== undefined) { if (slice.support !== undefined) {
@ -572,14 +640,20 @@ D3D.Slicer.prototype._slicesToGCode = function (slices, printer) {
for (var i = 0; i < slice.parts.length; i ++) { for (var i = 0; i < slice.parts.length; i ++) {
var part = slice.parts[i]; var part = slice.parts[i];
pathToGCode(part.outerLine, false, true, "outerLine"); if (part.addFill) {
pathToGCode(part.outerLine, false, true, "outerLine");
for (var j = 0; j < part.innerLines.length; j ++) { for (var j = 0; j < part.innerLines.length; j ++) {
var innerLine = part.innerLines[j]; var innerLine = part.innerLines[j];
pathToGCode(innerLine, false, false, "innerLine"); pathToGCode(innerLine, false, false, "innerLine");
}
pathToGCode(part.fill, true, false, "fill");
}
else {
var retract = !(slice.parts.length === 1 && slice.support === undefined);
pathToGCode(part.intersect, retract, retract, "outerLine");
} }
pathToGCode(part.fill, true, false, "fill");
} }
if (slice.support !== undefined) { if (slice.support !== undefined) {

View File

@ -47,7 +47,7 @@ function init () {
var scene = createScene(); var scene = createScene();
var localIp = location.hash.substring(1); var localIp = location.hash.substring(1);
doodleBox = new D3D.Box(localIp).init(); /*doodleBox = new D3D.Box(localIp).init();
doodleBox.onupdate = function (data) { doodleBox.onupdate = function (data) {
document.getElementById('state').innerHTML = data.state; document.getElementById('state').innerHTML = data.state;
document.getElementById('bed_temp').innerHTML = data.bed; document.getElementById('bed_temp').innerHTML = data.bed;
@ -58,7 +58,7 @@ function init () {
document.getElementById('buffered_lines').innerHTML = data.buffered_lines; document.getElementById('buffered_lines').innerHTML = data.buffered_lines;
document.getElementById('total_lines').innerHTML = data.total_lines; document.getElementById('total_lines').innerHTML = data.total_lines;
document.getElementById('print_batches').innerHTML = doodleBox._printBatches.length; document.getElementById('print_batches').innerHTML = doodleBox._printBatches.length;
}; };*/
printer = new D3D.Printer().updateConfig(USER_SETTINGS).updateConfig(PRINTER_SETTINGS['ultimaker2go']); printer = new D3D.Printer().updateConfig(USER_SETTINGS).updateConfig(PRINTER_SETTINGS['ultimaker2go']);