diff --git a/code/Exporter.cpp b/code/Exporter.cpp index b6d15e25f..5e9a86410 100644 --- a/code/Exporter.cpp +++ b/code/Exporter.cpp @@ -74,6 +74,7 @@ void GetPostProcessingStepInstanceList(std::vector< BaseProcess* >& out); void ExportSceneCollada(const char*,IOSystem*, const aiScene*); void ExportSceneObj(const char*,IOSystem*, const aiScene*); void ExportSceneSTL(const char*,IOSystem*, const aiScene*); +void ExportSceneSTLBinary(const char*,IOSystem*, const aiScene*); void ExportScenePly(const char*,IOSystem*, const aiScene*); void ExportScene3DS(const char*, IOSystem*, const aiScene*) {} @@ -94,6 +95,9 @@ Exporter::ExportFormatEntry gExporters[] = Exporter::ExportFormatEntry( "stl", "Stereolithography", "stl" , &ExportSceneSTL, aiProcess_Triangulate | aiProcess_GenNormals | aiProcess_PreTransformVertices ), + Exporter::ExportFormatEntry( "stlb", "Stereolithography(binary)", "stlb" , &ExportSceneSTLBinary, + aiProcess_Triangulate | aiProcess_GenNormals | aiProcess_PreTransformVertices + ), #endif #ifndef ASSIMP_BUILD_NO_PLY_EXPORTER diff --git a/code/STLExporter.cpp b/code/STLExporter.cpp index 521f28ae3..e3df2fbff 100644 --- a/code/STLExporter.cpp +++ b/code/STLExporter.cpp @@ -63,12 +63,25 @@ void ExportSceneSTL(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene outfile->Write( exporter.mOutput.str().c_str(), static_cast(exporter.mOutput.tellp()),1); } +void ExportSceneSTLBinary(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene) +{ + // invoke the exporter + STLExporter exporter(pFile, pScene, true); + + // we're still here - export successfully completed. Write the file. + boost::scoped_ptr outfile (pIOSystem->Open(pFile,"wt")); + if(outfile == NULL) { + throw DeadlyExportError("could not open output .stl file: " + std::string(pFile)); + } + + outfile->Write( exporter.mOutput.str().c_str(), static_cast(exporter.mOutput.tellp()),1); +} } // end of namespace Assimp // ------------------------------------------------------------------------------------------------ -STLExporter :: STLExporter(const char* _filename, const aiScene* pScene) +STLExporter :: STLExporter(const char* _filename, const aiScene* pScene, bool binary) : filename(_filename) , pScene(pScene) , endl("\n") @@ -76,14 +89,31 @@ STLExporter :: STLExporter(const char* _filename, const aiScene* pScene) // make sure that all formatting happens using the standard, C locale and not the user's current locale const std::locale& l = std::locale("C"); mOutput.imbue(l); - - const std::string& name = "AssimpScene"; + if (binary) { + char buf[80] = {0} ; + buf[0] = 'A'; buf[1] = 's'; buf[2] = 's'; buf[3] = 'i'; buf[4] = 'm'; buf[5] = 'p'; + buf[6] = 'S'; buf[7] = 'c'; buf[8] = 'e'; buf[9] = 'n'; buf[10] = 'e'; + mOutput.write(buf, 80); + unsigned int meshnum = 0; + for(unsigned int i = 0; i < pScene->mNumMeshes; ++i) { + for (unsigned int j = 0; j < pScene->mMeshes[i]->mNumFaces; ++j) { + meshnum++; + } + } + AI_SWAP4(meshnum); + mOutput.write((char *)&meshnum, 4); + for(unsigned int i = 0; i < pScene->mNumMeshes; ++i) { + WriteMeshBinary(pScene->mMeshes[i]); + } + } else { + const std::string& name = "AssimpScene"; - mOutput << "solid " << name << endl; - for(unsigned int i = 0; i < pScene->mNumMeshes; ++i) { - WriteMesh(pScene->mMeshes[i]); + mOutput << "solid " << name << endl; + for(unsigned int i = 0; i < pScene->mNumMeshes; ++i) { + WriteMesh(pScene->mMeshes[i]); + } + mOutput << "endsolid " << name << endl; } - mOutput << "endsolid " << name << endl; } // ------------------------------------------------------------------------------------------------ @@ -113,4 +143,31 @@ void STLExporter :: WriteMesh(const aiMesh* m) } } +void STLExporter :: WriteMeshBinary(const aiMesh* m) +{ + for (unsigned int i = 0; i < m->mNumFaces; ++i) { + const aiFace& f = m->mFaces[i]; + // we need per-face normals. We specified aiProcess_GenNormals as pre-requisite for this exporter, + // but nonetheless we have to expect per-vertex normals. + aiVector3D nor; + if (m->mNormals) { + for(unsigned int a = 0; a < f.mNumIndices; ++a) { + nor += m->mNormals[f.mIndices[a]]; + } + nor.Normalize(); + } + float nx = nor.x, ny = nor.y, nz = nor.z; + AI_SWAP4(nx); AI_SWAP4(ny); AI_SWAP4(nz); + mOutput.write((char *)&nx, 4); mOutput.write((char *)&ny, 4); mOutput.write((char *)&nz, 4); + for(unsigned int a = 0; a < f.mNumIndices; ++a) { + const aiVector3D& v = m->mVertices[f.mIndices[a]]; + float vx = v.x, vy = v.y, vz = v.z; + AI_SWAP4(vx); AI_SWAP4(vy); AI_SWAP4(vz); + mOutput.write((char *)&vx, 4); mOutput.write((char *)&vy, 4); mOutput.write((char *)&vz, 4); + } + char dummy[2] = {0}; + mOutput.write(dummy, 2); + } +} + #endif diff --git a/code/STLExporter.h b/code/STLExporter.h index d64fe92e6..0ed60d812 100644 --- a/code/STLExporter.h +++ b/code/STLExporter.h @@ -59,7 +59,7 @@ class STLExporter { public: /// Constructor for a specific scene to export - STLExporter(const char* filename, const aiScene* pScene); + STLExporter(const char* filename, const aiScene* pScene, bool binary = false); public: @@ -69,6 +69,7 @@ public: private: void WriteMesh(const aiMesh* m); + void WriteMeshBinary(const aiMesh* m); private: