vcglib/wrap/io_trimesh/export_u3d.h

375 lines
10 KiB
C
Raw Normal View History

2007-10-17 09:57:04 +02:00
#ifndef __VCGLIB_EXPORTERU3D
#define __VCGLIB_EXPORTERU3D
2007-10-17 12:03:14 +02:00
#include <cstdlib>
2007-10-17 09:57:04 +02:00
#include <string>
2007-11-19 12:30:27 +01:00
#include <QDir>
#include <QString>
#include <QProcess>
2007-12-14 00:15:45 +01:00
#include <vector>
2007-10-17 12:03:14 +02:00
#include "export_idtf.h"
2007-12-05 15:12:13 +01:00
#include<vcg/space/point3.h>
2007-10-17 09:57:04 +02:00
namespace vcg {
namespace tri {
namespace io {
2007-12-05 15:12:13 +01:00
namespace u3dparametersclasses
2007-10-17 09:57:04 +02:00
{
2007-12-05 15:12:13 +01:00
struct IDTFConverterParameters
2007-11-21 11:25:45 +01:00
{
const QString _converter_loc;
const QString _input_file;
const QString _output_file;
2007-11-21 11:25:45 +01:00
2007-12-05 15:12:13 +01:00
IDTFConverterParameters(const QString& converter_loc,const QString& input_file,const QString& output_file)
:_converter_loc(converter_loc),_input_file(input_file),_output_file(output_file)
2007-11-21 11:25:45 +01:00
{
2007-12-05 15:12:13 +01:00
}
2007-11-21 11:25:45 +01:00
};
struct Movie15Parameters
{
Movie15Parameters()
{
_campar = NULL;
}
//WARNING: in movie15 y-axis and z-axis have been inverted!!!
class CameraParameters
{
public:
2007-12-05 15:12:13 +01:00
CameraParameters()
2007-12-11 15:51:34 +01:00
:_cam_fov_angle(0.0f),_cam_roll_angle(0.0f),_obj_to_cam_dir(vcg::Point3f(0.0f,0.0f,0.0f)),_obj_to_cam_dist(0.0f),_obj_bbox_diag(0.0f),_obj_pos(vcg::Point3f(0.0f,0.0f,0.0f))
{
}
CameraParameters(const vcg::Point3f& mesh_center,const float mesh_bbox_diag)
:_cam_fov_angle(0.0f),_cam_roll_angle(0.0f),_obj_to_cam_dir(vcg::Point3f(0.0f,0.0f,mesh_bbox_diag)),_obj_to_cam_dist(0.0),_obj_pos(mesh_center),_obj_bbox_diag(mesh_bbox_diag)
2007-12-05 15:12:13 +01:00
{
}
2007-11-21 11:25:45 +01:00
CameraParameters(const float cam_fov_angle,const float cam_roll_angle,
const vcg::Point3f& obj_to_cam_dir,const float obj_to_cam_dist,
2007-12-14 00:15:45 +01:00
const float obj_bbox_diag,
2007-11-21 11:25:45 +01:00
const vcg::Point3f& obj_pos = vcg::Point3f(0.0f,0.0f,0.0f))
2007-12-14 00:15:45 +01:00
:_cam_fov_angle(cam_fov_angle),_cam_roll_angle(cam_roll_angle),_obj_to_cam_dir(obj_to_cam_dir),_obj_to_cam_dist(obj_to_cam_dist),_obj_pos(obj_pos),_obj_bbox_diag(obj_bbox_diag)
2007-11-21 11:25:45 +01:00
{
}
float _cam_fov_angle;
float _cam_roll_angle;
vcg::Point3f _obj_to_cam_dir;
float _obj_to_cam_dist;
vcg::Point3f _obj_pos;
2007-12-11 15:51:34 +01:00
float _obj_bbox_diag;
2007-11-21 11:25:45 +01:00
};
CameraParameters* _campar;
};
2007-12-05 15:12:13 +01:00
}
2007-11-21 11:25:45 +01:00
2007-12-07 11:45:43 +01:00
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)
{
2007-12-14 00:15:45 +01:00
2007-12-07 11:45:43 +01:00
if (file_path.size() > 0)
return file_path.at(file_path.size() - 1);
2007-12-14 00:15:45 +01:00
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);
2007-12-07 11:45:43 +01:00
}
}
2007-12-14 00:15:45 +01:00
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();
std::ofstream file(qPrintable(outfile),std::ofstream::binary);
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<unsigned char*>(im.bits());
else
{
tmpchan = new unsigned char[totbyte];
unsigned int ii = 0;
while(ii < totbyte)
{
tmpchan[ii] = const_cast<unsigned char*>(im.bits())[ii + (ii/3)];
++ii;
}
}
file.write((char *) &tga,sizeof(tga));
file.write(reinterpret_cast<const char*>(tmpchan),totbyte);
file.close();
}
};
2007-12-07 11:45:43 +01:00
2007-12-05 15:12:13 +01:00
template<typename SaveMeshType>
class ExporterU3D
{
2007-10-17 09:57:04 +02:00
2007-12-05 15:12:13 +01:00
public:
enum U3DError
2007-11-21 11:25:45 +01:00
{
2007-12-05 15:12:13 +01:00
E_NOERROR, // 0
E_ABORTED_CONVERSION //1
};
2007-11-21 11:25:45 +01:00
2007-12-05 15:12:13 +01:00
static const char *ErrorMsg(int error)
{
static const char * dae_error_msg[] =
2007-11-21 11:25:45 +01:00
{
2007-12-05 15:12:13 +01:00
"No errors",
"Conversion Process From Idtf intermediate file to U3D format aborted"
};
if(error>1 || error<0) return "Unknown error";
else return dae_error_msg[error];
2007-11-21 11:25:45 +01:00
};
2007-12-05 15:12:13 +01:00
private:
static int InvokeConverter(const u3dparametersclasses::IDTFConverterParameters& par)
2007-10-17 09:57:04 +02:00
{
QProcess p;
2007-11-21 11:25:45 +01:00
QString convstring = par._converter_loc;
convstring = convstring + " -en1 -input " + par._input_file + " -output " + par._output_file;
qDebug("Starting converter %s", qPrintable(convstring));
p.setProcessChannelMode(QProcess::MergedChannels);
2007-11-21 11:25:45 +01:00
p.start(convstring);
//wait until the task has been completed
bool t = p.waitForFinished(-1);
p.close();
2007-11-21 11:25:45 +01:00
return (int) t;
2007-10-17 09:57:04 +02:00
}
2007-12-12 01:24:57 +01:00
static void SaveLatex(SaveMeshType& /*m*/,const QString& file,const u3dparametersclasses::Movie15Parameters& mov_par)
{
Output_File latex(file.toStdString() + ".tex");
QString u3df = file + ".u3d";
2007-12-05 15:12:13 +01:00
QStringList file_trim;
2007-12-07 11:45:43 +01:00
QtUtilityFunctions::splitFilePath(u3df,file_trim);
std::string u3d_final = QtUtilityFunctions::fileNameFromTrimmedPath(file_trim).toStdString();
2007-10-19 12:49:20 +02:00
latex.write(0,"\\begin{document}");
latex.write(0,"\\includemovie[");
latex.write(1,"poster,");
latex.write(1,"toolbar, %same as `controls\'");
2007-12-05 15:12:13 +01:00
latex.write(1,"label=" + u3d_final + ",");
latex.write(1,"text=(" + u3d_final + "),");
2007-11-21 11:25:45 +01:00
std::string cam_string;
2007-12-05 15:12:13 +01:00
u3dparametersclasses::Movie15Parameters::CameraParameters* cam = mov_par._campar;
if (cam != NULL)
{
cam_string = cam_string + "3Daac=" + TextUtility::nmbToStr(cam->_cam_fov_angle) +
", 3Droll=" + TextUtility::nmbToStr(cam->_cam_roll_angle) +
2007-12-10 17:52:38 +01:00
", 3Dc2c=" + TextUtility::nmbToStr(cam->_obj_to_cam_dir.X()) + " " + TextUtility::nmbToStr(cam->_obj_to_cam_dir.Z()) + " " + TextUtility::nmbToStr(cam->_obj_to_cam_dir.Y()) +
2007-12-05 15:12:13 +01:00
", 3Droo=" + TextUtility::nmbToStr(cam->_obj_to_cam_dist) +
2007-12-14 13:03:44 +01:00
", 3Dcoo=" + TextUtility::nmbToStr(-cam->_obj_pos.X()) + " " + TextUtility::nmbToStr(cam->_obj_pos.Z()) + " " + TextUtility::nmbToStr(cam->_obj_pos.Y()) + ",";
2007-12-05 15:12:13 +01:00
latex.write(1,cam_string);
}
latex.write(1,"3Dlights=File,");
2007-12-05 15:12:13 +01:00
latex.write(0,"]{\\linewidth}{\\linewidth}{" + u3d_final + "}");
latex.write(0,"\\end{document}");
}
2007-10-17 12:03:14 +02:00
2007-12-14 00:15:45 +01:00
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);
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;
qtmp = stmp + qtmp.remove(ext) + "tga";
m.textures[ii] = qtmp.toStdString();
TGA_Exporter::convert(qtmp,img);
conv_file.push_back(qtmp);
}
}
}
static void removeConvertedTexturesFiles(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]));
}
}
2007-10-17 09:57:04 +02:00
public:
2007-11-21 11:25:45 +01:00
2007-12-05 15:12:13 +01:00
static int Save(SaveMeshType& m,const char* output_file,const char* conv_loc,const u3dparametersclasses::Movie15Parameters& mov_par,const int mask)
2007-10-17 09:57:04 +02:00
{
QString curr = QDir::currentPath();
2007-12-05 15:12:13 +01:00
QString out(output_file);
QStringList out_trim;
2007-12-07 11:45:43 +01:00
QtUtilityFunctions::splitFilePath(out,out_trim);
QString tmp(QDir::tempPath());
2007-12-14 00:15:45 +01:00
2007-12-07 11:45:43 +01:00
tmp = tmp + "/" + QtUtilityFunctions::fileNameFromTrimmedPath(out_trim) + ".idtf";
2007-12-05 15:12:13 +01:00
QString conv_loc_st(conv_loc);
QString output_file_st(output_file);
2007-12-14 00:15:45 +01:00
//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.
QStringList oldtextname;
for(unsigned int ii = 0; ii < m.textures.size();++ii)
oldtextname.push_back(m.textures[ii].c_str());
//tmp vector to save the tga created files that should be deleted.
QStringList convfile;
convertTexturesFiles(m,curr,convfile);
vcg::tri::io::ExporterIDTF<SaveMeshType>::Save(m,qPrintable(tmp),mask);
2007-12-05 15:12:13 +01:00
u3dparametersclasses::IDTFConverterParameters idtfpar(conv_loc_st,tmp,output_file_st);
qDebug("conv_loc_st '%s'", qPrintable(conv_loc_st));
qDebug("conv_loc '%s'", conv_loc);
qDebug("idtfpar._converter_loc '%s'", qPrintable(idtfpar._converter_loc));
2007-11-21 11:25:45 +01:00
int res = InvokeConverter(idtfpar);
2007-12-14 00:15:45 +01:00
m.textures.clear();
for(QStringList::iterator it = oldtextname.begin(); it != oldtextname.end();++it)
m.textures.push_back(it->toStdString());
//if some tga files have been created I have to delete them
removeConvertedTexturesFiles(convfile);
QDir::setCurrent(curr);
2007-11-21 11:25:45 +01:00
QString lat (output_file);
QStringList l = lat.split(".");
2007-11-21 11:25:45 +01:00
SaveLatex(m,l[0],mov_par);
QDir dir(QDir::tempPath());
2007-12-14 00:15:45 +01:00
dir.remove(tmp);
2007-12-05 15:12:13 +01:00
if (res)
return 0;
else
return 1;
2007-10-19 12:49:20 +02:00
}
static int GetExportMaskCapability()
{
int capability = 0;
//vert
2007-12-06 00:08:13 +01:00
capability |= Mask::IOM_VERTNORMAL;
2007-11-21 11:25:45 +01:00
2007-10-19 12:49:20 +02:00
////wedg
2007-12-06 00:08:13 +01:00
capability |= Mask::IOM_WEDGTEXCOORD;
capability |= Mask::IOM_WEDGNORMAL;
2007-10-19 12:49:20 +02:00
return capability;
2007-10-17 09:57:04 +02:00
}
2007-11-21 11:25:45 +01:00
2007-10-17 09:57:04 +02:00
};
}
}
}
2007-11-21 11:25:45 +01:00
#endif