Skip to content
Snippets Groups Projects
Commit 7551f8af authored by Zain Selman's avatar Zain Selman :speech_balloon:
Browse files

adds additional conditions that will reduce the number of materials written....

adds additional conditions that will reduce the number of materials written. so far the speed is already useable again
parent c42cd9f4
No related tags found
No related merge requests found
......@@ -39,22 +39,17 @@
* *
\*===========================================================================*/
#define FILEOBJPLUGIN_C
#include "FileOBJ.hh"
#include <OpenMesh/Core/Utils/color_cast.hh>
#include <OpenMesh/Core/Geometry/VectorT.hh>
#include <OpenMesh/Core/Utils/color_cast.hh>
//-----------------------------------------------------------------------------------------------------
template <class MeshT>
bool FileOBJPlugin::writeMaterial(QString _filename, MeshT& _mesh, int _objId )
{
bool FileOBJPlugin::writeMaterial(QString _filename, MeshT& _mesh, int _objId) {
bool optionColorAlpha = false;
bool optionTextures = false;
bool optionCopyTextures = false;
......@@ -72,8 +67,8 @@ bool FileOBJPlugin::writeMaterial(QString _filename, MeshT& _mesh, int _objId )
std::fstream matStream(_filename.toStdString().c_str(), std::ios_base::out);
if (!matStream) {
emit log(LOGERR, tr("writeMaterial : cannot not open file %1").arg(_filename) );
emit log(LOGERR,
tr("writeMaterial : cannot not open file %1").arg(_filename));
return false;
}
......@@ -93,7 +88,8 @@ bool FileOBJPlugin::writeMaterial(QString _filename, MeshT& _mesh, int _objId )
}
// write the materials
for(MaterialList::iterator it = materials_.begin(); it != materials_.end(); ++it) {
for (MaterialList::iterator it = materials_.begin(); it != materials_.end();
++it) {
Material& mat = (*it).second;
matStream << "newmtl " << mat << '\n';
matStream << "Ka 0.5000 0.5000 0.5000" << '\n';
......@@ -112,7 +108,8 @@ bool FileOBJPlugin::writeMaterial(QString _filename, MeshT& _mesh, int _objId )
if (optionCreateTexFolder) {
QFileInfo materialFilename(_filename);
matStream << "map_Kd " << materialFilename.baseName().toStdString() << "_textures" << QDir::separator().toLatin1()
matStream << "map_Kd " << materialFilename.baseName().toStdString()
<< "_textures" << QDir::separator().toLatin1()
<< file.fileName().toStdString() << '\n';
} else {
matStream << "map_Kd " << file.fileName().toStdString() << '\n';
......@@ -134,8 +131,9 @@ bool FileOBJPlugin::writeMaterial(QString _filename, MeshT& _mesh, int _objId )
//-----------------------------------------------------------------------------------------------------
template <class MeshT>
Material& FileOBJPlugin::getMaterial(MeshT& _mesh, const OpenMesh::FaceHandle& _fh, int _objId)
{
Material& FileOBJPlugin::getMaterial(MeshT& _mesh,
const OpenMesh::FaceHandle& _fh,
int _objId) {
// check options
bool optionColorAlpha = false;
if (!OpenFlipper::Options::savingSettings() && saveOptions_ != 0)
......@@ -144,9 +142,12 @@ Material& FileOBJPlugin::getMaterial(MeshT& _mesh, const OpenMesh::FaceHandle& _
OpenMesh::Vec4f c = _mesh.color(_fh);
// If one of the entries is out of range, assume uninitialized color and set to default
// Ugly hack to ensure that materials will only be generated if initialized
if ( c[0] > 255.0 || c[1] > 255.0 || c[2] > 255.0 || c[0] < 0.0 || c[1] < 0.0 || c[2] < 0.0) {
// If one of the entries is out of range, assume uninitialized color and set
// to default Ugly hack to ensure that materials will only be generated if
// initialized
if (c[0] > 255.0 || c[1] > 255.0 || c[2] > 255.0 || c[0] < 0.0 ||
c[1] < 0.0 || c[2] < 0.0 || std::isnan(c[0]) || std::isnan(c[1]) ||
std::isnan(c[2])) {
c[0] = 155.0;
c[1] = 155.0;
c[2] = 155.0;
......@@ -161,24 +162,24 @@ Material& FileOBJPlugin::getMaterial(MeshT& _mesh, const OpenMesh::FaceHandle& _
int texIndex = -1;
OpenMesh::FPropHandleT<int> texture_index_property;
if ( _mesh.get_property_handle(texture_index_property, textureIndexPropertyName_.toStdString()) ) {
if (_mesh.get_property_handle(texture_index_property,
textureIndexPropertyName_.toStdString())) {
texIndex = _mesh.property(texture_index_property, _fh);
} else if ( _mesh.get_property_handle(texture_index_property, "f:textureindex") ) {
} else if (_mesh.get_property_handle(texture_index_property,
"f:textureindex")) {
texIndex = _mesh.property(texture_index_property, _fh);
} else if (_mesh.has_face_texture_index()) {
texIndex = _mesh.texture_index(_fh);
} else {
QString texName;
emit getCurrentTexture(_objId, texName);
if(texName != "NONE")
emit textureIndex(texName, _objId, texIndex);
if (texName != "NONE") emit textureIndex(texName, _objId, texIndex);
}
QString filename;
bool hasTexture = false;
if (texIndex != -1) {
// Search for texture index in local map
std::map<int, QString>::iterator it = texIndexFileMap_.find(texIndex);
......@@ -200,19 +201,21 @@ Material& FileOBJPlugin::getMaterial(MeshT& _mesh, const OpenMesh::FaceHandle& _
}
}
for (MaterialList::iterator it = materials_.begin(); it != materials_.end(); ++it) {
for (MaterialList::iterator it = materials_.begin(); it != materials_.end();
++it) {
// No texture has been found
if (!hasTexture) {
// ... just look for diffuse color in materials list
if (((*it).second).Kd() == ACG::Vec3f(c[0], c[1], c[2]) &&
((optionColorAlpha && ((*it).second).Tr() == c[3]) || !optionColorAlpha))
((optionColorAlpha && ((*it).second).Tr() == c[3]) ||
!optionColorAlpha))
return (*it).second;
} else {
// Texture has been found, look for both, matching texture and color
QString mKd(((*it).second).map_Kd().c_str());
if ((((*it).second).Kd() == ACG::Vec3f(c[0], c[1], c[2]) &&
((optionColorAlpha && ((*it).second).Tr() == c[3]) || !optionColorAlpha)) &&
((optionColorAlpha && ((*it).second).Tr() == c[3]) ||
!optionColorAlpha)) &&
(filename == mKd && ((*it).second).map_Kd_index() == texIndex))
return (*it).second;
}
......@@ -226,23 +229,20 @@ Material& FileOBJPlugin::getMaterial(MeshT& _mesh, const OpenMesh::FaceHandle& _
if (optionColorAlpha) mat.set_Tr(c[3]);
mat.material_number(materials_.size());
// Set texture info
if(hasTexture)
mat.set_map_Kd(filename.toStdString(), texIndex);
if (hasTexture) mat.set_map_Kd(filename.toStdString(), texIndex);
materials_.insert(std::make_pair(QString("Material%1").arg(mat.material_number()).toStdString(), mat));
materials_.insert(std::make_pair(
QString("Material%1").arg(mat.material_number()).toStdString(), mat));
MaterialList::iterator it = materials_.end();
--it;
return (*it).second;
}
//-----------------------------------------------------------------------------------------------------
template <class MeshT>
bool FileOBJPlugin::writeMesh(std::ostream& _out, QString _filename, MeshT& _mesh, int _objId){
bool FileOBJPlugin::writeMesh(std::ostream& _out, QString _filename,
MeshT& _mesh, int _objId) {
unsigned int i, nV, idx;
Vec3f v, n;
Vec2f t(0.0f, 0.0f);
......@@ -273,8 +273,8 @@ bool FileOBJPlugin::writeMesh(std::ostream& _out, QString _filename, MeshT& _mes
// create material file if needed
if (optionFaceColors || optionTextures) {
QString matFile = fi.absolutePath() + QDir::separator() + fi.baseName() + ".mtl";
QString matFile =
fi.absolutePath() + QDir::separator() + fi.baseName() + ".mtl";
useMaterial = writeMaterial(matFile, _mesh, _objId);
}
......@@ -294,8 +294,7 @@ bool FileOBJPlugin::writeMesh(std::ostream& _out, QString _filename, MeshT& _mes
int cf = 1;
// vertex data (point, normals, texcoords)
for (i=0, nV=_mesh.n_vertices(); i<nV; ++i)
{
for (i = 0, nV = _mesh.n_vertices(); i < nV; ++i) {
vh = typename MeshT::VertexHandle(i);
v = _mesh.point(vh);
n = _mesh.normal(vh);
......@@ -311,7 +310,8 @@ bool FileOBJPlugin::writeMesh(std::ostream& _out, QString _filename, MeshT& _mes
_out << "vn " << n[0] << " " << n[1] << " " << n[2] << '\n';
// Write out vertex texture coordinates
if ( optionVertexTexCoords && _mesh.has_vertex_texcoords2D() && !_mesh.has_halfedge_texcoords2D()) {
if (optionVertexTexCoords && _mesh.has_vertex_texcoords2D() &&
!_mesh.has_halfedge_texcoords2D()) {
_out << "vt " << t[0] << " " << t[1] << '\n';
vtMapV.insert(std::pair<typename MeshT::VertexHandle, int>(vh, cf));
cf++;
......@@ -334,26 +334,29 @@ bool FileOBJPlugin::writeMesh(std::ostream& _out, QString _filename, MeshT& _mes
for (fh_it = _mesh.fh_iter(f_it); fh_it.is_valid(); ++fh_it) {
typename MeshT::TexCoord2D t = _mesh.texcoord2D(*fh_it);
_out << "vt " << t[0] << " " << t[1] << '\n';
vtMap.insert(std::pair<typename MeshT::HalfedgeHandle, int>(*fh_it, count));
vtMap.insert(
std::pair<typename MeshT::HalfedgeHandle, int>(*fh_it, count));
count++;
}
}
}
Material lastMat;
lastMat.material_number(std::numeric_limits<unsigned int>::max());
// we do not want to write separators if we only write vertex indices
bool vertexOnly = !(optionVertexTexCoords && _mesh.has_halfedge_texcoords2D())
&& !(optionVertexTexCoords && !_mesh.has_halfedge_texcoords2D() && _mesh.has_vertex_texcoords2D())
&& !(optionVertexNormals);
bool vertexOnly =
!(optionVertexTexCoords && _mesh.has_halfedge_texcoords2D()) &&
!(optionVertexTexCoords && !_mesh.has_halfedge_texcoords2D() &&
_mesh.has_vertex_texcoords2D()) &&
!(optionVertexNormals);
for (auto f_it : _mesh.faces()) {
if (useMaterial && optionFaceColors) {
Material& material = getMaterial(_mesh, f_it, _objId);
// If we are ina a new material block, specify in the file which material to use
// If we are ina a new material block, specify in the file which material
// to use
if (lastMat.material_number() != material.material_number()) {
_out << "usemtl " << material << '\n';
lastMat = material;
......@@ -364,13 +367,11 @@ bool FileOBJPlugin::writeMesh(std::ostream& _out, QString _filename, MeshT& _mes
// Write out face information
for (fh_it = _mesh.fh_iter(f_it); fh_it.is_valid(); ++fh_it) {
// Write vertex index
idx = _mesh.to_vertex_handle(*fh_it).idx() + 1;
_out << " " << idx;
if (!vertexOnly) {
// Write separator
_out << "/";
......@@ -378,14 +379,16 @@ bool FileOBJPlugin::writeMesh(std::ostream& _out, QString _filename, MeshT& _mes
// Write vertex texture coordinate index
if (optionVertexTexCoords && _mesh.has_halfedge_texcoords2D()) {
// Refer to halfedge texture coordinates
typename std::map<typename MeshT::HalfedgeHandle, int>::iterator it = vtMap.find(*fh_it);
if(it != vtMap.end())
_out << (*it).second;
} else if (optionVertexTexCoords && !_mesh.has_halfedge_texcoords2D() && _mesh.has_vertex_texcoords2D()) {
typename std::map<typename MeshT::HalfedgeHandle, int>::iterator
it = vtMap.find(*fh_it);
if (it != vtMap.end()) _out << (*it).second;
} else if (optionVertexTexCoords &&
!_mesh.has_halfedge_texcoords2D() &&
_mesh.has_vertex_texcoords2D()) {
// Refer to vertex texture coordinates
typename std::map<typename MeshT::VertexHandle, int>::iterator it = vtMapV.find(_mesh.to_vertex_handle(*fh_it));
if(it != vtMapV.end())
_out << (*it).second;
typename std::map<typename MeshT::VertexHandle, int>::iterator it =
vtMapV.find(_mesh.to_vertex_handle(*fh_it));
if (it != vtMapV.end()) _out << (*it).second;
}
}
......@@ -407,7 +410,8 @@ bool FileOBJPlugin::writeMesh(std::ostream& _out, QString _filename, MeshT& _mes
// Only test existence of folder once
// (for multiple textures)
bool testedOnce = false;
for(MaterialList::iterator it = materials_.begin(); it != materials_.end(); ++it) {
for (MaterialList::iterator it = materials_.begin(); it != materials_.end();
++it) {
Material& mat = (*it).second;
if (!mat.has_Texture()) continue;
......@@ -417,18 +421,22 @@ bool FileOBJPlugin::writeMesh(std::ostream& _out, QString _filename, MeshT& _mes
if (img.isNull()) {
// Something happened wrong
emit log(LOGERR, tr("An error occurred when trying to copy a texture file."));
emit log(LOGERR,
tr("An error occurred when trying to copy a texture file."));
continue;
} else {
if (optionCreateTexFolder) {
// Create folder
QDir dir(fi.absolutePath());
if(!testedOnce && dir.exists(fi.absolutePath() + QDir::separator() + fi.baseName() + "_textures")) {
emit log(LOGERR, tr("The specified target folder already contains a subfolder called textures. Skipping!"));
if (!testedOnce && dir.exists(fi.absolutePath() + QDir::separator() +
fi.baseName() + "_textures")) {
emit log(LOGERR, tr("The specified target folder already contains "
"a subfolder called textures. Skipping!"));
continue;
} else {
dir.mkdir(fi.baseName() + "_textures");
img.save(fi.absolutePath() + QDir::separator() + fi.baseName() + "_textures" + QDir::separator() + img_f.fileName());
img.save(fi.absolutePath() + QDir::separator() + fi.baseName() +
"_textures" + QDir::separator() + img_f.fileName());
testedOnce = true;
}
......@@ -445,7 +453,3 @@ bool FileOBJPlugin::writeMesh(std::ostream& _out, QString _filename, MeshT& _mes
return true;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment