add binary exporter to STLExporter

pull/70/head
YoheiKakiuchi 2013-07-31 20:15:59 +09:00
parent 3542bad65d
commit 4ccb16fe01
3 changed files with 68 additions and 8 deletions

View File

@ -73,6 +73,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*) {}
@ -93,6 +94,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

View File

@ -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,7 +89,23 @@ 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);
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"; const std::string& name = "AssimpScene";
mOutput << "solid " << name << endl; mOutput << "solid " << name << endl;
@ -84,6 +113,7 @@ STLExporter :: STLExporter(const char* _filename, const aiScene* pScene)
WriteMesh(pScene->mMeshes[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 #endif

View File

@ -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: