Improve STL representation detection
Previously, the STL loader relied on a string check at the start of the buffer to determine if the STL file was of ASCII representation. This led to certain false-positives for binary STL files with the magic string present in their header. This patch addresses the issue by adding a proper binary check to the representation detection.pull/79/head
parent
6eaff77a7c
commit
7db5dcb357
|
@ -51,6 +51,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
|
|
||||||
|
namespace {
|
||||||
static const aiImporterDesc desc = {
|
static const aiImporterDesc desc = {
|
||||||
"Stereolithography (STL) Importer",
|
"Stereolithography (STL) Importer",
|
||||||
"",
|
"",
|
||||||
|
@ -64,6 +65,34 @@ static const aiImporterDesc desc = {
|
||||||
"stl"
|
"stl"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// A valid binary STL buffer should consist of the following elements, in order:
|
||||||
|
// 1) 80 byte header
|
||||||
|
// 2) 4 byte face count
|
||||||
|
// 3) 50 bytes per face
|
||||||
|
bool IsBinarySTL(const char* buffer, unsigned int fileSize) {
|
||||||
|
if (fileSize < 84)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const uint32_t faceCount = *reinterpret_cast<const uint32_t*>(buffer + 80);
|
||||||
|
const uint32_t expectedBinaryFileSize = faceCount * 50 + 84;
|
||||||
|
|
||||||
|
return expectedBinaryFileSize == fileSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
// An ascii STL buffer will begin with "solid NAME", where NAME is optional.
|
||||||
|
// Note: The "solid NAME" check is necessary, but not sufficient, to determine
|
||||||
|
// if the buffer is ASCII; a binary header could also begin with "solid NAME".
|
||||||
|
bool IsAsciiSTL(const char* buffer, unsigned int fileSize) {
|
||||||
|
if (IsBinarySTL(buffer, fileSize))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (fileSize < 5)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return strncmp(buffer, "solid", 5) == 0;
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Constructor to be privately used by Importer
|
// Constructor to be privately used by Importer
|
||||||
STLImporter::STLImporter()
|
STLImporter::STLImporter()
|
||||||
|
@ -136,12 +165,13 @@ void STLImporter::InternReadFile( const std::string& pFile,
|
||||||
|
|
||||||
bool bMatClr = false;
|
bool bMatClr = false;
|
||||||
|
|
||||||
// check whether the file starts with 'solid' -
|
if (IsBinarySTL(mBuffer, fileSize)) {
|
||||||
// in this case we can simply assume it IS a text file. finished.
|
bMatClr = LoadBinaryFile();
|
||||||
if (!::strncmp(mBuffer,"solid",5)) {
|
} else if (IsAsciiSTL(mBuffer, fileSize)) {
|
||||||
LoadASCIIFile();
|
LoadASCIIFile();
|
||||||
|
} else {
|
||||||
|
throw DeadlyImportError( "Failed to determine STL storage representation for " + pFile + ".");
|
||||||
}
|
}
|
||||||
else bMatClr = LoadBinaryFile();
|
|
||||||
|
|
||||||
// now copy faces
|
// now copy faces
|
||||||
pMesh->mFaces = new aiFace[pMesh->mNumFaces];
|
pMesh->mFaces = new aiFace[pMesh->mNumFaces];
|
||||||
|
|
Loading…
Reference in New Issue