parseBinary method
Implementation
BufferGeometry parseBinary(Uint8List data) {
final reader = ByteData.view(data.buffer);
final faces = reader.getUint32(80, Endian.little);
double r = 0;
double g = 0;
double b = 0;
bool hasColors = false;
late Float32Array colors;
double defaultR = 0;
double defaultG = 0;
double defaultB = 0;
double alpha = 0;
// process STL header
// check for default color in header ("COLOR=rgba" sequence).
for (int index = 0; index < 80 - 10; index ++ ) {
if ((reader.getUint32(index) == 0x434F4C4F /*COLO*/ ) &&
(reader.getUint8( index + 4 ) == 0x52 /*'R'*/ ) &&
(reader.getUint8( index + 5 ) == 0x3D /*'='*/ )
){
hasColors = true;
colors = Float32Array( faces * 3 * 3 );
defaultR = reader.getUint8( index + 6 ) / 255;
defaultG = reader.getUint8( index + 7 ) / 255;
defaultB = reader.getUint8( index + 8 ) / 255;
alpha = reader.getUint8( index + 9 ) / 255;
}
}
const dataOffset = 84;
const faceLength = 12 * 4 + 2;
final geometry = BufferGeometry();
final vertices = Float32Array( faces * 3 * 3 );
final normals = Float32Array( faces * 3 * 3 );
final color = Color();
for(int face = 0; face < faces; face ++){
final start = dataOffset + face * faceLength;
final normalX = reader.getFloat32( start, Endian.little);
final normalY = reader.getFloat32( start + 4, Endian.little);
final normalZ = reader.getFloat32( start + 8, Endian.little);
if ( hasColors ) {
final packedColor = reader.getUint16( start + 48, Endian.little);
if ( ( packedColor & 0x8000 ) == 0 ) {
// facet has its own unique color
r = ( packedColor & 0x1F ) / 31;
g = ( ( packedColor >> 5 ) & 0x1F ) / 31;
b = ( ( packedColor >> 10 ) & 0x1F ) / 31;
}
else {
r = defaultR;
g = defaultG;
b = defaultB;
}
}
for(int i = 1; i <= 3; i ++ ) {
final vertexstart = start + i * 12;
final componentIdx = ( face * 3 * 3 ) + ( ( i - 1 ) * 3 );
vertices[componentIdx] = reader.getFloat32( vertexstart, Endian.little);
vertices[componentIdx + 1] = reader.getFloat32( vertexstart + 4, Endian.little);
vertices[componentIdx + 2] = reader.getFloat32( vertexstart + 8, Endian.little);
normals[componentIdx] = normalX;
normals[componentIdx + 1] = normalY;
normals[componentIdx + 2] = normalZ;
if ( hasColors ) {
color.setRGB(r, g, b).convertSRGBToLinear();
colors[componentIdx] = color.r;
colors[componentIdx + 1] = color.g;
colors[componentIdx + 2] = color.b;
}
}
}
geometry.setAttribute('position', Float32BufferAttribute(vertices,3));
geometry.setAttribute('normal', Float32BufferAttribute(normals,3));
if(hasColors){
geometry.setAttribute('color', Float32BufferAttribute(colors,3));
//geometry.hasColors = true;
//geometry.alpha = alpha;
}
return geometry;
}