2012-03-20 01:57:42 +01:00
# include "lc_global.h"
2012-03-29 03:10:55 +02:00
# include "lc_math.h"
2012-04-14 04:20:27 +02:00
# include "lc_mesh.h"
2011-09-07 23:06:51 +02:00
# include <locale.h>
# include "pieceinf.h"
2012-10-12 01:55:55 +02:00
# include "lc_texture.h"
2011-09-07 23:06:51 +02:00
# include "piece.h"
# include "camera.h"
# include "light.h"
# include "group.h"
# include "project.h"
# include "image.h"
2013-08-16 03:25:51 +02:00
# include "lc_mainwindow.h"
2011-09-07 23:06:51 +02:00
# include "view.h"
2012-10-02 03:23:44 +02:00
# include "lc_library.h"
2011-09-07 23:06:51 +02:00
# include "lc_application.h"
2013-08-09 06:57:18 +02:00
# include "lc_profile.h"
2014-04-14 05:20:16 +02:00
# include "preview.h"
2014-12-13 00:42:09 +01:00
# include "lc_qmodellistdialog.h"
2011-09-07 23:06:51 +02:00
Project : : Project ( )
{
2014-12-08 08:32:39 +01:00
mModified = false ;
2014-12-13 00:42:09 +01:00
mActiveModel = new lcModel ( tr ( " Model #1 " ) ) ;
2015-02-22 03:39:15 +01:00
mActiveModel - > CreatePieceInfo ( this ) ;
2014-12-16 00:55:17 +01:00
mActiveModel - > SetSaved ( ) ;
2014-12-13 00:42:09 +01:00
mModels . Add ( mActiveModel ) ;
2011-09-07 23:06:51 +02:00
}
Project : : ~ Project ( )
{
2014-12-08 08:32:39 +01:00
mModels . DeleteAll ( ) ;
2011-09-07 23:06:51 +02:00
}
2014-12-13 00:42:09 +01:00
bool Project : : IsModified ( ) const
2011-09-07 23:06:51 +02:00
{
2014-12-13 00:42:09 +01:00
if ( mModified )
return true ;
for ( int ModelIdx = 0 ; ModelIdx < mModels . GetSize ( ) ; ModelIdx + + )
if ( mModels [ ModelIdx ] - > IsModified ( ) )
return true ;
return false ;
}
QString Project : : GetTitle ( ) const
{
2015-02-22 03:39:15 +01:00
if ( ! mFileName . isEmpty ( ) )
return QFileInfo ( mFileName ) . fileName ( ) ;
return mModels . GetSize ( ) = = 1 ? tr ( " New Project.ldr " ) : tr ( " New Project.mpd " ) ;
2014-12-13 00:42:09 +01:00
}
void Project : : SetActiveModel ( int ModelIndex )
{
if ( ModelIndex < 0 | | ModelIndex > = mModels . GetSize ( ) )
return ;
2014-12-25 16:25:50 +01:00
for ( int ModelIdx = 0 ; ModelIdx < mModels . GetSize ( ) ; ModelIdx + + )
2014-12-30 17:56:13 +01:00
mModels [ ModelIdx ] - > SetActive ( ModelIdx = = ModelIndex ) ;
2014-12-25 16:25:50 +01:00
2015-01-17 19:29:10 +01:00
lcArray < lcModel * > UpdatedModels ;
UpdatedModels . AllocGrow ( mModels . GetSize ( ) ) ;
2015-01-02 17:44:01 +01:00
for ( int ModelIdx = 0 ; ModelIdx < mModels . GetSize ( ) ; ModelIdx + + )
2015-01-17 19:29:10 +01:00
mModels [ ModelIdx ] - > UpdatePieceInfo ( UpdatedModels ) ;
2015-01-02 17:44:01 +01:00
2014-12-13 00:42:09 +01:00
mActiveModel = mModels [ ModelIndex ] ;
mActiveModel - > UpdateInterface ( ) ;
const lcArray < View * > & Views = gMainWindow - > GetViews ( ) ;
for ( int ViewIdx = 0 ; ViewIdx < Views . GetSize ( ) ; ViewIdx + + )
Views [ ViewIdx ] - > SetModel ( lcGetActiveModel ( ) ) ;
}
bool Project : : IsModelNameValid ( const QString & Name ) const
{
if ( Name . isEmpty ( ) )
return false ;
for ( int ModelIdx = 0 ; ModelIdx < mModels . GetSize ( ) ; ModelIdx + + )
if ( mModels [ ModelIdx ] - > GetProperties ( ) . mName = = Name )
return false ;
return true ;
}
2015-12-02 02:16:12 +01:00
lcModel * Project : : CreateNewModel ( bool ShowModel )
2014-12-13 00:42:09 +01:00
{
const QString Prefix = tr ( " Model # " ) ;
int Max = 0 ;
for ( int ModelIdx = 0 ; ModelIdx < mModels . GetSize ( ) ; ModelIdx + + )
{
QString Name = mModels [ ModelIdx ] - > GetProperties ( ) . mName ;
if ( Name . startsWith ( Prefix ) )
{
QString NumberString = Name . mid ( Prefix . length ( ) ) ;
QTextStream Stream ( & NumberString ) ;
int Number ;
Stream > > Number ;
Max = qMax ( Max , Number ) ;
}
}
QString Name = Prefix + QString : : number ( Max + 1 ) ;
for ( ; ; )
{
bool Ok = false ;
2015-01-26 00:04:39 +01:00
Name = QInputDialog : : getText ( gMainWindow , tr ( " New Model " ) , tr ( " Name: " ) , QLineEdit : : Normal , Name , & Ok ) ;
2014-12-13 00:42:09 +01:00
if ( ! Ok )
2015-12-02 02:16:12 +01:00
return NULL ;
2014-12-13 00:42:09 +01:00
if ( IsModelNameValid ( Name ) )
break ;
if ( Name . isEmpty ( ) )
2015-01-26 00:04:39 +01:00
QMessageBox : : information ( gMainWindow , tr ( " Empty Name " ) , tr ( " The model name cannot be empty. " ) ) ;
2014-12-13 00:42:09 +01:00
else
2015-01-26 00:04:39 +01:00
QMessageBox : : information ( gMainWindow , tr ( " Duplicate Model " ) , tr ( " A model named '%1' already exists in this project, please enter an unique name. " ) . arg ( Name ) ) ;
2014-12-13 00:42:09 +01:00
}
2015-12-02 02:16:12 +01:00
lcModel * Model = NULL ;
2014-12-13 00:42:09 +01:00
if ( ! Name . isEmpty ( ) )
{
mModified = true ;
2015-12-02 02:16:12 +01:00
Model = new lcModel ( Name ) ;
2015-02-22 03:39:15 +01:00
Model - > CreatePieceInfo ( this ) ;
2014-12-16 00:55:17 +01:00
Model - > SetSaved ( ) ;
mModels . Add ( Model ) ;
2015-12-02 02:16:12 +01:00
if ( ShowModel )
{
SetActiveModel ( mModels . GetSize ( ) - 1 ) ;
gMainWindow - > UpdateTitle ( ) ;
}
else
SetActiveModel ( mModels . FindIndex ( mActiveModel ) ) ;
2014-12-13 00:42:09 +01:00
}
2015-12-02 02:16:12 +01:00
return Model ;
2014-12-13 00:42:09 +01:00
}
void Project : : ShowModelListDialog ( )
{
QList < QPair < QString , lcModel * > > Models ;
Models . reserve ( mModels . GetSize ( ) ) ;
for ( int ModelIdx = 0 ; ModelIdx < mModels . GetSize ( ) ; ModelIdx + + )
{
lcModel * Model = mModels [ ModelIdx ] ;
Models . append ( QPair < QString , lcModel * > ( Model - > GetProperties ( ) . mName , Model ) ) ;
}
2015-01-26 00:04:39 +01:00
lcQModelListDialog Dialog ( gMainWindow , Models ) ;
2014-12-13 00:42:09 +01:00
if ( Dialog . exec ( ) ! = QDialog : : Accepted | | Models . isEmpty ( ) )
return ;
lcArray < lcModel * > NewModels ;
for ( QList < QPair < QString , lcModel * > > : : iterator it = Models . begin ( ) ; it ! = Models . end ( ) ; it + + )
{
lcModel * Model = it - > second ;
if ( ! Model )
{
Model = new lcModel ( it - > first ) ;
2015-02-22 03:39:15 +01:00
Model - > CreatePieceInfo ( this ) ;
2014-12-16 00:55:17 +01:00
Model - > SetSaved ( ) ;
2014-12-13 00:42:09 +01:00
mModified = true ;
}
else if ( Model - > GetProperties ( ) . mName ! = it - > first )
{
Model - > SetName ( it - > first ) ;
mModified = true ;
}
NewModels . Add ( Model ) ;
}
for ( int ModelIdx = 0 ; ModelIdx < mModels . GetSize ( ) ; ModelIdx + + )
{
lcModel * Model = mModels [ ModelIdx ] ;
if ( NewModels . FindIndex ( Model ) = = - 1 )
{
delete Model ;
mModified = true ;
}
}
mModels = NewModels ;
SetActiveModel ( Dialog . mActiveModel ) ;
gMainWindow - > UpdateTitle ( ) ;
2011-09-07 23:06:51 +02:00
}
2014-12-08 08:32:39 +01:00
bool Project : : Load ( const QString & FileName )
2011-09-07 23:06:51 +02:00
{
2014-12-08 08:32:39 +01:00
QFile File ( FileName ) ;
2011-09-07 23:06:51 +02:00
2014-12-08 08:32:39 +01:00
if ( ! File . open ( QIODevice : : ReadOnly ) )
2011-09-07 23:06:51 +02:00
{
2015-01-26 00:04:39 +01:00
QMessageBox : : warning ( gMainWindow , tr ( " Error " ) , tr ( " Error reading file '%1': \n %2 " ) . arg ( FileName , File . errorString ( ) ) ) ;
2014-12-08 08:32:39 +01:00
return false ;
2011-09-07 23:06:51 +02:00
}
2014-12-13 00:42:09 +01:00
mModels . DeleteAll ( ) ;
2015-02-22 03:39:15 +01:00
QFileInfo FileInfo ( FileName ) ;
QString Extension = FileInfo . suffix ( ) . toLower ( ) ;
2013-12-19 14:41:49 +01:00
2014-12-08 08:32:39 +01:00
if ( Extension = = QLatin1String ( " dat " ) | | Extension = = QLatin1String ( " ldr " ) | | Extension = = QLatin1String ( " mpd " ) )
2013-01-06 20:24:25 +01:00
{
2015-01-06 16:38:51 +01:00
QByteArray FileData = File . readAll ( ) ;
QBuffer Buffer ( & FileData ) ;
Buffer . open ( QIODevice : : ReadOnly ) ;
2011-09-07 23:06:51 +02:00
2015-01-06 16:38:51 +01:00
while ( ! Buffer . atEnd ( ) )
2011-09-07 23:06:51 +02:00
{
2014-12-24 16:52:52 +01:00
lcModel * Model = new lcModel ( QString ( ) ) ;
2015-02-22 03:39:15 +01:00
Model - > LoadLDraw ( Buffer , this ) ;
2015-03-25 16:33:58 +01:00
if ( mModels . IsEmpty ( ) | | ! Model - > GetProperties ( ) . mName . isEmpty ( ) )
{
mModels . Add ( Model ) ;
Model - > SetSaved ( ) ;
}
else
delete Model ;
2011-09-07 23:06:51 +02:00
}
}
else
{
2014-12-08 08:32:39 +01:00
lcMemFile MemFile ;
QByteArray FileData = File . readAll ( ) ;
MemFile . WriteBuffer ( FileData . constData ( ) , FileData . size ( ) ) ;
MemFile . Seek ( 0 , SEEK_SET ) ;
2011-09-07 23:06:51 +02:00
2014-12-24 16:52:52 +01:00
lcModel * Model = new lcModel ( QString ( ) ) ;
2011-09-07 23:06:51 +02:00
2014-12-08 08:32:39 +01:00
if ( Model - > LoadBinary ( & MemFile ) )
2014-12-16 00:55:17 +01:00
{
2014-12-08 08:32:39 +01:00
mModels . Add ( Model ) ;
2014-12-16 00:55:17 +01:00
Model - > SetSaved ( ) ;
}
2014-12-08 08:32:39 +01:00
else
delete Model ;
2011-09-07 23:06:51 +02:00
}
2014-12-08 08:32:39 +01:00
if ( mModels . IsEmpty ( ) )
return false ;
2011-09-07 23:06:51 +02:00
2015-02-22 03:39:15 +01:00
if ( mModels . GetSize ( ) = = 1 )
2014-12-24 16:52:52 +01:00
{
2015-02-22 03:39:15 +01:00
lcModel * Model = mModels [ 0 ] ;
2014-12-24 16:52:52 +01:00
if ( Model - > GetProperties ( ) . mName . isEmpty ( ) )
2015-02-22 03:39:15 +01:00
Model - > SetName ( FileInfo . fileName ( ) ) ;
2014-12-24 16:52:52 +01:00
}
2015-02-22 03:39:15 +01:00
for ( int ModelIdx = 0 ; ModelIdx < mModels . GetSize ( ) ; ModelIdx + + )
mModels [ ModelIdx ] - > CreatePieceInfo ( this ) ;
2015-02-23 21:25:53 +01:00
lcArray < lcModel * > UpdatedModels ;
UpdatedModels . AllocGrow ( mModels . GetSize ( ) ) ;
for ( int ModelIdx = 0 ; ModelIdx < mModels . GetSize ( ) ; ModelIdx + + )
mModels [ ModelIdx ] - > UpdatePieceInfo ( UpdatedModels ) ;
2014-12-08 08:32:39 +01:00
mFileName = FileName ;
2014-12-13 00:42:09 +01:00
mModified = false ;
2011-09-07 23:06:51 +02:00
return true ;
}
2014-12-08 08:32:39 +01:00
bool Project : : Save ( const QString & FileName )
2011-09-07 23:06:51 +02:00
{
2014-12-08 08:32:39 +01:00
QFile File ( FileName ) ;
2011-09-07 23:06:51 +02:00
2014-12-08 08:32:39 +01:00
if ( ! File . open ( QIODevice : : WriteOnly ) )
2012-03-23 00:44:56 +01:00
{
2015-01-26 00:04:39 +01:00
QMessageBox : : warning ( gMainWindow , tr ( " Error " ) , tr ( " Error writing to file '%1': \n %2 " ) . arg ( FileName , File . errorString ( ) ) ) ;
2014-12-08 08:32:39 +01:00
return false ;
2012-03-23 00:44:56 +01:00
}
2011-09-07 23:06:51 +02:00
2014-12-08 08:32:39 +01:00
QTextStream Stream ( & File ) ;
bool MPD = mModels . GetSize ( ) > 1 ;
2011-09-07 23:06:51 +02:00
2014-12-08 08:32:39 +01:00
for ( int ModelIdx = 0 ; ModelIdx < mModels . GetSize ( ) ; ModelIdx + + )
2011-09-07 23:06:51 +02:00
{
2014-12-08 08:32:39 +01:00
lcModel * Model = mModels [ ModelIdx ] ;
2013-08-16 18:16:45 +02:00
2014-12-08 08:32:39 +01:00
if ( MPD )
Stream < < QLatin1String ( " 0 FILE " ) < < Model - > GetProperties ( ) . mName < < QLatin1String ( " \r \n " ) ;
2013-08-16 18:16:45 +02:00
2015-02-08 04:29:42 +01:00
Model - > SaveLDraw ( Stream , MPD , false ) ;
2014-12-08 08:32:39 +01:00
Model - > SetSaved ( ) ;
2013-08-16 18:16:45 +02:00
2014-12-08 08:32:39 +01:00
if ( MPD )
2014-12-26 18:09:11 +01:00
Stream < < QLatin1String ( " 0 NOFILE \r \n " ) ;
2014-12-08 08:32:39 +01:00
}
2013-08-16 18:16:45 +02:00
2014-12-08 08:32:39 +01:00
mFileName = FileName ;
mModified = false ;
2013-08-16 18:16:45 +02:00
2014-12-08 08:32:39 +01:00
return true ;
}
2013-08-16 18:16:45 +02:00
2014-12-23 18:02:23 +01:00
void Project : : Merge ( Project * Other )
{
for ( int ModelIdx = 0 ; ModelIdx < Other - > mModels . GetSize ( ) ; ModelIdx + + )
2015-02-22 03:39:15 +01:00
{
lcModel * Model = Other - > mModels [ ModelIdx ] ;
QString Name = Model - > GetProperties ( ) . mName ;
for ( ; ; )
{
bool Duplicate = false ;
for ( int SearchIdx = 0 ; SearchIdx < mModels . GetSize ( ) ; SearchIdx + + )
{
if ( mModels [ SearchIdx ] - > GetProperties ( ) . mName = = Name )
{
Duplicate = true ;
break ;
}
}
if ( ! Duplicate )
break ;
Name = tr ( " Merged " ) + Name ;
Model - > SetName ( Name ) ;
}
mModels . Add ( Model ) ;
}
2014-12-23 18:02:23 +01:00
mModified = true ;
}
2014-12-30 17:30:12 +01:00
void Project : : GetModelParts ( lcArray < lcModelPartsEntry > & ModelParts )
{
if ( mModels . IsEmpty ( ) )
return ;
for ( int ModelIdx = 0 ; ModelIdx < mModels . GetSize ( ) ; ModelIdx + + )
mModels [ ModelIdx ] - > CalculateStep ( LC_STEP_MAX ) ;
mModels [ 0 ] - > GetModelParts ( lcMatrix44Identity ( ) , gDefaultColor , ModelParts ) ;
SetActiveModel ( mModels . FindIndex ( mActiveModel ) ) ;
}
2015-03-27 21:39:43 +01:00
QString Project : : GetExportFileName ( const QString & FileName , const QString & DefaultExtension , const QString & DialogTitle , const QString & DialogFilter ) const
{
if ( ! FileName . isEmpty ( ) )
return FileName ;
QString SaveFileName ;
if ( ! mFileName . isEmpty ( ) )
SaveFileName = mFileName ;
else
SaveFileName = GetTitle ( ) ;
QString Extension = QFileInfo ( SaveFileName ) . suffix ( ) . toLower ( ) ;
if ( Extension . isEmpty ( ) )
SaveFileName + = " . " + DefaultExtension ;
else if ( Extension ! = DefaultExtension & & SaveFileName . length ( ) > 4 )
{
SaveFileName = SaveFileName . left ( SaveFileName . length ( ) - Extension . length ( ) - 1 ) ;
SaveFileName + = " . " + DefaultExtension ;
}
return QFileDialog : : getSaveFileName ( gMainWindow , DialogTitle , SaveFileName , DialogFilter ) ;
}
2015-03-27 21:20:12 +01:00
void Project : : Export3DStudio ( const QString & FileName )
2014-12-30 17:30:12 +01:00
{
lcArray < lcModelPartsEntry > ModelParts ;
GetModelParts ( ModelParts ) ;
if ( ModelParts . IsEmpty ( ) )
{
2015-01-30 17:30:13 +01:00
QMessageBox : : information ( gMainWindow , tr ( " LeoCAD " ) , tr ( " Nothing to export. " ) ) ;
2014-12-30 17:30:12 +01:00
return ;
}
2015-03-27 21:39:43 +01:00
QString SaveFileName = GetExportFileName ( FileName , " 3ds " , tr ( " Export 3D Studio " ) , tr ( " 3DS Files (*.3ds);;All Files (*.*) " ) ) ;
2014-12-30 17:30:12 +01:00
2015-03-27 21:39:43 +01:00
if ( SaveFileName . isEmpty ( ) )
return ;
2014-12-30 17:30:12 +01:00
lcDiskFile File ;
2015-03-27 21:20:12 +01:00
if ( ! File . Open ( SaveFileName , " wb " ) )
2014-12-30 17:30:12 +01:00
{
2015-01-30 17:30:13 +01:00
QMessageBox : : warning ( gMainWindow , tr ( " LeoCAD " ) , tr ( " Could not open file '%1' for writing. " ) . arg ( FileName ) ) ;
2014-12-30 17:30:12 +01:00
return ;
}
long M3DStart = File . GetPosition ( ) ;
File . WriteU16 ( 0x4D4D ) ; // CHK_M3DMAGIC
File . WriteU32 ( 0 ) ;
File . WriteU16 ( 0x0002 ) ; // CHK_M3D_VERSION
File . WriteU32 ( 10 ) ;
File . WriteU32 ( 3 ) ;
long MDataStart = File . GetPosition ( ) ;
File . WriteU16 ( 0x3D3D ) ; // CHK_MDATA
File . WriteU32 ( 0 ) ;
File . WriteU16 ( 0x3D3E ) ; // CHK_MESH_VERSION
File . WriteU32 ( 10 ) ;
File . WriteU32 ( 3 ) ;
const int MaterialNameLength = 11 ;
char MaterialName [ 32 ] ;
for ( int ColorIdx = 0 ; ColorIdx < gColorList . GetSize ( ) ; ColorIdx + + )
{
lcColor * Color = & gColorList [ ColorIdx ] ;
sprintf ( MaterialName , " Material%03d " , ColorIdx ) ;
long MaterialStart = File . GetPosition ( ) ;
File . WriteU16 ( 0xAFFF ) ; // CHK_MAT_ENTRY
File . WriteU32 ( 0 ) ;
File . WriteU16 ( 0xA000 ) ; // CHK_MAT_NAME
File . WriteU32 ( 6 + MaterialNameLength + 1 ) ;
File . WriteBuffer ( MaterialName , MaterialNameLength + 1 ) ;
File . WriteU16 ( 0xA010 ) ; // CHK_MAT_AMBIENT
File . WriteU32 ( 24 ) ;
File . WriteU16 ( 0x0011 ) ; // CHK_COLOR_24
File . WriteU32 ( 9 ) ;
File . WriteU8 ( floor ( 255.0 * Color - > Value [ 0 ] + 0.5 ) ) ;
File . WriteU8 ( floor ( 255.0 * Color - > Value [ 1 ] + 0.5 ) ) ;
File . WriteU8 ( floor ( 255.0 * Color - > Value [ 2 ] + 0.5 ) ) ;
File . WriteU16 ( 0x0012 ) ; // CHK_LIN_COLOR_24
File . WriteU32 ( 9 ) ;
File . WriteU8 ( floor ( 255.0 * Color - > Value [ 0 ] + 0.5 ) ) ;
File . WriteU8 ( floor ( 255.0 * Color - > Value [ 1 ] + 0.5 ) ) ;
File . WriteU8 ( floor ( 255.0 * Color - > Value [ 2 ] + 0.5 ) ) ;
File . WriteU16 ( 0xA020 ) ; // CHK_MAT_AMBIENT
File . WriteU32 ( 24 ) ;
File . WriteU16 ( 0x0011 ) ; // CHK_COLOR_24
File . WriteU32 ( 9 ) ;
File . WriteU8 ( floor ( 255.0 * Color - > Value [ 0 ] + 0.5 ) ) ;
File . WriteU8 ( floor ( 255.0 * Color - > Value [ 1 ] + 0.5 ) ) ;
File . WriteU8 ( floor ( 255.0 * Color - > Value [ 2 ] + 0.5 ) ) ;
File . WriteU16 ( 0x0012 ) ; // CHK_LIN_COLOR_24
File . WriteU32 ( 9 ) ;
File . WriteU8 ( floor ( 255.0 * Color - > Value [ 0 ] + 0.5 ) ) ;
File . WriteU8 ( floor ( 255.0 * Color - > Value [ 1 ] + 0.5 ) ) ;
File . WriteU8 ( floor ( 255.0 * Color - > Value [ 2 ] + 0.5 ) ) ;
File . WriteU16 ( 0xA030 ) ; // CHK_MAT_SPECULAR
File . WriteU32 ( 24 ) ;
File . WriteU16 ( 0x0011 ) ; // CHK_COLOR_24
File . WriteU32 ( 9 ) ;
File . WriteU8 ( floor ( 255.0 * 0.9f + 0.5 ) ) ;
File . WriteU8 ( floor ( 255.0 * 0.9f + 0.5 ) ) ;
File . WriteU8 ( floor ( 255.0 * 0.9f + 0.5 ) ) ;
File . WriteU16 ( 0x0012 ) ; // CHK_LIN_COLOR_24
File . WriteU32 ( 9 ) ;
File . WriteU8 ( floor ( 255.0 * 0.9f + 0.5 ) ) ;
File . WriteU8 ( floor ( 255.0 * 0.9f + 0.5 ) ) ;
File . WriteU8 ( floor ( 255.0 * 0.9f + 0.5 ) ) ;
File . WriteU16 ( 0xA040 ) ; // CHK_MAT_SHININESS
File . WriteU32 ( 14 ) ;
File . WriteU16 ( 0x0030 ) ; // CHK_INT_PERCENTAGE
File . WriteU32 ( 8 ) ;
File . WriteS16 ( ( lcuint8 ) floor ( 100.0 * 0.25 + 0.5 ) ) ;
File . WriteU16 ( 0xA041 ) ; // CHK_MAT_SHIN2PCT
File . WriteU32 ( 14 ) ;
File . WriteU16 ( 0x0030 ) ; // CHK_INT_PERCENTAGE
File . WriteU32 ( 8 ) ;
File . WriteS16 ( ( lcuint8 ) floor ( 100.0 * 0.05 + 0.5 ) ) ;
File . WriteU16 ( 0xA050 ) ; // CHK_MAT_TRANSPARENCY
File . WriteU32 ( 14 ) ;
File . WriteU16 ( 0x0030 ) ; // CHK_INT_PERCENTAGE
File . WriteU32 ( 8 ) ;
File . WriteS16 ( ( lcuint8 ) floor ( 100.0 * ( 1.0f - Color - > Value [ 3 ] ) + 0.5 ) ) ;
File . WriteU16 ( 0xA052 ) ; // CHK_MAT_XPFALL
File . WriteU32 ( 14 ) ;
File . WriteU16 ( 0x0030 ) ; // CHK_INT_PERCENTAGE
File . WriteU32 ( 8 ) ;
File . WriteS16 ( ( lcuint8 ) floor ( 100.0 * 0.0 + 0.5 ) ) ;
File . WriteU16 ( 0xA053 ) ; // CHK_MAT_REFBLUR
File . WriteU32 ( 14 ) ;
File . WriteU16 ( 0x0030 ) ; // CHK_INT_PERCENTAGE
File . WriteU32 ( 8 ) ;
File . WriteS16 ( ( lcuint8 ) floor ( 100.0 * 0.2 + 0.5 ) ) ;
File . WriteU16 ( 0xA100 ) ; // CHK_MAT_SHADING
File . WriteU32 ( 8 ) ;
File . WriteS16 ( 3 ) ;
File . WriteU16 ( 0xA084 ) ; // CHK_MAT_SELF_ILPCT
File . WriteU32 ( 14 ) ;
File . WriteU16 ( 0x0030 ) ; // CHK_INT_PERCENTAGE
File . WriteU32 ( 8 ) ;
File . WriteS16 ( ( lcuint8 ) floor ( 100.0 * 0.0 + 0.5 ) ) ;
File . WriteU16 ( 0xA081 ) ; // CHK_MAT_TWO_SIDE
File . WriteU32 ( 6 ) ;
File . WriteU16 ( 0xA087 ) ; // CHK_MAT_WIRE_SIZE
File . WriteU32 ( 10 ) ;
File . WriteFloat ( 1.0f ) ;
long MaterialEnd = File . GetPosition ( ) ;
File . Seek ( MaterialStart + 2 , SEEK_SET ) ;
File . WriteU32 ( MaterialEnd - MaterialStart ) ;
File . Seek ( MaterialEnd , SEEK_SET ) ;
}
const lcModelProperties & Properties = mModels [ 0 ] - > GetProperties ( ) ;
File . WriteU16 ( 0x0100 ) ; // CHK_MASTER_SCALE
File . WriteU32 ( 10 ) ;
File . WriteFloat ( 1.0f ) ;
File . WriteU16 ( 0x1400 ) ; // CHK_LO_SHADOW_BIAS
File . WriteU32 ( 10 ) ;
File . WriteFloat ( 1.0f ) ;
File . WriteU16 ( 0x1420 ) ; // CHK_SHADOW_MAP_SIZE
File . WriteU32 ( 8 ) ;
File . WriteS16 ( 512 ) ;
File . WriteU16 ( 0x1450 ) ; // CHK_SHADOW_FILTER
File . WriteU32 ( 10 ) ;
File . WriteFloat ( 3.0f ) ;
File . WriteU16 ( 0x1460 ) ; // CHK_RAY_BIAS
File . WriteU32 ( 10 ) ;
File . WriteFloat ( 1.0f ) ;
File . WriteU16 ( 0x1500 ) ; // CHK_O_CONSTS
File . WriteU32 ( 18 ) ;
File . WriteFloat ( 0.0f ) ;
File . WriteFloat ( 0.0f ) ;
File . WriteFloat ( 0.0f ) ;
File . WriteU16 ( 0x2100 ) ; // CHK_AMBIENT_LIGHT
File . WriteU32 ( 42 ) ;
File . WriteU16 ( 0x0010 ) ; // CHK_COLOR_F
File . WriteU32 ( 18 ) ;
File . WriteFloats ( Properties . mAmbientColor , 3 ) ;
File . WriteU16 ( 0x0013 ) ; // CHK_LIN_COLOR_F
File . WriteU32 ( 18 ) ;
File . WriteFloats ( Properties . mAmbientColor , 3 ) ;
File . WriteU16 ( 0x1200 ) ; // CHK_SOLID_BGND
File . WriteU32 ( 42 ) ;
File . WriteU16 ( 0x0010 ) ; // CHK_COLOR_F
File . WriteU32 ( 18 ) ;
File . WriteFloats ( Properties . mBackgroundSolidColor , 3 ) ;
File . WriteU16 ( 0x0013 ) ; // CHK_LIN_COLOR_F
File . WriteU32 ( 18 ) ;
File . WriteFloats ( Properties . mBackgroundSolidColor , 3 ) ;
File . WriteU16 ( 0x1100 ) ; // CHK_BIT_MAP
QByteArray BackgroundImage = Properties . mBackgroundImage . toLatin1 ( ) ;
File . WriteU32 ( 6 + 1 + strlen ( BackgroundImage . constData ( ) ) ) ;
File . WriteBuffer ( BackgroundImage . constData ( ) , strlen ( BackgroundImage . constData ( ) ) + 1 ) ;
File . WriteU16 ( 0x1300 ) ; // CHK_V_GRADIENT
File . WriteU32 ( 118 ) ;
File . WriteFloat ( 1.0f ) ;
File . WriteU16 ( 0x0010 ) ; // CHK_COLOR_F
File . WriteU32 ( 18 ) ;
File . WriteFloats ( Properties . mBackgroundGradientColor1 , 3 ) ;
File . WriteU16 ( 0x0013 ) ; // CHK_LIN_COLOR_F
File . WriteU32 ( 18 ) ;
File . WriteFloats ( Properties . mBackgroundGradientColor1 , 3 ) ;
File . WriteU16 ( 0x0010 ) ; // CHK_COLOR_F
File . WriteU32 ( 18 ) ;
File . WriteFloats ( ( Properties . mBackgroundGradientColor1 + Properties . mBackgroundGradientColor2 ) / 2.0f , 3 ) ;
File . WriteU16 ( 0x0013 ) ; // CHK_LIN_COLOR_F
File . WriteU32 ( 18 ) ;
File . WriteFloats ( ( Properties . mBackgroundGradientColor1 + Properties . mBackgroundGradientColor2 ) / 2.0f , 3 ) ;
File . WriteU16 ( 0x0010 ) ; // CHK_COLOR_F
File . WriteU32 ( 18 ) ;
File . WriteFloats ( Properties . mBackgroundGradientColor2 , 3 ) ;
File . WriteU16 ( 0x0013 ) ; // CHK_LIN_COLOR_F
File . WriteU32 ( 18 ) ;
File . WriteFloats ( Properties . mBackgroundGradientColor2 , 3 ) ;
if ( Properties . mBackgroundType = = LC_BACKGROUND_GRADIENT )
{
File . WriteU16 ( 0x1301 ) ; // LIB3DS_USE_V_GRADIENT
File . WriteU32 ( 6 ) ;
}
else if ( Properties . mBackgroundType = = LC_BACKGROUND_IMAGE )
{
File . WriteU16 ( 0x1101 ) ; // LIB3DS_USE_BIT_MAP
File . WriteU32 ( 6 ) ;
}
else
{
File . WriteU16 ( 0x1201 ) ; // LIB3DS_USE_SOLID_BGND
File . WriteU32 ( 6 ) ;
}
File . WriteU16 ( 0x2200 ) ; // CHK_FOG
File . WriteU32 ( 46 ) ;
File . WriteFloat ( 0.0f ) ;
File . WriteFloat ( 0.0f ) ;
File . WriteFloat ( 1000.0f ) ;
File . WriteFloat ( 100.0f ) ;
File . WriteU16 ( 0x0010 ) ; // CHK_COLOR_F
File . WriteU32 ( 18 ) ;
File . WriteFloats ( Properties . mFogColor , 3 ) ;
File . WriteU16 ( 0x2210 ) ; // CHK_FOG_BGND
File . WriteU32 ( 6 ) ;
File . WriteU16 ( 0x2302 ) ; // CHK_LAYER_FOG
File . WriteU32 ( 40 ) ;
File . WriteFloat ( 0.0f ) ;
File . WriteFloat ( 100.0f ) ;
File . WriteFloat ( 50.0f ) ;
File . WriteU32 ( 0x00100000 ) ;
File . WriteU16 ( 0x0010 ) ; // CHK_COLOR_F
File . WriteU32 ( 18 ) ;
File . WriteFloats ( Properties . mFogColor , 3 ) ;
File . WriteU16 ( 0x2300 ) ; // CHK_DISTANCE_CUE
File . WriteU32 ( 28 ) ;
File . WriteFloat ( 0.0f ) ;
File . WriteFloat ( 0.0f ) ;
File . WriteFloat ( 1000.0f ) ;
File . WriteFloat ( 100.0f ) ;
File . WriteU16 ( 0x2310 ) ; // CHK_DICHK_DCUE_BGNDSTANCE_CUE
File . WriteU32 ( 6 ) ;
int NumPieces = 0 ;
for ( int PartIdx = 0 ; PartIdx < ModelParts . GetSize ( ) ; PartIdx + + )
{
PieceInfo * Info = ModelParts [ PartIdx ] . Info ;
2014-12-31 17:38:30 +01:00
lcMesh * Mesh = Info - > GetMesh ( ) ;
2014-12-30 17:30:12 +01:00
2014-12-31 17:38:30 +01:00
if ( ! Mesh | | Mesh - > mIndexType = = GL_UNSIGNED_INT )
2014-12-30 17:30:12 +01:00
continue ;
long NamedObjectStart = File . GetPosition ( ) ;
File . WriteU16 ( 0x4000 ) ; // CHK_NAMED_OBJECT
File . WriteU32 ( 0 ) ;
char Name [ 32 ] ;
sprintf ( Name , " Piece%.3d " , NumPieces ) ;
NumPieces + + ;
File . WriteBuffer ( Name , strlen ( Name ) + 1 ) ;
long TriObjectStart = File . GetPosition ( ) ;
File . WriteU16 ( 0x4100 ) ; // CHK_N_TRI_OBJECT
File . WriteU32 ( 0 ) ;
File . WriteU16 ( 0x4110 ) ; // CHK_POINT_ARRAY
File . WriteU32 ( 8 + 12 * Mesh - > mNumVertices ) ;
File . WriteU16 ( Mesh - > mNumVertices ) ;
2015-04-26 20:14:33 +02:00
float * Verts = ( float * ) Mesh - > mVertexData ;
2014-12-30 17:30:12 +01:00
const lcMatrix44 & ModelWorld = ModelParts [ PartIdx ] . WorldMatrix ;
for ( int VertexIdx = 0 ; VertexIdx < Mesh - > mNumVertices ; VertexIdx + + )
{
lcVector3 Pos ( Verts [ VertexIdx * 3 ] , Verts [ VertexIdx * 3 + 1 ] , Verts [ VertexIdx * 3 + 2 ] ) ;
Pos = lcMul31 ( Pos , ModelWorld ) ;
File . WriteFloat ( Pos [ 0 ] ) ;
File . WriteFloat ( Pos [ 1 ] ) ;
File . WriteFloat ( Pos [ 2 ] ) ;
}
File . WriteU16 ( 0x4160 ) ; // CHK_MESH_MATRIX
File . WriteU32 ( 54 ) ;
lcMatrix44 Matrix = lcMatrix44Identity ( ) ;
File . WriteFloats ( Matrix [ 0 ] , 3 ) ;
File . WriteFloats ( Matrix [ 1 ] , 3 ) ;
File . WriteFloats ( Matrix [ 2 ] , 3 ) ;
File . WriteFloats ( Matrix [ 3 ] , 3 ) ;
File . WriteU16 ( 0x4165 ) ; // CHK_MESH_COLOR
File . WriteU32 ( 7 ) ;
File . WriteU8 ( 0 ) ;
long FaceArrayStart = File . GetPosition ( ) ;
File . WriteU16 ( 0x4120 ) ; // CHK_FACE_ARRAY
File . WriteU32 ( 0 ) ;
int NumTriangles = 0 ;
2015-05-24 06:36:25 +02:00
for ( int SectionIdx = 0 ; SectionIdx < Mesh - > mLods [ LC_MESH_LOD_HIGH ] . NumSections ; SectionIdx + + )
2014-12-30 17:30:12 +01:00
{
2015-05-24 06:36:25 +02:00
lcMeshSection * Section = & Mesh - > mLods [ LC_MESH_LOD_HIGH ] . Sections [ SectionIdx ] ;
2014-12-30 17:30:12 +01:00
if ( Section - > PrimitiveType ! = GL_TRIANGLES )
continue ;
NumTriangles + = Section - > NumIndices / 3 ;
}
File . WriteU16 ( NumTriangles ) ;
2015-05-24 06:36:25 +02:00
for ( int SectionIdx = 0 ; SectionIdx < Mesh - > mLods [ LC_MESH_LOD_HIGH ] . NumSections ; SectionIdx + + )
2014-12-30 17:30:12 +01:00
{
2015-05-24 06:36:25 +02:00
lcMeshSection * Section = & Mesh - > mLods [ LC_MESH_LOD_HIGH ] . Sections [ SectionIdx ] ;
2014-12-30 17:30:12 +01:00
if ( Section - > PrimitiveType ! = GL_TRIANGLES )
continue ;
2015-04-26 20:14:33 +02:00
lcuint16 * Indices = ( lcuint16 * ) Mesh - > mIndexData + Section - > IndexOffset / sizeof ( lcuint16 ) ;
2014-12-30 17:30:12 +01:00
for ( int IndexIdx = 0 ; IndexIdx < Section - > NumIndices ; IndexIdx + = 3 )
{
File . WriteU16 ( Indices [ IndexIdx + 0 ] ) ;
File . WriteU16 ( Indices [ IndexIdx + 1 ] ) ;
File . WriteU16 ( Indices [ IndexIdx + 2 ] ) ;
File . WriteU16 ( 7 ) ;
}
}
NumTriangles = 0 ;
2015-05-24 06:36:25 +02:00
for ( int SectionIdx = 0 ; SectionIdx < Mesh - > mLods [ LC_MESH_LOD_HIGH ] . NumSections ; SectionIdx + + )
2014-12-30 17:30:12 +01:00
{
2015-05-24 06:36:25 +02:00
lcMeshSection * Section = & Mesh - > mLods [ LC_MESH_LOD_HIGH ] . Sections [ SectionIdx ] ;
2014-12-30 17:30:12 +01:00
if ( Section - > PrimitiveType ! = GL_TRIANGLES )
continue ;
int MaterialIndex = Section - > ColorIndex = = gDefaultColor ? ModelParts [ PartIdx ] . ColorIndex : Section - > ColorIndex ;
File . WriteU16 ( 0x4130 ) ; // CHK_MSH_MAT_GROUP
File . WriteU32 ( 6 + MaterialNameLength + 1 + 2 + 2 * Section - > NumIndices / 3 ) ;
sprintf ( MaterialName , " Material%03d " , MaterialIndex ) ;
File . WriteBuffer ( MaterialName , MaterialNameLength + 1 ) ;
File . WriteU16 ( Section - > NumIndices / 3 ) ;
for ( int IndexIdx = 0 ; IndexIdx < Section - > NumIndices ; IndexIdx + = 3 )
File . WriteU16 ( NumTriangles + + ) ;
}
long FaceArrayEnd = File . GetPosition ( ) ;
File . Seek ( FaceArrayStart + 2 , SEEK_SET ) ;
File . WriteU32 ( FaceArrayEnd - FaceArrayStart ) ;
File . Seek ( FaceArrayEnd , SEEK_SET ) ;
long TriObjectEnd = File . GetPosition ( ) ;
File . Seek ( TriObjectStart + 2 , SEEK_SET ) ;
File . WriteU32 ( TriObjectEnd - TriObjectStart ) ;
File . Seek ( TriObjectEnd , SEEK_SET ) ;
long NamedObjectEnd = File . GetPosition ( ) ;
File . Seek ( NamedObjectStart + 2 , SEEK_SET ) ;
File . WriteU32 ( NamedObjectEnd - NamedObjectStart ) ;
File . Seek ( NamedObjectEnd , SEEK_SET ) ;
}
long MDataEnd = File . GetPosition ( ) ;
File . Seek ( MDataStart + 2 , SEEK_SET ) ;
File . WriteU32 ( MDataEnd - MDataStart ) ;
File . Seek ( MDataEnd , SEEK_SET ) ;
long KFDataStart = File . GetPosition ( ) ;
File . WriteU16 ( 0xB000 ) ; // CHK_KFDATA
File . WriteU32 ( 0 ) ;
File . WriteU16 ( 0xB00A ) ; // LIB3DS_KFHDR
File . WriteU32 ( 6 + 2 + 1 + 4 ) ;
File . WriteS16 ( 5 ) ;
File . WriteU8 ( 0 ) ;
File . WriteS32 ( 100 ) ;
long KFDataEnd = File . GetPosition ( ) ;
File . Seek ( KFDataStart + 2 , SEEK_SET ) ;
File . WriteU32 ( KFDataEnd - KFDataStart ) ;
File . Seek ( KFDataEnd , SEEK_SET ) ;
long M3DEnd = File . GetPosition ( ) ;
File . Seek ( M3DStart + 2 , SEEK_SET ) ;
File . WriteU32 ( M3DEnd - M3DStart ) ;
File . Seek ( M3DEnd , SEEK_SET ) ;
}
void Project : : ExportBrickLink ( )
{
lcArray < lcPartsListEntry > PartsList ;
if ( ! mModels . IsEmpty ( ) )
mModels [ 0 ] - > GetPartsList ( gDefaultColor , PartsList ) ;
if ( PartsList . IsEmpty ( ) )
{
2015-01-30 17:30:13 +01:00
QMessageBox : : information ( gMainWindow , tr ( " LeoCAD " ) , tr ( " Nothing to export. " ) ) ;
2014-12-30 17:30:12 +01:00
return ;
}
2015-03-27 21:39:43 +01:00
QString SaveFileName = GetExportFileName ( QString ( ) , " xml " , tr ( " Export BrickLink " ) , tr ( " XML Files (*.xml);;All Files (*.*) " ) ) ;
2014-12-30 17:30:12 +01:00
2015-03-27 21:39:43 +01:00
if ( SaveFileName . isEmpty ( ) )
2014-12-30 17:30:12 +01:00
return ;
lcDiskFile BrickLinkFile ;
char Line [ 1024 ] ;
2015-03-27 21:39:43 +01:00
if ( ! BrickLinkFile . Open ( SaveFileName , " wt " ) )
2014-12-30 17:30:12 +01:00
{
2015-03-27 21:39:43 +01:00
QMessageBox : : warning ( gMainWindow , tr ( " LeoCAD " ) , tr ( " Could not open file '%1' for writing. " ) . arg ( SaveFileName ) ) ;
2014-12-30 17:30:12 +01:00
return ;
}
const char * OldLocale = setlocale ( LC_NUMERIC , " C " ) ;
BrickLinkFile . WriteLine ( " <INVENTORY> \n " ) ;
for ( int PieceIdx = 0 ; PieceIdx < PartsList . GetSize ( ) ; PieceIdx + + )
{
BrickLinkFile . WriteLine ( " <ITEM> \n " ) ;
BrickLinkFile . WriteLine ( " <ITEMTYPE>P</ITEMTYPE> \n " ) ;
sprintf ( Line , " <ITEMID>%s</ITEMID> \n " , PartsList [ PieceIdx ] . Info - > m_strName ) ;
BrickLinkFile . WriteLine ( Line ) ;
int Count = PartsList [ PieceIdx ] . Count ;
if ( Count > 1 )
{
sprintf ( Line , " <MINQTY>%d</MINQTY> \n " , Count ) ;
BrickLinkFile . WriteLine ( Line ) ;
}
int Color = lcGetBrickLinkColor ( PartsList [ PieceIdx ] . ColorIndex ) ;
if ( Color )
{
sprintf ( Line , " <COLOR>%d</COLOR> \n " , Color ) ;
BrickLinkFile . WriteLine ( Line ) ;
}
BrickLinkFile . WriteLine ( " </ITEM> \n " ) ;
}
BrickLinkFile . WriteLine ( " </INVENTORY> \n " ) ;
setlocale ( LC_NUMERIC , OldLocale ) ;
}
void Project : : ExportCSV ( )
{
lcArray < lcPartsListEntry > PartsList ;
if ( ! mModels . IsEmpty ( ) )
mModels [ 0 ] - > GetPartsList ( gDefaultColor , PartsList ) ;
if ( PartsList . IsEmpty ( ) )
{
2015-01-30 17:30:13 +01:00
QMessageBox : : information ( gMainWindow , tr ( " LeoCAD " ) , tr ( " Nothing to export. " ) ) ;
2014-12-30 17:30:12 +01:00
return ;
}
2015-03-27 21:39:43 +01:00
QString SaveFileName = GetExportFileName ( QString ( ) , " csv " , tr ( " Export CSV " ) , tr ( " CSV Files (*.csv);;All Files (*.*) " ) ) ;
2014-12-30 17:30:12 +01:00
2015-03-27 21:39:43 +01:00
if ( SaveFileName . isEmpty ( ) )
2014-12-30 17:30:12 +01:00
return ;
lcDiskFile CSVFile ;
char Line [ 1024 ] ;
2015-03-27 21:39:43 +01:00
if ( ! CSVFile . Open ( SaveFileName , " wt " ) )
2014-12-30 17:30:12 +01:00
{
2015-03-27 21:39:43 +01:00
QMessageBox : : warning ( gMainWindow , tr ( " LeoCAD " ) , tr ( " Could not open file '%1' for writing. " ) . arg ( SaveFileName ) ) ;
2014-12-30 17:30:12 +01:00
return ;
}
const char * OldLocale = setlocale ( LC_NUMERIC , " C " ) ;
CSVFile . WriteLine ( " Part Name,Color,Quantity,Part ID,Color Code \n " ) ;
for ( int PieceIdx = 0 ; PieceIdx < PartsList . GetSize ( ) ; PieceIdx + + )
{
sprintf ( Line , " \" %s \" , \" %s \" ,%d,%s,%d \n " , PartsList [ PieceIdx ] . Info - > m_strDescription , gColorList [ PartsList [ PieceIdx ] . ColorIndex ] . Name ,
PartsList [ PieceIdx ] . Count , PartsList [ PieceIdx ] . Info - > m_strName , gColorList [ PartsList [ PieceIdx ] . ColorIndex ] . Code ) ;
CSVFile . WriteLine ( Line ) ;
}
setlocale ( LC_NUMERIC , OldLocale ) ;
}
2015-01-12 05:49:30 +01:00
void Project : : CreateHTMLPieceList ( QTextStream & Stream , lcModel * Model , lcStep Step , bool Images , const QString & ImageExtension )
2014-12-30 17:30:12 +01:00
{
2015-01-12 05:49:30 +01:00
int * ColorsUsed = new int [ gColorList . GetSize ( ) ] ;
memset ( ColorsUsed , 0 , sizeof ( ColorsUsed [ 0 ] ) * gColorList . GetSize ( ) ) ;
int * PiecesUsed = new int [ gColorList . GetSize ( ) ] ;
int NumColors = 0 ;
2014-12-30 17:30:12 +01:00
2015-01-12 05:49:30 +01:00
lcArray < lcPartsListEntry > PartsList ;
2014-12-30 17:30:12 +01:00
2015-01-12 05:49:30 +01:00
if ( Step = = 0 )
Model - > GetPartsList ( gDefaultColor , PartsList ) ;
else
Model - > GetPartsListForStep ( Step , gDefaultColor , PartsList ) ;
2014-12-30 17:30:12 +01:00
2015-01-12 05:49:30 +01:00
for ( int PieceIdx = 0 ; PieceIdx < PartsList . GetSize ( ) ; PieceIdx + + )
ColorsUsed [ PartsList [ PieceIdx ] . ColorIndex ] + + ;
2014-12-30 17:30:12 +01:00
2015-01-12 05:49:30 +01:00
Stream < < QLatin1String ( " <br><table border=1><tr><td><center>Piece</center></td> \r \n " ) ;
2014-12-30 17:30:12 +01:00
2015-01-12 05:49:30 +01:00
for ( int ColorIdx = 0 ; ColorIdx < gColorList . GetSize ( ) ; ColorIdx + + )
2014-12-30 17:30:12 +01:00
{
2015-01-12 05:49:30 +01:00
if ( ColorsUsed [ ColorIdx ] )
{
ColorsUsed [ ColorIdx ] = NumColors ;
NumColors + + ;
Stream < < QString ( " <td><center>%1</center></td> \n " ) . arg ( gColorList [ ColorIdx ] . Name ) ;
}
2014-12-30 17:30:12 +01:00
}
2015-01-12 05:49:30 +01:00
NumColors + + ;
Stream < < QLatin1String ( " </tr> \n " ) ;
2014-12-30 17:30:12 +01:00
2015-01-12 05:49:30 +01:00
for ( int j = 0 ; j < lcGetPiecesLibrary ( ) - > mPieces . GetSize ( ) ; j + + )
{
bool Add = false ;
memset ( PiecesUsed , 0 , sizeof ( PiecesUsed [ 0 ] ) * gColorList . GetSize ( ) ) ;
PieceInfo * pInfo = lcGetPiecesLibrary ( ) - > mPieces [ j ] ;
2014-12-30 17:30:12 +01:00
2015-01-12 05:49:30 +01:00
for ( int PieceIdx = 0 ; PieceIdx < PartsList . GetSize ( ) ; PieceIdx + + )
{
if ( PartsList [ PieceIdx ] . Info = = pInfo )
{
PiecesUsed [ PartsList [ PieceIdx ] . ColorIndex ] + = PartsList [ PieceIdx ] . Count ;
Add = true ;
}
}
2014-12-30 17:30:12 +01:00
2015-01-12 05:49:30 +01:00
if ( Add )
{
if ( Images )
Stream < < QString ( " <tr><td><IMG SRC= \" %1%2 \" ALT= \" %3 \" ></td> \n " ) . arg ( pInfo - > m_strName , ImageExtension , pInfo - > m_strDescription ) ;
else
Stream < < QString ( " <tr><td>%1</td> \r \n " ) . arg ( pInfo - > m_strDescription ) ;
2014-12-30 17:30:12 +01:00
2015-01-12 05:49:30 +01:00
int curcol = 1 ;
for ( int ColorIdx = 0 ; ColorIdx < gColorList . GetSize ( ) ; ColorIdx + + )
{
if ( PiecesUsed [ ColorIdx ] )
{
while ( curcol ! = ColorsUsed [ ColorIdx ] + 1 )
{
Stream < < QLatin1String ( " <td><center>-</center></td> \r \n " ) ;
curcol + + ;
}
2014-12-30 17:30:12 +01:00
2015-01-12 05:49:30 +01:00
Stream < < QString ( " <td><center>%1</center></td> \r \n " ) . arg ( QString : : number ( PiecesUsed [ ColorIdx ] ) ) ;
curcol + + ;
}
}
2014-12-30 17:30:12 +01:00
2015-01-12 05:49:30 +01:00
while ( curcol ! = NumColors )
{
Stream < < QLatin1String ( " <td><center>-</center></td> \r \n " ) ;
curcol + + ;
}
2014-12-30 17:30:12 +01:00
2015-01-12 05:49:30 +01:00
Stream < < QLatin1String ( " </tr> \r \n " ) ;
}
}
Stream < < QLatin1String ( " </table> \r \n <br> " ) ;
2014-12-30 17:30:12 +01:00
2015-01-12 05:49:30 +01:00
delete [ ] PiecesUsed ;
delete [ ] ColorsUsed ;
}
2014-12-30 17:30:12 +01:00
2015-01-12 05:49:30 +01:00
void Project : : ExportHTML ( )
{
lcHTMLDialogOptions Options ;
2014-12-30 17:30:12 +01:00
2015-01-12 05:49:30 +01:00
if ( ! mFileName . isEmpty ( ) )
Options . PathName = QFileInfo ( mFileName ) . canonicalPath ( ) ;
2014-12-30 17:30:12 +01:00
2015-01-12 05:49:30 +01:00
int ImageOptions = lcGetProfileInt ( LC_PROFILE_HTML_IMAGE_OPTIONS ) ;
int HTMLOptions = lcGetProfileInt ( LC_PROFILE_HTML_OPTIONS ) ;
2014-12-30 17:30:12 +01:00
2015-01-12 05:49:30 +01:00
Options . ImageFormat = ( LC_IMAGE_FORMAT ) ( ImageOptions & ~ ( LC_IMAGE_MASK ) ) ;
Options . TransparentImages = ( ImageOptions & LC_IMAGE_TRANSPARENT ) ! = 0 ;
Options . SinglePage = ( HTMLOptions & LC_HTML_SINGLEPAGE ) ! = 0 ;
Options . IndexPage = ( HTMLOptions & LC_HTML_INDEX ) ! = 0 ;
Options . StepImagesWidth = lcGetProfileInt ( LC_PROFILE_HTML_IMAGE_WIDTH ) ;
Options . StepImagesHeight = lcGetProfileInt ( LC_PROFILE_HTML_IMAGE_HEIGHT ) ;
Options . HighlightNewParts = ( HTMLOptions & LC_HTML_HIGHLIGHT ) ! = 0 ;
Options . PartsListStep = ( HTMLOptions & LC_HTML_LISTSTEP ) ! = 0 ;
Options . PartsListEnd = ( HTMLOptions & LC_HTML_LISTEND ) ! = 0 ;
Options . PartsListImages = ( HTMLOptions & LC_HTML_IMAGES ) ! = 0 ;
Options . PartImagesColor = lcGetColorIndex ( lcGetProfileInt ( LC_PROFILE_HTML_PARTS_COLOR ) ) ;
Options . PartImagesWidth = lcGetProfileInt ( LC_PROFILE_HTML_PARTS_WIDTH ) ;
Options . PartImagesHeight = lcGetProfileInt ( LC_PROFILE_HTML_PARTS_HEIGHT ) ;
2014-12-30 17:30:12 +01:00
2015-01-12 05:49:30 +01:00
if ( ! gMainWindow - > DoDialog ( LC_DIALOG_EXPORT_HTML , & Options ) )
return ;
2014-12-30 17:30:12 +01:00
2015-01-12 05:49:30 +01:00
HTMLOptions = 0 ;
2014-12-30 17:30:12 +01:00
2015-01-12 05:49:30 +01:00
if ( Options . SinglePage )
HTMLOptions | = LC_HTML_SINGLEPAGE ;
if ( Options . IndexPage )
HTMLOptions | = LC_HTML_INDEX ;
if ( Options . HighlightNewParts )
HTMLOptions | = LC_HTML_HIGHLIGHT ;
if ( Options . PartsListStep )
HTMLOptions | = LC_HTML_LISTSTEP ;
if ( Options . PartsListEnd )
HTMLOptions | = LC_HTML_LISTEND ;
if ( Options . PartsListImages )
HTMLOptions | = LC_HTML_IMAGES ;
2014-12-30 17:30:12 +01:00
2015-01-12 05:49:30 +01:00
ImageOptions = Options . ImageFormat ;
2014-12-30 17:30:12 +01:00
2015-01-12 05:49:30 +01:00
if ( Options . TransparentImages )
ImageOptions | = LC_IMAGE_TRANSPARENT ;
2014-12-30 17:30:12 +01:00
2015-01-12 05:49:30 +01:00
lcSetProfileInt ( LC_PROFILE_HTML_IMAGE_OPTIONS , ImageOptions ) ;
lcSetProfileInt ( LC_PROFILE_HTML_OPTIONS , HTMLOptions ) ;
lcSetProfileInt ( LC_PROFILE_HTML_IMAGE_WIDTH , Options . StepImagesWidth ) ;
lcSetProfileInt ( LC_PROFILE_HTML_IMAGE_HEIGHT , Options . StepImagesHeight ) ;
lcSetProfileInt ( LC_PROFILE_HTML_PARTS_COLOR , lcGetColorCode ( Options . PartImagesColor ) ) ;
lcSetProfileInt ( LC_PROFILE_HTML_PARTS_WIDTH , Options . PartImagesWidth ) ;
lcSetProfileInt ( LC_PROFILE_HTML_PARTS_HEIGHT , Options . PartImagesHeight ) ;
2014-12-30 17:30:12 +01:00
2015-01-12 05:49:30 +01:00
QDir Dir ( Options . PathName ) ;
Dir . mkpath ( QLatin1String ( " . " ) ) ;
2014-12-30 17:30:12 +01:00
2015-01-12 05:49:30 +01:00
QString Title = GetTitle ( ) ;
QString BaseName = Title . left ( Title . length ( ) - QFileInfo ( Title ) . suffix ( ) . length ( ) - 1 ) ;
QString HTMLExtension = QLatin1String ( " .html " ) ;
QString ImageExtension ;
2014-12-30 17:30:12 +01:00
2015-01-12 05:49:30 +01:00
switch ( Options . ImageFormat )
{
case LC_IMAGE_BMP :
ImageExtension = QLatin1String ( " .bmp " ) ;
break ;
case LC_IMAGE_JPG :
ImageExtension = QLatin1String ( " .jpg " ) ;
break ;
default :
case LC_IMAGE_PNG :
ImageExtension = QLatin1String ( " .png " ) ;
break ;
}
lcModel * Model = mModels [ 0 ] ;
lcStep LastStep = Model - > GetLastStep ( ) ;
2014-12-30 17:30:12 +01:00
2015-01-12 05:49:30 +01:00
if ( Options . SinglePage )
{
QString FileName = QFileInfo ( Dir , BaseName + HTMLExtension ) . absoluteFilePath ( ) ;
QFile File ( FileName ) ;
if ( ! File . open ( QIODevice : : WriteOnly ) )
2014-12-30 17:30:12 +01:00
{
2015-01-26 00:04:39 +01:00
QMessageBox : : warning ( gMainWindow , tr ( " Error " ) , tr ( " Error writing to file '%1': \n %2 " ) . arg ( FileName , File . errorString ( ) ) ) ;
2014-12-30 17:30:12 +01:00
return ;
}
2015-01-12 05:49:30 +01:00
QTextStream Stream ( & File ) ;
2014-12-30 17:30:12 +01:00
2015-01-12 05:49:30 +01:00
Stream < < QString ( " <HTML> \r \n <HEAD> \r \n <TITLE>Instructions for %1</TITLE> \r \n </HEAD> \r \n <BR> \r \n <CENTER> \r \n " ) . arg ( Title ) ;
2014-12-30 17:30:12 +01:00
2015-01-12 05:49:30 +01:00
for ( lcStep Step = 1 ; Step < = LastStep ; Step + + )
{
QString StepString = QString ( " %1 " ) . arg ( Step , 2 , 10 , QLatin1Char ( ' 0 ' ) ) ;
Stream < < QString ( " <IMG SRC= \" %1-%2%3 \" ALT= \" Step %4 \" WIDTH=%5 HEIGHT=%6><BR><BR> \r \n " ) . arg ( BaseName , StepString , ImageExtension , StepString , QString : : number ( Options . StepImagesWidth ) , QString : : number ( Options . StepImagesHeight ) ) ;
2014-12-30 17:30:12 +01:00
2015-01-12 05:49:30 +01:00
if ( Options . PartsListStep )
CreateHTMLPieceList ( Stream , Model , Step , Options . PartsListImages , ImageExtension ) ;
2014-12-30 17:30:12 +01:00
}
2015-01-12 05:49:30 +01:00
if ( Options . PartsListEnd )
CreateHTMLPieceList ( Stream , Model , 0 , Options . PartsListImages , ImageExtension ) ;
2014-12-30 17:30:12 +01:00
2015-01-12 05:49:30 +01:00
Stream < < QLatin1String ( " </CENTER> \n <BR><HR><BR><B><I>Created by <A HREF= \" http://www.leocad.org \" >LeoCAD</A></B></I><BR></HTML> \r \n " ) ;
}
else
2014-12-30 17:30:12 +01:00
{
2015-01-12 05:49:30 +01:00
if ( Options . IndexPage )
2014-12-30 17:30:12 +01:00
{
2015-01-12 05:49:30 +01:00
QString FileName = QFileInfo ( Dir , BaseName + QLatin1String ( " -index " ) + HTMLExtension ) . absoluteFilePath ( ) ;
QFile File ( FileName ) ;
2014-12-30 17:30:12 +01:00
2015-01-12 05:49:30 +01:00
if ( ! File . open ( QIODevice : : WriteOnly ) )
2014-12-30 17:30:12 +01:00
{
2015-01-26 00:04:39 +01:00
QMessageBox : : warning ( gMainWindow , tr ( " Error " ) , tr ( " Error writing to file '%1': \n %2 " ) . arg ( FileName , File . errorString ( ) ) ) ;
2015-01-12 05:49:30 +01:00
return ;
}
2014-12-30 17:30:12 +01:00
2015-01-12 05:49:30 +01:00
QTextStream Stream ( & File ) ;
2014-12-30 17:30:12 +01:00
2015-01-12 05:49:30 +01:00
Stream < < QString ( " <HTML> \r \n <HEAD> \r \n <TITLE>Instructions for %1</TITLE> \r \n </HEAD> \r \n <BR> \r \n <CENTER> \r \n " ) . arg ( Title ) ;
2014-12-30 17:30:12 +01:00
2015-01-12 05:49:30 +01:00
for ( lcStep Step = 1 ; Step < = LastStep ; Step + + )
Stream < < QString ( " <A HREF= \" %1-%2.html \" >Step %3<BR> \r \n </A> " ) . arg ( BaseName , QString ( " %1 " ) . arg ( Step , 2 , 10 , QLatin1Char ( ' 0 ' ) ) , QString : : number ( Step ) ) ;
2014-12-30 17:30:12 +01:00
2015-01-12 05:49:30 +01:00
if ( Options . PartsListEnd )
Stream < < QString ( " <A HREF= \" %1-pieces.html \" >Pieces Used</A><BR> \r \n " ) . arg ( BaseName ) ;
2014-12-30 17:30:12 +01:00
2015-01-12 05:49:30 +01:00
Stream < < QLatin1String ( " </CENTER> \r \n <BR><HR><BR><B><I>Created by <A HREF= \" http://www.leocad.org \" >LeoCAD</A></B></I><BR></HTML> \r \n " ) ;
2014-12-30 17:30:12 +01:00
}
2015-01-12 05:49:30 +01:00
for ( lcStep Step = 1 ; Step < = LastStep ; Step + + )
{
QString StepString = QString ( " %1 " ) . arg ( Step , 2 , 10 , QLatin1Char ( ' 0 ' ) ) ;
QString FileName = QFileInfo ( Dir , BaseName + QLatin1String ( " - " ) + StepString + HTMLExtension ) . absoluteFilePath ( ) ;
QFile File ( FileName ) ;
2014-12-30 17:30:12 +01:00
2015-01-12 05:49:30 +01:00
if ( ! File . open ( QIODevice : : WriteOnly ) )
{
2015-01-26 00:04:39 +01:00
QMessageBox : : warning ( gMainWindow , tr ( " Error " ) , tr ( " Error writing to file '%1': \n %2 " ) . arg ( FileName , File . errorString ( ) ) ) ;
2015-01-12 05:49:30 +01:00
return ;
}
2014-12-30 17:30:12 +01:00
2015-01-12 05:49:30 +01:00
QTextStream Stream ( & File ) ;
2014-12-30 17:30:12 +01:00
2015-01-12 05:49:30 +01:00
Stream < < QString ( " <HTML> \r \n <HEAD> \r \n <TITLE>%1 - Step %2</TITLE> \r \n </HEAD> \r \n <BR> \r \n <CENTER> \r \n " ) . arg ( Title , QString : : number ( Step ) ) ;
Stream < < QString ( " <IMG SRC= \" %1-%2%3 \" ALT= \" Step %4 \" WIDTH=%5 HEIGHT=%6><BR><BR> \r \n " ) . arg ( BaseName , StepString , ImageExtension , StepString , QString : : number ( Options . StepImagesWidth ) , QString : : number ( Options . StepImagesHeight ) ) ;
2014-12-30 17:30:12 +01:00
2015-01-12 05:49:30 +01:00
if ( Options . PartsListStep )
CreateHTMLPieceList ( Stream , Model , Step , Options . PartsListImages , ImageExtension ) ;
2014-12-30 17:30:12 +01:00
2015-01-12 05:49:30 +01:00
Stream < < QLatin1String ( " </CENTER> \r \n <BR><HR><BR> " ) ;
if ( Step ! = 1 )
Stream < < QString ( " <A HREF= \" %1-%2.html \" >Previous</A> " ) . arg ( BaseName , QString ( " %1 " ) . arg ( Step - 1 , 2 , 10 , QLatin1Char ( ' 0 ' ) ) ) ;
2014-12-30 17:30:12 +01:00
2015-01-12 05:49:30 +01:00
if ( Options . IndexPage )
Stream < < QString ( " <A HREF= \" %1-index.html \" >Index</A> " ) . arg ( BaseName ) ;
2014-12-30 17:30:12 +01:00
2015-01-12 05:49:30 +01:00
if ( Step ! = LastStep )
Stream < < QString ( " <A HREF= \" %1-%2.html \" >Next</A> " ) . arg ( BaseName , QString ( " %1 " ) . arg ( Step + 1 , 2 , 10 , QLatin1Char ( ' 0 ' ) ) ) ;
else if ( Options . PartsListEnd )
Stream < < QString ( " <A HREF= \" %1-pieces.html \" >Pieces Used</A> " ) . arg ( BaseName ) ;
2014-12-30 17:30:12 +01:00
2015-01-12 05:49:30 +01:00
Stream < < QLatin1String ( " <BR></HTML> \r \n " ) ;
}
2014-12-30 17:30:12 +01:00
2015-01-12 05:49:30 +01:00
if ( Options . PartsListEnd )
{
QString FileName = QFileInfo ( Dir , BaseName + QLatin1String ( " -pieces " ) + HTMLExtension ) . absoluteFilePath ( ) ;
QFile File ( FileName ) ;
2014-12-30 17:30:12 +01:00
2015-01-12 05:49:30 +01:00
if ( ! File . open ( QIODevice : : WriteOnly ) )
{
2015-01-26 00:04:39 +01:00
QMessageBox : : warning ( gMainWindow , tr ( " Error " ) , tr ( " Error writing to file '%1': \n %2 " ) . arg ( FileName , File . errorString ( ) ) ) ;
2015-01-12 05:49:30 +01:00
return ;
}
2014-12-30 17:30:12 +01:00
2015-01-12 05:49:30 +01:00
QTextStream Stream ( & File ) ;
2014-12-30 17:30:12 +01:00
2015-01-12 05:49:30 +01:00
Stream < < QString ( " <HTML> \r \n <HEAD> \r \n <TITLE>Pieces used by %1</TITLE> \r \n </HEAD> \r \n <BR> \r \n <CENTER> \n " ) . arg ( Title ) ;
2014-12-30 17:30:12 +01:00
2015-01-12 05:49:30 +01:00
CreateHTMLPieceList ( Stream , Model , 0 , Options . PartsListImages , ImageExtension ) ;
2014-12-30 17:30:12 +01:00
2015-01-12 05:49:30 +01:00
Stream < < QLatin1String ( " </CENTER> \n <BR><HR><BR> " ) ;
Stream < < QString ( " <A HREF= \" %1-%2.html \" >Previous</A> " ) . arg ( BaseName , QString ( " %1 " ) . arg ( LastStep , 2 , 10 , QLatin1Char ( ' 0 ' ) ) ) ;
2014-12-30 17:30:12 +01:00
2015-01-12 05:49:30 +01:00
if ( Options . IndexPage )
Stream < < QString ( " <A HREF= \" %1-index.html \" >Index</A> " ) . arg ( BaseName ) ;
2014-12-30 17:30:12 +01:00
2015-01-12 05:49:30 +01:00
Stream < < QLatin1String ( " <BR></HTML> \r \n " ) ;
2014-12-30 17:30:12 +01:00
}
}
2015-01-12 05:49:30 +01:00
QString StepImageBaseName = QFileInfo ( Dir , BaseName + QLatin1String ( " -%1 " ) + ImageExtension ) . absoluteFilePath ( ) ;
Model - > SaveStepImages ( StepImageBaseName , Options . StepImagesWidth , Options . StepImagesHeight , 1 , LastStep ) ;
2014-12-30 17:30:12 +01:00
2015-01-12 05:49:30 +01:00
if ( Options . PartsListImages )
2014-12-30 17:30:12 +01:00
{
2015-01-12 05:49:30 +01:00
gMainWindow - > mPreviewWidget - > MakeCurrent ( ) ;
lcContext * Context = gMainWindow - > mPreviewWidget - > mContext ;
int Width = Options . PartImagesWidth ;
int Height = Options . PartImagesHeight ;
2014-12-30 17:30:12 +01:00
2015-01-12 05:49:30 +01:00
if ( ! Context - > BeginRenderToTexture ( Width , Height ) )
2014-12-30 17:30:12 +01:00
{
2015-01-30 17:30:13 +01:00
QMessageBox : : warning ( gMainWindow , tr ( " LeoCAD " ) , tr ( " Error creating images. " ) ) ;
2015-01-12 05:49:30 +01:00
return ;
2014-12-30 17:30:12 +01:00
}
2015-01-12 05:49:30 +01:00
float aspect = ( float ) Width / ( float ) Height ;
Context - > SetViewport ( 0 , 0 , Width , Height ) ;
lcArray < lcPartsListEntry > PartsList ;
Model - > GetPartsList ( gDefaultColor , PartsList ) ;
lcMatrix44 ProjectionMatrix = lcMatrix44Perspective ( 30.0f , aspect , 1.0f , 2500.0f ) ;
lcMatrix44 ViewMatrix ;
Context - > SetDefaultState ( ) ;
Context - > SetProjectionMatrix ( ProjectionMatrix ) ;
2015-05-17 01:04:35 +02:00
Context - > SetProgram ( LC_PROGRAM_SIMPLE ) ;
2015-01-12 05:49:30 +01:00
for ( int PieceIdx = 0 ; PieceIdx < PartsList . GetSize ( ) ; PieceIdx + + )
2014-12-30 17:30:12 +01:00
{
2015-01-12 05:49:30 +01:00
PieceInfo * Info = PartsList [ PieceIdx ] . Info ;
2014-12-30 17:30:12 +01:00
2015-01-12 05:49:30 +01:00
glClearColor ( 1.0f , 1.0f , 1.0f , 0.0f ) ;
glClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ) ;
2014-12-30 17:30:12 +01:00
2015-01-12 05:49:30 +01:00
lcVector3 CameraPosition ( - 100.0f , - 100.0f , 75.0f ) ;
Info - > ZoomExtents ( ProjectionMatrix , ViewMatrix , CameraPosition ) ;
lcScene Scene ;
2015-02-08 19:54:51 +01:00
Scene . Begin ( ViewMatrix ) ;
2015-01-12 05:49:30 +01:00
Info - > AddRenderMeshes ( Scene , lcMatrix44Identity ( ) , Options . PartImagesColor , false , false ) ;
2015-02-08 19:54:51 +01:00
Scene . End ( ) ;
2015-01-12 05:49:30 +01:00
2015-05-17 01:04:35 +02:00
Context - > SetViewMatrix ( ViewMatrix ) ;
Context - > DrawOpaqueMeshes ( Scene . mOpaqueMeshes ) ;
Context - > DrawTranslucentMeshes ( Scene . mTranslucentMeshes ) ;
2015-01-12 05:49:30 +01:00
Context - > UnbindMesh ( ) ; // context remove
QString FileName = QFileInfo ( Dir , Info - > m_strName + ImageExtension ) . absoluteFilePath ( ) ;
if ( ! Context - > SaveRenderToTextureImage ( FileName , Width , Height ) )
break ;
}
Context - > EndRenderToTexture ( ) ;
2014-12-30 17:30:12 +01:00
}
}
2015-01-12 05:49:30 +01:00
void Project : : ExportPOVRay ( )
2014-12-30 17:30:12 +01:00
{
lcArray < lcModelPartsEntry > ModelParts ;
GetModelParts ( ModelParts ) ;
if ( ModelParts . IsEmpty ( ) )
{
2015-01-30 17:30:13 +01:00
QMessageBox : : information ( gMainWindow , tr ( " LeoCAD " ) , tr ( " Nothing to export. " ) ) ;
2014-12-30 17:30:12 +01:00
return ;
}
2015-01-12 05:49:30 +01:00
lcPOVRayDialogOptions Options ;
2014-12-30 17:30:12 +01:00
2015-01-31 22:44:57 +01:00
Options . POVRayPath = lcGetProfileString ( LC_PROFILE_POVRAY_PATH ) ;
Options . LGEOPath = lcGetProfileString ( LC_PROFILE_POVRAY_LGEO_PATH ) ;
2015-01-12 05:49:30 +01:00
Options . Render = lcGetProfileInt ( LC_PROFILE_POVRAY_RENDER ) ;
if ( ! gMainWindow - > DoDialog ( LC_DIALOG_EXPORT_POVRAY , & Options ) )
2014-12-30 17:30:12 +01:00
return ;
2015-01-12 05:49:30 +01:00
lcSetProfileString ( LC_PROFILE_POVRAY_PATH , Options . POVRayPath ) ;
lcSetProfileString ( LC_PROFILE_POVRAY_LGEO_PATH , Options . LGEOPath ) ;
lcSetProfileInt ( LC_PROFILE_POVRAY_RENDER , Options . Render ) ;
2014-12-30 17:30:12 +01:00
2015-01-12 05:49:30 +01:00
lcDiskFile POVFile ;
2015-02-02 07:00:42 +01:00
if ( ! POVFile . Open ( Options . FileName , " wt " ) )
2014-12-30 17:30:12 +01:00
{
2015-01-30 17:30:13 +01:00
QMessageBox : : warning ( gMainWindow , tr ( " LeoCAD " ) , tr ( " Could not open file '%1' for writing. " ) . arg ( Options . FileName ) ) ;
2014-12-30 17:30:12 +01:00
return ;
}
2015-01-12 05:49:30 +01:00
char Line [ 1024 ] ;
2014-12-30 17:30:12 +01:00
2015-01-12 05:49:30 +01:00
lcPiecesLibrary * Library = lcGetPiecesLibrary ( ) ;
char * PieceTable = new char [ Library - > mPieces . GetSize ( ) * LC_PIECE_NAME_LEN ] ;
int * PieceFlags = new int [ Library - > mPieces . GetSize ( ) ] ;
int NumColors = gColorList . GetSize ( ) ;
char * ColorTable = new char [ NumColors * LC_MAX_COLOR_NAME ] ;
2014-12-30 17:30:12 +01:00
2015-01-12 05:49:30 +01:00
memset ( PieceTable , 0 , Library - > mPieces . GetSize ( ) * LC_PIECE_NAME_LEN ) ;
memset ( PieceFlags , 0 , Library - > mPieces . GetSize ( ) * sizeof ( int ) ) ;
memset ( ColorTable , 0 , NumColors * LC_MAX_COLOR_NAME ) ;
2014-12-30 17:30:12 +01:00
2015-01-12 05:49:30 +01:00
enum
{
LGEO_PIECE_LGEO = 0x01 ,
LGEO_PIECE_AR = 0x02 ,
LGEO_PIECE_SLOPE = 0x04
} ;
2014-12-30 17:30:12 +01:00
2015-01-12 05:49:30 +01:00
enum
2014-12-30 17:30:12 +01:00
{
2015-01-12 05:49:30 +01:00
LGEO_COLOR_SOLID = 0x01 ,
LGEO_COLOR_TRANSPARENT = 0x02 ,
LGEO_COLOR_CHROME = 0x04 ,
LGEO_COLOR_PEARL = 0x08 ,
LGEO_COLOR_METALLIC = 0x10 ,
LGEO_COLOR_RUBBER = 0x20 ,
LGEO_COLOR_GLITTER = 0x40
} ;
2014-12-30 17:30:12 +01:00
2015-01-31 22:44:57 +01:00
if ( ! Options . LGEOPath . isEmpty ( ) )
2014-12-30 17:30:12 +01:00
{
2015-01-12 05:49:30 +01:00
lcDiskFile TableFile , ColorFile ;
2014-12-31 17:38:30 +01:00
2015-02-02 07:00:42 +01:00
if ( ! TableFile . Open ( QFileInfo ( QDir ( Options . LGEOPath ) , QLatin1String ( " lg_elements.lst " ) ) . absoluteFilePath ( ) , " rt " ) )
2014-12-30 17:30:12 +01:00
{
2015-01-12 05:49:30 +01:00
delete [ ] PieceTable ;
delete [ ] PieceFlags ;
2015-01-31 22:44:57 +01:00
QMessageBox : : information ( gMainWindow , tr ( " LeoCAD " ) , tr ( " Could not find LGEO files in folder '%1'. " ) . arg ( Options . LGEOPath ) ) ;
2015-01-12 05:49:30 +01:00
return ;
2014-12-30 17:30:12 +01:00
}
2015-01-12 05:49:30 +01:00
while ( TableFile . ReadLine ( Line , sizeof ( Line ) ) )
2014-12-31 17:38:30 +01:00
{
2015-01-12 05:49:30 +01:00
char Src [ 1024 ] , Dst [ 1024 ] , Flags [ 1024 ] ;
2013-12-08 00:15:28 +01:00
2015-01-12 05:49:30 +01:00
if ( * Line = = ' ; ' )
continue ;
2013-08-16 18:16:45 +02:00
2015-01-12 05:49:30 +01:00
if ( sscanf ( Line , " %s%s%s " , Src , Dst , Flags ) ! = 3 )
continue ;
2011-09-07 23:06:51 +02:00
2015-01-12 05:49:30 +01:00
strupr ( Src ) ;
2011-09-07 23:06:51 +02:00
2015-02-22 03:39:15 +01:00
PieceInfo * Info = Library - > FindPiece ( Src , NULL , false ) ;
2015-01-12 05:49:30 +01:00
if ( ! Info )
continue ;
2011-09-07 23:06:51 +02:00
2015-01-12 05:49:30 +01:00
int Index = Library - > mPieces . FindIndex ( Info ) ;
2014-10-12 01:26:23 +02:00
2015-01-12 05:49:30 +01:00
if ( strchr ( Flags , ' L ' ) )
{
PieceFlags [ Index ] | = LGEO_PIECE_LGEO ;
sprintf ( PieceTable + Index * LC_PIECE_NAME_LEN , " lg_%s " , Dst ) ;
}
2014-10-12 01:26:23 +02:00
2015-01-12 05:49:30 +01:00
if ( strchr ( Flags , ' A ' ) )
{
PieceFlags [ Index ] | = LGEO_PIECE_AR ;
sprintf ( PieceTable + Index * LC_PIECE_NAME_LEN , " ar_%s " , Dst ) ;
}
2014-10-12 01:26:23 +02:00
2015-01-12 05:49:30 +01:00
if ( strchr ( Flags , ' S ' ) )
PieceFlags [ Index ] | = LGEO_PIECE_SLOPE ;
}
2014-10-12 01:26:23 +02:00
2015-02-02 07:00:42 +01:00
if ( ! ColorFile . Open ( QFileInfo ( QDir ( Options . LGEOPath ) , QLatin1String ( " lg_colors.lst " ) ) . absoluteFilePath ( ) , " rt " ) )
2015-01-12 05:49:30 +01:00
{
delete [ ] PieceTable ;
delete [ ] PieceFlags ;
2015-01-31 22:44:57 +01:00
QMessageBox : : information ( gMainWindow , tr ( " LeoCAD " ) , tr ( " Could not find LGEO files in folder '%1'. " ) . arg ( Options . LGEOPath ) ) ;
2015-01-12 05:49:30 +01:00
return ;
}
2014-10-12 01:26:23 +02:00
2015-01-12 05:49:30 +01:00
while ( ColorFile . ReadLine ( Line , sizeof ( Line ) ) )
{
char Name [ 1024 ] , Flags [ 1024 ] ;
int Code ;
2014-10-12 01:26:23 +02:00
2015-01-12 05:49:30 +01:00
if ( * Line = = ' ; ' )
continue ;
2014-10-12 01:26:23 +02:00
2015-01-12 05:49:30 +01:00
if ( sscanf ( Line , " %d%s%s " , & Code , Name , Flags ) ! = 3 )
continue ;
2014-10-12 01:26:23 +02:00
2015-01-12 05:49:30 +01:00
int Color = lcGetColorIndex ( Code ) ;
if ( Color > = NumColors )
continue ;
2014-10-12 01:26:23 +02:00
2015-01-12 05:49:30 +01:00
strcpy ( & ColorTable [ Color * LC_MAX_COLOR_NAME ] , Name ) ;
}
2014-05-18 01:03:05 +02:00
}
2011-09-07 23:06:51 +02:00
2015-01-12 05:49:30 +01:00
const char * OldLocale = setlocale ( LC_NUMERIC , " C " ) ;
2011-09-07 23:06:51 +02:00
2015-01-31 22:44:57 +01:00
if ( ! Options . LGEOPath . isEmpty ( ) )
2014-05-18 01:03:05 +02:00
{
2015-01-12 05:49:30 +01:00
POVFile . WriteLine ( " #include \" lg_defs.inc \" \n #include \" lg_color.inc \" \n \n " ) ;
2011-09-07 23:06:51 +02:00
2015-01-12 05:49:30 +01:00
for ( int PartIdx = 0 ; PartIdx < ModelParts . GetSize ( ) ; PartIdx + + )
{
PieceInfo * Info = ModelParts [ PartIdx ] . Info ;
2011-09-07 23:06:51 +02:00
2015-01-12 05:49:30 +01:00
for ( int CheckIdx = 0 ; CheckIdx < ModelParts . GetSize ( ) ; CheckIdx + + )
{
if ( ModelParts [ CheckIdx ] . Info ! = Info )
continue ;
2011-09-07 23:06:51 +02:00
2015-01-12 05:49:30 +01:00
if ( CheckIdx ! = PartIdx )
break ;
2011-09-07 23:06:51 +02:00
2015-01-12 05:49:30 +01:00
int Index = Library - > mPieces . FindIndex ( Info ) ;
2011-09-07 23:06:51 +02:00
2015-01-12 05:49:30 +01:00
if ( PieceTable [ Index * LC_PIECE_NAME_LEN ] )
{
sprintf ( Line , " #include \" %s.inc \" \n " , PieceTable + Index * LC_PIECE_NAME_LEN ) ;
POVFile . WriteLine ( Line ) ;
}
2011-09-07 23:06:51 +02:00
2015-01-12 05:49:30 +01:00
break ;
}
2011-09-07 23:06:51 +02:00
}
2015-01-12 05:49:30 +01:00
POVFile . WriteLine ( " \n " ) ;
2014-05-18 01:03:05 +02:00
}
2015-01-12 05:49:30 +01:00
else
POVFile . WriteLine ( " #include \" colors.inc \" \n \n " ) ;
2011-09-07 23:06:51 +02:00
2015-01-12 05:49:30 +01:00
for ( int ColorIdx = 0 ; ColorIdx < gColorList . GetSize ( ) ; ColorIdx + + )
2011-09-07 23:06:51 +02:00
{
2015-01-12 05:49:30 +01:00
lcColor * Color = & gColorList [ ColorIdx ] ;
2013-08-31 23:58:47 +02:00
2015-01-12 05:49:30 +01:00
if ( lcIsColorTranslucent ( ColorIdx ) )
2013-08-31 23:58:47 +02:00
{
2015-01-12 05:49:30 +01:00
sprintf ( Line , " #declare lc_%s = texture { pigment { rgb <%f, %f, %f> filter 0.9 } finish { ambient 0.3 diffuse 0.2 reflection 0.25 phong 0.3 phong_size 60 } } \n " ,
Color - > SafeName , Color - > Value [ 0 ] , Color - > Value [ 1 ] , Color - > Value [ 2 ] ) ;
2014-05-18 01:03:05 +02:00
}
2015-01-12 05:49:30 +01:00
else
2014-05-18 01:03:05 +02:00
{
2015-01-12 05:49:30 +01:00
sprintf ( Line , " #declare lc_%s = texture { pigment { rgb <%f, %f, %f> } finish { ambient 0.1 phong 0.2 phong_size 20 } } \n " ,
Color - > SafeName , Color - > Value [ 0 ] , Color - > Value [ 1 ] , Color - > Value [ 2 ] ) ;
}
2014-05-18 01:03:05 +02:00
2015-01-12 05:49:30 +01:00
POVFile . WriteLine ( Line ) ;
2013-08-31 23:58:47 +02:00
2015-01-12 05:49:30 +01:00
if ( ! ColorTable [ ColorIdx * LC_MAX_COLOR_NAME ] )
sprintf ( & ColorTable [ ColorIdx * LC_MAX_COLOR_NAME ] , " lc_%s " , Color - > SafeName ) ;
}
2013-08-31 23:58:47 +02:00
2015-01-12 05:49:30 +01:00
POVFile . WriteLine ( " \n " ) ;
2013-08-31 23:58:47 +02:00
2015-01-12 05:49:30 +01:00
for ( int PartIdx = 0 ; PartIdx < ModelParts . GetSize ( ) ; PartIdx + + )
{
PieceInfo * Info = ModelParts [ PartIdx ] . Info ;
lcMesh * Mesh = Info - > GetMesh ( ) ;
int Index = Library - > mPieces . FindIndex ( Info ) ;
2011-09-07 23:06:51 +02:00
2015-01-12 05:49:30 +01:00
if ( ! Mesh | | PieceTable [ Index * LC_PIECE_NAME_LEN ] )
continue ;
2011-09-07 23:06:51 +02:00
2015-01-12 05:49:30 +01:00
char Name [ LC_PIECE_NAME_LEN ] ;
char * Ptr ;
2014-10-13 05:43:33 +02:00
2015-01-12 05:49:30 +01:00
strcpy ( Name , Info - > m_strName ) ;
while ( ( Ptr = strchr ( Name , ' - ' ) ) )
* Ptr = ' _ ' ;
2014-10-13 05:43:33 +02:00
2015-01-12 05:49:30 +01:00
sprintf ( PieceTable + Index * LC_PIECE_NAME_LEN , " lc_%s " , Name ) ;
2014-10-13 05:43:33 +02:00
2015-01-12 05:49:30 +01:00
Mesh - > ExportPOVRay ( POVFile , Name , ColorTable ) ;
2014-10-13 05:43:33 +02:00
2015-01-12 05:49:30 +01:00
POVFile . WriteLine ( " } \n \n " ) ;
2014-10-13 05:43:33 +02:00
2015-01-12 05:49:30 +01:00
sprintf ( Line , " #declare lc_%s_clear = lc_%s \n \n " , Name , Name ) ;
POVFile . WriteLine ( Line ) ;
}
2014-10-13 05:43:33 +02:00
2015-01-12 05:49:30 +01:00
lcCamera * Camera = gMainWindow - > GetActiveView ( ) - > mCamera ;
const lcVector3 & Position = Camera - > mPosition ;
const lcVector3 & Target = Camera - > mTargetPosition ;
const lcVector3 & Up = Camera - > mUpVector ;
const lcModelProperties & Properties = mModels [ 0 ] - > GetProperties ( ) ;
2014-10-13 05:43:33 +02:00
2015-01-12 05:49:30 +01:00
sprintf ( Line , " camera { \n sky<%1g,%1g,%1g> \n location <%1g, %1g, %1g> \n look_at <%1g, %1g, %1g> \n angle %.0f \n } \n \n " ,
Up [ 0 ] , Up [ 1 ] , Up [ 2 ] , Position [ 1 ] / 25.0f , Position [ 0 ] / 25.0f , Position [ 2 ] / 25.0f , Target [ 1 ] / 25.0f , Target [ 0 ] / 25.0f , Target [ 2 ] / 25.0f , Camera - > m_fovy ) ;
POVFile . WriteLine ( Line ) ;
sprintf ( Line , " background { color rgb <%1g, %1g, %1g> } \n \n light_source { <0, 0, 20> White shadowless } \n \n " ,
Properties . mBackgroundSolidColor [ 0 ] , Properties . mBackgroundSolidColor [ 1 ] , Properties . mBackgroundSolidColor [ 2 ] ) ;
POVFile . WriteLine ( Line ) ;
2014-10-13 05:43:33 +02:00
2015-01-12 05:49:30 +01:00
for ( int PartIdx = 0 ; PartIdx < ModelParts . GetSize ( ) ; PartIdx + + )
{
int Index = Library - > mPieces . FindIndex ( ModelParts [ PartIdx ] . Info ) ;
int Color ;
2014-10-13 05:43:33 +02:00
2015-01-12 05:49:30 +01:00
Color = ModelParts [ PartIdx ] . ColorIndex ;
const char * Suffix = lcIsColorTranslucent ( Color ) ? " _clear " : " " ;
2014-10-13 05:43:33 +02:00
2015-01-12 05:49:30 +01:00
const float * f = ModelParts [ PartIdx ] . WorldMatrix ;
2014-10-13 05:43:33 +02:00
2015-01-12 05:49:30 +01:00
if ( PieceFlags [ Index ] & LGEO_PIECE_SLOPE )
{
sprintf ( Line , " merge { \n object { \n %s%s \n texture { %s } \n } \n "
" object { \n %s_slope \n texture { %s normal { bumps 0.3 scale 0.02 } } \n } \n "
" matrix <%.4f, %.4f, %.4f, %.4f, %.4f, %.4f, %.4f, %.4f, %.4f, %.4f, %.4f, %.4f> \n } \n " ,
PieceTable + Index * LC_PIECE_NAME_LEN , Suffix , & ColorTable [ Color * LC_MAX_COLOR_NAME ] , PieceTable + Index * LC_PIECE_NAME_LEN , & ColorTable [ Color * LC_MAX_COLOR_NAME ] ,
- f [ 5 ] , - f [ 4 ] , - f [ 6 ] , - f [ 1 ] , - f [ 0 ] , - f [ 2 ] , f [ 9 ] , f [ 8 ] , f [ 10 ] , f [ 13 ] / 25.0f , f [ 12 ] / 25.0f , f [ 14 ] / 25.0f ) ;
}
else
{
sprintf ( Line , " object { \n %s%s \n texture { %s } \n matrix <%.4f, %.4f, %.4f, %.4f, %.4f, %.4f, %.4f, %.4f, %.4f, %.4f, %.4f, %.4f> \n } \n " ,
PieceTable + Index * LC_PIECE_NAME_LEN , Suffix , & ColorTable [ Color * LC_MAX_COLOR_NAME ] , - f [ 5 ] , - f [ 4 ] , - f [ 6 ] , - f [ 1 ] , - f [ 0 ] , - f [ 2 ] , f [ 9 ] , f [ 8 ] , f [ 10 ] , f [ 13 ] / 25.0f , f [ 12 ] / 25.0f , f [ 14 ] / 25.0f ) ;
}
2014-10-13 05:43:33 +02:00
2015-01-12 05:49:30 +01:00
POVFile . WriteLine ( Line ) ;
2014-10-13 05:43:33 +02:00
}
2015-01-12 05:49:30 +01:00
delete [ ] PieceTable ;
delete [ ] PieceFlags ;
setlocale ( LC_NUMERIC , OldLocale ) ;
POVFile . Close ( ) ;
if ( Options . Render )
2014-10-13 05:43:33 +02:00
{
2015-01-31 21:38:53 +01:00
QStringList Arguments ;
2014-10-13 05:43:33 +02:00
2015-01-31 22:44:57 +01:00
Arguments . append ( QString : : fromLatin1 ( " +I%1 " ) . arg ( Options . FileName ) ) ;
2015-01-12 05:49:30 +01:00
2015-01-31 22:44:57 +01:00
if ( ! Options . LGEOPath . isEmpty ( ) )
2014-10-13 05:43:33 +02:00
{
2015-01-31 22:44:57 +01:00
Arguments . append ( QString : : fromLatin1 ( " +L%1lg/ " ) . arg ( Options . LGEOPath ) ) ;
Arguments . append ( QString : : fromLatin1 ( " +L%1ar/ " ) . arg ( Options . LGEOPath ) ) ;
2014-10-13 05:43:33 +02:00
}
2015-08-08 22:55:10 +02:00
Arguments . append ( QString : : fromLatin1 ( " /EXIT " ) ) ;
2014-10-13 05:43:33 +02:00
2015-01-31 21:38:53 +01:00
QProcess : : execute ( Options . POVRayPath , Arguments ) ;
2014-10-13 05:43:33 +02:00
}
2015-01-12 05:49:30 +01:00
}
2014-10-13 05:43:33 +02:00
2015-01-23 02:58:33 +01:00
void Project : : ExportWavefront ( const QString & FileName )
2015-01-12 05:49:30 +01:00
{
lcArray < lcModelPartsEntry > ModelParts ;
2014-10-13 05:43:33 +02:00
2015-01-12 05:49:30 +01:00
GetModelParts ( ModelParts ) ;
2014-10-13 05:43:33 +02:00
2015-01-12 05:49:30 +01:00
if ( ModelParts . IsEmpty ( ) )
{
2015-01-30 17:30:13 +01:00
QMessageBox : : information ( gMainWindow , tr ( " LeoCAD " ) , tr ( " Nothing to export. " ) ) ;
2015-01-12 05:49:30 +01:00
return ;
}
2014-10-13 05:43:33 +02:00
2015-03-27 21:39:43 +01:00
QString SaveFileName = GetExportFileName ( FileName , " obj " , tr ( " Export Wavefront " ) , tr ( " Wavefront Files (*.obj);;All Files (*.*) " ) ) ;
2014-10-13 05:43:33 +02:00
2015-03-27 21:39:43 +01:00
if ( SaveFileName . isEmpty ( ) )
return ;
2014-10-13 05:43:33 +02:00
2015-01-12 05:49:30 +01:00
lcDiskFile OBJFile ;
char Line [ 1024 ] ;
2014-10-13 05:43:33 +02:00
2015-02-02 07:00:42 +01:00
if ( ! OBJFile . Open ( SaveFileName , " wt " ) )
2015-01-12 05:49:30 +01:00
{
2015-01-30 17:30:13 +01:00
QMessageBox : : warning ( gMainWindow , tr ( " LeoCAD " ) , tr ( " Could not open file '%1' for writing. " ) . arg ( SaveFileName ) ) ;
2015-01-12 05:49:30 +01:00
return ;
}
2014-10-13 05:43:33 +02:00
2015-01-12 05:49:30 +01:00
char buf [ LC_MAXPATH ] , * ptr ;
lcuint32 vert = 1 ;
2014-10-13 05:43:33 +02:00
2015-01-12 05:49:30 +01:00
const char * OldLocale = setlocale ( LC_NUMERIC , " C " ) ;
2014-10-13 05:43:33 +02:00
2015-01-12 05:49:30 +01:00
OBJFile . WriteLine ( " # Model exported from LeoCAD \n " ) ;
2014-10-13 05:43:33 +02:00
2015-01-23 02:58:33 +01:00
strcpy ( buf , SaveFileName . toLatin1 ( ) . constData ( ) ) ;
2015-01-12 05:49:30 +01:00
ptr = strrchr ( buf , ' . ' ) ;
if ( ptr )
* ptr = 0 ;
2014-10-13 05:43:33 +02:00
2015-01-12 05:49:30 +01:00
strcat ( buf , " .mtl " ) ;
ptr = strrchr ( buf , ' \\ ' ) ;
if ( ptr )
ptr + + ;
else
{
ptr = strrchr ( buf , ' / ' ) ;
if ( ptr )
ptr + + ;
else
ptr = buf ;
}
2014-10-13 05:43:33 +02:00
2015-01-12 05:49:30 +01:00
sprintf ( Line , " # \n \n mtllib %s \n \n " , ptr ) ;
OBJFile . WriteLine ( Line ) ;
2014-10-13 05:43:33 +02:00
2015-01-12 05:49:30 +01:00
FILE * mat = fopen ( buf , " wt " ) ;
fputs ( " # Colors used by LeoCAD \n # You need to add transparency values \n # \n \n " , mat ) ;
for ( int ColorIdx = 0 ; ColorIdx < gColorList . GetSize ( ) ; ColorIdx + + )
{
lcColor * Color = & gColorList [ ColorIdx ] ;
fprintf ( mat , " newmtl %s \n Kd %.2f %.2f %.2f \n \n " , Color - > SafeName , Color - > Value [ 0 ] , Color - > Value [ 1 ] , Color - > Value [ 2 ] ) ;
}
fclose ( mat ) ;
2014-10-13 05:43:33 +02:00
2015-01-12 05:49:30 +01:00
for ( int PartIdx = 0 ; PartIdx < ModelParts . GetSize ( ) ; PartIdx + + )
{
lcMesh * Mesh = ModelParts [ PartIdx ] . Info - > GetMesh ( ) ;
2014-10-13 05:43:33 +02:00
2015-01-12 05:49:30 +01:00
if ( ! Mesh )
continue ;
2014-10-13 05:43:33 +02:00
2015-01-12 05:49:30 +01:00
const lcMatrix44 & ModelWorld = ModelParts [ PartIdx ] . WorldMatrix ;
2015-04-26 20:14:33 +02:00
float * Verts = ( float * ) Mesh - > mVertexData ;
2014-10-13 05:43:33 +02:00
2015-01-12 05:49:30 +01:00
for ( int i = 0 ; i < Mesh - > mNumVertices * 3 ; i + = 3 )
{
lcVector3 Vertex = lcMul31 ( lcVector3 ( Verts [ i ] , Verts [ i + 1 ] , Verts [ i + 2 ] ) , ModelWorld ) ;
sprintf ( Line , " v %.2f %.2f %.2f \n " , Vertex [ 0 ] , Vertex [ 1 ] , Vertex [ 2 ] ) ;
OBJFile . WriteLine ( Line ) ;
}
2014-10-13 05:43:33 +02:00
2015-01-12 05:49:30 +01:00
OBJFile . WriteLine ( " # \n \n " ) ;
}
2014-10-13 05:43:33 +02:00
2015-01-12 05:49:30 +01:00
for ( int PartIdx = 0 ; PartIdx < ModelParts . GetSize ( ) ; PartIdx + + )
{
PieceInfo * Info = ModelParts [ PartIdx ] . Info ;
2014-10-13 05:43:33 +02:00
2015-01-12 05:49:30 +01:00
sprintf ( Line , " g Piece%.3d \n " , PartIdx ) ;
OBJFile . WriteLine ( Line ) ;
2014-10-13 05:43:33 +02:00
2015-01-12 05:49:30 +01:00
lcMesh * Mesh = Info - > GetMesh ( ) ;
2014-10-13 05:43:33 +02:00
2015-01-12 05:49:30 +01:00
if ( Mesh )
{
2015-01-14 17:41:32 +01:00
Mesh - > ExportWavefrontIndices ( OBJFile , ModelParts [ PartIdx ] . ColorIndex , vert ) ;
2015-01-12 05:49:30 +01:00
vert + = Mesh - > mNumVertices ;
2014-10-13 05:43:33 +02:00
}
}
2015-01-12 05:49:30 +01:00
setlocale ( LC_NUMERIC , OldLocale ) ;
}
2014-10-13 05:43:33 +02:00
2015-01-12 05:49:30 +01:00
void Project : : SaveImage ( )
{
lcImageDialogOptions Options ;
lcStep LastStep = mActiveModel - > GetLastStep ( ) ;
2014-10-13 05:43:33 +02:00
2015-01-12 05:49:30 +01:00
Options . Width = lcGetProfileInt ( LC_PROFILE_IMAGE_WIDTH ) ;
Options . Height = lcGetProfileInt ( LC_PROFILE_IMAGE_HEIGHT ) ;
Options . Start = mActiveModel - > GetCurrentStep ( ) ;
Options . End = LastStep ;
2014-10-13 05:43:33 +02:00
2015-01-12 05:49:30 +01:00
if ( ! mFileName . isEmpty ( ) )
{
Options . FileName = mFileName ;
QString Extension = QFileInfo ( Options . FileName ) . suffix ( ) ;
2015-01-14 23:38:07 +01:00
Options . FileName = Options . FileName . left ( Options . FileName . length ( ) - Extension . length ( ) - 1 ) ;
2014-10-13 05:43:33 +02:00
}
2015-01-12 05:49:30 +01:00
else
Options . FileName = QLatin1String ( " image " ) ;
Options . FileName + = lcGetProfileString ( LC_PROFILE_IMAGE_EXTENSION ) ;
if ( ! gMainWindow - > DoDialog ( LC_DIALOG_SAVE_IMAGE , & Options ) )
return ;
QString Extension = QFileInfo ( Options . FileName ) . suffix ( ) ;
if ( ! Extension . isEmpty ( ) )
lcSetProfileString ( LC_PROFILE_IMAGE_EXTENSION , Options . FileName . right ( Extension . length ( ) + 1 ) ) ;
lcSetProfileInt ( LC_PROFILE_IMAGE_WIDTH , Options . Width ) ;
lcSetProfileInt ( LC_PROFILE_IMAGE_HEIGHT , Options . Height ) ;
if ( Options . Start ! = Options . End )
Options . FileName = Options . FileName . insert ( Options . FileName . length ( ) - Extension . length ( ) - 1 , QLatin1String ( " %1 " ) ) ;
mActiveModel - > SaveStepImages ( Options . FileName , Options . Width , Options . Height , Options . Start , Options . End ) ;
2014-10-13 05:43:33 +02:00
}