Commit 2790e9f3 authored by Martin Schultz's avatar Martin Schultz

added widgets folder to cmakelists

modified assimpPlugin to split loading of components to different
functions
parent 7db6f547
......@@ -44,22 +44,64 @@
#include "AssimpPlugin.hh"
#include <Type-Light/ObjectTypes/Light/Light.hh>
#include <Type-Light/ObjectTypes/Light/LightObject.hh>
#include <ObjectTypes/Light/LightNode.hh>
#include <OpenMesh/Core/Geometry/VectorT.hh>
#include <Type-Light/ObjectTypes/Light/PluginFunctionsLight.hh>
// Defines for the type handling drop down box
#define TYPEAUTODETECT 0
#define TYPEASK 1
#define TYPEPOLY 2
#define TYPETRIANGLE 3
#include <ObjectTypes/Camera/Camera.hh>
#include "AssimpPluginCommon.hh"
#include "widgets/AssimpOptionsWidget.hh"
#include "widgets/AssimpLoadOptionsWidget.hh"
#include "widgets/AssimpSaveOptionsWidget.hh"
using namespace OpenMesh;
namespace
{
//helper function to convert aiVector to OpenMeshVector
template<typename T, typename R>
static T toOMVec(R _vec)
{
T res;
for(size_t i = 0 ; i < res.size() ; ++i )
res[i] = _vec[i];
return res;
}
}
// static variable to conveniently iterate over all texture types of assimp
std::vector<aiTextureType> allTextureTypes = {aiTextureType_UNKNOWN ,
aiTextureType_AMBIENT ,
aiTextureType_DIFFUSE ,
aiTextureType_DISPLACEMENT ,
aiTextureType_EMISSIVE ,
aiTextureType_HEIGHT ,
aiTextureType_LIGHTMAP ,
aiTextureType_NONE ,
aiTextureType_NORMALS ,
aiTextureType_OPACITY ,
aiTextureType_REFLECTION ,
aiTextureType_SHININESS ,
aiTextureType_SPECULAR };
AssimpPlugin::AssimpPlugin()
:
loadOptions_(nullptr),
saveOptions_(nullptr),
type_(DATA_TRIANGLE_MESH),
options_(),
type_(DATA_UNKNOWN),
cancel_(false)
{
processSteps = aiProcess_FindDegenerates | aiProcess_JoinIdenticalVertices | 0;
}
//--------------------------------------------------------------------------
void AssimpPlugin::initializePlugin() {
QString info =
......@@ -92,68 +134,55 @@ void AssimpPlugin::initializePlugin() {
emit addAboutInfo(info,"File-Assimp Plugin");
connect(this, SIGNAL(showConfirmationDialog(const QString&, const QString&)), this, SLOT(slotShowConfirmationDialog(const QString&, const QString&)), Qt::BlockingQueuedConnection);
connect(this, SIGNAL(showConfirmationDialog(const QString&, const QString&)), this, SLOT(slotShowConfirmationDialog(const QString&, const QString&)), Qt::BlockingQueuedConnection);
}
//--------------------------------------------------------------------------
int AssimpPlugin::convertAiSceneToOpenMesh(const aiScene *_scene, QString _objectName) {
int returnId = -1;
std::vector<int> ids;
embeddedTextures_.clear();
loadedImages_.clear();
if (_scene->mNumMeshes == 0)
emit log(LOGWARN, tr("aiScene contains no meshes"));
if(_scene->mNumMaterials > 1)
// TODO: change the confirmation dialog to a selection dialog where the user can select how to deal with multiple materials
if(_scene->mNumMaterials > 1 && OpenFlipper::Options::gui())
{
if(!emit showConfirmationDialog(tr("Multiple MAterials in file"),
if(!emit showConfirmationDialog(tr("Multiple Materials in file"),
tr("The File you are trying to load contains %1 materials. "
"Assimp creates a separate Mesh for each material, which may cause performance issues.\n\n "
"Do you want to continue loading the file?").arg(_scene->mNumMaterials)))
return returnId;
}
//load textures first if requested,
//as they are referenced by the materials
if(options_.loadTexturesOption_)
loadTexturesFromScene(_scene);
// we always want to load meshes
loadMeshesFromScene(_scene, ids, _objectName);
returnId = ids[0];
#ifdef ENABLE_CAMERA_SUPPORT
if(options_.loadCamerasOption_)
loadCamerasFromScene(_scene);
#endif
#ifdef ENABLE_LIGHT_SUPPORT
if(options_.loadLightsOption_)
loadLightsFromScene(_scene);
#endif
#ifdef ENABLE_SKELETON_SUPPORT
if(options_.loadAnimationsOption_)
loadAnimationsFromScene(_scene);
#endif
for (unsigned int i = 0; i < _scene->mNumMeshes && !cancel_; ++i) {
int objectId = -1;
if(type_ == DATA_UNKNOWN)
{
if(_scene->mMeshes[i]->mPrimitiveTypes & aiPrimitiveType_POLYGON)
emit addEmptyObject(DATA_POLY_MESH, objectId);
else
emit addEmptyObject(DATA_TRIANGLE_MESH, objectId);
}
else
emit addEmptyObject(type_, objectId);
BaseObject* object(0);
if(!PluginFunctions::getObject( objectId, object )) {
emit log(LOGERR, tr("Could not create new object!"));
return -1;
}
if (i == 0)
returnId = objectId;
object->setName(_objectName);
PolyMeshObject* polyMeshObj = dynamic_cast< PolyMeshObject* > (object);
TriMeshObject* triMeshObj = dynamic_cast< TriMeshObject* > (object);
if (polyMeshObj) {
convertAiMeshToPolyMesh(polyMeshObj->mesh(), _scene->mMeshes[i]);
emit updatedObject(polyMeshObj->id(), UPDATE_ALL);
ids.push_back(object->id());
} else if (triMeshObj) {
convertAiMeshToTriMesh(triMeshObj->mesh(), _scene->mMeshes[i]);
emit updatedObject(triMeshObj->id(), UPDATE_ALL);
ids.push_back(object->id());
}
emit openedFile( object->id() );
}
//group OpenFlipper objects, if the file contains multiple meshes
if (_scene->mNumMeshes > 1) {
bool dataControlExists = false;
pluginExists( "datacontrol", dataControlExists );
......@@ -166,6 +195,8 @@ int AssimpPlugin::convertAiSceneToOpenMesh(const aiScene *_scene, QString _objec
return returnId;
}
//--------------------------------------------------------------------------
bool AssimpPlugin::convertOpenMeshToAiScene(aiScene *_scene, BaseObjectData *_object) {
_scene->mMeshes = new aiMesh*[1];
_scene->mMeshes[0] = new aiMesh();
......@@ -193,6 +224,8 @@ bool AssimpPlugin::convertOpenMeshToAiScene(aiScene *_scene, BaseObjectData *_ob
}
}
//--------------------------------------------------------------------------
void AssimpPlugin::convertAiMeshToPolyMesh(PolyMesh *_polyMesh, aiMesh *_mesh) {
mapVertices(_polyMesh, _mesh);
......@@ -201,12 +234,11 @@ void AssimpPlugin::convertAiMeshToPolyMesh(PolyMesh *_polyMesh, aiMesh *_mesh) {
aiFace& face = _mesh->mFaces[i];
for (unsigned int j = 0; j < face.mNumIndices; ++j) {
vhandles.push_back(vertexHandles_[face.mIndices[j]]);
if (_mesh->HasNormals()) {
if (_mesh->HasNormals() && options_.loadNormalsOption_) {
aiVector3D& aiNormal = _mesh->mNormals[face.mIndices[j]];
_polyMesh->set_normal(vhandles.back(), ACG::Vec3d(aiNormal.x, aiNormal.y, aiNormal.z));
}
}
_polyMesh->add_face(vhandles);
vhandles.clear();
}
......@@ -217,6 +249,8 @@ void AssimpPlugin::convertAiMeshToPolyMesh(PolyMesh *_polyMesh, aiMesh *_mesh) {
_polyMesh->update_face_normals();
}
//--------------------------------------------------------------------------
void AssimpPlugin::convertAiMeshToTriMesh(TriMesh *_triMesh, aiMesh *_mesh) {
mapVertices(_triMesh, _mesh);
......@@ -225,7 +259,7 @@ void AssimpPlugin::convertAiMeshToTriMesh(TriMesh *_triMesh, aiMesh *_mesh) {
aiFace& face = _mesh->mFaces[i];
for (unsigned int j = 0; j < face.mNumIndices; ++j) {
vhandles.push_back(vertexHandles_[face.mIndices[j]]);
if (_mesh->HasNormals()) {
if (_mesh->HasNormals() && options_.loadNormalsOption_) {
aiVector3D& aiNormal = _mesh->mNormals[face.mIndices[j]];
_triMesh->set_normal(vhandles.back(), ACG::Vec3d(aiNormal.x, aiNormal.y, aiNormal.z));
}
......@@ -241,6 +275,8 @@ void AssimpPlugin::convertAiMeshToTriMesh(TriMesh *_triMesh, aiMesh *_mesh) {
_triMesh->update_face_normals();
}
//--------------------------------------------------------------------------
bool AssimpPlugin::convertPolyMeshToAiMesh(PolyMesh *_polyMesh, aiMesh *_mesh) {
_mesh->mPrimitiveTypes = aiPrimitiveType_POLYGON;
_mesh->mNumVertices = _polyMesh->n_vertices();
......@@ -278,6 +314,8 @@ bool AssimpPlugin::convertPolyMeshToAiMesh(PolyMesh *_polyMesh, aiMesh *_mesh) {
return true;
}
//--------------------------------------------------------------------------
bool AssimpPlugin::convertTriMeshToAiMesh(TriMesh *_triMesh, aiMesh *_mesh) {
_mesh->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
_mesh->mNumVertices = _triMesh->n_vertices();
......@@ -310,326 +348,295 @@ bool AssimpPlugin::convertTriMeshToAiMesh(TriMesh *_triMesh, aiMesh *_mesh) {
return true;
}
void AssimpPlugin::mapVertices(PolyMesh *_polyMesh, aiMesh *_mesh) {
vertexHandles_.clear();
//--------------------------------------------------------------------------
void AssimpPlugin::loadAnimationsFromScene(const aiScene* _scene)
{
for(unsigned int i = 0 ; !cancel_ && i < _scene->mNumAnimations ; ++i)
{
//TODO: implement animation loading
}
}
//--------------------------------------------------------------------------
void AssimpPlugin::loadLightsFromScene(const aiScene* _scene)
{
for(unsigned int i = 0 ; !cancel_ && i < _scene->mNumLights ; ++i)
{
//only support point lights for now
//TODO: support more light types
if(_scene->mLights[i]->mType == aiLightSource_POINT)
{
int id;
BaseObjectData* object;
emit addEmptyObject(DATA_LIGHT, id);
if(!PluginFunctions::getObject(id, object))
{
emit log(LOGERR, "could not add new light object");
return;
}
LightObject* light = PluginFunctions::lightObject(object);
if(light)
{
light->setName(_scene->mLights[i]->mName.C_Str());
//compute the absolute light position
aiNode* node = _scene->mRootNode->FindNode(_scene->mLights[i]->mName);
//TODO: check if position is always corrent, e.g. if multiple nodes are used,
//and for file formats other than blender files
aiVector3D position = node->mTransformation * _scene->mLights[i]->mPosition;
LightSource* source = PluginFunctions::lightSource(light);
source->position(toOMVec<Vec3d>(position));
source->constantAttenuation(_scene->mLights[i]->mAttenuationConstant);
source->linearAttenuation(_scene->mLights[i]->mAttenuationLinear);
source->quadraticAttenuation(_scene->mLights[i]->mAttenuationQuadratic);
source->ambientColor(color_cast<Vec4f>(toOMVec<Vec3f>(_scene->mLights[i]->mColorAmbient)));
source->diffuseColor(color_cast<Vec4f>(toOMVec<Vec3f>(_scene->mLights[i]->mColorDiffuse)));
source->specularColor(color_cast<Vec4f>(toOMVec<Vec3f>(_scene->mLights[i]->mColorSpecular)));
source->enable();
emit updatedObject(id, UPDATE_ALL);
}
}
else
emit log(LOGWARN, "unsupported light type");
}
}
//--------------------------------------------------------------------------
for (unsigned int i = 0; i < _mesh->mNumVertices; ++i) {
vertexHandles_[i] = _polyMesh->add_vertex(ACG::Vec3d(_mesh->mVertices[i].x, _mesh->mVertices[i].y, _mesh->mVertices[i].z));
void AssimpPlugin::loadCamerasFromScene(const aiScene* _scene)
{
for(unsigned int i = 0 ; !cancel_ && i < _scene->mNumCameras ; ++i)
{
int id;
emit addEmptyObject(DATA_CAMERA,id);
CameraObject* cameraObject = PluginFunctions::cameraObject(id);
if(cameraObject)
{
CameraNode* cameraNode = cameraObject->cameraNode();
cameraObject->setName(_scene->mCameras[i]->mName.C_Str());
cameraNode->setNearPlane(_scene->mCameras[i]->mClipPlaneNear);
cameraNode->setFarPlane(_scene->mCameras[i]->mClipPlaneFar);
//todo retrieve matrices
//cameraNode->
}
emit updatedObject(id,UPDATE_ALL);
}
}
void AssimpPlugin::mapVertices(TriMesh *_triMesh, aiMesh *_mesh) {
vertexHandles_.clear();
//--------------------------------------------------------------------------
void AssimpPlugin::loadTexturesFromScene(const aiScene* _scene)
{
//load embedded textures
for(unsigned int j = 0 ;!cancel_ && j < _scene->mNumTextures ; ++j)
{
aiTexture* tex = _scene->mTextures[j];
QImage img;
img = QImage::fromData(reinterpret_cast<uchar *>(tex->pcData),tex->mWidth);
embeddedTextures_.push_back(std::make_pair(QString("EmbeddedTexture_%1").arg(j).toStdString(),img));
//if you encounter cases where mHeight if tex is not 0, copy them via memcopy, or use the following code block.
/*uint sz = tex->mWidth * tex->mHeight;
QByteArray data;
data.resize(sz * 4);
uchar *p = reinterpret_cast<uchar *>(data.data());
for (uint j = 0; j < sz; ++j) {
*p++ = tex->pcData[j].r;
*p++ = tex->pcData[j].g;
*p++ = tex->pcData[j].b;
*p++ = tex->pcData[j].a;
}
img = QImage(reinterpret_cast<const uchar *>(data.constData()), tex->mWidth, tex->mHeight, QImage::Format_RGBA8888);
img.detach();*/
}
}
for (unsigned int i = 0; i < _mesh->mNumVertices; ++i) {
vertexHandles_[i] = _triMesh->add_vertex(ACG::Vec3d(_mesh->mVertices[i].x, _mesh->mVertices[i].y, _mesh->mVertices[i].z));
//--------------------------------------------------------------------------
std::vector<std::pair<std::string,QImage>> AssimpPlugin::loadTexturesFromMaterial(const aiMaterial* _material, aiTextureType _textureType)
{
std::vector<std::pair<std::string, QImage>> result;
aiString path;
for(unsigned int i = 0 ; i < _material->GetTextureCount(_textureType) ; i++ )
{
//retrieve texture path embedded textures start with * followed by the texture index e.g. *0
_material->GetTexture(_textureType, i, &path, nullptr, nullptr, nullptr, nullptr, nullptr);
if(path.length > 0)
{
if(path.C_Str()[0]=='*') // load the embedded texture
{
const char* substr = path.C_Str();
++substr; //skip leading * character
result.push_back(embeddedTextures_[std::atoi(substr)]);
}
else // load the external texture
{
QImage img(QString(path.C_Str()));
if(!img.isNull())
result.push_back(std::make_pair(path.C_Str(),img));
else
emit log(LOGWARN, QString("could not load texture: %1").arg(path.C_Str()));
}
}
path.Clear();
}
return result;
}
//--------------------------------------------------------------------------
void AssimpPlugin::loadMaterial(const aiScene* _scene, MaterialNode* _materialNode, unsigned int _materialIndex)
{
if(_materialIndex >= _scene->mNumMaterials)
{
emit log(LOGERR, "Unable to load material, index is out of bounds.");
return;
}
//load properties from the material
//TODO: load more properties if applicable
aiMaterial* mat = _scene->mMaterials[_materialIndex];
for(unsigned int i = 0; i < mat->mNumProperties ; ++i)
{
aiColor3D color;
float coefficient;
if(mat->Get(AI_MATKEY_COLOR_DIFFUSE,color)==AI_SUCCESS)
_materialNode->set_diffuse_color(color_cast<Vec4f>(toOMVec<Vec3f>(color)));
if(mat->Get(AI_MATKEY_COLOR_AMBIENT, color)==AI_SUCCESS)
_materialNode->set_ambient_color(color_cast<Vec4f>(toOMVec<Vec3f>(color)));
if(mat->Get(AI_MATKEY_COLOR_EMISSIVE, color)==AI_SUCCESS)
_materialNode->set_emission(color_cast<Vec4f>(toOMVec<Vec3f>(color)));
if(mat->Get(AI_MATKEY_COLOR_SPECULAR, color)==AI_SUCCESS)
_materialNode->set_specular_color(color_cast<Vec4f>(toOMVec<Vec3f>(color)));
if(mat->Get(AI_MATKEY_REFLECTIVITY, coefficient) == AI_SUCCESS)
_materialNode->set_reflectance(coefficient);
if(mat->Get(AI_MATKEY_SHININESS, coefficient) == AI_SUCCESS)
_materialNode->set_shininess(coefficient);
}
//load textures from this material if requested
if(options_.loadTexturesOption_)
{
std::vector<std::pair<std::string, QImage>> materialImages;
for(aiTextureType type : allTextureTypes)
{
//gater all textures in a single vector
auto images = loadTexturesFromMaterial(mat,type);
materialImages.insert(materialImages.end(),images.begin(), images.end());
}
//add entry for the material
loadedImages_[_materialIndex] = materialImages;
}
}
//--------------------------------------------------------------------------
void AssimpPlugin::loadMeshesFromScene(const aiScene* _scene, std::vector<int> & _outIds, QString& _objectName)
{
// create a new OpenFlipper object for each mesh in the scene, as long as the user did not cancel loading
for (unsigned int i = 0; i < _scene->mNumMeshes && !cancel_; ++i) {
int objectId = -1;
if(type_ == DATA_UNKNOWN)
{
if(_scene->mMeshes[i]->mPrimitiveTypes & aiPrimitiveType_POLYGON)
emit addEmptyObject(DATA_POLY_MESH, objectId);
else
emit addEmptyObject(DATA_TRIANGLE_MESH, objectId);
}
else
emit addEmptyObject(type_, objectId);
BaseObject* object(0);
if(!PluginFunctions::getObject( objectId, object )) {
emit log(LOGERR, tr("Could not create new object!"));
_outIds.push_back(-1);
return;
}
object->setName(_objectName);
PolyMeshObject* polyMeshObj = dynamic_cast< PolyMeshObject* > (object);
TriMeshObject* triMeshObj = dynamic_cast< TriMeshObject* > (object);
if (polyMeshObj) {
convertAiMeshToPolyMesh(polyMeshObj->mesh(), _scene->mMeshes[i]);
loadMaterial(_scene, polyMeshObj->materialNode(),_scene->mMeshes[i]->mMaterialIndex);
} else if (triMeshObj) {
convertAiMeshToTriMesh(triMeshObj->mesh(), _scene->mMeshes[i]);
loadMaterial(_scene, triMeshObj->materialNode(),_scene->mMeshes[i]->mMaterialIndex);
}
//add the textures if requested
if(options_.loadTexturesOption_)
{
for(auto entry : loadedImages_[_scene->mMeshes[i]->mMaterialIndex])
{
emit addTexture (QString(entry.first.c_str()), entry.second, 2, objectId); //only support 2d textures for now TODO: add more
emit switchTexture (QString(entry.first.c_str()), objectId );
//TODO: investigate why new textures are not rendered. probably because texture index property is not set
//emit setTextureMode(QString(entry.first.c_str()),"indexProperty=OriginalTexIndexMapping", objectId );
}
}
_outIds.push_back(object->id());
emit updatedObject(objectId, UPDATE_ALL);
emit openedFile( object->id() );
}
}
//--------------------------------------------------------------------------
DataType AssimpPlugin::supportedType() {
DataType type = DATA_POLY_MESH | DATA_TRIANGLE_MESH | DATA_GROUP;
return type;
}
//--------------------------------------------------------------------------
QString AssimpPlugin::getSaveFilters() {
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 );;AutoCAD DXF ( *.dxf );;Collada ( *.dae );;Stereolithography files ( *.stl );;Polygon File Format files ( *.ply );;Blender 3D( *.blend );;3ds Max 3DS ( *.3ds );;3ds Max ASE( *.ase );;Industry Foundation Classes ( *.ifc );;XGL ( *.xgl *.zgl );;Lightwave ( *.lwo );;Lightwave Scene ( *.lws );;Modo ( *.lxo );;DirectX X ( *.x );;AC3D ( *.ac );;Milkshape 3D ( *.ms3d );;TrueSpace ( *.cob *.scn )") );
return QString( tr("Alias/Wavefront ( *.obj );;AutoCAD DXF ( *.dxf );;Collada ( *.dae );;Stereolithography files ( *.stl );;Polygon File Format files ( *.ply );;Blender 3D( *.blend );;3ds Max 3DS ( *.3ds );;3ds Max ASE( *.ase );;Industry Foundation Classes ( *.ifc );;XGL ( *.xgl *.zgl );;Lightwave ( *.lwo );;Lightwave Scene ( *.lws );;Modo ( *.lxo );;DirectX X ( *.x );;AC3D ( *.ac );;Milkshape 3D ( *.ms3d );;TrueSpace ( *.cob *.scn );;Filmbox ( *.fbx )") );
}
//--------------------------------------------------------------------------
QWidget *AssimpPlugin::saveOptionsWidget(QString) {
if (saveOptions_ == nullptr){
//generate widget
saveOptions_ = new QWidget();
QVBoxLayout* layout = new QVBoxLayout();
layout->setAlignment(Qt::AlignTop);
saveFaceColor_ = new QCheckBox("Save Face Colors");
saveNormals_ = new QCheckBox("Save Normals");
saveTexCoords_ = new QCheckBox("Save Texture Coordinates");
saveTextures_ = new QCheckBox("Save Textures");
QList<QWidget*> generalOptions = { saveFaceColor_, saveNormals_, saveTexCoords_, saveTextures_};
QTreeWidget* tree = new QTreeWidget();
tree->setHeaderLabel("Configuration:");
QTreeWidgetItem* advanced = new QTreeWidgetItem();
advanced->setText(0,"Advanced");
QTreeWidgetItem* general = new QTreeWidgetItem();
general->setText(0,"General");
tree->invisibleRootItem()->addChild(general);
tree->invisibleRootItem()->addChild(advanced);
save_assimp_process_calcTangentSpace = new QCheckBox("assimp_process_calcTangentSpace ");
save_assimp_process_joinIdenticalVertices = new QCheckBox("assimp_process_joinIdenticalVertices ");
save_assimp_process_makeLeftHanded = new QCheckBox("assimp_process_makeLeftHanded ");
save_assimp_process_triangulate = new QCheckBox("assimp_process_triangulate ");
save_assimp_process_removeComponent = new QCheckBox("assimp_process_removeComponent ");
save_assimp_process_genNormals = new QCheckBox("assimp_process_genNormals ");
save_assimp_process_genSmoothNormals = new QCheckBox("assimp_process_genSmoothNormals ");
save_assimp_process_splitLargeMeshes = new QCheckBox("assimp_process_splitLargeMeshes ");
save_assimp_process_preTransformVertices = new QCheckBox("assimp_process_preTransformVertices ");
save_assimp_process_limitBoneWeights = new QCheckBox("assimp_process_limitBoneWeights ");
save_assimp_process_validateDataStructure = new QCheckBox("assimp_process_validateDataStructure ");
save_assimp_process_improveCacheLocality = new QCheckBox("assimp_process_improveCacheLocality ");
save_assimp_process_removeRedundantMaterials = new QCheckBox("assimp_process_removeRedundantMaterials");
save_assimp_process_fixInfacingNormals = new QCheckBox("assimp_process_fixInfacingNormals ");
save_assimp_process_sortByPType = new QCheckBox("assimp_process_sortByPType ");
save_assimp_process_findDegenerates = new QCheckBox("assimp_process_findDegenerates ");
save_assimp_process_findInvalidData = new QCheckBox("assimp_process_findInvalidData ");
save_assimp_process_genUVCoords = new QCheckBox("assimp_process_genUVCoords ");
save_assimp_process_transformUVCoords = new QCheckBox("assimp_process_transformUVCoords ");
save_assimp_process_findInstances = new QCheckBox("assimp_process_findInstances ");
save_assimp_process_optimizeMeshes = new QCheckBox("assimp_process_optimizeMeshes ");
save_assimp_process_optimizeGraph = new QCheckBox("assimp_process_optimizeGraph ");
save_assimp_process_flipUVs = new QCheckBox("assimp_process_flipUVs ");
save_assimp_process_flipWindingOrder = new QCheckBox("assimp_process_flipWindingOrder ");
save_assimp_process_splitByBoneCount = new QCheckBox("assimp_process_splitByBoneCount ");
save_assimp_process_debone = new QCheckBox("assimp_process_debone ");
QList<QWidget*> advancedOptions= {save_assimp_process_calcTangentSpace ,
save_assimp_process_joinIdenticalVertices ,
save_assimp_process_makeLeftHanded ,
save_assimp_process_triangulate ,
save_assimp_process_removeComponent ,
save_assimp_process_genNormals ,
save_assimp_process_genSmoothNormals ,
save_assimp_process_splitLargeMeshes ,
save_assimp_process_preTransformVertices ,
save_assimp_process_limitBoneWeights ,
save_assimp_process_validateDataStructure ,
save_assimp_process_improveCacheLocality ,
save_assimp_process_removeRedundantMaterials,
save_assimp_process_fixInfacingNormals ,
save_assimp_process_sortByPType ,
save_assimp_process_findDegenerates ,
save_assimp_process_findInvalidData ,
save_assimp_process_genUVCoords ,
save_assimp_process_transformUVCoords ,
save_assimp_process_findInstances ,
save_assimp_process_optimizeMeshes ,
save_assimp_process_optimizeGraph ,
save_assimp_process_flipUVs ,
save_assimp_process_flipWindingOrder ,
save_assimp_process_splitByBoneCount ,
save_assimp_process_debone };
for(QList<QWidget*>::iterator it = advancedOptions.begin() ; it != advancedOptions.end(); ++it)
{
QTreeWidgetItem* treeWidget = new QTreeWidgetItem();
advanced->addChild(treeWidget);
tree->setItemWidget(treeWidget,0,*it);
}
for(QList<QWidget*>::iterator it = generalOptions.begin() ; it != generalOptions.end(); ++it)
{
QTreeWidgetItem* treeWidget = new QTreeWidgetItem();
general->addChild(treeWidget);
tree->setItemWidget(treeWidget,0,*it);
}
saveDefaultButton_ = new QPushButton("Make Default");
layout->addWidget(tree);
layout->addWidget(saveDefaultButton_);
saveOptions_->setLayout(layout);
connect(saveDefaultButton_, SIGNAL(clicked()), this, SLOT(slotSaveDefault()));
saveFaceColor_->setChecked( OpenFlipperSettings().value("Assimp/Save/FaceColor",true).toBool() );
saveNormals_->setChecked ( OpenFlipperSettings().value("Assimp/Save/Normals" ,true).toBool() );
saveTexCoords_->setChecked( OpenFlipperSettings().value("Assimp/Save/TexCoords",true).toBool() );
saveTextures_->setChecked ( OpenFlipperSettings().value("Assimp/Save/Textures" ,true).toBool() );
save_assimp_process_calcTangentSpace ->setChecked(OpenFlipperSettings().value( "Assimp/Save/process/calcTangentSpace" , false).toBool());
save_assimp_process_joinIdenticalVertices ->setChecked(OpenFlipperSettings().value( "Assimp/Save/process/joinIdenticalVertices" , true ).toBool());
save_assimp_process_makeLeftHanded ->setChecked(OpenFlipperSettings().value( "Assimp/Save/process/makeLeftHanded" , false).toBool());
save_assimp_process_triangulate ->setChecked(OpenFlipperSettings().value( "Assimp/Save/process/triangulate" , false).toBool());
save_assimp_process_removeComponent ->setChecked(OpenFlipperSettings().value( "Assimp/Save/process/removeComponent" , false).toBool());
save_assimp_process_genNormals ->setChecked(OpenFlipperSettings().value( "Assimp/Save/process/genNormals" , false).toBool());
save_assimp_process_genSmoothNormals ->setChecked(OpenFlipperSettings().value( "Assimp/Save/process/genSmoothNormals" , false).toBool());
save_assimp_process_splitLargeMeshes ->setChecked(OpenFlipperSettings().value( "Assimp/Save/process/splitLargeMeshes" , false).toBool());
save_assimp_process_preTransformVertices ->setChecked(OpenFlipperSettings().value( "Assimp/Save/process/preTransformVertices" , false).toBool());
save_assimp_process_limitBoneWeights ->setChecked(OpenFlipperSettings().value( "Assimp/Save/process/limitBoneWeights" , false).toBool());
save_assimp_process_validateDataStructure ->setChecked(OpenFlipperSettings().value( "Assimp/Save/process/validateDataStructure" , false).toBool());
save_assimp_process_improveCacheLocality ->setChecked(OpenFlipperSettings().value( "Assimp/Save/process/improveCacheLocality" , false).toBool());
save_assimp_process_removeRedundantMaterials ->setChecked(OpenFlipperSettings().value( "Assimp/Save/process/removeRedundantMaterials", false).toBool());
save_assimp_process_fixInfacingNormals ->setChecked(OpenFlipperSettings().value( "Assimp/Save/process/fixInfacingNormals" , false).toBool());
save_assimp_process_sortByPType ->setChecked(OpenFlipperSettings().value( "Assimp/Save/process/sortByPType" , false).toBool());
save_assimp_process_findDegenerates ->setChecked(OpenFlipperSettings().value( "Assimp/Save/process/findDegenerates" , true ).toBool());
save_assimp_process_findInvalidData ->setChecked(OpenFlipperSettings().value( "Assimp/Save/process/findInvalidData" , false).toBool());
save_assimp_process_genUVCoords ->setChecked(OpenFlipperSettings().value( "Assimp/Save/process/genUVCoords" , false).toBool());
save_assimp_process_transformUVCoords ->setChecked(OpenFlipperSettings().value( "Assimp/Save/process/transformUVCoords" , false).toBool());
save_assimp_process_findInstances ->setChecked(OpenFlipperSettings().value( "Assimp/Save/process/findInstances" , false).toBool());
save_assimp_process_optimizeMeshes ->setChecked(OpenFlipperSettings().value( "Assimp/Save/process/optimizeMeshes" , false).toBool());
save_assimp_process_optimizeGraph ->setChecked(OpenFlipperSettings().value( "Assimp/Save/process/optimizeGraph" , false).toBool());
save_assimp_process_flipUVs ->setChecked(OpenFlipperSettings().value( "Assimp/Save/process/flipUVs" , false).toBool());
save_assimp_process_flipWindingOrder ->setChecked(OpenFlipperSettings().value( "Assimp/Save/process/flipWindingOrder" , false).toBool());
save_assimp_process_splitByBoneCount ->setChecked(OpenFlipperSettings().value( "Assimp/Save/process/splitByBoneCount" , false).toBool());
save_assimp_process_debone ->setChecked(OpenFlipperSettings().value( "Assimp/Save/process/debone" , false).toBool());
saveOptions_ = new AssimpSaveOptionsWidget(options_);
}
return saveOptions_;
}
//--------------------------------------------------------------------------
QWidget *AssimpPlugin::loadOptionsWidget(QString) {
if (loadOptions_ == 0){
//generate widget
loadOptions_ = new QWidget();
QVBoxLayout* layout = new QVBoxLayout();
layout->setAlignment(Qt::AlignTop);
// generic configuration
triMeshHandling_ = new QComboBox();
triMeshHandling_->addItem( tr("Detect correct mesh type") );
triMeshHandling_->addItem( tr("Ask") );
triMeshHandling_->addItem( tr("Open as PolyMesh") );
triMeshHandling_->addItem( tr("Open as TriangleMesh") );
loadFaceColor_ = new QCheckBox("Load Vertex Colors");
loadNormals_ = new QCheckBox("Load Vertex Normals");
loadTexCoords_ = new QCheckBox("Load Vertex Texture Coordinates");
loadTextures_ = new QCheckBox("Load Textures");
//loading textures is not yet supported
loadTextures_->setDisabled(true);
QList<QWidget*> generalOptions = {triMeshHandling_, loadFaceColor_, loadNormals_, loadTexCoords_, loadTextures_};
QTreeWidget* tree = new QTreeWidget();
tree->setHeaderLabel("Configuration:");
QTreeWidgetItem* advanced = new QTreeWidgetItem();
advanced->setText(0,"Advanced");
QTreeWidgetItem* general = new QTreeWidgetItem();
general->setText(0,"General");