From f2ca2efddb312198e778bdbbd4ef3a93ab1459bf Mon Sep 17 00:00:00 2001 From: Paolo Cignoni cignoni Date: Fri, 2 Oct 2009 20:11:11 +0000 Subject: [PATCH] used the std function to write output file --- src/fgt/filter_hqrender/filter_hqrender.cpp | 1037 ++++++++++--------- src/fgt/filter_hqrender/filter_hqrender.h | 2 +- 2 files changed, 564 insertions(+), 475 deletions(-) diff --git a/src/fgt/filter_hqrender/filter_hqrender.cpp b/src/fgt/filter_hqrender/filter_hqrender.cpp index 33365988c..412c63953 100644 --- a/src/fgt/filter_hqrender/filter_hqrender.cpp +++ b/src/fgt/filter_hqrender/filter_hqrender.cpp @@ -1,476 +1,565 @@ -#include -#include -#include -//#include -#include -#include - -#include -#include -#include - - - -// Constructor usually performs only two simple tasks of filling the two lists -// - typeList: with all the possible id of the filtering actions -// - actionList with the corresponding actions. If you want to add icons to your filtering actions you can do here by construction the QActions accordingly - -FilterHighQualityRender::FilterHighQualityRender() -{ - typeList << FP_HIGHQUALITY_RENDER; +#include +#include +#include +//#include +#include +#include + +#include +#include +#include + + + +// Constructor usually performs only two simple tasks of filling the two lists +// - typeList: with all the possible id of the filtering actions +// - actionList with the corresponding actions. If you want to add icons to your filtering actions you can do here by construction the QActions accordingly + +FilterHighQualityRender::FilterHighQualityRender() +{ + typeList << FP_HIGHQUALITY_RENDER; + + foreach(FilterIDType tt , types()) + actionList << new QAction(filterName(tt), this); + + templateDir = qApp->applicationDirPath(); +#if defined(Q_OS_WIN) + if (templateDir.dirName() == "debug" || templateDir.dirName() == "release" || templateDir.dirName() == "plugins") + templateDir.cdUp(); +#elif defined(Q_OS_MAC) + if (templateDir.dirName() == "MacOS") { + for (int i = 0; i < 6; ++i) { + templateDir.cdUp(); + if (templateDir.exists("render_template")) + break; + } + } +#endif + if(!templateDir.cd("render_template")) { + qDebug("Error. I was expecting to find the render_template dir. Now i am in dir %s",qPrintable(templateDir.absolutePath())); + ;//this->errorMessage = "\"render_template\" folder not found"; + } +} + +// ST() must return the very short string describing each filtering action +// (this string is used also to define the menu entry) +const QString FilterHighQualityRender::filterName(FilterIDType filterId) const +{ + switch(filterId) { + case FP_HIGHQUALITY_RENDER : return QString("Render high quality image"); + default : assert(0); + } + return QString(); +} + +// Info() must return the longer string describing each filtering action +// (this string is used in the About plugin dialog) +const QString FilterHighQualityRender::filterInfo(FilterIDType filterId) const +{ + switch(filterId) { + case FP_HIGHQUALITY_RENDER : return QString("Make an high quality image of current mesh on a choosen template scene."); + default : assert(0); + } + return QString("Unknown Filter"); +} + +// The FilterClass describes in which generic class of filters it fits. +// This choice affect the submenu in which each filter will be placed +// More than a single class can be choosen. +const FilterHighQualityRender::FilterClass FilterHighQualityRender::getClass(QAction *a) +{ + switch(ID(a)) + { + case FP_HIGHQUALITY_RENDER : return MeshFilterInterface::Generic; + default : assert(0); + } + return MeshFilterInterface::Generic; +} + +// This function define the needed parameters for each filter. Return true if the filter has some parameters +// it is called every time, so you can set the default value of parameters according to the mesh +// For each parmeter you need to define, +// - the name of the parameter, +// - the string shown in the dialog +// - the default value +// - a possibly long string describing the meaning of that parameter (shown as a popup help in the dialog) +void FilterHighQualityRender::initParameterSet(QAction *action, MeshModel &m, RichParameterSet & parlst) +{ + switch(ID(action)) { + case FP_HIGHQUALITY_RENDER : + { + parlst.addParam(new RichInt("FormatX", 800, "Format X")); + parlst.addParam(new RichInt("FormatY", 600, "Format Y")); + parlst.addParam(new RichFloat("PixelAspectRatio", 1.0, "Pixel aspect ratio")); + parlst.addParam(new RichBool("Autoscale",true,"Auto-scale mesh","Check if the object will be scaled on render scene")); + + //update the template list + templates = QStringList(); + foreach(QString subDir, templateDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot)) { + QString temp(templateDir.absolutePath() + QDir::separator() + subDir + QDir::separator() + subDir + ".rib"); + if(QFile::exists(temp)) + templates << subDir; + } + if(templates.isEmpty()) + { + this->errorMessage = "No template scene has been found in \"render_template\" directory"; + qDebug(qPrintable(this->errorMessage)); + } + parlst.addParam(new RichEnum("scene",0,templates,"Select scene")); + + // ******Ë il nome dell'immagine, ma poi va copiata nella cartella della mesh...****** + parlst.addParam(new RichString("ImageName", "default.tiff", "Name of output image")); + + //DON'T WORK!! + //delRibFiles = true; + //FileValue fv(""); + //parlst.addParam(new RichSaveFile("SceneName",&fv,&FileDecoration(&fv,".rib","Name of file rib to save","If not specified, the file will be removed"))); + + + break; + } + default : assert(0); + } +} + +// The Real Core Function doing the actual mesh processing. +bool FilterHighQualityRender::applyFilter(QAction *filter, MeshModel &m, RichParameterSet & par, vcg::CallBackPos *cb) +{ + // Typical usage of the callback for showing a nice progress bar in the bottom. + // First parameter is a 0..100 number indicating percentage of completion, the second is an info string. + //cb(100*i/m.cm.vert.size(), "Randomly Displacing..."); + // Log function dump textual info in the lower part of the MeshLab screen. + //Log(GLLogStream::FILTER,"Successfully displaced %i vertices",m.cm.vn); + + + //read a template file e make a new file rib + + //QString templatePath = par.getOpenFileName("TemplateName"); + QString templateName = templates.at(par.getEnum("scene")); + QString templatePath = templateDir.absolutePath() + QDir::separator() + templateName + QDir::separator() + templateName + ".rib"; + //QString templatePath("e:\\fgt\\meshlab\\src\\meshlab\\render_template\\default\\default.rib"); + + + QString templateDir = getDirFromPath(&templatePath); + + RibFileStack files(&templateName, &templateDir); //constructor + //open file and stream + if(!files.pushFile(&templatePath)) { + this->errorMessage = "Template path is wrong: " + templatePath; + return false; + } + + //destination diretory + QString dest(""); + //QString dest = par.getSaveFileName("SceneName"); + if(dest == "") { //default value: temporany directory + QDir temp = QDir::temp(); + if(!temp.cd("scene")) { + if(temp.mkdir("scene")) { + if(!temp.cd("scene")) + return false; + } + else { + return false; + } + } + dest = temp.absolutePath() + QDir::separator() + "scene.rib"; + delRibFiles = true; + } + else { + delRibFiles = false; + } + + QString destDir = getDirFromPath(&dest); + QString destFile = getFileNameFromPath(&dest); + qDebug("Starting to write rib file into %s",qPrintable(dest)); + //output file + QFile outFile(dest); + if(!outFile.open(QIODevice::WriteOnly | QIODevice::Text)) { + return false; + } + QTextStream out(&outFile); + FILE* fout; + //fout = fopen(dest.data.data(),"wb"); + fout = fopen(qPrintable(dest),"wb"); + if(fout==NULL) { - foreach(FilterIDType tt , types()) - actionList << new QAction(filterName(tt), this); - - templateDir = qApp->applicationDirPath(); -#if defined(Q_OS_WIN) - if (templateDir.dirName() == "debug" || templateDir.dirName() == "release" || templateDir.dirName() == "plugins") - templateDir.cdUp(); -#elif defined(Q_OS_MAC) - if (templateDir.dirName() == "MacOS") { - for (int i = 0; i < 6; ++i) { - templateDir.cdUp(); - if (templateDir.exists("render_template")) - break; - } - } -#endif - if(!templateDir.cd("render_template")) { - qDebug("Error. I was expecting to find the render_template dir. Now i am in dir %s",qPrintable(templateDir.absolutePath())); - ;//this->errorMessage = "\"render_template\" folder not found"; - } -} - -// ST() must return the very short string describing each filtering action -// (this string is used also to define the menu entry) -const QString FilterHighQualityRender::filterName(FilterIDType filterId) const -{ - switch(filterId) { - case FP_HIGHQUALITY_RENDER : return QString("Render high quality image"); - default : assert(0); - } - return QString(); -} - -// Info() must return the longer string describing each filtering action -// (this string is used in the About plugin dialog) -const QString FilterHighQualityRender::filterInfo(FilterIDType filterId) const -{ - switch(filterId) { - case FP_HIGHQUALITY_RENDER : return QString("Make an high quality image of current mesh on a choosen template scene."); - default : assert(0); - } - return QString("Unknown Filter"); -} - -// The FilterClass describes in which generic class of filters it fits. -// This choice affect the submenu in which each filter will be placed -// More than a single class can be choosen. -const FilterHighQualityRender::FilterClass FilterHighQualityRender::getClass(QAction *a) -{ - switch(ID(a)) - { - case FP_HIGHQUALITY_RENDER : return MeshFilterInterface::Generic; - default : assert(0); - } - return MeshFilterInterface::Generic; -} - -// This function define the needed parameters for each filter. Return true if the filter has some parameters -// it is called every time, so you can set the default value of parameters according to the mesh -// For each parmeter you need to define, -// - the name of the parameter, -// - the string shown in the dialog -// - the default value -// - a possibly long string describing the meaning of that parameter (shown as a popup help in the dialog) -void FilterHighQualityRender::initParameterSet(QAction *action, MeshModel &m, RichParameterSet & parlst) -{ - switch(ID(action)) { - case FP_HIGHQUALITY_RENDER : - { - parlst.addParam(new RichInt("FormatX", 800, "Format X")); - parlst.addParam(new RichInt("FormatY", 600, "Format Y")); - parlst.addParam(new RichFloat("PixelAspectRatio", 1.0, "Pixel aspect ratio")); - parlst.addParam(new RichBool("Autoscale",true,"Auto-scale mesh","Check if the object will be scaled on render scene")); - - //update the template list - templates = QStringList(); - foreach(QString subDir, templateDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot)) { - QString temp(templateDir.absolutePath() + QDir::separator() + subDir + QDir::separator() + subDir + ".rib"); - if(QFile::exists(temp)) - templates << subDir; - } - if(templates.isEmpty()) - { - this->errorMessage = "No template scene has been found in \"render_template\" directory"; - qDebug(qPrintable(this->errorMessage)); - } - parlst.addParam(new RichEnum("scene",0,templates,"Select scene")); - - // ******Ë il nome dell'immagine, ma poi va copiata nella cartella della mesh...****** - parlst.addParam(new RichString("ImageName", "default.tiff", "Name of output image")); - - //DON'T WORK!! - //delRibFiles = true; - //FileValue fv(""); - //parlst.addParam(new RichSaveFile("SceneName",&fv,&FileDecoration(&fv,".rib","Name of file rib to save","If not specified, the file will be removed"))); - - - break; - } - default : assert(0); - } -} - -// The Real Core Function doing the actual mesh processing. -bool FilterHighQualityRender::applyFilter(QAction *filter, MeshModel &m, RichParameterSet & par, vcg::CallBackPos *cb) -{ - // Typical usage of the callback for showing a nice progress bar in the bottom. - // First parameter is a 0..100 number indicating percentage of completion, the second is an info string. - //cb(100*i/m.cm.vert.size(), "Randomly Displacing..."); - // Log function dump textual info in the lower part of the MeshLab screen. - //Log(GLLogStream::FILTER,"Successfully displaced %i vertices",m.cm.vn); - - - //read a template file e make a new file rib - - //QString templatePath = par.getOpenFileName("TemplateName"); - QString templateName = templates.at(par.getEnum("scene")); - QString templatePath = templateDir.absolutePath() + QDir::separator() + templateName + QDir::separator() + templateName + ".rib"; - //QString templatePath("e:\\fgt\\meshlab\\src\\meshlab\\render_template\\default\\default.rib"); - - - QString templateDir = getDirFromPath(&templatePath); - - RibFileStack files(&templateName, &templateDir); //constructor - //open file and stream - if(!files.pushFile(&templatePath)) { - this->errorMessage = "Template path is wrong: " + templatePath; - return false; - } - - //destination diretory - QString dest(""); - //QString dest = par.getSaveFileName("SceneName"); - if(dest == "") { //default value: temporany directory - QDir temp = QDir::temp(); - if(!temp.cd("scene")) { - if(temp.mkdir("scene")) { - if(!temp.cd("scene")) - return false; - } - else { - return false; - } - } - dest = temp.absolutePath() + QDir::separator() + "scene.rib"; - delRibFiles = true; - } - else { - delRibFiles = false; - } - - QString destDir = getDirFromPath(&dest); - QString destFile = getFileNameFromPath(&dest); - qDebug("Starting to write rib file into %s",qPrintable(dest)); - //output file - QFile outFile(dest); - if(!outFile.open(QIODevice::WriteOnly | QIODevice::Text)) { - return false; - } - QTextStream out(&outFile); - - /////controlli di coordinate, ecc.... per ora non servono... credo - //if(m.cm.textures.size()>1 && m.cm.HasPerWedgeTexCoord() || m.cm.HasPerVertexTexCoord()) - - //TEXTURE: - //1. Take the list of texture mesh - QStringList textureList; - for(int i=0; i5) { - for(int i= 5; ido nothing - } - } - } - } - if(writeLine) { - //copy the same line of in file - (out)<isEmpty() && !exit) { - QString line = files->topNextLine(); - QStringList token = line.split(' '); - - if(token[0].trimmed() == "AttributeBegin") - ++c; - if(token[0].trimmed() == "AttributeEnd") - --c; - - //autoscale - if(token[0].trimmed() == "Bound") { - if(par.getBool("Autoscale")) { - float meshX = m.cm.trBB().DimX(); - float meshY = m.cm.trBB().DimY(); - float meshZ = m.cm.trBB().DimZ(); - float dummyX = token[2].toFloat() - token[1].toFloat(); - float dummyY = token[4].toFloat() - token[3].toFloat(); - float dummyZ = token[6].toFloat() - token[5].toFloat(); - float ratioX = dummyX / meshX; - float ratioY = dummyY / meshZ; - float ratioZ = dummyZ / meshY; - scale = std::min(ratioX, ratioY); - scale = std::min(scale, ratioZ); - } - out<topNextLine(); - out<topNextLine(); - out<1 && m.cm.HasPerWedgeTexCoord() || m.cm.HasPerVertexTexCoord()) { - foreach(QString textureName, *textureList) { - out<<"Surface \"paintedplastic\" \"texturename\" [\"" + getFileNameFromPath(&textureName,false) + ".tx\"]"<::CompactVertexVector(m.cm); - vcg::tri::Allocator::CompactFaceVector(m.cm); - - QTime tt; tt.start(); - - //replace with opened mesh - out<<"Declare \"Cs\" \"facevarying color\""<::VertexClearV(m.cm); - - //second: index of vertex for face - for(CMeshO::FaceIterator fi=m.cm.face.begin(); fi!=m.cm.face.end(); ++fi) { - for(int j=0; j<3; ++j) { - int indexOfVertex = (*fi).V(j) - &(m.cm.vert[0]); - out<IsV()) { - (*fi).V(j)->SetV(); - } -// out<IsV()) { - vcg::Point3f p; - //p.Import(vi->P()); - p = vi->P(); - if(scale!= 1.0) { - p[0] = (p[0] + c[0])*scale - c[0]; - p[1] = (p[1] + c[1])*scale - c[1]; - p[2] = (p[2] + c[2])*scale - c[2]; - } - out<N(); - out<C(); - out< tc(((*fi).V(j))->T().U(),((*fi).V(j))->T().V()); ; - //out<left(path->lastIndexOf(QDir::separator())); //don't work :/ - return path->left(std::max(path->lastIndexOf('\\'),path->lastIndexOf('/'))); -} - -QString FilterHighQualityRender::getFileNameFromPath(QString* path, bool type) { - //return path->right(path->size() - 1 - path->lastIndexOf(QDir::separator())); //don't work :/ - QString temp = path->right(path->size() - 1 - std::max(path->lastIndexOf('\\'),path->lastIndexOf('/'))); - if(type) - return temp; - else - return temp.left(temp.lastIndexOf('.')); -} - + } + + /////controlli di coordinate, ecc.... per ora non servono... credo + //if(m.cm.textures.size()>1 && m.cm.HasPerWedgeTexCoord() || m.cm.HasPerVertexTexCoord()) + + //TEXTURE: + //1. Take the list of texture mesh + QStringList textureList; + for(int i=0; i5) { + for(int i= 5; ido nothing + } + } + } + } + if(writeLine) { + //copy the same line of in file + //(out)<isEmpty() && !exit) { + QString line = files->topNextLine(); + QStringList token = line.split(' '); + + if(token[0].trimmed() == "AttributeBegin") + ++c; + if(token[0].trimmed() == "AttributeEnd") + --c; + + //take the transformation matrix of dummy + if(token[0].trimmed() == "Transform") { + float t[16]; + //an array in renderman can contains the char '\n' :( + QString matrixString = line; + while(!line.contains(']')) { + line = files->topNextLine(); + matrixString += line; + } + int k=0; + QStringList list = matrixString.split(' '); + for(int i=0; i(ratioX, ratioY); + scale = std::min(scale, ratioZ); + + vcg::Point3f c = m.cm.trBB().Center(); + vcg::Matrix44f m1,m2,m3,m4,result; + m1.SetTranslate(c[0],c[1],c[2]); + m2.SetScale(scale,scale,scale); + m3.SetTranslate(-c[0],-c[1],-c[2]); + m4 = vcg::Inverse(transfMatrix); + result = m3 * m2 * m1 * transfMatrix; + //out<<"Transform [ "; + fprintf(fout,"Transform [ "); + for(int i = 0; i<4; i++) + for(int j = 0; j<4; j++) + //out<topNextLine(); + //out<1 && m.cm.HasPerWedgeTexCoord() || m.cm.HasPerVertexTexCoord()) { + foreach(QString textureName, *textureList) { + //out<<"Surface \"paintedplastic\" \"texturename\" [\"" + getFileNameFromPath(&textureName,false) + ".tx\"]"<::CompactVertexVector(m.cm); + vcg::tri::Allocator::CompactFaceVector(m.cm); + + QTime tt; tt.start(); + + //replace with opened mesh + //out<<"Declare \"Cs\" \"facevarying color\""<::VertexClearV(m.cm); + + //second: index of vertex for face + for(CMeshO::FaceIterator fi=m.cm.face.begin(); fi!=m.cm.face.end(); ++fi) { + for(int j=0; j<3; ++j) { + int indexOfVertex = (*fi).V(j) - &(m.cm.vert[0]); + //out<IsV()) { + (*fi).V(j)->SetV(); + } + //out<IsV()) { + vcg::Point3f p; + //p.Import(vi->P()); + p = vi->P(); + if(scale!= 1.0) { + /*vcg::Point3f c = m.cm.trBB().Center(); + vcg::Matrix44f m1,m2,m3; + m1.SetTranslate(c[0],c[1],c[2]); + m2.SetScale(scale,scale,scale); + m3.SetTranslate(-c[0],-c[1],-c[2]); + p = m1 * m2 * m3 * p;*/ + //p[0] = (p[0] + c[0])*scale - c[0]; + //p[1] = (p[1] + c[1])*scale - c[1]; + //p[2] = (p[2] + c[2])*scale - c[2]; + //p[0] = (p[0] + x)*scale - x; + //p[1] = (p[1] + y)*scale - y; + //p[2] = (p[2] + z)*scale - z; + } + //out<N(); + //out<C(); + //out< tc(((*fi).V(j))->T().U(),((*fi).V(j))->T().V()); ; + //out<left(path->lastIndexOf(QDir::separator())); //don't work :/ + return path->left(std::max(path->lastIndexOf('\\'),path->lastIndexOf('/'))); +} + +QString FilterHighQualityRender::getFileNameFromPath(QString* path, bool type) { + //return path->right(path->size() - 1 - path->lastIndexOf(QDir::separator())); //don't work :/ + QString temp = path->right(path->size() - 1 - std::max(path->lastIndexOf('\\'),path->lastIndexOf('/'))); + if(type) + return temp; + else + return temp.left(temp.lastIndexOf('.')); +} + Q_EXPORT_PLUGIN(FilterHighQualityRender) \ No newline at end of file diff --git a/src/fgt/filter_hqrender/filter_hqrender.h b/src/fgt/filter_hqrender/filter_hqrender.h index ebad85d9e..14dad8d21 100644 --- a/src/fgt/filter_hqrender/filter_hqrender.h +++ b/src/fgt/filter_hqrender/filter_hqrender.h @@ -33,7 +33,7 @@ private: QStringList templates; bool delRibFiles; - int convertGeometry(RibFileStack* files, QTextStream &out, MeshModel &m, RichParameterSet &, QStringList* textureList); + int convertGeometry(RibFileStack* files, FILE* fout /*QTextStream &out*/, MeshModel &m, RichParameterSet &, QStringList* textureList); QString getDirFromPath(QString* path); QString getFileNameFromPath(QString* path, bool type = true); };