Commit 97986824 authored by Isaak Lim's avatar Isaak Lim

implemented saving with assimp

refs #1274

git-svn-id: http://www.openflipper.org/svnrepo/OpenFlipper/branches/Free-Staging@16830 383ad7c9-94d9-4d36-a494-682f7c89f535
parent bf3e05de
......@@ -45,9 +45,67 @@
#include "AssimpPlugin.hh"
#include <assimp/Importer.hpp>
#include <assimp/scene.h>
#include <assimp/postprocess.h>
/*
* we have to implement our own aiScene and aiMaterial constructor/destructor
* since the linker cannot find the corresponding symbols from the
* assimp library
*/
aiMaterial::aiMaterial() {
mNumAllocated = 0;
mNumProperties = 0;
mProperties = NULL;
}
aiMaterial::~aiMaterial() {
for (unsigned int i = 0; i < mNumProperties; ++i)
delete mProperties[i];
delete[] mProperties;
}
aiScene::aiScene() {
mFlags = 0;
mRootNode = NULL;
mNumMeshes = 0;
mMeshes = NULL;
mNumMaterials = 0;
mMaterials = NULL;
mNumAnimations = 0;
mAnimations = NULL;
mNumTextures = 0;
mTextures = NULL;
mNumLights = 0;
mLights = NULL;
mNumCameras = 0;
mCameras = NULL;
}
aiScene::~aiScene() {
delete mRootNode;
for (unsigned int i = 0; i < mNumMeshes; ++i)
delete mMeshes[i];
delete[] mMeshes;
for (unsigned int i = 0; i < mNumMaterials; ++i)
delete mMaterials[i];
delete[] mMaterials;
for (unsigned int i = 0; i < mNumAnimations; ++i)
delete mAnimations[i];
delete[] mAnimations;
for (unsigned int i = 0; i < mNumTextures; ++i)
delete mTextures[i];
delete[] mTextures;
for (unsigned int i = 0; i < mNumLights; ++i)
delete mLights[i];
delete[] mLights;
for (unsigned int i = 0; i < mNumCameras; ++i)
delete mCameras[i];
delete[] mCameras;
}
AssimpPlugin::AssimpPlugin()
:
......@@ -60,7 +118,7 @@ AssimpPlugin::AssimpPlugin()
void AssimpPlugin::initializePlugin() {
}
int AssimpPlugin::convertToOpenMesh(const aiScene *_scene) {
int AssimpPlugin::convertAiSceneToOpenMesh(const aiScene *_scene, QString _objectName) {
int objectId = -1;
emit addEmptyObject(type_, objectId);
......@@ -70,19 +128,21 @@ int AssimpPlugin::convertToOpenMesh(const aiScene *_scene) {
return -1;
}
object->setName(_objectName);
PolyMeshObject* polyMeshObj = dynamic_cast< PolyMeshObject* > (object);
TriMeshObject* triMeshObj = dynamic_cast< TriMeshObject* > (object);
if (polyMeshObj) {
for (unsigned int i = 0; i < _scene->mNumMeshes; ++i)
convertAiMesh(polyMeshObj->mesh(), _scene->mMeshes[i]);
convertPolyMeshToAiMesh(polyMeshObj->mesh(), _scene->mMeshes[i]);
polyMeshObj->update();
polyMeshObj->show();
} else if (triMeshObj) {
for (unsigned int i = 0; i < _scene->mNumMeshes; ++i)
convertAiMesh(triMeshObj->mesh(), _scene->mMeshes[i]);
convertAiMeshToTriMesh(triMeshObj->mesh(), _scene->mMeshes[i]);
triMeshObj->update();
triMeshObj->show();
......@@ -96,7 +156,34 @@ int AssimpPlugin::convertToOpenMesh(const aiScene *_scene) {
return objectId;
}
void AssimpPlugin::convertAiMesh(PolyMesh *_polyMesh, aiMesh *_mesh) {
bool AssimpPlugin::convertOpenMeshToAiScene(aiScene *_scene, BaseObjectData *_object) {
_scene->mMeshes = new aiMesh*[1];
_scene->mMeshes[0] = new aiMesh();
_scene->mNumMeshes = 1;
_scene->mRootNode = new aiNode();
_scene->mRootNode->mNumChildren = 0;
_scene->mRootNode->mNumMeshes = 1;
_scene->mRootNode->mMeshes = new unsigned int[1];
_scene->mRootNode->mMeshes[0] = 0;
// assimp requires at least one material
_scene->mMaterials = new aiMaterial*[1];
_scene->mMaterials[0] = new aiMaterial();
_scene->mNumMaterials = 1;
if ( _object->dataType( DATA_POLY_MESH ) ) {
return convertPolyMeshToAiMesh(dynamic_cast<PolyMeshObject*>(_object)->mesh(), _scene->mMeshes[0]);
}
else if ( _object->dataType( DATA_TRIANGLE_MESH ) ) {
return convertTriMeshToAiMesh(dynamic_cast<TriMeshObject*>(_object)->mesh(), _scene->mMeshes[0]);
}
else {
emit log(LOGERR, tr("Unable to save (object is not a compatible mesh type)"));
return false;
}
}
void AssimpPlugin::convertAiMeshToPolyMesh(PolyMesh *_polyMesh, aiMesh *_mesh) {
mapVertices(_polyMesh, _mesh);
std::vector<OpenMesh::VertexHandle> vhandles;
......@@ -120,7 +207,7 @@ void AssimpPlugin::convertAiMesh(PolyMesh *_polyMesh, aiMesh *_mesh) {
_polyMesh->update_face_normals();
}
void AssimpPlugin::convertAiMesh(TriMesh *_triMesh, aiMesh *_mesh) {
void AssimpPlugin::convertAiMeshToTriMesh(TriMesh *_triMesh, aiMesh *_mesh) {
mapVertices(_triMesh, _mesh);
std::vector<OpenMesh::VertexHandle> vhandles;
......@@ -144,6 +231,75 @@ void AssimpPlugin::convertAiMesh(TriMesh *_triMesh, aiMesh *_mesh) {
_triMesh->update_face_normals();
}
bool AssimpPlugin::convertPolyMeshToAiMesh(PolyMesh *_polyMesh, aiMesh *_mesh) {
_mesh->mPrimitiveTypes = aiPrimitiveType_POLYGON;
_mesh->mNumVertices = _polyMesh->n_vertices();
_mesh->mNumFaces = _polyMesh->n_faces();
_mesh->mVertices = new aiVector3D[_mesh->mNumVertices];
_mesh->mNormals = new aiVector3D[_mesh->mNumVertices];
_mesh->mFaces = new aiFace[_mesh->mNumFaces];
std::map<OpenMesh::VertexHandle, int> vertexHandles;
int i = 0;
for (PolyMesh::ConstVertexIter v_it = _polyMesh->vertices_begin(); v_it != _polyMesh->vertices_end(); ++v_it, ++i) {
ACG::Vec3d pos = _polyMesh->point(v_it);
ACG::Vec3d normal = _polyMesh->normal(v_it);
_mesh->mVertices[i] = aiVector3D(pos[0], pos[1], pos[2]);
_mesh->mNormals[i] = aiVector3D(normal[0], normal[1], normal[2]);
vertexHandles[*v_it] = i;
}
i = 0;
for (PolyMesh::ConstFaceIter f_it = _polyMesh->faces_begin(); f_it != _polyMesh->faces_end(); ++f_it, ++i) {
int nVertices = 0;
for (PolyMesh::ConstFaceVertexIter fv_it = _polyMesh->fv_iter(*f_it); fv_it; ++fv_it) {
++nVertices;
}
_mesh->mFaces[i].mNumIndices = nVertices;
_mesh->mFaces[i].mIndices = new unsigned int[nVertices];
int j = 0;
for (PolyMesh::ConstFaceVertexIter fv_it = _polyMesh->fv_iter(*f_it); fv_it; ++fv_it, ++j) {
_mesh->mFaces[i].mIndices[j] = vertexHandles[fv_it];
}
}
return true;
}
bool AssimpPlugin::convertTriMeshToAiMesh(TriMesh *_triMesh, aiMesh *_mesh) {
_mesh->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
_mesh->mNumVertices = _triMesh->n_vertices();
_mesh->mNumFaces = _triMesh->n_faces();
_mesh->mVertices = new aiVector3D[_mesh->mNumVertices];
_mesh->mNormals = new aiVector3D[_mesh->mNumVertices];
_mesh->mFaces = new aiFace[_mesh->mNumFaces];
std::map<OpenMesh::VertexHandle, int> vertexHandles;
int i = 0;
for (TriMesh::ConstVertexIter v_it = _triMesh->vertices_begin(); v_it != _triMesh->vertices_end(); ++v_it, ++i) {
ACG::Vec3d pos = _triMesh->point(v_it);
ACG::Vec3d normal = _triMesh->normal(v_it);
_mesh->mVertices[i] = aiVector3D(pos[0], pos[1], pos[2]);
_mesh->mNormals[i] = aiVector3D(normal[0], normal[1], normal[2]);
vertexHandles[*v_it] = i;
}
i = 0;
for (TriMesh::ConstFaceIter f_it = _triMesh->faces_begin(); f_it != _triMesh->faces_end(); ++f_it, ++i) {
_mesh->mFaces[i].mNumIndices = 3;
_mesh->mFaces[i].mIndices = new unsigned int[3];
int j = 0;
for (PolyMesh::ConstFaceVertexIter fv_it = _triMesh->fv_iter(*f_it); fv_it; ++fv_it, ++j) {
_mesh->mFaces[i].mIndices[j] = vertexHandles[fv_it];
}
}
return true;
}
void AssimpPlugin::mapVertices(PolyMesh *_polyMesh, aiMesh *_mesh) {
vertexHandles_.clear();
......@@ -167,11 +323,11 @@ DataType AssimpPlugin::supportedType() {
QString AssimpPlugin::getSaveFilters() {
return QString( tr("Alias/Wavefront ( *.obj )") );
return QString( tr("Alias/Wavefront ( *.obj );;Collada ( *.dae );;Stereolithography files ( *.stl );;Polygon File Format files ( *.ply )" ) );
}
QString AssimpPlugin::getLoadFilters() {
return QString( tr("Alias/Wavefront ( *.obj )") );
return QString( tr("Alias/Wavefront ( *.obj );;AutoCAD DXF ( *.dxf );;Collada ( *.dae );;Stereolithography files ( *.stl );;Polygon File Format files ( *.ply )") );
}
QWidget *AssimpPlugin::saveOptionsWidget(QString) {
......@@ -204,7 +360,8 @@ int AssimpPlugin::loadObject(QString _filename) {
return -1;
}
return convertToOpenMesh(scene);
QFileInfo f(_filename);
return convertAiSceneToOpenMesh(scene, f.fileName());
}
int AssimpPlugin::loadObject(QString _filename, DataType _type) {
......@@ -213,7 +370,32 @@ int AssimpPlugin::loadObject(QString _filename, DataType _type) {
}
bool AssimpPlugin::saveObject(int _id, QString _filename) {
return true;
BaseObjectData* object;
PluginFunctions::getObject(_id,object);
if (!object) {
emit log(LOGERR, tr("Could not get the object with the given id"));
return false;
}
object->setFromFileName(_filename);
object->setName(object->filename());
aiScene scene;
if (!convertOpenMeshToAiScene(&scene, object))
return false;
Assimp::Exporter exporter;
QFileInfo f(_filename);
std::string formatId = (f.suffix() == "dae") ? "collada" : f.suffix().toStdString();
bool ok = exporter.Export(&scene, formatId, _filename.toStdString()) == AI_SUCCESS;
if (!ok)
emit log(LOGERR, exporter.GetErrorString());
return ok;
}
Q_EXPORT_PLUGIN2( assimpplugin , AssimpPlugin );
Q_EXPORT_PLUGIN2( assimpplugin , AssimpPlugin )
......@@ -59,8 +59,11 @@
#include <ObjectTypes/PolyMesh/PolyMesh.hh>
#include <ObjectTypes/TriangleMesh/TriangleMesh.hh>
struct aiScene;
struct aiMesh;
#include <assimp/Importer.hpp>
#include <assimp/Exporter.hpp>
#include <assimp/postprocess.h>
#include <assimp/scene.h>
class AssimpPlugin : public QObject, BaseInterface, FileInterface, LoadSaveInterface,
LoggingInterface, ScriptInterface
......@@ -119,13 +122,19 @@ private slots:
private:
int convertToOpenMesh(const aiScene* _scene);
int convertAiSceneToOpenMesh(const aiScene* _scene, QString _objectName);
bool convertOpenMeshToAiScene(aiScene* _scene, BaseObjectData* _object);
/// converts _mesh into _polyMesh
void convertAiMesh(PolyMesh* _polyMesh, aiMesh* _mesh);
void convertAiMeshToPolyMesh(PolyMesh* _polyMesh, aiMesh* _mesh);
/// converts _mesh into _triMesh
void convertAiMesh(TriMesh* _triMesh, aiMesh* _mesh);
void convertAiMeshToTriMesh(TriMesh* _triMesh, aiMesh* _mesh);
bool convertPolyMeshToAiMesh(PolyMesh* _polyMesh, aiMesh* _mesh);
bool convertTriMeshToAiMesh(TriMesh* _triMesh, aiMesh* _mesh);
/// add a vertex from _mesh to _polyMesh and stores the index to handle mapping
void mapVertices(PolyMesh* _polyMesh, aiMesh* _mesh);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment