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

Merge pull request #8208 from stity/binaryVTKLoader

Binary VTK parser and support for triangle strip
......@@ -3,7 +3,7 @@
* @author Alex Pletzer
*/
THREE.VTKLoader = function ( manager ) {
THREE.VTKLoader = function( manager ) {
this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
......@@ -13,22 +13,40 @@ THREE.VTKLoader.prototype = {
constructor: THREE.VTKLoader,
load: function ( url, onLoad, onProgress, onError ) {
load: function( url, onLoad, onProgress, onError ) {
// Will we bump into trouble reading the whole file into memory?
var scope = this;
var loader = new THREE.XHRLoader( scope.manager );
loader.load( url, function ( text ) {
loader.setResponseType( 'arraybuffer' );
loader.load( url, function( text ) {
onLoad( scope.parse( text ) );
},
onProgress, onError );
onProgress, onError );
},
parse: function ( data ) {
parse: function( data ) {
//get the 5 first lines of the files to check if there is the key word binary
var meta = String.fromCharCode.apply( null, new Uint8Array( data, 0, 250 ) ).split( '\n' );
console.log( meta );
if ( meta[ 2 ] === 'ASCII' ) {
return this.parseASCII( String.fromCharCode.apply( null, new Uint8Array( data ) ) );
} else {
return this.parseBinary( data );
}
},
parseASCII: function( data ) {
// connectivity of the triangles
var indices = [];
......@@ -57,6 +75,9 @@ THREE.VTKLoader.prototype = {
// indicates start of polygon connectivity section
var patPOLYGONS = /^POLYGONS /;
// indicates start of triangle strips section
var patTRIANGLE_STRIPS = /^TRIANGLE_STRIPS /;
// POINT_DATA number_of_values
var patPOINT_DATA = /^POINT_DATA[ ]+(\d+)/;
......@@ -71,6 +92,7 @@ THREE.VTKLoader.prototype = {
var inPointsSection = false;
var inPolygonsSection = false;
var inTriangleStripSection = false;
var inPointDataSection = false;
var inCellDataSection = false;
var inColorSection = false;
......@@ -111,7 +133,7 @@ THREE.VTKLoader.prototype = {
for ( var j = 0; j < numVertices - 2; ++ j ) {
i1 = parseInt( inds[ k ] );
i2 = parseInt( inds[ k + 1 ] );
i2 = parseInt( inds[ k + 1 ] );
indices.push( i0, i1, i2 );
k ++;
......@@ -121,6 +143,42 @@ THREE.VTKLoader.prototype = {
}
} else if ( inTriangleStripSection ) {
if ( ( result = patConnectivity.exec( line ) ) !== null ) {
// numVertices i0 i1 i2 ...
var numVertices = parseInt( result[ 1 ] );
var inds = result[ 2 ].split( /\s+/ );
if ( numVertices >= 3 ) {
var i0, i1, i2;
// split the polygon in numVertices - 2 triangles
for ( var j = 0; j < numVertices - 2; j ++ ) {
if ( j % 2 === 1 ) {
i0 = parseInt( inds[ j ] );
i1 = parseInt( inds[ j + 2 ] );
i2 = parseInt( inds[ j + 1 ] );
indices.push( i0, i1, i2 );
} else {
i0 = parseInt( inds[ j ] );
i1 = parseInt( inds[ j + 1 ] );
i2 = parseInt( inds[ j + 2 ] );
indices.push( i0, i1, i2 );
}
}
}
}
} else if ( inPointDataSection || inCellDataSection ) {
if ( inColorSection ) {
......@@ -157,23 +215,33 @@ THREE.VTKLoader.prototype = {
inPolygonsSection = true;
inPointsSection = false;
inTriangleStripSection = false;
} else if ( patPOINTS.exec( line ) !== null ) {
inPolygonsSection = false;
inPointsSection = true;
inTriangleStripSection = false;
} else if ( patTRIANGLE_STRIPS.exec( line ) !== null ) {
inPolygonsSection = false;
inPointsSection = false;
inTriangleStripSection = true;
} else if ( patPOINT_DATA.exec( line ) !== null ) {
inPointDataSection = true;
inPointsSection = false;
inPolygonsSection = false;
inTriangleStripSection = false;
} else if ( patCELL_DATA.exec( line ) !== null ) {
inCellDataSection = true;
inPointsSection = false;
inPolygonsSection = false;
inTriangleStripSection = false;
} else if ( patCOLOR_SCALARS.exec( line ) !== null ) {
......@@ -181,6 +249,7 @@ THREE.VTKLoader.prototype = {
inNormalsSection = false;
inPointsSection = false;
inPolygonsSection = false;
inTriangleStripSection = false;
} else if ( patNORMALS.exec( line ) !== null ) {
......@@ -188,6 +257,7 @@ THREE.VTKLoader.prototype = {
inColorSection = false;
inPointsSection = false;
inPolygonsSection = false;
inTriangleStripSection = false;
}
......@@ -265,10 +335,214 @@ THREE.VTKLoader.prototype = {
}
}
}
}
return geometry;
},
parseBinary: function( data ) {
var count, pointIndex, i, numberOfPoints, pt, s;
var buffer = new Uint8Array ( data );
var dataView = new DataView ( data );
// Points and normals, by default, are empty
var points = [];
var normals = [];
var indices = [];
// Going to make a big array of strings
var vtk = [];
var index = 0;
var findString = function( buffer, start ) {
var index = start;
var c = buffer[ index ];
var s = [];
while ( c != 10 ) {
s.push ( String.fromCharCode ( c ) );
index ++;
c = buffer[ index ];
}
return { start: start,
end: index,
next: index + 1,
parsedString: s.join( '' ) };
}
var state, line;
while ( true ) {
// Get a string
state = findString ( buffer, index );
line = state.parsedString;
if ( line.indexOf ( "POINTS" ) == 0 ) {
vtk.push ( line );
// Add the points
numberOfPoints = parseInt ( line.split( " " )[ 1 ], 10 );
// Each point is 3 4-byte floats
count = numberOfPoints * 4 * 3;
points = new Float32Array( numberOfPoints * 3 );
pointIndex = state.next;
for ( i = 0; i < numberOfPoints; i ++ ) {
points[ 3 * i ] = dataView.getFloat32( pointIndex, false );
points[ 3 * i + 1 ] = dataView.getFloat32( pointIndex + 4, false );
points[ 3 * i + 2 ] = dataView.getFloat32( pointIndex + 8, false );
pointIndex = pointIndex + 12;
}
// increment our next pointer
state.next = state.next + count + 1;
} else if ( line.indexOf ( "TRIANGLE_STRIPS" ) === 0 ) {
var numberOfStrips = parseInt ( line.split( " " )[ 1 ], 10 );
var size = parseInt ( line.split ( " " )[ 2 ], 10 );
// 4 byte integers
count = size * 4;
indices = new Uint32Array( 3 * size - 9 * numberOfStrips );
var indicesIndex = 0;
pointIndex = state.next;
for ( i = 0; i < numberOfStrips; i ++ ) {
// For each strip, read the first value, then record that many more points
var indexCount = dataView.getInt32( pointIndex, false );
var strip = [];
pointIndex += 4;
for ( s = 0; s < indexCount; s ++ ) {
strip.push ( dataView.getInt32( pointIndex, false ) );
pointIndex += 4;
}
// retrieves the n-2 triangles from the triangle strip
for ( var j = 0; j < indexCount - 2; j ++ ) {
if ( j % 2 ) {
indices[ indicesIndex ++ ] = strip[ j ];
indices[ indicesIndex ++ ] = strip[ j + 2 ];
indices[ indicesIndex ++ ] = strip[ j + 1 ];
} else {
indices[ indicesIndex ++ ] = strip[ j ];
indices[ indicesIndex ++ ] = strip[ j + 1 ];
indices[ indicesIndex ++ ] = strip[ j + 2 ];
}
}
}
// increment our next pointer
state.next = state.next + count + 1;
} else if ( line.indexOf ( "POLYGONS" ) === 0 ) {
var numberOfStrips = parseInt ( line.split( " " )[ 1 ], 10 );
var size = parseInt ( line.split ( " " )[ 2 ], 10 );
// 4 byte integers
count = size * 4;
indices = new Uint32Array( 3 * size - 9 * numberOfStrips );
var indicesIndex = 0;
pointIndex = state.next;
for ( i = 0; i < numberOfStrips; i ++ ) {
// For each strip, read the first value, then record that many more points
var indexCount = dataView.getInt32( pointIndex, false );
var strip = [];
pointIndex += 4;
for ( s = 0; s < indexCount; s ++ ) {
strip.push ( dataView.getInt32( pointIndex, false ) );
pointIndex += 4;
}
var i0 = strip[ 0 ]
// divide the polygon in n-2 triangle
for ( var j = 1; j < indexCount - 1; j ++ ) {
indices[ indicesIndex ++ ] = strip[ 0 ];
indices[ indicesIndex ++ ] = strip[ j ];
indices[ indicesIndex ++ ] = strip[ j + 1 ];
}
}
// increment our next pointer
state.next = state.next + count + 1;
} else if ( line.indexOf ( "POINT_DATA" ) == 0 ) {
numberOfPoints = parseInt ( line.split( " " )[ 1 ], 10 );
// Grab the next line
state = findString ( buffer, state.next );
// Now grab the binary data
count = numberOfPoints * 4 * 3;
normals = new Float32Array( numberOfPoints * 3 );
pointIndex = state.next;
for ( i = 0; i < numberOfPoints; i ++ ) {
normals[ 3 * i ] = dataView.getFloat32( pointIndex, false );
normals[ 3 * i + 1 ] = dataView.getFloat32( pointIndex + 4, false );
normals[ 3 * i + 2 ] = dataView.getFloat32( pointIndex + 8, false );
pointIndex += 12;
}
// Increment past our data
state.next = state.next + count;
}
// Increment index
index = state.next;
if ( index >= buffer.byteLength ) {
break;
}
}
var geometry = new THREE.BufferGeometry();
geometry.setIndex( new THREE.BufferAttribute( indices, 1 ) );
geometry.addAttribute( 'position', new THREE.BufferAttribute( points, 3 ) );
if ( normals.length == points.length ) {
geometry.addAttribute( 'normal', new THREE.BufferAttribute( normals, 3 ) );
}
return geometry;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册