diff --git a/code/STLLoader.cpp b/code/STLLoader.cpp index f4d6ddda7..6b71ba920 100644 --- a/code/STLLoader.cpp +++ b/code/STLLoader.cpp @@ -200,17 +200,17 @@ void STLImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOS 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->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 white diffuse color for consistency with // other geometric types (e.g., PLY). aiMaterial* pcMat = new aiMaterial(); @@ -231,11 +231,12 @@ void STLImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOS pScene->mMaterials = new aiMaterial*[1]; pScene->mMaterials[0] = pcMat; } + // ------------------------------------------------------------------------------------------------ // Read an ASCII STL file -void STLImporter::LoadASCIIFile() -{ +void STLImporter::LoadASCIIFile( aiNode *root ) { std::vector meshes; + std::vector nodes; const char* sz = mBuffer; const char* bufferEnd = mBuffer + fileSize; std::vector positionBuffer; @@ -247,12 +248,15 @@ void STLImporter::LoadASCIIFile() positionBuffer.reserve(sizeEstimate); normalBuffer.reserve(sizeEstimate); - while (IsAsciiSTL(sz, static_cast(bufferEnd - sz))) - { + while (IsAsciiSTL(sz, static_cast(bufferEnd - sz))) { + std::vector meshIndices; aiMesh* pMesh = new aiMesh(); pMesh->mMaterialIndex = 0; + meshIndices.push_back( meshes.size() ); meshes.push_back(pMesh); - + aiNode *node = new aiNode; + node->mParent = root; + nodes.push_back( node ); SkipSpaces(&sz); ai_assert(!IsLineEnd(sz)); @@ -265,20 +269,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(""); } - else pScene->mRootNode->mName.Set(""); unsigned int faceVertexCounter = 3; - for ( ;; ) - { + for ( ;; ) { // go to the next token if(!SkipSpacesAndLineEnd(&sz)) { @@ -300,9 +305,7 @@ 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"); } @@ -316,16 +319,11 @@ void STLImporter::LoadASCIIFile() 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"); } @@ -340,17 +338,14 @@ void STLImporter::LoadASCIIFile() sz = fast_atoreal_move(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)); @@ -380,13 +375,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 = nodes.size(); + root->mChildren = new aiNode*[ root->mNumChildren ]; + for ( size_t i=0; imChildren[ i ] = nodes[ i ]; } } @@ -513,4 +517,18 @@ bool STLImporter::LoadBinaryFile() return false; } +void STLImporter::pushMeshesToNode( std::vector &meshIndices, aiNode *node ) { + ai_assert( nullptr != node ); + if ( meshIndices.empty() ) { + return; + } + + node->mNumMeshes = static_cast( meshIndices.size() ); + node->mMeshes = new unsigned int[ meshIndices.size() ]; + for ( size_t i=0; imMeshes[ i ] = meshIndices[ i ]; + } + meshIndices.clear(); +} + #endif // !! ASSIMP_BUILD_NO_STL_IMPORTER diff --git a/code/STLLoader.h b/code/STLLoader.h index 87ed3288d..ff7b32a15 100644 --- a/code/STLLoader.h +++ b/code/STLLoader.h @@ -48,53 +48,61 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "BaseImporter.h" #include -namespace Assimp { +// Forward declarations +class aiNode; + +namespace Assimp { + // --------------------------------------------------------------------------- -/** Importer class for the sterolithography STL file format -*/ -class STLImporter : public BaseImporter -{ +/** + * @brief Importer class for the sterolithography STL file format. + */ +class STLImporter : public BaseImporter { public: + /** + * @brief STLImporter, the class default constructor. + */ STLImporter(); + + /** + * @brief The class destructor. + */ ~STLImporter(); - -public: - - // ------------------------------------------------------------------- - /** Returns whether the class can handle the format of the given file. - * See BaseImporter::CanRead() for details. + /** + * @brief Returns whether the class can handle the format of the given file. + * See BaseImporter::CanRead() for details. */ - bool CanRead( const std::string& pFile, IOSystem* pIOHandler, - bool checkSig) const; + bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const; protected: - // ------------------------------------------------------------------- - /** Return importer meta information. - * See #BaseImporter::GetInfo for the details + /** + * @brief Return importer meta information. + * See #BaseImporter::GetInfo for the details */ const aiImporterDesc* GetInfo () const; - // ------------------------------------------------------------------- - /** Imports the given file into the given scene structure. + /** + * @brief Imports the given file into the given scene structure. * See BaseImporter::InternReadFile() for details */ void InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler); - - // ------------------------------------------------------------------- - /** Loads a binary .stl file + /** + * @brief Loads a binary .stl file * @return true if the default vertex color must be used as material color - */ + */ bool LoadBinaryFile(); - // ------------------------------------------------------------------- - /** Loads a ASCII text .stl file - */ - void LoadASCIIFile(); + /** + * @brief Loads a ASCII text .stl file + */ + void LoadASCIIFile( aiNode *root ); + + void pushMeshesToNode( std::vector &meshIndices, aiNode *node ); protected: