libstl: add buffered reading of triangle data (binary format)

This commit is contained in:
Hugues Delorme 2012-02-28 20:32:00 +01:00
parent 6f7bfd31e6
commit 98176be41d

View File

@ -116,6 +116,7 @@ Io::ReadError Io::read(AbstractGeometryBuilder* builder)
AbstractStream* istream = this->stream(); AbstractStream* istream = this->stream();
AbstractTaskProgress* progress = this->taskProgress(); AbstractTaskProgress* progress = this->taskProgress();
// Io::ReadError readErr = Io::NoReadError; // Io::ReadError readErr = Io::NoReadError;
const UInt32 chunkSize = stlTriangleDataSize * 163;
UInt8 buffer[8192]; UInt8 buffer[8192];
char* charBuffer = reinterpret_cast<char*>(buffer); char* charBuffer = reinterpret_cast<char*>(buffer);
@ -140,40 +141,54 @@ Io::ReadError Io::read(AbstractGeometryBuilder* builder)
} }
// Read triangles // Read triangles
const UInt64 totalFacetSize = stlTriangleDataSize * facetCount;
UInt64 amountReadSize = 0;
Triangle triangle; Triangle triangle;
for (UInt32 facet = 0; facet < facetCount; ++facet) { bool streamError = false;
istream->read(charBuffer, stlTriangleDataSize); while (amountReadSize < totalFacetSize && !streamError) {
// if ((readErr = streamRead(istream, charBuffer, stlTriangleDataSize)) != NoReadError) const Int64 iReadSize = istream->read(charBuffer, chunkSize);
// return readErr; if (iReadSize > 0 && (iReadSize % stlTriangleDataSize == 0)) {
const UInt32 iFacetCount = iReadSize / stlTriangleDataSize;
UInt32 bufferOffset = 0;
for (UInt32 i = 0; i < iFacetCount; ++i) {
// Read normal
triangle.normal.x = ::fromLittleEndian<Real32>(buffer + bufferOffset);
triangle.normal.y = ::fromLittleEndian<Real32>(buffer + 1*sizeof(Real32) + bufferOffset);
triangle.normal.z = ::fromLittleEndian<Real32>(buffer + 2*sizeof(Real32) + bufferOffset);
// Read normal // Read vertex1
triangle.normal.x = ::fromLittleEndian<Real32>(buffer); triangle.v1.x = ::fromLittleEndian<Real32>(buffer + 3*sizeof(Real32) + bufferOffset);
triangle.normal.y = ::fromLittleEndian<Real32>(buffer + 1*sizeof(Real32)); triangle.v1.y = ::fromLittleEndian<Real32>(buffer + 4*sizeof(Real32) + bufferOffset);
triangle.normal.z = ::fromLittleEndian<Real32>(buffer + 2*sizeof(Real32)); triangle.v1.z = ::fromLittleEndian<Real32>(buffer + 5*sizeof(Real32) + bufferOffset);
// Read vertex1 // Read vertex2
triangle.v1.x = ::fromLittleEndian<Real32>(buffer + 3*sizeof(Real32)); triangle.v2.x = ::fromLittleEndian<Real32>(buffer + 6*sizeof(Real32) + bufferOffset);
triangle.v1.y = ::fromLittleEndian<Real32>(buffer + 4*sizeof(Real32)); triangle.v2.y = ::fromLittleEndian<Real32>(buffer + 7*sizeof(Real32) + bufferOffset);
triangle.v1.z = ::fromLittleEndian<Real32>(buffer + 5*sizeof(Real32)); triangle.v2.z = ::fromLittleEndian<Real32>(buffer + 8*sizeof(Real32) + bufferOffset);
// Read vertex2 // Read vertex3
triangle.v2.x = ::fromLittleEndian<Real32>(buffer + 6*sizeof(Real32)); triangle.v3.x = ::fromLittleEndian<Real32>(buffer + 9*sizeof(Real32) + bufferOffset);
triangle.v2.y = ::fromLittleEndian<Real32>(buffer + 7*sizeof(Real32)); triangle.v3.y = ::fromLittleEndian<Real32>(buffer + 10*sizeof(Real32) + bufferOffset);
triangle.v2.z = ::fromLittleEndian<Real32>(buffer + 8*sizeof(Real32)); triangle.v3.z = ::fromLittleEndian<Real32>(buffer + 11*sizeof(Real32) + bufferOffset);
// Read vertex3 // Attribute byte count
triangle.v3.x = ::fromLittleEndian<Real32>(buffer + 9*sizeof(Real32)); const UInt16 attributeByteCount =
triangle.v3.y = ::fromLittleEndian<Real32>(buffer + 10*sizeof(Real32)); ::fromLittleEndian<UInt16>(buffer + 12*sizeof(Real32) + bufferOffset);
triangle.v3.z = ::fromLittleEndian<Real32>(buffer + 11*sizeof(Real32));
// Attribute byte count // Add triangle
const UInt16 attributeByteCount = ::fromLittleEndian<UInt16>(buffer + 12*sizeof(Real32)); builder->nextTriangle(triangle, attributeByteCount);
// Add triangle bufferOffset += stlTriangleDataSize;
builder->nextTriangle(triangle, attributeByteCount); }
if (progress != 0) if (progress != 0)
progress->setValue(facet + 1); progress->setValue(amountReadSize / stlTriangleDataSize);
amountReadSize += iReadSize;
}
else {
streamError = true;
}
} }
builder->endTriangles(); builder->endTriangles();