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
{
2007-12-06 10:58:54 +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
{
2007-10-18 17:01:53 +02:00
QProcess p ;
2007-11-21 11:25:45 +01:00
QString convstring = par . _converter_loc ;
2007-12-11 14:00:35 +01:00
convstring = convstring + " -en1 -input " + par . _input_file + " -output " + par . _output_file ;
2007-12-06 10:58:54 +01:00
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 ) ;
2007-10-18 17:01:53 +02:00
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 )
2007-10-18 17:01:53 +02:00
{
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} " ) ;
2007-10-18 17:01:53 +02:00
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 ) ;
}
2007-10-18 17:01:53 +02:00
latex . write ( 1 , " 3Dlights=File, " ) ;
2007-12-05 15:12:13 +01:00
latex . write ( 0 , " ]{ \\ linewidth}{ \\ linewidth}{ " + u3d_final + " } " ) ;
2007-10-18 17:01:53 +02:00
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
{
2007-10-18 17:01:53 +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 ) ;
2007-10-18 17:01:53 +02:00
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 ) ;
2007-12-06 10:58:54 +01:00
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 ) ;
2007-10-18 17:01:53 +02:00
QDir : : setCurrent ( curr ) ;
2007-11-21 11:25:45 +01:00
QString lat ( output_file ) ;
2007-10-18 17:01:53 +02:00
QStringList l = lat . split ( " . " ) ;
2007-11-21 11:25:45 +01:00
SaveLatex ( m , l [ 0 ] , mov_par ) ;
2007-10-18 17:01:53 +02:00
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