STL exporting using assimp
This commit is contained in:
@@ -183,6 +183,94 @@ namespace OpenVulkano::Scene
|
|||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
throw std::runtime_error("Unable to convert the scene to FBX: Assimp is not available!");
|
throw std::runtime_error("Unable to convert the scene to FBX: Assimp is not available!");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void MeshWriter::WriteAsSTL(Geometry* geometry, const std::string& filePath, bool binary)
|
||||||
|
{
|
||||||
|
#if __has_include("assimp/Exporter.hpp")
|
||||||
|
aiNode rootNode;
|
||||||
|
|
||||||
|
aiScene scene;
|
||||||
|
scene.mRootNode = &rootNode;
|
||||||
|
|
||||||
|
aiMesh mesh;
|
||||||
|
mesh.mNumVertices = geometry->vertexCount;
|
||||||
|
mesh.mMaterialIndex = 0;
|
||||||
|
mesh.mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
|
||||||
|
|
||||||
|
std::unique_ptr<aiVector3D[]> vertices = std::make_unique<aiVector3D[]>(geometry->vertexCount);
|
||||||
|
mesh.mVertices = vertices.get();
|
||||||
|
|
||||||
|
std::unique_ptr<aiVector3D[]> normals = std::make_unique<aiVector3D[]>(geometry->vertexCount);
|
||||||
|
mesh.mNormals = normals.get();
|
||||||
|
|
||||||
|
for (int i = 0; i < geometry->vertexCount; ++i)
|
||||||
|
{
|
||||||
|
const Vertex& vertex = geometry->vertices[i];
|
||||||
|
mesh.mVertices[i] = aiVector3D(vertex.position.x, vertex.position.y, vertex.position.z);
|
||||||
|
mesh.mNormals[i] = aiVector3D(vertex.normal.x, vertex.normal.y, vertex.normal.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
mesh.mNumFaces = geometry->indexCount / 3;
|
||||||
|
std::unique_ptr<aiFace[]> faces = std::make_unique<aiFace[]>(mesh.mNumFaces);
|
||||||
|
mesh.mFaces = faces.get();
|
||||||
|
|
||||||
|
std::unique_ptr<unsigned int[]> indices = std::make_unique<unsigned int[]>(geometry->indexCount);
|
||||||
|
size_t lastUsedIndex = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < mesh.mNumFaces; ++i)
|
||||||
|
{
|
||||||
|
aiFace& face = mesh.mFaces[i];
|
||||||
|
face.mNumIndices = 3;
|
||||||
|
face.mIndices = &indices[lastUsedIndex];
|
||||||
|
|
||||||
|
face.mIndices[0] = geometry->GetIndex(i * 3 + 0);
|
||||||
|
face.mIndices[1] = geometry->GetIndex(i * 3 + 1);
|
||||||
|
face.mIndices[2] = geometry->GetIndex(i * 3 + 2);
|
||||||
|
|
||||||
|
lastUsedIndex += face.mNumIndices;
|
||||||
|
}
|
||||||
|
|
||||||
|
aiMesh* meshes[1] = { &mesh };
|
||||||
|
scene.mMeshes = meshes;
|
||||||
|
scene.mNumMeshes = 1;
|
||||||
|
|
||||||
|
unsigned int meshIndices[1];
|
||||||
|
scene.mRootNode->mMeshes = meshIndices;
|
||||||
|
scene.mRootNode->mMeshes[0] = 0;
|
||||||
|
scene.mRootNode->mNumMeshes = 1;
|
||||||
|
|
||||||
|
// STL doesn't use materials, but Assimp requires at least one
|
||||||
|
aiMaterial material;
|
||||||
|
aiMaterial* materials[1] = { &material };
|
||||||
|
scene.mMaterials = materials;
|
||||||
|
scene.mNumMaterials = 1;
|
||||||
|
|
||||||
|
Assimp::Exporter exporter;
|
||||||
|
const char* formatId = binary ? "stlb" : "stl";
|
||||||
|
aiReturn result = exporter.Export(&scene, formatId, filePath);
|
||||||
|
|
||||||
|
mesh.mVertices = nullptr;
|
||||||
|
mesh.mNormals = nullptr;
|
||||||
|
for (int i = 0; i < mesh.mNumFaces; ++i)
|
||||||
|
{
|
||||||
|
aiFace& face = mesh.mFaces[i];
|
||||||
|
face.mIndices = nullptr;
|
||||||
|
}
|
||||||
|
mesh.mFaces = nullptr;
|
||||||
|
|
||||||
|
rootNode.mMeshes = nullptr;
|
||||||
|
scene.mRootNode = nullptr;
|
||||||
|
scene.mMeshes = nullptr;
|
||||||
|
scene.mMaterials = nullptr;
|
||||||
|
|
||||||
|
if (result != aiReturn_SUCCESS)
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Unable to write STL file to " + filePath + ": " + exporter.GetErrorString());
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
throw std::runtime_error("Unable to export to STL: Assimp is not available!");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -19,5 +19,6 @@ namespace OpenVulkano::Scene
|
|||||||
static void WriteObjAsZip(Geometry* geometry, const std::string& texturePath, const std::string& zipPath);
|
static void WriteObjAsZip(Geometry* geometry, const std::string& texturePath, const std::string& zipPath);
|
||||||
static void WriteAsUSDZ(Geometry* geometry, const std::string& texturePath, const std::string& usdzPath);
|
static void WriteAsUSDZ(Geometry* geometry, const std::string& texturePath, const std::string& usdzPath);
|
||||||
static void WriteAsFBX(Geometry* geometry, const std::string& texturePath, const std::string& fbxPath);
|
static void WriteAsFBX(Geometry* geometry, const std::string& texturePath, const std::string& fbxPath);
|
||||||
|
static void WriteAsSTL(Geometry* geometry, const std::string& filePath, bool binary);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user