|
@@ -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' -
|
|
|
|
- // in this case we can simply assume it IS a text file. finished.
|
|
|
|
- if (!::strncmp(mBuffer,"solid",5)) {
|
|
|
|
|
|
+ if (IsBinarySTL(mBuffer, fileSize)) {
|
|
|
|
+ bMatClr = LoadBinaryFile();
|
|
|
|
+ } 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];
|