arpruss пре 8 година
родитељ
комит
4277f9dabe
1 измењених фајлова са 83 додато и 25 уклоњено
  1. 83 25
      split.html

+ 83 - 25
split.html

@@ -23,6 +23,10 @@ function getString(view, position, length) {
     return out;
 }
 
+// For hashing during splitting, ASCII mode is used, where vectors are stored
+// as strings. From a binary STL, the vectors are stored as hex strings, and
+// from an ASCII STL, they are stored as directly extracted ASCII.
+
 function getVector(view, position) {
     if (ASCII_MODE) {
         x = view.getUint32(position, true);
@@ -37,20 +41,28 @@ function getVector(view, position) {
     return [x,y,z]; // x.toString()+","+y.toString()+","+z.toString(); //[x,y,z];
 }
 
-function setVector(view, position, vector) {
+function parseVector(vector) {
     if (typeof vector === "string") {
-        if (vector.includes(":")) {
-            data = vector.split(":");
-            view.setUint32(position, parseInt(data[0],16), true);
-            view.setUint32(position+4, parseInt(data[1],16), true);
-            view.setUint32(position+8, parseInt(data[2],16), true);
-        }
-        else {
-            data = vector.split(",");
-            view.setFloat32(position, parseFloat(data[0]), true);
-            view.setFloat32(position+4, parseFloat(data[1]), true);
-            view.setFloat32(position+8, parseFloat(data[2]), true);
+        var data = vector.split(":");
+        var buf = new ArrayBuffer(4);
+        var view = new DataView(buf);
+        function parse(s) {
+            view.setUint32(0, parseInt(s,16));
+            return view.getFloat32(0);
         }
+        return [parse(data[0]),parse(data[1]),parse(data[2])];
+    }
+    else {
+        return vector;
+    }
+}
+
+function setVector(view, position, vector) {
+    if (typeof vector === "string") {
+        var data = vector.split(":");
+        view.setUint32(position, parseInt(data[0],16), true);
+        view.setUint32(position+4, parseInt(data[1],16), true);
+        view.setUint32(position+8, parseInt(data[2],16), true);
     }
     else {
         view.setFloat32(position, vector[0], true);
@@ -60,12 +72,21 @@ function setVector(view, position, vector) {
 }
 
 function getVectorFromText(line, position) {
-    data = line.substr(position).split(/[\s,]+/);
+    var data = line.substr(position).split(/[\s,]+/);
+    
     if (data.length < 3)
         throw 'Invalid vector';
         
     if (ASCII_MODE) {
-        return data[0]+","+data[1]+","+data[2];
+        var buf = new ArrayBuffer(4);
+        var view = new DataView(buf);
+
+        function toHex32(number) {
+            view.setFloat32(0, parseFloat(number));
+            return view.getUint32(0).toString(16);
+        }
+
+        return toHex32(data[0])+":"+toHex32(data[1])+":"+toHex32(data[2]);
     }
 
     return [parseFloat(data[0]), parseFloat(data[1]), parseFloat(data[2])];
@@ -88,9 +109,8 @@ function getASCIISTL(text) {
     for (var i = 0 ; i < lines.length ; i++ ) {
         l = lines[i].trim().toLowerCase();
         if (l == 'endfacet') {
-            if (triangle.length != 3) {
+            if (triangle.length != 3) 
                 throw 'invalid triangle';
-            }
             triangles.push([triangle[0],triangle[1],triangle[2],normal]);
             triangle = [];
             normal = [0,0,0];
@@ -171,13 +191,37 @@ function splitMesh(triangles) {
         m.triangles.push(t);
     }
     
-    out = [];
-    
     for (var i = 0 ; i < meshes.length ; i++) {
-        out.push(meshes[i].triangles);
+        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;
     }
     
-    return out;
+    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);
+    
+    return meshes;
 }
 
 function downloadBlob(name,blob) {
@@ -211,6 +255,11 @@ function downloadMesh(i) {
     downloadBlob(baseFilename+i+".stl", new Blob([makeMeshByteArray(allSplitMeshes[i])], {type: "application/octet-stream"}));
 }
 
+function describeBounds(bounds) {
+    return "("+bounds[0].toFixed(2)+", "+bounds[1].toFixed(2)+", "+bounds[2].toFixed(2)+") - ("+
+            bounds[3].toFixed(2)+", "+bounds[4].toFixed(2)+", "+bounds[5].toFixed(2)+")";
+}
+
 function processSTL(data) {
     length = data.byteLength;
     view = new DataView(data);
@@ -240,20 +289,22 @@ function processSTL(data) {
     }
     else {
         message(String(splitMeshes.length)+" meshes extracted");
-        allSplitMeshes = splitMeshes;
+        allSplitMeshes = [];
+        
         for (var i=0; i<splitMeshes.length; i++) {
-            message("<a href='#' onclick='downloadMesh("+i+");'>Download mesh part "+i+"</a>");
+            allSplitMeshes.push(splitMeshes[i].triangles);
+            message("<a href='#' onclick='downloadMesh("+i+");'>Download mesh part "+i+"</a> "+describeBounds(splitMeshes[i].bounds));
         }
     }
 }
 
 function handleFileSelect(evt) {
     var e = document.getElementById('file');
-    e.parentNode.removeChild(e);
+    e.disabled = true;
+    document.getElementById('console').innerHTML = '';
 
     var f = evt.target.files[0];
     
-    message( escape(f.name) );
     message( String(f.size) + ' bytes');
     
     var n = f.name.split(/[/\\]+/);
@@ -261,7 +312,14 @@ function handleFileSelect(evt) {
 
     var reader = new FileReader();
     reader.onload = function(event) {
-        processSTL(event.target.result);
+        try {
+            processSTL(event.target.result);
+        }
+        catch(err) {
+            message( "Error: "+err);
+        }
+        var e = document.getElementById('file');
+        e.disabled = false;
     }
     reader.readAsArrayBuffer(f);
 }