From e19de27332e13d0059ac6b374e9175e254c0b5e4 Mon Sep 17 00:00:00 2001 From: granzuglia Date: Wed, 13 May 2009 16:34:29 +0000 Subject: [PATCH] added color per face rather than color per vertex --- wrap/io_trimesh/export_idtf.h | 1180 +++++++++++++++++---------------- 1 file changed, 606 insertions(+), 574 deletions(-) diff --git a/wrap/io_trimesh/export_idtf.h b/wrap/io_trimesh/export_idtf.h index 25af8ee7..b8e108d9 100644 --- a/wrap/io_trimesh/export_idtf.h +++ b/wrap/io_trimesh/export_idtf.h @@ -1,576 +1,608 @@ -#ifndef __VCGLIB_EXPORTERIDTF -#define __VCGLIB_EXPORTERIDTF - - -#include -#include -#include -#include -#include -#include -#include - - -class TextUtility -{ -public: - template - static std::string nmbToStr(NUMERICTYPE n) - { - std::stringstream ss; - ss << n; - return ss.str(); - } -}; - -class Output_File -{ -public: - Output_File(const std::string& file) - :_file() - { - _file.open(file.c_str(),std::ios::out); - } - - void write(unsigned int tabl,const std::string& st) - { - std::string tmp; - for(unsigned int ii = 0;ii < tabl;++ii) - tmp += '\t'; - _file << tmp << st << std::endl; - } - - ~Output_File() - { - _file.close(); - } - -private: - std::ofstream _file; - std::string _tab; -}; - -#include -#include -#include -#include - - -namespace vcg { -namespace tri { -namespace io { - - -namespace QtUtilityFunctions -{ - static void splitFilePath(const QString& filepath,QStringList& trim_path) - { - QString file_uniformed = filepath; - file_uniformed.replace(QString("\\"),QString("/")); - trim_path = file_uniformed.split("/"); - } - - static QString fileNameFromTrimmedPath(const QStringList& file_path) - { - - if (file_path.size() > 0) - return file_path.at(file_path.size() - 1); - else - return QString(); - } - - static QString fileNameFromPath(const QString& filepath) - { - QStringList list; - splitFilePath(filepath,list); - return fileNameFromTrimmedPath(list); - } - - static QString pathWithoutFileName(const QString& filepath) - { - QString tmp(filepath); - tmp.remove(fileNameFromPath(filepath)); - return tmp; - } - - static QString fileExtension(const QString& filepath) - { - QStringList trim_list; - splitFilePath(filepath,trim_list); - QString file = fileNameFromTrimmedPath(trim_list); - trim_list = file.split("."); - return trim_list.at(trim_list.size() - 1); - } -} - -class TGA_Exporter -{ -public: - - struct TGAHeader - { - unsigned char identsize; - unsigned char colourmaptype; - unsigned char imagetype; - - unsigned char colormapspecs[5]; - - short xstart; - short ystart; - short width; - short height; - unsigned char bits; - unsigned char descriptor; - }; - - static void convert(const QString& outfile,const QImage& im) - { - TGAHeader tga; - tga.identsize = 0; - tga.colourmaptype = 0; - tga.imagetype = 2; - - memset(tga.colormapspecs,0,5); - tga.xstart = (short) im.offset().x(); - tga.ystart = (short) im.offset().y(); - tga.height = (short) im.height(); - tga.width = (short) im.width(); - - +#ifndef __VCGLIB_EXPORTERIDTF +#define __VCGLIB_EXPORTERIDTF + + +#include +#include +#include +#include +#include +#include +#include + + +class TextUtility +{ +public: + template + static std::string nmbToStr(NUMERICTYPE n) + { + std::stringstream ss; + ss << n; + return ss.str(); + } +}; + +class Output_File +{ +public: + Output_File(const std::string& file) + :_file() + { + _file.open(file.c_str(),std::ios::out); + } + + void write(unsigned int tabl,const std::string& st) + { + std::string tmp; + for(unsigned int ii = 0;ii < tabl;++ii) + tmp += '\t'; + _file << tmp << st << std::endl; + } + + ~Output_File() + { + _file.close(); + } + +private: + std::ofstream _file; + std::string _tab; +}; + +#include +#include +#include +#include + + +namespace vcg { +namespace tri { +namespace io { + + +namespace QtUtilityFunctions +{ + static void splitFilePath(const QString& filepath,QStringList& trim_path) + { + QString file_uniformed = filepath; + file_uniformed.replace(QString("\\"),QString("/")); + trim_path = file_uniformed.split("/"); + } + + static QString fileNameFromTrimmedPath(const QStringList& file_path) + { + + if (file_path.size() > 0) + return file_path.at(file_path.size() - 1); + else + return QString(); + } + + static QString fileNameFromPath(const QString& filepath) + { + QStringList list; + splitFilePath(filepath,list); + return fileNameFromTrimmedPath(list); + } + + static QString pathWithoutFileName(const QString& filepath) + { + QString tmp(filepath); + tmp.remove(fileNameFromPath(filepath)); + return tmp; + } + + static QString fileExtension(const QString& filepath) + { + QStringList trim_list; + splitFilePath(filepath,trim_list); + QString file = fileNameFromTrimmedPath(trim_list); + trim_list = file.split("."); + return trim_list.at(trim_list.size() - 1); + } +} + +class TGA_Exporter +{ +public: + + struct TGAHeader + { + unsigned char identsize; + unsigned char colourmaptype; + unsigned char imagetype; + + unsigned char colormapspecs[5]; + + short xstart; + short ystart; + short width; + short height; + unsigned char bits; + unsigned char descriptor; + }; + + static void convert(const QString& outfile,const QImage& im) + { + TGAHeader tga; + tga.identsize = 0; + tga.colourmaptype = 0; + tga.imagetype = 2; + + memset(tga.colormapspecs,0,5); + tga.xstart = (short) im.offset().x(); + tga.ystart = (short) im.offset().y(); + tga.height = (short) im.height(); + tga.width = (short) im.width(); + + //QString moutfile = QString("C:/Users/Guido/AppData/Local/Temp/duckCM.tga"); - - QFile file(qPrintable(outfile)); - file.setPermissions(QFile::WriteOther); - file.open(QIODevice::WriteOnly); - QString err = file.errorString(); - //bool val = file.failbit; - unsigned char* tmpchan; - int totbyte; - if (im.hasAlphaChannel()) - { - //is a 8-digits binary number code - // always 0 0 | mirroring | bits - //(future uses)| image | for alpha-channel - //-------------------------------------------- - // 7 6 | 5 4 | 3 2 1 0 - //-------------------------------------------- - // 0 0 | 1 0 | 1 0 0 0 - tga.descriptor = (char) 40; - tga.bits = (char) 32; - } - else - { - //is a 8-digits binary number code - // always 0 0 | mirroring | bits - //(future uses)| image | for alpha-channel - //-------------------------------------------- - // 7 6 | 5 4 | 3 2 1 0 - //-------------------------------------------- - // 0 0 | 1 0 | 0 0 0 0 - tga.descriptor = (char) 32; - tga.bits = (char) 24; - } - - totbyte = tga.height * tga.width * (tga.bits / 8); - - if (im.hasAlphaChannel()) - tmpchan = const_cast(im.bits()); - else - { - tmpchan = new unsigned char[totbyte]; - - int ii = 0; - while(ii < totbyte) - { - tmpchan[ii] = const_cast(im.bits())[ii + (ii/3)]; - ++ii; - } - } - - file.write((char *) &tga,qint64(sizeof(tga))); - file.write(reinterpret_cast(tmpchan),qint64(totbyte)); - file.close(); - } - - template - static void convertTexturesFiles(SaveMeshType& m,const QString& file_path,QStringList& conv_file) - { - for(unsigned int ii = 0; ii < m.textures.size(); ++ii) - { - QString qtmp(m.textures[ii].c_str()); - QString ext = QtUtilityFunctions::fileExtension(qtmp); - QString filename = QtUtilityFunctions::fileNameFromPath(qtmp); - if (ext.toLower() != "tga") - { - QImage img(qtmp); - QString stmp; - if ((file_path.at(file_path.length() - 1) != '/') || (file_path.at(file_path.length() - 1) != '\\')) - stmp = file_path + QString("/"); - else - stmp = file_path; - filename = stmp + filename.remove(ext) + "tga"; - m.textures[ii] = filename.toStdString(); - TGA_Exporter::convert(filename,img); - conv_file.push_back(filename); - } - } - } - - static void removeConvertedTexturesFiles(const QStringList& conv_file) - { - for(unsigned int ii = 0;ii < conv_file.size();++ii) - { - QDir dir(QtUtilityFunctions::pathWithoutFileName(conv_file[ii])); - dir.remove(QtUtilityFunctions::fileNameFromPath(conv_file[ii])); - } - } -}; - - - -template -class ExporterIDTF -{ - -public: -typedef typename SaveMeshType::VertexPointer VertexPointer; -typedef typename SaveMeshType::ScalarType ScalarType; -typedef typename SaveMeshType::VertexType VertexType; -typedef typename SaveMeshType::FaceType FaceType; -typedef typename SaveMeshType::ConstVertexIterator ConstVertexIterator; -typedef typename SaveMeshType::VertexIterator VertexIterator; -typedef typename SaveMeshType::FaceIterator FaceIterator; -typedef typename SaveMeshType::ConstFaceIterator ConstFaceIterator; -typedef typename SaveMeshType::CoordType CoordType; - - enum IDTFError - { - E_NOERROR // 0 - }; - - static const char *ErrorMsg(int error) - { - static const char * dae_error_msg[] = - { - "No errors" - }; - - if(error>0 || error<0) return "Unknown error"; - else return dae_error_msg[error]; - }; - - static QStringList convertInTGATextures(SaveMeshType& m,const QString& path,QStringList& textures_to_be_restored) - { - //if there are textures file that aren't in tga format I have to convert them - //I maintain the converted file name (i.e. file_path + originalname without extension + tga) in mesh.textures but I have to revert to the original ones - //before the function return. - for(unsigned int ii = 0; ii < m.textures.size();++ii) - textures_to_be_restored.push_back(m.textures[ii].c_str()); - - //tmp vector to save the tga created files that should be deleted. - QStringList convfile; - vcg::tri::io::TGA_Exporter::convertTexturesFiles(m,path,convfile); - return convfile; - } - - static void removeConvertedTGATextures(const QStringList& convfile) - { - //if some tga files have been created I have to delete them - vcg::tri::io::TGA_Exporter::removeConvertedTexturesFiles(convfile); - } - - static void restoreConvertedTextures(SaveMeshType& mesh_with_textures_to_be_restored,const QStringList& textures_to_be_restored) - { - mesh_with_textures_to_be_restored.textures.clear(); - for(QStringList::ConstIterator it = textures_to_be_restored.begin();it != textures_to_be_restored.end();++it) - mesh_with_textures_to_be_restored.textures.push_back(it->toStdString()); - } - - static int Save(SaveMeshType& m,const char* file,const int mask) - { - - Output_File idtf(file); - - idtf.write(0,"FILE_FORMAT \"IDTF\""); - idtf.write(0,"FORMAT_VERSION 100\n"); - - idtf.write(0,"NODE \"MODEL\" {"); - idtf.write(1,"NODE_NAME \"VcgMesh01\""); - idtf.write(1,"PARENT_LIST {"); - idtf.write(2,"PARENT_COUNT 1"); - idtf.write(2,"PARENT 0 {"); - idtf.write(3,"PARENT_NAME \"\""); - idtf.write(3,"PARENT_TM {"); - idtf.write(4,"1.000000 0.000000 0.000000 0.000000"); - idtf.write(4,"0.000000 1.000000 0.000000 0.000000"); - idtf.write(4,"0.000000 0.000000 1.000000 0.000000"); - idtf.write(4,"0.000000 0.000000 0.000000 1.000000"); - idtf.write(3,"}"); - idtf.write(2,"}"); - idtf.write(1,"}"); - idtf.write(1,"RESOURCE_NAME \"MyVcgMesh01\""); - idtf.write(0,"}"); - - - if (mask & Mask::IOM_WEDGTEXCOORD) - { - idtf.write(0,""); - idtf.write(0,"RESOURCE_LIST \"SHADER\" {"); - idtf.write(1,"RESOURCE_COUNT " + TextUtility::nmbToStr(m.textures.size())); - for(unsigned int ii = 0; ii < m.textures.size(); ++ii) - { - idtf.write(1,"RESOURCE " + TextUtility::nmbToStr(ii) + " {"); - idtf.write(2,"RESOURCE_NAME \"ModelShader" + TextUtility::nmbToStr(ii) +"\""); - idtf.write(2,"SHADER_MATERIAL_NAME \"Material1\""); - idtf.write(2,"SHADER_ACTIVE_TEXTURE_COUNT 1"); - idtf.write(2,"SHADER_TEXTURE_LAYER_LIST {"); - idtf.write(3,"TEXTURE_LAYER 0 {"); - idtf.write(4,"TEXTURE_NAME \"Texture" + TextUtility::nmbToStr(ii) +"\""); - idtf.write(3,"}"); - idtf.write(2,"}"); - } - idtf.write(1,"}"); - idtf.write(0,"}"); - idtf.write(0,""); - idtf.write(0,"RESOURCE_LIST \"MATERIAL\" {"); - idtf.write(1,"RESOURCE_COUNT 1"); - idtf.write(1,"RESOURCE 0 {"); - idtf.write(2,"RESOURCE_NAME \"Material1\""); - idtf.write(2,"MATERIAL_AMBIENT 0.2 0.2 0.2"); - idtf.write(2,"MATERIAL_DIFFUSE 0.8 0.8 0.8"); - idtf.write(2,"MATERIAL_SPECULAR 0.0 0.0 0.0"); - idtf.write(2,"MATERIAL_EMISSIVE 0.0 0.0 0.0"); - idtf.write(2,"MATERIAL_REFLECTIVITY 0.100000"); - idtf.write(2,"MATERIAL_OPACITY 1.000000"); - idtf.write(1,"}"); - idtf.write(0,"}"); - idtf.write(0,""); - idtf.write(0,"RESOURCE_LIST \"TEXTURE\" {"); - idtf.write(1,"RESOURCE_COUNT " + TextUtility::nmbToStr(m.textures.size())); - for(unsigned int ii = 0; ii < m.textures.size();++ii) - { - idtf.write(1,"RESOURCE " + TextUtility::nmbToStr(ii) + " {"); - idtf.write(2,"RESOURCE_NAME \"Texture" + TextUtility::nmbToStr(ii) + "\""); - idtf.write(2,"TEXTURE_PATH \"" + m.textures[ii] + "\""); - idtf.write(1,"}"); - } - idtf.write(0,"}"); - } - idtf.write(0,""); - idtf.write(0,"RESOURCE_LIST \"MODEL\" {"); - idtf.write(1,"RESOURCE_COUNT 1"); - idtf.write(1,"RESOURCE 0 {"); - idtf.write(2,"RESOURCE_NAME \"MyVcgMesh01\""); - idtf.write(2,"MODEL_TYPE \"MESH\""); - idtf.write(2,"MESH {"); - idtf.write(3,"FACE_COUNT " + TextUtility::nmbToStr(m.face.size())); - idtf.write(3,"MODEL_POSITION_COUNT " + TextUtility::nmbToStr(m.vert.size())); - idtf.write(3,"MODEL_NORMAL_COUNT " + TextUtility::nmbToStr(m.face.size() * 3)); - if (mask & vcg::tri::io::Mask::IOM_VERTCOLOR) - idtf.write(3,"MODEL_DIFFUSE_COLOR_COUNT " + TextUtility::nmbToStr(m.face.size() * 3)); - else - idtf.write(3,"MODEL_DIFFUSE_COLOR_COUNT 0"); - idtf.write(3,"MODEL_SPECULAR_COLOR_COUNT 0"); - if (mask & vcg::tri::io::Mask::IOM_WEDGTEXCOORD) idtf.write(3,"MODEL_TEXTURE_COORD_COUNT " + TextUtility::nmbToStr(m.face.size() * 3)); - else idtf.write(3,"MODEL_TEXTURE_COORD_COUNT 0"); - idtf.write(3,"MODEL_BONE_COUNT 0"); - unsigned int mod_sha; - if (m.textures.size() == 0) - mod_sha = 1; - else - mod_sha = m.textures.size(); - idtf.write(3,"MODEL_SHADING_COUNT " + TextUtility::nmbToStr(mod_sha)); - idtf.write(3,"MODEL_SHADING_DESCRIPTION_LIST {"); - unsigned int hh = 0; - do - { - idtf.write(4,"SHADING_DESCRIPTION " + TextUtility::nmbToStr(hh) + " {"); - if (mask & vcg::tri::io::Mask::IOM_WEDGTEXCOORD) - { - idtf.write(5,"TEXTURE_LAYER_COUNT 1"); - idtf.write(5,"TEXTURE_COORD_DIMENSION_LIST {"); - idtf.write(6,"TEXTURE_LAYER 0 DIMENSION: 2"); - idtf.write(5,"}"); - idtf.write(5,"SHADER_ID 0"); - } - else - { - idtf.write(5,"TEXTURE_LAYER_COUNT 0"); - idtf.write(5,"SHADER_ID 0"); - } - idtf.write(4,"}"); - ++hh; - } - while(hh < m.textures.size()); - idtf.write(3,"}"); - idtf.write(3,"MESH_FACE_POSITION_LIST {"); - for(ConstFaceIterator fit = m.face.begin();fit != m.face.end();++fit) - { - idtf.write(4,TextUtility::nmbToStr(fit->V(0) - &(*m.vert.begin())) + " " + - TextUtility::nmbToStr(fit->V(1) - &(*m.vert.begin())) + " " + - TextUtility::nmbToStr(fit->V(2) - &(*m.vert.begin()))); - } - idtf.write(3,"}"); - - idtf.write(3,"MESH_FACE_NORMAL_LIST {"); - unsigned int nn = 0; - for(ConstFaceIterator fit = m.face.begin();fit != m.face.end();++fit) - { - idtf.write(4,TextUtility::nmbToStr(nn) + " " + - TextUtility::nmbToStr(nn + 1) + " " + - TextUtility::nmbToStr(nn + 2)); - nn += 3; - } - idtf.write(3,"}"); - - idtf.write(3,"MESH_FACE_SHADING_LIST {"); - for(FaceIterator fit = m.face.begin();fit != m.face.end();++fit) - { - unsigned int texind = 0; - if (mask & vcg::tri::io::Mask::IOM_WEDGTEXCOORD) - texind = fit->WT(0).N(); - idtf.write(4,TextUtility::nmbToStr(texind)); - } - idtf.write(3,"}"); - - if (mask & vcg::tri::io::Mask::IOM_VERTCOLOR) - { - idtf.write(3,"MESH_FACE_DIFFUSE_COLOR_LIST {"); - nn = 0; - for(FaceIterator fit = m.face.begin();fit != m.face.end();++fit) - { - idtf.write(4,TextUtility::nmbToStr(nn) + " " + - TextUtility::nmbToStr(nn + 2) + " " + - TextUtility::nmbToStr(nn + 1)); - nn += 3; - } - idtf.write(3,"}"); - } - if (mask & vcg::tri::io::Mask::IOM_WEDGTEXCOORD) - { - idtf.write(3,"MESH_FACE_TEXTURE_COORD_LIST {"); - for(unsigned int ii = 0; ii < m.face.size();++ii) - { - idtf.write(4,"FACE " + TextUtility::nmbToStr(ii) + " {"); - idtf.write(5,"TEXTURE_LAYER 0 TEX_COORD: " + TextUtility::nmbToStr(ii * 3) + " " + TextUtility::nmbToStr(ii * 3 + 1) + " " + TextUtility::nmbToStr(ii * 3 + 2)); - idtf.write(4,"}"); - } - idtf.write(3,"}"); - } - - idtf.write(3,"MODEL_POSITION_LIST {"); - //vcg::tri::UpdateBounding::Box(m); - //ScalarType diag = m.bbox.Diag(); - //CoordType center = m.bbox.Center(); - for(ConstVertexIterator vit = m.vert.begin();vit != m.vert.end();++vit) - { - CoordType tmp = vit->P();// - center);// /diag; - idtf.write(4,TextUtility::nmbToStr(-tmp.X()) + " " + - TextUtility::nmbToStr(tmp.Z()) + " " + - TextUtility::nmbToStr(tmp.Y())); - } - idtf.write(3,"}"); - - idtf.write(3,"MODEL_NORMAL_LIST {"); - for(FaceIterator fitn = m.face.begin();fitn != m.face.end();++fitn) - { - for(unsigned int ii = 0;ii < 3;++ii) - { - fitn->N().Normalize(); - idtf.write(4,TextUtility::nmbToStr(-fitn->N().X()) + " " + - TextUtility::nmbToStr(fitn->N().Z()) + " " + - TextUtility::nmbToStr(fitn->N().Y())); - } - } - idtf.write(3,"}"); - - if (mask & vcg::tri::io::Mask::IOM_WEDGTEXCOORD) - { - idtf.write(3,"MODEL_TEXTURE_COORD_LIST {"); - for(FaceIterator fitn = m.face.begin();fitn != m.face.end();++fitn) - { - for(unsigned int ii = 0;ii < 3;++ii) - { - idtf.write(4,TextUtility::nmbToStr(fitn->WT(ii).U()) + " " + - TextUtility::nmbToStr(-fitn->WT(ii).V()) + " " + TextUtility::nmbToStr(0.0f) + " " + TextUtility::nmbToStr(0.0f)); - } - } - idtf.write(3,"}"); - } - - if (mask & vcg::tri::io::Mask::IOM_VERTCOLOR) - { - idtf.write(3,"MODEL_DIFFUSE_COLOR_LIST {"); - //ScalarType diag = m.bbox.Diag(); - //CoordType center = m.bbox.Center(); - for(FaceIterator vit = m.face.begin();vit != m.face.end();++vit) - { - for (unsigned int ii =0; ii <3;++ii) - idtf.write(4,TextUtility::nmbToStr((int) vit->V(ii)->C().X()) + " " + - TextUtility::nmbToStr((int) vit->V(ii)->C().Y()) + " " + - TextUtility::nmbToStr((int) vit->V(ii)->C().Z()) + " 0"); - } - idtf.write(3,"}"); - } - - idtf.write(2,"}"); - idtf.write(1,"}"); - idtf.write(0,"}"); - - if (mask & vcg::tri::io::Mask::IOM_VERTCOLOR) - { - idtf.write(0,"RESOURCE_LIST \"SHADER\" {"); - idtf.write(1,"RESOURCE_COUNT 1"); - idtf.write(1,"RESOURCE 0 {"); - idtf.write(2,"RESOURCE_NAME \"VcgMesh010\""); - idtf.write(2,"ATTRIBUTE_USE_VERTEX_COLOR \"TRUE\""); - idtf.write(2,"SHADER_ACTIVE_TEXTURE_COUNT 0"); - idtf.write(1,"}"); - idtf.write(0,"}"); - } - - if (mask & vcg::tri::io::Mask::IOM_WEDGTEXCOORD) - { - idtf.write(0,""); - idtf.write(0,"MODIFIER \"SHADING\" {"); - idtf.write(1,"MODIFIER_NAME \"VcgMesh01\""); - idtf.write(1,"PARAMETERS {"); - idtf.write(2,"SHADER_LIST_COUNT " + TextUtility::nmbToStr(m.textures.size())); - idtf.write(2,"SHADING_GROUP {"); - for(unsigned int ii = 0; ii < m.textures.size();++ii) - { - idtf.write(3,"SHADER_LIST " + TextUtility::nmbToStr(ii) + "{"); - idtf.write(4,"SHADER_COUNT 1"); - idtf.write(4,"SHADER_NAME_LIST {"); - idtf.write(5,"SHADER 0 NAME: \"ModelShader" + TextUtility::nmbToStr(ii) + "\""); - idtf.write(4,"}"); - idtf.write(3,"}"); - } - idtf.write(2,"}"); - idtf.write(1,"}"); - idtf.write(0,"}"); - } - - return E_NOERROR; - } - - static int GetExportMaskCapability() - { - int capability = 0; - - //vert - capability |= vcg::tri::io::Mask::IOM_VERTNORMAL; - capability |= vcg::tri::io::Mask::IOM_VERTCOLOR; - - ////wedg - capability |= vcg::tri::io::Mask::IOM_WEDGTEXCOORD; - capability |= vcg::tri::io::Mask::IOM_WEDGNORMAL; - - return capability; - } -}; -} -} -} - + + QFile file(qPrintable(outfile)); + file.setPermissions(QFile::WriteOther); + file.open(QIODevice::WriteOnly); + QString err = file.errorString(); + //bool val = file.failbit; + unsigned char* tmpchan; + int totbyte; + if (im.hasAlphaChannel()) + { + //is a 8-digits binary number code + // always 0 0 | mirroring | bits + //(future uses)| image | for alpha-channel + //-------------------------------------------- + // 7 6 | 5 4 | 3 2 1 0 + //-------------------------------------------- + // 0 0 | 1 0 | 1 0 0 0 + tga.descriptor = (char) 40; + tga.bits = (char) 32; + } + else + { + //is a 8-digits binary number code + // always 0 0 | mirroring | bits + //(future uses)| image | for alpha-channel + //-------------------------------------------- + // 7 6 | 5 4 | 3 2 1 0 + //-------------------------------------------- + // 0 0 | 1 0 | 0 0 0 0 + tga.descriptor = (char) 32; + tga.bits = (char) 24; + } + + totbyte = tga.height * tga.width * (tga.bits / 8); + + if (im.hasAlphaChannel()) + tmpchan = const_cast(im.bits()); + else + { + tmpchan = new unsigned char[totbyte]; + + int ii = 0; + while(ii < totbyte) + { + tmpchan[ii] = const_cast(im.bits())[ii + (ii/3)]; + ++ii; + } + } + + file.write((char *) &tga,qint64(sizeof(tga))); + file.write(reinterpret_cast(tmpchan),qint64(totbyte)); + file.close(); + } + + template + static void convertTexturesFiles(SaveMeshType& m,const QString& file_path,QStringList& conv_file) + { + for(unsigned int ii = 0; ii < m.textures.size(); ++ii) + { + QString qtmp(m.textures[ii].c_str()); + QString ext = QtUtilityFunctions::fileExtension(qtmp); + QString filename = QtUtilityFunctions::fileNameFromPath(qtmp); + if (ext.toLower() != "tga") + { + QImage img(qtmp); + QString stmp; + if ((file_path.at(file_path.length() - 1) != '/') || (file_path.at(file_path.length() - 1) != '\\')) + stmp = file_path + QString("/"); + else + stmp = file_path; + filename = stmp + filename.remove(ext) + "tga"; + m.textures[ii] = filename.toStdString(); + TGA_Exporter::convert(filename,img); + conv_file.push_back(filename); + } + } + } + + static void removeConvertedTexturesFiles(const QStringList& conv_file) + { + for(unsigned int ii = 0;ii < conv_file.size();++ii) + { + QDir dir(QtUtilityFunctions::pathWithoutFileName(conv_file[ii])); + dir.remove(QtUtilityFunctions::fileNameFromPath(conv_file[ii])); + } + } +}; + + + +template +class ExporterIDTF +{ + +public: +typedef typename SaveMeshType::VertexPointer VertexPointer; +typedef typename SaveMeshType::ScalarType ScalarType; +typedef typename SaveMeshType::VertexType VertexType; +typedef typename SaveMeshType::FaceType FaceType; +typedef typename SaveMeshType::ConstVertexIterator ConstVertexIterator; +typedef typename SaveMeshType::VertexIterator VertexIterator; +typedef typename SaveMeshType::FaceIterator FaceIterator; +typedef typename SaveMeshType::ConstFaceIterator ConstFaceIterator; +typedef typename SaveMeshType::CoordType CoordType; + + enum IDTFError + { + E_NOERROR // 0 + }; + + static const char *ErrorMsg(int error) + { + static const char * dae_error_msg[] = + { + "No errors" + }; + + if(error>0 || error<0) return "Unknown error"; + else return dae_error_msg[error]; + }; + + static QStringList convertInTGATextures(SaveMeshType& m,const QString& path,QStringList& textures_to_be_restored) + { + //if there are textures file that aren't in tga format I have to convert them + //I maintain the converted file name (i.e. file_path + originalname without extension + tga) in mesh.textures but I have to revert to the original ones + //before the function return. + for(unsigned int ii = 0; ii < m.textures.size();++ii) + textures_to_be_restored.push_back(m.textures[ii].c_str()); + + //tmp vector to save the tga created files that should be deleted. + QStringList convfile; + vcg::tri::io::TGA_Exporter::convertTexturesFiles(m,path,convfile); + return convfile; + } + + static void removeConvertedTGATextures(const QStringList& convfile) + { + //if some tga files have been created I have to delete them + vcg::tri::io::TGA_Exporter::removeConvertedTexturesFiles(convfile); + } + + static void restoreConvertedTextures(SaveMeshType& mesh_with_textures_to_be_restored,const QStringList& textures_to_be_restored) + { + mesh_with_textures_to_be_restored.textures.clear(); + for(QStringList::ConstIterator it = textures_to_be_restored.begin();it != textures_to_be_restored.end();++it) + mesh_with_textures_to_be_restored.textures.push_back(it->toStdString()); + } + + static int Save(SaveMeshType& m,const char* file,const int mask) + { + + Output_File idtf(file); + + idtf.write(0,"FILE_FORMAT \"IDTF\""); + idtf.write(0,"FORMAT_VERSION 100\n"); + + idtf.write(0,"NODE \"MODEL\" {"); + idtf.write(1,"NODE_NAME \"VcgMesh01\""); + idtf.write(1,"PARENT_LIST {"); + idtf.write(2,"PARENT_COUNT 1"); + idtf.write(2,"PARENT 0 {"); + idtf.write(3,"PARENT_NAME \"\""); + idtf.write(3,"PARENT_TM {"); + idtf.write(4,"1.000000 0.000000 0.000000 0.000000"); + idtf.write(4,"0.000000 1.000000 0.000000 0.000000"); + idtf.write(4,"0.000000 0.000000 1.000000 0.000000"); + idtf.write(4,"0.000000 0.000000 0.000000 1.000000"); + idtf.write(3,"}"); + idtf.write(2,"}"); + idtf.write(1,"}"); + idtf.write(1,"RESOURCE_NAME \"MyVcgMesh01\""); + idtf.write(0,"}"); + + + if (mask & Mask::IOM_WEDGTEXCOORD) + { + idtf.write(0,""); + idtf.write(0,"RESOURCE_LIST \"SHADER\" {"); + idtf.write(1,"RESOURCE_COUNT " + TextUtility::nmbToStr(m.textures.size())); + for(unsigned int ii = 0; ii < m.textures.size(); ++ii) + { + idtf.write(1,"RESOURCE " + TextUtility::nmbToStr(ii) + " {"); + idtf.write(2,"RESOURCE_NAME \"ModelShader" + TextUtility::nmbToStr(ii) +"\""); + idtf.write(2,"SHADER_MATERIAL_NAME \"Material1\""); + idtf.write(2,"SHADER_ACTIVE_TEXTURE_COUNT 1"); + idtf.write(2,"SHADER_TEXTURE_LAYER_LIST {"); + idtf.write(3,"TEXTURE_LAYER 0 {"); + idtf.write(4,"TEXTURE_NAME \"Texture" + TextUtility::nmbToStr(ii) +"\""); + idtf.write(3,"}"); + idtf.write(2,"}"); + } + idtf.write(1,"}"); + idtf.write(0,"}"); + idtf.write(0,""); + idtf.write(0,"RESOURCE_LIST \"MATERIAL\" {"); + idtf.write(1,"RESOURCE_COUNT 1"); + idtf.write(1,"RESOURCE 0 {"); + idtf.write(2,"RESOURCE_NAME \"Material1\""); + idtf.write(2,"MATERIAL_AMBIENT 0.2 0.2 0.2"); + idtf.write(2,"MATERIAL_DIFFUSE 0.8 0.8 0.8"); + idtf.write(2,"MATERIAL_SPECULAR 0.0 0.0 0.0"); + idtf.write(2,"MATERIAL_EMISSIVE 0.0 0.0 0.0"); + idtf.write(2,"MATERIAL_REFLECTIVITY 0.100000"); + idtf.write(2,"MATERIAL_OPACITY 1.000000"); + idtf.write(1,"}"); + idtf.write(0,"}"); + idtf.write(0,""); + idtf.write(0,"RESOURCE_LIST \"TEXTURE\" {"); + idtf.write(1,"RESOURCE_COUNT " + TextUtility::nmbToStr(m.textures.size())); + for(unsigned int ii = 0; ii < m.textures.size();++ii) + { + idtf.write(1,"RESOURCE " + TextUtility::nmbToStr(ii) + " {"); + idtf.write(2,"RESOURCE_NAME \"Texture" + TextUtility::nmbToStr(ii) + "\""); + idtf.write(2,"TEXTURE_PATH \"" + m.textures[ii] + "\""); + idtf.write(1,"}"); + } + idtf.write(0,"}"); + } + idtf.write(0,""); + idtf.write(0,"RESOURCE_LIST \"MODEL\" {"); + idtf.write(1,"RESOURCE_COUNT 1"); + idtf.write(1,"RESOURCE 0 {"); + idtf.write(2,"RESOURCE_NAME \"MyVcgMesh01\""); + idtf.write(2,"MODEL_TYPE \"MESH\""); + idtf.write(2,"MESH {"); + idtf.write(3,"FACE_COUNT " + TextUtility::nmbToStr(m.face.size())); + idtf.write(3,"MODEL_POSITION_COUNT " + TextUtility::nmbToStr(m.vert.size())); + idtf.write(3,"MODEL_NORMAL_COUNT " + TextUtility::nmbToStr(m.face.size() * 3)); + if (mask & vcg::tri::io::Mask::IOM_VERTCOLOR) + idtf.write(3,"MODEL_DIFFUSE_COLOR_COUNT " + TextUtility::nmbToStr(m.face.size() * 3)); + else + idtf.write(3,"MODEL_DIFFUSE_COLOR_COUNT 0"); + idtf.write(3,"MODEL_SPECULAR_COLOR_COUNT 0"); + if (mask & vcg::tri::io::Mask::IOM_WEDGTEXCOORD) idtf.write(3,"MODEL_TEXTURE_COORD_COUNT " + TextUtility::nmbToStr(m.face.size() * 3)); + else idtf.write(3,"MODEL_TEXTURE_COORD_COUNT 0"); + idtf.write(3,"MODEL_BONE_COUNT 0"); + unsigned int mod_sha; + if (m.textures.size() == 0) + mod_sha = 1; + else + mod_sha = m.textures.size(); + idtf.write(3,"MODEL_SHADING_COUNT " + TextUtility::nmbToStr(mod_sha)); + idtf.write(3,"MODEL_SHADING_DESCRIPTION_LIST {"); + unsigned int hh = 0; + do + { + idtf.write(4,"SHADING_DESCRIPTION " + TextUtility::nmbToStr(hh) + " {"); + if (mask & vcg::tri::io::Mask::IOM_WEDGTEXCOORD) + { + idtf.write(5,"TEXTURE_LAYER_COUNT 1"); + idtf.write(5,"TEXTURE_COORD_DIMENSION_LIST {"); + idtf.write(6,"TEXTURE_LAYER 0 DIMENSION: 2"); + idtf.write(5,"}"); + idtf.write(5,"SHADER_ID 0"); + } + else + { + idtf.write(5,"TEXTURE_LAYER_COUNT 0"); + idtf.write(5,"SHADER_ID 0"); + } + idtf.write(4,"}"); + ++hh; + } + while(hh < m.textures.size()); + idtf.write(3,"}"); + idtf.write(3,"MESH_FACE_POSITION_LIST {"); + for(ConstFaceIterator fit = m.face.begin();fit != m.face.end();++fit) + { + idtf.write(4,TextUtility::nmbToStr(fit->V(0) - &(*m.vert.begin())) + " " + + TextUtility::nmbToStr(fit->V(1) - &(*m.vert.begin())) + " " + + TextUtility::nmbToStr(fit->V(2) - &(*m.vert.begin()))); + } + idtf.write(3,"}"); + + idtf.write(3,"MESH_FACE_NORMAL_LIST {"); + unsigned int nn = 0; + for(ConstFaceIterator fit = m.face.begin();fit != m.face.end();++fit) + { + idtf.write(4,TextUtility::nmbToStr(nn) + " " + + TextUtility::nmbToStr(nn + 1) + " " + + TextUtility::nmbToStr(nn + 2)); + nn += 3; + } + idtf.write(3,"}"); + + idtf.write(3,"MESH_FACE_SHADING_LIST {"); + for(FaceIterator fit = m.face.begin();fit != m.face.end();++fit) + { + unsigned int texind = 0; + if (mask & vcg::tri::io::Mask::IOM_WEDGTEXCOORD) + texind = fit->WT(0).N(); + idtf.write(4,TextUtility::nmbToStr(texind)); + } + idtf.write(3,"}"); + + if (mask & vcg::tri::io::Mask::IOM_VERTCOLOR) + { + idtf.write(3,"MESH_FACE_DIFFUSE_COLOR_LIST {"); + nn = 0; + for(FaceIterator fit = m.face.begin();fit != m.face.end();++fit) + { + idtf.write(4,TextUtility::nmbToStr(nn) + " " + + TextUtility::nmbToStr(nn + 2) + " " + + TextUtility::nmbToStr(nn + 1)); + nn += 3; + } + idtf.write(3,"}"); + } + if (mask & vcg::tri::io::Mask::IOM_WEDGTEXCOORD) + { + idtf.write(3,"MESH_FACE_TEXTURE_COORD_LIST {"); + for(unsigned int ii = 0; ii < m.face.size();++ii) + { + idtf.write(4,"FACE " + TextUtility::nmbToStr(ii) + " {"); + idtf.write(5,"TEXTURE_LAYER 0 TEX_COORD: " + TextUtility::nmbToStr(ii * 3) + " " + TextUtility::nmbToStr(ii * 3 + 1) + " " + TextUtility::nmbToStr(ii * 3 + 2)); + idtf.write(4,"}"); + } + idtf.write(3,"}"); + } + + idtf.write(3,"MODEL_POSITION_LIST {"); + //vcg::tri::UpdateBounding::Box(m); + //ScalarType diag = m.bbox.Diag(); + //CoordType center = m.bbox.Center(); + for(ConstVertexIterator vit = m.vert.begin();vit != m.vert.end();++vit) + { + CoordType tmp = vit->P();// - center);// /diag; + idtf.write(4,TextUtility::nmbToStr(-tmp.X()) + " " + + TextUtility::nmbToStr(tmp.Z()) + " " + + TextUtility::nmbToStr(tmp.Y())); + } + idtf.write(3,"}"); + + idtf.write(3,"MODEL_NORMAL_LIST {"); + for(FaceIterator fitn = m.face.begin();fitn != m.face.end();++fitn) + { + for(unsigned int ii = 0;ii < 3;++ii) + { + fitn->N().Normalize(); + idtf.write(4,TextUtility::nmbToStr(-fitn->N().X()) + " " + + TextUtility::nmbToStr(fitn->N().Z()) + " " + + TextUtility::nmbToStr(fitn->N().Y())); + } + } + idtf.write(3,"}"); + + if (mask & vcg::tri::io::Mask::IOM_WEDGTEXCOORD) + { + idtf.write(3,"MODEL_TEXTURE_COORD_LIST {"); + for(FaceIterator fitn = m.face.begin();fitn != m.face.end();++fitn) + { + for(unsigned int ii = 0;ii < 3;++ii) + { + idtf.write(4,TextUtility::nmbToStr(fitn->WT(ii).U()) + " " + + TextUtility::nmbToStr(-fitn->WT(ii).V()) + " " + TextUtility::nmbToStr(0.0f) + " " + TextUtility::nmbToStr(0.0f)); + } + } + idtf.write(3,"}"); + } + + if (mask & vcg::tri::io::Mask::IOM_VERTCOLOR) + { + idtf.write(3,"MODEL_DIFFUSE_COLOR_LIST {"); + //ScalarType diag = m.bbox.Diag(); + //CoordType center = m.bbox.Center(); + for(FaceIterator vit = m.face.begin();vit != m.face.end();++vit) + { + for (unsigned int ii =0; ii <3;++ii) + { + vcg::Color4b cc = vit->V(ii)->C(); + idtf.write(4,TextUtility::nmbToStr(float(cc.X()) / 255.0f) + " " + + TextUtility::nmbToStr(float(cc.Y()) / 255.0f) + " " + + TextUtility::nmbToStr(float(cc.Z()) / 255.0f) + " " + TextUtility::nmbToStr(float(cc.W()) / 255.0f)); + } + } + idtf.write(3,"}"); + } + + idtf.write(2,"}"); + idtf.write(1,"}"); + idtf.write(0,"}"); + + if (mask & vcg::tri::io::Mask::IOM_VERTCOLOR) + { + idtf.write(0,"RESOURCE_LIST \"SHADER\" {"); + idtf.write(1,"RESOURCE_COUNT 1"); + idtf.write(1,"RESOURCE 0 {"); + idtf.write(2,"RESOURCE_NAME \"VcgMesh010\""); + idtf.write(2,"ATTRIBUTE_USE_VERTEX_COLOR \"TRUE\""); + idtf.write(2,"SHADER_MATERIAL_NAME \"Mat01\""); + idtf.write(2,"SHADER_ACTIVE_TEXTURE_COUNT 0"); + idtf.write(1,"}"); + idtf.write(0,"}"); + + idtf.write(0,"RESOURCE_LIST \"MATERIAL\" {"); + idtf.write(1,"RESOURCE_COUNT 1"); + idtf.write(1,"RESOURCE 0 {"); + idtf.write(2,"RESOURCE_NAME \"Mat01\""); + idtf.write(2,"MATERIAL_AMBIENT 0.2 0.2 0.2"); + idtf.write(2,"MATERIAL_DIFFUSE 0.8 0.8 0.8"); + idtf.write(2,"MATERIAL_SPECULAR 0.0 0.0 0.0"); + idtf.write(2,"MATERIAL_EMISSIVE 0.0 0.0 0.0"); + idtf.write(2,"MATERIAL_REFLECTIVITY 0.0"); + idtf.write(2,"MATERIAL_OPACITY 1.000000"); + idtf.write(1,"}"); + idtf.write(0,"}"); + } + + if ((mask & vcg::tri::io::Mask::IOM_WEDGTEXCOORD) | (mask & vcg::tri::io::Mask::IOM_VERTCOLOR)) + { + idtf.write(0,""); + idtf.write(0,"MODIFIER \"SHADING\" {"); + idtf.write(1,"MODIFIER_NAME \"VcgMesh01\""); + idtf.write(1,"PARAMETERS {"); + if (mask & vcg::tri::io::Mask::IOM_WEDGTEXCOORD) + { + idtf.write(2,"SHADER_LIST_COUNT " + TextUtility::nmbToStr(m.textures.size())); + idtf.write(2,"SHADING_GROUP {"); + for(unsigned int ii = 0; ii < m.textures.size();++ii) + { + idtf.write(3,"SHADER_LIST " + TextUtility::nmbToStr(ii) + "{"); + idtf.write(4,"SHADER_COUNT 1"); + idtf.write(4,"SHADER_NAME_LIST {"); + idtf.write(5,"SHADER 0 NAME: \"ModelShader" + TextUtility::nmbToStr(ii) + "\""); + idtf.write(4,"}"); + idtf.write(3,"}"); + } + idtf.write(2,"}"); + } + else + { + idtf.write(2,"SHADER_LIST_COUNT 1"); + idtf.write(2,"SHADER_LIST_LIST {"); + idtf.write(3,"SHADER_LIST 0 {"); + idtf.write(4,"SHADER_COUNT 1"); + idtf.write(4,"SHADER_NAME_LIST {"); + idtf.write(5,"SHADER 0 NAME: \"VcgMesh010\""); + idtf.write(4,"}"); + idtf.write(3,"}"); + idtf.write(2,"}"); + } + idtf.write(1,"}"); + idtf.write(0,"}"); + } + + return E_NOERROR; + } + + static int GetExportMaskCapability() + { + int capability = 0; + + //vert + capability |= vcg::tri::io::Mask::IOM_VERTNORMAL; + capability |= vcg::tri::io::Mask::IOM_VERTCOLOR; + + ////wedg + capability |= vcg::tri::io::Mask::IOM_WEDGTEXCOORD; + capability |= vcg::tri::io::Mask::IOM_WEDGNORMAL; + + return capability; + } +}; +} +} +} + #endif \ No newline at end of file