diff --git a/code/Exporter.cpp b/code/Exporter.cpp index 846e5f8bb..72b4bffbf 100644 --- a/code/Exporter.cpp +++ b/code/Exporter.cpp @@ -78,6 +78,7 @@ 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 ExportScenePlyBinary(const char*, IOSystem*, const aiScene*); void ExportScene3DS(const char*, IOSystem*, const aiScene*); void ExportSceneAssbin(const char*, IOSystem*, const aiScene*); void ExportSceneAssxml(const char*, IOSystem*, const aiScene*); @@ -113,6 +114,9 @@ Exporter::ExportFormatEntry gExporters[] = Exporter::ExportFormatEntry( "ply", "Stanford Polygon Library", "ply" , &ExportScenePly, aiProcess_PreTransformVertices ), + Exporter::ExportFormatEntry("plyb", "Stanford Polygon Library Binary", "ply", &ExportScenePlyBinary, + aiProcess_PreTransformVertices + ), #endif #ifndef ASSIMP_BUILD_NO_3DS_EXPORTER diff --git a/code/PlyExporter.cpp b/code/PlyExporter.cpp index e78cfd964..6ddefdb17 100644 --- a/code/PlyExporter.cpp +++ b/code/PlyExporter.cpp @@ -56,7 +56,7 @@ void ExportScenePly(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene PlyExporter exporter(pFile, pScene); // we're still here - export successfully completed. Write the file. - boost::scoped_ptr outfile (pIOSystem->Open(pFile,"wt")); + boost::scoped_ptr outfile (pIOSystem->Open(pFile,"wt")); if(outfile == NULL) { throw DeadlyExportError("could not open output .ply file: " + std::string(pFile)); } @@ -64,6 +64,20 @@ void ExportScenePly(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene outfile->Write( exporter.mOutput.str().c_str(), static_cast(exporter.mOutput.tellp()),1); } +void ExportScenePlyBinary(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene) +{ + // invoke the exporter + PlyExporter exporter(pFile, pScene, true); + + // we're still here - export successfully completed. Write the file. + boost::scoped_ptr outfile(pIOSystem->Open(pFile, "wb")); + if (outfile == NULL) { + throw DeadlyExportError("could not open output .ply file: " + std::string(pFile)); + } + + outfile->Write(exporter.mOutput.str().c_str(), static_cast(exporter.mOutput.tellp()), 1); +} + } // end of namespace Assimp #define PLY_EXPORT_HAS_NORMALS 0x1 @@ -72,7 +86,7 @@ void ExportScenePly(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene #define PLY_EXPORT_HAS_COLORS (PLY_EXPORT_HAS_TEXCOORDS << AI_MAX_NUMBER_OF_TEXTURECOORDS) // ------------------------------------------------------------------------------------------------ -PlyExporter :: PlyExporter(const char* _filename, const aiScene* pScene) +PlyExporter::PlyExporter(const char* _filename, const aiScene* pScene, bool binary) : filename(_filename) , pScene(pScene) , endl("\n") @@ -102,7 +116,18 @@ PlyExporter :: PlyExporter(const char* _filename, const aiScene* pScene) } mOutput << "ply" << endl; - mOutput << "format ascii 1.0" << endl; + if (binary) + { +#if (defined AI_BUILD_BIG_ENDIAN) + mOutput << "format binary_big_endian 1.0" << endl; +#else + mOutput << "format binary_little_endian 1.0" << endl; +#endif + } + else + { + mOutput << "format ascii 1.0" << endl; + } mOutput << "comment Created by Open Asset Import Library - http://assimp.sf.net (v" << aiGetVersionMajor() << '.' << aiGetVersionMinor() << '.' << aiGetVersionRevision() << ")" << endl; @@ -160,13 +185,19 @@ PlyExporter :: PlyExporter(const char* _filename, const aiScene* pScene) mOutput << "element face " << faces << endl; mOutput << "property list uint uint vertex_index" << endl; - mOutput << "end_header" << endl; + mOutput << "end_header" << endl; for (unsigned int i = 0; i < pScene->mNumMeshes; ++i) { - WriteMeshVerts(pScene->mMeshes[i],components); + if (binary) + WriteMeshVertsBinary(pScene->mMeshes[i], components); + else + WriteMeshVerts(pScene->mMeshes[i], components); } for (unsigned int i = 0, ofs = 0; i < pScene->mNumMeshes; ++i) { - WriteMeshIndices(pScene->mMeshes[i],ofs); + if (binary) + WriteMeshIndicesBinary(pScene->mMeshes[i], ofs); + else + WriteMeshIndices(pScene->mMeshes[i], ofs); ofs += pScene->mMeshes[i]->mNumVertices; } } @@ -236,6 +267,54 @@ void PlyExporter :: WriteMeshVerts(const aiMesh* m, unsigned int components) } } +// ------------------------------------------------------------------------------------------------ +void PlyExporter::WriteMeshVertsBinary(const aiMesh* m, unsigned int components) +{ + aiVector3D defaultNormal(0, 0, 0); + aiVector2D defaultUV(-1, -1); + aiColor4D defaultColor(-1, -1, -1, -1); + for (unsigned int i = 0; i < m->mNumVertices; ++i) { + mOutput.write(reinterpret_cast(&m->mVertices[i].x), 12); + if (components & PLY_EXPORT_HAS_NORMALS) { + if (m->HasNormals()) { + mOutput.write(reinterpret_cast(&m->mNormals[i].x), 12); + } + else { + mOutput.write(reinterpret_cast(&defaultNormal.x), 12); + } + } + + for (unsigned int n = PLY_EXPORT_HAS_TEXCOORDS, c = 0; (components & n) && c != AI_MAX_NUMBER_OF_TEXTURECOORDS; n <<= 1, ++c) { + if (m->HasTextureCoords(c)) { + mOutput.write(reinterpret_cast(&m->mTextureCoords[c][i].x), 6); + } + else { + mOutput.write(reinterpret_cast(&defaultUV.x), 6); + } + } + + for (unsigned int n = PLY_EXPORT_HAS_COLORS, c = 0; (components & n) && c != AI_MAX_NUMBER_OF_COLOR_SETS; n <<= 1, ++c) { + if (m->HasVertexColors(c)) { + mOutput.write(reinterpret_cast(&m->mColors[c][i].r), 16); + } + else { + mOutput.write(reinterpret_cast(&defaultColor.r), 16); + } + } + + if (components & PLY_EXPORT_HAS_TANGENTS_BITANGENTS) { + if (m->HasTangentsAndBitangents()) { + mOutput.write(reinterpret_cast(&m->mTangents[i].x), 12); + mOutput.write(reinterpret_cast(&m->mBitangents[i].x), 12); + } + else { + mOutput.write(reinterpret_cast(&defaultNormal.x), 12); + mOutput.write(reinterpret_cast(&defaultNormal.x), 12); + } + } + } +} + // ------------------------------------------------------------------------------------------------ void PlyExporter :: WriteMeshIndices(const aiMesh* m, unsigned int offset) { @@ -248,4 +327,16 @@ void PlyExporter :: WriteMeshIndices(const aiMesh* m, unsigned int offset) } } +void PlyExporter::WriteMeshIndicesBinary(const aiMesh* m, unsigned int offset) +{ + for (unsigned int i = 0; i < m->mNumFaces; ++i) { + const aiFace& f = m->mFaces[i]; + mOutput.write(reinterpret_cast(&f.mNumIndices), 4); + for (unsigned int c = 0; c < f.mNumIndices; ++c) { + unsigned int index = f.mIndices[c] + offset; + mOutput.write(reinterpret_cast(&index), 4); + } + } +} + #endif diff --git a/code/PlyExporter.h b/code/PlyExporter.h index a0a0e9091..522821b1a 100644 --- a/code/PlyExporter.h +++ b/code/PlyExporter.h @@ -59,7 +59,7 @@ class PlyExporter { public: /// Constructor for a specific scene to export - PlyExporter(const char* filename, const aiScene* pScene); + PlyExporter(const char* filename, const aiScene* pScene, bool binary = false); public: @@ -71,6 +71,9 @@ private: void WriteMeshVerts(const aiMesh* m, unsigned int components); void WriteMeshIndices(const aiMesh* m, unsigned int ofs); + void WriteMeshVertsBinary(const aiMesh* m, unsigned int components); + void WriteMeshIndicesBinary(const aiMesh* m, unsigned int offset); + private: const std::string filename;