|
@@ -10,6 +10,8 @@ but are merely close together.</p>
|
|
|
<input type="file" id="file" name="file" />
|
|
|
<ul id="console">
|
|
|
</ul>
|
|
|
+<p id="progress">
|
|
|
+</p>
|
|
|
|
|
|
|
|
|
<script>
|
|
@@ -162,76 +164,111 @@ function getBinarySTL(view) {
|
|
|
return triangles;
|
|
|
}
|
|
|
|
|
|
+var splitMeshIndex;
|
|
|
+var meshes;
|
|
|
+
|
|
|
function splitMesh(triangles) {
|
|
|
meshes = [];
|
|
|
+ splitMeshIndex = 0;
|
|
|
|
|
|
- for (var i = 0; i<triangles.length; i++) {
|
|
|
- var t = triangles[i];
|
|
|
- var matches = [];
|
|
|
- for (var j = 0 ; j < meshes.length; j++) {
|
|
|
- for (var k = 0 ; k < 3 ; k++) {
|
|
|
- if (t[k] in meshes[j].points) {
|
|
|
- matches.push(j);
|
|
|
- break;
|
|
|
+ function process() {
|
|
|
+ var i = splitMeshIndex;
|
|
|
+
|
|
|
+ document.getElementById('progress').innerHTML = "Splitting "+(i/triangles.length*100).toFixed(1)+'% done ('+(meshes.length)+' parts found)';
|
|
|
+
|
|
|
+ for (; i<triangles.length; i++) {
|
|
|
+ var t = triangles[i];
|
|
|
+ var matches = [];
|
|
|
+ for (var j = 0 ; j < meshes.length; j++) {
|
|
|
+ for (var k = 0 ; k < 3 ; k++) {
|
|
|
+ if (t[k] in meshes[j].points) {
|
|
|
+ matches.push(j);
|
|
|
+ break;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
- }
|
|
|
- var m;
|
|
|
- if (matches.length == 0) {
|
|
|
- m = {points:{}, triangles:[]};
|
|
|
- meshes.push(m);
|
|
|
- }
|
|
|
- else {
|
|
|
- m = meshes[matches[0]];
|
|
|
- for (var j = matches.length - 1 ; j >= 1 ; j--) {
|
|
|
- mm = meshes[matches[j]];
|
|
|
- for (var key in mm.points) {
|
|
|
- if (mm.points.hasOwnProperty(key))
|
|
|
- m.points[key] = true;
|
|
|
- }
|
|
|
- for (var k = 0 ; k < mm.triangles.length; k++) {
|
|
|
- m.triangles.push(mm.triangles[k]);
|
|
|
+ var m;
|
|
|
+ if (matches.length == 0) {
|
|
|
+ m = {points:{}, triangles:[]};
|
|
|
+ meshes.push(m);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ m = meshes[matches[0]];
|
|
|
+ for (var j = matches.length - 1 ; j >= 1 ; j--) {
|
|
|
+ mm = meshes[matches[j]];
|
|
|
+ for (var key in mm.points) {
|
|
|
+ if (mm.points.hasOwnProperty(key))
|
|
|
+ m.points[key] = true;
|
|
|
+ }
|
|
|
+ for (var k = 0 ; k < mm.triangles.length; k++) {
|
|
|
+ m.triangles.push(mm.triangles[k]);
|
|
|
+ }
|
|
|
+ meshes.splice(matches[j], 1);
|
|
|
}
|
|
|
- meshes.splice(matches[j], 1);
|
|
|
+ }
|
|
|
+ for (var k = 0 ; k < 3 ; k++) {
|
|
|
+ m.points[t[k]] = true;
|
|
|
+ }
|
|
|
+ m.triangles.push(t);
|
|
|
+
|
|
|
+ if (i && i % 5000 == 0) {
|
|
|
+ setTimeout(process, 0);
|
|
|
+ splitMeshIndex = i+1;
|
|
|
+ return;
|
|
|
}
|
|
|
}
|
|
|
- for (var k = 0 ; k < 3 ; k++) {
|
|
|
- m.points[t[k]] = true;
|
|
|
- }
|
|
|
- m.triangles.push(t);
|
|
|
- }
|
|
|
-
|
|
|
- for (var i = 0 ; i < meshes.length ; i++) {
|
|
|
- var bounds = [Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY,
|
|
|
- Number.NEGATIVE_INFINITY, Number.NEGATIVE_INFINITY, Number.NEGATIVE_INFINITY ];
|
|
|
-
|
|
|
- for (var key in meshes[i].points) {
|
|
|
- if (meshes[i].points.hasOwnProperty(key)) {
|
|
|
- var v = parseVector(key);
|
|
|
- for (var k=0; k<3; k++) {
|
|
|
- bounds[k] = Math.min(bounds[k], v[k]);
|
|
|
- bounds[3+k] = Math.max(bounds[3+k], v[k]);
|
|
|
+
|
|
|
+ for (var i = 0 ; i < meshes.length ; i++) {
|
|
|
+ var bounds = [Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY,
|
|
|
+ Number.NEGATIVE_INFINITY, Number.NEGATIVE_INFINITY, Number.NEGATIVE_INFINITY ];
|
|
|
+
|
|
|
+ for (var key in meshes[i].points) {
|
|
|
+ if (meshes[i].points.hasOwnProperty(key)) {
|
|
|
+ var v = parseVector(key);
|
|
|
+ for (var k=0; k<3; k++) {
|
|
|
+ bounds[k] = Math.min(bounds[k], v[k]);
|
|
|
+ bounds[3+k] = Math.max(bounds[3+k], v[k]);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ meshes[i].bounds = bounds;
|
|
|
+ delete meshes[i].points;
|
|
|
}
|
|
|
-
|
|
|
- meshes[i].bounds = bounds;
|
|
|
- delete meshes[i].points;
|
|
|
- }
|
|
|
-
|
|
|
- function compareByBounds(m,m) {
|
|
|
- for (var i=0; i<6; i++) {
|
|
|
- if (m.bounds[i] < m.bounds[i])
|
|
|
- return -1;
|
|
|
- else if (m.bounds[i] < m.bounds[i])
|
|
|
- return -1;
|
|
|
+
|
|
|
+ function compareByBounds(m,m) {
|
|
|
+ for (var i=0; i<6; i++) {
|
|
|
+ if (m.bounds[i] < m.bounds[i])
|
|
|
+ return -1;
|
|
|
+ else if (m.bounds[i] < m.bounds[i])
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ meshes.sort(compareByBounds);
|
|
|
+
|
|
|
+ if (meshes.length == 1) {
|
|
|
+ message("No splitting done: Only one mesh in file.");
|
|
|
+ }
|
|
|
+ else if (meshes.length == 0) {
|
|
|
+ message("No mesh found in file.");
|
|
|
}
|
|
|
- return 0;
|
|
|
+ else {
|
|
|
+ message(String(meshes.length)+" meshes extracted");
|
|
|
+ allSplitMeshes = [];
|
|
|
+
|
|
|
+ for (var i=0; i<meshes.length; i++) {
|
|
|
+ allSplitMeshes.push(meshes[i].triangles);
|
|
|
+ message("<a href='#' onclick='downloadMesh("+i+");'>Download mesh part "+i+"</a> "+describeBounds(meshes[i].bounds));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ document.getElementById('progress').innerHTML = '';
|
|
|
+ document.getElementById('file').disabled = false;
|
|
|
}
|
|
|
|
|
|
- meshes.sort(compareByBounds);
|
|
|
-
|
|
|
- return meshes;
|
|
|
+ process();
|
|
|
}
|
|
|
|
|
|
function downloadBlob(name,blob) {
|
|
@@ -292,22 +329,7 @@ function processSTL(data) {
|
|
|
message(binary ? "binary STL" : "ASCII STL");
|
|
|
triangles = binary ? getBinarySTL(view) : getASCIISTL(text);
|
|
|
message("data successfully read");
|
|
|
- splitMeshes = splitMesh(triangles);
|
|
|
- if (splitMeshes.length == 1) {
|
|
|
- message("No splitting done: Only one mesh in file.");
|
|
|
- }
|
|
|
- else if (splitMeshes.length == 0) {
|
|
|
- message("No mesh found in file.");
|
|
|
- }
|
|
|
- else {
|
|
|
- message(String(splitMeshes.length)+" meshes extracted");
|
|
|
- allSplitMeshes = [];
|
|
|
-
|
|
|
- for (var i=0; i<splitMeshes.length; i++) {
|
|
|
- allSplitMeshes.push(splitMeshes[i].triangles);
|
|
|
- message("<a href='#' onclick='downloadMesh("+i+");'>Download mesh part "+i+"</a> "+describeBounds(splitMeshes[i].bounds));
|
|
|
- }
|
|
|
- }
|
|
|
+ splitMesh(triangles);
|
|
|
}
|
|
|
|
|
|
function handleFileSelect(evt) {
|
|
@@ -317,7 +339,7 @@ function handleFileSelect(evt) {
|
|
|
|
|
|
var f = evt.target.files[0];
|
|
|
|
|
|
- message( String(f.size) + ' bytes');
|
|
|
+ message( "reading "+ String(f.size) + ' bytes');
|
|
|
|
|
|
var n = f.name.split(/[/\\]+/);
|
|
|
baseFilename = f.name.replace(/.*[/\\]/, "").replace(/\.[sS][tT][lL]$/, "");
|
|
@@ -329,9 +351,9 @@ function handleFileSelect(evt) {
|
|
|
}
|
|
|
catch(err) {
|
|
|
message( "Error: "+err);
|
|
|
+ var e = document.getElementById('file');
|
|
|
+ e.disabled = false;
|
|
|
}
|
|
|
- var e = document.getElementById('file');
|
|
|
- e.disabled = false;
|
|
|
}
|
|
|
reader.readAsArrayBuffer(f);
|
|
|
}
|