parse method
Implementation
BufferGeometry parse(data, [String? path, Function? onLoad, Function? onError]) {
bool matchDataViewAt( query, reader, offset ) {
// Check if each byte in query matches the corresponding byte from the current offset
for (int i = 0, il = query.length; i < il; i ++ ) {
if ( query[ i ] != reader.getUint8( offset + i ) ) return false;
}
return true;
}
bool isBinary(Uint8List data){
final reader = ByteData.view(data.buffer);
const face_size = ( 32 / 8 * 3 ) + ( ( 32 / 8 * 3 ) * 3 ) + ( 16 / 8 );
final n_faces = reader.getUint32( 80, Endian.little);
final expect = 80 + ( 32 / 8 ) + ( n_faces * face_size );
if (expect == reader.lengthInBytes) {
return true;
}
// An ASCII STL data must begin with 'solid ' as the first six bytes.
// However, ASCII STLs lacking the SPACE after the 'd' are known to be
// plentiful. So, check the first 5 bytes for 'solid'.
// Several encodings, such as UTF-8, precede the text with up to 5 bytes:
// https://en.wikipedia.org/wiki/Byte_order_mark#Byte_order_marks_by_encoding
// Search for "solid" to start anywhere after those prefixes.
// US-ASCII ordinal values for 's', 'o', 'l', 'i', 'd'
const solid = [ 115, 111, 108, 105, 100 ];
for (int off = 0; off < 5; off ++ ) {
// If "solid" text is matched to the current offset, declare it to be an ASCII STL.
if(matchDataViewAt(solid, reader, off)){
return false;
}
}
// Couldn't find "solid" text at the beginning; it is binary STL.
return true;
}
String ensureString(buffer){
if(buffer is String) {
return buffer;
}
return String.fromCharCodes(buffer);
}
Uint8List ensureBinary(buffer) {
if (buffer is String) {
final array_buffer = Uint8List(buffer.length);
for (int i = 0; i < buffer.length; i ++ ) {
array_buffer[i] = buffer.codeUnits[i] & 0xff; // implicitly assumes little-endian
}
return array_buffer;
}
else {
return buffer;
}
}
// start
final binData = ensureBinary(data);
return isBinary(binData)?parseBinary(binData):parseASCII(ensureString(data));
}