summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/assimp/code/STLLoader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/assimp/code/STLLoader.cpp')
-rw-r--r--src/3rdparty/assimp/code/STLLoader.cpp158
1 files changed, 91 insertions, 67 deletions
diff --git a/src/3rdparty/assimp/code/STLLoader.cpp b/src/3rdparty/assimp/code/STLLoader.cpp
index 95fce47e2..be4c7584d 100644
--- a/src/3rdparty/assimp/code/STLLoader.cpp
+++ b/src/3rdparty/assimp/code/STLLoader.cpp
@@ -3,7 +3,8 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
-Copyright (c) 2006-2016, assimp team
+Copyright (c) 2006-2017, assimp team
+
All rights reserved.
@@ -52,10 +53,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/IOSystem.hpp>
#include <assimp/scene.h>
#include <assimp/DefaultLogger.hpp>
+#include <assimp/importerdesc.h>
using namespace Assimp;
namespace {
+
static const aiImporterDesc desc = {
"Stereolithography (STL) Importer",
"",
@@ -78,7 +81,9 @@ static bool IsBinarySTL(const char* buffer, unsigned int fileSize) {
return false;
}
- const uint32_t faceCount = *reinterpret_cast<const uint32_t*>(buffer + 80);
+ const char *facecount_pos = buffer + 80;
+ uint32_t faceCount( 0 );
+ ::memcpy( &faceCount, facecount_pos, sizeof( uint32_t ) );
const uint32_t expectedBinaryFileSize = faceCount * 50 + 84;
return expectedBinaryFileSize == fileSize;
@@ -144,7 +149,7 @@ bool STLImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool
const char* tokens[] = {"STL","solid"};
return SearchFileHeaderForToken(pIOHandler,pFile,tokens,2);
}
-
+
return false;
}
@@ -168,8 +173,7 @@ void addFacesToMesh(aiMesh* pMesh)
// ------------------------------------------------------------------------------------------------
// Imports the given file into the given scene structure.
-void STLImporter::InternReadFile( const std::string& pFile,
- aiScene* pScene, IOSystem* pIOHandler)
+void STLImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler )
{
std::unique_ptr<IOStream> file( pIOHandler->Open( pFile, "rb"));
@@ -189,7 +193,7 @@ void STLImporter::InternReadFile( const std::string& pFile,
this->mBuffer = &mBuffer2[0];
// the default vertex color is light gray.
- clrColorDefault.r = clrColorDefault.g = clrColorDefault.b = clrColorDefault.a = 0.6f;
+ clrColorDefault.r = clrColorDefault.g = clrColorDefault.b = clrColorDefault.a = (ai_real) 0.6;
// allocate a single node
pScene->mRootNode = new aiNode();
@@ -199,42 +203,37 @@ void STLImporter::InternReadFile( const std::string& pFile,
if (IsBinarySTL(mBuffer, fileSize)) {
bMatClr = LoadBinaryFile();
} else if (IsAsciiSTL(mBuffer, fileSize)) {
- LoadASCIIFile();
+ LoadASCIIFile( pScene->mRootNode );
} else {
throw DeadlyImportError( "Failed to determine STL storage representation for " + pFile + ".");
}
- // add all created meshes to the single node
- pScene->mRootNode->mNumMeshes = pScene->mNumMeshes;
- pScene->mRootNode->mMeshes = new unsigned int[pScene->mNumMeshes];
- for (unsigned int i = 0; i < pScene->mNumMeshes; i++)
- pScene->mRootNode->mMeshes[i] = i;
-
- // create a single default material, using a light gray diffuse color for consistency with
+ // create a single default material, using a white diffuse color for consistency with
// other geometric types (e.g., PLY).
aiMaterial* pcMat = new aiMaterial();
aiString s;
s.Set(AI_DEFAULT_MATERIAL_NAME);
pcMat->AddProperty(&s, AI_MATKEY_NAME);
- aiColor4D clrDiffuse(0.6f,0.6f,0.6f,1.0f);
+ aiColor4D clrDiffuse(ai_real(1.0),ai_real(1.0),ai_real(1.0),ai_real(1.0));
if (bMatClr) {
clrDiffuse = clrColorDefault;
}
pcMat->AddProperty(&clrDiffuse,1,AI_MATKEY_COLOR_DIFFUSE);
pcMat->AddProperty(&clrDiffuse,1,AI_MATKEY_COLOR_SPECULAR);
- clrDiffuse = aiColor4D(0.05f,0.05f,0.05f,1.0f);
+ clrDiffuse = aiColor4D( ai_real(1.0), ai_real(1.0), ai_real(1.0), ai_real(1.0));
pcMat->AddProperty(&clrDiffuse,1,AI_MATKEY_COLOR_AMBIENT);
pScene->mNumMaterials = 1;
pScene->mMaterials = new aiMaterial*[1];
pScene->mMaterials[0] = pcMat;
}
+
// ------------------------------------------------------------------------------------------------
// Read an ASCII STL file
-void STLImporter::LoadASCIIFile()
-{
+void STLImporter::LoadASCIIFile( aiNode *root ) {
std::vector<aiMesh*> meshes;
+ std::vector<aiNode*> nodes;
const char* sz = mBuffer;
const char* bufferEnd = mBuffer + fileSize;
std::vector<aiVector3D> positionBuffer;
@@ -246,12 +245,15 @@ void STLImporter::LoadASCIIFile()
positionBuffer.reserve(sizeEstimate);
normalBuffer.reserve(sizeEstimate);
- while (IsAsciiSTL(sz, bufferEnd - sz))
- {
+ while (IsAsciiSTL(sz, static_cast<unsigned int>(bufferEnd - sz))) {
+ std::vector<unsigned int> meshIndices;
aiMesh* pMesh = new aiMesh();
pMesh->mMaterialIndex = 0;
+ meshIndices.push_back((unsigned int) meshes.size() );
meshes.push_back(pMesh);
-
+ aiNode *node = new aiNode;
+ node->mParent = root;
+ nodes.push_back( node );
SkipSpaces(&sz);
ai_assert(!IsLineEnd(sz));
@@ -264,20 +266,21 @@ void STLImporter::LoadASCIIFile()
size_t temp;
// setup the name of the node
- if ((temp = (size_t)(sz-szMe))) {
+ if ((temp = (size_t)(sz-szMe))) {
if (temp >= MAXLEN) {
throw DeadlyImportError( "STL: Node name too long" );
}
-
- pScene->mRootNode->mName.length = temp;
- memcpy(pScene->mRootNode->mName.data,szMe,temp);
- pScene->mRootNode->mName.data[temp] = '\0';
+ std::string name( szMe, temp );
+ node->mName.Set( name.c_str() );
+ //pScene->mRootNode->mName.length = temp;
+ //memcpy(pScene->mRootNode->mName.data,szMe,temp);
+ //pScene->mRootNode->mName.data[temp] = '\0';
+ } else {
+ pScene->mRootNode->mName.Set("<STL_ASCII>");
}
- else pScene->mRootNode->mName.Set("<STL_ASCII>");
- unsigned int faceVertexCounter = 0;
- for ( ;; )
- {
+ unsigned int faceVertexCounter = 3;
+ for ( ;; ) {
// go to the next token
if(!SkipSpacesAndLineEnd(&sz))
{
@@ -299,32 +302,25 @@ void STLImporter::LoadASCIIFile()
SkipSpaces(&sz);
if (strncmp(sz,"normal",6)) {
DefaultLogger::get()->warn("STL: a facet normal vector was expected but not found");
- }
- else
- {
+ } else {
if (sz[6] == '\0') {
throw DeadlyImportError("STL: unexpected EOF while parsing facet");
}
sz += 7;
SkipSpaces(&sz);
- sz = fast_atoreal_move<float>(sz, (float&)vn->x );
+ sz = fast_atoreal_move<ai_real>(sz, (ai_real&)vn->x );
SkipSpaces(&sz);
- sz = fast_atoreal_move<float>(sz, (float&)vn->y );
+ sz = fast_atoreal_move<ai_real>(sz, (ai_real&)vn->y );
SkipSpaces(&sz);
- sz = fast_atoreal_move<float>(sz, (float&)vn->z );
+ sz = fast_atoreal_move<ai_real>(sz, (ai_real&)vn->z );
normalBuffer.push_back(*vn);
normalBuffer.push_back(*vn);
}
- }
- // vertex 1.50000 1.50000 0.00000
- else if (!strncmp(sz,"vertex",6) && ::IsSpaceOrNewLine(*(sz+6)))
- {
+ } else if (!strncmp(sz,"vertex",6) && ::IsSpaceOrNewLine(*(sz+6))) { // vertex 1.50000 1.50000 0.00000
if (faceVertexCounter >= 3) {
DefaultLogger::get()->error("STL: a facet with more than 3 vertices has been found");
++sz;
- }
- else
- {
+ } else {
if (sz[6] == '\0') {
throw DeadlyImportError("STL: unexpected EOF while parsing facet");
}
@@ -332,24 +328,21 @@ void STLImporter::LoadASCIIFile()
SkipSpaces(&sz);
positionBuffer.push_back(aiVector3D());
aiVector3D* vn = &positionBuffer.back();
- sz = fast_atoreal_move<float>(sz, (float&)vn->x );
+ sz = fast_atoreal_move<ai_real>(sz, (ai_real&)vn->x );
SkipSpaces(&sz);
- sz = fast_atoreal_move<float>(sz, (float&)vn->y );
+ sz = fast_atoreal_move<ai_real>(sz, (ai_real&)vn->y );
SkipSpaces(&sz);
- sz = fast_atoreal_move<float>(sz, (float&)vn->z );
+ sz = fast_atoreal_move<ai_real>(sz, (ai_real&)vn->z );
faceVertexCounter++;
}
- }
- else if (!::strncmp(sz,"endsolid",8)) {
+ } else if (!::strncmp(sz,"endsolid",8)) {
do {
++sz;
} while (!::IsLineEnd(*sz));
SkipSpacesAndLineEnd(&sz);
// finished!
break;
- }
- // else skip the whole identifier
- else {
+ } else { // else skip the whole identifier
do {
++sz;
} while (!::IsSpaceOrNewLine(*sz));
@@ -368,8 +361,8 @@ void STLImporter::LoadASCIIFile()
pMesh->mNumFaces = 0;
throw DeadlyImportError("Normal buffer size does not match position buffer size");
}
- pMesh->mNumFaces = positionBuffer.size() / 3;
- pMesh->mNumVertices = positionBuffer.size();
+ pMesh->mNumFaces = static_cast<unsigned int>(positionBuffer.size() / 3);
+ pMesh->mNumVertices = static_cast<unsigned int>(positionBuffer.size());
pMesh->mVertices = new aiVector3D[pMesh->mNumVertices];
memcpy(pMesh->mVertices, &positionBuffer[0].x, pMesh->mNumVertices * sizeof(aiVector3D));
positionBuffer.clear();
@@ -379,13 +372,22 @@ void STLImporter::LoadASCIIFile()
// now copy faces
addFacesToMesh(pMesh);
+
+ // assign the meshes to the current node
+ pushMeshesToNode( meshIndices, node );
}
+
// now add the loaded meshes
pScene->mNumMeshes = (unsigned int)meshes.size();
pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
- for (size_t i = 0; i < meshes.size(); i++)
- {
- pScene->mMeshes[i] = meshes[i];
+ for (size_t i = 0; i < meshes.size(); i++) {
+ pScene->mMeshes[ i ] = meshes[i];
+ }
+
+ root->mNumChildren = (unsigned int) nodes.size();
+ root->mChildren = new aiNode*[ root->mNumChildren ];
+ for ( size_t i=0; i<nodes.size(); ++i ) {
+ root->mChildren[ i ] = nodes[ i ];
}
}
@@ -416,10 +418,11 @@ bool STLImporter::LoadBinaryFile()
// read the default vertex color for facets
bIsMaterialise = true;
DefaultLogger::get()->info("STL: Taking code path for Materialise files");
- clrColorDefault.r = (*sz2++) / 255.0f;
- clrColorDefault.g = (*sz2++) / 255.0f;
- clrColorDefault.b = (*sz2++) / 255.0f;
- clrColorDefault.a = (*sz2++) / 255.0f;
+ const ai_real invByte = (ai_real)1.0 / ( ai_real )255.0;
+ clrColorDefault.r = (*sz2++) * invByte;
+ clrColorDefault.g = (*sz2++) * invByte;
+ clrColorDefault.b = (*sz2++) * invByte;
+ clrColorDefault.a = (*sz2++) * invByte;
break;
}
}
@@ -480,18 +483,19 @@ bool STLImporter::LoadBinaryFile()
DefaultLogger::get()->info("STL: Mesh has vertex colors");
}
aiColor4D* clr = &pMesh->mColors[0][i*3];
- clr->a = 1.0f;
+ clr->a = 1.0;
+ const ai_real invVal( (ai_real)1.0 / ( ai_real )31.0 );
if (bIsMaterialise) // this is reversed
{
- clr->r = (color & 0x31u) / 31.0f;
- clr->g = ((color & (0x31u<<5))>>5u) / 31.0f;
- clr->b = ((color & (0x31u<<10))>>10u) / 31.0f;
+ clr->r = (color & 0x31u) *invVal;
+ clr->g = ((color & (0x31u<<5))>>5u) *invVal;
+ clr->b = ((color & (0x31u<<10))>>10u) *invVal;
}
else
{
- clr->b = (color & 0x31u) / 31.0f;
- clr->g = ((color & (0x31u<<5))>>5u) / 31.0f;
- clr->r = ((color & (0x31u<<10))>>10u) / 31.0f;
+ clr->b = (color & 0x31u) *invVal;
+ clr->g = ((color & (0x31u<<5))>>5u) *invVal;
+ clr->r = ((color & (0x31u<<10))>>10u) *invVal;
}
// assign the color to all vertices of the face
*(clr+1) = *clr;
@@ -502,6 +506,12 @@ bool STLImporter::LoadBinaryFile()
// now copy faces
addFacesToMesh(pMesh);
+ // add all created meshes to the single node
+ pScene->mRootNode->mNumMeshes = pScene->mNumMeshes;
+ pScene->mRootNode->mMeshes = new unsigned int[pScene->mNumMeshes];
+ for (unsigned int i = 0; i < pScene->mNumMeshes; i++)
+ pScene->mRootNode->mMeshes[i] = i;
+
if (bIsMaterialise && !pMesh->mColors[0])
{
// use the color as diffuse material color
@@ -510,4 +520,18 @@ bool STLImporter::LoadBinaryFile()
return false;
}
+void STLImporter::pushMeshesToNode( std::vector<unsigned int> &meshIndices, aiNode *node ) {
+ ai_assert( nullptr != node );
+ if ( meshIndices.empty() ) {
+ return;
+ }
+
+ node->mNumMeshes = static_cast<unsigned int>( meshIndices.size() );
+ node->mMeshes = new unsigned int[ meshIndices.size() ];
+ for ( size_t i=0; i<meshIndices.size(); ++i ) {
+ node->mMeshes[ i ] = meshIndices[ i ];
+ }
+ meshIndices.clear();
+}
+
#endif // !! ASSIMP_BUILD_NO_STL_IMPORTER