From 9ad3cd6b4a43e5e41d8f3dc36820fb1e8dbcdbf2 Mon Sep 17 00:00:00 2001 From: Alex Weiss Date: Fri, 8 Nov 2013 16:50:32 -0500 Subject: [PATCH] PlyLoader: Added support for binary ply files. --- examples/js/loaders/PLYLoader.js | 158 ++++++++++++++++----- examples/models/ply/binary/dolphins_be.ply | Bin 0 -> 32388 bytes examples/models/ply/binary/dolphins_le.ply | Bin 0 -> 32391 bytes 3 files changed, 124 insertions(+), 34 deletions(-) create mode 100644 examples/models/ply/binary/dolphins_be.ply create mode 100644 examples/models/ply/binary/dolphins_le.ply diff --git a/examples/js/loaders/PLYLoader.js b/examples/js/loaders/PLYLoader.js index 0c8f19d8d3..721f46b79a 100644 --- a/examples/js/loaders/PLYLoader.js +++ b/examples/js/loaders/PLYLoader.js @@ -70,11 +70,10 @@ THREE.PLYLoader.prototype = { }, - isASCII: function(buf){ + isASCII: function( data ){ - var header = this.parseHeader( buf ); + var header = this.parseHeader( this.bin2str( data ) ); - // currently only supports ASCII encoded files. return header.format === "ascii"; }, @@ -83,7 +82,7 @@ THREE.PLYLoader.prototype = { if ( data instanceof ArrayBuffer ) { - return this.isASCII( this.bin2str( data ) ) + return this.isASCII( data ) ? this.parseASCII( this.bin2str( data ) ) : this.parseBinary( data ); @@ -97,7 +96,7 @@ THREE.PLYLoader.prototype = { parseHeader: function ( data ) { - var patternHeader = /ply([\s\S]*)end_header/; + var patternHeader = /ply([\s\S]*)end_header\n/; var headerText = ""; if ( ( result = patternHeader.exec( data ) ) != null ) { headerText = result [ 1 ]; @@ -106,6 +105,7 @@ THREE.PLYLoader.prototype = { var header = new Object(); header.comments = []; header.elements = []; + header.headerLength = result[0].length; var lines = headerText.split( '\n' ); var currentElement = undefined; @@ -250,7 +250,7 @@ THREE.PLYLoader.prototype = { var lines = body.split( '\n' ); var currentElement = 0; var currentElementCount = 0; - var useColor = false; + geometry.useColor = false; for ( var i = 0; i < lines.length; i ++ ) { @@ -267,35 +267,19 @@ THREE.PLYLoader.prototype = { var element = this.parseASCIIElement( header.elements[currentElement].properties, line ); - if ( header.elements[currentElement].name === "vertex" ) { - - geometry.vertices.push( - new THREE.Vector3( element.x, element.y, element.z ) - ); - - if ( 'red' in element && 'green' in element && 'blue' in element ) { - - useColor = true; - - color = new THREE.Color(); - color.setRGB( element.red / 255.0, element.green / 255.0, element.blue / 255.0 ); - geometry.colors.push( color ); - - } - - } else if ( header.elements[currentElement].name === "face" ) { - - geometry.faces.push( - new THREE.Face3( element.vertex_indices[0], element.vertex_indices[1], element.vertex_indices[2] ) - ); - - } + this.handleElement( geometry, header.elements[currentElement].name, element ); currentElementCount++; } - if ( useColor ) { + return this.postProcess( geometry ); + + }, + + postProcess: function ( geometry ) { + + if ( geometry.useColor ) { for ( var i = 0; i < geometry.faces.length; i ++ ) { @@ -315,14 +299,120 @@ THREE.PLYLoader.prototype = { geometry.computeBoundingSphere(); return geometry; + + }, - }, + handleElement: function ( geometry, elementName, element ) { + + if ( elementName === "vertex" ) { + + geometry.vertices.push( + new THREE.Vector3( element.x, element.y, element.z ) + ); + + if ( 'red' in element && 'green' in element && 'blue' in element ) { + + geometry.useColor = true; + + color = new THREE.Color(); + color.setRGB( element.red / 255.0, element.green / 255.0, element.blue / 255.0 ); + geometry.colors.push( color ); + + } + + } else if ( elementName === "face" ) { + + geometry.faces.push( + new THREE.Face3( element.vertex_indices[0], element.vertex_indices[1], element.vertex_indices[2] ) + ); + + } + + }, + + binaryRead: function ( dataview, at, type, little_endian ) { + + switch( type ) { + + // corespondences for non-specific length types here match rply: + case 'int8': case 'char': return [ dataview.getInt8( at ), 1 ]; + case 'uint8': case 'uchar': return [ dataview.getUint8( at ), 1 ]; + case 'int16': case 'short': return [ dataview.getInt16( at, little_endian ), 2 ]; + case 'uint16': case 'ushort': return [ dataview.getUint16( at, little_endian ), 2 ]; + case 'int32': case 'int': return [ dataview.getInt32( at, little_endian ), 4 ]; + case 'uint32': case 'uint': return [ dataview.getUint32( at, little_endian ), 4 ]; + case 'float32': case 'float': return [ dataview.getFloat32( at, little_endian ), 4 ]; + case 'float64': case 'double': return [ dataview.getFloat64( at, little_endian ), 8 ]; + + } + + }, - parseBinary: function (buf) { + binaryReadElement: function ( dataview, at, properties, little_endian ) { + + var element = Object(); + var result, read = 0; + + for ( var i = 0; i < properties.length; i ++ ) { + + if ( properties[i].type === "list" ) { + + var list = []; + + result = this.binaryRead( dataview, at+read, properties[i].countType, little_endian ); + var n = result[0]; + read += result[1]; + + for ( j = 0; j < n; j ++ ) { + + result = this.binaryRead( dataview, at+read, properties[i].itemType, little_endian ); + list.push( result[0] ); + read += result[1]; + + } + + element[ properties[i].name ] = list; + + } else { + + result = this.binaryRead( dataview, at+read, properties[i].type, little_endian ); + element[ properties[i].name ] = result[0]; + read += result[1]; + + } + + } + + return [ element, read ]; + + }, + + parseBinary: function ( data ) { - // not supported yet - console.error('Not supported yet.'); + var geometry = new THREE.Geometry(); + var header = this.parseHeader( this.bin2str( data ) ); + var little_endian = (header.format === "binary_little_endian"); + + var body = new DataView( data, header.headerLength ); + + var result, loc = 0; + for ( var currentElement = 0; currentElement < header.elements.length; currentElement ++ ) { + + for ( var currentElementCount = 0; currentElementCount < header.elements[currentElement].count; currentElementCount ++ ) { + + result = this.binaryReadElement( body, loc, header.elements[currentElement].properties, little_endian ); + loc += result[1]; + var element = result[0]; + + this.handleElement( geometry, header.elements[currentElement].name, element ); + + } + + } + + return this.postProcess( geometry ); + } diff --git a/examples/models/ply/binary/dolphins_be.ply b/examples/models/ply/binary/dolphins_be.ply new file mode 100644 index 0000000000000000000000000000000000000000..1e65c7c243679d4f60ce270f3cbbf8ae52d92afc GIT binary patch literal 32388 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 b@ee47-~RrKxSSdvFO(JhuL$=mGD`S=^H^b5 literal 0 HcmV?d00001 -- GitLab