Merge branch 'feature/improved-open-closed-detection' into develop

This commit is contained in:
casperlamboo 2017-07-18 10:42:04 +02:00
commit 4e38acd9bd
12 changed files with 53 additions and 186788 deletions

File diff suppressed because one or more lines are too long

View File

@ -1,5 +1,4 @@
import 'three.js'; import 'three.js';
import 'three.js/loaders/STLLoader';
import { Settings, printerSettings, userSettings, Slicer } from 'src/index.js'; import { Settings, printerSettings, userSettings, Slicer } from 'src/index.js';
import { saveAs } from 'file-saver'; import { saveAs } from 'file-saver';
@ -8,18 +7,15 @@ const settings = new Settings({
...userSettings ...userSettings
}); });
const stlLoader = new THREE.STLLoader(); const jsonLoader = new THREE.JSONLoader();
stlLoader.load('stl/traktor.stl', async (geometry) => { jsonLoader.load('models/airplane.json', async geometry => {
geometry = new THREE.Geometry().fromBufferGeometry(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.mergeVertices();
geometry.computeFaceNormals(); geometry.computeFaceNormals();
const slicer = new Slicer().setGeometry(geometry); const slicer = new Slicer().setGeometry(geometry);
const gcode = await slicer.slice(settings); const gcode = slicer.sliceSync(settings);
const file = new File([gcode], 'traktor.gcode', { type: 'text/plain' }); const file = new File([gcode], 'gcode.gcode', { type: 'text/plain' });
saveAs(file); saveAs(file);
}); });

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@ -19,7 +19,6 @@ SystemJS.config({
"https": "npm:jspm-nodelibs-https@0.2.0", "https": "npm:jspm-nodelibs-https@0.2.0",
"react-dom": "npm:react-dom@15.3.2", "react-dom": "npm:react-dom@15.3.2",
"babel-plugin-transform-react-jsx": "npm:babel-plugin-transform-react-jsx@6.8.0", "babel-plugin-transform-react-jsx": "npm:babel-plugin-transform-react-jsx@6.8.0",
"three.js/loaders/STLLoader": "github:mrdoob/three.js@r83/examples/js/loaders/STLLoader.js",
"file-saver": "npm:file-saver@1.3.3" "file-saver": "npm:file-saver@1.3.3"
}, },
"packages": { "packages": {
@ -139,16 +138,8 @@ SystemJS.config({
} }
} }
}, },
meta: {
"three.js/loaders/STLLoader": {
"deps": [
"three.js"
]
}
},
map: { map: {
"babel": "npm:babel-core@5.8.38", "babel": "npm:babel-core@5.8.38"
"three.js/loaders/STLLoader": "github:mrdoob/three.js@r75/examples/js/loaders/STLLoader.js"
} }
}); });

View File

@ -13,6 +13,8 @@ export default function calculateLayersIntersections(lines, settings) {
for (let lineIndex = 0; lineIndex < lines.length; lineIndex ++) { for (let lineIndex = 0; lineIndex < lines.length; lineIndex ++) {
const line = lines[lineIndex].line; const line = lines[lineIndex].line;
if (line.isFlat) continue;
const min = Math.ceil(Math.min(line.start.y, line.end.y) / layerHeight); const min = Math.ceil(Math.min(line.start.y, line.end.y) / layerHeight);
const max = Math.floor(Math.max(line.start.y, line.end.y) / layerHeight); const max = Math.floor(Math.max(line.start.y, line.end.y) / layerHeight);

View File

@ -1,6 +1,6 @@
import * as THREE from 'three.js'; import * as THREE from 'three.js';
function addLine(geometry, lineLookup, lines, a, b) { function addLine(geometry, lineLookup, lines, a, b, isFlat) {
const index = lines.length; const index = lines.length;
lineLookup[`${a}_${b}`] = index; lineLookup[`${a}_${b}`] = index;
@ -8,13 +8,13 @@ function addLine(geometry, lineLookup, lines, a, b) {
line: new THREE.Line3(geometry.vertices[a], geometry.vertices[b]), line: new THREE.Line3(geometry.vertices[a], geometry.vertices[b]),
connects: [], connects: [],
normals: [], normals: [],
open: false isFlat
}); });
return index; return index;
} }
export default function createLines(geometry, settings, openClosed) { export default function createLines(geometry, settings) {
console.log('constructing unique lines from geometry'); console.log('constructing unique lines from geometry');
const lines = []; const lines = [];
@ -22,34 +22,28 @@ export default function createLines(geometry, settings, openClosed) {
for (let i = 0; i < geometry.faces.length; i ++) { for (let i = 0; i < geometry.faces.length; i ++) {
const face = geometry.faces[i]; const face = geometry.faces[i];
const open = openClosed[i];
if (face.normal.y !== 1 && face.normal.y !== -1) { const lookupA = lineLookup[`${face.b}_${face.a}`];
const normal = new THREE.Vector2(face.normal.z, face.normal.x).normalize(); const lookupB = lineLookup[`${face.c}_${face.b}`];
const lookupC = lineLookup[`${face.a}_${face.c}`];
const lookupA = lineLookup[`${face.b}_${face.a}`]; const isFlat = face.normal.y !== 1 && face.normal.y !== -1;
const lookupB = lineLookup[`${face.c}_${face.b}`];
const lookupC = lineLookup[`${face.a}_${face.c}`];
// only add unique lines // only add unique lines
// returns index of said line // returns index of said line
const indexA = typeof lookupA !== 'undefined' ? lookupA : addLine(geometry, lineLookup, lines, face.a, face.b); const lineIndexA = typeof lookupA !== 'undefined' ? lookupA : addLine(geometry, lineLookup, lines, face.a, face.b, isFlat);
const indexB = typeof lookupB !== 'undefined' ? lookupB : addLine(geometry, lineLookup, lines, face.b, face.c); const lineIndexB = typeof lookupB !== 'undefined' ? lookupB : addLine(geometry, lineLookup, lines, face.b, face.c, isFlat);
const indexC = typeof lookupC !== 'undefined' ? lookupC : addLine(geometry, lineLookup, lines, face.c, face.a); const lineIndexC = typeof lookupC !== 'undefined' ? lookupC : addLine(geometry, lineLookup, lines, face.c, face.a, isFlat);
// set connecting lines (based on face) // set connecting lines (based on face)
lines[indexA].connects.push(indexB, indexC); lines[lineIndexA].connects.push(lineIndexB, lineIndexC);
lines[indexB].connects.push(indexC, indexA); lines[lineIndexB].connects.push(lineIndexC, lineIndexA);
lines[indexC].connects.push(indexA, indexB); lines[lineIndexC].connects.push(lineIndexA, lineIndexB);
lines[indexA].normals.push(normal); const normal = new THREE.Vector2(face.normal.z, face.normal.x).normalize();
lines[indexB].normals.push(normal); lines[lineIndexA].normals.push(normal);
lines[indexC].normals.push(normal); lines[lineIndexB].normals.push(normal);
lines[lineIndexC].normals.push(normal);
lines[indexA].open = open;
lines[indexB].open = open;
lines[indexC].open = open;
}
} }
return lines; return lines;

View File

@ -1,42 +1,45 @@
export default function detectOpenClosed(geometry) { export default function detectOpenClosed(lines) {
console.log('detecting open and closed lines'); console.log('detecting open and closed lines');
const pools = getPools(geometry); const pools = getPools(lines);
const openVertices = getOpenVertices(geometry); const openLines = lines.map(line => line.connects.length === 2);
const openFaces = [];
for (let i = 0; i < pools.length; i ++) { for (let i = 0; i < pools.length; i ++) {
const pool = pools[i]; const pool = pools[i];
const isOpen = pool.some(face => openVertices[face.a] || openVertices[face.b] || openVertices[face.c]); const isOpenGeometry = pool.some(lineIndex => openLines[lineIndex]);
if (isOpen) openFaces.splice(openFaces.length, 0, ...pool); for (let j = 0; j < pool.length; j ++) {
const lineIndex = pool[j];
const line = lines[lineIndex];
line.openGeometry = isOpenGeometry;
}
} }
return geometry.faces.map(face => openFaces.includes(face));
} }
function findPool(pools, faceA) { function findPool(pools, lines, lineIndex) {
const { connects } = lines[lineIndex];
for (let i = 0; i < pools.length; i ++) { for (let i = 0; i < pools.length; i ++) {
const pool = pools[i]; const pool = pools[i];
if (pool.find(faceB => faceA.a === faceB.a || faceA.a === faceB.b || faceA.a === faceB.c)) { if (pool.find(lineIndex => connects.includes(lineIndex))) {
return pool; return pool;
} }
} }
// no pool found
// create new pool
const pool = []; const pool = [];
pools.push(pool); pools.push(pool);
return pool; return pool;
} }
function getPools(geometry) { function getPools(lines) {
const pools = []; const pools = [];
for (let i = 0; i < geometry.faces.length; i ++) { for (let lineIndex = 0; lineIndex < lines.length; lineIndex ++) {
const face = geometry.faces[i]; const pool = findPool(pools, lines, lineIndex);
const pool = findPool(pools, face); pool.push(lineIndex);
pool.push(face);
} }
for (let i = 0; i < pools.length; i ++) { for (let i = 0; i < pools.length; i ++) {
@ -46,8 +49,9 @@ function getPools(geometry) {
const poolB = pools[j]; const poolB = pools[j];
for (let k = 0; k < poolA.length; k ++) { for (let k = 0; k < poolA.length; k ++) {
const faceA = poolA[k]; const { connects } = lines[poolA[k]];
if (poolB.find(faceB => faceA.a === faceB.a || faceA.a === faceB.b || faceA.a === faceB.c)) {
if (poolB.find(lineIndex => connects.includes(lineIndex))) {
poolA.splice(poolA.length, 0, ...poolB); poolA.splice(poolA.length, 0, ...poolB);
poolB.splice(0, poolB.length); poolB.splice(0, poolB.length);
} }
@ -57,15 +61,3 @@ function getPools(geometry) {
return pools.filter(pool => pool.length > 0); return pools.filter(pool => pool.length > 0);
} }
function getOpenVertices(geometry) {
const vertices = Array(geometry.vertices.length).fill(0);
for (let i = 0; i < geometry.faces.length; i ++) {
const face = geometry.faces[i];
vertices[face.a] ++;
vertices[face.b] ++;
vertices[face.c] ++;
}
return vertices.map(numFaces => numFaces < 4);
}

View File

@ -22,7 +22,7 @@ export default function intersectionsToShapes(layerIntersectionIndexes, layerInt
const shape = []; const shape = [];
const firstPoints = [index]; const firstPoints = [index];
const { open: openGeometry } = lines[index]; const { openGeometry } = lines[index];
let isFirstPoint = true; let isFirstPoint = true;
let openShape = true; let openShape = true;

View File

@ -13,12 +13,11 @@ import applyPrecision from './applyPrecision.js';
import removePrecision from './removePrecision.js'; import removePrecision from './removePrecision.js';
export default function(geometry, settings) { export default function(geometry, settings) {
geometry.mergeVertices();
geometry.computeFaceNormals(); geometry.computeFaceNormals();
// get unique lines from geometry; // get unique lines from geometry;
const openClosed = detectOpenClosed(geometry); const lines = createLines(geometry, settings);
const lines = createLines(geometry, settings, openClosed); const openClosed = detectOpenClosed(lines);
const { const {
layerIntersectionIndexes, layerIntersectionIndexes,