├── notes.doc ├── asset ├── arrowUp.png ├── arrowDown.png ├── arrowLeft.png ├── arrowRight.png ├── cube_vnt.stl ├── monkey_vtn.stl ├── torus_vtn.stl ├── arrowUpOver.png ├── arrowDownOver.png ├── arrowLeftOver.png ├── arrowRightOver.png ├── cone_vtn_100v.stl ├── cylinder_vtn_200v.stl └── sphere_vtn_32x32.stl ├── README.md ├── default.css ├── index.html └── STL.js /notes.doc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yeuchi/STLDecoder/HEAD/notes.doc -------------------------------------------------------------------------------- /asset/arrowUp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yeuchi/STLDecoder/HEAD/asset/arrowUp.png -------------------------------------------------------------------------------- /asset/arrowDown.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yeuchi/STLDecoder/HEAD/asset/arrowDown.png -------------------------------------------------------------------------------- /asset/arrowLeft.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yeuchi/STLDecoder/HEAD/asset/arrowLeft.png -------------------------------------------------------------------------------- /asset/arrowRight.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yeuchi/STLDecoder/HEAD/asset/arrowRight.png -------------------------------------------------------------------------------- /asset/cube_vnt.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yeuchi/STLDecoder/HEAD/asset/cube_vnt.stl -------------------------------------------------------------------------------- /asset/monkey_vtn.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yeuchi/STLDecoder/HEAD/asset/monkey_vtn.stl -------------------------------------------------------------------------------- /asset/torus_vtn.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yeuchi/STLDecoder/HEAD/asset/torus_vtn.stl -------------------------------------------------------------------------------- /asset/arrowUpOver.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yeuchi/STLDecoder/HEAD/asset/arrowUpOver.png -------------------------------------------------------------------------------- /asset/arrowDownOver.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yeuchi/STLDecoder/HEAD/asset/arrowDownOver.png -------------------------------------------------------------------------------- /asset/arrowLeftOver.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yeuchi/STLDecoder/HEAD/asset/arrowLeftOver.png -------------------------------------------------------------------------------- /asset/arrowRightOver.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yeuchi/STLDecoder/HEAD/asset/arrowRightOver.png -------------------------------------------------------------------------------- /asset/cone_vtn_100v.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yeuchi/STLDecoder/HEAD/asset/cone_vtn_100v.stl -------------------------------------------------------------------------------- /asset/cylinder_vtn_200v.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yeuchi/STLDecoder/HEAD/asset/cylinder_vtn_200v.stl -------------------------------------------------------------------------------- /asset/sphere_vtn_32x32.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yeuchi/STLDecoder/HEAD/asset/sphere_vtn_32x32.stl -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # STLDecoder 2 | 3D format: STL file decoder for javascript \ 3 | - binary 4 | - ascii 5 | 6 | Page: https://yeuchi.github.io/STLDecoder/index.html 7 | 8 | 9 | 10 | # References 11 | 1. Wiki 12 | https://en.wikipedia.org/wiki/STL_(file_format) 13 | -------------------------------------------------------------------------------- /default.css: -------------------------------------------------------------------------------- 1 | @charset "utf-8"; 2 | /* CSS Document */ 3 | 4 | 5 | canvas { 6 | border: 1px dashed red; 7 | position:relative; 8 | left: 50; 9 | top: 20; 10 | } 11 | 12 | button { 13 | width: 200px; 14 | } 15 | 16 | #divLeft { 17 | margin-left: 160px; 18 | float: left; 19 | position:relative; 20 | top:20; 21 | left:190; 22 | } 23 | 24 | #divRight { 25 | margin-left: 20px; 26 | float: left; 27 | position:relative; 28 | top:-15; 29 | left:280; 30 | } 31 | 32 | #divCanvas { 33 | float: left; 34 | position: relative; 35 | } 36 | 37 | #divControls { 38 | margin-left: 10px; 39 | top:-450; 40 | left:470; 41 | position:relative; 42 | float: left; 43 | } 44 | 45 | 46 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 23 | 24 | 25 | STL decoder 26 | 27 | 28 | 29 | 30 | 122 | 123 | 124 | 125 |
126 |
127 | 128 | HTML5 canvas failed to load. 129 | 130 |
131 | 132 |
133 |

Javascript-STL loader
134 |
135 | Reference:
136 | (1)3D Computer Graphics - 3rd Edition by Alan Watt, pg. 5
137 | (2)STL (binary)specification
138 | (3)STL (ascii)specification
139 | (4)Devon Govett's bmp.js
140 | (5)sample models
141 |
142 | Controls:
143 | (1) Magnification (slider range: 0 - 200 in Chrome).
144 | (2) Click on an arrow to rotate 10 degrees increment.

145 |

146 | 154 |

Rotate X:

155 |

Rotate Y:

156 | 157 | Magnification:
158 |
159 |
160 |
161 | 162 | 163 |
164 | 167 |
168 | 169 |
170 | 173 |
174 | 175 | 176 | 177 | -------------------------------------------------------------------------------- /STL.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | /* 3 | # Module: STL.js 4 | # 5 | # Description: decode STL 3D file 6 | # modified Devon Govett's bmp.js 7 | # 8 | # Reference: 9 | # STL specs. http://en.wikipedia.org/wiki/STL_%28file_format%29#Binary_STL 10 | # BMP.js http://devongovett.github.com/bmp.js/ 11 | # 12 | # Author(s): Devon Govett provide a bmp decoding example. 13 | # C.T. Yeung modify to decode STL. 14 | # 15 | # History: 16 | # 20Dec11 1st crack at it cty 17 | # 23Dec11 loading vertexies OK 18 | # need to test normal when rendering shades 19 | # rotation is off when passed 180 degrees cty 20 | # 21 | # MIT LICENSE 22 | # Copyright (c) 2011 CT Yeung 23 | # Copyright (c) 2011 Devon Govett 24 | # 25 | # Permission is hereby granted, free of charge, to any person obtaining a copy of this 26 | # software and associated documentation files (the "Software"), to deal in the Software 27 | # without restriction, including without limitation the rights to use, copy, modify, merge, 28 | # publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons 29 | # to whom the Software is furnished to do so, subject to the following conditions: 30 | # 31 | # The above copyright notice and this permission notice shall be included in all copies or 32 | # substantial portions of the Software. 33 | # 34 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 35 | # BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 36 | # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 37 | # DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 38 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 39 | */ 40 | 41 | var STL; 42 | var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }; 43 | var HDR_LEN = 80; 44 | var PI = 3.14159265; 45 | 46 | STL = (function() { 47 | STL.load = function(url, callback) { 48 | var xhr; 49 | xhr = new XMLHttpRequest; 50 | xhr.open("GET", url, true); 51 | xhr.responseType = "arraybuffer"; 52 | xhr.onload = __bind(function() { 53 | var data = new Uint8Array(xhr.response || xhr.mozResponseArrayBuffer); 54 | return callback(new STL(data)); 55 | }, this); 56 | return xhr.send(null); 57 | }; 58 | 59 | function STL(data) { 60 | var HDR_LEN = 80; 61 | var hdr; 62 | this.data = data; 63 | this.TYPE_ASCII = "ascii"; 64 | this.TYPE_BINARY = "binary"; 65 | this.dataType = ""; 66 | 67 | this.ASCII_TITLE = "solid"; 68 | this.TYPE_VERTEX = "vertex"; 69 | this.TYPE_NORMAL = "normal"; 70 | this.TYPE_END = "end" 71 | this.NOT_ASCII = -1; 72 | this.listVertex = null; 73 | this.listNormal = null; 74 | 75 | if(this.data.length<(HDR_LEN+4)) 76 | throw 'STL file too small'; 77 | } 78 | 79 | STL.prototype.findEndPos = function(stt) { 80 | var i = stt; 81 | while(i<(this.data.length-1)) { 82 | // seek linefeed 83 | if(this.data[i]==10) 84 | return i; 85 | i++; 86 | } 87 | return this.data.length-1; 88 | }; 89 | 90 | STL.prototype.bin2String = function(sttPos, endPos) { 91 | var buf=""; 92 | for(var i=sttPos; i> 1; 158 | } 159 | mask = 0x80; 160 | for(var j=0; j<8; j++) { 161 | if(0!=(byteArray[2]&mask)) 162 | num += 1 / Math.pow(2, j+8); 163 | mask = mask >> 1; 164 | } 165 | mask = 0x80; 166 | for(var k=0; k<8; k++) { 167 | if(0!=(byteArray[2]&mask)) 168 | num += 1 / Math.pow(2, k+16); 169 | mask = mask >> 1; 170 | } 171 | return (num+1); 172 | }; 173 | 174 | STL.prototype.readNormal = function(index) { 175 | var sttPos = this.listNormal[index]; 176 | var endPos = this.findEndPos(sttPos); // return EOF pos if not found 177 | var vString = this.bin2String(sttPos, endPos); 178 | var pos = vString.indexOf(this.TYPE_NORMAL); 179 | vString = vString.substring(pos+this.TYPE_NORMAL.length+1, vString.length) 180 | var list = vString.split(" "); 181 | 182 | var normal = new Array(); 183 | for(var i=0; i=0) { 222 | this.dataType = this.TYPE_ASCII; 223 | this.listVertex = new Array(); 224 | this.listNormal = new Array(); 225 | 226 | while(endPos < (this.data.length-1)) { 227 | endPos = this.findEndPos(sttPos); // return EOF pos if not found 228 | str = this.bin2String(sttPos, endPos); 229 | 230 | if(str.indexOf(this.TYPE_VERTEX)>=0) 231 | this.listVertex.push(sttPos); 232 | 233 | else if(str.indexOf(this.TYPE_NORMAL)>=0) 234 | this.listNormal.push(sttPos); 235 | 236 | sttPos = endPos+1; 237 | } 238 | } 239 | else 240 | this.dataType = this.TYPE_BINARY; 241 | 242 | return this.dataType; 243 | }; 244 | 245 | STL.prototype.drawWireFrame = function(context, // [in] canvas context 246 | w, // [in] canvas width 247 | h, // [in] canvas height 248 | mag, // [in] magnification 249 | rX, 250 | rY, 251 | rZ) { 252 | var numTriangles; 253 | var i; 254 | 255 | if(this.dataType==this.TYPE_BINARY){ 256 | this.pos = HDR_LEN; 257 | numTriangles = this.readUInt32(); 258 | } 259 | else 260 | numTriangles = this.listVertex.length/3; 261 | 262 | if(this.dataType==this.TYPE_BINARY) { 263 | for(i=0; i