提交 f41b02ed 编写于 作者: M Mr.doob

STLLoader: Some clean up.

上级 a73d7924
var Loader = function ( signals ) {
scope = this;
scope = this;
var sceneExporter = new THREE.ObjectExporter();
var sceneExporter = new THREE.ObjectExporter();
document.addEventListener( 'dragover', function ( event ) {
document.addEventListener( 'dragover', function ( event ) {
event.preventDefault();
event.dataTransfer.dropEffect = 'copy';
event.preventDefault();
event.dataTransfer.dropEffect = 'copy';
}, false );
}, false );
document.addEventListener( 'drop', function ( event ) {
document.addEventListener( 'drop', function ( event ) {
event.preventDefault();
event.preventDefault();
var file = event.dataTransfer.files[ 0 ];
var file = event.dataTransfer.files[ 0 ];
var chunks = file.name.split( '.' );
var extension = chunks.pop().toLowerCase();
var filename = chunks.join( '.' );
var chunks = file.name.split( '.' );
var extension = chunks.pop().toLowerCase();
var filename = chunks.join( '.' );
scope.parseFile( file, filename, extension );
scope.parseFile( file, filename, extension );
}, false );
}, false );
var timeout;
var timeout;
signals.sceneChanged.add( function ( scene ) {
signals.sceneChanged.add( function ( scene ) {
clearTimeout( timeout );
clearTimeout( timeout );
timeout = setTimeout( function () {
timeout = setTimeout( function () {
scope.saveLocalStorage( scene );
scope.saveLocalStorage( scene );
}, 3000 );
}, 3000 );
} );
} );
this.loadLocalStorage = function() {
this.loadLocalStorage = function() {
if ( localStorage.threejsEditor !== undefined ) {
if ( localStorage.threejsEditor !== undefined ) {
var loader = new THREE.ObjectLoader();
var scene = loader.parse( JSON.parse( localStorage.threejsEditor ) );
var loader = new THREE.ObjectLoader();
var scene = loader.parse( JSON.parse( localStorage.threejsEditor ) );
signals.sceneAdded.dispatch( scene );
signals.sceneAdded.dispatch( scene );
}
}
};
};
this.saveLocalStorage = function ( scene ) {
this.saveLocalStorage = function ( scene ) {
localStorage.threejsEditor = JSON.stringify( sceneExporter.parse( scene ) );
localStorage.threejsEditor = JSON.stringify( sceneExporter.parse( scene ) );
}
}
this.handleJSON = function ( data ) {
this.handleJSON = function ( data ) {
if ( data.metadata === undefined ) { // 2.0
if ( data.metadata === undefined ) { // 2.0
data.metadata = { type: 'geometry' };
data.metadata = { type: 'geometry' };
}
}
if ( data.metadata.type === undefined ) { // 3.0
if ( data.metadata.type === undefined ) { // 3.0
data.metadata.type = 'geometry';
data.metadata.type = 'geometry';
}
}
if ( data.metadata.version === undefined ) {
if ( data.metadata.version === undefined ) {
data.metadata.version = data.metadata.formatVersion;
data.metadata.version = data.metadata.formatVersion;
}
}
if ( data.metadata.type === 'geometry' ) {
if ( data.metadata.type === 'geometry' ) {
var loader = new THREE.JSONLoader();
var result = loader.parse( data );
var loader = new THREE.JSONLoader();
var result = loader.parse( data );
var geometry = result.geometry;
var material = result.materials !== undefined
? new THREE.MeshFaceMaterial( result.materials )
: new THREE.MeshPhongMaterial();
var geometry = result.geometry;
var material = result.materials !== undefined
? new THREE.MeshFaceMaterial( result.materials )
: new THREE.MeshPhongMaterial();
geometry.sourceType = "ascii";
geometry.sourceFile = file.name;
geometry.sourceType = "ascii";
geometry.sourceFile = file.name;
var mesh = new THREE.Mesh( geometry, material );
mesh.name = filename;
var mesh = new THREE.Mesh( geometry, material );
mesh.name = filename;
signals.objectAdded.dispatch( mesh );
signals.objectSelected.dispatch( mesh );
signals.objectAdded.dispatch( mesh );
signals.objectSelected.dispatch( mesh );
} else if ( data.metadata.type === 'object' ) {
} else if ( data.metadata.type === 'object' ) {
var loader = new THREE.ObjectLoader();
var result = loader.parse( data );
var loader = new THREE.ObjectLoader();
var result = loader.parse( data );
if ( result instanceof THREE.Scene ) {
if ( result instanceof THREE.Scene ) {
signals.sceneAdded.dispatch( result );
signals.sceneAdded.dispatch( result );
} else {
} else {
signals.objectAdded.dispatch( result );
signals.objectAdded.dispatch( result );
}
}
} else if ( data.metadata.type === 'scene' ) {
} else if ( data.metadata.type === 'scene' ) {
// DEPRECATED
// DEPRECATED
var loader = new THREE.SceneLoader();
loader.parse( data, function ( result ) {
var loader = new THREE.SceneLoader();
loader.parse( data, function ( result ) {
var scene = result.scene;
var scene = result.scene;
while ( scene.children.length > 0 ) {
while ( scene.children.length > 0 ) {
signals.objectAdded.dispatch( scene.children[ 0 ] );
signals.objectAdded.dispatch( scene.children[ 0 ] );
}
}
}, '' );
}, '' );
}
}
};
};
this.parseFile = function ( file, filename, extension ) {
this.parseFile = function ( file, filename, extension ) {
switch ( extension ) {
switch ( extension ) {
case 'ctm':
case 'ctm':
var reader = new FileReader();
reader.addEventListener( 'load', function ( event ) {
var reader = new FileReader();
reader.addEventListener( 'load', function ( event ) {
var contents = event.target.result;
var contents = event.target.result;
var stream = new CTM.Stream( contents );
stream.offset = 0;
var stream = new CTM.Stream( contents );
stream.offset = 0;
var loader = new THREE.CTMLoader();
loader.createModelClassic( new CTM.File( stream ), function( geometry ) {
var loader = new THREE.CTMLoader();
loader.createModelClassic( new CTM.File( stream ), function( geometry ) {
geometry.sourceType = "ctm";
geometry.sourceFile = file.name;
geometry.sourceType = "ctm";
geometry.sourceFile = file.name;
var material = new THREE.MeshPhongMaterial();
var material = new THREE.MeshPhongMaterial();
var mesh = new THREE.Mesh( geometry, material );
mesh.name = filename;
var mesh = new THREE.Mesh( geometry, material );
mesh.name = filename;
signals.objectAdded.dispatch( mesh );
signals.objectSelected.dispatch( mesh );
signals.objectAdded.dispatch( mesh );
signals.objectSelected.dispatch( mesh );
} );
} );
}, false );
reader.readAsBinaryString( file );
}, false );
reader.readAsBinaryString( file );
break;
break;
case 'dae':
case 'dae':
var reader = new FileReader();
reader.addEventListener( 'load', function ( event ) {
var reader = new FileReader();
reader.addEventListener( 'load', function ( event ) {
var contents = event.target.result;
var contents = event.target.result;
var parser = new DOMParser();
var xml = parser.parseFromString( contents, 'text/xml' );
var parser = new DOMParser();
var xml = parser.parseFromString( contents, 'text/xml' );
var loader = new THREE.ColladaLoader();
loader.parse( xml, function ( collada ) {
var loader = new THREE.ColladaLoader();
loader.parse( xml, function ( collada ) {
collada.scene.name = filename;
collada.scene.name = filename;
signals.objectAdded.dispatch( collada.scene );
signals.objectSelected.dispatch( collada.scene );
signals.objectAdded.dispatch( collada.scene );
signals.objectSelected.dispatch( collada.scene );
} );
} );
}, false );
reader.readAsText( file );
}, false );
reader.readAsText( file );
break;
break;
case 'js':
case 'json':
case 'js':
case 'json':
var reader = new FileReader();
reader.addEventListener( 'load', function ( event ) {
var reader = new FileReader();
reader.addEventListener( 'load', function ( event ) {
var contents = event.target.result;
var contents = event.target.result;
// 2.0
// 2.0
if ( contents.indexOf( 'postMessage' ) !== -1 ) {
if ( contents.indexOf( 'postMessage' ) !== -1 ) {
var blob = new Blob( [ contents ], { type: 'text/javascript' } );
var url = URL.createObjectURL( blob );
var blob = new Blob( [ contents ], { type: 'text/javascript' } );
var url = URL.createObjectURL( blob );
var worker = new Worker( url );
var worker = new Worker( url );
worker.onmessage = function ( event ) {
worker.onmessage = function ( event ) {
event.data.metadata = { version: 2 };
scope.handleJSON( event.data );
event.data.metadata = { version: 2 };
scope.handleJSON( event.data );
};
};
worker.postMessage( Date.now() );
worker.postMessage( Date.now() );
return;
return;
}
}
// >= 3.0
// >= 3.0
var data;
var data;
try {
try {
data = JSON.parse( contents );
data = JSON.parse( contents );
} catch ( error ) {
} catch ( error ) {
alert( error );
return;
alert( error );
return;
}
}
scope.handleJSON( data );
scope.handleJSON( data );
}, false );
reader.readAsText( file );
}, false );
reader.readAsText( file );
break;
break;
case 'obj':
case 'obj':
var reader = new FileReader();
reader.addEventListener( 'load', function ( event ) {
var reader = new FileReader();
reader.addEventListener( 'load', function ( event ) {
var contents = event.target.result;
var contents = event.target.result;
var object = new THREE.OBJLoader().parse( contents );
object.name = filename;
var object = new THREE.OBJLoader().parse( contents );
object.name = filename;
signals.objectAdded.dispatch( object );
signals.objectSelected.dispatch( object );
signals.objectAdded.dispatch( object );
signals.objectSelected.dispatch( object );
}, false );
reader.readAsText( file );
}, false );
reader.readAsText( file );
break;
break;
case 'ply':
case 'ply':
var reader = new FileReader();
reader.addEventListener( 'load', function ( event ) {
var reader = new FileReader();
reader.addEventListener( 'load', function ( event ) {
var contents = event.target.result;
var contents = event.target.result;
console.log( contents );
console.log( contents );
var geometry = new THREE.PLYLoader().parse( contents );
geometry.sourceType = "ply";
geometry.sourceFile = file.name;
var geometry = new THREE.PLYLoader().parse( contents );
geometry.sourceType = "ply";
geometry.sourceFile = file.name;
var material = new THREE.MeshPhongMaterial();
var material = new THREE.MeshPhongMaterial();
var mesh = new THREE.Mesh( geometry, material );
mesh.name = filename;
var mesh = new THREE.Mesh( geometry, material );
mesh.name = filename;
signals.objectAdded.dispatch( mesh );
signals.objectSelected.dispatch( mesh );
signals.objectAdded.dispatch( mesh );
signals.objectSelected.dispatch( mesh );
}, false );
reader.readAsText( file );
}, false );
reader.readAsText( file );
break;
break;
case 'stl':
case 'stl':
var reader = new FileReader();
reader.addEventListener( 'load', function ( event ) {
var reader = new FileReader();
reader.addEventListener( 'load', function ( event ) {
var contents = event.target.result;
var contents = event.target.result;
var geometry = new THREE.STLLoader().parse( contents );
geometry.sourceType = "stl";
geometry.sourceFile = file.name;
var geometry = new THREE.STLLoader().parse( contents );
geometry.sourceType = "stl";
geometry.sourceFile = file.name;
var material = new THREE.MeshPhongMaterial();
var material = new THREE.MeshPhongMaterial();
var mesh = new THREE.Mesh( geometry, material );
mesh.name = filename;
var mesh = new THREE.Mesh( geometry, material );
mesh.name = filename;
signals.objectAdded.dispatch( mesh );
signals.objectSelected.dispatch( mesh );
signals.objectAdded.dispatch( mesh );
signals.objectSelected.dispatch( mesh );
}, false );
if (reader.readAsBinaryString) {
}, false );
reader.readAsBinaryStrings(file);
if ( reader.readAsBinaryString !== undefined ) {
} else {
reader.readAsArrayBuffer(file);
}
break;
reader.readAsBinaryString( file );
/*
case 'utf8':
} else {
var reader = new FileReader();
reader.addEventListener( 'load', function ( event ) {
reader.readAsArrayBuffer( file );
var contents = event.target.result;
}
var geometry = new THREE.UTF8Loader().parse( contents );
var material = new THREE.MeshLambertMaterial();
break;
var mesh = new THREE.Mesh( geometry, material );
/*
case 'utf8':
signals.objectAdded.dispatch( mesh );
signals.objectSelected.dispatch( mesh );
var reader = new FileReader();
reader.addEventListener( 'load', function ( event ) {
}, false );
reader.readAsBinaryString( file );
var contents = event.target.result;
break;
*/
var geometry = new THREE.UTF8Loader().parse( contents );
var material = new THREE.MeshLambertMaterial();
case 'vtk':
var mesh = new THREE.Mesh( geometry, material );
var reader = new FileReader();
reader.addEventListener( 'load', function ( event ) {
signals.objectAdded.dispatch( mesh );
signals.objectSelected.dispatch( mesh );
var contents = event.target.result;
}, false );
reader.readAsBinaryString( file );
var geometry = new THREE.VTKLoader().parse( contents );
geometry.sourceType = "vtk";
geometry.sourceFile = file.name;
break;
*/
var material = new THREE.MeshPhongMaterial();
case 'vtk':
var mesh = new THREE.Mesh( geometry, material );
mesh.name = filename;
var reader = new FileReader();
reader.addEventListener( 'load', function ( event ) {
signals.objectAdded.dispatch( mesh );
signals.objectSelected.dispatch( mesh );
var contents = event.target.result;
}, false );
reader.readAsText( file );
var geometry = new THREE.VTKLoader().parse( contents );
geometry.sourceType = "vtk";
geometry.sourceFile = file.name;
break;
var material = new THREE.MeshPhongMaterial();
}
var mesh = new THREE.Mesh( geometry, material );
mesh.name = filename;
}
signals.objectAdded.dispatch( mesh );
signals.objectSelected.dispatch( mesh );
}
\ No newline at end of file
}, false );
reader.readAsText( file );
break;
}
}
}
......@@ -7,9 +7,10 @@
*
* Supports both binary and ASCII encoded files, with automatic detection of type.
*
* Limitations: Binary decoding ignores header. There doesn't seem to be much of a use for it.
* There is perhaps some question as to how valid it is to always assume little-endian-ness.
* ASCII decoding assumes file is UTF-8. Seems to work for the examples...
* Limitations:
* Binary decoding ignores header. There doesn't seem to be much of a use for it.
* There is perhaps some question as to how valid it is to always assume little-endian-ness.
* ASCII decoding assumes file is UTF-8. Seems to work for the examples...
*
* Usage:
* var loader = new THREE.STLLoader();
......@@ -95,39 +96,44 @@ THREE.STLLoader.prototype.parse = function (data) {
return expect === reader.byteLength;
};
var binData = this.ensureBinary(data);
if (isBinary()) {
var binData = this.ensureBinary( data );
return this.parseBinary(binData);
return isBinary()
? this.parseBinary( binData )
: this.parseASCII( this.ensureString( data ) );
} else {
return this.parseASCII(this.ensureString(data));
}
};
THREE.STLLoader.prototype.parseBinary = function (data) {
var face, geometry, n_faces, reader, length, normal, i, dataOffset, faceLength, start, vertexstart;
reader = new DataView( data );
n_faces = reader.getUint32(80,true);
geometry = new THREE.Geometry();
dataOffset = 84;
dataOffset = 84;
faceLength = 12 * 4 + 2;
for (face = 0; face < n_faces; face++) {
start = dataOffset + face * faceLength;
normal = new THREE.Vector3(reader.getFloat32(start,true),reader.getFloat32(start + 4,true),reader.getFloat32(start + 8,true));
start = dataOffset + face * faceLength;
normal = new THREE.Vector3(
reader.getFloat32(start,true),
reader.getFloat32(start + 4,true),
reader.getFloat32(start + 8,true)
);
for (i = 1; i <= 3; i++) {
vertexstart = start + i * 12;
geometry.vertices.push(new THREE.Vector3(reader.getFloat32(vertexstart,true),reader.getFloat32(vertexstart +4,true),reader.getFloat32(vertexstart + 8,true)));
vertexstart = start + i * 12;
geometry.vertices.push(
new THREE.Vector3(
reader.getFloat32(vertexstart,true),
reader.getFloat32(vertexstart +4,true),
reader.getFloat32(vertexstart + 8,true)
)
);
}
......@@ -138,7 +144,7 @@ THREE.STLLoader.prototype.parseBinary = function (data) {
geometry.computeCentroids();
geometry.computeBoundingSphere();
return geometry;
};
......@@ -182,7 +188,7 @@ THREE.STLLoader.prototype.parseASCII = function (data) {
};
THREE.STLLoader.prototype.ensureString = function (buf) {
if (typeof buf !== "string"){
var array_buffer = new Uint8Array(buf);
var str = '';
......@@ -195,8 +201,9 @@ THREE.STLLoader.prototype.ensureString = function (buf) {
}
};
THREE.STLLoader.prototype.ensureBinary = function (buf) {
if (typeof buf === "string"){
var array_buffer = new Uint8Array(buf.length);
for(var i = 0; i < buf.length; i++) {
......@@ -210,16 +217,18 @@ THREE.STLLoader.prototype.ensureBinary = function (buf) {
};
if ( typeof DataView === 'undefined'){
DataView = function(buffer, byteOffset, byteLength){
this.buffer = buffer;
this.byteOffset = byteOffset || 0;
this.byteLength = byteLength || buffer.byteLength || buffer.length;
this._isString = typeof buffer === "string";
}
DataView.prototype = {
DataView = function(buffer, byteOffset, byteLength){
this.buffer = buffer;
this.byteOffset = byteOffset || 0;
this.byteLength = byteLength || buffer.byteLength || buffer.length;
this._isString = typeof buffer === "string";
}
DataView.prototype = {
_getCharCodes:function(buffer,start,length){
start = start || 0;
length = length || buffer.length;
......@@ -230,63 +239,86 @@ if ( typeof DataView === 'undefined'){
}
return codes;
},
_getBytes: function (length, byteOffset, littleEndian) {
_getBytes: function (length, byteOffset, littleEndian) {
var result;
// Handle the lack of endianness
if (littleEndian === undefined) {
littleEndian = this._littleEndian;
}
// Handle the lack of byteOffset
if (byteOffset === undefined) {
byteOffset = this.byteOffset;
} else {
byteOffset = this.byteOffset + byteOffset;
}
if (length === undefined) {
length = this.byteLength - byteOffset;
}
// Error Checking
if (typeof byteOffset !== 'number') {
throw new TypeError('DataView byteOffset is not a number');
}
if (length < 0 || byteOffset + length > this.byteLength) {
throw new Error('DataView length or (byteOffset+length) value is out of bounds');
}
if (this.isString){
result = this._getCharCodes(this.buffer, byteOffset, byteOffset + length);
} else {
result = this.buffer.slice(byteOffset, byteOffset + length);
}
if (!littleEndian && length > 1) {
if (!(result instanceof Array)) {
result = Array.prototype.slice.call(result);
}
result.reverse();
}
return result;
},
// Compatibility functions on a String Buffer
getFloat64: function (byteOffset, littleEndian) {
var b = this._getBytes(8, byteOffset, littleEndian),
sign = 1 - (2 * (b[7] >> 7)),
exponent = ((((b[7] << 1) & 0xff) << 3) | (b[6] >> 4)) - ((1 << 10) - 1),
// Binary operators such as | and << operate on 32 bit values, using + and Math.pow(2) instead
mantissa = ((b[6] & 0x0f) * Math.pow(2, 48)) + (b[5] * Math.pow(2, 40)) + (b[4] * Math.pow(2, 32)) +
(b[3] * Math.pow(2, 24)) + (b[2] * Math.pow(2, 16)) + (b[1] * Math.pow(2, 8)) + b[0];
if (exponent === 1024) {
if (mantissa !== 0) {
return NaN;
......@@ -294,21 +326,23 @@ if ( typeof DataView === 'undefined'){
return sign * Infinity;
}
}
if (exponent === -1023) { // Denormalized
return sign * mantissa * Math.pow(2, -1022 - 52);
}
return sign * (1 + mantissa * Math.pow(2, -52)) * Math.pow(2, exponent);
},
getFloat32: function (byteOffset, littleEndian) {
var b = this._getBytes(4, byteOffset, littleEndian),
sign = 1 - (2 * (b[3] >> 7)),
exponent = (((b[3] << 1) & 0xff) | (b[2] >> 7)) - 127,
mantissa = ((b[2] & 0x7f) << 16) | (b[1] << 8) | b[0];
if (exponent === 128) {
if (mantissa !== 0) {
return NaN;
......@@ -316,38 +350,40 @@ if ( typeof DataView === 'undefined'){
return sign * Infinity;
}
}
if (exponent === -127) { // Denormalized
return sign * mantissa * Math.pow(2, -126 - 23);
}
return sign * (1 + mantissa * Math.pow(2, -23)) * Math.pow(2, exponent);
},
getInt32: function (byteOffset, littleEndian) {
var b = this._getBytes(4, byteOffset, littleEndian);
return (b[3] << 24) | (b[2] << 16) | (b[1] << 8) | b[0];
},
getUint32: function (byteOffset, littleEndian) {
return this.getInt32(byteOffset, littleEndian) >>> 0;
},
getInt16: function (byteOffset, littleEndian) {
return (this.getUint16(byteOffset, littleEndian) << 16) >> 16;
},
getUint16: function (byteOffset, littleEndian) {
var b = this._getBytes(2, byteOffset, littleEndian);
return (b[1] << 8) | b[0];
},
getInt8: function (byteOffset) {
return (this.getUint8(byteOffset) << 24) >> 24;
},
getUint8: function (byteOffset) {
return this._getBytes(1, byteOffset)[0];
}
};
};
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册