From 4ccb16fe01674b5bbe1129948d2e71aa6b6db97d Mon Sep 17 00:00:00 2001 From: YoheiKakiuchi Date: Wed, 31 Jul 2013 20:15:59 +0900 Subject: [PATCH 1/2] add binary exporter to STLExporter --- code/Exporter.cpp | 4 +++ code/STLExporter.cpp | 69 +++++++++++++++++++++++++++++++++++++++----- code/STLExporter.h | 3 +- 3 files changed, 68 insertions(+), 8 deletions(-) diff --git a/code/Exporter.cpp b/code/Exporter.cpp index 3b2badab7..405fa2e29 100644 --- a/code/Exporter.cpp +++ b/code/Exporter.cpp @@ -73,6 +73,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*) {} @@ -93,6 +94,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..249f0f6f8 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]; + for(int i = 0; i < 80; ++i) buf[i] = 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++; + } + } + 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,29 @@ 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; + 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; + mOutput.write((char *)&vx, 4); mOutput.write((char *)&vy, 4); mOutput.write((char *)&vz, 4); + } + char dummy[2]; + 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: From 60a65aaaebdb81ebb82e2500be4cc6562cd24b67 Mon Sep 17 00:00:00 2001 From: YoheiKakiuchi Date: Fri, 9 Aug 2013 17:54:28 +0900 Subject: [PATCH 2/2] add AI_SWAP4 for big endian architecture --- code/STLExporter.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/code/STLExporter.cpp b/code/STLExporter.cpp index 249f0f6f8..e3df2fbff 100644 --- a/code/STLExporter.cpp +++ b/code/STLExporter.cpp @@ -90,8 +90,7 @@ STLExporter :: STLExporter(const char* _filename, const aiScene* pScene, bool bi const std::locale& l = std::locale("C"); mOutput.imbue(l); if (binary) { - char buf[80]; - for(int i = 0; i < 80; ++i) buf[i] = 0; + 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); @@ -101,6 +100,7 @@ STLExporter :: STLExporter(const char* _filename, const aiScene* pScene, bool bi meshnum++; } } + AI_SWAP4(meshnum); mOutput.write((char *)&meshnum, 4); for(unsigned int i = 0; i < pScene->mNumMeshes; ++i) { WriteMeshBinary(pScene->mMeshes[i]); @@ -157,13 +157,15 @@ void STLExporter :: WriteMeshBinary(const aiMesh* m) 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]; + char dummy[2] = {0}; mOutput.write(dummy, 2); } }