浏览代码

Merge pull request #70 from YoheiKakiuchi/master

Add binary exporter to STLExporter
Alexander Gessler 12 年之前
父节点
当前提交
36a899abcf
共有 3 个文件被更改,包括 70 次插入8 次删除
  1. 4 0
      code/Exporter.cpp
  2. 64 7
      code/STLExporter.cpp
  3. 2 1
      code/STLExporter.h

+ 4 - 0
code/Exporter.cpp

@@ -74,6 +74,7 @@ void GetPostProcessingStepInstanceList(std::vector< BaseProcess* >& out);
 void ExportSceneCollada(const char*,IOSystem*, const aiScene*);
 void ExportSceneCollada(const char*,IOSystem*, const aiScene*);
 void ExportSceneObj(const char*,IOSystem*, const aiScene*);
 void ExportSceneObj(const char*,IOSystem*, const aiScene*);
 void ExportSceneSTL(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 ExportScenePly(const char*,IOSystem*, const aiScene*);
 void ExportScene3DS(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, 
 	Exporter::ExportFormatEntry( "stl", "Stereolithography", "stl" , &ExportSceneSTL, 
 		aiProcess_Triangulate | aiProcess_GenNormals | aiProcess_PreTransformVertices
 		aiProcess_Triangulate | aiProcess_GenNormals | aiProcess_PreTransformVertices
 	),
 	),
+	Exporter::ExportFormatEntry( "stlb", "Stereolithography(binary)", "stlb" , &ExportSceneSTLBinary, 
+		aiProcess_Triangulate | aiProcess_GenNormals | aiProcess_PreTransformVertices
+	),
 #endif
 #endif
 
 
 #ifndef ASSIMP_BUILD_NO_PLY_EXPORTER
 #ifndef ASSIMP_BUILD_NO_PLY_EXPORTER

+ 64 - 7
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<size_t>(exporter.mOutput.tellp()),1);
 	outfile->Write( exporter.mOutput.str().c_str(), static_cast<size_t>(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<IOStream> 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<size_t>(exporter.mOutput.tellp()),1);
+}
 
 
 } // end of namespace Assimp
 } // end of namespace Assimp
 
 
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
-STLExporter :: STLExporter(const char* _filename, const aiScene* pScene)
+STLExporter :: STLExporter(const char* _filename, const aiScene* pScene, bool binary)
 : filename(_filename)
 : filename(_filename)
 , pScene(pScene)
 , pScene(pScene)
 , endl("\n") 
 , 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
 	// 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");
 	const std::locale& l = std::locale("C");
 	mOutput.imbue(l);
 	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
 #endif

+ 2 - 1
code/STLExporter.h

@@ -59,7 +59,7 @@ class STLExporter
 {
 {
 public:
 public:
 	/// Constructor for a specific scene to export
 	/// 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:
 public:
 
 
@@ -69,6 +69,7 @@ public:
 private:
 private:
 
 
 	void WriteMesh(const aiMesh* m);
 	void WriteMesh(const aiMesh* m);
+	void WriteMeshBinary(const aiMesh* m);
 
 
 private:
 private: